Skip to content

Commit 148c8ad

Browse files
authored
IBX-7999: Checkbox and ThreeStateCheckbox (#13)
1 parent a1bcc4a commit 148c8ad

File tree

10 files changed

+206
-1
lines changed

10 files changed

+206
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import BaseCheckbox from '../../shared/BaseCheckbox';
2+
3+
export default class Checkbox extends BaseCheckbox {}

src/bundle/Resources/public/ts/components/inputs/InputText.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Base from '../../shared/Base';
22

3-
export default class InpuText extends Base {
3+
export default class InputText extends Base {
44
private _inputElement: HTMLInputElement;
55
private _actionsElement: HTMLDivElement;
66
private _clearBtnElement: HTMLButtonElement;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import BaseCheckbox from '../../shared/BaseCheckbox';
2+
3+
export default class ThreeStateCheckbox extends BaseCheckbox {
4+
constructor(container: HTMLDivElement) {
5+
super(container);
6+
7+
this.setIndeterminate(this._inputElement.classList.contains('ids-input--indeterminate'));
8+
}
9+
10+
setIndeterminate(value: boolean) {
11+
this._inputElement.indeterminate = value;
12+
this._inputElement.classList.toggle('ids-input--indeterminate', value);
13+
14+
if (value) {
15+
this._inputElement.checked = false;
16+
17+
this._inputElement.dispatchEvent(new Event('input', { bubbles: true }));
18+
this._inputElement.dispatchEvent(new Event('change', { bubbles: true }));
19+
}
20+
}
21+
}

src/bundle/Resources/public/ts/init_components.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import Accordion from './components/accordion';
2+
import Checkbox from './components/inputs/Checkbox';
23
import InputText from './components/inputs/InputText';
4+
import ThreeStateCheckbox from './components/inputs/ThreeStateCheckbox';
35

46
const accordionContainers = document.querySelectorAll<HTMLDivElement>('.ids-accordion:not([custom-init])');
57

@@ -9,10 +11,26 @@ accordionContainers.forEach((accordionContainer: HTMLDivElement) => {
911
accordionInstance.init();
1012
});
1113

14+
const checkboxContainers = document.querySelectorAll<HTMLDivElement>('.ids-checkbox:not([custom-init])');
15+
16+
checkboxContainers.forEach((checkboxContainer: HTMLDivElement) => {
17+
const checkboxInstance = new Checkbox(checkboxContainer);
18+
19+
checkboxInstance.init();
20+
});
21+
1222
const inputTextContainers = document.querySelectorAll<HTMLDivElement>('.ids-input-text:not([custom-init])');
1323

1424
inputTextContainers.forEach((inputTextContainer: HTMLDivElement) => {
1525
const inputTextInstance = new InputText(inputTextContainer);
1626

1727
inputTextInstance.init();
1828
});
29+
30+
const threeStateCheckboxContainers = document.querySelectorAll<HTMLDivElement>('.ids-three-state-checkbox:not([custom-init])');
31+
32+
threeStateCheckboxContainers.forEach((threeStateCheckboxContainer: HTMLDivElement) => {
33+
const threeStateCheckboxInstance = new ThreeStateCheckbox(threeStateCheckboxContainer);
34+
35+
threeStateCheckboxInstance.init();
36+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Base from './Base';
2+
3+
export default abstract class BaseCheckbox extends Base {
4+
protected _inputElement: HTMLInputElement;
5+
6+
constructor(container: HTMLDivElement) {
7+
super(container);
8+
9+
const inputElement = container.querySelector<HTMLInputElement>('.ids-input');
10+
11+
if (!inputElement) {
12+
throw new Error('Checkbox: Required elements are missing in the container.');
13+
}
14+
15+
this._inputElement = inputElement;
16+
}
17+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{% set input_classes =
2+
html_classes(
3+
'ids-input ids-input--checkbox ids-input--medium',
4+
{
5+
'ids-input--disabled': disabled,
6+
'ids-input--error': error,
7+
'ids-input--required': required
8+
},
9+
attributes.render('class') ?? ''
10+
)
11+
%}
12+
13+
<div class="ids-checkbox">
14+
<input
15+
class="{{ input_classes }}"
16+
type="checkbox"
17+
{{
18+
attributes.defaults({
19+
disabled,
20+
required
21+
})
22+
}}
23+
/>
24+
</div>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{% set input_classes =
2+
html_classes(
3+
'ids-input ids-input--checkbox ids-input--medium',
4+
{
5+
'ids-input--disabled': disabled,
6+
'ids-input--error': error,
7+
'ids-input--required': required,
8+
'ids-input--indeterminate': indeterminate
9+
},
10+
attributes.render('class') ?? ''
11+
)
12+
%}
13+
14+
<div class="ids-three-state-checkbox">
15+
<input
16+
class="{{ input_classes }}"
17+
type="checkbox"
18+
{{
19+
attributes.defaults({
20+
disabled,
21+
required
22+
})
23+
}}
24+
/>
25+
</div>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\DesignSystemTwig\Twig\Components\inputs;
10+
11+
use Symfony\Component\OptionsResolver\OptionsResolver;
12+
use Symfony\UX\TwigComponent\Attribute\PreMount;
13+
14+
abstract class AbstractCheckbox
15+
{
16+
public bool $disabled = false;
17+
18+
public bool $error = false;
19+
20+
public bool $required = false;
21+
22+
/**
23+
* @param array<string, mixed> $props
24+
*
25+
* @return array<string, mixed>
26+
*/
27+
#[PreMount]
28+
public function validate(array $props): array
29+
{
30+
$resolver = new OptionsResolver();
31+
$resolver->setIgnoreUndefined();
32+
$resolver
33+
->define('disabled')
34+
->allowedTypes('bool')
35+
->default(false);
36+
$resolver
37+
->define('error')
38+
->allowedTypes('bool')
39+
->default(false);
40+
$resolver
41+
->define('required')
42+
->allowedTypes('bool')
43+
->default(false);
44+
45+
$this->configurePropsResolver($resolver);
46+
47+
return $resolver->resolve($props) + $props;
48+
}
49+
50+
abstract protected function configurePropsResolver(OptionsResolver $resolver): void;
51+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\DesignSystemTwig\Twig\Components\inputs;
10+
11+
use Symfony\Component\OptionsResolver\OptionsResolver;
12+
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
13+
14+
#[AsTwigComponent]
15+
final class Checkbox extends AbstractCheckbox
16+
{
17+
protected function configurePropsResolver(OptionsResolver $resolver): void
18+
{
19+
}
20+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\DesignSystemTwig\Twig\Components\inputs;
10+
11+
use Symfony\Component\OptionsResolver\OptionsResolver;
12+
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
13+
14+
#[AsTwigComponent]
15+
final class ThreeStateCheckbox extends AbstractCheckbox
16+
{
17+
public bool $indeterminate = false;
18+
19+
protected function configurePropsResolver(OptionsResolver $resolver): void
20+
{
21+
$resolver
22+
->define('indeterminate')
23+
->allowedTypes('bool')
24+
->default(false);
25+
}
26+
}

0 commit comments

Comments
 (0)