From 4657c208f128ce1733357f928eb65cddb073364d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grabowski?= Date: Fri, 22 Aug 2025 13:59:31 +0200 Subject: [PATCH 1/4] temp --- .../public/ts/components/inputs/Checkbox.ts | 17 ++++++ .../public/ts/components/inputs/InputText.ts | 2 +- .../components/inputs/ThreeStateCheckbox.ts | 9 ++++ .../Resources/public/ts/init_components.ts | 18 +++++++ .../components/inputs/Checkbox.html.twig | 22 ++++++++ .../inputs/ThreeStateCheckbox.html.twig | 24 +++++++++ .../Components/inputs/AbstractCheckbox.php | 52 +++++++++++++++++++ src/lib/Twig/Components/inputs/Checkbox.php | 21 ++++++++ .../Components/inputs/ThreeStateCheckbox.php | 26 ++++++++++ 9 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 src/bundle/Resources/public/ts/components/inputs/Checkbox.ts create mode 100644 src/bundle/Resources/public/ts/components/inputs/ThreeStateCheckbox.ts create mode 100644 src/bundle/Resources/views/themes/standard/design_system/components/inputs/Checkbox.html.twig create mode 100644 src/bundle/Resources/views/themes/standard/design_system/components/inputs/ThreeStateCheckbox.html.twig create mode 100644 src/lib/Twig/Components/inputs/AbstractCheckbox.php create mode 100644 src/lib/Twig/Components/inputs/Checkbox.php create mode 100644 src/lib/Twig/Components/inputs/ThreeStateCheckbox.php diff --git a/src/bundle/Resources/public/ts/components/inputs/Checkbox.ts b/src/bundle/Resources/public/ts/components/inputs/Checkbox.ts new file mode 100644 index 0000000..3614f13 --- /dev/null +++ b/src/bundle/Resources/public/ts/components/inputs/Checkbox.ts @@ -0,0 +1,17 @@ +import Base from '../../shared/Base'; + +export default class Checkbox extends Base { + protected _inputElement: HTMLInputElement; + + constructor(container: HTMLDivElement) { + super(container); + + const inputElement = container.querySelector('.ids-input'); + + if (!inputElement) { + throw new Error('Checkbox: Required elements are missing in the container.'); + } + + this._inputElement = inputElement; + } +} diff --git a/src/bundle/Resources/public/ts/components/inputs/InputText.ts b/src/bundle/Resources/public/ts/components/inputs/InputText.ts index e7c66e4..3ae160f 100644 --- a/src/bundle/Resources/public/ts/components/inputs/InputText.ts +++ b/src/bundle/Resources/public/ts/components/inputs/InputText.ts @@ -1,6 +1,6 @@ import Base from '../../shared/Base'; -export default class InpuText extends Base { +export default class InputText extends Base { private _inputElement: HTMLInputElement; private _actionsElement: HTMLDivElement; private _clearBtnElement: HTMLButtonElement; diff --git a/src/bundle/Resources/public/ts/components/inputs/ThreeStateCheckbox.ts b/src/bundle/Resources/public/ts/components/inputs/ThreeStateCheckbox.ts new file mode 100644 index 0000000..f0c87ab --- /dev/null +++ b/src/bundle/Resources/public/ts/components/inputs/ThreeStateCheckbox.ts @@ -0,0 +1,9 @@ +import Checkbox from './Checkbox'; + +export default class ThreeStateCheckbox extends Checkbox { + init() { + super.init(); + + console.log(this._inputElement); + } +} diff --git a/src/bundle/Resources/public/ts/init_components.ts b/src/bundle/Resources/public/ts/init_components.ts index bbfa94d..a5a1246 100644 --- a/src/bundle/Resources/public/ts/init_components.ts +++ b/src/bundle/Resources/public/ts/init_components.ts @@ -1,5 +1,7 @@ import Accordion from './components/accordion'; +import Checkbox from './components/inputs/Checkbox'; import InputText from './components/inputs/InputText'; +import ThreeStateCheckbox from './components/inputs/ThreeStateCheckbox'; const accordionContainers = document.querySelectorAll('.ids-accordion:not([custom-init])'); @@ -9,6 +11,14 @@ accordionContainers.forEach((accordionContainer: HTMLDivElement) => { accordionInstance.init(); }); +const checkboxContainers = document.querySelectorAll('.ids-checkbox:not([custom-init])'); + +checkboxContainers.forEach((checkboxContainer: HTMLDivElement) => { + const checkboxInstance = new Checkbox(checkboxContainer); + + checkboxInstance.init(); +}); + const inputTextContainers = document.querySelectorAll('.ids-input-text:not([custom-init])'); inputTextContainers.forEach((inputTextContainer: HTMLDivElement) => { @@ -16,3 +26,11 @@ inputTextContainers.forEach((inputTextContainer: HTMLDivElement) => { inputTextInstance.init(); }); + +const threeStateCheckboxContainers = document.querySelectorAll('.ids-checkbox.ids-checkbox--three-state:not([custom-init])'); + +threeStateCheckboxContainers.forEach((threeStateCheckboxContainer: HTMLDivElement) => { + const threeStateCheckboxInstance = new ThreeStateCheckbox(threeStateCheckboxContainer); + + threeStateCheckboxInstance.init(); +}); diff --git a/src/bundle/Resources/views/themes/standard/design_system/components/inputs/Checkbox.html.twig b/src/bundle/Resources/views/themes/standard/design_system/components/inputs/Checkbox.html.twig new file mode 100644 index 0000000..51bb7dd --- /dev/null +++ b/src/bundle/Resources/views/themes/standard/design_system/components/inputs/Checkbox.html.twig @@ -0,0 +1,22 @@ +{% set input_classes = html_classes( + 'ids-input ids-input--checkbox ids-input--medium', + { + 'ids-input--disabled': disabled, + 'ids-input--error': error, + 'ids-input--required': required + }, + attributes.render('class') ?? '' +) %} + +
+ +
diff --git a/src/bundle/Resources/views/themes/standard/design_system/components/inputs/ThreeStateCheckbox.html.twig b/src/bundle/Resources/views/themes/standard/design_system/components/inputs/ThreeStateCheckbox.html.twig new file mode 100644 index 0000000..d6a8e0c --- /dev/null +++ b/src/bundle/Resources/views/themes/standard/design_system/components/inputs/ThreeStateCheckbox.html.twig @@ -0,0 +1,24 @@ +{% set input_classes = html_classes( + 'ids-input ids-input--checkbox ids-input--medium', + { + 'ids-input--disabled': disabled, + 'ids-input--error': error, + 'ids-input--required': required + }, + attributes.render('class') ?? '' +) %} + +{{dump()}} + +
+ +
diff --git a/src/lib/Twig/Components/inputs/AbstractCheckbox.php b/src/lib/Twig/Components/inputs/AbstractCheckbox.php new file mode 100644 index 0000000..adebf7c --- /dev/null +++ b/src/lib/Twig/Components/inputs/AbstractCheckbox.php @@ -0,0 +1,52 @@ + $props + * + * @return array + */ + #[PreMount] + public function validate(array $props): array + { + $resolver = new OptionsResolver(); + $resolver->setIgnoreUndefined(); + $resolver + ->define('disabled') + ->allowedTypes('bool') + ->default(false); + $resolver + ->define('error') + ->allowedTypes('bool') + ->default(false); + $resolver + ->define('required') + ->allowedTypes('bool') + ->default(false); + + $this->configurePropsResolver($resolver); + + return $resolver->resolve($props) + $props; + } + + abstract protected function configurePropsResolver(OptionsResolver $resolver): void; +} diff --git a/src/lib/Twig/Components/inputs/Checkbox.php b/src/lib/Twig/Components/inputs/Checkbox.php new file mode 100644 index 0000000..b0ca43d --- /dev/null +++ b/src/lib/Twig/Components/inputs/Checkbox.php @@ -0,0 +1,21 @@ +define('indeterminate') + ->allowedTypes('bool') + ->default(false); + } +} From 711ad97a7ee341e543213df66500d08f03fa7417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grabowski?= Date: Fri, 22 Aug 2025 15:54:12 +0200 Subject: [PATCH 2/4] IBX-7999: IBX-7999: Checkbox and ThreeStateCheckbox --- .../public/ts/components/inputs/Checkbox.ts | 18 ++-------- .../components/inputs/ThreeStateCheckbox.ts | 25 +++++++++++--- .../Resources/public/ts/init_components.ts | 2 +- .../public/ts/shared/BaseCheckbox.ts | 17 ++++++++++ .../components/inputs/Checkbox.html.twig | 28 ++++++++-------- .../inputs/ThreeStateCheckbox.html.twig | 33 ++++++++++--------- 6 files changed, 72 insertions(+), 51 deletions(-) create mode 100644 src/bundle/Resources/public/ts/shared/BaseCheckbox.ts diff --git a/src/bundle/Resources/public/ts/components/inputs/Checkbox.ts b/src/bundle/Resources/public/ts/components/inputs/Checkbox.ts index 3614f13..9746168 100644 --- a/src/bundle/Resources/public/ts/components/inputs/Checkbox.ts +++ b/src/bundle/Resources/public/ts/components/inputs/Checkbox.ts @@ -1,17 +1,3 @@ -import Base from '../../shared/Base'; +import BaseCheckbox from '../../shared/BaseCheckbox'; -export default class Checkbox extends Base { - protected _inputElement: HTMLInputElement; - - constructor(container: HTMLDivElement) { - super(container); - - const inputElement = container.querySelector('.ids-input'); - - if (!inputElement) { - throw new Error('Checkbox: Required elements are missing in the container.'); - } - - this._inputElement = inputElement; - } -} +export default class Checkbox extends BaseCheckbox {} diff --git a/src/bundle/Resources/public/ts/components/inputs/ThreeStateCheckbox.ts b/src/bundle/Resources/public/ts/components/inputs/ThreeStateCheckbox.ts index f0c87ab..ff0ebc6 100644 --- a/src/bundle/Resources/public/ts/components/inputs/ThreeStateCheckbox.ts +++ b/src/bundle/Resources/public/ts/components/inputs/ThreeStateCheckbox.ts @@ -1,9 +1,24 @@ -import Checkbox from './Checkbox'; +import BaseCheckbox from '../../shared/BaseCheckbox'; -export default class ThreeStateCheckbox extends Checkbox { - init() { - super.init(); +export default class ThreeStateCheckbox extends BaseCheckbox { + private _indeterminate = false; - console.log(this._inputElement); + constructor(container: HTMLDivElement) { + super(container); + + this.indeterminate = this._inputElement.classList.contains('ids-input--indeterminate'); + } + + set indeterminate(value: boolean) { + this._indeterminate = value; + this._inputElement.indeterminate = value; + this._inputElement.classList.toggle('ids-input--indeterminate', value); + + if (value) { + this._inputElement.checked = false; + + this._inputElement.dispatchEvent(new Event('input', { bubbles: true })); + this._inputElement.dispatchEvent(new Event('change', { bubbles: true })); + } } } diff --git a/src/bundle/Resources/public/ts/init_components.ts b/src/bundle/Resources/public/ts/init_components.ts index a5a1246..3a05bcb 100644 --- a/src/bundle/Resources/public/ts/init_components.ts +++ b/src/bundle/Resources/public/ts/init_components.ts @@ -27,7 +27,7 @@ inputTextContainers.forEach((inputTextContainer: HTMLDivElement) => { inputTextInstance.init(); }); -const threeStateCheckboxContainers = document.querySelectorAll('.ids-checkbox.ids-checkbox--three-state:not([custom-init])'); +const threeStateCheckboxContainers = document.querySelectorAll('.ids-three-state-checkbox:not([custom-init])'); threeStateCheckboxContainers.forEach((threeStateCheckboxContainer: HTMLDivElement) => { const threeStateCheckboxInstance = new ThreeStateCheckbox(threeStateCheckboxContainer); diff --git a/src/bundle/Resources/public/ts/shared/BaseCheckbox.ts b/src/bundle/Resources/public/ts/shared/BaseCheckbox.ts new file mode 100644 index 0000000..71250c7 --- /dev/null +++ b/src/bundle/Resources/public/ts/shared/BaseCheckbox.ts @@ -0,0 +1,17 @@ +import Base from './Base'; + +export default abstract class BaseCheckbox extends Base { + protected _inputElement: HTMLInputElement; + + constructor(container: HTMLDivElement) { + super(container); + + const inputElement = container.querySelector('.ids-input'); + + if (!inputElement) { + throw new Error('Checkbox: Required elements are missing in the container.'); + } + + this._inputElement = inputElement; + } +} diff --git a/src/bundle/Resources/views/themes/standard/design_system/components/inputs/Checkbox.html.twig b/src/bundle/Resources/views/themes/standard/design_system/components/inputs/Checkbox.html.twig index 51bb7dd..e68d675 100644 --- a/src/bundle/Resources/views/themes/standard/design_system/components/inputs/Checkbox.html.twig +++ b/src/bundle/Resources/views/themes/standard/design_system/components/inputs/Checkbox.html.twig @@ -1,22 +1,24 @@ -{% set input_classes = html_classes( - 'ids-input ids-input--checkbox ids-input--medium', - { - 'ids-input--disabled': disabled, - 'ids-input--error': error, - 'ids-input--required': required - }, - attributes.render('class') ?? '' -) %} +{% set input_classes = + html_classes( + 'ids-input ids-input--checkbox ids-input--medium', + { + 'ids-input--disabled': disabled, + 'ids-input--error': error, + 'ids-input--required': required + }, + attributes.render('class') ?? '' + ) +%}
diff --git a/src/bundle/Resources/views/themes/standard/design_system/components/inputs/ThreeStateCheckbox.html.twig b/src/bundle/Resources/views/themes/standard/design_system/components/inputs/ThreeStateCheckbox.html.twig index d6a8e0c..fa3a643 100644 --- a/src/bundle/Resources/views/themes/standard/design_system/components/inputs/ThreeStateCheckbox.html.twig +++ b/src/bundle/Resources/views/themes/standard/design_system/components/inputs/ThreeStateCheckbox.html.twig @@ -1,24 +1,25 @@ -{% set input_classes = html_classes( - 'ids-input ids-input--checkbox ids-input--medium', - { - 'ids-input--disabled': disabled, - 'ids-input--error': error, - 'ids-input--required': required - }, - attributes.render('class') ?? '' -) %} +{% set input_classes = + html_classes( + 'ids-input ids-input--checkbox ids-input--medium', + { + 'ids-input--disabled': disabled, + 'ids-input--error': error, + 'ids-input--required': required, + 'ids-input--indeterminate': indeterminate + }, + attributes.render('class') ?? '' + ) +%} -{{dump()}} - -
+
From 198ff9f73447d871e388bcb2520704eeeadb37fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grabowski?= Date: Tue, 26 Aug 2025 14:03:59 +0200 Subject: [PATCH 3/4] removed unused use --- src/lib/Twig/Components/inputs/AbstractCheckbox.php | 1 - src/lib/Twig/Components/inputs/Checkbox.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/lib/Twig/Components/inputs/AbstractCheckbox.php b/src/lib/Twig/Components/inputs/AbstractCheckbox.php index adebf7c..bd7aa64 100644 --- a/src/lib/Twig/Components/inputs/AbstractCheckbox.php +++ b/src/lib/Twig/Components/inputs/AbstractCheckbox.php @@ -9,7 +9,6 @@ namespace Ibexa\DesignSystemTwig\Twig\Components\inputs; use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\UX\TwigComponent\Attribute\AsTwigComponent; use Symfony\UX\TwigComponent\Attribute\PreMount; abstract class AbstractCheckbox diff --git a/src/lib/Twig/Components/inputs/Checkbox.php b/src/lib/Twig/Components/inputs/Checkbox.php index b0ca43d..2974ad5 100644 --- a/src/lib/Twig/Components/inputs/Checkbox.php +++ b/src/lib/Twig/Components/inputs/Checkbox.php @@ -10,7 +10,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\UX\TwigComponent\Attribute\AsTwigComponent; -use Symfony\UX\TwigComponent\Attribute\PreMount; #[AsTwigComponent] final class Checkbox extends AbstractCheckbox From d3fb35126ae400bb96f151a801206643ad92ba50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grabowski?= Date: Wed, 27 Aug 2025 13:50:30 +0200 Subject: [PATCH 4/4] change from setter to setX --- .../public/ts/components/inputs/ThreeStateCheckbox.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/bundle/Resources/public/ts/components/inputs/ThreeStateCheckbox.ts b/src/bundle/Resources/public/ts/components/inputs/ThreeStateCheckbox.ts index ff0ebc6..d7340cd 100644 --- a/src/bundle/Resources/public/ts/components/inputs/ThreeStateCheckbox.ts +++ b/src/bundle/Resources/public/ts/components/inputs/ThreeStateCheckbox.ts @@ -1,16 +1,13 @@ import BaseCheckbox from '../../shared/BaseCheckbox'; export default class ThreeStateCheckbox extends BaseCheckbox { - private _indeterminate = false; - constructor(container: HTMLDivElement) { super(container); - this.indeterminate = this._inputElement.classList.contains('ids-input--indeterminate'); + this.setIndeterminate(this._inputElement.classList.contains('ids-input--indeterminate')); } - set indeterminate(value: boolean) { - this._indeterminate = value; + setIndeterminate(value: boolean) { this._inputElement.indeterminate = value; this._inputElement.classList.toggle('ids-input--indeterminate', value);