Skip to content

Commit

Permalink
Icon selection dropdown
Browse files Browse the repository at this point in the history
  • Loading branch information
Hannes Giesenow authored and hgiesenow committed Dec 20, 2023
1 parent 3231e4f commit 701cf18
Show file tree
Hide file tree
Showing 11 changed files with 248 additions and 19 deletions.
29 changes: 29 additions & 0 deletions Resources/encore/ez.config.manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// See https://doc.ibexa.co/en/3.3/extending/import_assets_from_bundle/#configuration-from-main-project-files
const path = require('path');

module.exports = (eZConfig, eZConfigManager) => {
// Edit
eZConfigManager.add({
eZConfig,
entryName: 'ezplatform-admin-ui-content-edit-parts-js',
newItems: [
path.resolve(__dirname, '../public/js/elbformat-icon-edit.js')
]
});
eZConfigManager.add({
eZConfig,
entryName: 'ezplatform-admin-ui-content-edit-parts-css',
newItems: [
path.resolve(__dirname, '../public/css/elbformat-icon-edit.css')
]
});
// Preview
eZConfigManager.add({
eZConfig,
entryName: 'ezplatform-admin-ui-layout-css',
newItems: [
path.resolve(__dirname, '../public/css/elbformat-icon-preview.css')
]
});

};
84 changes: 84 additions & 0 deletions Resources/public/css/elbformat-icon-edit.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* Inspired by https://codepen.io/giannisrig/pen/ywBWOV */
.elbformat-icon-select {
display: none;
}
.icon-dropdown-wrapper {
width: 100%;
max-width: 34.375rem;
height: calc(1.5em + 0.75rem + 2px);
position: relative;
border:1px solid #878b90;
}
.icon-dropdown-wrapper .icon-dropdown-trigger {
width: 100%;
height: 100%;
background-color: #fff;
border: 0;
padding: 2px 10px;
transition: 0.2s ease-in;
cursor:pointer;
text-align: left;
}
.icon-dropdown-wrapper .icon-dropdown-trigger::before {
content: '˅';
position: absolute;
top: 7px;
right: 10px;
}
.icon-dropdown-wrapper.open .icon-dropdown-trigger::before {
top: 5px;
right: 10px;
transform: rotate(180deg);
}
.icon-dropdown-wrapper .icon-dropdown-trigger .icon-container {
width: 50px;
height: 30px;
padding-right: 10px;
display: inline-block;
}

.icon-dropdown-wrapper .icon-dropdown-list {
width: 100%;
display:none;
z-index: 1;
position: absolute;
background-color: #fff;
left: 0;
top: 37px;
box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
max-height: 300px;
overflow: scroll;
}
.icon-dropdown-wrapper.open .icon-dropdown-list {
display:block;
}

