@aleph-alpha/ui-library 1.11.0 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +0 -2
  2. package/dist/system/index.d.ts +860 -179
  3. package/dist/system/lib.js +33936 -9729
  4. package/package.json +1 -2
  5. package/src/compositions/UiDataTable/UiDataTable.stories.ts +6 -7
  6. package/src/compositions/UiDataTable/UiDataTableColumnHeader.vue +22 -8
  7. package/src/compositions/UiDataTable/UiDataTablePagination.vue +5 -5
  8. package/src/compositions/UiDatePicker/UiDatePicker.vue +2 -2
  9. package/src/primitives/UiAlert/UiAlert.stories.ts +8 -8
  10. package/src/primitives/UiBadge/UiBadge.stories.ts +9 -9
  11. package/src/primitives/UiButton/UiButton.stories.ts +12 -12
  12. package/src/primitives/UiCalendar/UiCalendar.stories.ts +4 -4
  13. package/src/primitives/UiDropdownMenu/UiDropdownMenu.stories.ts +2 -2
  14. package/src/primitives/UiIcon/UiIcon.stories.ts +59 -13
  15. package/src/primitives/UiIcon/UiIcon.vue +41 -3
  16. package/src/primitives/UiIcon/__tests__/UiIcon.test.ts +33 -4
  17. package/src/primitives/UiIcon/index.ts +1 -0
  18. package/src/primitives/UiIcon/types.ts +24 -5
  19. package/src/primitives/UiIconButton/UiIconButton.stories.ts +36 -36
  20. package/src/primitives/UiKbd/UiKbd.stories.ts +551 -0
  21. package/src/primitives/UiKbd/UiKbd.vue +62 -0
  22. package/src/primitives/UiKbd/UiKbdGroup.vue +16 -0
  23. package/src/primitives/UiKbd/__tests__/UiKbd.test.ts +46 -0
  24. package/src/primitives/UiKbd/index.ts +3 -0
  25. package/src/primitives/UiKbd/types.ts +32 -0
  26. package/src/primitives/UiLabel/UiLabel.stories.ts +192 -0
  27. package/src/primitives/UiLabel/UiLabel.vue +16 -0
  28. package/src/primitives/UiLabel/__tests__/UiLabel.test.ts +43 -0
  29. package/src/primitives/UiLabel/index.ts +2 -0
  30. package/src/primitives/UiLabel/types.ts +16 -0
  31. package/src/primitives/UiListbox/UiListbox.stories.ts +607 -0
  32. package/src/primitives/UiListbox/UiListbox.vue +30 -0
  33. package/src/primitives/UiListbox/UiListboxContent.vue +16 -0
  34. package/src/primitives/UiListbox/UiListboxFilter.vue +16 -0
  35. package/src/primitives/UiListbox/UiListboxGroup.vue +16 -0
  36. package/src/primitives/UiListbox/UiListboxGroupLabel.vue +16 -0
  37. package/src/primitives/UiListbox/UiListboxItem.vue +20 -0
  38. package/src/primitives/UiListbox/UiListboxItemIndicator.vue +16 -0
  39. package/src/primitives/UiListbox/__tests__/UiListbox.test.ts +42 -0
  40. package/src/primitives/UiListbox/index.ts +8 -0
  41. package/src/primitives/UiListbox/types.ts +119 -0
  42. package/src/primitives/UiPopover/index.ts +1 -0
  43. package/src/primitives/UiSeparator/UiSeparator.stories.ts +177 -0
  44. package/src/primitives/UiSeparator/UiSeparator.vue +17 -0
  45. package/src/primitives/UiSeparator/__tests__/UiSeparator.test.ts +34 -0
  46. package/src/primitives/UiSeparator/index.ts +2 -0
  47. package/src/primitives/UiSeparator/types.ts +23 -0
  48. package/src/primitives/UiSkeleton/UiSkeleton.stories.ts +247 -0
  49. package/src/primitives/UiSkeleton/UiSkeleton.vue +24 -0
  50. package/src/primitives/UiSkeleton/__tests__/UiSkeleton.test.ts +47 -0
  51. package/src/primitives/UiSkeleton/index.ts +2 -0
  52. package/src/primitives/UiSkeleton/types.ts +26 -0
  53. package/src/primitives/UiTable/UiTable.stories.ts +2 -2
  54. package/src/primitives/UiTagsInput/UiTagsInput.stories.ts +538 -0
  55. package/src/primitives/UiTagsInput/UiTagsInput.vue +27 -0
  56. package/src/primitives/UiTagsInput/UiTagsInputInput.vue +14 -0
  57. package/src/primitives/UiTagsInput/UiTagsInputItem.vue +16 -0
  58. package/src/primitives/UiTagsInput/UiTagsInputItemDelete.vue +16 -0
  59. package/src/primitives/UiTagsInput/UiTagsInputItemText.vue +14 -0
  60. package/src/primitives/UiTagsInput/__tests__/UiTagsInput.test.ts +44 -0
  61. package/src/primitives/UiTagsInput/index.ts +6 -0
  62. package/src/primitives/UiTagsInput/types.ts +60 -0
  63. package/src/primitives/UiToggle/UiToggle.stories.ts +370 -0
  64. package/src/primitives/UiToggle/UiToggle.vue +28 -0
  65. package/src/primitives/UiToggle/__tests__/UiToggle.test.ts +62 -0
  66. package/src/primitives/UiToggle/index.ts +2 -0
  67. package/src/primitives/UiToggle/types.ts +35 -0
  68. package/src/primitives/UiTooltip/UiTooltip.stories.ts +8 -8
  69. package/src/primitives/index.ts +7 -0
  70. package/src/primitives/shadcn/accordion/AccordionTrigger.vue +5 -4
  71. package/src/primitives/shadcn/calendar/CalendarNextButton.vue +2 -2
  72. package/src/primitives/shadcn/calendar/CalendarPrevButton.vue +2 -2
  73. package/src/primitives/shadcn/checkbox/Checkbox.vue +2 -2
  74. package/src/primitives/shadcn/dropdown-menu/DropdownMenuCheckboxItem.vue +2 -2
  75. package/src/primitives/shadcn/dropdown-menu/DropdownMenuSubTrigger.vue +2 -2
  76. package/src/primitives/shadcn/kbd/Kbd.vue +20 -0
  77. package/src/primitives/shadcn/kbd/KbdGroup.vue +12 -0
  78. package/src/primitives/shadcn/kbd/index.ts +2 -0
  79. package/src/primitives/shadcn/listbox/Listbox.vue +23 -0
  80. package/src/primitives/shadcn/listbox/ListboxContent.vue +26 -0
  81. package/src/primitives/shadcn/listbox/ListboxFilter.vue +30 -0
  82. package/src/primitives/shadcn/listbox/ListboxGroup.vue +26 -0
  83. package/src/primitives/shadcn/listbox/ListboxGroupLabel.vue +26 -0
  84. package/src/primitives/shadcn/listbox/ListboxItem.vue +32 -0
  85. package/src/primitives/shadcn/listbox/ListboxItemIndicator.vue +40 -0
  86. package/src/primitives/shadcn/listbox/index.ts +7 -0
  87. package/src/primitives/shadcn/native-select/NativeSelect.vue +5 -4
  88. package/src/primitives/shadcn/range-calendar/RangeCalendarNextButton.vue +2 -2
  89. package/src/primitives/shadcn/range-calendar/RangeCalendarPrevButton.vue +2 -2
  90. package/src/primitives/shadcn/select/SelectItem.vue +2 -2
  91. package/src/primitives/shadcn/select/SelectScrollDownButton.vue +2 -2
  92. package/src/primitives/shadcn/select/SelectScrollUpButton.vue +2 -2
  93. package/src/primitives/shadcn/select/SelectTrigger.vue +2 -2
  94. package/src/primitives/shadcn/skeleton/Skeleton.vue +10 -0
  95. package/src/primitives/shadcn/skeleton/index.ts +1 -0
  96. package/src/primitives/shadcn/spinner/Spinner.vue +5 -4
  97. package/src/primitives/shadcn/tags-input/TagsInput.vue +33 -0
  98. package/src/primitives/shadcn/tags-input/TagsInputInput.vue +24 -0
  99. package/src/primitives/shadcn/tags-input/TagsInputItem.vue +31 -0
  100. package/src/primitives/shadcn/tags-input/TagsInputItemDelete.vue +46 -0
  101. package/src/primitives/shadcn/tags-input/TagsInputItemText.vue +24 -0
  102. package/src/primitives/shadcn/tags-input/index.ts +5 -0
  103. package/src/primitives/shadcn/toggle/Toggle.vue +34 -0
  104. package/src/primitives/shadcn/toggle/index.ts +27 -0
