laif-ds 0.2.44 → 0.2.45
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/_virtual/index4.js +5 -5
- package/dist/_virtual/index5.js +5 -5
- package/dist/_virtual/index6.js +2 -2
- package/dist/_virtual/index7.js +2 -2
- package/dist/agent-docs/components/Accordion.md +157 -0
- package/dist/agent-docs/components/Alert.md +95 -0
- package/dist/agent-docs/components/AlertDialog.md +126 -0
- package/dist/agent-docs/components/AppEditor.md +90 -0
- package/dist/agent-docs/components/AppForm.md +242 -0
- package/dist/agent-docs/components/AppMultipleSelectDropdown.md +38 -0
- package/dist/agent-docs/components/AppRadioGroup.md +223 -0
- package/dist/agent-docs/components/AppSelect.md +427 -0
- package/dist/agent-docs/components/AppSidebar.md +122 -0
- package/dist/agent-docs/components/AppStepper.md +77 -0
- package/dist/agent-docs/components/AspectRatio.md +87 -0
- package/dist/agent-docs/components/AsyncSelect.md +127 -0
- package/dist/agent-docs/components/AudioVisualizer.md +41 -0
- package/dist/agent-docs/components/Avatar.md +113 -0
- package/dist/agent-docs/components/Badge.md +118 -0
- package/dist/agent-docs/components/Breadcrumb.md +78 -0
- package/dist/agent-docs/components/Button.md +129 -0
- package/dist/agent-docs/components/Calendar.md +222 -0
- package/dist/agent-docs/components/Card.md +147 -0
- package/dist/agent-docs/components/Carousel.md +129 -0
- package/dist/agent-docs/components/Chart.md +75 -0
- package/dist/agent-docs/components/Chat.md +109 -0
- package/dist/agent-docs/components/ChatMessage.md +61 -0
- package/dist/agent-docs/components/Checkbox.md +135 -0
- package/dist/agent-docs/components/CircularProgress.md +49 -0
- package/dist/agent-docs/components/CodeHighlighter.md +31 -0
- package/dist/agent-docs/components/Collapsible.md +95 -0
- package/dist/agent-docs/components/Command.md +142 -0
- package/dist/agent-docs/components/Confirmer.md +175 -0
- package/dist/agent-docs/components/ContextMenu.md +191 -0
- package/dist/agent-docs/components/CopyButton.md +26 -0
- package/dist/agent-docs/components/DataCrossTable.md +94 -0
- package/dist/agent-docs/components/DataTable.md +254 -0
- package/dist/agent-docs/components/DatePicker.md +109 -0
- package/dist/agent-docs/components/Dialog.md +125 -0
- package/dist/agent-docs/components/Drawer.md +127 -0
- package/dist/agent-docs/components/DropdownMenu.md +57 -0
- package/dist/agent-docs/components/FilePreview.md +99 -0
- package/dist/agent-docs/components/FilePreviewer.md +139 -0
- package/dist/agent-docs/components/FileUploader.md +129 -0
- package/dist/agent-docs/components/Form.md +62 -0
- package/dist/agent-docs/components/FormComposer.md +137 -0
- package/dist/agent-docs/components/GanttChart.md +122 -0
- package/dist/agent-docs/components/HoverCard.md +37 -0
- package/dist/agent-docs/components/Icon.md +99 -0
- package/dist/agent-docs/components/Input.md +138 -0
- package/dist/agent-docs/components/InputOtp.md +40 -0
- package/dist/agent-docs/components/InputSelector.md +97 -0
- package/dist/agent-docs/components/InterruptPrompt.md +32 -0
- package/dist/agent-docs/components/Label.md +28 -0
- package/dist/agent-docs/components/MarkdownRenderer.md +36 -0
- package/dist/agent-docs/components/Menubar.md +164 -0
- package/dist/agent-docs/components/MessageInput.md +131 -0
- package/dist/agent-docs/components/MessageList.md +96 -0
- package/dist/agent-docs/components/MultipleSelector.md +146 -0
- package/dist/agent-docs/components/NavigationMenu.md +51 -0
- package/dist/agent-docs/components/Pagination.md +55 -0
- package/dist/agent-docs/components/Popover.md +103 -0
- package/dist/agent-docs/components/Progress.md +30 -0
- package/dist/agent-docs/components/PromptSuggestions.md +33 -0
- package/dist/agent-docs/components/RadioGroup.md +90 -0
- package/dist/agent-docs/components/Resizable.md +35 -0
- package/dist/agent-docs/components/ResizePrompt.md +13 -0
- package/dist/agent-docs/components/ScrollArea.md +49 -0
- package/dist/agent-docs/components/SecurePdfViewer.md +38 -0
- package/dist/agent-docs/components/Select.md +132 -0
- package/dist/agent-docs/components/Separator.md +32 -0
- package/dist/agent-docs/components/Sheet.md +40 -0
- package/dist/agent-docs/components/ShikiHighlighter.md +31 -0
- package/dist/agent-docs/components/Sidebar.md +85 -0
- package/dist/agent-docs/components/Skeleton.md +29 -0
- package/dist/agent-docs/components/Slider.md +58 -0
- package/dist/agent-docs/components/Sonner.md +21 -0
- package/dist/agent-docs/components/Spinner.md +139 -0
- package/dist/agent-docs/components/Stepper.md +67 -0
- package/dist/agent-docs/components/Switch.md +42 -0
- package/dist/agent-docs/components/Table.md +63 -0
- package/dist/agent-docs/components/TableSkeleton.md +46 -0
- package/dist/agent-docs/components/Tabs.md +86 -0
- package/dist/agent-docs/components/TextArea.md +52 -0
- package/dist/agent-docs/components/ThemeSwitcher.md +69 -0
- package/dist/agent-docs/components/Toaster.md +23 -0
- package/dist/agent-docs/components/Toggle.md +31 -0
- package/dist/agent-docs/components/ToggleGroup.md +30 -0
- package/dist/agent-docs/components/Tooltip.md +91 -0
- package/dist/agent-docs/components/TypingIndicator.md +21 -0
- package/dist/agent-docs/components/Typo.md +65 -0
- package/dist/agent-docs/components/WeeklyCalendar.md +64 -0
- package/dist/agent-docs/components-list.md +144 -0
- package/dist/node_modules/eventemitter3/index2.js +1 -1
- package/dist/node_modules/hast-util-to-jsx-runtime/lib/index.js +1 -1
- package/dist/node_modules/style-to-object/cjs/index.js +1 -1
- package/dist/node_modules/unified/lib/index.js +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Dialog
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Accessible modal dialog built on Radix. Includes overlay, content with size variants, header/footer layout, title/description, trigger and close controls.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
### Dialog (Root)
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
| -------------- | ------------------- | ----------- | ---------------------------------------- |
|
|
15
|
+
| `open` | `boolean` | `undefined` | Controlled open state. |
|
|
16
|
+
| `defaultOpen` | `boolean` | `false` | Uncontrolled initial open state. |
|
|
17
|
+
| `onOpenChange` | `(open: boolean) => void` | `undefined` | Called when open state changes. |
|
|
18
|
+
| `modal` | `boolean` | `true` | Modal behavior (trap focus, background). |
|
|
19
|
+
|
|
20
|
+
### DialogContent
|
|
21
|
+
|
|
22
|
+
Additional prop:
|
|
23
|
+
|
|
24
|
+
| Prop | Type | Default | Description |
|
|
25
|
+
| -------- | ----------------------------- | ----------- | ------------------------------------- |
|
|
26
|
+
| `size` | `"sm" | "default" | "lg" | "xl"` | `"default"` | Max-width preset for the content. |
|
|
27
|
+
| `className` | `string` | `""` | Additional classes for the panel. |
|
|
28
|
+
|
|
29
|
+
### Subcomponents
|
|
30
|
+
|
|
31
|
+
- `DialogTrigger`: Element that opens the dialog (supports `asChild`).
|
|
32
|
+
- `DialogPortal` / `DialogOverlay`: Portal root and backdrop.
|
|
33
|
+
- `DialogContent`: Centered panel with animations and close button.
|
|
34
|
+
- `DialogHeader` / `DialogFooter`: Layout helpers for content.
|
|
35
|
+
- `DialogTitle` / `DialogDescription`: Accessible title and description.
|
|
36
|
+
- `DialogClose`: Close button (already included inside `DialogContent`).
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Behavior
|
|
41
|
+
|
|
42
|
+
- **Focus management**: Traps focus while open; returns on close.
|
|
43
|
+
- **Pointer outside exception**: Clicks inside elements marked `data-command-portal` are ignored to prevent unintended close.
|
|
44
|
+
- **Sizes**: `size` controls the max-width (`sm`, `default`, `lg`, `xl`).
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Examples
|
|
49
|
+
|
|
50
|
+
### Basic
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import { Button } from "laif-ds";
|
|
54
|
+
import {
|
|
55
|
+
Dialog,
|
|
56
|
+
DialogTrigger,
|
|
57
|
+
DialogContent,
|
|
58
|
+
DialogHeader,
|
|
59
|
+
DialogTitle,
|
|
60
|
+
DialogDescription,
|
|
61
|
+
DialogFooter,
|
|
62
|
+
} from "laif-ds";
|
|
63
|
+
|
|
64
|
+
export function BasicDialog() {
|
|
65
|
+
return (
|
|
66
|
+
<Dialog>
|
|
67
|
+
<DialogTrigger asChild>
|
|
68
|
+
<Button variant="outline">Open Dialog</Button>
|
|
69
|
+
</DialogTrigger>
|
|
70
|
+
<DialogContent>
|
|
71
|
+
<DialogHeader>
|
|
72
|
+
<DialogTitle>Basic Dialog</DialogTitle>
|
|
73
|
+
<DialogDescription>
|
|
74
|
+
This is a basic dialog with title and description.
|
|
75
|
+
</DialogDescription>
|
|
76
|
+
</DialogHeader>
|
|
77
|
+
<div className="py-4">
|
|
78
|
+
<p className="text-d-secondary-foreground text-sm">
|
|
79
|
+
Dialog content goes here.
|
|
80
|
+
</p>
|
|
81
|
+
</div>
|
|
82
|
+
<DialogFooter>
|
|
83
|
+
<Button type="submit">Save changes</Button>
|
|
84
|
+
</DialogFooter>
|
|
85
|
+
</DialogContent>
|
|
86
|
+
</Dialog>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Size Variants
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
import { Button } from "laif-ds";
|
|
95
|
+
import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle } from "laif-ds";
|
|
96
|
+
|
|
97
|
+
export function SizeVariants() {
|
|
98
|
+
return (
|
|
99
|
+
<div className="flex flex-wrap gap-3">
|
|
100
|
+
{["sm", "default", "lg", "xl"].map((sz) => (
|
|
101
|
+
<Dialog key={sz as string}>
|
|
102
|
+
<DialogTrigger asChild>
|
|
103
|
+
<Button variant="outline">Open {String(sz)}</Button>
|
|
104
|
+
</DialogTrigger>
|
|
105
|
+
<DialogContent size={sz as any}>
|
|
106
|
+
<DialogHeader>
|
|
107
|
+
<DialogTitle>Size: {String(sz)}</DialogTitle>
|
|
108
|
+
</DialogHeader>
|
|
109
|
+
<div className="text-sm">Content for {String(sz)}</div>
|
|
110
|
+
</DialogContent>
|
|
111
|
+
</Dialog>
|
|
112
|
+
))}
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Notes
|
|
121
|
+
|
|
122
|
+
- **Accessibility**: Use `DialogTitle` and `DialogDescription` for screen readers.
|
|
123
|
+
- **Styling**: Customize panel via `className` on `DialogContent`.
|
|
124
|
+
- **Closing**: A close button is rendered in the top-right of `DialogContent`.
|
|
125
|
+
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Drawer
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Sliding panel component (top/right/bottom/left) built on Vaul. Supports modal behavior, background scaling, snap points, and full keyboard accessibility.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
### Drawer (Root)
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
| -------------------- | ------------------------------------- | ----------- | ------------------------------------------------------------------ |
|
|
15
|
+
| `open` | `boolean` | `undefined` | Controlled open state. |
|
|
16
|
+
| `onOpenChange` | `(open: boolean) => void` | `undefined` | Called when open state changes. |
|
|
17
|
+
| `direction` | `"top" | "right" | "bottom" | "left"` | `"bottom"` | Drawer opening direction. |
|
|
18
|
+
| `modal` | `boolean` | `true` | Modal behavior (trap focus, block background interaction). |
|
|
19
|
+
| `shouldScaleBackground` | `boolean` | `true` | Scales the background when the drawer is open. |
|
|
20
|
+
| `snapPoints` | `number[]` | `[]` | Optional snap points (fractions of viewport: e.g., `0.4`, `0.6`). |
|
|
21
|
+
| `activeSnapPoint` | `number | string` | `undefined` | The active snap point index/value. |
|
|
22
|
+
| `closeThreshold` | `number` | `undefined` | Threshold to trigger close on drag. |
|
|
23
|
+
|
|
24
|
+
### Subcomponents
|
|
25
|
+
|
|
26
|
+
- `DrawerTrigger`: Element that opens the drawer (supports `asChild`).
|
|
27
|
+
- `DrawerPortal` / `DrawerOverlay`: Portal root and backdrop.
|
|
28
|
+
- `DrawerContent`: Panel container; includes a grab handle in bottom direction.
|
|
29
|
+
- `DrawerHeader` / `DrawerFooter`: Layout helpers for content.
|
|
30
|
+
- `DrawerTitle` / `DrawerDescription`: Header title and description.
|
|
31
|
+
- `DrawerClose`: Close button helper to wrap an element.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Behavior
|
|
36
|
+
|
|
37
|
+
- **Directions**: Open from any side via `direction` prop.
|
|
38
|
+
- **Snap points**: Provide a list of fractional heights; control active point via `activeSnapPoint`.
|
|
39
|
+
- **Modal**: When `modal` is true, interaction outside is blocked and overlay is shown.
|
|
40
|
+
- **Accessibility**: Focus trapping and keyboard navigation handled by the underlying library.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Examples
|
|
45
|
+
|
|
46
|
+
### Interactive Drawer
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { Button } from "laif-ds";
|
|
50
|
+
import {
|
|
51
|
+
Drawer,
|
|
52
|
+
DrawerTrigger,
|
|
53
|
+
DrawerContent,
|
|
54
|
+
DrawerHeader,
|
|
55
|
+
DrawerTitle,
|
|
56
|
+
DrawerDescription,
|
|
57
|
+
DrawerFooter,
|
|
58
|
+
DrawerClose,
|
|
59
|
+
} from "laif-ds";
|
|
60
|
+
import { Input } from "laif-ds";
|
|
61
|
+
|
|
62
|
+
export function InteractiveDrawer() {
|
|
63
|
+
return (
|
|
64
|
+
<Drawer direction="bottom" modal shouldScaleBackground>
|
|
65
|
+
<DrawerTrigger asChild>
|
|
66
|
+
<Button variant="outline">Apri Drawer</Button>
|
|
67
|
+
</DrawerTrigger>
|
|
68
|
+
<DrawerContent>
|
|
69
|
+
<DrawerHeader>
|
|
70
|
+
<DrawerTitle>Drawer di Esempio</DrawerTitle>
|
|
71
|
+
<DrawerDescription>
|
|
72
|
+
Personalizza contenuti e comportamento tramite le props.
|
|
73
|
+
</DrawerDescription>
|
|
74
|
+
</DrawerHeader>
|
|
75
|
+
<div className="space-y-4 p-4">
|
|
76
|
+
<Input label="Nome" placeholder="Inserisci il tuo nome" />
|
|
77
|
+
<Input label="Email" type="email" placeholder="Inserisci la tua email" />
|
|
78
|
+
</div>
|
|
79
|
+
<DrawerFooter>
|
|
80
|
+
<Button>Salva modifiche</Button>
|
|
81
|
+
<DrawerClose asChild>
|
|
82
|
+
<Button variant="outline">Annulla</Button>
|
|
83
|
+
</DrawerClose>
|
|
84
|
+
</DrawerFooter>
|
|
85
|
+
</DrawerContent>
|
|
86
|
+
</Drawer>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### With Snap Points
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
import { Button } from "laif-ds";
|
|
95
|
+
import { Drawer, DrawerTrigger, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, DrawerFooter, DrawerClose } from "laif-ds";
|
|
96
|
+
|
|
97
|
+
export function DrawerWithSnapPoints() {
|
|
98
|
+
const snapPoints = [0.4, 0.6, 0.9];
|
|
99
|
+
return (
|
|
100
|
+
<Drawer snapPoints={snapPoints} activeSnapPoint={0}>
|
|
101
|
+
<DrawerTrigger asChild>
|
|
102
|
+
<Button variant="outline">Drawer con Snap Points</Button>
|
|
103
|
+
</DrawerTrigger>
|
|
104
|
+
<DrawerContent>
|
|
105
|
+
<DrawerHeader>
|
|
106
|
+
<DrawerTitle>Drawer con Snap Points</DrawerTitle>
|
|
107
|
+
<DrawerDescription>Snap a 40%, 60% e 90% dell'altezza.</DrawerDescription>
|
|
108
|
+
</DrawerHeader>
|
|
109
|
+
<DrawerFooter>
|
|
110
|
+
<DrawerClose asChild>
|
|
111
|
+
<Button variant="outline">Chiudi</Button>
|
|
112
|
+
</DrawerClose>
|
|
113
|
+
</DrawerFooter>
|
|
114
|
+
</DrawerContent>
|
|
115
|
+
</Drawer>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Notes
|
|
123
|
+
|
|
124
|
+
- **Handle**: A grab handle is visible for bottom direction.
|
|
125
|
+
- **Layout**: Use `DrawerHeader`/`DrawerFooter` and your own content in between.
|
|
126
|
+
- **Styling**: Customize via `className` on `DrawerContent`.
|
|
127
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# DropdownMenu
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Contextual menu built on Radix Dropdown Menu with support for submenus, checkboxes, radio items, labels, separators, and shortcuts.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Exports
|
|
10
|
+
|
|
11
|
+
- `DropdownMenu`, `DropdownMenuTrigger`, `DropdownMenuContent`
|
|
12
|
+
- `DropdownMenuItem`, `DropdownMenuCheckboxItem`, `DropdownMenuRadioItem`
|
|
13
|
+
- `DropdownMenuLabel`, `DropdownMenuSeparator`, `DropdownMenuShortcut`
|
|
14
|
+
- `DropdownMenuGroup`, `DropdownMenuPortal`
|
|
15
|
+
- `DropdownMenuSub`, `DropdownMenuSubContent`, `DropdownMenuSubTrigger`
|
|
16
|
+
- `DropdownMenuRadioGroup`
|
|
17
|
+
|
|
18
|
+
All components extend Radix props.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Example
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import {
|
|
26
|
+
DropdownMenu,
|
|
27
|
+
DropdownMenuTrigger,
|
|
28
|
+
DropdownMenuContent,
|
|
29
|
+
DropdownMenuItem,
|
|
30
|
+
DropdownMenuSeparator,
|
|
31
|
+
DropdownMenuSub,
|
|
32
|
+
DropdownMenuSubTrigger,
|
|
33
|
+
DropdownMenuSubContent,
|
|
34
|
+
} from "laif-ds";
|
|
35
|
+
import { Button } from "laif-ds";
|
|
36
|
+
|
|
37
|
+
export function UserMenu() {
|
|
38
|
+
return (
|
|
39
|
+
<DropdownMenu>
|
|
40
|
+
<DropdownMenuTrigger asChild>
|
|
41
|
+
<Button variant="outline">Open</Button>
|
|
42
|
+
</DropdownMenuTrigger>
|
|
43
|
+
<DropdownMenuContent sideOffset={4}>
|
|
44
|
+
<DropdownMenuItem>Profile</DropdownMenuItem>
|
|
45
|
+
<DropdownMenuItem>Settings</DropdownMenuItem>
|
|
46
|
+
<DropdownMenuSeparator />
|
|
47
|
+
<DropdownMenuSub>
|
|
48
|
+
<DropdownMenuSubTrigger>More</DropdownMenuSubTrigger>
|
|
49
|
+
<DropdownMenuSubContent>
|
|
50
|
+
<DropdownMenuItem>Theme</DropdownMenuItem>
|
|
51
|
+
</DropdownMenuSubContent>
|
|
52
|
+
</DropdownMenuSub>
|
|
53
|
+
</DropdownMenuContent>
|
|
54
|
+
</DropdownMenu>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# FilePreview
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Compact file chip with name, format/size info, optional remove button, and optional action menu (preview/download/remove). Automatically adapts its preview based on file type (image, text, generic).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| ---------------- | -------------------------------------------------------------------- | ------------- | ---------------------------------------------------------- |
|
|
13
|
+
| `file` | `File \| { name: string; url: string; type?: string }` | **required** | File object or remote descriptor with `url`. |
|
|
14
|
+
| `onRemove` | `(url: string) => void` | `undefined` | Called when user removes the file. |
|
|
15
|
+
| `onPreview` | `(url: string) => void` | `undefined` | Called when user clicks Preview from the action menu. |
|
|
16
|
+
| `onDownload` | `(url: string) => void` | `undefined` | Called when user clicks Download from the action menu. |
|
|
17
|
+
| `showActionMenu` | `boolean` | `false` | Show overflow menu (Preview/Download/Delete if provided). |
|
|
18
|
+
| `className` | `string` | `""` | Additional classes for the wrapper. |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Behavior
|
|
23
|
+
|
|
24
|
+
- **Automatic preview**:
|
|
25
|
+
- Images: thumbnail preview.
|
|
26
|
+
- Text: small snippet (first 100 chars).
|
|
27
|
+
- Generic: file-type icon and labels.
|
|
28
|
+
- **Format & size**: Displays file size (if available) and format label (e.g., PDF, JPG).
|
|
29
|
+
- **Actions**:
|
|
30
|
+
- Inline remove button if `onRemove` is provided and `showActionMenu` is false.
|
|
31
|
+
- Popover action menu when `showActionMenu` is true, using `onPreview`, `onDownload`, `onRemove`.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
### Image
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { FilePreview } from "laif-ds";
|
|
41
|
+
|
|
42
|
+
export function ImagePreview() {
|
|
43
|
+
return (
|
|
44
|
+
<FilePreview
|
|
45
|
+
file={{ name: "photo.jpg", url: "https://picsum.photos/id/237/200/200", type: "image/jpeg" }}
|
|
46
|
+
onPreview={(url) => console.log("preview", url)}
|
|
47
|
+
onDownload={(url) => console.log("download", url)}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### With Remove Button
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import { FilePreview } from "laif-ds";
|
|
57
|
+
|
|
58
|
+
export function RemovablePreview() {
|
|
59
|
+
return (
|
|
60
|
+
<FilePreview
|
|
61
|
+
file={{
|
|
62
|
+
name: "document.docx",
|
|
63
|
+
url: "https://example.com/document.docx",
|
|
64
|
+
type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
65
|
+
}}
|
|
66
|
+
onRemove={(url) => console.log("remove", url)}
|
|
67
|
+
onPreview={(url) => console.log("preview", url)}
|
|
68
|
+
onDownload={(url) => console.log("download", url)}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### With Action Menu
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import { FilePreview } from "laif-ds";
|
|
78
|
+
|
|
79
|
+
export function WithMenu() {
|
|
80
|
+
return (
|
|
81
|
+
<FilePreview
|
|
82
|
+
file={{ name: "presentation.ppt", url: "https://example.com/presentation.ppt", type: "application/vnd.ms-powerpoint" }}
|
|
83
|
+
showActionMenu
|
|
84
|
+
onPreview={(url) => console.log("preview", url)}
|
|
85
|
+
onDownload={(url) => console.log("download", url)}
|
|
86
|
+
onRemove={(url) => console.log("remove", url)}
|
|
87
|
+
/>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Notes
|
|
95
|
+
|
|
96
|
+
- **Thumbnails**: Image previews use object-fit to contain within the chip.
|
|
97
|
+
- **Security**: For local `File` previews, temporary object URLs are created; cleanup is handled by the browser GC.
|
|
98
|
+
- **Internationalization**: Text labels in the action menu can be adjusted at call sites when needed.
|
|
99
|
+
|
|
@@ -0,0 +1,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.
|
|
139
|
+
|
|
@@ -0,0 +1,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`.
|
|
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
|
+
|