laif-ds 0.2.74 → 0.2.76

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 (155) hide show
  1. package/dist/CHANGELOG.md +446 -0
  2. package/dist/agent-docs/adoption-report.json +615 -0
  3. package/dist/agent-docs/components/Accordion.md +46 -16
  4. package/dist/agent-docs/components/Alert.md +90 -95
  5. package/dist/agent-docs/components/AlertDialog.md +132 -126
  6. package/dist/agent-docs/components/AppEditor.md +90 -90
  7. package/dist/agent-docs/components/AppRadioGroup.md +18 -18
  8. package/dist/agent-docs/components/AppSidebar.md +129 -122
  9. package/dist/agent-docs/components/AppStepper.md +81 -77
  10. package/dist/agent-docs/components/AspectRatio.md +70 -62
  11. package/dist/agent-docs/components/AudioVisualizer.md +5 -5
  12. package/dist/agent-docs/components/Avatar.md +112 -113
  13. package/dist/agent-docs/components/Badge.md +123 -118
  14. package/dist/agent-docs/components/Breadcrumb.md +8 -1
  15. package/dist/agent-docs/components/Button.md +131 -129
  16. package/dist/agent-docs/components/Card.md +172 -147
  17. package/dist/agent-docs/components/Carousel.md +148 -129
  18. package/dist/agent-docs/components/Chat.md +121 -109
  19. package/dist/agent-docs/components/ChatMessage.md +72 -61
  20. package/dist/agent-docs/components/Checkbox.md +150 -135
  21. package/dist/agent-docs/components/CircularProgress.md +53 -49
  22. package/dist/agent-docs/components/CodeHighlighter.md +4 -4
  23. package/dist/agent-docs/components/Collapsible.md +114 -95
  24. package/dist/agent-docs/components/Command.md +141 -142
  25. package/dist/agent-docs/components/Confirmer.md +182 -175
  26. package/dist/agent-docs/components/ContextMenu.md +196 -191
  27. package/dist/agent-docs/components/DataCrossTable.md +114 -94
  28. package/dist/agent-docs/components/DataTable.md +32 -24
  29. package/dist/agent-docs/components/Dialog.md +130 -125
  30. package/dist/agent-docs/components/Drawer.md +141 -127
  31. package/dist/agent-docs/components/FilePreviewer.md +138 -139
  32. package/dist/agent-docs/components/FileUploader.md +149 -129
  33. package/dist/agent-docs/components/Form.md +3 -1
  34. package/dist/agent-docs/components/FormComposer.md +163 -137
  35. package/dist/agent-docs/components/GanttChart.md +125 -122
  36. package/dist/agent-docs/components/HoverCard.md +1 -1
  37. package/dist/agent-docs/components/Icon.md +98 -99
  38. package/dist/agent-docs/components/Input.md +173 -138
  39. package/dist/agent-docs/components/InputOtp.md +6 -1
  40. package/dist/agent-docs/components/InputSelector.md +94 -97
  41. package/dist/agent-docs/components/InterruptPrompt.md +4 -4
  42. package/dist/agent-docs/components/MarkdownRenderer.md +5 -2
  43. package/dist/agent-docs/components/Menubar.md +60 -57
  44. package/dist/agent-docs/components/MessageInput.md +134 -131
  45. package/dist/agent-docs/components/MessageList.md +110 -96
  46. package/dist/agent-docs/components/MultipleSelector.md +147 -146
  47. package/dist/agent-docs/components/NavigationMenu.md +6 -2
  48. package/dist/agent-docs/components/Popover.md +112 -103
  49. package/dist/agent-docs/components/PromptSuggestions.md +5 -5
  50. package/dist/agent-docs/components/RadioGroup.md +97 -90
  51. package/dist/agent-docs/components/Resizable.md +4 -1
  52. package/dist/agent-docs/components/ResizePrompt.md +12 -13
  53. package/dist/agent-docs/components/ScrollArea.md +6 -2
  54. package/dist/agent-docs/components/SecurePdfViewer.md +10 -6
  55. package/dist/agent-docs/components/Select.md +131 -132
  56. package/dist/agent-docs/components/Sheet.md +8 -1
  57. package/dist/agent-docs/components/ShikiHighlighter.md +5 -5
  58. package/dist/agent-docs/components/Sidebar.md +94 -85
  59. package/dist/agent-docs/components/Slider.md +62 -58
  60. package/dist/agent-docs/components/Sonner.md +1 -0
  61. package/dist/agent-docs/components/Spinner.md +14 -14
  62. package/dist/agent-docs/components/Stepper.md +93 -67
  63. package/dist/agent-docs/components/Switch.md +41 -42
  64. package/dist/agent-docs/components/TableSkeleton.md +8 -8
  65. package/dist/agent-docs/components/Tabs.md +106 -86
  66. package/dist/agent-docs/components/TextArea.md +51 -52
  67. package/dist/agent-docs/components/ThemeSwitcher.md +72 -69
  68. package/dist/agent-docs/components/Toaster.md +1 -0
  69. package/dist/agent-docs/components/Tooltip.md +102 -91
  70. package/dist/agent-docs/components/Typo.md +68 -65
  71. package/dist/agent-docs/components/WeeklyCalendar.md +63 -64
  72. package/dist/agent-docs/components-list.md +1 -0
  73. package/dist/agent-docs/manifest.json +5981 -0
  74. package/dist/agent-docs/truncated-cell.md +342 -0
  75. package/dist/components/editor/editor-hooks/use-update-toolbar.js +6 -6
  76. package/dist/components/editor/plugins/actions/counter-character-plugin.js +6 -6
  77. package/dist/components/editor/plugins/toolbar/font-format-toolbar-plugin.js +18 -18
  78. package/dist/components/editor/plugins/toolbar/history-toolbar-plugin.js +10 -10
  79. package/dist/components/editor/plugins/toolbar/toolbar-plugin.js +9 -9
  80. package/dist/components/ui/app-checkbox.js +1 -1
  81. package/dist/components/ui/app-dialog.js +70 -64
  82. package/dist/components/ui/app-editor.js +51 -51
  83. package/dist/components/ui/app-form.js +81 -81
  84. package/dist/components/ui/app-multiple-select-dropdown.js +36 -36
  85. package/dist/components/ui/app-select.js +109 -104
  86. package/dist/components/ui/app-sidebar.js +41 -41
  87. package/dist/components/ui/app-stepper.js +1 -1
  88. package/dist/components/ui/app-time-picker.js +18 -18
  89. package/dist/components/ui/app-tooltip.js +1 -1
  90. package/dist/components/ui/async-select.js +5 -5
  91. package/dist/components/ui/audio-visualizer.js +61 -58
  92. package/dist/components/ui/card.js +1 -1
  93. package/dist/components/ui/carousel.js +2 -2
  94. package/dist/components/ui/chart.js +1 -1
  95. package/dist/components/ui/chat-message.js +8 -8
  96. package/dist/components/ui/chat.js +86 -88
  97. package/dist/components/ui/command.js +2 -2
  98. package/dist/components/ui/copy-button.js +4 -4
  99. package/dist/components/ui/date-picker.js +20 -20
  100. package/dist/components/ui/file-preview/index.js +13 -13
  101. package/dist/components/ui/file-previewer.js +12 -11
  102. package/dist/components/ui/file-uploader.js +86 -78
  103. package/dist/components/ui/form.js +2 -2
  104. package/dist/components/ui/gantt/components/Chart/Bars/Bars.js +56 -56
  105. package/dist/components/ui/gantt/components/Chart/Bars/BarsRow/BarItem/BarItem.js +12 -12
  106. package/dist/components/ui/gantt/components/Chart/Bars/BarsRow/BarsItems/BarItems.js +1 -1
  107. package/dist/components/ui/gantt/components/Chart/Bars/BarsRow/BarsRow.js +4 -4
  108. package/dist/components/ui/gantt/components/Chart/Bars/BarsRow/RepeteadBars/RepeteadBars.js +2 -2
  109. package/dist/components/ui/gantt/components/Chart/Chart.js +23 -23
  110. package/dist/components/ui/gantt/components/Chart/Scale/Scale.js +1 -1
  111. package/dist/components/ui/gantt/components/Chart/Tree/Tree.js +34 -34
  112. package/dist/components/ui/gantt/components/Controls/Controls.js +5 -5
  113. package/dist/components/ui/gantt/components/Gantt/Gantt.js +4 -4
  114. package/dist/components/ui/gantt/hooks/useGanttCalculate.js +25 -18
  115. package/dist/components/ui/input-selector.js +1 -1
  116. package/dist/components/ui/input.js +23 -23
  117. package/dist/components/ui/kanban.js +8 -9
  118. package/dist/components/ui/markdown-renderer.js +41 -35
  119. package/dist/components/ui/message-input.js +45 -44
  120. package/dist/components/ui/multiple-selector.js +91 -82
  121. package/dist/components/ui/secure-pdf-viewer.js +19 -7
  122. package/dist/components/ui/sidebar.js +1 -1
  123. package/dist/components/ui/slider.js +1 -1
  124. package/dist/components/ui/spinner.js +4 -4
  125. package/dist/components/ui/stepper.js +157 -138
  126. package/dist/components/ui/tables/data-cross-table/data-cross-table-buttons.js +29 -29
  127. package/dist/components/ui/tables/data-cross-table/data-cross-table.js +258 -246
  128. package/dist/components/ui/tables/data-table/components/data-table-advanced-filter.js +4 -1
  129. package/dist/components/ui/tables/data-table/components/data-table-body.js +211 -367
  130. package/dist/components/ui/tables/data-table/components/data-table-filter-inputs.js +114 -112
  131. package/dist/components/ui/tables/data-table/components/data-table-filters.js +116 -96
  132. package/dist/components/ui/tables/data-table/components/data-table-header.js +211 -0
  133. package/dist/components/ui/tables/data-table/components/data-table-searchbar.js +8 -8
  134. package/dist/components/ui/tables/data-table/components/data-table-skeleton-rows.js +33 -0
  135. package/dist/components/ui/tables/data-table/data-table.js +258 -250
  136. package/dist/components/ui/tables/data-table/data-table.service.js +112 -97
  137. package/dist/components/ui/tables/data-table/data-table.utils.js +25 -15
  138. package/dist/components/ui/textarea.js +2 -2
  139. package/dist/components/ui/theme-switcher.js +1 -1
  140. package/dist/components/ui/toggle-group.js +2 -2
  141. package/dist/components/ui/truncated-cell.js +100 -0
  142. package/dist/components/ui/weekly-calendar/appointment-card.js +16 -16
  143. package/dist/components/ui/weekly-calendar/calendar-context.js +6 -6
  144. package/dist/components/ui/weekly-calendar/calendar-header.js +12 -12
  145. package/dist/components/ui/weekly-calendar/day-column.js +16 -16
  146. package/dist/components/ui/weekly-calendar/time-column.js +4 -4
  147. package/dist/components/ui/weekly-calendar/weekly-calendar.js +4 -4
  148. package/dist/hooks/use-audio-recording.js +1 -1
  149. package/dist/hooks/use-auto-scroll.js +18 -18
  150. package/dist/hooks/use-autosize-textarea.js +12 -13
  151. package/dist/index.d.ts +100 -45
  152. package/dist/index.js +362 -360
  153. package/dist/lib/utils.js +6 -6
  154. package/dist/styles.v3.css +1 -1
  155. package/package.json +14 -4
