florixui 1.0.0
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/README.md +919 -0
- package/dist/components/custom/actions-menu.d.ts +41 -0
- package/dist/components/custom/advanced-input.d.ts +39 -0
- package/dist/components/custom/advanced-select.d.ts +67 -0
- package/dist/components/custom/data-table.d.ts +38 -0
- package/dist/components/custom/date-time-range-picker-utils.d.ts +32 -0
- package/dist/components/custom/date-time-range-picker.d.ts +15 -0
- package/dist/components/ui/alert-dialog.d.ts +18 -0
- package/dist/components/ui/alert.d.ts +10 -0
- package/dist/components/ui/badge.d.ts +9 -0
- package/dist/components/ui/button-group.d.ts +11 -0
- package/dist/components/ui/button.d.ts +10 -0
- package/dist/components/ui/calendar.d.ts +10 -0
- package/dist/components/ui/card.d.ts +11 -0
- package/dist/components/ui/chart.d.ts +44 -0
- package/dist/components/ui/checkbox.d.ts +4 -0
- package/dist/components/ui/command.d.ts +18 -0
- package/dist/components/ui/dialog.d.ts +17 -0
- package/dist/components/ui/dropdown-menu.d.ts +29 -0
- package/dist/components/ui/field.d.ts +24 -0
- package/dist/components/ui/hover-card.d.ts +6 -0
- package/dist/components/ui/input-group.d.ts +16 -0
- package/dist/components/ui/input.d.ts +3 -0
- package/dist/components/ui/item.d.ts +23 -0
- package/dist/components/ui/label.d.ts +4 -0
- package/dist/components/ui/map.d.ts +278 -0
- package/dist/components/ui/popover.d.ts +10 -0
- package/dist/components/ui/progress.d.ts +4 -0
- package/dist/components/ui/radio-group.d.ts +5 -0
- package/dist/components/ui/select.d.ts +15 -0
- package/dist/components/ui/separator.d.ts +4 -0
- package/dist/components/ui/sheet.d.ts +14 -0
- package/dist/components/ui/slider.d.ts +4 -0
- package/dist/components/ui/sonner.d.ts +3 -0
- package/dist/components/ui/spinner.d.ts +2 -0
- package/dist/components/ui/stepper.d.ts +27 -0
- package/dist/components/ui/switch.d.ts +6 -0
- package/dist/components/ui/table.d.ts +10 -0
- package/dist/components/ui/tabs.d.ts +11 -0
- package/dist/components/ui/textarea.d.ts +3 -0
- package/dist/components/ui/timeline.d.ts +25 -0
- package/dist/components/ui/toggle-group.d.ts +10 -0
- package/dist/components/ui/toggle.d.ts +9 -0
- package/dist/components/ui/tooltip.d.ts +7 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +3638 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/styles.css +2 -0
- package/package.json +104 -0
package/README.md
ADDED
|
@@ -0,0 +1,919 @@
|
|
|
1
|
+
# FlorixUI
|
|
2
|
+
|
|
3
|
+
A React component library built on [shadcn/ui](https://ui.shadcn.com) and [Tailwind CSS v4](https://tailwindcss.com). Ships as a bundled npm package (`florixui`) — install it, import components, import one stylesheet.
|
|
4
|
+
|
|
5
|
+
**A focused set of components** is included — shadcn/ui primitives (Alert, Alert Dialog, Badge, Button, Button Group, Calendar, Card, Chart, Checkbox, Command, Dialog, Dropdown Menu, Field, Hover Card, Input, Input Group, Item, Label, Popover, Progress, Radio Group, Select, Separator, Sheet, Slider, Sonner, Spinner, Stepper, Switch, Table, Tabs, Textarea, Timeline, Toggle, Toggle Group, Tooltip), plus custom components (Actions Menu, Advanced Input, Advanced Select, Data Table, Date Time Range Picker, Map) — each documented with live examples in the docs site. Browse them with `npm run dev`.
|
|
6
|
+
|
|
7
|
+
Primitives that are app-specific or pull in extra dependencies (Accordion, Aspect Ratio, Avatar, Breadcrumb, Carousel, Collapsible, Context Menu, Drawer, Empty, Form, Input OTP, Kbd, Menubar, Native Select, Navigation Menu, Pagination, Resizable, Scroll Area, Sidebar, Skeleton) are intentionally not bundled — add them directly with `npx shadcn@latest add <name>` in your app if you need them.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Install (in a consuming project)
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install florixui
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`react` and `react-dom` (v18+) are peer dependencies — your app already provides them.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
Import the stylesheet **once** at your app's entry point, then use components anywhere:
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
// main.tsx / App entry
|
|
24
|
+
import "florixui/styles.css";
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import { Button } from "florixui";
|
|
29
|
+
|
|
30
|
+
export function Example() {
|
|
31
|
+
return (
|
|
32
|
+
<div className="flex gap-3">
|
|
33
|
+
<Button>Default</Button>
|
|
34
|
+
<Button variant="secondary">Secondary</Button>
|
|
35
|
+
<Button variant="outline">Outline</Button>
|
|
36
|
+
<Button variant="destructive">Delete</Button>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The `cn()` class-merging helper is also exported:
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { cn } from "florixui";
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Dark mode
|
|
49
|
+
|
|
50
|
+
The stylesheet defines a `.dark` variant. Toggle dark mode by adding the `dark`
|
|
51
|
+
class to a root element (e.g. `<html class="dark">`).
|
|
52
|
+
|
|
53
|
+
### Themes
|
|
54
|
+
|
|
55
|
+
The package ships **5 themes**. Select one by setting `data-theme` on a root
|
|
56
|
+
element; the default (no attribute) is `slate-blue`. Themes combine with dark
|
|
57
|
+
mode:
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<html data-theme="crimson" class="dark">
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
| slug | look |
|
|
64
|
+
| ------------- | ------------------------------------- |
|
|
65
|
+
| `slate-blue` | Calm blue on slate (default) · Inter |
|
|
66
|
+
| `crimson` | Vivid red · Inter + JetBrains Mono |
|
|
67
|
+
| `terracotta` | Warm rust · DM Sans family |
|
|
68
|
+
| `indigo` | Bold indigo · Inter + Merriweather |
|
|
69
|
+
| `azure` | Bright blue · Inter + JetBrains Mono |
|
|
70
|
+
|
|
71
|
+
Each theme references specific fonts but the package does **not** bundle them
|
|
72
|
+
(see below) — colors, radius, and shadows all work without the fonts; install
|
|
73
|
+
the matching `@fontsource` package if you want a theme's exact typeface.
|
|
74
|
+
|
|
75
|
+
### Fonts (optional)
|
|
76
|
+
|
|
77
|
+
To keep `styles.css` a single self-contained file, fonts are **not** bundled.
|
|
78
|
+
Each theme's font stack falls back to system fonts, so everything works without
|
|
79
|
+
them. To render a theme in its true typeface, install the matching
|
|
80
|
+
`@fontsource` package(s) and import them in your app entry. For example, for
|
|
81
|
+
the default `slate-blue` theme (Inter):
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npm install @fontsource-variable/inter
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import "@fontsource-variable/inter";
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Fonts used across the themes: Inter, JetBrains Mono, Roboto Mono, DM Sans,
|
|
92
|
+
DM Serif Text, DM Mono, Merriweather, Noto Serif Georgian.
|
|
93
|
+
|
|
94
|
+
## Developing this library
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npm run docs:dev # run the documentation site with HMR (default dev server)
|
|
98
|
+
npm run docs:build # build the docs site into dist-docs/
|
|
99
|
+
npm run docs:preview # preview the built docs site
|
|
100
|
+
npm run build:lib # build the publishable package into dist/
|
|
101
|
+
npm run lint
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Documentation site
|
|
105
|
+
|
|
106
|
+
The `docs/` directory is a small React app that documents the library. It
|
|
107
|
+
imports components straight from source (`@/components/...`), so examples stay
|
|
108
|
+
in sync as you build. Each component page shows a **live preview**, the
|
|
109
|
+
**source code** (with copy button), a **props/API table**, and **usage notes**.
|
|
110
|
+
There's a sidebar for navigation and a light/dark theme toggle.
|
|
111
|
+
|
|
112
|
+
It is **not** part of the published package — only `dist/` is published.
|
|
113
|
+
|
|
114
|
+
Everything is driven by `docs/registry.tsx`. To document a new component, add a
|
|
115
|
+
`ComponentDoc` entry there:
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
// docs/registry.tsx
|
|
119
|
+
import { Card } from '@/components/ui/card'
|
|
120
|
+
|
|
121
|
+
export const components: ComponentDoc[] = [
|
|
122
|
+
// ...existing entries
|
|
123
|
+
{
|
|
124
|
+
slug: 'card',
|
|
125
|
+
name: 'Card',
|
|
126
|
+
description: 'A container that groups related content.',
|
|
127
|
+
usage: <p>Use cards to…</p>,
|
|
128
|
+
examples: [
|
|
129
|
+
{
|
|
130
|
+
name: 'Basic',
|
|
131
|
+
render: () => <Card>…</Card>,
|
|
132
|
+
code: `<Card>…</Card>`,
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
props: [
|
|
136
|
+
{ prop: 'className', type: 'string', description: 'Extra classes.' },
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
]
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The sidebar, routing (`#/card`), and page layout update automatically.
|
|
143
|
+
|
|
144
|
+
### Adding components
|
|
145
|
+
|
|
146
|
+
Add shadcn components, then export them from `src/index.ts` and document them
|
|
147
|
+
in `docs/registry.tsx`:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npx shadcn@latest add card input dialog
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
// src/index.ts
|
|
155
|
+
export { Card, CardHeader, CardContent } from "@/components/ui/card";
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Publishing
|
|
159
|
+
|
|
160
|
+
`prepublishOnly` runs `build:lib` automatically, so:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
npm version patch
|
|
164
|
+
npm publish # add --access public for a public scoped package
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Only the `dist/` directory is published (see the `files` field in `package.json`).
|
|
168
|
+
|
|
169
|
+
## How it's built
|
|
170
|
+
|
|
171
|
+
- **`src/index.ts`** — the package entry; re-exports every public component + util.
|
|
172
|
+
- **`src/styles.css`** — the distributable stylesheet; `@source "./components"`
|
|
173
|
+
tells Tailwind to scan components so the compiled CSS contains every utility
|
|
174
|
+
class they use.
|
|
175
|
+
- **Vite library mode** (`vite.config.ts`, gated on `LIB_BUILD`) emits the ESM
|
|
176
|
+
bundle with React externalized, plus `.d.ts` files via `vite-plugin-dts`.
|
|
177
|
+
|
|
178
|
+
<!-- COMPONENTS:START -->
|
|
179
|
+
|
|
180
|
+
## Components
|
|
181
|
+
|
|
182
|
+
> Auto-generated from the docs registry. Each component below shows a quick usage snippet; run `npm run dev` for the full interactive docs (every variant + props table).
|
|
183
|
+
|
|
184
|
+
### Actions Menu
|
|
185
|
+
|
|
186
|
+
A drop-in "three-dot" overflow menu. Pass a flat list of items (actions, labels, separators) and it renders a kebab-triggered dropdown.
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
<ActionsMenu
|
|
190
|
+
triggerLabel="Open row actions"
|
|
191
|
+
items={[
|
|
192
|
+
{ label: "Edit", icon: Pencil },
|
|
193
|
+
{ label: "Duplicate", icon: Copy },
|
|
194
|
+
{ type: "separator" },
|
|
195
|
+
{ label: "Delete", icon: Trash2, destructive: true },
|
|
196
|
+
]}
|
|
197
|
+
/>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Advanced Input
|
|
201
|
+
|
|
202
|
+
A batteries-included input that bundles label, description, icons, affixes, password toggle, loading, error/helper text, and a textarea mode into one component.
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
<AdvancedInput
|
|
206
|
+
label="Email"
|
|
207
|
+
required
|
|
208
|
+
type="email"
|
|
209
|
+
placeholder="m@example.com"
|
|
210
|
+
helperText="We'll never share your email."
|
|
211
|
+
description="Used for sign-in and notifications."
|
|
212
|
+
/>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Advanced Select
|
|
216
|
+
|
|
217
|
+
A combobox-style select built on Popover + Command with search, multi-select, groups, descriptions, clear, select-all, create-new, infinite scroll, and input-group affixes.
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
const [value, setValue] = React.useState("")
|
|
221
|
+
|
|
222
|
+
<AdvancedSelect
|
|
223
|
+
options={["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"]}
|
|
224
|
+
value={value}
|
|
225
|
+
onValueChange={(v) => setValue(v as string)}
|
|
226
|
+
placeholder="Pick a fruit"
|
|
227
|
+
searchable
|
|
228
|
+
clearable
|
|
229
|
+
/>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Alert
|
|
233
|
+
|
|
234
|
+
Displays a short, important message that draws attention without interrupting the user.
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
<Alert>
|
|
238
|
+
<Terminal />
|
|
239
|
+
<AlertTitle>Heads up!</AlertTitle>
|
|
240
|
+
<AlertDescription>
|
|
241
|
+
You can add components to your app using the CLI.
|
|
242
|
+
</AlertDescription>
|
|
243
|
+
</Alert>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Alert Dialog
|
|
247
|
+
|
|
248
|
+
A modal dialog that interrupts the user with important content and expects a confirm or cancel response before continuing.
|
|
249
|
+
|
|
250
|
+
```tsx
|
|
251
|
+
<AlertDialog>
|
|
252
|
+
<AlertDialogTrigger asChild>
|
|
253
|
+
<Button variant="destructive">Delete account</Button>
|
|
254
|
+
</AlertDialogTrigger>
|
|
255
|
+
<AlertDialogContent>
|
|
256
|
+
<AlertDialogHeader>
|
|
257
|
+
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
|
258
|
+
<AlertDialogDescription>
|
|
259
|
+
This permanently deletes your account and removes your data from
|
|
260
|
+
our servers. This action cannot be undone.
|
|
261
|
+
</AlertDialogDescription>
|
|
262
|
+
</AlertDialogHeader>
|
|
263
|
+
<AlertDialogFooter>
|
|
264
|
+
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
|
265
|
+
<AlertDialogAction variant="destructive">
|
|
266
|
+
Delete account
|
|
267
|
+
</AlertDialogAction>
|
|
268
|
+
</AlertDialogFooter>
|
|
269
|
+
</AlertDialogContent>
|
|
270
|
+
</AlertDialog>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Badge
|
|
274
|
+
|
|
275
|
+
A small label that highlights status, category, or count alongside other content.
|
|
276
|
+
|
|
277
|
+
```tsx
|
|
278
|
+
<Badge>Default</Badge>
|
|
279
|
+
<Badge variant="secondary">Secondary</Badge>
|
|
280
|
+
<Badge variant="destructive">Destructive</Badge>
|
|
281
|
+
<Badge variant="outline">Outline</Badge>
|
|
282
|
+
<Badge variant="ghost">Ghost</Badge>
|
|
283
|
+
<Badge variant="link">Link</Badge>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Button
|
|
287
|
+
|
|
288
|
+
Triggers an action or event, such as submitting a form or opening a dialog.
|
|
289
|
+
|
|
290
|
+
```tsx
|
|
291
|
+
<Button>Default</Button>
|
|
292
|
+
<Button variant="secondary">Secondary</Button>
|
|
293
|
+
<Button variant="outline">Outline</Button>
|
|
294
|
+
<Button variant="destructive">Destructive</Button>
|
|
295
|
+
<Button variant="ghost">Ghost</Button>
|
|
296
|
+
<Button variant="link">Link</Button>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Button Group
|
|
300
|
+
|
|
301
|
+
Visually and semantically groups a set of related buttons (or button-like elements) into a single connected control.
|
|
302
|
+
|
|
303
|
+
```tsx
|
|
304
|
+
<ButtonGroup aria-label="Text alignment">
|
|
305
|
+
<Button variant="outline">Left</Button>
|
|
306
|
+
<Button variant="outline">Center</Button>
|
|
307
|
+
<Button variant="outline">Right</Button>
|
|
308
|
+
</ButtonGroup>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Calendar
|
|
312
|
+
|
|
313
|
+
A date field that lets users view a month grid and select a single day, multiple days, or a range.
|
|
314
|
+
|
|
315
|
+
```tsx
|
|
316
|
+
const [date, setDate] = React.useState<Date | undefined>(new Date())
|
|
317
|
+
|
|
318
|
+
return (
|
|
319
|
+
<Calendar
|
|
320
|
+
mode="single"
|
|
321
|
+
selected={date}
|
|
322
|
+
onSelect={setDate}
|
|
323
|
+
className="rounded-md border"
|
|
324
|
+
/>
|
|
325
|
+
)
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Card
|
|
329
|
+
|
|
330
|
+
A bordered surface that groups related content and actions into a single container.
|
|
331
|
+
|
|
332
|
+
```tsx
|
|
333
|
+
<Card className="w-full max-w-sm">
|
|
334
|
+
<CardHeader>
|
|
335
|
+
<CardTitle>Create project</CardTitle>
|
|
336
|
+
<CardDescription>
|
|
337
|
+
Deploy your new project in one click.
|
|
338
|
+
</CardDescription>
|
|
339
|
+
</CardHeader>
|
|
340
|
+
<CardContent>
|
|
341
|
+
<p className="text-muted-foreground">
|
|
342
|
+
Name your project and choose a region to get started.
|
|
343
|
+
</p>
|
|
344
|
+
</CardContent>
|
|
345
|
+
<CardFooter className="justify-end gap-2">
|
|
346
|
+
<Button variant="outline">Cancel</Button>
|
|
347
|
+
<Button>Deploy</Button>
|
|
348
|
+
</CardFooter>
|
|
349
|
+
</Card>
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Chart
|
|
353
|
+
|
|
354
|
+
A theming and tooltip/legend wrapper around Recharts that maps a config object to CSS color variables for consistent, accessible charts.
|
|
355
|
+
|
|
356
|
+
```tsx
|
|
357
|
+
const chartConfig = {
|
|
358
|
+
desktop: { label: 'Desktop', color: 'hsl(220 70% 50%)' },
|
|
359
|
+
mobile: { label: 'Mobile', color: 'hsl(160 60% 45%)' },
|
|
360
|
+
} satisfies ChartConfig
|
|
361
|
+
|
|
362
|
+
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
|
|
363
|
+
<BarChart accessibilityLayer data={data}>
|
|
364
|
+
<CartesianGrid vertical={false} />
|
|
365
|
+
<XAxis dataKey="month" tickLine={false} tickMargin={10} axisLine={false} />
|
|
366
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
367
|
+
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
|
368
|
+
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
|
369
|
+
</BarChart>
|
|
370
|
+
</ChartContainer>
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Checkbox
|
|
374
|
+
|
|
375
|
+
A control that lets the user toggle a single option on or off, or select multiple options from a set.
|
|
376
|
+
|
|
377
|
+
```tsx
|
|
378
|
+
<div className="flex items-center gap-2">
|
|
379
|
+
<Checkbox id="terms" />
|
|
380
|
+
<label htmlFor="terms" className="text-sm leading-none">
|
|
381
|
+
Accept terms and conditions
|
|
382
|
+
</label>
|
|
383
|
+
</div>
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Colors
|
|
387
|
+
|
|
388
|
+
Global semantic accent colors — red, orange, blue, green — each with a foreground pairing and distinct light/dark shades. Independent of the active theme.
|
|
389
|
+
|
|
390
|
+
```tsx
|
|
391
|
+
<div className="bg-red text-red-foreground">…</div>
|
|
392
|
+
<div className="bg-orange text-orange-foreground">…</div>
|
|
393
|
+
<div className="bg-blue text-blue-foreground">…</div>
|
|
394
|
+
<div className="bg-green text-green-foreground">…</div>
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### Command
|
|
398
|
+
|
|
399
|
+
A fast, composable command menu with fuzzy search for navigating actions, built on cmdk.
|
|
400
|
+
|
|
401
|
+
```tsx
|
|
402
|
+
<Command className="max-w-md rounded-lg border shadow-md">
|
|
403
|
+
<CommandInput placeholder="Type a command or search..." />
|
|
404
|
+
<CommandList>
|
|
405
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
406
|
+
<CommandGroup heading="Suggestions">
|
|
407
|
+
<CommandItem>Calendar</CommandItem>
|
|
408
|
+
<CommandItem>Search Emoji</CommandItem>
|
|
409
|
+
<CommandItem>Calculator</CommandItem>
|
|
410
|
+
</CommandGroup>
|
|
411
|
+
</CommandList>
|
|
412
|
+
</Command>
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### Data Table
|
|
416
|
+
|
|
417
|
+
A simple, column-driven table with the shadcn data-table look: badge cells, row selection, a row-actions menu, and empty/loading states — no sorting/pagination machinery.
|
|
418
|
+
|
|
419
|
+
```tsx
|
|
420
|
+
const columns: DataTableColumn<Section>[] = [
|
|
421
|
+
{ key: "header", header: "Header", cell: (r) => <span className="font-medium">{r.header}</span> },
|
|
422
|
+
{ key: "type", header: "Section Type", cell: (r) => <Badge variant="outline">{r.type}</Badge> },
|
|
423
|
+
{ key: "status", header: "Status", cell: (r) => <StatusBadge status={r.status} /> },
|
|
424
|
+
{ key: "target", header: "Target", align: "right", width: "6rem" },
|
|
425
|
+
{ key: "limit", header: "Limit", align: "right", width: "6rem" },
|
|
426
|
+
{ key: "reviewer", header: "Reviewer" },
|
|
427
|
+
]
|
|
428
|
+
|
|
429
|
+
<DataTable
|
|
430
|
+
data={sections}
|
|
431
|
+
columns={columns}
|
|
432
|
+
getRowId={(r) => r.id}
|
|
433
|
+
selectable
|
|
434
|
+
selectedIds={selected}
|
|
435
|
+
onSelectionChange={setSelected}
|
|
436
|
+
rowActions={(row) => [
|
|
437
|
+
{ label: "Edit", icon: Pencil, onSelect: () => edit(row) },
|
|
438
|
+
{ type: "separator" },
|
|
439
|
+
{ label: "Delete", icon: Trash2, destructive: true, onSelect: () => remove(row) },
|
|
440
|
+
]}
|
|
441
|
+
/>
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Date Time Range Picker
|
|
445
|
+
|
|
446
|
+
A time-range picker with quick presets (hour/day/week/month) and a custom From/To selector — each a calendar plus a precise hour:minute:second time row. Timezone-aware, controlled via ISO strings.
|
|
447
|
+
|
|
448
|
+
```tsx
|
|
449
|
+
import { DateTimeRangePicker, presetToRange, type TimeRange } from "florixui"
|
|
450
|
+
|
|
451
|
+
const [range, setRange] = React.useState<TimeRange>({
|
|
452
|
+
preset: "day",
|
|
453
|
+
...presetToRange("day"),
|
|
454
|
+
})
|
|
455
|
+
|
|
456
|
+
<DateTimeRangePicker value={range} onChange={setRange} />
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### Dialog
|
|
460
|
+
|
|
461
|
+
A modal window overlaid on the page that interrupts the user to require a response, such as a confirmation or a focused form.
|
|
462
|
+
|
|
463
|
+
```tsx
|
|
464
|
+
<Dialog>
|
|
465
|
+
<DialogTrigger asChild>
|
|
466
|
+
<Button variant="outline">Open dialog</Button>
|
|
467
|
+
</DialogTrigger>
|
|
468
|
+
<DialogContent>
|
|
469
|
+
<DialogHeader>
|
|
470
|
+
<DialogTitle>Share document</DialogTitle>
|
|
471
|
+
<DialogDescription>
|
|
472
|
+
Anyone with the link will be able to view this document.
|
|
473
|
+
</DialogDescription>
|
|
474
|
+
</DialogHeader>
|
|
475
|
+
<DialogFooter>
|
|
476
|
+
<DialogClose asChild>
|
|
477
|
+
<Button variant="outline">Cancel</Button>
|
|
478
|
+
</DialogClose>
|
|
479
|
+
<Button>Copy link</Button>
|
|
480
|
+
</DialogFooter>
|
|
481
|
+
</DialogContent>
|
|
482
|
+
</Dialog>
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Dropdown Menu
|
|
486
|
+
|
|
487
|
+
Displays a menu of actions or options triggered by a button, built on Radix UI with full keyboard and focus support.
|
|
488
|
+
|
|
489
|
+
```tsx
|
|
490
|
+
<DropdownMenu>
|
|
491
|
+
<DropdownMenuTrigger asChild>
|
|
492
|
+
<Button variant="outline">Open menu</Button>
|
|
493
|
+
</DropdownMenuTrigger>
|
|
494
|
+
<DropdownMenuContent className="w-56">
|
|
495
|
+
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
|
496
|
+
<DropdownMenuSeparator />
|
|
497
|
+
<DropdownMenuGroup>
|
|
498
|
+
<DropdownMenuItem>
|
|
499
|
+
Profile
|
|
500
|
+
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
|
|
501
|
+
</DropdownMenuItem>
|
|
502
|
+
<DropdownMenuItem>
|
|
503
|
+
Settings
|
|
504
|
+
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
|
|
505
|
+
</DropdownMenuItem>
|
|
506
|
+
</DropdownMenuGroup>
|
|
507
|
+
<DropdownMenuSeparator />
|
|
508
|
+
<DropdownMenuItem variant="destructive">
|
|
509
|
+
Log out
|
|
510
|
+
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
|
|
511
|
+
</DropdownMenuItem>
|
|
512
|
+
</DropdownMenuContent>
|
|
513
|
+
</DropdownMenu>
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### Field
|
|
517
|
+
|
|
518
|
+
Layout primitives that pair a form control with its label, description, and error message in a consistent, accessible structure.
|
|
519
|
+
|
|
520
|
+
```tsx
|
|
521
|
+
<Field>
|
|
522
|
+
<FieldLabel htmlFor="email">Email</FieldLabel>
|
|
523
|
+
<Input id="email" type="email" placeholder="you@example.com" />
|
|
524
|
+
<FieldDescription>
|
|
525
|
+
We'll only use this to send receipts.
|
|
526
|
+
</FieldDescription>
|
|
527
|
+
</Field>
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### Hover Card
|
|
531
|
+
|
|
532
|
+
Shows rich preview content in a floating card when the user hovers over or focuses a trigger.
|
|
533
|
+
|
|
534
|
+
```tsx
|
|
535
|
+
<HoverCard>
|
|
536
|
+
<HoverCardTrigger asChild>
|
|
537
|
+
<Button variant="link">@shadcn</Button>
|
|
538
|
+
</HoverCardTrigger>
|
|
539
|
+
<HoverCardContent>
|
|
540
|
+
<p className="font-medium">@shadcn</p>
|
|
541
|
+
<p className="text-muted-foreground">
|
|
542
|
+
Creator of the component library. Hover to learn more.
|
|
543
|
+
</p>
|
|
544
|
+
</HoverCardContent>
|
|
545
|
+
</HoverCard>
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Input
|
|
549
|
+
|
|
550
|
+
A single-line text field for collecting short, free-form user input such as names, emails, or passwords.
|
|
551
|
+
|
|
552
|
+
```tsx
|
|
553
|
+
<Input type="text" placeholder="Enter your name" />
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
### Input Group
|
|
557
|
+
|
|
558
|
+
Wraps an input or textarea with aligned addons such as icons, text, or buttons to form a single composed control.
|
|
559
|
+
|
|
560
|
+
```tsx
|
|
561
|
+
<InputGroup className="max-w-sm">
|
|
562
|
+
<InputGroupAddon>
|
|
563
|
+
<InputGroupText>https://</InputGroupText>
|
|
564
|
+
</InputGroupAddon>
|
|
565
|
+
<InputGroupInput placeholder="example.com" />
|
|
566
|
+
</InputGroup>
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
### Item
|
|
570
|
+
|
|
571
|
+
A flexible row for displaying a piece of content with optional media, title, description, and actions.
|
|
572
|
+
|
|
573
|
+
```tsx
|
|
574
|
+
<Item variant="outline" className="max-w-md">
|
|
575
|
+
<ItemMedia variant="icon">
|
|
576
|
+
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
577
|
+
<circle cx="12" cy="12" r="10" fill="currentColor" />
|
|
578
|
+
</svg>
|
|
579
|
+
</ItemMedia>
|
|
580
|
+
<ItemContent>
|
|
581
|
+
<ItemTitle>Project Atlas</ItemTitle>
|
|
582
|
+
<ItemDescription>Updated 3 minutes ago by Dana.</ItemDescription>
|
|
583
|
+
</ItemContent>
|
|
584
|
+
<ItemActions>
|
|
585
|
+
<Button variant="outline" size="sm">Open</Button>
|
|
586
|
+
</ItemActions>
|
|
587
|
+
</Item>
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
### Label
|
|
591
|
+
|
|
592
|
+
Renders an accessible caption for a form control, associating text with an input via htmlFor.
|
|
593
|
+
|
|
594
|
+
```tsx
|
|
595
|
+
<div className="grid w-full max-w-sm gap-2">
|
|
596
|
+
<Label htmlFor="email">Email</Label>
|
|
597
|
+
<Input id="email" type="email" placeholder="you@example.com" />
|
|
598
|
+
</div>
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### Map
|
|
602
|
+
|
|
603
|
+
An interactive map built on MapLibre GL (via mapcn), with markers, routes, clustering, and overlays. Uses a free CARTO light basemap by default with no attribution — no API key required.
|
|
604
|
+
|
|
605
|
+
```tsx
|
|
606
|
+
<Map
|
|
607
|
+
viewport={{ center: [-122.4194, 37.7749], zoom: 10 }}
|
|
608
|
+
className="h-[360px] w-full rounded-lg border"
|
|
609
|
+
/>
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
### Popover
|
|
613
|
+
|
|
614
|
+
Displays rich, floating content in a portal, anchored to a trigger and toggled by click.
|
|
615
|
+
|
|
616
|
+
```tsx
|
|
617
|
+
<Popover>
|
|
618
|
+
<PopoverTrigger asChild>
|
|
619
|
+
<Button variant="outline">Open popover</Button>
|
|
620
|
+
</PopoverTrigger>
|
|
621
|
+
<PopoverContent>
|
|
622
|
+
<PopoverHeader>
|
|
623
|
+
<PopoverTitle>Dimensions</PopoverTitle>
|
|
624
|
+
<PopoverDescription>
|
|
625
|
+
Set the size for the selected layer.
|
|
626
|
+
</PopoverDescription>
|
|
627
|
+
</PopoverHeader>
|
|
628
|
+
</PopoverContent>
|
|
629
|
+
</Popover>
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### Progress
|
|
633
|
+
|
|
634
|
+
Displays an indicator showing the completion progress of a task, such as a download or upload.
|
|
635
|
+
|
|
636
|
+
```tsx
|
|
637
|
+
<Progress value={60} aria-label="Loading" />
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
### Radio Group
|
|
641
|
+
|
|
642
|
+
A set of checkable buttons where no more than one can be selected at a time.
|
|
643
|
+
|
|
644
|
+
```tsx
|
|
645
|
+
<RadioGroup defaultValue="comfortable">
|
|
646
|
+
<div className="flex items-center gap-2">
|
|
647
|
+
<RadioGroupItem value="default" id="r1" />
|
|
648
|
+
<Label htmlFor="r1">Default</Label>
|
|
649
|
+
</div>
|
|
650
|
+
<div className="flex items-center gap-2">
|
|
651
|
+
<RadioGroupItem value="comfortable" id="r2" />
|
|
652
|
+
<Label htmlFor="r2">Comfortable</Label>
|
|
653
|
+
</div>
|
|
654
|
+
<div className="flex items-center gap-2">
|
|
655
|
+
<RadioGroupItem value="compact" id="r3" />
|
|
656
|
+
<Label htmlFor="r3">Compact</Label>
|
|
657
|
+
</div>
|
|
658
|
+
</RadioGroup>
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### Select
|
|
662
|
+
|
|
663
|
+
Displays a list of options for the user to pick from, triggered by a button.
|
|
664
|
+
|
|
665
|
+
```tsx
|
|
666
|
+
<Select>
|
|
667
|
+
<SelectTrigger className="w-48">
|
|
668
|
+
<SelectValue placeholder="Select a fruit" />
|
|
669
|
+
</SelectTrigger>
|
|
670
|
+
<SelectContent>
|
|
671
|
+
<SelectItem value="apple">Apple</SelectItem>
|
|
672
|
+
<SelectItem value="banana">Banana</SelectItem>
|
|
673
|
+
<SelectItem value="blueberry">Blueberry</SelectItem>
|
|
674
|
+
<SelectItem value="grapes">Grapes</SelectItem>
|
|
675
|
+
</SelectContent>
|
|
676
|
+
</Select>
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
### Separator
|
|
680
|
+
|
|
681
|
+
Visually or semantically divides content, either horizontally or vertically.
|
|
682
|
+
|
|
683
|
+
```tsx
|
|
684
|
+
<div className="w-full max-w-sm">
|
|
685
|
+
<div className="space-y-1">
|
|
686
|
+
<h4 className="text-sm font-medium leading-none">Radix Primitives</h4>
|
|
687
|
+
<p className="text-sm text-muted-foreground">
|
|
688
|
+
An open-source UI component library.
|
|
689
|
+
</p>
|
|
690
|
+
</div>
|
|
691
|
+
<Separator className="my-4" />
|
|
692
|
+
<p className="text-sm text-muted-foreground">Built with care.</p>
|
|
693
|
+
</div>
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
### Sheet
|
|
697
|
+
|
|
698
|
+
A panel that slides in from an edge of the screen to show supplementary content or actions without leaving the current page.
|
|
699
|
+
|
|
700
|
+
```tsx
|
|
701
|
+
<Sheet>
|
|
702
|
+
<SheetTrigger asChild>
|
|
703
|
+
<Button variant="outline">Open sheet</Button>
|
|
704
|
+
</SheetTrigger>
|
|
705
|
+
<SheetContent>
|
|
706
|
+
<SheetHeader>
|
|
707
|
+
<SheetTitle>Edit profile</SheetTitle>
|
|
708
|
+
<SheetDescription>
|
|
709
|
+
Make changes to your profile here. Click save when you're done.
|
|
710
|
+
</SheetDescription>
|
|
711
|
+
</SheetHeader>
|
|
712
|
+
<SheetFooter>
|
|
713
|
+
<SheetClose asChild>
|
|
714
|
+
<Button>Save changes</Button>
|
|
715
|
+
</SheetClose>
|
|
716
|
+
<SheetClose asChild>
|
|
717
|
+
<Button variant="outline">Cancel</Button>
|
|
718
|
+
</SheetClose>
|
|
719
|
+
</SheetFooter>
|
|
720
|
+
</SheetContent>
|
|
721
|
+
</Sheet>
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
### Slider
|
|
725
|
+
|
|
726
|
+
Lets users select a value or range from a continuous track by dragging one or more thumbs.
|
|
727
|
+
|
|
728
|
+
```tsx
|
|
729
|
+
<Slider defaultValue={[50]} max={100} step={1} className="w-72" />
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
### Sonner
|
|
733
|
+
|
|
734
|
+
An opinionated toast notification system for surfacing brief, non-blocking feedback.
|
|
735
|
+
|
|
736
|
+
```tsx
|
|
737
|
+
import { toast } from "sonner"
|
|
738
|
+
import { Toaster } from "@/components/ui/sonner"
|
|
739
|
+
import { Button } from "@/components/ui/button"
|
|
740
|
+
|
|
741
|
+
// Render <Toaster /> once near your app root.
|
|
742
|
+
<Toaster />
|
|
743
|
+
|
|
744
|
+
<Button
|
|
745
|
+
variant="outline"
|
|
746
|
+
onClick={() => toast("Your changes have been saved")}
|
|
747
|
+
>
|
|
748
|
+
Show toast
|
|
749
|
+
</Button>
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
### Spinner
|
|
753
|
+
|
|
754
|
+
An animated loading indicator that communicates that content or an action is in progress.
|
|
755
|
+
|
|
756
|
+
```tsx
|
|
757
|
+
<Spinner />
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
### Stepper
|
|
761
|
+
|
|
762
|
+
A composable stepper (from Origin UI) for multi-step flows — horizontal or vertical, with numbered indicators, titles, descriptions, and an active/completed state.
|
|
763
|
+
|
|
764
|
+
```tsx
|
|
765
|
+
<Stepper defaultValue={2}>
|
|
766
|
+
{steps.map(({ step, title, description }) => (
|
|
767
|
+
<StepperItem key={step} step={step} className="relative flex-1 flex-col!">
|
|
768
|
+
<StepperTrigger className="flex-col gap-3 rounded">
|
|
769
|
+
<StepperIndicator />
|
|
770
|
+
<div className="space-y-0.5 px-2">
|
|
771
|
+
<StepperTitle>{title}</StepperTitle>
|
|
772
|
+
<StepperDescription className="max-sm:hidden">{description}</StepperDescription>
|
|
773
|
+
</div>
|
|
774
|
+
</StepperTrigger>
|
|
775
|
+
{step < steps.length && (
|
|
776
|
+
<StepperSeparator className="-order-1 absolute inset-x-0 top-3 left-[calc(50%+0.75rem+0.125rem)] m-0 -translate-y-1/2 group-data-[orientation=horizontal]/stepper:w-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=horizontal]/stepper:flex-none" />
|
|
777
|
+
)}
|
|
778
|
+
</StepperItem>
|
|
779
|
+
))}
|
|
780
|
+
</Stepper>
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
### Switch
|
|
784
|
+
|
|
785
|
+
A toggle control that lets the user switch a single setting on or off, applying the change immediately.
|
|
786
|
+
|
|
787
|
+
```tsx
|
|
788
|
+
<div className="flex items-center gap-2">
|
|
789
|
+
<Switch id="airplane" defaultChecked />
|
|
790
|
+
<Label htmlFor="airplane">Airplane mode</Label>
|
|
791
|
+
</div>
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
### Table
|
|
795
|
+
|
|
796
|
+
Displays tabular data in rows and columns, composed from semantic header, body, footer, and caption parts.
|
|
797
|
+
|
|
798
|
+
```tsx
|
|
799
|
+
<Table>
|
|
800
|
+
<TableHeader>
|
|
801
|
+
<TableRow>
|
|
802
|
+
<TableHead>Name</TableHead>
|
|
803
|
+
<TableHead>Role</TableHead>
|
|
804
|
+
<TableHead className="text-right">Status</TableHead>
|
|
805
|
+
</TableRow>
|
|
806
|
+
</TableHeader>
|
|
807
|
+
<TableBody>
|
|
808
|
+
<TableRow>
|
|
809
|
+
<TableCell className="font-medium">Ada Lovelace</TableCell>
|
|
810
|
+
<TableCell>Engineer</TableCell>
|
|
811
|
+
<TableCell className="text-right">Active</TableCell>
|
|
812
|
+
</TableRow>
|
|
813
|
+
<TableRow>
|
|
814
|
+
<TableCell className="font-medium">Alan Turing</TableCell>
|
|
815
|
+
<TableCell>Researcher</TableCell>
|
|
816
|
+
<TableCell className="text-right">Active</TableCell>
|
|
817
|
+
</TableRow>
|
|
818
|
+
</TableBody>
|
|
819
|
+
</Table>
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
### Tabs
|
|
823
|
+
|
|
824
|
+
A set of layered sections of content (tab panels) where only one panel is shown at a time.
|
|
825
|
+
|
|
826
|
+
```tsx
|
|
827
|
+
<Tabs defaultValue="account" className="w-[360px]">
|
|
828
|
+
<TabsList>
|
|
829
|
+
<TabsTrigger value="account">Account</TabsTrigger>
|
|
830
|
+
<TabsTrigger value="password">Password</TabsTrigger>
|
|
831
|
+
</TabsList>
|
|
832
|
+
<TabsContent value="account">
|
|
833
|
+
<p className="text-muted-foreground">Make changes to your account here.</p>
|
|
834
|
+
</TabsContent>
|
|
835
|
+
<TabsContent value="password">
|
|
836
|
+
<p className="text-muted-foreground">Change your password here.</p>
|
|
837
|
+
</TabsContent>
|
|
838
|
+
</Tabs>
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
### Textarea
|
|
842
|
+
|
|
843
|
+
A multi-line text input for longer free-form content such as comments, descriptions, or messages.
|
|
844
|
+
|
|
845
|
+
```tsx
|
|
846
|
+
<Textarea placeholder="Type your message here." />
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
### Timeline
|
|
850
|
+
|
|
851
|
+
A composable timeline (from Origin UI) for sequences of events — vertical or horizontal, with active/completed state, icon or avatar indicators, and an alternating layout.
|
|
852
|
+
|
|
853
|
+
```tsx
|
|
854
|
+
<Timeline defaultValue={3}>
|
|
855
|
+
{items.map((item) => (
|
|
856
|
+
<TimelineItem key={item.id} step={item.id}
|
|
857
|
+
className="group-data-[orientation=vertical]/timeline:ms-10">
|
|
858
|
+
<TimelineHeader>
|
|
859
|
+
<TimelineSeparator className="group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5" />
|
|
860
|
+
<TimelineTitle className="mt-0.5">{item.title}</TimelineTitle>
|
|
861
|
+
<TimelineIndicator className="flex size-6 items-center justify-center border-none bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground group-data-[orientation=vertical]/timeline:-left-7">
|
|
862
|
+
<item.icon size={14} />
|
|
863
|
+
</TimelineIndicator>
|
|
864
|
+
</TimelineHeader>
|
|
865
|
+
<TimelineContent>
|
|
866
|
+
{item.description}
|
|
867
|
+
<TimelineDate className="mt-2 mb-0">{item.date}</TimelineDate>
|
|
868
|
+
</TimelineContent>
|
|
869
|
+
</TimelineItem>
|
|
870
|
+
))}
|
|
871
|
+
</Timeline>
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
### Toggle
|
|
875
|
+
|
|
876
|
+
A two-state button that can be either on or off, toggling the active state when pressed.
|
|
877
|
+
|
|
878
|
+
```tsx
|
|
879
|
+
<Toggle aria-label="Toggle bold">
|
|
880
|
+
<Bold />
|
|
881
|
+
</Toggle>
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
### Toggle Group
|
|
885
|
+
|
|
886
|
+
A set of two-state buttons that can be toggled on or off, supporting single or multiple selection.
|
|
887
|
+
|
|
888
|
+
```tsx
|
|
889
|
+
<ToggleGroup type="single" defaultValue="center" variant="outline">
|
|
890
|
+
<ToggleGroupItem value="left" aria-label="Align left">
|
|
891
|
+
Left
|
|
892
|
+
</ToggleGroupItem>
|
|
893
|
+
<ToggleGroupItem value="center" aria-label="Align center">
|
|
894
|
+
Center
|
|
895
|
+
</ToggleGroupItem>
|
|
896
|
+
<ToggleGroupItem value="right" aria-label="Align right">
|
|
897
|
+
Right
|
|
898
|
+
</ToggleGroupItem>
|
|
899
|
+
</ToggleGroup>
|
|
900
|
+
```
|
|
901
|
+
|
|
902
|
+
### Tooltip
|
|
903
|
+
|
|
904
|
+
Displays a brief, contextual label in a popup when the user hovers or focuses an element.
|
|
905
|
+
|
|
906
|
+
```tsx
|
|
907
|
+
<TooltipProvider>
|
|
908
|
+
<Tooltip>
|
|
909
|
+
<TooltipTrigger asChild>
|
|
910
|
+
<Button variant="outline">Hover me</Button>
|
|
911
|
+
</TooltipTrigger>
|
|
912
|
+
<TooltipContent>
|
|
913
|
+
<p>Add to library</p>
|
|
914
|
+
</TooltipContent>
|
|
915
|
+
</Tooltip>
|
|
916
|
+
</TooltipProvider>
|
|
917
|
+
```
|
|
918
|
+
|
|
919
|
+
<!-- COMPONENTS:END -->
|