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,139 +1,138 @@
1
- # FilePreviewer
2
-
3
- ## Overview
4
-
5
- Modal file preview component with support for images, PDFs (including secure read-only mode), audio, video, text, and Office documents (via online viewers). Use helper functions to open the modal from anywhere; mount the component once.
6
-
7
- ---
8
-
9
- ## API
10
-
11
- ### Functions
12
-
13
- | Function | Signature | Description |
14
- | ----------------------- | ------------------------------------------------------------- | --------------------------------------------------------- |
15
- | `previewFileModal` | `(arg: string | PreviewOptions) => Promise<void>` | Opens the preview modal. Resolves when closed. |
16
- | `safePreviewFileModal` | `(arg: string | PreviewOptions) => Promise<void | undefined>` | Safe variant that never throws on close. |
17
-
18
- ```ts
19
- export type PreviewOptions = {
20
- url?: string;
21
- filename?: string;
22
- mimeType?: string;
23
- title?: React.ReactNode;
24
- readOnly?: boolean; // Enables SecurePdfViewer for PDFs
25
- page?: number; // Initial page for PDFs (1-based)
26
- };
27
- ```
28
-
29
- ### Component
30
-
31
- - `FilePreviewer`: Mount once near the app root. Controls the dialog UI and renders the appropriate preview body.
32
-
33
- ---
34
-
35
- ## Behavior
36
-
37
- - **Kind detection**: Determines preview type from `mimeType`, `filename` or `url`.
38
- - **Image**: Responsive `<img>` with contain fit.
39
- - **PDF**:
40
- - `readOnly=true` uses `SecurePdfViewer` with `page` support.
41
- - Otherwise embedded via `<iframe>` (supports `#page=` parameter).
42
- - **Audio/Video**: Native `<audio>`/`<video>` players.
43
- - **Text**: Rendered in an `<iframe>` for remote text URLs.
44
- - **Office**: Uses an online viewer when `url` is HTTP(S); otherwise shows a fallback notice.
45
- - **Dialog**: Uses `Dialog` with `size="xl"` and a heading showing `title` or `filename` with a file icon.
46
-
47
- ---
48
-
49
- ## Examples
50
-
51
- ### Preview an Image (URL)
52
-
53
- ```tsx
54
- import { Button } from "laif-ds";
55
- import { FilePreviewer, previewFileModal } from "laif-ds";
56
-
57
- export function PreviewImageButton() {
58
- return (
59
- <>
60
- <Button
61
- onClick={() =>
62
- previewFileModal({
63
- url: "https://picsum.photos/id/1003/1200/800",
64
- filename: "image.jpg",
65
- title: "Random Image",
66
- })
67
- }
68
- >
69
- Preview Image
70
- </Button>
71
- <FilePreviewer />
72
- </>
73
- );
74
- }
75
- ```
76
-
77
- ### PDF with Read-only Secure Viewer
78
-
79
- ```tsx
80
- import { Button } from "laif-ds";
81
- import { FilePreviewer, previewFileModal } from "laif-ds";
82
-
83
- export function PreviewPdf() {
84
- return (
85
- <>
86
- <Button
87
- onClick={() =>
88
- previewFileModal({
89
- url: "https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf",
90
- filename: "dummy.pdf",
91
- title: "PDF Document",
92
- readOnly: true,
93
- page: 1,
94
- })
95
- }
96
- >
97
- Preview PDF
98
- </Button>
99
- <FilePreviewer />
100
- </>
101
- );
102
- }
103
- ```
104
-
105
- ### Office Document (XLSX)
106
-
107
- ```tsx
108
- import { Button } from "laif-ds";
109
- import { FilePreviewer, previewFileModal } from "laif-ds";
110
-
111
- export function PreviewSpreadsheet() {
112
- return (
113
- <>
114
- <Button
115
- onClick={() =>
116
- previewFileModal({
117
- url: "https://filesamples.com/samples/document/xlsx/sample3.xlsx",
118
- filename: "spreadsheet.xlsx",
119
- title: "Excel Spreadsheet",
120
- readOnly: true,
121
- })
122
- }
123
- >
124
- Preview XLSX
125
- </Button>
126
- <FilePreviewer />
127
- </>
128
- );
129
- }
130
- ```
131
-
132
- ---
133
-
134
- ## Notes
135
-
136
- - **Mount**: Add a single `<FilePreviewer />` near app root or in Storybook decorators.
137
- - **Filenames**: If `filename` is omitted, it is inferred from `url`.
138
- - **Security**: For local files, prefer read-only mode for PDFs when appropriate.
139
-
1
+ # FilePreviewer
2
+
3
+ ## Overview
4
+
5
+ Modal file preview component with support for images, PDFs (including secure read-only mode), audio, video, text, and Office documents (via online viewers). Use helper functions to open the modal from anywhere; mount the component once.
6
+
7
+ ---
8
+
9
+ ## API
10
+
11
+ ### Functions
12
+
13
+ | Function | Signature | Description |
14
+ | ---------------------- | ------------- | --------------------------------- | ---------------------------------------------- | ---------------------------------------- |
15
+ | `previewFileModal` | `(arg: string | PreviewOptions) => Promise<void>` | Opens the preview modal. Resolves when closed. |
16
+ | `safePreviewFileModal` | `(arg: string | PreviewOptions) => Promise<void | undefined>` | Safe variant that never throws on close. |
17
+
18
+ ```ts
19
+ export type PreviewOptions = {
20
+ url?: string;
21
+ filename?: string;
22
+ mimeType?: string;
23
+ title?: React.ReactNode;
24
+ readOnly?: boolean; // Enables SecurePdfViewer for PDFs
25
+ page?: number; // Initial page for PDFs (1-based)
26
+ };
27
+ ```
28
+
29
+ ### Component
30
+
31
+ - `FilePreviewer`: Mount once near the app root. Controls the dialog UI and renders the appropriate preview body.
32
+
33
+ ---
34
+
35
+ ## Behavior
36
+
37
+ - **Kind detection**: Determines preview type from `mimeType`, `filename` or `url`.
38
+ - **Image**: Responsive `<img>` with contain fit.
39
+ - **PDF**:
40
+ - `readOnly=true` uses `SecurePdfViewer` with `page` support.
41
+ - Otherwise embedded via `<iframe>` (supports `#page=` parameter).
42
+ - **Audio/Video**: Native `<audio>`/`<video>` players.
43
+ - **Text**: Rendered in an `<iframe>` for remote text URLs.
44
+ - **Office**: Uses an online viewer when `url` is HTTP(S); otherwise shows a fallback notice.
45
+ - **Dialog**: Uses `Dialog` with `size="xl"` and a heading showing `title` or `filename` with a file icon.
46
+
47
+ ---
48
+
49
+ ## Examples
50
+
51
+ ### Preview an Image (URL)
52
+
53
+ ```tsx
54
+ import { Button } from "laif-ds";
55
+ import { FilePreviewer, previewFileModal } from "laif-ds";
56
+
57
+ export function PreviewImageButton() {
58
+ return (
59
+ <>
60
+ <Button
61
+ onClick={() =>
62
+ previewFileModal({
63
+ url: "https://picsum.photos/id/1003/1200/800",
64
+ filename: "image.jpg",
65
+ title: "Random Image",
66
+ })
67
+ }
68
+ >
69
+ Preview Image
70
+ </Button>
71
+ <FilePreviewer />
72
+ </>
73
+ );
74
+ }
75
+ ```
76
+
77
+ ### PDF with Read-only Secure Viewer
78
+
79
+ ```tsx
80
+ import { Button } from "laif-ds";
81
+ import { FilePreviewer, previewFileModal } from "laif-ds";
82
+
83
+ export function PreviewPdf() {
84
+ return (
85
+ <>
86
+ <Button
87
+ onClick={() =>
88
+ previewFileModal({
89
+ url: "https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf",
90
+ filename: "dummy.pdf",
91
+ title: "PDF Document",
92
+ readOnly: true,
93
+ page: 1,
94
+ })
95
+ }
96
+ >
97
+ Preview PDF
98
+ </Button>
99
+ <FilePreviewer />
100
+ </>
101
+ );
102
+ }
103
+ ```
104
+
105
+ ### Office Document (XLSX)
106
+
107
+ ```tsx
108
+ import { Button } from "laif-ds";
109
+ import { FilePreviewer, previewFileModal } from "laif-ds";
110
+
111
+ export function PreviewSpreadsheet() {
112
+ return (
113
+ <>
114
+ <Button
115
+ onClick={() =>
116
+ previewFileModal({
117
+ url: "https://filesamples.com/samples/document/xlsx/sample3.xlsx",
118
+ filename: "spreadsheet.xlsx",
119
+ title: "Excel Spreadsheet",
120
+ readOnly: true,
121
+ })
122
+ }
123
+ >
124
+ Preview XLSX
125
+ </Button>
126
+ <FilePreviewer />
127
+ </>
128
+ );
129
+ }
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Notes
135
+
136
+ - **Mount**: Add a single `<FilePreviewer />` near app root or in Storybook decorators.
137
+ - **Filenames**: If `filename` is omitted, it is inferred from `url`.
138
+ - **Security**: For local files, prefer read-only mode for PDFs when appropriate.
@@ -1,129 +1,149 @@
1
- # FileUploader
2
-
3
- ## Overview
4
-
5
- Drag-and-drop uploader with keyboard activation, file type filtering, limits (count/total size), previews via `FilePreview`, and external upload integration.
6
-
7
- ---
8
-
9
- ## Props
10
-
11
- | Prop | Type | Default | Description |
12
- | ------------------ | --------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------- |
13
- | `extensions` | `AcceptItem[]` | `["pdf","image","video","audio"]` | Allowed extensions/categories (maps to accept attribute). |
14
- | `multiple` | `boolean` | `false` | Enables multiple file selection. |
15
- | `onUpload` | `(files: File[]) => void` | `undefined` | Called whenever selected files change. |
16
- | `description` | `string` | `"Trascina un file o clicca per selezionare"` | Dropzone hint. |
17
- | `formatDescription`| `string` | `"Formato accettato: PDF, Immagini, Video, Audio"` | Accepted formats hint. |
18
- | `selectedLabel` | `string` | `"File selezionati"` | Title shown above selected files list. |
19
- | `removeAllLabel` | `string` | `"rimuovi tutto"` | Label for the "remove all" button. |
20
- | `maxTotalSize` | `number` (bytes) | `undefined` | Maximum total size of selected files. |
21
- | `maxFiles` | `number` | `undefined` | Maximum number of files (when `multiple` is true). |
22
-
23
- `AcceptItem` includes: `pdf | doc | docx | xls | xlsx | ppt | pptx | txt | csv | jpg | jpeg | png | gif | image | video | audio`.
24
-
25
- ---
26
-
27
- ## Behavior
28
-
29
- - **Dropzone**: Click or drag files; keyboard accessible (Enter/Space opens file dialog).
30
- - **Filtering**: `extensions` map to accept string; only matching files are added.
31
- - **Limits**: Enforces `maxFiles` and `maxTotalSize` (with compact error caption).
32
- - **Previews**: Renders selected files with `FilePreview`; supports remove per file and remove-all.
33
- - **Integration**: `onUpload` provides the current `File[]`; perform the actual upload externally.
34
-
35
- ---
36
-
37
- ## Examples
38
-
39
- ### Default
40
-
41
- ```tsx
42
- import { FileUploader } from "laif-ds";
43
-
44
- export function DefaultUploader() {
45
- return <FileUploader multiple={false} />;
46
- }
47
- ```
48
-
49
- ### Multiple + Custom Extensions
50
-
51
- ```tsx
52
- import { FileUploader, type AcceptItem } from "laif-ds";
53
-
54
- const exts: AcceptItem[] = [
55
- "pdf","doc","docx","xls","xlsx","ppt","pptx","txt","csv","jpg","jpeg","png","gif","image","video","audio",
56
- ];
57
-
58
- export function MultiUploader() {
59
- return (
60
- <FileUploader
61
- multiple
62
- extensions={exts}
63
- description="Seleziona più file"
64
- formatDescription="Trascina o clicca per selezionare più file"
65
- />
66
- );
67
- }
68
- ```
69
-
70
- ### With Limits
71
-
72
- ```tsx
73
- import { FileUploader } from "laif-ds";
74
-
75
- export function LimitedUploader() {
76
- return (
77
- <FileUploader
78
- multiple
79
- maxFiles={3}
80
- maxTotalSize={10 * 1024 * 1024} // 10 MB
81
- description="Con limiti su numero e dimensione totale"
82
- formatDescription="Esempio: max 3 file, max totale 10 MB"
83
- />
84
- );
85
- }
86
- ```
87
-
88
- ### External Upload Flow
89
-
90
- ```tsx
91
- import * as React from "react";
92
- import { Button } from "laif-ds";
93
- import { FileUploader } from "laif-ds";
94
-
95
- export function ExternalUploadExample() {
96
- const [files, setFiles] = React.useState<File[]>([]);
97
- const [loading, setLoading] = React.useState(false);
98
-
99
- const handleSubmit = async () => {
100
- setLoading(true);
101
- // ...upload files
102
- await new Promise((r) => setTimeout(r, 1500));
103
- setLoading(false);
104
- alert(`Upload completato: ${files.length} file`);
105
- };
106
-
107
- return (
108
- <div className="space-y-4">
109
- <FileUploader multiple onUpload={setFiles} />
110
- {files.length > 0 && (
111
- <div className="flex justify-end">
112
- <Button onClick={handleSubmit} isLoading={loading} iconLeft="Upload">
113
- {loading ? "Caricamento..." : `Carica ${files.length} file`}
114
- </Button>
115
- </div>
116
- )}
117
- </div>
118
- );
119
- }
120
- ```
121
-
122
- ---
123
-
124
- ## Notes
125
-
126
- - **A11y**: Dropzone is a button-like region with `aria-describedby` hints and keyboard support.
127
- - **Errors**: Limit violations are summarized in a compact caption.
128
- - **Localization**: Provide localized `description`/`formatDescription`/labels when needed.
129
-
1
+ # FileUploader
2
+
3
+ ## Overview
4
+
5
+ Drag-and-drop uploader with keyboard activation, file type filtering, limits (count/total size), previews via `FilePreview`, and external upload integration.
6
+
7
+ ---
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | ------------------- | ------------------------- | -------------------------------------------------- | --------------------------------------------------------- |
13
+ | `extensions` | `AcceptItem[]` | `["pdf","image","video","audio"]` | Allowed extensions/categories (maps to accept attribute). |
14
+ | `multiple` | `boolean` | `false` | Enables multiple file selection. |
15
+ | `onUpload` | `(files: File[]) => void` | `undefined` | Called whenever selected files change. |
16
+ | `description` | `string` | `"Trascina un file o clicca per selezionare"` | Dropzone hint. |
17
+ | `formatDescription` | `string` | `"Formato accettato: PDF, Immagini, Video, Audio"` | Accepted formats hint. |
18
+ | `selectedLabel` | `string` | `"File selezionati"` | Title shown above selected files list. |
19
+ | `removeAllLabel` | `string` | `"rimuovi tutto"` | Label for the "remove all" button. |
20
+ | `maxTotalSize` | `number` (bytes) | `undefined` | Maximum total size of selected files. |
21
+ | `maxFiles` | `number` | `undefined` | Maximum number of files (when `multiple` is true). |
22
+
23
+ `AcceptItem` includes: `pdf | doc | docx | xls | xlsx | ppt | pptx | txt | csv | jpg | jpeg | png | gif | image | video | audio | zip | rar | 7z | tar | gz | tgz`.
24
+
25
+ ---
26
+
27
+ ## Behavior
28
+
29
+ - **Dropzone**: Click or drag files; keyboard accessible (Enter/Space opens file dialog).
30
+ - **Filtering**: `extensions` map to accept string; only matching files are added.
31
+ - **Limits**: Enforces `maxFiles` and `maxTotalSize` (with compact error caption).
32
+ - **Previews**: Renders selected files with `FilePreview`; supports remove per file and remove-all.
33
+ - **Integration**: `onUpload` provides the current `File[]`; perform the actual upload externally.
34
+
35
+ ---
36
+
37
+ ## Examples
38
+
39
+ ### Default
40
+
41
+ ```tsx
42
+ import { FileUploader } from "laif-ds";
43
+
44
+ export function DefaultUploader() {
45
+ return <FileUploader multiple={false} />;
46
+ }
47
+ ```
48
+
49
+ ### Multiple + Custom Extensions
50
+
51
+ ```tsx
52
+ import { FileUploader, type AcceptItem } from "laif-ds";
53
+
54
+ const exts: AcceptItem[] = [
55
+ "pdf",
56
+ "doc",
57
+ "docx",
58
+ "xls",
59
+ "xlsx",
60
+ "ppt",
61
+ "pptx",
62
+ "txt",
63
+ "csv",
64
+ "jpg",
65
+ "jpeg",
66
+ "png",
67
+ "gif",
68
+ "image",
69
+ "video",
70
+ "audio",
71
+ "zip",
72
+ "rar",
73
+ "7z",
74
+ "tar",
75
+ "gz",
76
+ "tgz",
77
+ ];
78
+
79
+ export function MultiUploader() {
80
+ return (
81
+ <FileUploader
82
+ multiple
83
+ extensions={exts}
84
+ description="Seleziona più file"
85
+ formatDescription="Trascina o clicca per selezionare più file"
86
+ />
87
+ );
88
+ }
89
+ ```
90
+
91
+ ### With Limits
92
+
93
+ ```tsx
94
+ import { FileUploader } from "laif-ds";
95
+
96
+ export function LimitedUploader() {
97
+ return (
98
+ <FileUploader
99
+ multiple
100
+ maxFiles={3}
101
+ maxTotalSize={10 * 1024 * 1024} // 10 MB
102
+ description="Con limiti su numero e dimensione totale"
103
+ formatDescription="Esempio: max 3 file, max totale 10 MB"
104
+ />
105
+ );
106
+ }
107
+ ```
108
+
109
+ ### External Upload Flow
110
+
111
+ ```tsx
112
+ import * as React from "react";
113
+ import { Button } from "laif-ds";
114
+ import { FileUploader } from "laif-ds";
115
+
116
+ export function ExternalUploadExample() {
117
+ const [files, setFiles] = React.useState<File[]>([]);
118
+ const [loading, setLoading] = React.useState(false);
119
+
120
+ const handleSubmit = async () => {
121
+ setLoading(true);
122
+ // ...upload files
123
+ await new Promise((r) => setTimeout(r, 1500));
124
+ setLoading(false);
125
+ alert(`Upload completato: ${files.length} file`);
126
+ };
127
+
128
+ return (
129
+ <div className="space-y-4">
130
+ <FileUploader multiple onUpload={setFiles} />
131
+ {files.length > 0 && (
132
+ <div className="flex justify-end">
133
+ <Button onClick={handleSubmit} isLoading={loading} iconLeft="Upload">
134
+ {loading ? "Caricamento..." : `Carica ${files.length} file`}
135
+ </Button>
136
+ </div>
137
+ )}
138
+ </div>
139
+ );
140
+ }
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Notes
146
+
147
+ - **A11y**: Dropzone is a button-like region with `aria-describedby` hints and keyboard support.
148
+ - **Errors**: Limit violations are summarized in a compact caption.
149
+ - **Localization**: Provide localized `description`/`formatDescription`/labels when needed.
@@ -54,7 +54,9 @@ export function ProfileForm() {
54
54
  </FormItem>
55
55
  )}
56
56
  />
57
- <Button type="submit" className="mt-4">Save</Button>
57
+ <Button type="submit" className="mt-4">
58
+ Save
59
+ </Button>
58
60
  </form>
59
61
  </Form>
60
62
  );