laif-ds 0.2.43 → 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/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/components/ui/spinner.js +67 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +363 -361
- package/dist/node_modules/eventemitter3/index2.js +1 -1
- package/dist/node_modules/style-to-object/cjs/index.js +1 -1
- package/dist/styles.v3.css +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Form
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
React Hook Form helpers: provider and primitives to build accessible fields with labels, descriptions, and error messages.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Exports
|
|
10
|
+
|
|
11
|
+
- `Form` — React Hook Form provider (alias of `FormProvider`)
|
|
12
|
+
- `FormField` — Wraps `Controller` and provides field context
|
|
13
|
+
- `FormItem` — Field container that provides IDs to children
|
|
14
|
+
- `FormLabel` — Label bound to the current field
|
|
15
|
+
- `FormControl` — Slot wrapper that wires aria-attributes
|
|
16
|
+
- `FormDescription` — Helper text
|
|
17
|
+
- `FormMessage` — Error message (auto reads from RHF state)
|
|
18
|
+
- `useFormField` — Hook to access field context
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Example
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import { useForm } from "react-hook-form";
|
|
26
|
+
import { Input, Button } from "laif-ds";
|
|
27
|
+
import {
|
|
28
|
+
Form,
|
|
29
|
+
FormField,
|
|
30
|
+
FormItem,
|
|
31
|
+
FormLabel,
|
|
32
|
+
FormControl,
|
|
33
|
+
FormDescription,
|
|
34
|
+
FormMessage,
|
|
35
|
+
} from "laif-ds";
|
|
36
|
+
|
|
37
|
+
export function ProfileForm() {
|
|
38
|
+
const form = useForm<{ email: string }>({ defaultValues: { email: "" } });
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<Form {...form}>
|
|
42
|
+
<form onSubmit={form.handleSubmit((v) => console.log(v))}>
|
|
43
|
+
<FormField
|
|
44
|
+
control={form.control}
|
|
45
|
+
name="email"
|
|
46
|
+
render={({ field }) => (
|
|
47
|
+
<FormItem>
|
|
48
|
+
<FormLabel>Email</FormLabel>
|
|
49
|
+
<FormControl>
|
|
50
|
+
<Input type="email" placeholder="you@example.com" {...field} />
|
|
51
|
+
</FormControl>
|
|
52
|
+
<FormDescription>We will never share your email.</FormDescription>
|
|
53
|
+
<FormMessage />
|
|
54
|
+
</FormItem>
|
|
55
|
+
)}
|
|
56
|
+
/>
|
|
57
|
+
<Button type="submit" className="mt-4">Save</Button>
|
|
58
|
+
</form>
|
|
59
|
+
</Form>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
```
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# FormComposer
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Declarative form builder using `react-hook-form` (with optional Zod). Renders inputs, selects, textareas, and checkboxes from a simple items config, handles validation, and provides a submit button with loading state.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Types
|
|
10
|
+
|
|
11
|
+
### FormComposerItem
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
interface FormComposerItem {
|
|
15
|
+
label: string;
|
|
16
|
+
component: "input" | "select" | "textarea" | "checkbox";
|
|
17
|
+
name: string;
|
|
18
|
+
defaultValue?: string | boolean | number;
|
|
19
|
+
options?: AppSelectOption[]; // only for "select"
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
placeholder?: string;
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Props
|
|
28
|
+
|
|
29
|
+
| Prop | Type | Default | Description |
|
|
30
|
+
| -------------- | ------------------------ | ----------- | ----------------------------------------------------- |
|
|
31
|
+
| `cols` | `"1" | "2" | "3"` | `"2"` | Grid columns for the items. |
|
|
32
|
+
| `items` | `FormComposerItem[]` | **required**| Field configuration list. |
|
|
33
|
+
| `schema` | `ZodTypeAny` | `undefined` | Optional Zod schema to enable validation/resolver. |
|
|
34
|
+
| `defaultValues`| `Record<string, any>` | `undefined` | RHF default values; overrides item `defaultValue`. |
|
|
35
|
+
| `submitText` | `string` | `"Invia"` | Submit button label. |
|
|
36
|
+
| `onSubmit` | `(data: any) => void` | `undefined` | Called with valid form values. |
|
|
37
|
+
| `isSubmitting` | `boolean` | `false` | Controls submit button loading/disabled state. |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Behavior
|
|
42
|
+
|
|
43
|
+
- **Validation**: If `schema` is provided, a Zod resolver is attached; otherwise native validity is used.
|
|
44
|
+
- **Defaults**: Each `item.defaultValue` is merged into RHF defaults, unless `defaultValues` is passed.
|
|
45
|
+
- **Components**:
|
|
46
|
+
- `component: "input"` → `Input` with `label` and `placeholder`.
|
|
47
|
+
- `component: "textarea"` → `Textarea` with `label`.
|
|
48
|
+
- `component: "select"` → `AppSelect` with `options`.
|
|
49
|
+
- `component: "checkbox"` → `Checkbox` + `Label` inline.
|
|
50
|
+
- **Errors**: Zod error messages are rendered under each field.
|
|
51
|
+
- **Layout**: Items are placed in a responsive grid with `cols` columns; last item may span full width.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Examples
|
|
56
|
+
|
|
57
|
+
### With Zod Schema
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { z } from "zod";
|
|
61
|
+
import { FormComposer } from "laif-ds";
|
|
62
|
+
|
|
63
|
+
const formSchema = z.object({
|
|
64
|
+
name: z.string().min(2, "Il nome è troppo corto"),
|
|
65
|
+
email: z.string().email("Email non valida"),
|
|
66
|
+
message: z.string().min(10, "Almeno 10 caratteri"),
|
|
67
|
+
select: z.string().min(1, "Seleziona una opzione"),
|
|
68
|
+
checkbox: z.boolean().default(false),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export function ContactForm() {
|
|
72
|
+
return (
|
|
73
|
+
<div className="w-[800px]">
|
|
74
|
+
<FormComposer
|
|
75
|
+
schema={formSchema}
|
|
76
|
+
items={[
|
|
77
|
+
{ label: "Name", component: "input", name: "name", placeholder: "Inserisci il tuo nome", defaultValue: "ciao" },
|
|
78
|
+
{ label: "Select", component: "select", name: "select", defaultValue: "1", options: [
|
|
79
|
+
{ value: "1", label: "Option 1" },
|
|
80
|
+
{ value: "2", label: "Option 2" },
|
|
81
|
+
{ value: "3", label: "Option 3" },
|
|
82
|
+
] },
|
|
83
|
+
{ label: "Email", component: "input", name: "email", placeholder: "Inserisci la tua email" },
|
|
84
|
+
{ label: "Checkbox", component: "checkbox", name: "checkbox", defaultValue: true },
|
|
85
|
+
{ label: "Message", component: "textarea", name: "message", placeholder: "Inserisci il tuo messaggio" },
|
|
86
|
+
]}
|
|
87
|
+
onSubmit={(data) => console.log(data)}
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Submit State
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
import * as React from "react";
|
|
98
|
+
import { z } from "zod";
|
|
99
|
+
import { FormComposer } from "laif-ds";
|
|
100
|
+
|
|
101
|
+
const schema = z.object({ name: z.string().min(2), email: z.string().email() });
|
|
102
|
+
|
|
103
|
+
export function SubmitExample() {
|
|
104
|
+
const [values, setValues] = React.useState({});
|
|
105
|
+
const [isSubmitting, setSubmitting] = React.useState(false);
|
|
106
|
+
|
|
107
|
+
const onSubmit = (data: any) => {
|
|
108
|
+
setSubmitting(true);
|
|
109
|
+
setTimeout(() => setSubmitting(false), 2000);
|
|
110
|
+
setValues(data);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
<div className="w-[800px]">
|
|
115
|
+
<FormComposer
|
|
116
|
+
schema={schema}
|
|
117
|
+
items={[
|
|
118
|
+
{ label: "Name", component: "input", name: "name" },
|
|
119
|
+
{ label: "Email", component: "input", name: "email" },
|
|
120
|
+
]}
|
|
121
|
+
onSubmit={onSubmit}
|
|
122
|
+
isSubmitting={isSubmitting}
|
|
123
|
+
/>
|
|
124
|
+
<pre>{JSON.stringify(values, null, 2)}</pre>
|
|
125
|
+
</div>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Notes
|
|
133
|
+
|
|
134
|
+
- **Extensibility**: Use `startContent`, `endContent`, `iconLeft`, `iconRight` props of `Input` for richer fields.
|
|
135
|
+
- **Select**: Provide `options` for `component: "select"` (`AppSelectOption[]`).
|
|
136
|
+
- **Accessibility**: Labels are wired via `htmlFor`/`id`; errors use `role="alert"` and `aria-live` when relevant.
|
|
137
|
+
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# GanttChart
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Composable Gantt chart with a tree, time scale, and draggable bars. Built as a root `Gantt` component with subcomponents `Gantt.Controls` and `Gantt.Chart`. Supports zoom dimensions, drag step sizes, programmatic callbacks, and custom left-render content for items.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Components & Props
|
|
10
|
+
|
|
11
|
+
### Gantt (root)
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
| --------------------- | -------------------------------------- | ---------------------- | ----------- |
|
|
15
|
+
| `children` | `React.ReactNode` | — | Compose `Gantt.Controls` and `Gantt.Chart`. |
|
|
16
|
+
| `draggable` | `boolean` | `false` | Enable dragging/resizing of bars. |
|
|
17
|
+
| `defaultDimension` | `GanttDimensions` | `GanttDimensions.HOUR` | Initial zoom (hour, day, etc.). |
|
|
18
|
+
| `defaultDragStepSize` | `DragStepSizes` | `DragStepSizes.THIRTY_MIN` | Initial drag step. |
|
|
19
|
+
| `treeTitle` | `string` | `"Attività"` | Title of the left tree column. |
|
|
20
|
+
|
|
21
|
+
See `enums` in `ui/gantt/enums/` for `GanttDimensions` and `DragStepSizes` values.
|
|
22
|
+
|
|
23
|
+
### Gantt.Chart
|
|
24
|
+
|
|
25
|
+
| Prop | Type | Default | Description |
|
|
26
|
+
| ----------------- | --------------------------- | ----------- | ----------- |
|
|
27
|
+
| `data` | `GanttDataType[]` | **required**| Items to render (with optional nested children). |
|
|
28
|
+
| `className` | `string` | `undefined` | Wrapper classes. |
|
|
29
|
+
| `onBarDoubleClick`| `(bar) => void` | `undefined` | Invoked on item double click. |
|
|
30
|
+
| `onBarChange` | `(bar, newData) => void` | `undefined` | Invoked after drag/resize changes. |
|
|
31
|
+
|
|
32
|
+
### Gantt.Controls
|
|
33
|
+
|
|
34
|
+
| Prop | Type | Default | Description |
|
|
35
|
+
| ----------- | -------- | ----------- | ----------- |
|
|
36
|
+
| `className` | `string` | `undefined` | Toolbar wrapper classes. |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Data Types
|
|
41
|
+
|
|
42
|
+
Minimal item structure (`ui/gantt/types/GanttData.tsx`):
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
type RawGanttDataType = {
|
|
46
|
+
key: string
|
|
47
|
+
title: string
|
|
48
|
+
color?: string
|
|
49
|
+
data?: BarItemDataType // Repeat or fixed datetime interval
|
|
50
|
+
children?: GanttDataType[] // Nested items
|
|
51
|
+
leftRender?: React.ReactNode | ((bar) => React.ReactNode)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type NoRepeatDataType = { startDate: string; endDate: string }
|
|
55
|
+
type RepeatDataType = {
|
|
56
|
+
repeatType: DataRepeatTypes
|
|
57
|
+
fromTime: number
|
|
58
|
+
toTime: number
|
|
59
|
+
fromDate?: string
|
|
60
|
+
toDate?: string
|
|
61
|
+
weekdays?: number[]
|
|
62
|
+
monthdays?: number[]
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Examples
|
|
69
|
+
|
|
70
|
+
### Default
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
import Gantt from "laif-ds/ui/gantt/components/Gantt/Gantt";
|
|
74
|
+
|
|
75
|
+
export function Basic() {
|
|
76
|
+
return (
|
|
77
|
+
<div className="h-[500px]">
|
|
78
|
+
<Gantt>
|
|
79
|
+
<Gantt.Controls />
|
|
80
|
+
<Gantt.Chart data={sampleData} />
|
|
81
|
+
</Gantt>
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Draggable + Defaults
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import { GanttDimensions, DragStepSizes } from "laif-ds/ui/gantt/enums";
|
|
91
|
+
|
|
92
|
+
export function Draggable() {
|
|
93
|
+
return (
|
|
94
|
+
<div className="h-[500px]">
|
|
95
|
+
<Gantt draggable defaultDimension={GanttDimensions.DAY} defaultDragStepSize={DragStepSizes.ONE_DAY}>
|
|
96
|
+
<Gantt.Controls />
|
|
97
|
+
<Gantt.Chart data={sampleData} />
|
|
98
|
+
</Gantt>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Custom Tree Title
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
<div className="h-[500px]">
|
|
108
|
+
<Gantt draggable treeTitle="Progetti">
|
|
109
|
+
<Gantt.Controls />
|
|
110
|
+
<Gantt.Chart data={sampleData} />
|
|
111
|
+
</Gantt>
|
|
112
|
+
</div>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Notes
|
|
118
|
+
|
|
119
|
+
- **Virtualization**: Tree, bars, and scale use windowed lists for performance.
|
|
120
|
+
- **Current time**: Auto-updates while scrolling to keep the date indicator in sync.
|
|
121
|
+
- **Left render**: Use `leftRender` to inject icons/actions next to item titles.
|
|
122
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# HoverCard
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Small informational card that appears on hover. Built on Radix Hover Card.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Exports
|
|
10
|
+
|
|
11
|
+
- `HoverCard`
|
|
12
|
+
- `HoverCardTrigger`
|
|
13
|
+
- `HoverCardContent` (props: `align = "center"`, `sideOffset = 4`)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Example
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { HoverCard, HoverCardTrigger, HoverCardContent, Button } from "laif-ds";
|
|
21
|
+
|
|
22
|
+
export function UserHover() {
|
|
23
|
+
return (
|
|
24
|
+
<HoverCard>
|
|
25
|
+
<HoverCardTrigger asChild>
|
|
26
|
+
<Button variant="outline">Hover me</Button>
|
|
27
|
+
</HoverCardTrigger>
|
|
28
|
+
<HoverCardContent className="w-64">
|
|
29
|
+
<div className="space-y-1">
|
|
30
|
+
<p className="font-medium">John Doe</p>
|
|
31
|
+
<p className="text-sm text-muted-foreground">Frontend Engineer</p>
|
|
32
|
+
</div>
|
|
33
|
+
</HoverCardContent>
|
|
34
|
+
</HoverCard>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
```
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Icon
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Wrapper around `lucide-react` icons with design-system sizes and convenient color/className support.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| ----------- | ------------------------------------------- | --------- | ----------------------------------------------- |
|
|
13
|
+
| `name` | `IconName` (key of `lucide-react` exports) | **required** | Icon name from `lucide-react`. |
|
|
14
|
+
| `size` | `"xs" | "sm" | "md" | "lg" | "xl"` | `"md"` | Predefined pixel sizes: 16, 20, 24, 32, 40. |
|
|
15
|
+
| `className` | `string` | `""` | Additional classes (e.g., color via theme tokens). |
|
|
16
|
+
| `color` | `string` | `undefined` | Overrides color style directly. |
|
|
17
|
+
|
|
18
|
+
Any extra props are passed to the underlying `lucide-react` icon component.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Behavior
|
|
23
|
+
|
|
24
|
+
- **Sizing**: The `size` prop maps to pixel sizes (`xs=16`, `sm=20`, `md=24`, `lg=32`, `xl=40`).
|
|
25
|
+
- **Coloring**: Prefer theme tokens via `className` (e.g., `text-d-destructive`). For one-off colors, use `color`.
|
|
26
|
+
- **Safety**: If `name` is not found, the component renders `null` and logs a warning.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Examples
|
|
31
|
+
|
|
32
|
+
### Default
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import { Icon } from "laif-ds";
|
|
36
|
+
|
|
37
|
+
export function DefaultIcon() {
|
|
38
|
+
return <Icon name="Check" size="md" />;
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Sizes
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { Icon } from "laif-ds";
|
|
46
|
+
|
|
47
|
+
export function IconSizes() {
|
|
48
|
+
return (
|
|
49
|
+
<div className="flex items-end gap-4">
|
|
50
|
+
<div className="flex flex-col items-center gap-2">
|
|
51
|
+
<Icon name="Check" size="xs" />
|
|
52
|
+
<span className="text-xs">xs</span>
|
|
53
|
+
</div>
|
|
54
|
+
<div className="flex flex-col items-center gap-2">
|
|
55
|
+
<Icon name="Check" size="sm" />
|
|
56
|
+
<span className="text-xs">sm</span>
|
|
57
|
+
</div>
|
|
58
|
+
<div className="flex flex-col items-center gap-2">
|
|
59
|
+
<Icon name="Check" size="md" />
|
|
60
|
+
<span className="text-xs">md</span>
|
|
61
|
+
</div>
|
|
62
|
+
<div className="flex flex-col items-center gap-2">
|
|
63
|
+
<Icon name="Check" size="lg" />
|
|
64
|
+
<span className="text-xs">lg</span>
|
|
65
|
+
</div>
|
|
66
|
+
<div className="flex flex-col items-center gap-2">
|
|
67
|
+
<Icon name="Check" size="xl" />
|
|
68
|
+
<span className="text-xs">xl</span>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Colors
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import { Icon } from "laif-ds";
|
|
79
|
+
|
|
80
|
+
export function IconColors() {
|
|
81
|
+
return (
|
|
82
|
+
<div className="flex gap-4">
|
|
83
|
+
<Icon name="Heart" size="lg" className="text-d-destructive" />
|
|
84
|
+
<Icon name="Heart" size="lg" className="text-d-primary" />
|
|
85
|
+
<Icon name="Heart" size="lg" className="text-d-muted-foreground" />
|
|
86
|
+
<Icon name="Heart" size="lg" color="#8B5CF6" />
|
|
87
|
+
<Icon name="Heart" size="lg" color="#EC4899" />
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Notes
|
|
96
|
+
|
|
97
|
+
- **Design tokens**: Use theme token classes (`text-d-*`) rather than raw Tailwind colors.
|
|
98
|
+
- **Icon library**: Use only `laif-ds` `Icon` (no external icon libraries).
|
|
99
|
+
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Input
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Text input component with label, sizes, optional left/right icons, custom start/end content, built-in password toggle, validation styles and accessible error messaging.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
Extends native `<input>` props (except `size` and `label` which are redefined).
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
| --------------- | -------------------------------------- | ----------- | -------------------------------------------------------------------- |
|
|
15
|
+
| `label` | `string | React.ReactNode` | `undefined` | Field label shown above the input. |
|
|
16
|
+
| `labelClassName`| `string` | `""` | Extra classes for the label. |
|
|
17
|
+
| `size` | `"sm" | "default" | "lg"` | `"default"` | Controls height and font-size. |
|
|
18
|
+
| `iconLeft` | `IconName` | `undefined` | Optional left icon (uses `Icon`). |
|
|
19
|
+
| `iconRight` | `IconName` | `undefined` | Optional right icon (ignored when `type="password"`). |
|
|
20
|
+
| `startContent` | `React.ReactNode` | `undefined` | Custom content before the input (coexists with `iconLeft`). |
|
|
21
|
+
| `endContent` | `React.ReactNode` | `undefined` | Custom content after the input (coexists with `iconRight`). |
|
|
22
|
+
| `errorMessage` | `string` | `undefined` | Custom error message (shown after interaction/invalid state). |
|
|
23
|
+
|
|
24
|
+
All other standard input attributes (e.g., `type`, `placeholder`, `required`, `min`, `max`, `pattern`, etc.) are supported.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Behavior
|
|
29
|
+
|
|
30
|
+
- **Wrapper focus**: Clicking the wrapper focuses the input; selects text for non-password types (except file).
|
|
31
|
+
- **Password toggle**: When `type="password"`, a toggle button switches visibility with accessible labels (`Mostra/Nascondi password`).
|
|
32
|
+
- **Validation**: The wrapper reflects validity (`aria-invalid`) and shows `errorMessage` or the browser validation message once touched/invalid.
|
|
33
|
+
- **Accessibility**: Errors use `role="alert"` and `aria-live="polite"`; labels link via `htmlFor`/`id`.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Examples
|
|
38
|
+
|
|
39
|
+
### Basic
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { Input } from "laif-ds";
|
|
43
|
+
|
|
44
|
+
export function BasicInput() {
|
|
45
|
+
return (
|
|
46
|
+
<Input
|
|
47
|
+
label="Nome"
|
|
48
|
+
placeholder="Inserisci testo..."
|
|
49
|
+
className="w-full max-w-sm"
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Sizes and Icons
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { Input } from "laif-ds";
|
|
59
|
+
|
|
60
|
+
export function SizesAndIcons() {
|
|
61
|
+
return (
|
|
62
|
+
<div className="flex flex-col gap-3 w-full max-w-sm">
|
|
63
|
+
<Input size="sm" label="Email" type="email" iconLeft="Mail" placeholder="esempio@dominio.com" />
|
|
64
|
+
<Input size="default" label="Cerca" type="search" iconLeft="Search" placeholder="Cerca..." />
|
|
65
|
+
<Input size="lg" label="Prezzo" type="number" iconRight="Euro" placeholder="0.00" />
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Custom Start/End Content
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { Input } from "laif-ds";
|
|
75
|
+
|
|
76
|
+
export function CustomContent() {
|
|
77
|
+
return (
|
|
78
|
+
<div className="flex flex-col gap-3 w-full max-w-sm">
|
|
79
|
+
<Input
|
|
80
|
+
label="Importo"
|
|
81
|
+
type="number"
|
|
82
|
+
placeholder="0.00"
|
|
83
|
+
startContent={<span className="text-d-muted-foreground text-sm font-medium">€</span>}
|
|
84
|
+
/>
|
|
85
|
+
<Input
|
|
86
|
+
label="Percentuale"
|
|
87
|
+
type="number"
|
|
88
|
+
placeholder="0"
|
|
89
|
+
endContent={<span className="text-d-muted-foreground text-sm font-medium">%</span>}
|
|
90
|
+
/>
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Password with Toggle
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
import { Input } from "laif-ds";
|
|
100
|
+
|
|
101
|
+
export function PasswordField() {
|
|
102
|
+
return (
|
|
103
|
+
<Input
|
|
104
|
+
label="Password"
|
|
105
|
+
type="password"
|
|
106
|
+
placeholder="Inserisci la tua password"
|
|
107
|
+
className="w-full max-w-sm"
|
|
108
|
+
required
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Validation States
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
import { Input } from "laif-ds";
|
|
118
|
+
|
|
119
|
+
export function ValidationStates() {
|
|
120
|
+
return (
|
|
121
|
+
<div className="flex flex-col gap-3 w-full max-w-sm">
|
|
122
|
+
<Input label="Campo obbligatorio" placeholder="Questo campo è obbligatorio" required />
|
|
123
|
+
<Input label="Email" type="email" placeholder="email@esempio.com" required />
|
|
124
|
+
<Input label="URL" type="url" placeholder="https://esempio.com" required />
|
|
125
|
+
<Input label="Età (18-65)" type="number" min={18} max={65} required />
|
|
126
|
+
</div>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Notes
|
|
134
|
+
|
|
135
|
+
- **Icons**: Prefer `iconLeft`/`iconRight` rather than embedding icons manually.
|
|
136
|
+
- **Content**: `startContent`/`endContent` are ideal for units, prefixes/suffixes, or badges.
|
|
137
|
+
- **A11y**: Include helpful placeholders and `aria-describedby` for extra guidance when needed.
|
|
138
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# InputOtp
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
OTP (One-Time Password) input built on `input-otp`. Includes grouped slots and an optional separator.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Exports
|
|
10
|
+
|
|
11
|
+
- `InputOTP` (accepts all `input-otp` props, plus `containerClassName`)
|
|
12
|
+
- `InputOTPGroup`
|
|
13
|
+
- `InputOTPSlot` (requires `index: number`)
|
|
14
|
+
- `InputOTPSeparator`
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Example
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from "laif-ds";
|
|
22
|
+
|
|
23
|
+
export function OtpExample() {
|
|
24
|
+
return (
|
|
25
|
+
<InputOTP maxLength={6} containerClassName="w-full justify-center">
|
|
26
|
+
<InputOTPGroup>
|
|
27
|
+
{Array.from({ length: 3 }).map((_, i) => (
|
|
28
|
+
<InputOTPSlot key={i} index={i} />
|
|
29
|
+
))}
|
|
30
|
+
</InputOTPGroup>
|
|
31
|
+
<InputOTPSeparator />
|
|
32
|
+
<InputOTPGroup>
|
|
33
|
+
{Array.from({ length: 3 }).map((_, i) => (
|
|
34
|
+
<InputOTPSlot key={i + 3} index={i + 3} />
|
|
35
|
+
))}
|
|
36
|
+
</InputOTPGroup>
|
|
37
|
+
</InputOTP>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
```
|