@@ -1,96 +1,110 @@
1
- # MessageList
2
-
3
- ## Overview
4
-
5
- Vertical list of chat messages with optional typing indicator. Renders each message via `ChatMessage` and supports per-message actions.
6
-
7
- ---
8
-
9
- ## Props
10
-
11
- | Prop | Type | Default | Description |
12
- | ----------------- | -------------------------------------------------------------------- | ----------- | ----------- |
13
- | `messages` | `Message[]` | `[]` | Array of messages to render. |
14
- | `showTimeStamps` | `boolean` | `true` | Show timestamps on each message. |
15
- | `isTyping` | `boolean` | `false` | Shows a typing indicator at the end of the list. |
16
- | `messageOptions` | `AdditionalMessageOptions \| (message: Message) => AdditionalMessageOptions` | `undefined` | Additional props/actions per message (static or function of message). |
17
- | `onEdit` | `(id: string, newContent: string) => void` | `undefined` | Called when a message enters edit mode and changes. |
18
- | `onMessageSave` | `(id: string, content: string) => void` | `undefined` | Called when a message edit is saved. |
19
-
20
- `AdditionalMessageOptions` mirrors `ChatMessageProps` except base `Message` fields.
21
-
22
- ---
23
-
24
- ## Behavior
25
-
26
- - **Per-message customization**: Pass `messageOptions` as a function to supply contextual actions.
27
- - **Typing indicator**: `isTyping` renders `TypingIndicator` as the last item.
28
- - **Composition**: Each message is passed to `ChatMessage` with merged props.
29
-
30
- ---
31
-
32
- ## Examples
33
-
34
- ### Default
35
-
36
- ```tsx
37
- import { MessageList } from "laif-ds";
38
-
39
- export function Chat() {
40
- const messages = [
41
- { id: "1", role: "user", content: "Ciao!", createdAt: new Date() },
42
- { id: "2", role: "assistant", content: "Come posso aiutarti?", createdAt: new Date() },
43
- ];
44
- return (
45
- <div className="border-d-border w-full max-w-2xl rounded-lg border p-4">
46
- <MessageList messages={messages} showTimeStamps />
47
- </div>
48
- );
49
- }
50
- ```
51
-
52
- ### With Actions
53
-
54
- ```tsx
55
- import { Button, Icon } from "laif-ds";
56
- import { MessageList } from "laif-ds";
57
-
58
- export function ChatWithActions() {
59
- const messages = [
60
- { id: "1", role: "user", content: "Spiegami il virtual DOM", createdAt: new Date() },
61
- { id: "2", role: "assistant", content: "Il Virtual DOM è...", createdAt: new Date() },
62
- ];
63
-
64
- return (
65
- <div className="border-d-border w-full max-w-2xl rounded-lg border p-4">
66
- <MessageList
67
- messages={messages}
68
- messageOptions={(m) =>
69
- m.role === "assistant"
70
- ? {
71
- actions: (
72
- <>
73
- <Button variant="ghost" size="icon" className="h-6 w-6">
74
- <Icon name="ThumbsUp" className="size-4" />
75
- </Button>
76
- <Button variant="ghost" size="icon" className="h-6 w-6">
77
- <Icon name="ThumbsDown" className="size-4" />
78
- </Button>
79
- </>
80
- ),
81
- }
82
- : {}
83
- }
84
- />
85
- </div>
86
- );
87
- }
88
- ```
89
-
90
- ---
91
-
92
- ## Notes
93
-
94
- - **Data model**: See `ChatMessage` for the `Message` shape and advanced features (tool invocations, reasoning parts, edits).
95
- - **A11y**: Provide readable timestamps and roles; actions should include accessible labels.
96
-
1
+ # MessageList
2
+
3
+ ## Overview
4
+
5
+ Vertical list of chat messages with optional typing indicator. Renders each message via `ChatMessage` and supports per-message actions.
6
+
7
+ ---
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | ---------------- | ---------------------------------------------------------------------------- | ----------- | --------------------------------------------------------------------- |
13
+ | `messages` | `Message[]` | `[]` | Array of messages to render. |
14
+ | `showTimeStamps` | `boolean` | `true` | Show timestamps on each message. |
15
+ | `isTyping` | `boolean` | `false` | Shows a typing indicator at the end of the list. |
16
+ | `messageOptions` | `AdditionalMessageOptions \| (message: Message) => AdditionalMessageOptions` | `undefined` | Additional props/actions per message (static or function of message). |
17
+ | `onEdit` | `(id: string, newContent: string) => void` | `undefined` | Called when a message enters edit mode and changes. |
18
+ | `onMessageSave` | `(id: string, content: string) => void` | `undefined` | Called when a message edit is saved. |
19
+
20
+ `AdditionalMessageOptions` mirrors `ChatMessageProps` except base `Message` fields.
21
+
22
+ ---
23
+
24
+ ## Behavior
25
+
26
+ - **Per-message customization**: Pass `messageOptions` as a function to supply contextual actions.
27
+ - **Typing indicator**: `isTyping` renders `TypingIndicator` as the last item.
28
+ - **Composition**: Each message is passed to `ChatMessage` with merged props.
29
+
30
+ ---
31
+
32
+ ## Examples
33
+
34
+ ### Default
35
+
36
+ ```tsx
37
+ import { MessageList } from "laif-ds";
38
+
39
+ export function Chat() {
40
+ const messages = [
41
+ { id: "1", role: "user", content: "Ciao!", createdAt: new Date() },
42
+ {
43
+ id: "2",
44
+ role: "assistant",
45
+ content: "Come posso aiutarti?",
46
+ createdAt: new Date(),
47
+ },
48
+ ];
49
+ return (
50
+ <div className="border-d-border w-full max-w-2xl rounded-lg border p-4">
51
+ <MessageList messages={messages} showTimeStamps />
52
+ </div>
53
+ );
54
+ }
55
+ ```
56
+
57
+ ### With Actions
58
+
59
+ ```tsx
60
+ import { Button, Icon } from "laif-ds";
61
+ import { MessageList } from "laif-ds";
62
+
63
+ export function ChatWithActions() {
64
+ const messages = [
65
+ {
66
+ id: "1",
67
+ role: "user",
68
+ content: "Spiegami il virtual DOM",
69
+ createdAt: new Date(),
70
+ },
71
+ {
72
+ id: "2",
73
+ role: "assistant",
74
+ content: "Il Virtual DOM è...",
75
+ createdAt: new Date(),
76
+ },
77
+ ];
78
+
79
+ return (
80
+ <div className="border-d-border w-full max-w-2xl rounded-lg border p-4">
81
+ <MessageList
82
+ messages={messages}
83
+ messageOptions={(m) =>
84
+ m.role === "assistant"
85
+ ? {
86
+ actions: (
87
+ <>
88
+ <Button variant="ghost" size="icon" className="h-6 w-6">
89
+ <Icon name="ThumbsUp" className="size-4" />
90
+ </Button>
91
+ <Button variant="ghost" size="icon" className="h-6 w-6">
92
+ <Icon name="ThumbsDown" className="size-4" />
93
+ </Button>
94
+ </>
95
+ ),
96
+ }
97
+ : {}
98
+ }
99
+ />
100
+ </div>
101
+ );
102
+ }
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Notes
108
+
109
+ - **Data model**: See `ChatMessage` for the `Message` shape and advanced features (tool invocations, reasoning parts, edits).
110
+ - **A11y**: Provide readable timestamps and roles; actions should include accessible labels.
@@ -1,146 +1,147 @@
1
- # MultipleSelector (Deprecated)
2
-
3
- ## Overview
4
-
5
- Tag-style multi-select built on `cmdk` and `Popover` with search, grouping, creatable options, and badges for selections.
6
-
7
- - ⚠️ This component is deprecated. Prefer `AppSelect` for new code.
8
-
9
- ---
10
-
11
- ## Types
12
-
13
- ```ts
14
- // Deprecated interface. Prefer AppSelect options.
15
- export interface Option {
16
- value: string;
17
- label: string;
18
- disable?: boolean;
19
- fixed?: boolean; // fixed option that can't be removed
20
- [key: string]: string | boolean | undefined; // for grouping keys
21
- }
22
- ```
23
-
24
- ---
25
-
26
- ## Props (highlights)
27
-
28
- | Prop | Type | Default | Description |
29
- | ----------------------------- | -------------------------------------- | ------------------------------- | ----------- |
30
- | `value` | `Option[]` | `[]` | Controlled selected options. |
31
- | `defaultOptions` | `Option[]` | `[]` | Initial options to display. |
32
- | `options` | `Option[]` | `undefined` | Manually controlled options (when not using search). |
33
- | `placeholder` | `string` | `"Cerca..."` | Input placeholder. |
34
- | `onSearch` | `(q: string) => Promise<Option[]>` | `undefined` | Async search. Debounced by `delay`. |
35
- | `onSearchSync` | `(q: string) => Option[]` | `undefined` | Sync search alternative. |
36
- | `delay` | `number` | `500` | Debounce ms for `onSearch`. |
37
- | `triggerSearchOnFocus` | `boolean` | `false` | Trigger search when input focuses. |
38
- | `onChange` | `(opts: Option[]) => void` | `undefined` | Fired on selection change. |
39
- | `maxSelected` | `number` | `Number.MAX_SAFE_INTEGER` | Selection limit. |
40
- | `onMaxSelected` | `(limit: number) => void` | `undefined` | Called when limit reached. |
41
- | `groupBy` | `string` | `undefined` | Group options by key. |
42
- | `disabled` | `boolean` | `false` | Disable interactions. |
43
- | `hidePlaceholderWhenSelected` | `boolean` | `true` | Hide placeholder when badges exist. |
44
- | `selectFirstItem` | `boolean` | `true` | Cmdk behavior workaround. |
45
- | `creatable` | `boolean` | `false` | Allow creating new option if not found. |
46
- | `hideClearAllButton` | `boolean` | `false` | Hide the clear-all icon. |
47
- | `className` | `string` | `""` | Trigger wrapper classes. |
48
- | `badgeClassName` | `string` | `""` | Badge classes. |
49
- | `label` | `string | React.ReactNode` | `undefined` | Optional label above control. |
50
-
51
- Also exposes `commandProps` and `inputProps` to pass through to internal `Command` and search input.
52
-
53
- ---
54
-
55
- ## Behavior
56
-
57
- - **Search**: Use `onSearch` (async) or `onSearchSync` (sync). Debounced input.
58
- - **Grouping**: Provide `groupBy` key to group options.
59
- - **Creatable**: When enabled, offers "Create \"query\"" item when not found.
60
- - **Badges**: Selected options render as removable badges. `fixed` badges cannot be removed.
61
- - **Limits**: Enforces `maxSelected`; calls `onMaxSelected` when exceeded.
62
- - **Clear all**: Built-in clear-all icon (hidden with `hideClearAllButton`).
63
- - **Disabled**: Disables input and badge removal.
64
-
65
- ---
66
-
67
- ## Examples
68
-
69
- ### Default
70
-
71
- ```tsx
72
- import { MultipleSelector } from "laif-ds";
73
-
74
- export function DefaultMulti() {
75
- return (
76
- <div className="w-[400px]">
77
- <MultipleSelector
78
- placeholder="Seleziona dei tag..."
79
- defaultOptions={[
80
- { value: "react", label: "React" },
81
- { value: "typescript", label: "TypeScript" },
82
- ]}
83
- />
84
- </div>
85
- );
86
- }
87
- ```
88
-
89
- ### Grouped Options
90
-
91
- ```tsx
92
- import { MultipleSelector } from "laif-ds";
93
-
94
- const frameworks = [
95
- { value: "react", label: "React", category: "Frontend" },
96
- { value: "node", label: "Node.js", category: "Backend" },
97
- ];
98
-
99
- export function Grouped() {
100
- return (
101
- <div className="w-[400px]">
102
- <MultipleSelector
103
- placeholder="Seleziona dei framework..."
104
- defaultOptions={frameworks}
105
- groupBy="category"
106
- />
107
- </div>
108
- );
109
- }
110
- ```
111
-
112
- ### Async Search
113
-
114
- ```tsx
115
- import { MultipleSelector } from "laif-ds";
116
-
117
- async function mockSearch(query: string) {
118
- await new Promise((r) => setTimeout(r, 300));
119
- const tags = [
120
- { value: "react", label: "React" },
121
- { value: "typescript", label: "TypeScript" },
122
- ];
123
- return tags.filter((t) => t.label.toLowerCase().includes(query.toLowerCase()));
124
- }
125
-
126
- export function AsyncSearch() {
127
- return (
128
- <div className="w-[400px]">
129
- <MultipleSelector
130
- placeholder="Cerca dei tag..."
131
- onSearch={mockSearch}
132
- delay={300}
133
- triggerSearchOnFocus
134
- />
135
- </div>
136
- );
137
- }
138
- ```
139
-
140
- ---
141
-
142
- ## Notes
143
-
144
- - **Use AppSelect**: Prefer `AppSelect` for multiselect scenarios.
145
- - **A11y**: The trigger is keyboard-accessible; ensure label association when using `label`.
146
-
1
+ # MultipleSelector (Deprecated)
2
+
3
+ ## Overview
4
+
5
+ Tag-style multi-select built on `cmdk` and `Popover` with search, grouping, creatable options, and badges for selections.
6
+
7
+ - ⚠️ This component is deprecated. Prefer `AppSelect` for new code.
8
+
9
+ ---
10
+
11
+ ## Types
12
+
13
+ ```ts
14
+ // Deprecated interface. Prefer AppSelect options.
15
+ export interface Option {
16
+ value: string;
17
+ label: string;
18
+ disable?: boolean;
19
+ fixed?: boolean; // fixed option that can't be removed
20
+ [key: string]: string | boolean | undefined; // for grouping keys
21
+ }
22
+ ```
23
+
24
+ ---
25
+
26
+ ## Props (highlights)
27
+
28
+ | Prop | Type | Default | Description |
29
+ | ----------------------------- | ---------------------------------- | ------------------------- | ---------------------------------------------------- | ----------------------------- |
30
+ | `value` | `Option[]` | `[]` | Controlled selected options. |
31
+ | `defaultOptions` | `Option[]` | `[]` | Initial options to display. |
32
+ | `options` | `Option[]` | `undefined` | Manually controlled options (when not using search). |
33
+ | `placeholder` | `string` | `"Cerca..."` | Input placeholder. |
34
+ | `onSearch` | `(q: string) => Promise<Option[]>` | `undefined` | Async search. Debounced by `delay`. |
35
+ | `onSearchSync` | `(q: string) => Option[]` | `undefined` | Sync search alternative. |
36
+ | `delay` | `number` | `500` | Debounce ms for `onSearch`. |
37
+ | `triggerSearchOnFocus` | `boolean` | `false` | Trigger search when input focuses. |
38
+ | `onChange` | `(opts: Option[]) => void` | `undefined` | Fired on selection change. |
39
+ | `maxSelected` | `number` | `Number.MAX_SAFE_INTEGER` | Selection limit. |
40
+ | `onMaxSelected` | `(limit: number) => void` | `undefined` | Called when limit reached. |
41
+ | `groupBy` | `string` | `undefined` | Group options by key. |
42
+ | `disabled` | `boolean` | `false` | Disable interactions. |
43
+ | `hidePlaceholderWhenSelected` | `boolean` | `true` | Hide placeholder when badges exist. |
44
+ | `selectFirstItem` | `boolean` | `true` | Cmdk behavior workaround. |
45
+ | `creatable` | `boolean` | `false` | Allow creating new option if not found. |
46
+ | `hideClearAllButton` | `boolean` | `false` | Hide the clear-all icon. |
47
+ | `className` | `string` | `""` | Trigger wrapper classes. |
48
+ | `badgeClassName` | `string` | `""` | Badge classes. |
49
+ | `label` | `string | React.ReactNode` | `undefined` | Optional label above control. |
50
+
51
+ Also exposes `commandProps` and `inputProps` to pass through to internal `Command` and search input.
52
+
53
+ ---
54
+
55
+ ## Behavior
56
+
57
+ - **Search**: Use `onSearch` (async) or `onSearchSync` (sync). Debounced input.
58
+ - **Grouping**: Provide `groupBy` key to group options.
59
+ - **Creatable**: When enabled, offers "Create \"query\"" item when not found.
60
+ - **Badges**: Selected options render as removable badges. `fixed` badges cannot be removed.
61
+ - **Limits**: Enforces `maxSelected`; calls `onMaxSelected` when exceeded.
62
+ - **Clear all**: Built-in clear-all icon (hidden with `hideClearAllButton`).
63
+ - **Disabled**: Disables input and badge removal.
64
+
65
+ ---
66
+
67
+ ## Examples
68
+
69
+ ### Default
70
+
71
+ ```tsx
72
+ import { MultipleSelector } from "laif-ds";
73
+
74
+ export function DefaultMulti() {
75
+ return (
76
+ <div className="w-[400px]">
77
+ <MultipleSelector
78
+ placeholder="Seleziona dei tag..."
79
+ defaultOptions={[
80
+ { value: "react", label: "React" },
81
+ { value: "typescript", label: "TypeScript" },
82
+ ]}
83
+ />
84
+ </div>
85
+ );
86
+ }
87
+ ```
88
+
89
+ ### Grouped Options
90
+
91
+ ```tsx
92
+ import { MultipleSelector } from "laif-ds";
93
+
94
+ const frameworks = [
95
+ { value: "react", label: "React", category: "Frontend" },
96
+ { value: "node", label: "Node.js", category: "Backend" },
97
+ ];
98
+
99
+ export function Grouped() {
100
+ return (
101
+ <div className="w-[400px]">
102
+ <MultipleSelector
103
+ placeholder="Seleziona dei framework..."
104
+ defaultOptions={frameworks}
105
+ groupBy="category"
106
+ />
107
+ </div>
108
+ );
109
+ }
110
+ ```
111
+
112
+ ### Async Search
113
+
114
+ ```tsx
115
+ import { MultipleSelector } from "laif-ds";
116
+
117
+ async function mockSearch(query: string) {
118
+ await new Promise((r) => setTimeout(r, 300));
119
+ const tags = [
120
+ { value: "react", label: "React" },
121
+ { value: "typescript", label: "TypeScript" },
122
+ ];
123
+ return tags.filter((t) =>
124
+ t.label.toLowerCase().includes(query.toLowerCase()),
125
+ );
126
+ }
127
+
128
+ export function AsyncSearch() {
129
+ return (
130
+ <div className="w-[400px]">
131
+ <MultipleSelector
132
+ placeholder="Cerca dei tag..."
133
+ onSearch={mockSearch}
134
+ delay={300}
135
+ triggerSearchOnFocus
136
+ />
137
+ </div>
138
+ );
139
+ }
140
+ ```
141
+
142
+ ---
143
+
144
+ ## Notes
145
+
146
+ - **Use AppSelect**: Prefer `AppSelect` for multiselect scenarios.
147
+ - **A11y**: The trigger is keyboard-accessible; ensure label association when using `label`.
@@ -39,8 +39,12 @@ export function MainNav() {
39
39
  <NavigationMenuTrigger>Products</NavigationMenuTrigger>
40
40
  <NavigationMenuContent>
41
41
  <div className="grid w-[300px] gap-2 p-2">
42
- <NavigationMenuLink href="/products/a">Product A</NavigationMenuLink>
43
- <NavigationMenuLink href="/products/b">Product B</NavigationMenuLink>
42
+ <NavigationMenuLink href="/products/a">
43
+ Product A
44
+ </NavigationMenuLink>
45
+ <NavigationMenuLink href="/products/b">
46
+ Product B
47
+ </NavigationMenuLink>
44
48
  </div>
45
49
  </NavigationMenuContent>
46
50
  </NavigationMenuItem>