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.
- package/dist/CHANGELOG.md +446 -0
- package/dist/agent-docs/adoption-report.json +615 -0
- package/dist/agent-docs/components/Accordion.md +46 -16
- package/dist/agent-docs/components/Alert.md +90 -95
- package/dist/agent-docs/components/AlertDialog.md +132 -126
- package/dist/agent-docs/components/AppEditor.md +90 -90
- package/dist/agent-docs/components/AppRadioGroup.md +18 -18
- package/dist/agent-docs/components/AppSidebar.md +129 -122
- package/dist/agent-docs/components/AppStepper.md +81 -77
- package/dist/agent-docs/components/AspectRatio.md +70 -62
- package/dist/agent-docs/components/AudioVisualizer.md +5 -5
- package/dist/agent-docs/components/Avatar.md +112 -113
- package/dist/agent-docs/components/Badge.md +123 -118
- package/dist/agent-docs/components/Breadcrumb.md +8 -1
- package/dist/agent-docs/components/Button.md +131 -129
- package/dist/agent-docs/components/Card.md +172 -147
- package/dist/agent-docs/components/Carousel.md +148 -129
- package/dist/agent-docs/components/Chat.md +121 -109
- package/dist/agent-docs/components/ChatMessage.md +72 -61
- package/dist/agent-docs/components/Checkbox.md +150 -135
- package/dist/agent-docs/components/CircularProgress.md +53 -49
- package/dist/agent-docs/components/CodeHighlighter.md +4 -4
- package/dist/agent-docs/components/Collapsible.md +114 -95
- package/dist/agent-docs/components/Command.md +141 -142
- package/dist/agent-docs/components/Confirmer.md +182 -175
- package/dist/agent-docs/components/ContextMenu.md +196 -191
- package/dist/agent-docs/components/DataCrossTable.md +114 -94
- package/dist/agent-docs/components/DataTable.md +32 -24
- package/dist/agent-docs/components/Dialog.md +130 -125
- package/dist/agent-docs/components/Drawer.md +141 -127
- package/dist/agent-docs/components/FilePreviewer.md +138 -139
- package/dist/agent-docs/components/FileUploader.md +149 -129
- package/dist/agent-docs/components/Form.md +3 -1
- package/dist/agent-docs/components/FormComposer.md +163 -137
- package/dist/agent-docs/components/GanttChart.md +125 -122
- package/dist/agent-docs/components/HoverCard.md +1 -1
- package/dist/agent-docs/components/Icon.md +98 -99
- package/dist/agent-docs/components/Input.md +173 -138
- package/dist/agent-docs/components/InputOtp.md +6 -1
- package/dist/agent-docs/components/InputSelector.md +94 -97
- package/dist/agent-docs/components/InterruptPrompt.md +4 -4
- package/dist/agent-docs/components/MarkdownRenderer.md +5 -2
- package/dist/agent-docs/components/Menubar.md +60 -57
- package/dist/agent-docs/components/MessageInput.md +134 -131
- package/dist/agent-docs/components/MessageList.md +110 -96
- package/dist/agent-docs/components/MultipleSelector.md +147 -146
- package/dist/agent-docs/components/NavigationMenu.md +6 -2
- package/dist/agent-docs/components/Popover.md +112 -103
- package/dist/agent-docs/components/PromptSuggestions.md +5 -5
- package/dist/agent-docs/components/RadioGroup.md +97 -90
- package/dist/agent-docs/components/Resizable.md +4 -1
- package/dist/agent-docs/components/ResizePrompt.md +12 -13
- package/dist/agent-docs/components/ScrollArea.md +6 -2
- package/dist/agent-docs/components/SecurePdfViewer.md +10 -6
- package/dist/agent-docs/components/Select.md +131 -132
- package/dist/agent-docs/components/Sheet.md +8 -1
- package/dist/agent-docs/components/ShikiHighlighter.md +5 -5
- package/dist/agent-docs/components/Sidebar.md +94 -85
- package/dist/agent-docs/components/Slider.md +62 -58
- package/dist/agent-docs/components/Sonner.md +1 -0
- package/dist/agent-docs/components/Spinner.md +14 -14
- package/dist/agent-docs/components/Stepper.md +93 -67
- package/dist/agent-docs/components/Switch.md +41 -42
- package/dist/agent-docs/components/TableSkeleton.md +8 -8
- package/dist/agent-docs/components/Tabs.md +106 -86
- package/dist/agent-docs/components/TextArea.md +51 -52
- package/dist/agent-docs/components/ThemeSwitcher.md +72 -69
- package/dist/agent-docs/components/Toaster.md +1 -0
- package/dist/agent-docs/components/Tooltip.md +102 -91
- package/dist/agent-docs/components/Typo.md +68 -65
- package/dist/agent-docs/components/WeeklyCalendar.md +63 -64
- package/dist/agent-docs/components-list.md +1 -0
- package/dist/agent-docs/manifest.json +5981 -0
- package/dist/agent-docs/truncated-cell.md +342 -0
- package/dist/components/editor/editor-hooks/use-update-toolbar.js +6 -6
- package/dist/components/editor/plugins/actions/counter-character-plugin.js +6 -6
- package/dist/components/editor/plugins/toolbar/font-format-toolbar-plugin.js +18 -18
- package/dist/components/editor/plugins/toolbar/history-toolbar-plugin.js +10 -10
- package/dist/components/editor/plugins/toolbar/toolbar-plugin.js +9 -9
- package/dist/components/ui/app-checkbox.js +1 -1
- package/dist/components/ui/app-dialog.js +70 -64
- package/dist/components/ui/app-editor.js +51 -51
- package/dist/components/ui/app-form.js +81 -81
- package/dist/components/ui/app-multiple-select-dropdown.js +36 -36
- package/dist/components/ui/app-select.js +109 -104
- package/dist/components/ui/app-sidebar.js +41 -41
- package/dist/components/ui/app-stepper.js +1 -1
- package/dist/components/ui/app-time-picker.js +18 -18
- package/dist/components/ui/app-tooltip.js +1 -1
- package/dist/components/ui/async-select.js +5 -5
- package/dist/components/ui/audio-visualizer.js +61 -58
- package/dist/components/ui/card.js +1 -1
- package/dist/components/ui/carousel.js +2 -2
- package/dist/components/ui/chart.js +1 -1
- package/dist/components/ui/chat-message.js +8 -8
- package/dist/components/ui/chat.js +86 -88
- package/dist/components/ui/command.js +2 -2
- package/dist/components/ui/copy-button.js +4 -4
- package/dist/components/ui/date-picker.js +20 -20
- package/dist/components/ui/file-preview/index.js +13 -13
- package/dist/components/ui/file-previewer.js +12 -11
- package/dist/components/ui/file-uploader.js +86 -78
- package/dist/components/ui/form.js +2 -2
- package/dist/components/ui/gantt/components/Chart/Bars/Bars.js +56 -56
- package/dist/components/ui/gantt/components/Chart/Bars/BarsRow/BarItem/BarItem.js +12 -12
- package/dist/components/ui/gantt/components/Chart/Bars/BarsRow/BarsItems/BarItems.js +1 -1
- package/dist/components/ui/gantt/components/Chart/Bars/BarsRow/BarsRow.js +4 -4
- package/dist/components/ui/gantt/components/Chart/Bars/BarsRow/RepeteadBars/RepeteadBars.js +2 -2
- package/dist/components/ui/gantt/components/Chart/Chart.js +23 -23
- package/dist/components/ui/gantt/components/Chart/Scale/Scale.js +1 -1
- package/dist/components/ui/gantt/components/Chart/Tree/Tree.js +34 -34
- package/dist/components/ui/gantt/components/Controls/Controls.js +5 -5
- package/dist/components/ui/gantt/components/Gantt/Gantt.js +4 -4
- package/dist/components/ui/gantt/hooks/useGanttCalculate.js +25 -18
- package/dist/components/ui/input-selector.js +1 -1
- package/dist/components/ui/input.js +23 -23
- package/dist/components/ui/kanban.js +8 -9
- package/dist/components/ui/markdown-renderer.js +41 -35
- package/dist/components/ui/message-input.js +45 -44
- package/dist/components/ui/multiple-selector.js +91 -82
- package/dist/components/ui/secure-pdf-viewer.js +19 -7
- package/dist/components/ui/sidebar.js +1 -1
- package/dist/components/ui/slider.js +1 -1
- package/dist/components/ui/spinner.js +4 -4
- package/dist/components/ui/stepper.js +157 -138
- package/dist/components/ui/tables/data-cross-table/data-cross-table-buttons.js +29 -29
- package/dist/components/ui/tables/data-cross-table/data-cross-table.js +258 -246
- package/dist/components/ui/tables/data-table/components/data-table-advanced-filter.js +4 -1
- package/dist/components/ui/tables/data-table/components/data-table-body.js +211 -367
- package/dist/components/ui/tables/data-table/components/data-table-filter-inputs.js +114 -112
- package/dist/components/ui/tables/data-table/components/data-table-filters.js +116 -96
- package/dist/components/ui/tables/data-table/components/data-table-header.js +211 -0
- package/dist/components/ui/tables/data-table/components/data-table-searchbar.js +8 -8
- package/dist/components/ui/tables/data-table/components/data-table-skeleton-rows.js +33 -0
- package/dist/components/ui/tables/data-table/data-table.js +258 -250
- package/dist/components/ui/tables/data-table/data-table.service.js +112 -97
- package/dist/components/ui/tables/data-table/data-table.utils.js +25 -15
- package/dist/components/ui/textarea.js +2 -2
- package/dist/components/ui/theme-switcher.js +1 -1
- package/dist/components/ui/toggle-group.js +2 -2
- package/dist/components/ui/truncated-cell.js +100 -0
- package/dist/components/ui/weekly-calendar/appointment-card.js +16 -16
- package/dist/components/ui/weekly-calendar/calendar-context.js +6 -6
- package/dist/components/ui/weekly-calendar/calendar-header.js +12 -12
- package/dist/components/ui/weekly-calendar/day-column.js +16 -16
- package/dist/components/ui/weekly-calendar/time-column.js +4 -4
- package/dist/components/ui/weekly-calendar/weekly-calendar.js +4 -4
- package/dist/hooks/use-audio-recording.js +1 -1
- package/dist/hooks/use-auto-scroll.js +18 -18
- package/dist/hooks/use-autosize-textarea.js +12 -13
- package/dist/index.d.ts +100 -45
- package/dist/index.js +362 -360
- package/dist/lib/utils.js +6 -6
- package/dist/styles.v3.css +1 -1
- package/package.json +14 -4
|
@@ -1,97 +1,94 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
- **Bounds UX**: The slight vibration on bound hit provides feedback without changing the value.
|
|
96
|
-
- **Styling**: Prefer design tokens (`bg-d-*`, `text-d-*`) over raw colors.
|
|
97
|
-
|
|
1
|
+
# InputSelector
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Compact numeric selector with increment/decrement buttons, value bounds, and subtle animations. Useful for choosing small integer quantities (e.g., seats, guests).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| ------------------ | ------------------------- | ----------- | -------------------------------- |
|
|
13
|
+
| `value` | `number` | `1` | Current numeric value. |
|
|
14
|
+
| `onChange` | `(value: number) => void` | `undefined` | Called with the new value. |
|
|
15
|
+
| `min` | `number` | `1` | Minimum allowed value. |
|
|
16
|
+
| `max` | `number` | `4` | Maximum allowed value. |
|
|
17
|
+
| `className` | `string` | `""` | Wrapper classes. |
|
|
18
|
+
| `buttonClassName` | `string` | `""` | Classes for +/- buttons. |
|
|
19
|
+
| `counterClassName` | `string` | `""` | Classes for the numeric counter. |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Behavior
|
|
24
|
+
|
|
25
|
+
- **Controlled**: `value` is controlled; emits `onChange(newValue)` on clicks within bounds.
|
|
26
|
+
- **Bounds**: At min or max, the component vibrates (subtle shake animation) instead of changing value.
|
|
27
|
+
- **A11y**: Buttons are real `<button>` elements with clear `+`/`-` labels.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+
### Basic
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { useState } from "react";
|
|
37
|
+
import { InputSelector } from "laif-ds";
|
|
38
|
+
|
|
39
|
+
export function BasicSelector() {
|
|
40
|
+
const [value, setValue] = useState(2);
|
|
41
|
+
|
|
42
|
+
return <InputSelector value={value} onChange={setValue} min={1} max={4} />;
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Controlled
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { useState } from "react";
|
|
50
|
+
import { InputSelector } from "laif-ds";
|
|
51
|
+
|
|
52
|
+
export function ControlledSelector() {
|
|
53
|
+
const [value, setValue] = useState(2);
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div className="flex flex-col items-center gap-2">
|
|
57
|
+
<InputSelector value={value} onChange={setValue} min={1} max={6} />
|
|
58
|
+
<div className="text-d-secondary-foreground text-sm">
|
|
59
|
+
Current value: {value}
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Custom Styling
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { useState } from "react";
|
|
70
|
+
import { InputSelector } from "laif-ds";
|
|
71
|
+
|
|
72
|
+
export function CustomStyledSelector() {
|
|
73
|
+
const [value, setValue] = useState(2);
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<InputSelector
|
|
77
|
+
value={value}
|
|
78
|
+
onChange={setValue}
|
|
79
|
+
min={1}
|
|
80
|
+
max={4}
|
|
81
|
+
className="bg-d-secondary/10 rounded-xl p-6"
|
|
82
|
+
buttonClassName="bg-d-primary text-d-primary-foreground hover:bg-d-primary/90 border-0"
|
|
83
|
+
counterClassName="text-d-primary font-bold"
|
|
84
|
+
/>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Notes
|
|
92
|
+
|
|
93
|
+
- **Bounds UX**: The slight vibration on bound hit provides feedback without changing the value.
|
|
94
|
+
- **Styling**: Prefer design tokens (`bg-d-*`, `text-d-*`) over raw colors.
|
|
@@ -8,10 +8,10 @@ Animated prompt that appears to allow interrupting an action (e.g., hitting Ente
|
|
|
8
8
|
|
|
9
9
|
## Props
|
|
10
10
|
|
|
11
|
-
| Prop
|
|
12
|
-
|
|
|
13
|
-
| `isOpen` | `boolean`
|
|
14
|
-
| `close`
|
|
11
|
+
| Prop | Type | Description |
|
|
12
|
+
| -------- | ------------ | ----------------------------- |
|
|
13
|
+
| `isOpen` | `boolean` | Whether the prompt is visible |
|
|
14
|
+
| `close` | `() => void` | Close handler |
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
@@ -11,10 +11,13 @@ Renders Markdown with GitHub-flavored Markdown (GFM) and async syntax highlighti
|
|
|
11
11
|
```tsx
|
|
12
12
|
import { MarkdownRenderer } from "laif-ds";
|
|
13
13
|
|
|
14
|
-
const content =
|
|
14
|
+
const content =
|
|
15
|
+
`
|
|
15
16
|
# Hello
|
|
16
17
|
|
|
17
|
-
Some ` +
|
|
18
|
+
Some ` +
|
|
19
|
+
"`code`" +
|
|
20
|
+
` and a list:
|
|
18
21
|
|
|
19
22
|
- Item A
|
|
20
23
|
- Item B
|
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
1
|
+
# Menubar
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Top-level horizontal application menu built on Radix Menubar. Supports nested submenus, checkbox and radio items, separators, and keyboard navigation.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Subcomponents & Props
|
|
10
|
+
|
|
11
|
+
- **Menubar**: Root container. Extends `@radix-ui/react-menubar` Root props.
|
|
12
|
+
- **MenubarMenu**: Wraps a single menu.
|
|
13
|
+
- **MenubarTrigger**: Button that opens its menu.
|
|
14
|
+
- **MenubarContent**: The floating panel with items.
|
|
15
|
+
- `align`: `start | center | end` (default `start`)
|
|
16
|
+
- `alignOffset`: `number` (default `-4`)
|
|
17
|
+
- `sideOffset`: `number` (default `8`)
|
|
18
|
+
- **MenubarItem**: Clickable action item.
|
|
19
|
+
- `variant`: `"default" | "destructive"` (default `"default"`)
|
|
20
|
+
- `inset`: `boolean` (indent the item)
|
|
21
|
+
- **MenubarCheckboxItem**: Checkbox item.
|
|
22
|
+
- `checked`: `boolean`
|
|
23
|
+
- **MenubarRadioGroup**: Groups radio items.
|
|
24
|
+
- `value`, `onValueChange`: controlled selection
|
|
25
|
+
- **MenubarRadioItem**: Radio item in a group.
|
|
26
|
+
- **MenubarLabel**: Non-interactive label.
|
|
27
|
+
- **MenubarSeparator**: Horizontal separator.
|
|
28
|
+
- **MenubarShortcut**: Right-aligned keyboard shortcut hint.
|
|
29
|
+
- **MenubarSub / MenubarSubTrigger / MenubarSubContent**: Submenu primitives.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Behavior
|
|
34
|
+
|
|
35
|
+
- **Keyboard navigation**: Arrow keys to move between triggers and items, Enter/Space to select.
|
|
36
|
+
- **States**: Triggers reflect open/focus states. `variant="destructive"` styles an item for dangerous actions.
|
|
37
|
+
- **Accessibility**: Proper roles and aria attributes via Radix primitives.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
41
|
## Examples
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
### Basic
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
```tsx
|
|
46
46
|
import {
|
|
47
47
|
Menubar,
|
|
@@ -87,9 +87,9 @@ export function BasicMenubar() {
|
|
|
87
87
|
);
|
|
88
88
|
}
|
|
89
89
|
```
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
### With Groups and Radios
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
```tsx
|
|
94
94
|
import {
|
|
95
95
|
Menubar,
|
|
@@ -121,9 +121,9 @@ export function MenubarWithGroups() {
|
|
|
121
121
|
);
|
|
122
122
|
}
|
|
123
123
|
```
|
|
124
|
-
|
|
124
|
+
|
|
125
125
|
### Destructive Item
|
|
126
|
-
|
|
126
|
+
|
|
127
127
|
```tsx
|
|
128
128
|
import {
|
|
129
129
|
Menubar,
|
|
@@ -141,8 +141,12 @@ export function DestructiveExample() {
|
|
|
141
141
|
<MenubarMenu>
|
|
142
142
|
<MenubarTrigger>Actions</MenubarTrigger>
|
|
143
143
|
<MenubarContent>
|
|
144
|
-
<MenubarItem>
|
|
145
|
-
|
|
144
|
+
<MenubarItem>
|
|
145
|
+
Copy <MenubarShortcut>⌘C</MenubarShortcut>
|
|
146
|
+
</MenubarItem>
|
|
147
|
+
<MenubarItem>
|
|
148
|
+
Paste <MenubarShortcut>⌘V</MenubarShortcut>
|
|
149
|
+
</MenubarItem>
|
|
146
150
|
<MenubarSeparator />
|
|
147
151
|
<MenubarItem variant="destructive">
|
|
148
152
|
Delete <MenubarShortcut>⌘⌫</MenubarShortcut>
|
|
@@ -153,12 +157,11 @@ export function DestructiveExample() {
|
|
|
153
157
|
);
|
|
154
158
|
}
|
|
155
159
|
```
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Notes
|
|
164
|
+
|
|
165
|
+
- **Composition**: Combine subcomponents to build complex menus.
|
|
166
|
+
- **Shortcuts**: Use `MenubarShortcut` for right-aligned hints.
|
|
167
|
+
- **A11y**: Labels and roles are handled by Radix primitives and DS styling.
|
|
@@ -1,131 +1,134 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
1
|
+
# MessageInput
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Chat composer with autosizing textarea, optional file attachments, voice input (record/transcribe), and intelligent Enter-to-send behavior with interruption prompts.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
Extends native `<textarea>` props.
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
| ------------------ | ------------------------------------------- | ------------ | -------------------------------------------------------------------- | ------------------------------------------------- |
|
|
15
|
+
| `value` | `string` | **required** | Controlled text value. |
|
|
16
|
+
| `isGenerating` | `boolean` | `false` | If true, shows stop button and may display interrupt prompt. |
|
|
17
|
+
| `submitOnEnter` | `boolean` | `true` | Press Enter to submit (Shift+Enter for newline). |
|
|
18
|
+
| `stop` | `() => void` | `undefined` | Stop generation handler (used with `isGenerating`). |
|
|
19
|
+
| `enableInterrupt` | `boolean` | `true` | If true, pressing Enter while generating shows confirm to interrupt. |
|
|
20
|
+
| `transcribeAudio` | `(blob: Blob) => Promise<string>` | `undefined` | Optional audio-to-text function. |
|
|
21
|
+
| `allowAttachments` | `boolean` | `false` | Enable file attachments UI. |
|
|
22
|
+
| `files` | `File[] | null` | `null` | Current attached files (when `allowAttachments`). |
|
|
23
|
+
| `setFiles` | `React.Dispatch<React.SetStateAction<File[] | null>>` | `undefined` | Setter for attachments. |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Behavior
|
|
28
|
+
|
|
29
|
+
- **Enter to submit**: If `submitOnEnter` and not `shiftKey`, calls `form.requestSubmit()`.
|
|
30
|
+
- **Interrupt flow**: If `isGenerating` and `stop` and `enableInterrupt`, pressing Enter shows a prompt to confirm stopping the generation and sending the new message.
|
|
31
|
+
- **Autosize**: Textarea grows up to a max height, then scrolls.
|
|
32
|
+
- **Attachments**: Drag & drop, paste files; long pasted text (> 500 chars) becomes a text file. Uses `FilePreview` to show chips.
|
|
33
|
+
- **Voice input**: If supported, toggles microphone recording; shows visualizer while recording and a "transcribing" overlay after.
|
|
34
|
+
- **Actions**: Right-aligned action buttons: attach, mic, send/stop.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Examples
|
|
39
|
+
|
|
40
|
+
### Basic
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import * as React from "react";
|
|
44
|
+
import { MessageInput } from "laif-ds";
|
|
45
|
+
|
|
46
|
+
export function BasicComposer() {
|
|
47
|
+
const [value, setValue] = React.useState("");
|
|
48
|
+
const onSubmit = (e: React.FormEvent) => {
|
|
49
|
+
e.preventDefault();
|
|
50
|
+
console.log("Messaggio inviato:", value);
|
|
51
|
+
setValue("");
|
|
52
|
+
};
|
|
53
|
+
return (
|
|
54
|
+
<form onSubmit={onSubmit} className="w-full max-w-2xl">
|
|
55
|
+
<MessageInput
|
|
56
|
+
value={value}
|
|
57
|
+
onChange={(e) => setValue(e.target.value)}
|
|
58
|
+
isGenerating={false}
|
|
59
|
+
/>
|
|
60
|
+
</form>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### With Attachments
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
import * as React from "react";
|
|
69
|
+
import { MessageInput } from "laif-ds";
|
|
70
|
+
|
|
71
|
+
export function WithAttachments() {
|
|
72
|
+
const [value, setValue] = React.useState("");
|
|
73
|
+
const [files, setFiles] = React.useState<File[] | null>(null);
|
|
74
|
+
const onSubmit = (e: React.FormEvent) => {
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
console.log("Messaggio inviato:", value, files);
|
|
77
|
+
setValue("");
|
|
78
|
+
setFiles(null);
|
|
79
|
+
};
|
|
80
|
+
return (
|
|
81
|
+
<form onSubmit={onSubmit} className="w-full max-w-2xl">
|
|
82
|
+
<MessageInput
|
|
83
|
+
value={value}
|
|
84
|
+
onChange={(e) => setValue(e.target.value)}
|
|
85
|
+
isGenerating={false}
|
|
86
|
+
allowAttachments
|
|
87
|
+
files={files}
|
|
88
|
+
setFiles={setFiles}
|
|
89
|
+
placeholder="Scrivi un messaggio o trascina file qui..."
|
|
90
|
+
/>
|
|
91
|
+
</form>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Generating + Interrupt
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
import * as React from "react";
|
|
100
|
+
import { MessageInput } from "laif-ds";
|
|
101
|
+
|
|
102
|
+
export function Generating() {
|
|
103
|
+
const [value, setValue] = React.useState("");
|
|
104
|
+
const [isGenerating, setIsGenerating] = React.useState(true);
|
|
105
|
+
const stop = () => setIsGenerating(false);
|
|
106
|
+
const onSubmit = (e: React.FormEvent) => {
|
|
107
|
+
e.preventDefault();
|
|
108
|
+
if (isGenerating) return;
|
|
109
|
+
console.log("Messaggio inviato:", value);
|
|
110
|
+
setValue("");
|
|
111
|
+
setIsGenerating(true);
|
|
112
|
+
setTimeout(() => setIsGenerating(false), 3000);
|
|
113
|
+
};
|
|
114
|
+
return (
|
|
115
|
+
<form onSubmit={onSubmit} className="w-full max-w-2xl">
|
|
116
|
+
<MessageInput
|
|
117
|
+
value={value}
|
|
118
|
+
onChange={(e) => setValue(e.target.value)}
|
|
119
|
+
isGenerating={isGenerating}
|
|
120
|
+
stop={stop}
|
|
121
|
+
placeholder="L'AI sta generando una risposta..."
|
|
122
|
+
/>
|
|
123
|
+
</form>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Notes
|
|
131
|
+
|
|
132
|
+
- **File preview**: Uses `FilePreview` for attachment chips.
|
|
133
|
+
- **Paste handling**: Long text paste becomes a `.txt` file when attachments are enabled.
|
|
134
|
+
- **A11y**: Textarea has aria-label; action buttons have aria-labels as well.
|