feat: add data-testid attribute
This commit is contained in:
@@ -1,112 +0,0 @@
|
|||||||
<script module lang="ts">
|
|
||||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
||||||
import CheckboxFilter from './CheckboxFilter.svelte';
|
|
||||||
|
|
||||||
const { Story } = defineMeta({
|
|
||||||
title: 'Shared/UI/CheckboxFilter',
|
|
||||||
component: CheckboxFilter,
|
|
||||||
tags: ['autodocs'],
|
|
||||||
argTypes: {
|
|
||||||
displayedLabel: { control: 'text' },
|
|
||||||
// filter is complex, use stories for examples
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import WithFilterDecorator from './WithFilterDecorator.svelte';
|
|
||||||
import type { Property } from '$shared/lib';
|
|
||||||
|
|
||||||
// Define initial values for each story
|
|
||||||
const basicProperties: Property[] = [
|
|
||||||
{ id: 'serif', name: 'Serif', selected: false },
|
|
||||||
{ id: 'sans-serif', name: 'Sans-serif', selected: false },
|
|
||||||
{ id: 'display', name: 'Display', selected: false },
|
|
||||||
{ id: 'handwriting', name: 'Handwriting', selected: false },
|
|
||||||
{ id: 'monospace', name: 'Monospace', selected: false },
|
|
||||||
];
|
|
||||||
|
|
||||||
const withSelectedProperties: Property[] = [
|
|
||||||
{ id: 'serif', name: 'Serif', selected: true },
|
|
||||||
{ id: 'sans-serif', name: 'Sans-serif', selected: false },
|
|
||||||
{ id: 'display', name: 'Display', selected: true },
|
|
||||||
{ id: 'handwriting', name: 'Handwriting', selected: false },
|
|
||||||
];
|
|
||||||
|
|
||||||
const allSelectedProperties: Property[] = [
|
|
||||||
{ id: 'serif', name: 'Serif', selected: true },
|
|
||||||
{ id: 'sans-serif', name: 'Sans-serif', selected: true },
|
|
||||||
{ id: 'display', name: 'Display', selected: true },
|
|
||||||
{ id: 'handwriting', name: 'Handwriting', selected: true },
|
|
||||||
];
|
|
||||||
|
|
||||||
const emptyProperties: Property[] = [];
|
|
||||||
|
|
||||||
const singleProperty: Property[] = [{ id: 'serif', name: 'Serif', selected: false }];
|
|
||||||
|
|
||||||
const multipleProperties: Property[] = [
|
|
||||||
{ id: 'thin', name: 'Thin', selected: false },
|
|
||||||
{ id: 'extra-light', name: 'Extra Light', selected: false },
|
|
||||||
{ id: 'light', name: 'Light', selected: false },
|
|
||||||
{ id: 'regular', name: 'Regular', selected: false },
|
|
||||||
{ id: 'medium', name: 'Medium', selected: false },
|
|
||||||
{ id: 'semi-bold', name: 'Semi Bold', selected: false },
|
|
||||||
{ id: 'bold', name: 'Bold', selected: false },
|
|
||||||
{ id: 'extra-bold', name: 'Extra Bold', selected: false },
|
|
||||||
{ id: 'black', name: 'Black', selected: false },
|
|
||||||
];
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Basic usage - multiple properties -->
|
|
||||||
<Story name="Basic Usage" args={{ displayedLabel: 'Font Category' }}>
|
|
||||||
<WithFilterDecorator initialValues={basicProperties}>
|
|
||||||
{#snippet children({ filter })}
|
|
||||||
<CheckboxFilter displayedLabel={'Font Category'} {filter} />
|
|
||||||
{/snippet}
|
|
||||||
</WithFilterDecorator>
|
|
||||||
</Story>
|
|
||||||
|
|
||||||
<!-- With some items pre-selected -->
|
|
||||||
<Story name="With Selected Items" args={{ displayedLabel: 'Font Category' }}>
|
|
||||||
<WithFilterDecorator initialValues={withSelectedProperties}>
|
|
||||||
{#snippet children({ filter })}
|
|
||||||
<CheckboxFilter displayedLabel={'Font Category'} {filter} />
|
|
||||||
{/snippet}
|
|
||||||
</WithFilterDecorator>
|
|
||||||
</Story>
|
|
||||||
|
|
||||||
<!-- All items selected -->
|
|
||||||
<Story name="All Selected" args={{ displayedLabel: 'Font Category' }}>
|
|
||||||
<WithFilterDecorator initialValues={allSelectedProperties}>
|
|
||||||
{#snippet children({ filter })}
|
|
||||||
<CheckboxFilter displayedLabel={'Font Category'} {filter} />
|
|
||||||
{/snippet}
|
|
||||||
</WithFilterDecorator>
|
|
||||||
</Story>
|
|
||||||
|
|
||||||
<!-- Empty filter (no properties) -->
|
|
||||||
<Story name="Empty Filter" args={{ displayedLabel: 'Empty Filter' }}>
|
|
||||||
<WithFilterDecorator initialValues={emptyProperties}>
|
|
||||||
{#snippet children({ filter })}
|
|
||||||
<CheckboxFilter displayedLabel={'Empty Filter'} {filter} />
|
|
||||||
{/snippet}
|
|
||||||
</WithFilterDecorator>
|
|
||||||
</Story>
|
|
||||||
|
|
||||||
<!-- Single property -->
|
|
||||||
<Story name="Single Property" args={{ displayedLabel: 'Font Category' }}>
|
|
||||||
<WithFilterDecorator initialValues={singleProperty}>
|
|
||||||
{#snippet children({ filter })}
|
|
||||||
<CheckboxFilter displayedLabel={'Font Category'} {filter} />
|
|
||||||
{/snippet}
|
|
||||||
</WithFilterDecorator>
|
|
||||||
</Story>
|
|
||||||
|
|
||||||
<!-- Large number of properties -->
|
|
||||||
<Story name="Multiple Properties" args={{ displayedLabel: 'Font Weight' }}>
|
|
||||||
<WithFilterDecorator initialValues={multipleProperties}>
|
|
||||||
{#snippet children({ filter })}
|
|
||||||
<CheckboxFilter displayedLabel={'Font Weight'} {filter} />
|
|
||||||
{/snippet}
|
|
||||||
</WithFilterDecorator>
|
|
||||||
</Story>
|
|
||||||
@@ -86,6 +86,7 @@ const hasSelection = $derived(selectedCount > 0);
|
|||||||
{#if hasSelection}
|
{#if hasSelection}
|
||||||
<Badge
|
<Badge
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
|
data-testid="badge"
|
||||||
class="mr-auto h-5 min-w-5 px-1.5 text-xs font-medium tabular-nums"
|
class="mr-auto h-5 min-w-5 px-1.5 text-xs font-medium tabular-nums"
|
||||||
>
|
>
|
||||||
{selectedCount}
|
{selectedCount}
|
||||||
@@ -94,6 +95,7 @@ const hasSelection = $derived(selectedCount > 0);
|
|||||||
|
|
||||||
<!-- Chevron rotates based on open state for visual feedback -->
|
<!-- Chevron rotates based on open state for visual feedback -->
|
||||||
<div
|
<div
|
||||||
|
data-testid="chevron"
|
||||||
class="shrink-0 transition-transform duration-200 ease-out"
|
class="shrink-0 transition-transform duration-200 ease-out"
|
||||||
style:transform={isOpen ? 'rotate(0deg)' : 'rotate(-90deg)'}
|
style:transform={isOpen ? 'rotate(0deg)' : 'rotate(-90deg)'}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import type { Snippet } from 'svelte';
|
|
||||||
import { createFilter } from '$shared/lib';
|
|
||||||
import type { Property, Filter } from '$shared/lib';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Props for the WithFilter decorator component.
|
|
||||||
*/
|
|
||||||
let {
|
|
||||||
children,
|
|
||||||
/** Initial properties to create the filter from */
|
|
||||||
initialValues,
|
|
||||||
}: {
|
|
||||||
children: Snippet<[props: { filter: Filter }]>;
|
|
||||||
initialValues: Property[];
|
|
||||||
} = $props();
|
|
||||||
|
|
||||||
// Create filter inside component body so Svelte 5 runes work correctly
|
|
||||||
const filter = createFilter({ properties: initialValues });
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{@render children({ filter })}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
<script module lang="ts">
|
|
||||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
||||||
import ComboControl from './ComboControl.svelte';
|
|
||||||
|
|
||||||
const { Story } = defineMeta({
|
|
||||||
title: 'Shared/UI/ComboControl',
|
|
||||||
component: ComboControl,
|
|
||||||
tags: ['autodocs'],
|
|
||||||
argTypes: {
|
|
||||||
controlLabel: { control: 'text' },
|
|
||||||
increaseLabel: { control: 'text' },
|
|
||||||
decreaseLabel: { control: 'text' },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import WithControlDecorator from './WithControlDecorator.svelte';
|
|
||||||
|
|
||||||
// Define initial values for each story
|
|
||||||
const fontSizeInitial = { value: 16, min: 8, max: 100, step: 1 };
|
|
||||||
|
|
||||||
const letterSpacingInitial = { value: 0, min: -2, max: 4, step: 0.05 };
|
|
||||||
|
|
||||||
const atMinimumInitial = { value: 10, min: 10, max: 100, step: 1 };
|
|
||||||
|
|
||||||
const atMaximumInitial = { value: 100, min: 10, max: 100, step: 1 };
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Story name="Integer Step" args={{ controlLabel: 'Font size' }}>
|
|
||||||
<WithControlDecorator initialValues={fontSizeInitial}>
|
|
||||||
{#snippet children({ control })}
|
|
||||||
<ComboControl controlLabel={'Font size'} {control} />
|
|
||||||
{/snippet}
|
|
||||||
</WithControlDecorator>
|
|
||||||
</Story>
|
|
||||||
|
|
||||||
<Story name="Decimal Step" args={{ controlLabel: 'Letter spacing' }}>
|
|
||||||
<WithControlDecorator initialValues={letterSpacingInitial}>
|
|
||||||
{#snippet children({ control })}
|
|
||||||
<ComboControl controlLabel={'Letter spacing'} {control} />
|
|
||||||
{/snippet}
|
|
||||||
</WithControlDecorator>
|
|
||||||
</Story>
|
|
||||||
|
|
||||||
<Story
|
|
||||||
name="At Minimum"
|
|
||||||
args={{ controlLabel: 'Font size', increaseLabel: 'Increase', decreaseLabel: 'Decrease' }}
|
|
||||||
>
|
|
||||||
<WithControlDecorator initialValues={atMinimumInitial}>
|
|
||||||
{#snippet children({ control })}
|
|
||||||
<ComboControl
|
|
||||||
controlLabel={'Font size'}
|
|
||||||
increaseLabel={'Increase'}
|
|
||||||
decreaseLabel={'Decrease'}
|
|
||||||
{control}
|
|
||||||
/>
|
|
||||||
{/snippet}
|
|
||||||
</WithControlDecorator>
|
|
||||||
</Story>
|
|
||||||
|
|
||||||
<Story
|
|
||||||
name="At Maximum"
|
|
||||||
args={{ controlLabel: 'Font size', increaseLabel: 'Increase', decreaseLabel: 'Decrease' }}
|
|
||||||
>
|
|
||||||
<WithControlDecorator initialValues={atMaximumInitial}>
|
|
||||||
{#snippet children({ control })}
|
|
||||||
<ComboControl
|
|
||||||
controlLabel={'Font size'}
|
|
||||||
increaseLabel={'Increase'}
|
|
||||||
decreaseLabel={'Decrease'}
|
|
||||||
{control}
|
|
||||||
/>
|
|
||||||
{/snippet}
|
|
||||||
</WithControlDecorator>
|
|
||||||
</Story>
|
|
||||||
Reference in New Issue
Block a user