mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Merged PR 1891: feat: implement multi-level checkbox filter with hierarchical selection
feat: implement multi-level checkbox filter with hierarchical selection - Add support for hierarchical checkbox options with parent-child relationships - Implement automatic child selection/deselection when parent is toggled - Add checkbox-input-control component for individual option management - Add isCheckboxSelected helper for determining selection states - Extend FilterService with setInputCheckboxOptionSelected method - Update checkbox schemas to support nested option structures - Add comprehensive test coverage for new multi-level functionality Ref: #5231
This commit is contained in:
committed by
Nino Righi
parent
0b4aef5f6c
commit
b339a6d79f
@@ -1,105 +1,137 @@
|
||||
.ui-checkbox-label {
|
||||
@apply inline-flex items-center gap-4 text-isa-neutral-900 isa-text-body-2-regular;
|
||||
}
|
||||
|
||||
.ui-checkbox-label:has(:checked) {
|
||||
@apply isa-text-body-2-bold;
|
||||
}
|
||||
|
||||
.ui-checkbox.ui-checkbox__checkbox {
|
||||
@apply relative inline-flex p-3 items-center justify-center rounded-lg bg-isa-white size-6 border border-solid border-isa-neutral-900;
|
||||
font-size: 1.5rem;
|
||||
|
||||
.ui-checkbox__icon {
|
||||
@apply invisible min-w-6 size-6 text-isa-white;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
opacity: 0;
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
|
||||
&:has(input[type="checkbox"]:checked) {
|
||||
@apply bg-isa-neutral-900 text-isa-white;
|
||||
|
||||
.ui-checkbox__icon {
|
||||
@apply visible;
|
||||
}
|
||||
}
|
||||
|
||||
&:has(input[type="checkbox"]:disabled) {
|
||||
@apply bg-isa-neutral-400 border-isa-neutral-400 cursor-default;
|
||||
|
||||
&:has(input[type="checkbox"]:checked) {
|
||||
@apply bg-isa-neutral-400 border-isa-neutral-400;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
@apply cursor-default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ui-checkbox.ui-checkbox__bullet {
|
||||
display: inline-flex;
|
||||
padding: 0.75rem;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 1.5rem;
|
||||
position: relative;
|
||||
|
||||
@apply rounded-full bg-isa-neutral-300 size-12;
|
||||
|
||||
.ui-checkbox__icon {
|
||||
@apply invisible size-6 text-isa-neutral-100;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
opacity: 0;
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@apply bg-isa-neutral-400;
|
||||
}
|
||||
|
||||
&:has(input[type="checkbox"]:checked) {
|
||||
@apply bg-isa-neutral-700;
|
||||
|
||||
.ui-checkbox__icon {
|
||||
@apply visible;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@apply bg-isa-neutral-800;
|
||||
}
|
||||
}
|
||||
|
||||
&:has(input[type="checkbox"]:disabled) {
|
||||
@apply bg-isa-neutral-400 cursor-default;
|
||||
|
||||
&:has(input[type="checkbox"]:checked) {
|
||||
@apply bg-isa-neutral-700;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
@apply cursor-default;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ui-checkbox-label {
|
||||
@apply inline-flex items-center gap-4 text-isa-neutral-900 isa-text-body-2-regular;
|
||||
}
|
||||
|
||||
.ui-checkbox-label:has(:checked) {
|
||||
@apply isa-text-body-2-bold;
|
||||
}
|
||||
|
||||
.ui-checkbox.ui-checkbox__checkbox {
|
||||
@apply relative inline-flex p-3 items-center justify-center rounded-lg bg-isa-white size-6 border border-solid border-isa-neutral-900;
|
||||
font-size: 1.5rem;
|
||||
|
||||
.ui-checkbox__icon {
|
||||
@apply hidden min-w-6 size-6 text-isa-white;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
opacity: 0;
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
|
||||
&:has(input[type="checkbox"]:checked) {
|
||||
@apply bg-isa-neutral-900 text-isa-white;
|
||||
|
||||
.ui-checkbox__icon--checked {
|
||||
@apply inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
&:has(input[type="checkbox"]:indeterminate) {
|
||||
@apply bg-isa-neutral-900 text-isa-white;
|
||||
|
||||
.ui-checkbox__icon--checked {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
.ui-checkbox__icon--indeterminate {
|
||||
@apply inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
&:has(input[type="checkbox"]:disabled) {
|
||||
@apply bg-isa-neutral-400 border-isa-neutral-400 cursor-default;
|
||||
|
||||
&:has(input[type="checkbox"]:checked) {
|
||||
@apply bg-isa-neutral-400 border-isa-neutral-400;
|
||||
}
|
||||
|
||||
&:has(input[type="checkbox"]:indeterminate) {
|
||||
@apply bg-isa-neutral-400 border-isa-neutral-400;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
@apply cursor-default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ui-checkbox.ui-checkbox__bullet {
|
||||
display: inline-flex;
|
||||
padding: 0.75rem;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 1.5rem;
|
||||
position: relative;
|
||||
|
||||
@apply rounded-full bg-isa-neutral-300 size-12;
|
||||
|
||||
.ui-checkbox__icon {
|
||||
@apply hidden size-6 text-isa-neutral-100;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
opacity: 0;
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@apply bg-isa-neutral-400;
|
||||
}
|
||||
|
||||
&:has(input[type="checkbox"]:checked) {
|
||||
@apply bg-isa-neutral-700;
|
||||
|
||||
.ui-checkbox__icon--checked {
|
||||
@apply flex;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@apply bg-isa-neutral-800;
|
||||
}
|
||||
}
|
||||
|
||||
&:has(input[type="checkbox"]:indeterminate) {
|
||||
@apply bg-isa-neutral-700;
|
||||
|
||||
.ui-checkbox__icon--checked {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
.ui-checkbox__icon--indeterminate {
|
||||
@apply flex;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@apply bg-isa-neutral-800;
|
||||
}
|
||||
}
|
||||
|
||||
&:has(input[type="checkbox"]:disabled) {
|
||||
@apply bg-isa-neutral-400 cursor-default;
|
||||
|
||||
&:has(input[type="checkbox"]:checked) {
|
||||
@apply bg-isa-neutral-700;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
@apply cursor-default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,9 @@
|
||||
<ng-content select="input[type=checkbox]"></ng-content>
|
||||
<ng-icon class="ui-checkbox__icon" name="isaActionCheck"></ng-icon>
|
||||
<ng-content select="input[type=checkbox]"></ng-content>
|
||||
<ng-icon
|
||||
class="ui-checkbox__icon ui-checkbox__icon--checked"
|
||||
name="isaActionCheck"
|
||||
></ng-icon>
|
||||
<ng-icon
|
||||
class="ui-checkbox__icon ui-checkbox__icon--indeterminate"
|
||||
name="isaActionMinus"
|
||||
></ng-icon>
|
||||
|
||||
@@ -1,73 +1,73 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
input,
|
||||
ViewEncapsulation,
|
||||
} from '@angular/core';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
import { isaActionCheck } from '@isa/icons';
|
||||
|
||||
/**
|
||||
* Configuration options for CheckboxComponent appearance
|
||||
* @readonly
|
||||
*/
|
||||
export const CheckboxAppearance = {
|
||||
/** Renders the checkbox as a round bullet style selector */
|
||||
Bullet: 'bullet',
|
||||
/** Renders the checkbox as a traditional square checkbox (default) */
|
||||
Checkbox: 'checkbox',
|
||||
} as const;
|
||||
|
||||
export type CheckboxAppearance =
|
||||
(typeof CheckboxAppearance)[keyof typeof CheckboxAppearance];
|
||||
|
||||
/**
|
||||
* A customizable checkbox component that supports different visual appearances.
|
||||
*
|
||||
* This component provides a styled checkbox input that can be displayed either as
|
||||
* a traditional checkbox or as a bullet-style (round) selector. It uses Angular signals
|
||||
* for reactive state management and includes an optional checkmark icon when selected.
|
||||
*
|
||||
* @example
|
||||
* ```html
|
||||
* <!-- Default checkbox appearance -->
|
||||
* <ui-checkbox>
|
||||
* <input type="checkbox" />
|
||||
* </ui-checkbox>
|
||||
*
|
||||
* <!-- Bullet appearance -->
|
||||
* <ui-checkbox [appearance]="CheckboxAppearance.Bullet">
|
||||
* <input type="checkbox" />
|
||||
* </ui-checkbox>
|
||||
* ```
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ui-checkbox',
|
||||
templateUrl: './checkbox.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
imports: [NgIconComponent],
|
||||
providers: [provideIcons({ isaActionCheck })],
|
||||
host: {
|
||||
'[class]': '["ui-checkbox", appearanceClass()]',
|
||||
},
|
||||
})
|
||||
export class CheckboxComponent {
|
||||
/**
|
||||
* Controls the visual appearance of the checkbox.
|
||||
* Can be either "checkbox" (default) or "bullet".
|
||||
*/
|
||||
appearance = input<CheckboxAppearance>(CheckboxAppearance.Checkbox);
|
||||
|
||||
/**
|
||||
* Computes the CSS class to apply based on the current appearance setting.
|
||||
*
|
||||
* @returns A CSS class name string that corresponds to the current appearance
|
||||
*/
|
||||
appearanceClass = computed(() => {
|
||||
return this.appearance() === CheckboxAppearance.Bullet
|
||||
? 'ui-checkbox__bullet'
|
||||
: 'ui-checkbox__checkbox';
|
||||
});
|
||||
}
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
input,
|
||||
ViewEncapsulation,
|
||||
} from '@angular/core';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
import { isaActionCheck, isaActionMinus } from '@isa/icons';
|
||||
|
||||
/**
|
||||
* Configuration options for CheckboxComponent appearance
|
||||
* @readonly
|
||||
*/
|
||||
export const CheckboxAppearance = {
|
||||
/** Renders the checkbox as a round bullet style selector */
|
||||
Bullet: 'bullet',
|
||||
/** Renders the checkbox as a traditional square checkbox (default) */
|
||||
Checkbox: 'checkbox',
|
||||
} as const;
|
||||
|
||||
export type CheckboxAppearance =
|
||||
(typeof CheckboxAppearance)[keyof typeof CheckboxAppearance];
|
||||
|
||||
/**
|
||||
* A customizable checkbox component that supports different visual appearances.
|
||||
*
|
||||
* This component provides a styled checkbox input that can be displayed either as
|
||||
* a traditional checkbox or as a bullet-style (round) selector. It uses Angular signals
|
||||
* for reactive state management and includes an optional checkmark icon when selected.
|
||||
*
|
||||
* @example
|
||||
* ```html
|
||||
* <!-- Default checkbox appearance -->
|
||||
* <ui-checkbox>
|
||||
* <input type="checkbox" />
|
||||
* </ui-checkbox>
|
||||
*
|
||||
* <!-- Bullet appearance -->
|
||||
* <ui-checkbox [appearance]="CheckboxAppearance.Bullet">
|
||||
* <input type="checkbox" />
|
||||
* </ui-checkbox>
|
||||
* ```
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ui-checkbox',
|
||||
templateUrl: './checkbox.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
imports: [NgIconComponent],
|
||||
providers: [provideIcons({ isaActionCheck, isaActionMinus })],
|
||||
host: {
|
||||
'[class]': '["ui-checkbox", appearanceClass()]',
|
||||
},
|
||||
})
|
||||
export class CheckboxComponent {
|
||||
/**
|
||||
* Controls the visual appearance of the checkbox.
|
||||
* Can be either "checkbox" (default) or "bullet".
|
||||
*/
|
||||
appearance = input<CheckboxAppearance>(CheckboxAppearance.Checkbox);
|
||||
|
||||
/**
|
||||
* Computes the CSS class to apply based on the current appearance setting.
|
||||
*
|
||||
* @returns A CSS class name string that corresponds to the current appearance
|
||||
*/
|
||||
appearanceClass = computed(() => {
|
||||
return this.appearance() === CheckboxAppearance.Bullet
|
||||
? 'ui-checkbox__bullet'
|
||||
: 'ui-checkbox__checkbox';
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user