@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aleph-alpha/ui-library",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "dist/system/lib.js",
@@ -70,7 +70,6 @@
70
70
  "vue-tsc": "^2.2.12",
71
71
  "wait-on": "9.0.3",
72
72
  "@aleph-alpha/config-css": "0.20.0",
73
- "@aleph-alpha/ds-icons": "0.11.0",
74
73
  "@aleph-alpha/eslint-config-frontend": "0.4.0",
75
74
  "@aleph-alpha/prettier-config-frontend": "0.4.0",
76
75
  "@aleph-alpha/tsconfig-frontend": "0.5.0"
@@ -1,7 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
2
  import type { ColumnDef } from '@tanstack/vue-table';
3
3
  import { computed, h, ref } from 'vue';
4
- import { Ban, MoreHorizontal } from 'lucide-vue-next';
5
4
  import {
6
5
  UiDataTable,
7
6
  UiDataTableColumnHeader,
@@ -10,6 +9,7 @@ import {
10
9
  } from './index';
11
10
  import { UiCheckbox } from '@/primitives/UiCheckbox';
12
11
  import { UiButton } from '@/primitives/UiButton';
12
+ import { UiIcon } from '@/primitives/UiIcon';
13
13
  import {
14
14
  UiDropdownMenu,
15
15
  UiDropdownMenuContent,
@@ -930,8 +930,7 @@ export const WithCustomEmptyText: Story = {
930
930
  };
931
931
 
932
932
  const withCustomEmptySlotTemplateSource = `<script setup lang="ts">
933
- import { UiDataTable } from '@aleph-alpha/ui-library';
934
- import { Ban } from 'lucide-vue-next';
933
+ import { UiDataTable, UiIcon } from '@aleph-alpha/ui-library';
935
934
  import type { ColumnDef } from '@tanstack/vue-table';
936
935
 
937
936
  interface Payment {
@@ -954,7 +953,7 @@ const columns: ColumnDef<Payment>[] = [
954
953
  <UiDataTable :data="data" :columns="columns">
955
954
  <template #empty>
956
955
  <div class="flex flex-col items-center gap-2 text-muted-foreground">
957
- <Ban class="h-8 w-8" />
956
+ <UiIcon name="ban" :size="32" />
958
957
  <p>No data available for this view.</p>
959
958
  </div>
960
959
  </template>
@@ -978,7 +977,7 @@ export const WithCustomEmptySlot: Story = {
978
977
  },
979
978
  },
980
979
  render: (args) => ({
981
- components: { UiDataTable, Ban },
980
+ components: { UiDataTable, UiIcon },
982
981
  setup() {
983
982
  return { args };
984
983
  },
@@ -986,7 +985,7 @@ export const WithCustomEmptySlot: Story = {
986
985
  <UiDataTable v-bind="args">
987
986
  <template #empty>
988
987
  <div class="flex flex-col items-center gap-2 text-muted-foreground">
989
- <Ban class="h-8 w-8" />
988
+ <UiIcon name="ban" :size="32" />
990
989
  <p>No data available for this view.</p>
991
990
  </div>
992
991
  </template>
@@ -1285,7 +1284,7 @@ const rowActionsColumns: ColumnDef<Payment>[] = [
1285
1284
  h(UiDropdownMenuTrigger, { asChild: true }, () =>
1286
1285
  h(UiButton, { variant: 'ghost', size: 'icon', class: 'h-8 w-8' }, () => [
1287
1286
  h('span', { class: 'sr-only' }, 'Open menu'),
1288
- h(MoreHorizontal, { class: 'h-4 w-4' }),
1287
+ h(UiIcon, { name: 'more-horizontal', size: 16 }),
1289
1288
  ]),
1290
1289
  ),
1291
1290
  h(UiDropdownMenuContent, { align: 'end' }, () => [
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts" generic="TData, TValue">
2
2
  import type { Column } from '@tanstack/vue-table';
3
- import { ArrowDown, ArrowUp, ChevronsUpDown } from 'lucide-vue-next';
4
3
  import { UiButton } from '@/primitives/UiButton';
4
+ import { UiIcon } from '@/primitives/UiIcon';
5
5
  import {
6
6
  UiDropdownMenu,
7
7
  UiDropdownMenuContent,
@@ -65,26 +65,40 @@
65
65
  :aria-label="sortLabel"
66
66
  >
67
67
  <span>{{ title }}</span>
68
- <ArrowDown
68
+ <UiIcon
69
69
  v-if="column.getIsSorted() === 'desc'"
70
- class="ml-2 h-4 w-4"
70
+ name="arrow-down"
71
+ :size="16"
72
+ class="ml-2"
71
73
  aria-hidden="true"
72
74
  />
73
- <ArrowUp
75
+ <UiIcon
74
76
  v-else-if="column.getIsSorted() === 'asc'"
75
- class="ml-2 h-4 w-4"
77
+ name="arrow-up"
78
+ :size="16"
79
+ class="ml-2"
76
80
  aria-hidden="true"
77
81
  />
78
- <ChevronsUpDown v-else class="ml-2 h-4 w-4" aria-hidden="true" />
82
+ <UiIcon v-else name="chevrons-up-down" :size="16" class="ml-2" aria-hidden="true" />
79
83
  </UiButton>
80
84
  </UiDropdownMenuTrigger>
81
85
  <UiDropdownMenuContent align="start">
82
86
  <UiDropdownMenuItem @click="column.toggleSorting(false)">
83
- <ArrowUp class="mr-2 h-3.5 w-3.5 text-muted-foreground/70" aria-hidden="true" />
87
+ <UiIcon
88
+ name="arrow-up"
89
+ :size="14"
90
+ class="mr-2 text-muted-foreground/70"
91
+ aria-hidden="true"
92
+ />
84
93
  {{ labels.sortAscending }}
85
94
  </UiDropdownMenuItem>
86
95
  <UiDropdownMenuItem @click="column.toggleSorting(true)">
87
- <ArrowDown class="mr-2 h-3.5 w-3.5 text-muted-foreground/70" aria-hidden="true" />
96
+ <UiIcon
97
+ name="arrow-down"
98
+ :size="14"
99
+ class="mr-2 text-muted-foreground/70"
100
+ aria-hidden="true"
101
+ />
88
102
  {{ labels.sortDescending }}
89
103
  </UiDropdownMenuItem>
90
104
  </UiDropdownMenuContent>
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts" generic="TData">
2
2
  import type { Table } from '@tanstack/vue-table';
3
- import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-vue-next';
4
3
  import { UiButton } from '@/primitives/UiButton';
4
+ import { UiIcon } from '@/primitives/UiIcon';
5
5
  import {
6
6
  UiDropdownMenu,
7
7
  UiDropdownMenuContent,
@@ -109,7 +109,7 @@
109
109
  @click="table.setPageIndex(0)"
110
110
  >
111
111
  <span class="sr-only">{{ labels.goToFirstPage }}</span>
112
- <ChevronsLeft class="h-4 w-4" aria-hidden="true" />
112
+ <UiIcon name="chevrons-left" :size="16" aria-hidden="true" />
113
113
  </UiButton>
114
114
  <UiButton
115
115
  variant="outline"
@@ -119,7 +119,7 @@
119
119
  @click="table.previousPage()"
120
120
  >
121
121
  <span class="sr-only">{{ labels.goToPreviousPage }}</span>
122
- <ChevronLeft class="h-4 w-4" aria-hidden="true" />
122
+ <UiIcon name="chevron-left" :size="16" aria-hidden="true" />
123
123
  </UiButton>
124
124
  <UiButton
125
125
  variant="outline"
@@ -129,7 +129,7 @@
129
129
  @click="table.nextPage()"
130
130
  >
131
131
  <span class="sr-only">{{ labels.goToNextPage }}</span>
132
- <ChevronRight class="h-4 w-4" aria-hidden="true" />
132
+ <UiIcon name="chevron-right" :size="16" aria-hidden="true" />
133
133
  </UiButton>
134
134
  <UiButton
135
135
  variant="outline"
@@ -139,7 +139,7 @@
139
139
  @click="table.setPageIndex(table.getPageCount() - 1)"
140
140
  >
141
141
  <span class="sr-only">{{ labels.goToLastPage }}</span>
142
- <ChevronsRight class="h-4 w-4" aria-hidden="true" />
142
+ <UiIcon name="chevrons-right" :size="16" aria-hidden="true" />
143
143
  </UiButton>
144
144
  </div>
145
145
  </div>
@@ -1,10 +1,10 @@
1
1
  <script setup lang="ts">
2
- import { Calendar } from 'lucide-vue-next';
3
2
  import { DateFormatter, getLocalTimeZone } from '@internationalized/date';
4
3
  import type { DateRange, DateValue } from 'reka-ui';
5
4
  import { computed, defineAsyncComponent, ref } from 'vue';
6
5
  import { cn } from '@/lib/utils';
7
6
  import { UiButton } from '@/primitives/UiButton';
7
+ import { UiIcon } from '@/primitives/UiIcon';
8
8
  import { UiPopover, UiPopoverContent, UiPopoverTrigger } from '@/primitives/UiPopover';
9
9
  import type { UiDatePickerProps } from './types';
10
10
 
@@ -141,7 +141,7 @@
141
141
  :disabled="props.disabled"
142
142
  :aria-label="props.ariaLabel"
143
143
  >
144
- <Calendar class="mr-2 size-4 shrink-0" />
144
+ <UiIcon name="calendar" :size="16" class="mr-2 shrink-0" />
145
145
  <span class="truncate">{{ displayValue }}</span>
146
146
  </UiButton>
147
147
  </UiPopoverTrigger>
@@ -29,7 +29,7 @@ import { UiAlert, UiAlertDescription, UiAlertTitle, UiIcon } from '@aleph-alpha/
29
29
 
30
30
  <template>
31
31
  <UiAlert>
32
- <UiIcon icon="i-material-symbols-check-circle" class="size-4" />
32
+ <UiIcon name="circle-check" :size="16" />
33
33
  <UiAlertTitle>Success! Your changes have been saved</UiAlertTitle>
34
34
  <UiAlertDescription>
35
35
  This is an alert with icon, title and description.
@@ -53,7 +53,7 @@ export const Default: Story = {
53
53
  },
54
54
  template: `
55
55
  <UiAlert :variant="args.variant">
56
- <UiIcon icon="i-material-symbols-check-circle" class="size-4" />
56
+ <UiIcon name="circle-check" :size="16" />
57
57
  <UiAlertTitle>Success! Your changes have been saved</UiAlertTitle>
58
58
  <UiAlertDescription>
59
59
  This is an alert with icon, title and description.
@@ -76,7 +76,7 @@ import { UiAlert, UiAlertDescription, UiAlertTitle, UiIcon } from '@aleph-alpha/
76
76
 
77
77
  <template>
78
78
  <UiAlert variant="destructive">
79
- <UiIcon icon="i-material-symbols-error" class="size-4" />
79
+ <UiIcon name="circle-x" :size="16" />
80
80
  <UiAlertTitle>Unable to process your payment.</UiAlertTitle>
81
81
  <UiAlertDescription>
82
82
  <p>Please verify your billing information and try again.</p>
@@ -102,7 +102,7 @@ export const Destructive: Story = {
102
102
  },
103
103
  template: `
104
104
  <UiAlert variant="destructive">
105
- <UiIcon icon="i-material-symbols-error" class="size-4" />
105
+ <UiIcon name="circle-x" :size="16" />
106
106
  <UiAlertTitle>Unable to process your payment.</UiAlertTitle>
107
107
  <UiAlertDescription>
108
108
  <p>Please verify your billing information and try again.</p>
@@ -131,7 +131,7 @@ import { UiAlert, UiAlertDescription, UiAlertTitle, UiIcon } from '@aleph-alpha/
131
131
  <template>
132
132
  <div class="flex flex-col gap-4">
133
133
  <UiAlert>
134
- <UiIcon icon="i-material-symbols-check-circle" class="size-4" />
134
+ <UiIcon name="circle-check" :size="16" />
135
135
  <UiAlertTitle>Success! Your changes have been saved</UiAlertTitle>
136
136
  <UiAlertDescription>
137
137
  This is an alert with icon, title and description.
@@ -139,7 +139,7 @@ import { UiAlert, UiAlertDescription, UiAlertTitle, UiIcon } from '@aleph-alpha/
139
139
  </UiAlert>
140
140
 
141
141
  <UiAlert variant="destructive">
142
- <UiIcon icon="i-material-symbols-error" class="size-4" />
142
+ <UiIcon name="circle-x" :size="16" />
143
143
  <UiAlertTitle>Unable to process your payment.</UiAlertTitle>
144
144
  <UiAlertDescription>
145
145
  <p>Please verify your billing information and try again.</p>
@@ -167,7 +167,7 @@ export const AllVariants: Story = {
167
167
  template: `
168
168
  <div class="flex flex-col gap-4">
169
169
  <UiAlert>
170
- <UiIcon icon="i-material-symbols-check-circle" class="size-4" />
170
+ <UiIcon name="circle-check" :size="16" />
171
171
  <UiAlertTitle>Success! Your changes have been saved</UiAlertTitle>
172
172
  <UiAlertDescription>
173
173
  This is an alert with icon, title and description.
@@ -175,7 +175,7 @@ export const AllVariants: Story = {
175
175
  </UiAlert>
176
176
 
177
177
  <UiAlert variant="destructive">
178
- <UiIcon icon="i-material-symbols-error" class="size-4" />
178
+ <UiIcon name="circle-x" :size="16" />
179
179
  <UiAlertTitle>Unable to process your payment.</UiAlertTitle>
180
180
  <UiAlertDescription>
181
181
  <p>Please verify your billing information and try again.</p>
@@ -5,17 +5,17 @@ import { UiIcon } from '../UiIcon';
5
5
 
6
6
  const InfoIcon = {
7
7
  components: { UiIcon },
8
- template: '<UiIcon icon="i-material-symbols-info" class="size-4" />',
8
+ template: '<UiIcon name="info" :size="16" />',
9
9
  };
10
10
 
11
11
  const XIcon = {
12
12
  components: { UiIcon },
13
- template: '<UiIcon icon="i-material-symbols-close" class="size-4" />',
13
+ template: '<UiIcon name="x" :size="16" />',
14
14
  };
15
15
 
16
16
  const CheckIcon = {
17
17
  components: { UiIcon },
18
- template: '<UiIcon icon="i-material-symbols-check" class="size-4" />',
18
+ template: '<UiIcon name="check" :size="16" />',
19
19
  };
20
20
 
21
21
  const meta: Meta<typeof UiBadge> = {
@@ -154,7 +154,7 @@ import { UiBadge, UiIcon } from '@aleph-alpha/ui-library'
154
154
 
155
155
  const InfoIcon = {
156
156
  components: { UiIcon },
157
- template: '<UiIcon icon="i-material-symbols-info" class="size-4" />',
157
+ template: '<UiIcon name="info" :size="16" />',
158
158
  }
159
159
  </script>
160
160
 
@@ -187,7 +187,7 @@ import { UiBadge, UiIcon } from '@aleph-alpha/ui-library'
187
187
 
188
188
  const XIcon = {
189
189
  components: { UiIcon },
190
- template: '<UiIcon icon="i-material-symbols-close" class="size-4" />',
190
+ template: '<UiIcon name="x" :size="16" />',
191
191
  }
192
192
  </script>
193
193
 
@@ -220,12 +220,12 @@ import { UiBadge, UiIcon } from '@aleph-alpha/ui-library'
220
220
 
221
221
  const CheckIcon = {
222
222
  components: { UiIcon },
223
- template: '<UiIcon icon="i-material-symbols-check" class="size-4" />',
223
+ template: '<UiIcon name="check" :size="16" />',
224
224
  }
225
225
 
226
226
  const XIcon = {
227
227
  components: { UiIcon },
228
- template: '<UiIcon icon="i-material-symbols-close" class="size-4" />',
228
+ template: '<UiIcon name="x" :size="16" />',
229
229
  }
230
230
  </script>
231
231
 
@@ -261,7 +261,7 @@ import { UiBadge, UiIcon } from '@aleph-alpha/ui-library'
261
261
 
262
262
  <template>
263
263
  <UiBadge variant="secondary" class="bg-blue-500 text-white dark:bg-blue-600">
264
- <UiIcon icon="i-material-symbols-verified" class="size-3" />
264
+ <UiIcon name="badge-check" :size="12" />
265
265
  Verified
266
266
  </UiBadge>
267
267
  </template>`;
@@ -274,7 +274,7 @@ export const WithIconSlot: Story = {
274
274
  components: { UiBadge, UiIcon },
275
275
  template: `
276
276
  <UiBadge variant="secondary" class="bg-blue-500 text-white dark:bg-blue-600">
277
- <UiIcon icon="i-material-symbols-verified" class="size-3" />
277
+ <UiIcon name="badge-check" :size="12" />
278
278
  Verified
279
279
  </UiBadge>
280
280
  `,
@@ -4,17 +4,17 @@ import { UiIcon } from '../UiIcon';
4
4
 
5
5
  const ChevronLeftIcon = {
6
6
  components: { UiIcon },
7
- template: '<UiIcon icon="i-material-symbols-chevron-left" class="size-4" />',
7
+ template: '<UiIcon name="chevron-left" :size="16" />',
8
8
  };
9
9
 
10
10
  const ChevronRightIcon = {
11
11
  components: { UiIcon },
12
- template: '<UiIcon icon="i-material-symbols-chevron-right" class="size-4" />',
12
+ template: '<UiIcon name="chevron-right" :size="16" />',
13
13
  };
14
14
 
15
15
  const MailIcon = {
16
16
  components: { UiIcon },
17
- template: '<UiIcon icon="i-material-symbols-mail" class="size-4" />',
17
+ template: '<UiIcon name="mail" :size="16" />',
18
18
  };
19
19
 
20
20
  const meta: Meta<typeof UiButton> = {
@@ -256,7 +256,7 @@ import { UiButton, UiIcon } from '@aleph-alpha/ui-library'
256
256
 
257
257
  const ChevronLeftIcon = {
258
258
  components: { UiIcon },
259
- template: '<UiIcon icon="i-material-symbols-chevron-left" class="size-4" />',
259
+ template: '<UiIcon name="chevron-left" :size="16" />',
260
260
  }
261
261
  </script>
262
262
 
@@ -289,7 +289,7 @@ import { UiButton, UiIcon } from '@aleph-alpha/ui-library'
289
289
 
290
290
  const ChevronRightIcon = {
291
291
  components: { UiIcon },
292
- template: '<UiIcon icon="i-material-symbols-chevron-right" class="size-4" />',
292
+ template: '<UiIcon name="chevron-right" :size="16" />',
293
293
  }
294
294
  </script>
295
295
 
@@ -322,12 +322,12 @@ import { UiButton, UiIcon } from '@aleph-alpha/ui-library'
322
322
 
323
323
  const MailIcon = {
324
324
  components: { UiIcon },
325
- template: '<UiIcon icon="i-material-symbols-mail" class="size-4" />',
325
+ template: '<UiIcon name="mail" :size="16" />',
326
326
  }
327
327
 
328
328
  const ChevronRightIcon = {
329
329
  components: { UiIcon },
330
- template: '<UiIcon icon="i-material-symbols-chevron-right" class="size-4" />',
330
+ template: '<UiIcon name="chevron-right" :size="16" />',
331
331
  }
332
332
  </script>
333
333
 
@@ -362,7 +362,7 @@ import { UiButton, UiIcon } from '@aleph-alpha/ui-library'
362
362
 
363
363
  const MailIcon = {
364
364
  components: { UiIcon },
365
- template: '<UiIcon icon="i-material-symbols-mail" class="size-4" />',
365
+ template: '<UiIcon name="mail" :size="16" />',
366
366
  }
367
367
  </script>
368
368
 
@@ -395,12 +395,12 @@ import { UiButton, UiIcon } from '@aleph-alpha/ui-library'
395
395
 
396
396
  const MailIcon = {
397
397
  components: { UiIcon },
398
- template: '<UiIcon icon="i-material-symbols-mail" class="size-4" />',
398
+ template: '<UiIcon name="mail" :size="16" />',
399
399
  }
400
400
 
401
401
  const ChevronRightIcon = {
402
402
  components: { UiIcon },
403
- template: '<UiIcon icon="i-material-symbols-chevron-right" class="size-4" />',
403
+ template: '<UiIcon name="chevron-right" :size="16" />',
404
404
  }
405
405
  </script>
406
406
 
@@ -437,7 +437,7 @@ import { UiButton, UiIcon } from '@aleph-alpha/ui-library'
437
437
 
438
438
  <template>
439
439
  <UiButton variant="outline" size="sm">
440
- <UiIcon icon="i-material-symbols-call-split" class="size-4" />
440
+ <UiIcon name="git-branch" :size="16" />
441
441
  New Branch
442
442
  </UiButton>
443
443
  </template>`;
@@ -450,7 +450,7 @@ export const WithIconSlot: Story = {
450
450
  components: { UiButton, UiIcon },
451
451
  template: `
452
452
  <UiButton variant="outline" size="sm">
453
- <UiIcon icon="i-material-symbols-call-split" class="size-4" />
453
+ <UiIcon name="git-branch" :size="16" />
454
454
  New Branch
455
455
  </UiButton>
456
456
  `,
@@ -743,10 +743,10 @@ const defaultPlaceholder = today(getLocalTimeZone())
743
743
  </div>
744
744
  </template>
745
745
  <template #prev-icon>
746
- <UiIcon icon="i-material-symbols-chevrons-left" class="size-5 text-red-500" />
746
+ <UiIcon name="chevrons-left" :size="20" class="text-red-500" />
747
747
  </template>
748
748
  <template #next-icon>
749
- <UiIcon icon="i-material-symbols-chevrons-right" class="size-5 text-red-500" />
749
+ <UiIcon name="chevrons-right" :size="20" class="text-red-500" />
750
750
  </template>
751
751
  </UiCalendar>
752
752
  </template>`;
@@ -780,10 +780,10 @@ export const CustomHeadingAndCellSize: Story = {
780
780
  </div>
781
781
  </template>
782
782
  <template #prev-icon>
783
- <UiIcon icon="i-material-symbols-chevrons-left" class="size-5 text-red-500" />
783
+ <UiIcon name="chevrons-left" :size="20" class="text-red-500" />
784
784
  </template>
785
785
  <template #next-icon>
786
- <UiIcon icon="i-material-symbols-chevrons-right" class="size-5 text-red-500" />
786
+ <UiIcon name="chevrons-right" :size="20" class="text-red-500" />
787
787
  </template>
788
788
  </UiCalendar>`,
789
789
  }),
@@ -696,7 +696,7 @@ const open = ref(false)
696
696
  <UiDropdownMenu v-model:open="open">
697
697
  <UiDropdownMenuTrigger as-child>
698
698
  <UiIconButton aria-label="Open menu" variant="ghost">
699
- <UiIcon icon="i-material-symbols-more-vert" class="text-xl" />
699
+ <UiIcon name="more-vertical" :size="20" />
700
700
  </UiIconButton>
701
701
  </UiDropdownMenuTrigger>
702
702
  <UiDropdownMenuContent>
@@ -740,7 +740,7 @@ export const WithIconButton: Story = {
740
740
  template: `<UiDropdownMenu v-model:open="open" :modal="modal">
741
741
  <UiDropdownMenuTrigger as-child>
742
742
  <UiIconButton aria-label="Open menu" variant="ghost">
743
- <UiIcon icon="i-material-symbols-more-vert" class="text-xl" />
743
+ <UiIcon name="more-vertical" :size="20" />
744
744
  </UiIconButton>
745
745
  </UiDropdownMenuTrigger>
746
746
  <UiDropdownMenuContent>
@@ -3,17 +3,27 @@ import { UiIcon } from '.';
3
3
  import { UiIconButton } from '../UiIconButton';
4
4
 
5
5
  /**
6
- * UiIcon renders a single icon using the design system’s icon set (Material Symbols via UnoCSS preset-icons).
6
+ * UiIcon renders a single icon from the Lucide icon set.
7
7
  * Use it for consistent sizing, styling, and accessibility semantics across the UI library.
8
+ *
9
+ * @see https://lucide.dev/icons for available icons
8
10
  */
9
11
  const meta: Meta<typeof UiIcon> = {
10
12
  title: 'Primitives/UiIcon',
11
13
  component: UiIcon,
12
14
  tags: ['autodocs'],
13
15
  argTypes: {
14
- icon: {
16
+ name: {
15
17
  control: 'text',
16
- description: 'Icon class, e.g. `i-material-symbols-help`.',
18
+ description: 'Lucide icon name in kebab-case, e.g. `circle-help`, `chevron-down`.',
19
+ },
20
+ size: {
21
+ control: 'number',
22
+ description: 'Icon size in pixels. Defaults to 24.',
23
+ },
24
+ strokeWidth: {
25
+ control: 'number',
26
+ description: 'Stroke width. Defaults to 2.',
17
27
  },
18
28
  ariaLabel: {
19
29
  control: 'text',
@@ -21,7 +31,9 @@ const meta: Meta<typeof UiIcon> = {
21
31
  },
22
32
  },
23
33
  args: {
24
- icon: 'i-material-symbols-help',
34
+ name: 'circle-help',
35
+ size: 24,
36
+ strokeWidth: 2,
25
37
  ariaLabel: 'Help',
26
38
  },
27
39
  };
@@ -35,14 +47,14 @@ import { UiIcon } from '@aleph-alpha/ui-library'
35
47
 
36
48
  <template>
37
49
  <div class="flex items-center gap-4">
38
- <UiIcon icon="i-material-symbols-help" aria-label="Help" class="text-xl text-foreground" />
39
- <UiIcon icon="i-material-symbols-keyboard-arrow-down" aria-label="Down" class="text-xl text-foreground" />
40
- <UiIcon icon="i-material-symbols-check" aria-label="Check" class="text-xl text-foreground" />
50
+ <UiIcon name="circle-help" aria-label="Help" class="text-foreground" />
51
+ <UiIcon name="chevron-down" aria-label="Down" class="text-foreground" />
52
+ <UiIcon name="check" aria-label="Check" class="text-foreground" />
41
53
  </div>
42
54
  </template>`;
43
55
 
44
56
  /**
45
- * Basic icon rendering with Material Symbols.
57
+ * Basic icon rendering with Lucide icons.
46
58
  * Use this as a starting point for choosing an icon and verifying size/color alignment in your layout.
47
59
  */
48
60
  export const Default: Story = {
@@ -53,9 +65,9 @@ export const Default: Story = {
53
65
  },
54
66
  template: `
55
67
  <div class="flex items-center gap-4">
56
- <UiIcon v-bind="args" class="text-xl text-foreground" />
57
- <UiIcon icon="i-material-symbols-keyboard-arrow-down" aria-label="Down" class="text-xl text-foreground" />
58
- <UiIcon icon="i-material-symbols-check" aria-label="Check" class="text-xl text-foreground" />
68
+ <UiIcon v-bind="args" class="text-foreground" />
69
+ <UiIcon name="chevron-down" aria-label="Down" class="text-foreground" />
70
+ <UiIcon name="check" aria-label="Check" class="text-foreground" />
59
71
  </div>
60
72
  `,
61
73
  }),
@@ -64,13 +76,47 @@ export const Default: Story = {
64
76
  },
65
77
  };
66
78
 
79
+ const sizesTemplateSource = `<script setup lang="ts">
80
+ import { UiIcon } from '@aleph-alpha/ui-library'
81
+ </script>
82
+
83
+ <template>
84
+ <div class="flex items-center gap-4">
85
+ <UiIcon name="star" :size="16" />
86
+ <UiIcon name="star" :size="24" />
87
+ <UiIcon name="star" :size="32" />
88
+ <UiIcon name="star" :size="48" />
89
+ </div>
90
+ </template>`;
91
+
92
+ /**
93
+ * Icons can be rendered at different sizes using the `size` prop.
94
+ */
95
+ export const Sizes: Story = {
96
+ render: () => ({
97
+ components: { UiIcon },
98
+ template: `
99
+ <div class="flex items-center gap-4">
100
+ <UiIcon name="star" :size="16" />
101
+ <UiIcon name="star" :size="24" />
102
+ <UiIcon name="star" :size="32" />
103
+ <UiIcon name="star" :size="48" />
104
+ </div>
105
+ `,
106
+ }),
107
+ parameters: {
108
+ controls: { disable: true },
109
+ docs: { source: { code: sizesTemplateSource } },
110
+ },
111
+ };
112
+
67
113
  const iconButtonTemplateSource = `<script setup lang="ts">
68
114
  import { UiIconButton, UiIcon } from '@aleph-alpha/ui-library'
69
115
  </script>
70
116
 
71
117
  <template>
72
118
  <UiIconButton aria-label="Close">
73
- <UiIcon icon="i-material-symbols-close" class="text-xl" />
119
+ <UiIcon name="x" :size="20" />
74
120
  </UiIconButton>
75
121
  </template>`;
76
122
 
@@ -84,7 +130,7 @@ export const InIconButton: Story = {
84
130
  components: { UiIconButton, UiIcon },
85
131
  template: `
86
132
  <UiIconButton aria-label="Close">
87
- <UiIcon icon="i-material-symbols-close" class="text-xl" />
133
+ <UiIcon name="x" :size="20" />
88
134
  </UiIconButton>
89
135
  `,
90
136
  }),