.icon-dropdown-wrapper .icon-dropdown-trigger button,
.icon-dropdown-wrapper .icon-dropdown-list button {
width: 100%;
height: 54px;
line-height: 54px;
border: 0;
padding: 2px 10px;
cursor: pointer;
transition:0.2s ease-in;
text-align: left;
overflow: hidden;
}
.icon-dropdown-wrapper .icon-dropdown-list button:hover {
background-color:#e5e5e5;
}
.icon-dropdown-wrapper .icon-dropdown-list button:not(:last-child){
border-bottom: 1px solid #e5e5e5;
}
.icon-dropdown-wrapper .icon-dropdown-list .icon-container {
width: 50px;
height: 50px;
padding-right: 10px;
display: inline-block;
}
.icon-dropdown-wrapper .icon-dropdown-trigger .icon-container img,
.icon-dropdown-wrapper .icon-dropdown-list .icon-container img {
max-width: 90%;
max-height: 90%;
}
12 changes: 12 additions & 0 deletions Resources/public/css/elbformat-icon-preview.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.ez-content-preview .elbformat-icon {
text-align: left;
}
.ez-content-preview .elbformat-icon .icon-container {
height: 18px;
width: 30px;
display: inline-block;
}
.ez-content-preview .elbformat-icon .icon-container img {
max-height: 90%;
max-width: 90%;
}
60 changes: 60 additions & 0 deletions Resources/public/js/elbformat-icon-edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Inspired by https://codepen.io/giannisrig/pen/ywBWOV
window.addEventListener('load', function() {
document.querySelectorAll('.elbformat-icon-select').forEach((iconDropdown) => {
// Hidden field to carry the form data
let hiddenField = document.createElement('input');
hiddenField.setAttribute('type','hidden');
hiddenField.setAttribute('name', iconDropdown.getAttribute('name'));
let value = iconDropdown.value || '';
hiddenField.setAttribute('value', value);
iconDropdown.after(hiddenField);

// Wrapper for new widget
let wrapper = document.createElement('div');
wrapper.classList.add('icon-dropdown-wrapper');
iconDropdown.after(wrapper);

let button = document.createElement('button');
button.classList.add('icon-dropdown-trigger');
wrapper.appendChild(button);
let iconList = document.createElement('div');
iconList.classList.add('icon-dropdown-list');
wrapper.appendChild(iconList);

// Extract icons
let items = JSON.parse(iconDropdown.getAttribute('data-choices'));
for (const [key, tmpl] of Object.entries(items)) {
let container = document.createElement('button');
container.setAttribute('value', key)
let iconContainer = document.createElement('div');
iconContainer.classList.add('icon-container');
iconContainer.innerHTML = tmpl;
container.appendChild(iconContainer);
container.innerHTML+=key
iconList.appendChild(container);
if (value===key) {
button.innerHTML = container.innerHTML;
}
// Click on entry
container.addEventListener('click',(e) => {
button.innerHTML = container.innerHTML;
hiddenField.value = key;
wrapper.classList.remove('open');
e.preventDefault();
return false;
});
};

// Open/Close
button.addEventListener('click',(e) => {
if (wrapper.classList.contains('open')) {
wrapper.classList.remove('open');
} else {
wrapper.classList.add('open');
}
e.preventDefault();
return false;
});
});

});
15 changes: 8 additions & 7 deletions config/services.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
services:
Elbformat\IbexaIconFieldtype\FieldType\Icon\Type:
Elbformat\IconBundle\FieldType\Icon\Type:
arguments:
$serializer: '@eZ\Publish\SPI\FieldType\ValueSerializerInterface'
$validator: '@Symfony\Component\Validator\Validator\ValidatorInterface'
Expand All @@ -8,22 +8,23 @@ services:
- { name: ezplatform.field_type.form_mapper.value, fieldType: icon }
- { name: ezplatform.field_type.form_mapper.definition, fieldType: icon }

Elbformat\IbexaIconFieldtype\FieldType\Icon\SearchField:
Elbformat\IconBundle\FieldType\Icon\SearchField:
class: '%ezpublish.fieldType.indexable.unindexed.class%'
tags:
- { name: ezplatform.field_type.indexable, alias: icon }

Elbformat\IbexaIconFieldtype\Form\Type\IconType:
Elbformat\IconBundle\Form\Type\IconType:
arguments:
$iconSetManager: '@Elbformat\IbexaIconFieldtype\IconSet\IconSetManager'
$iconSetManager: '@Elbformat\IconBundle\IconSet\IconSetManager'
$twig: '@twig'
tags:
- { name: form.type }
Elbformat\IbexaIconFieldtype\Form\Type\IconSettingsType:
Elbformat\IconBundle\Form\Type\IconSettingsType:
arguments:
$iconSetManager: '@Elbformat\IbexaIconFieldtype\IconSet\IconSetManager'
$iconSetManager: '@Elbformat\IconBundle\IconSet\IconSetManager'
tags:
- { name: form.type }

