Merged PR 2005: feat(shared-filter, ui-switch): add switch filter menu button for inline toggle filters

feat(shared-filter, ui-switch): add switch filter menu button for inline toggle filters

Add a new SwitchMenuButtonComponent that renders filter inputs as compact toggle switches
without an overlay menu. This provides a more streamlined UX for simple boolean/single-option
filters directly in the controls panel.

Key changes:
- Create new switch-menu module with button component and tests
- Extend FilterControlsPanelComponent to accept switchFilters input array
- Rename IconSwitchComponent to SwitchComponent for consistency
- Update filter actions to use 'target' property instead of 'group' for filtering
- Add isEmptyFilterInput support for NumberRange inputs
- Export switch-menu module from shared/filter public API

The switch button auto-commits on toggle and uses the checkbox filter model internally,
allowing simple configuration like:

switchFilters = [{ filter: stockFilter, icon: 'isaFiliale' }]

This implementation follows the existing filter architecture patterns and maintains
full accessibility support through ARIA attributes and keyboard navigation.

Ref: #5427
This commit is contained in:
Nino Righi
2025-11-05 15:31:13 +00:00
committed by Lorenz Hilpert
parent a52928d212
commit eb0d96698c
33 changed files with 1211 additions and 536 deletions

View File

@@ -20,6 +20,7 @@
@import "../../../libs/ui/skeleton-loader/src/skeleton-loader.scss";
@import "../../../libs/ui/tooltip/src/tooltip.scss";
@import "../../../libs/ui/label/src/label.scss";
@import "../../../libs/ui/switch/src/switch.scss";
.input-control {
@apply rounded border border-solid border-[#AEB7C1] px-4 py-[1.125rem] outline-none;

View File

@@ -0,0 +1,104 @@
import { argsToTemplate, type Meta, type StoryObj } from '@storybook/angular';
import { IconSwitchComponent, IconSwitchColor } from '@isa/ui/switch';
import { provideIcons } from '@ng-icons/core';
import { isaFiliale, IsaIcons, isaNavigationDashboard } from '@isa/icons';
type IconSwitchComponentInputs = {
icon: string;
checked: boolean;
color: IconSwitchColor;
disabled: boolean;
};
const meta: Meta<IconSwitchComponentInputs> = {
component: IconSwitchComponent,
title: 'ui/switch/IconSwitch',
decorators: [
(story) => ({
...story(),
applicationConfig: {
providers: [provideIcons(IsaIcons)],
},
}),
],
argTypes: {
icon: {
control: { type: 'select' },
options: Object.keys(IsaIcons),
description: 'The name of the icon to display in the switch',
},
checked: {
control: 'boolean',
description: 'Whether the switch is checked (on) or not (off)',
},
color: {
control: { type: 'select' },
options: Object.values(IconSwitchColor),
description: 'Determines the switch color theme',
},
disabled: {
control: 'boolean',
description: 'Disables the switch when true',
},
},
args: {
icon: 'isaFiliale',
checked: false,
color: 'primary',
disabled: false,
},
render: (args) => ({
props: args,
template: `<ui-icon-switch ${argsToTemplate(args)}></ui-icon-switch>`,
}),
};
export default meta;
type Story = StoryObj<IconSwitchComponent>;
export const Default: Story = {
args: {},
};
export const Enabled: Story = {
args: {
checked: true,
},
parameters: {
docs: {
description: {
story:
'The switch in its enabled/checked state with the primary color theme.',
},
},
},
};
export const Disabled: Story = {
args: {
checked: false,
disabled: true,
},
parameters: {
docs: {
description: {
story:
'The switch in a disabled state. User interactions are prevented.',
},
},
},
};
export const EnabledAndDisabled: Story = {
args: {
checked: true,
disabled: true,
},
parameters: {
docs: {
description: {
story: 'The switch in both enabled and disabled states simultaneously.',
},
},
},
};