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,87 @@
|
|
|
1
|
+
# AspectRatio
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
A container that maintains a consistent aspect ratio for its content. Useful for images, videos, and any media that requires a fixed ratio.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
### AspectRatio (Root)
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
| ----------- | ------------------- | ----------- | ----------------------------------------------- |
|
|
15
|
+
| `ratio` | `number` | `undefined` | Aspect ratio expressed as a number (e.g., 16/9).|
|
|
16
|
+
| `className` | `string` | `""` | Additional classes applied to the container. |
|
|
17
|
+
| `children` | `React.ReactNode` | **required**| Content inside the ratio-constrained container. |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Behavior
|
|
22
|
+
|
|
23
|
+
- **Responsive**: The container scales while preserving the specified ratio.
|
|
24
|
+
- **Content fill**: Child content should handle its own layout (e.g., `object-cover`).
|
|
25
|
+
- **Styling**: Apply width/height and styling via `className`.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Examples
|
|
30
|
+
|
|
31
|
+
### 16:9 Ratio
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { AspectRatio } from "laif-ds";
|
|
35
|
+
|
|
36
|
+
export function Ratio16x9() {
|
|
37
|
+
return (
|
|
38
|
+
<AspectRatio ratio={16 / 9} className="bg-d-secondary/10 w-[400px] rounded-md overflow-hidden">
|
|
39
|
+
<div className="flex h-full items-center justify-center">
|
|
40
|
+
<p className="text-sm text-d-secondary-foreground">16:9 Aspect Ratio</p>
|
|
41
|
+
</div>
|
|
42
|
+
</AspectRatio>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Square (1:1)
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { AspectRatio } from "laif-ds";
|
|
51
|
+
|
|
52
|
+
export function Square() {
|
|
53
|
+
return (
|
|
54
|
+
<AspectRatio ratio={1 / 1} className="bg-d-secondary/10 w-[400px] rounded-md overflow-hidden">
|
|
55
|
+
<div className="flex h-full items-center justify-center">
|
|
56
|
+
<p className="text-sm text-d-secondary-foreground">1:1 Aspect Ratio</p>
|
|
57
|
+
</div>
|
|
58
|
+
</AspectRatio>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### With Image
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { AspectRatio } from "laif-ds";
|
|
67
|
+
|
|
68
|
+
export function ImageRatio() {
|
|
69
|
+
return (
|
|
70
|
+
<AspectRatio ratio={16 / 9} className="w-[400px] rounded-md overflow-hidden">
|
|
71
|
+
<img
|
|
72
|
+
src="https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&dpr=2&q=80"
|
|
73
|
+
alt="Image"
|
|
74
|
+
className="h-full w-full object-cover"
|
|
75
|
+
/>
|
|
76
|
+
</AspectRatio>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Notes
|
|
84
|
+
|
|
85
|
+
- **Children**: Place any content inside; use `object-cover` for images to avoid distortion.
|
|
86
|
+
- **Width**: Control width via `className`; height is computed from the ratio.
|
|
87
|
+
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# AsyncSelect
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Generic async select with search input, popover list, optional preload and multiple selection. Fully render-prop driven for option content and value extraction.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| ----------------- | -------------------------------------------- | ----------- | ----------- |
|
|
13
|
+
| `fetcher` | `(query?: string) => Promise<T[]>` | **required**| Async loader for options. Called on open and on search. |
|
|
14
|
+
| `preload` | `boolean` | `false` | Preload all data once; then client-filter using `filterFn`. |
|
|
15
|
+
| `filterFn` | `(option: T, query: string) => boolean` | `undefined` | Custom client-side filter when `preload=true`. |
|
|
16
|
+
| `renderOption` | `(option: T) => React.ReactNode` | **required**| How to render each option row. |
|
|
17
|
+
| `getOptionValue` | `(option: T) => string` | **required**| Extract option id. |
|
|
18
|
+
| `getDisplayValue` | `(option: T) => React.ReactNode` | **required**| Display value for trigger. |
|
|
19
|
+
| `multiple` | `boolean` | `false` | Enable multi-selection. Controls `value` type. |
|
|
20
|
+
| `value` | `string | string[]` | `undefined` | Controlled value. |
|
|
21
|
+
| `onChange` | `(value: string | string[]) => void` | `undefined` | Change callback. |
|
|
22
|
+
| `label` | `string | React.ReactNode` | `undefined` | Optional label above. |
|
|
23
|
+
| `labelClassName` | `string` | `undefined` | Label classes. |
|
|
24
|
+
| `placeholder` | `string` | `"Select..."` | Placeholder when empty. |
|
|
25
|
+
| `disabled` | `boolean` | `false` | Disable trigger and input. |
|
|
26
|
+
| `width` | `string | number | "auto"` | `200px` | Popover width; `auto` matches trigger width. |
|
|
27
|
+
| `triggerClassName`| `string` | `undefined` | Extra classes for trigger button. |
|
|
28
|
+
| `noResultsMessage`| `string` | `undefined` | Message when list is empty. |
|
|
29
|
+
| `clearable` | `boolean` | `true` | Show clear icon when a value is set. |
|
|
30
|
+
| `size` | `"sm" | "default" | "lg"` | `"default"` | Trigger size. |
|
|
31
|
+
| `loadingSkeleton` | `React.ReactNode` | `undefined` | Custom loading skeleton list. |
|
|
32
|
+
| `notFound` | `React.ReactNode` | `undefined` | Custom empty content. |
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Behavior
|
|
37
|
+
|
|
38
|
+
- **Search**: Debounced input (0ms when `preload=true`, 300ms otherwise).
|
|
39
|
+
- **Caching**: Results cached by query; reused when re-typing.
|
|
40
|
+
- **Multiple**: Renders selected count or first label; supports checkbox UI per item.
|
|
41
|
+
- **Clear**: Built-in clear icon (uses DS `Icon`), respects `clearable`.
|
|
42
|
+
- **A11y**: Trigger focus ring and keyboard navigation via `cmdk`.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Examples
|
|
47
|
+
|
|
48
|
+
### Preloaded
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import * as React from "react";
|
|
52
|
+
import { AsyncSelect } from "laif-ds";
|
|
53
|
+
|
|
54
|
+
type User = { id: number; name: string; email: string };
|
|
55
|
+
|
|
56
|
+
async function fetchUsers(query?: string): Promise<User[]> {
|
|
57
|
+
const res = await fetch("https://jsonplaceholder.typicode.com/users");
|
|
58
|
+
const data: User[] = await res.json();
|
|
59
|
+
if (!query) return data;
|
|
60
|
+
const q = query.toLowerCase();
|
|
61
|
+
return data.filter((u) => u.name.toLowerCase().includes(q));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function PreloadedUsers() {
|
|
65
|
+
const [value, setValue] = React.useState("");
|
|
66
|
+
return (
|
|
67
|
+
<AsyncSelect<User>
|
|
68
|
+
preload
|
|
69
|
+
fetcher={fetchUsers}
|
|
70
|
+
value={value}
|
|
71
|
+
onChange={setValue}
|
|
72
|
+
renderOption={(u) => (
|
|
73
|
+
<div className="truncate">
|
|
74
|
+
<div className="font-medium">{u.name}</div>
|
|
75
|
+
<div className="text-d-muted-foreground text-xs">{u.email}</div>
|
|
76
|
+
</div>
|
|
77
|
+
)}
|
|
78
|
+
getOptionValue={(u) => String(u.id)}
|
|
79
|
+
getDisplayValue={(u) => u.name}
|
|
80
|
+
placeholder="Select a user..."
|
|
81
|
+
width="300px"
|
|
82
|
+
/>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Multiple with Steps
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import * as React from "react";
|
|
91
|
+
import { AsyncSelect } from "laif-ds";
|
|
92
|
+
|
|
93
|
+
type Tag = { id: string; label: string };
|
|
94
|
+
const tags: Tag[] = [
|
|
95
|
+
{ id: "react", label: "React" },
|
|
96
|
+
{ id: "nextjs", label: "Next.js" },
|
|
97
|
+
{ id: "tailwind", label: "Tailwind" },
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
export function MultipleTags() {
|
|
101
|
+
const [value, setValue] = React.useState<string[]>([]);
|
|
102
|
+
const fetcher = async (q?: string) =>
|
|
103
|
+
!q ? tags : tags.filter((t) => t.label.toLowerCase().includes(q!.toLowerCase()));
|
|
104
|
+
return (
|
|
105
|
+
<AsyncSelect<Tag>
|
|
106
|
+
multiple
|
|
107
|
+
fetcher={fetcher}
|
|
108
|
+
value={value}
|
|
109
|
+
onChange={setValue}
|
|
110
|
+
renderOption={(t) => t.label}
|
|
111
|
+
getOptionValue={(t) => t.id}
|
|
112
|
+
getDisplayValue={(t) => t.label}
|
|
113
|
+
placeholder="Select tags..."
|
|
114
|
+
width="auto"
|
|
115
|
+
/>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Notes
|
|
123
|
+
|
|
124
|
+
- **Trigger width**: Use `width="auto"` to match trigger width; or a fixed `number|string`.
|
|
125
|
+
- **Filtering**: For big datasets prefer server search (no `preload`); for small datasets prefer `preload` + `filterFn`.
|
|
126
|
+
- **Theming**: Uses DS token classes across trigger, list, and states.
|
|
127
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# AudioVisualizer
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Canvas-based audio waveform visualizer for a MediaStream. Starts/stops with `isRecording` and resizes responsively.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Description |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| `stream` | `MediaStream | null` | Input audio stream |
|
|
14
|
+
| `isRecording` | `boolean` | Whether to render visualization |
|
|
15
|
+
| `onClick` | `() => void` | Click handler (e.g., to toggle state) |
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Example
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { useEffect, useState } from "react";
|
|
23
|
+
import { AudioVisualizer } from "laif-ds";
|
|
24
|
+
|
|
25
|
+
export function MicVisualizer() {
|
|
26
|
+
const [stream, setStream] = useState<MediaStream | null>(null);
|
|
27
|
+
const [isRecording, setIsRecording] = useState(false);
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
navigator.mediaDevices.getUserMedia({ audio: true }).then(setStream);
|
|
31
|
+
}, []);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<AudioVisualizer
|
|
35
|
+
stream={stream}
|
|
36
|
+
isRecording={isRecording}
|
|
37
|
+
onClick={() => setIsRecording((v) => !v)}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Avatar
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Circular user/avatar component with image and fallback. Accessible and easily styled.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
### Avatar (Root)
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
| ----------- | ----------------- | ----------- | ------------------------------------------------ |
|
|
15
|
+
| `className` | `string` | `""` | Additional classes for size/border/layout. |
|
|
16
|
+
| `children` | `React.ReactNode` | **required**| Typically `AvatarImage` and `AvatarFallback`. |
|
|
17
|
+
|
|
18
|
+
### Subcomponents
|
|
19
|
+
|
|
20
|
+
- `AvatarImage`: The image element.
|
|
21
|
+
- Props: `src`, `alt`, `className`.
|
|
22
|
+
- `AvatarFallback`: Fallback content shown when the image fails or loads slowly.
|
|
23
|
+
- Props: `children` (e.g., initials), `className`.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Behavior
|
|
28
|
+
|
|
29
|
+
- **Shape**: Circular by default (`rounded-full`).
|
|
30
|
+
- **Sizing**: Control via `className` (e.g., `h-16 w-16`).
|
|
31
|
+
- **Fallback**: Displays initials or an icon when the image is unavailable.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
### With Image
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { Avatar, AvatarImage, AvatarFallback } from "laif-ds";
|
|
41
|
+
|
|
42
|
+
export function WithImage() {
|
|
43
|
+
return (
|
|
44
|
+
<Avatar>
|
|
45
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
|
|
46
|
+
<AvatarFallback>CN</AvatarFallback>
|
|
47
|
+
</Avatar>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### With Fallback
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { Avatar, AvatarImage, AvatarFallback } from "laif-ds";
|
|
56
|
+
|
|
57
|
+
export function WithFallback() {
|
|
58
|
+
return (
|
|
59
|
+
<Avatar>
|
|
60
|
+
<AvatarImage src="" alt="User" />
|
|
61
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
62
|
+
</Avatar>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Custom Size
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { Avatar, AvatarImage, AvatarFallback } from "laif-ds";
|
|
71
|
+
|
|
72
|
+
export function CustomSize() {
|
|
73
|
+
return (
|
|
74
|
+
<Avatar className="h-16 w-16">
|
|
75
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
|
|
76
|
+
<AvatarFallback>CN</AvatarFallback>
|
|
77
|
+
</Avatar>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Avatar Group
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import { Avatar, AvatarImage, AvatarFallback } from "laif-ds";
|
|
86
|
+
|
|
87
|
+
export function AvatarGroup() {
|
|
88
|
+
return (
|
|
89
|
+
<div className="flex -space-x-2">
|
|
90
|
+
<Avatar className="border-background border-2">
|
|
91
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
|
|
92
|
+
<AvatarFallback>CN</AvatarFallback>
|
|
93
|
+
</Avatar>
|
|
94
|
+
<Avatar className="border-background border-2">
|
|
95
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
|
|
96
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
97
|
+
</Avatar>
|
|
98
|
+
<Avatar className="border-background border-2">
|
|
99
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
|
|
100
|
+
<AvatarFallback>MK</AvatarFallback>
|
|
101
|
+
</Avatar>
|
|
102
|
+
</div>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Notes
|
|
110
|
+
|
|
111
|
+
- **Accessibility**: Provide `alt` text for `AvatarImage`.
|
|
112
|
+
- **Styling**: Combine with borders/shadows via `className`.
|
|
113
|
+
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Badge
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Small, inline label for status and metadata. Supports many visual variants, optional icons, link mode, and disabled state.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
### Badge (Root)
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------- |
|
|
15
|
+
| `variant` | `"default" \| "destructive" \| "warning" \| "success" \| "outline" \| "outline-primary" \| "outline-destructive" \| "outline-warning" \| "outline-success" \| "secondary" \| "ghost" \| "ghost-destructive" \| "ghost-accent" \| "ghost-warning" \| "ghost-success" \| "link"` | `"default"` | Visual style of the badge. |
|
|
16
|
+
| `asChild` | `boolean` | `false` | Renders the badge as its child element. |
|
|
17
|
+
| `disabled` | `boolean` | `false` | Disables interactions and dims the badge. |
|
|
18
|
+
| `iconLeft` | `IconName` | `undefined` | Optional left icon (uses `Icon` component). |
|
|
19
|
+
| `iconRight` | `IconName` | `undefined` | Optional right icon (uses `Icon` component).|
|
|
20
|
+
| `className` | `string` | `""` | Additional classes on the root element. |
|
|
21
|
+
| `children` | `React.ReactNode` | **required** | Text or content inside the badge. |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Behavior
|
|
26
|
+
|
|
27
|
+
- **Variants**: Outline, ghost, and semantic variants available for flexible UIs.
|
|
28
|
+
- **As child**: Use `asChild` to render as an anchor or any custom element.
|
|
29
|
+
- **Icons**: `iconLeft`/`iconRight` render `Icon` with appropriate sizes.
|
|
30
|
+
- **Disabled**: Applies `cursor-not-allowed` and reduces opacity.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Examples
|
|
35
|
+
|
|
36
|
+
### Default
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import { Badge } from "laif-ds";
|
|
40
|
+
|
|
41
|
+
export function DefaultBadge() {
|
|
42
|
+
return <Badge>Badge</Badge>;
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Variants Grid
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { Badge, type BadgeProps } from "laif-ds";
|
|
50
|
+
|
|
51
|
+
const variants: BadgeProps["variant"][] = [
|
|
52
|
+
"default",
|
|
53
|
+
"destructive",
|
|
54
|
+
"warning",
|
|
55
|
+
"success",
|
|
56
|
+
"outline",
|
|
57
|
+
"outline-primary",
|
|
58
|
+
"outline-destructive",
|
|
59
|
+
"outline-warning",
|
|
60
|
+
"outline-success",
|
|
61
|
+
"secondary",
|
|
62
|
+
"ghost",
|
|
63
|
+
"ghost-accent",
|
|
64
|
+
"ghost-destructive",
|
|
65
|
+
"ghost-warning",
|
|
66
|
+
"ghost-success",
|
|
67
|
+
"link",
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
export function VariantsShowcase() {
|
|
71
|
+
return (
|
|
72
|
+
<div className="flex flex-wrap gap-2">
|
|
73
|
+
{variants.map((v) => (
|
|
74
|
+
<Badge key={v} variant={v}>
|
|
75
|
+
{v}
|
|
76
|
+
</Badge>
|
|
77
|
+
))}
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### With Icons
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { Badge } from "laif-ds";
|
|
87
|
+
|
|
88
|
+
export function WithIcons() {
|
|
89
|
+
return (
|
|
90
|
+
<div className="flex gap-2">
|
|
91
|
+
<Badge iconLeft="Check" iconRight="X">Approved</Badge>
|
|
92
|
+
<Badge variant="outline-primary" iconLeft="Pencil">Edit</Badge>
|
|
93
|
+
</div>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### As Link (asChild)
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import { Badge } from "laif-ds";
|
|
102
|
+
|
|
103
|
+
export function LinkBadge() {
|
|
104
|
+
return (
|
|
105
|
+
<Badge asChild>
|
|
106
|
+
<a href="#" className="cursor-pointer">Clickable Badge</a>
|
|
107
|
+
</Badge>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Notes
|
|
115
|
+
|
|
116
|
+
- **Icons**: Use `IconName` values supported by the design system.
|
|
117
|
+
- **AsChild**: Useful to keep semantics (e.g., anchors) while styling as badges.
|
|
118
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Breadcrumb
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Composable breadcrumb navigation components. Includes list, items, links, separators, current page, and ellipsis. Lightweight wrappers around semantic HTML with sensible styles.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Subcomponents
|
|
10
|
+
|
|
11
|
+
- `Breadcrumb`
|
|
12
|
+
- `BreadcrumbList`
|
|
13
|
+
- `BreadcrumbItem`
|
|
14
|
+
- `BreadcrumbLink` (supports `asChild`)
|
|
15
|
+
- `BreadcrumbPage`
|
|
16
|
+
- `BreadcrumbSeparator` (defaults to chevron icon)
|
|
17
|
+
- `BreadcrumbEllipsis` (three-dot ellipsis)
|
|
18
|
+
|
|
19
|
+
All subcomponents extend their respective native element props.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Examples
|
|
24
|
+
|
|
25
|
+
### Basic
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import {
|
|
29
|
+
Breadcrumb,
|
|
30
|
+
BreadcrumbList,
|
|
31
|
+
BreadcrumbItem,
|
|
32
|
+
BreadcrumbLink,
|
|
33
|
+
BreadcrumbPage,
|
|
34
|
+
BreadcrumbSeparator,
|
|
35
|
+
} from "laif-ds";
|
|
36
|
+
|
|
37
|
+
export function BasicBreadcrumb() {
|
|
38
|
+
return (
|
|
39
|
+
<Breadcrumb>
|
|
40
|
+
<BreadcrumbList>
|
|
41
|
+
<BreadcrumbItem>
|
|
42
|
+
<BreadcrumbLink href="/">Home</BreadcrumbLink>
|
|
43
|
+
</BreadcrumbItem>
|
|
44
|
+
<BreadcrumbSeparator />
|
|
45
|
+
<BreadcrumbItem>
|
|
46
|
+
<BreadcrumbLink href="/docs">Docs</BreadcrumbLink>
|
|
47
|
+
</BreadcrumbItem>
|
|
48
|
+
<BreadcrumbSeparator />
|
|
49
|
+
<BreadcrumbItem>
|
|
50
|
+
<BreadcrumbPage>Components</BreadcrumbPage>
|
|
51
|
+
</BreadcrumbItem>
|
|
52
|
+
</BreadcrumbList>
|
|
53
|
+
</Breadcrumb>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Custom Separator
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbSeparator, BreadcrumbPage } from "laif-ds";
|
|
62
|
+
|
|
63
|
+
export function CustomSeparator() {
|
|
64
|
+
return (
|
|
65
|
+
<Breadcrumb>
|
|
66
|
+
<BreadcrumbList>
|
|
67
|
+
<BreadcrumbItem>
|
|
68
|
+
<BreadcrumbLink href="/">Home</BreadcrumbLink>
|
|
69
|
+
</BreadcrumbItem>
|
|
70
|
+
<BreadcrumbSeparator>/</BreadcrumbSeparator>
|
|
71
|
+
<BreadcrumbItem>
|
|
72
|
+
<BreadcrumbPage>Current</BreadcrumbPage>
|
|
73
|
+
</BreadcrumbItem>
|
|
74
|
+
</BreadcrumbList>
|
|
75
|
+
</Breadcrumb>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
```
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Button
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Versatile button with multiple variants and sizes, optional leading/trailing icons, loading state, and support for rendering as a child element.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
### Button (Root)
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | -------------------------------------------------------- |
|
|
15
|
+
| `variant` | `"default" | "destructive" | "outline" | "outline-primary" | "outline-destructive" | "secondary" | "ghost" | "ghost-destructive" | "ghost-accent" | "link"` | `"default"` | Visual style of the button. |
|
|
16
|
+
| `size` | `"default" | "sm" | "lg" | "icon"` | `"default"` | Size of the button. |
|
|
17
|
+
| `asChild` | `boolean` | `false` | Render as child (e.g., anchor) while preserving styles. |
|
|
18
|
+
| `iconLeft` | `IconName` | `undefined` | Optional left icon name. |
|
|
19
|
+
| `iconRight` | `IconName` | `undefined` | Optional right icon name. |
|
|
20
|
+
| `isLoading` | `boolean` | `false` | Shows a loading spinner; overrides `iconLeft`. |
|
|
21
|
+
| `className` | `string` | `""` | Additional classes for layout/width. |
|
|
22
|
+
| `disabled` | `boolean` | `false` | Disables the button. |
|
|
23
|
+
| `onClick` | `(e: React.MouseEvent<HTMLButtonElement>) => void` | `undefined` | Click handler. |
|
|
24
|
+
| `children` | `React.ReactNode` | **required** | Button label or content. |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Behavior
|
|
29
|
+
|
|
30
|
+
- **Loading**: When `isLoading` is `true`, a spinner is shown and `iconLeft` is hidden.
|
|
31
|
+
- **Icons**: Icon sizes adapt to the button size (`sm`, `default`, `lg`, `icon`).
|
|
32
|
+
- **As Child**: Use `asChild` to render the button as a link or custom element while keeping button styles.
|
|
33
|
+
- **Accessibility**: Keyboard-focus ring and proper semantics are included.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Examples
|
|
38
|
+
|
|
39
|
+
### Default
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { Button } from "laif-ds";
|
|
43
|
+
|
|
44
|
+
export function DefaultButton() {
|
|
45
|
+
return <Button>Button</Button>;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Showcase (Variants × Sizes)
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import { Button, type ButtonProps } from "laif-ds";
|
|
53
|
+
|
|
54
|
+
const variants: ButtonProps["variant"][] = [
|
|
55
|
+
"default",
|
|
56
|
+
"destructive",
|
|
57
|
+
"outline",
|
|
58
|
+
"outline-primary",
|
|
59
|
+
"outline-destructive",
|
|
60
|
+
"secondary",
|
|
61
|
+
"ghost",
|
|
62
|
+
"ghost-accent",
|
|
63
|
+
"ghost-destructive",
|
|
64
|
+
"link",
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
const sizes: ButtonProps["size"][] = ["lg", "default", "sm", "icon"];
|
|
68
|
+
|
|
69
|
+
export function ButtonsGrid() {
|
|
70
|
+
return (
|
|
71
|
+
<div className="flex flex-col gap-4">
|
|
72
|
+
{variants.map((variant) => (
|
|
73
|
+
<div key={variant} className="flex items-center gap-2 flex-wrap">
|
|
74
|
+
{sizes.map((size) => (
|
|
75
|
+
size === "icon" ? (
|
|
76
|
+
<Button key={`${variant}-${size}`} variant={variant} size={size} iconLeft="BadgeInfo" />
|
|
77
|
+
) : (
|
|
78
|
+
<Button key={`${variant}-${size}`} variant={variant} size={size}>
|
|
79
|
+
{variant} - {size}
|
|
80
|
+
</Button>
|
|
81
|
+
)
|
|
82
|
+
))}
|
|
83
|
+
</div>
|
|
84
|
+
))}
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Full Width
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { Button } from "laif-ds";
|
|
94
|
+
|
|
95
|
+
export function FullWidthButton() {
|
|
96
|
+
return (
|
|
97
|
+
<Button className="w-full">Full Width Button</Button>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### With Icon
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
import { Button } from "laif-ds";
|
|
106
|
+
|
|
107
|
+
export function WithIcon() {
|
|
108
|
+
return <Button iconLeft="Check">Button with Icon</Button>;
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Loading
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
import { Button } from "laif-ds";
|
|
116
|
+
|
|
117
|
+
export function LoadingButton() {
|
|
118
|
+
return <Button isLoading>Loading Button</Button>;
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Notes
|
|
125
|
+
|
|
126
|
+
- **Disabled**: Applies reduced opacity and prevents interactions.
|
|
127
|
+
- **Icon-only**: Use `size="icon"` for square icon buttons.
|
|
128
|
+
- **Theming**: Use variants to match semantic meaning (primary, destructive, etc.).
|
|
129
|
+
|