Elbformat\IbexaIconFieldtype\IconSet\IconSetManager:
Elbformat\IconBundle\IconSet\IconSetManager:
arguments:
$configs: [] # Will be set from bundle config
21 changes: 20 additions & 1 deletion doc/development.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
## Local development
For local development you can use docker-compose.
```bash
docker-compose run php sh
Expand All @@ -13,4 +14,22 @@ export XDEBUG_MODE="debug"
Run tests
```bash
vendor/bin/phpunit
```
```

## In-Place development
If you want to test out how it integrates into ibexa, it's the easiest way to integrate the bundle into your project directly.
By adding it as "vcs" your are able to push the changes you made right from your vendor folder.
Add the following to your `composer.json`
```json
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/elbformat/icon-bundle"
}
]
}
```
and then run `composer require --prefer-source elbformat/icon-bundle:dev-main`.

Make sure you have **git** installed inside docker, when usin a docker setup.
4 changes: 4 additions & 0 deletions src/ElbformatIconBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@

class ElbformatIconBundle extends Bundle
{
public function getPath(): string
{
return realpath(__DIR__.'/..');
}

}
22 changes: 18 additions & 4 deletions src/Form/Type/IconType.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,33 @@
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Twig\Environment;

final class IconType extends AbstractType
{
public function __construct(
private readonly IconSetManager $iconSetManager,
) { }
private readonly Environment $twig,
)
{
}


public function buildForm(FormBuilderInterface $builder, array $options): void
{
$iconSet = $options['icon_set'];
$builder->add('icon', ChoiceType::class,[
'choices' => $this->iconSetManager->getSet($iconSet)->getList()
$iconList = $this->iconSetManager->getSet($iconSet)->getList();
$iconTemplates = [];
foreach($iconList as $icon) {
$iconTemplates[$icon] = $this->twig->render('@ElbformatIconFieldtype/icon.html.twig',['icon' => $icon,'iconset' => $iconSet]);
}
$builder->add('icon', ChoiceType::class, [
'choices' => $iconList,
'label' => false,
'attr' => [
'class' => 'elbformat-icon-select',
'data-choices' => json_encode($iconTemplates)
]
]);
}

Expand All @@ -31,6 +45,6 @@ public function configureOptions(OptionsResolver $resolver): void
'data_class' => Value::class,
'icon_set' => null,
]);
$resolver->addAllowedTypes('icon_set','string');
$resolver->addAllowedTypes('icon_set', 'string');
}
}
2 changes: 1 addition & 1 deletion src/IconSet/IconSetManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function __construct(array $configs)
$items = $setConfig['items'];
}
if (null !== ($setConfig['folder']??null)) {
$finder = (new Finder())->files()->in($setConfig['folder']);
$finder = (new Finder())->files()->in($setConfig['folder'])->depth(0);
if (null !== ($setConfig['pattern']??null)) {
$finder = $finder->name($setConfig['pattern']);
}
Expand Down
5 changes: 3 additions & 2 deletions templates/icon.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
@var iconset string
#}
{% if icon is not null %}
<i class="icon-{{ icon }}"></i>
{% if "set2" == iconset %}
<img src="assets/build/images/icons/{{ icon }}" />
<img src="/assets/build/images/icons/{{ icon }}" />
{% else %}
<i class="icon-{{ icon }}"></i>
{% endif %}
{% endif %}
13 changes: 9 additions & 4 deletions templates/icon_field.html.twig
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{% block icon_field %}
{{ include('@ElbformatIconFieldtype/icon.html.twig', {
icon: field.value.icon,
iconset: fieldSettings.iconset
}, with_context=false) }}
<div class="elbformat-icon">
<div class="icon-container">
{{ include('@ElbformatIconFieldtype/icon.html.twig', {
icon: field.value.icon,
iconset: fieldSettings.iconset
}, with_context=false) }}
</div>
{{ field.value.icon }}
</div>
{% endblock %}

0 comments on commit 701cf18

Please sign in to comment.