@@ -0,0 +1,32 @@
1
+ /**
2
+ * A keyboard key indicator component. Use to display keyboard shortcuts,
3
+ * hotkeys, or key combinations in documentation and UI hints.
4
+ *
5
+ * @category Feedback
6
+ * @useCases keyboard shortcut, hotkey display, key combination, command hint
7
+ * @keywords kbd, keyboard, key, shortcut, hotkey, command, keybinding
8
+ * @related UiKbdGroup, UiTooltip
9
+ */
10
+ export interface UiKbdProps {
11
+ /**
12
+ * The size of the keyboard key indicator.
13
+ * @default 'default'
14
+ */
15
+ size?: 'sm' | 'default' | 'lg';
16
+ }
17
+
18
+ /**
19
+ * A container for grouping multiple keyboard keys together. Use to display
20
+ * key combinations like "Ctrl + C" or "Cmd + Shift + P".
21
+ *
22
+ * @category Feedback
23
+ * @useCases key combination, shortcut group, multi-key display
24
+ * @keywords kbd, keyboard, group, combination, shortcut, keys
25
+ * @related UiKbd
26
+ */
27
+ export interface UiKbdGroupProps {
28
+ /**
29
+ * Additional CSS classes to apply to the group container.
30
+ */
31
+ class?: string;
32
+ }
@@ -0,0 +1,192 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import UiLabel from './UiLabel.vue';
3
+ import { UiInput } from '../UiInput';
4
+ import { UiCheckbox } from '../UiCheckbox';
5
+
6
+ /**
7
+ * UiLabel provides accessible text labels for form elements. Use to identify
8
+ * inputs, improve accessibility, and enable click-to-focus behavior via the `for` attribute.
9
+ */
10
+ const meta: Meta<typeof UiLabel> = {
11
+ title: 'Primitives/UiLabel',
12
+ component: UiLabel,
13
+ tags: ['autodocs'],
14
+ argTypes: {
15
+ for: {
16
+ control: 'text',
17
+ description: 'The id of the form element this label is associated with',
18
+ },
19
+ },
20
+ };
21
+
22
+ export default meta;
23
+
24
+ type Story = StoryObj<typeof UiLabel>;
25
+
26
+ const defaultTemplateSource = `<script setup lang="ts">
27
+ import { UiLabel } from '@aleph-alpha/ui-library'
28
+ </script>
29
+
30
+ <template>
31
+ <UiLabel for="email">Email</UiLabel>
32
+ </template>`;
33
+
34
+ /**
35
+ * Default label displaying text content. Use the `for` attribute to associate
36
+ * the label with a form element, enabling click-to-focus accessibility.
37
+ */
38
+ export const Default: Story = {
39
+ render: () => ({
40
+ components: { UiLabel },
41
+ template: `<UiLabel for="email">Email</UiLabel>`,
42
+ }),
43
+ parameters: {
44
+ docs: {
45
+ source: {
46
+ code: defaultTemplateSource,
47
+ },
48
+ },
49
+ },
50
+ };
51
+
52
+ const withInputTemplateSource = `<script setup lang="ts">
53
+ import { UiLabel, UiInput } from '@aleph-alpha/ui-library'
54
+ </script>
55
+
56
+ <template>
57
+ <div class="grid w-full max-w-sm items-center gap-1.5">
58
+ <UiLabel for="email">Email</UiLabel>
59
+ <UiInput id="email" name="email" type="email" placeholder="Enter your email" />
60
+ </div>
61
+ </template>`;
62
+
63
+ /**
64
+ * Label associated with an input field using the `for` attribute.
65
+ * Clicking the label will focus the input.
66
+ */
67
+ export const WithInput: Story = {
68
+ render: () => ({
69
+ components: { UiLabel, UiInput },
70
+ template: `
71
+ <div class="grid w-full max-w-sm items-center gap-1.5">
72
+ <UiLabel for="email">Email</UiLabel>
73
+ <UiInput id="email" name="email" type="email" placeholder="Enter your email" />
74
+ </div>
75
+ `,
76
+ }),
77
+ parameters: {
78
+ docs: {
79
+ source: {
80
+ code: withInputTemplateSource,
81
+ },
82
+ },
83
+ },
84
+ };
85
+
86
+ const withCheckboxTemplateSource = `<script setup lang="ts">
87
+ import { UiLabel, UiCheckbox } from '@aleph-alpha/ui-library'
88
+ </script>
89
+
90
+ <template>
91
+ <div class="flex items-center space-x-2">
92
+ <UiCheckbox id="terms" name="terms" />
93
+ <UiLabel for="terms">Accept terms and conditions</UiLabel>
94
+ </div>
95
+ </template>`;
96
+
97
+ /**
98
+ * Label paired with a checkbox for toggle options like terms acceptance.
99
+ * Position the label after the checkbox for standard form patterns.
100
+ */
101
+ export const WithCheckbox: Story = {
102
+ render: () => ({
103
+ components: { UiLabel, UiCheckbox },
104
+ template: `
105
+ <div class="flex items-center space-x-2">
106
+ <UiCheckbox id="terms" name="terms" />
107
+ <UiLabel for="terms">Accept terms and conditions</UiLabel>
108
+ </div>
109
+ `,
110
+ }),
111
+ parameters: {
112
+ docs: {
113
+ source: {
114
+ code: withCheckboxTemplateSource,
115
+ },
116
+ },
117
+ },
118
+ };
119
+
120
+ const disabledStateTemplateSource = `<script setup lang="ts">
121
+ import { UiLabel, UiInput } from '@aleph-alpha/ui-library'
122
+ </script>
123
+
124
+ <template>
125
+ <div class="grid w-full max-w-sm items-center gap-1.5" data-disabled="true">
126
+ <UiLabel for="disabled-input">Disabled Field</UiLabel>
127
+ <UiInput id="disabled-input" name="disabled-input" disabled placeholder="Disabled" />
128
+ </div>
129
+ </template>`;
130
+
131
+ /**
132
+ * Label with a disabled input field. The label automatically applies muted
133
+ * styling when the parent container has `data-disabled="true"` attribute.
134
+ */
135
+ export const DisabledState: Story = {
136
+ render: () => ({
137
+ components: { UiLabel, UiInput },
138
+ template: `
139
+ <div class="grid w-full max-w-sm items-center gap-1.5" data-disabled="true">
140
+ <UiLabel for="disabled-input">Disabled Field</UiLabel>
141
+ <UiInput id="disabled-input" name="disabled-input" disabled placeholder="Disabled" />
142
+ </div>
143
+ `,
144
+ }),
145
+ parameters: {
146
+ docs: {
147
+ source: {
148
+ code: disabledStateTemplateSource,
149
+ },
150
+ },
151
+ },
152
+ };
153
+
154
+ const requiredFieldTemplateSource = `<script setup lang="ts">
155
+ import { UiLabel, UiInput } from '@aleph-alpha/ui-library'
156
+ </script>
157
+
158
+ <template>
159
+ <div class="grid w-full max-w-sm items-center gap-1.5">
160
+ <UiLabel for="required-input">
161
+ Username
162
+ <span class="text-destructive">*</span>
163
+ </UiLabel>
164
+ <UiInput id="required-input" name="required-input" required placeholder="Enter username" />
165
+ </div>
166
+ </template>`;
167
+
168
+ /**
169
+ * Label for a required field with a red asterisk indicator. Use slot content
170
+ * to add custom elements like required markers alongside the label text.
171
+ */
172
+ export const RequiredField: Story = {
173
+ render: () => ({
174
+ components: { UiLabel, UiInput },
175
+ template: `
176
+ <div class="grid w-full max-w-sm items-center gap-1.5">
177
+ <UiLabel for="required-input">
178
+ Username
179
+ <span class="text-destructive">*</span>
180
+ </UiLabel>
181
+ <UiInput id="required-input" name="required-input" required placeholder="Enter username" />
182
+ </div>
183
+ `,
184
+ }),
185
+ parameters: {
186
+ docs: {
187
+ source: {
188
+ code: requiredFieldTemplateSource,
189
+ },
190
+ },
191
+ },
192
+ };
@@ -0,0 +1,16 @@
1
+ <script setup lang="ts">
2
+ import { Label as ShadcnLabel } from '@/primitives/shadcn/label';
3
+ import { UiLabelProps } from './types';
4
+
5
+ defineOptions({
6
+ name: 'UiLabel',
7
+ });
8
+
9
+ const props = defineProps<UiLabelProps>();
10
+ </script>
11
+
12
+ <template>
13
+ <ShadcnLabel :for="props.for">
14
+ <slot />
15
+ </ShadcnLabel>
16
+ </template>
@@ -0,0 +1,43 @@
1
+ import { render } from '@testing-library/vue';
2
+ import { describe, expect, test } from 'vitest';
3
+ import UiLabel from '../UiLabel.vue';
4
+
5
+ describe('UiLabel', () => {
6
+ test('renders label with text content', () => {
7
+ const labelText = 'Email';
8
+ const { getByText } = render(UiLabel, {
9
+ slots: { default: labelText },
10
+ });
11
+ expect(getByText(labelText)).toBeInTheDocument();
12
+ });
13
+
14
+ test('renders label with for attribute', () => {
15
+ const forValue = 'email-input';
16
+ const { container } = render(UiLabel, {
17
+ props: { for: forValue },
18
+ slots: { default: 'Email' },
19
+ });
20
+ const label = container.querySelector('label');
21
+ expect(label).toHaveAttribute('for', forValue);
22
+ });
23
+
24
+ test('applies custom class', () => {
25
+ const customClass = 'custom-label-class';
26
+ const { container } = render(UiLabel, {
27
+ props: { class: customClass },
28
+ slots: { default: 'Email' },
29
+ });
30
+ const label = container.querySelector('label');
31
+ expect(label).toHaveClass(customClass);
32
+ });
33
+
34
+ test('renders slot content', () => {
35
+ const { getByText, getByTestId } = render(UiLabel, {
36
+ slots: {
37
+ default: '<span data-testid="slot-content">Custom Content</span>',
38
+ },
39
+ });
40
+ expect(getByTestId('slot-content')).toBeInTheDocument();
41
+ expect(getByText('Custom Content')).toBeInTheDocument();
42
+ });
43
+ });
@@ -0,0 +1,2 @@
1
+ export { default as UiLabel } from './UiLabel.vue';
2
+ export type * from './types';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * A text label for form elements. Use to identify form inputs, provide
3
+ * context, and improve accessibility by associating labels with controls.
4
+ *
5
+ * @category Form Inputs
6
+ * @useCases form label, input label, field label, accessibility label
7
+ * @keywords label, form, input, text, field, accessibility, a11y
8
+ * @related UiInput, UiCheckbox, UiField, UiRadioGroup
9
+ */
10
+ export interface UiLabelProps {
11
+ /**
12
+ * The id of the form element that this label is associated with.
13
+ * When provided, clicking the label will focus the associated element.
14
+ */
15
+ for: string;
16
+ }