shapes-ui 0.4.1 → 0.5.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/.github/ISSUE_TEMPLATE/bug_report.yml +47 -0
- package/.github/ISSUE_TEMPLATE/config.yml +1 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +31 -0
- package/.github/pull_request_template.md +14 -0
- package/.github/workflows/pr-preview.yml +68 -0
- package/.github/workflows/release.yml +8 -0
- package/.idea/compiler.xml +6 -0
- package/.idea/copilot.data.migration.ask2agent.xml +6 -0
- package/.idea/vcs.xml +6 -0
- package/CHANGELOG.md +31 -0
- package/CODE_OF_CONDUCT.md +41 -0
- package/CONTRIBUTING.md +52 -0
- package/README.md +5 -0
- package/SECURITY.md +0 -0
- package/content/components/field.mdx +2 -2
- package/content/components/fieldset.mdx +1 -1
- package/content/components/menubar.mdx +4 -2
- package/content/components/meter.mdx +13 -1
- package/content/components/navigation-menu.mdx +6 -0
- package/content/components/number-field.mdx +24 -0
- package/content/components/popover.mdx +20 -0
- package/content/components/preview-card.mdx +11 -0
- package/content/components/progress.mdx +2 -0
- package/content/components/radio.mdx +20 -0
- package/content/components/select.mdx +30 -0
- package/content/components/slider.mdx +48 -0
- package/content/components/switch.mdx +26 -0
- package/content/components/tabs.mdx +32 -0
- package/content/components/toast.mdx +60 -0
- package/content/components/toggle.mdx +34 -2
- package/content/components/toolbar.mdx +26 -0
- package/content/components/tooltip.mdx +25 -0
- package/content-collections.ts +1 -1
- package/examples/__index.tsx +231 -0
- package/examples/checkbox-demo.tsx +1 -1
- package/examples/checkbox-form.tsx +3 -3
- package/examples/field-custom-control.tsx +33 -9
- package/examples/form-demo.tsx +5 -10
- package/examples/menu-advanced.tsx +1 -3
- package/examples/menu-align.tsx +19 -16
- package/examples/menu-checkbox.tsx +2 -3
- package/examples/menu-demo.tsx +1 -3
- package/examples/menu-group.tsx +1 -3
- package/examples/menu-radio.tsx +1 -3
- package/examples/menu-submenu.tsx +2 -3
- package/examples/menubar-advanced.tsx +91 -0
- package/examples/meter-demo.tsx +8 -21
- package/examples/meter-flip.tsx +13 -0
- package/examples/meter-no-label.tsx +12 -0
- package/examples/meter-no-value.tsx +12 -0
- package/examples/navigation-menu-demo.tsx +113 -1
- package/examples/number-field-buttons-end.tsx +20 -0
- package/examples/number-field-demo.tsx +17 -1
- package/examples/number-field-scrub.tsx +38 -0
- package/examples/popover-demo.tsx +18 -1
- package/examples/popover-form.tsx +46 -0
- package/examples/popover-positions.tsx +54 -0
- package/examples/preview-card-demo.tsx +26 -1
- package/examples/preview-card-links.tsx +38 -0
- package/examples/progress-demo.tsx +33 -1
- package/examples/radio-card.tsx +28 -0
- package/examples/radio-demo.tsx +19 -1
- package/examples/radio-description.tsx +26 -0
- package/examples/radio-orientation.tsx +21 -0
- package/examples/select-alignment.tsx +51 -0
- package/examples/select-demo.tsx +36 -1
- package/examples/select-disabled.tsx +38 -0
- package/examples/select-groups.tsx +54 -0
- package/examples/select-invalid.tsx +41 -0
- package/examples/select-scrollable.tsx +112 -0
- package/examples/slider-controlled.tsx +28 -0
- package/examples/slider-demo.tsx +3 -1
- package/examples/slider-disabled.tsx +7 -0
- package/examples/slider-edge.tsx +13 -0
- package/examples/slider-multiple.tsx +7 -0
- package/examples/slider-range.tsx +5 -0
- package/examples/slider-vertical.tsx +10 -0
- package/examples/switch-demo.tsx +19 -1
- package/examples/switch-disabled.tsx +20 -0
- package/examples/switch-sizes.tsx +24 -0
- package/examples/switch-with-label.tsx +16 -0
- package/examples/tabs-demo.tsx +14 -1
- package/examples/tabs-disabled.tsx +21 -0
- package/examples/tabs-line.tsx +18 -0
- package/examples/tabs-vertical.tsx +13 -0
- package/examples/toast-action.tsx +39 -0
- package/examples/toast-anchored.tsx +36 -0
- package/examples/toast-demo.tsx +27 -1
- package/examples/toast-positions.tsx +54 -0
- package/examples/toast-promise.tsx +51 -0
- package/examples/toast-stacked.tsx +30 -0
- package/examples/toast-timeout.tsx +43 -0
- package/examples/toast-update.tsx +38 -0
- package/examples/toast-variants.tsx +54 -0
- package/examples/toggle-controlled.tsx +20 -0
- package/examples/toggle-demo.tsx +7 -51
- package/examples/toggle-group-demo.tsx +19 -0
- package/examples/toggle-group-multiple.tsx +19 -0
- package/examples/toggle-icon-fill.tsx +12 -0
- package/examples/toolbar-demo.tsx +45 -21
- package/examples/toolbar-input-link.tsx +35 -0
- package/examples/toolbar-menu.tsx +53 -0
- package/examples/tooltip-demo.tsx +48 -0
- package/examples/tooltip-positions.tsx +60 -0
- package/package.json +8 -8
- package/public/r/drawer.json +1 -1
- package/public/r/field.json +1 -1
- package/public/r/menubar.json +1 -1
- package/public/r/meter.json +1 -1
- package/public/r/navigation-menu.json +1 -1
- package/public/r/number-field.json +4 -2
- package/public/r/popover.json +1 -1
- package/public/r/preview-card.json +1 -1
- package/public/r/progress.json +1 -1
- package/public/r/radio.json +1 -1
- package/public/r/select.json +1 -1
- package/public/r/slider.json +1 -1
- package/public/r/switch.json +1 -1
- package/public/r/tabs.json +1 -1
- package/public/r/toast.json +2 -1
- package/public/r/toggle.json +1 -1
- package/public/r/toolbar.json +1 -1
- package/public/r/tooltip.json +15 -0
- package/src/components/docs/layout/header.tsx +4 -14
- package/src/components/docs/layout/mobile-menu.tsx +27 -78
- package/src/components/docs/layout/nav-list.tsx +27 -21
- package/src/components/docs/layout/split-layout.tsx +6 -3
- package/src/components/ui/badge.tsx +1 -1
- package/src/components/ui/checkbox.tsx +1 -1
- package/src/components/ui/drawer.tsx +1 -1
- package/src/components/ui/field.tsx +9 -28
- package/src/components/ui/form.tsx +1 -1
- package/src/components/ui/menubar.tsx +52 -18
- package/src/components/ui/meter.tsx +12 -24
- package/src/components/ui/navigation-menu.tsx +121 -38
- package/src/components/ui/number-field.tsx +42 -46
- package/src/components/ui/popover.tsx +7 -2
- package/src/components/ui/preview-card.tsx +4 -2
- package/src/components/ui/progress.tsx +7 -18
- package/src/components/ui/radio.tsx +32 -19
- package/src/components/ui/select.tsx +6 -6
- package/src/components/ui/slider.tsx +8 -5
- package/src/components/ui/switch.tsx +13 -17
- package/src/components/ui/tabs.tsx +23 -10
- package/src/components/ui/toast.tsx +190 -29
- package/src/components/ui/toggle.tsx +1 -1
- package/src/components/ui/toolbar.tsx +17 -4
- package/src/components/ui/tooltip.tsx +54 -0
- package/src/routes/__root.tsx +3 -5
package/examples/menu-align.tsx
CHANGED
|
@@ -9,22 +9,25 @@ export default function MenuDemo() {
|
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
11
|
<Menu>
|
|
12
|
-
<MenuTrigger
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
12
|
+
<MenuTrigger
|
|
13
|
+
nativeButton={false}
|
|
14
|
+
render={
|
|
15
|
+
<ButtonGroup>
|
|
16
|
+
<Button variant="outline" onClick={() => setSide("bottom")}>
|
|
17
|
+
Bottom
|
|
18
|
+
</Button>
|
|
19
|
+
<Button variant="outline" onClick={() => setSide("top")}>
|
|
20
|
+
Top
|
|
21
|
+
</Button>
|
|
22
|
+
<Button variant="outline" onClick={() => setSide("left")}>
|
|
23
|
+
Left
|
|
24
|
+
</Button>
|
|
25
|
+
<Button variant="outline" onClick={() => setSide("right")}>
|
|
26
|
+
Right
|
|
27
|
+
</Button>
|
|
28
|
+
</ButtonGroup>
|
|
29
|
+
}
|
|
30
|
+
></MenuTrigger>
|
|
28
31
|
<MenuPopup side={side}>
|
|
29
32
|
<MenuItem>{side.charAt(0).toUpperCase() + side.slice(1)}</MenuItem>
|
|
30
33
|
</MenuPopup>
|
|
@@ -9,9 +9,8 @@ export default function MenuCheckboxDemo() {
|
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
11
|
<Menu>
|
|
12
|
-
<MenuTrigger>
|
|
13
|
-
|
|
14
|
-
</MenuTrigger>
|
|
12
|
+
<MenuTrigger render={<Button variant="outline">Checkbox items</Button>} />
|
|
13
|
+
|
|
15
14
|
<MenuPopup>
|
|
16
15
|
<MenuCheckboxItem
|
|
17
16
|
checked={showHidden}
|
package/examples/menu-demo.tsx
CHANGED
|
@@ -16,9 +16,7 @@ import {
|
|
|
16
16
|
export default function MenuDemo() {
|
|
17
17
|
return (
|
|
18
18
|
<Menu>
|
|
19
|
-
<MenuTrigger>
|
|
20
|
-
<Button variant="outline">Open Menu</Button>
|
|
21
|
-
</MenuTrigger>
|
|
19
|
+
<MenuTrigger render={<Button variant="outline">Open Menu</Button>} />
|
|
22
20
|
<MenuPopup>
|
|
23
21
|
<div className="flex items-center justify-between gap-2 p-3">
|
|
24
22
|
<Avatar size="sm">
|
package/examples/menu-group.tsx
CHANGED
|
@@ -14,9 +14,7 @@ import {
|
|
|
14
14
|
export default function MenuGroupDemo() {
|
|
15
15
|
return (
|
|
16
16
|
<Menu>
|
|
17
|
-
<MenuTrigger>
|
|
18
|
-
<Button variant="outline">Group menu</Button>
|
|
19
|
-
</MenuTrigger>
|
|
17
|
+
<MenuTrigger render={<Button variant="outline">Group menu</Button>} />
|
|
20
18
|
<MenuPopup>
|
|
21
19
|
<MenuGroup>
|
|
22
20
|
<MenuLabel>Account</MenuLabel>
|
package/examples/menu-radio.tsx
CHANGED
|
@@ -8,9 +8,7 @@ export default function MenuRadioDemo() {
|
|
|
8
8
|
|
|
9
9
|
return (
|
|
10
10
|
<Menu>
|
|
11
|
-
<MenuTrigger>
|
|
12
|
-
<Button variant="outline">Radio items</Button>
|
|
13
|
-
</MenuTrigger>
|
|
11
|
+
<MenuTrigger render={<Button variant="outline">Radio items</Button>} />
|
|
14
12
|
<MenuPopup>
|
|
15
13
|
<MenuRadioGroup value={view} onValueChange={(v) => setView(v as any)}>
|
|
16
14
|
<MenuRadioItem value="list">List view</MenuRadioItem>
|
|
@@ -14,9 +14,8 @@ import {
|
|
|
14
14
|
export default function MenuSubmenuDemo() {
|
|
15
15
|
return (
|
|
16
16
|
<Menu>
|
|
17
|
-
<MenuTrigger>
|
|
18
|
-
|
|
19
|
-
</MenuTrigger>
|
|
17
|
+
<MenuTrigger render={<Button variant="outline">Submenu</Button>} />
|
|
18
|
+
|
|
20
19
|
<MenuPopup>
|
|
21
20
|
<MenuItem>New file</MenuItem>
|
|
22
21
|
<MenuItem>Open…</MenuItem>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { FolderIcon, FileTextIcon, FileCode2Icon } from "lucide-react";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
Menubar,
|
|
6
|
+
Menu,
|
|
7
|
+
MenuTrigger,
|
|
8
|
+
MenuPopup,
|
|
9
|
+
MenuItem,
|
|
10
|
+
MenuSeparator,
|
|
11
|
+
MenuCheckboxItem,
|
|
12
|
+
MenuShortcut,
|
|
13
|
+
MenuSub,
|
|
14
|
+
MenuSubPopup,
|
|
15
|
+
MenuSubTrigger,
|
|
16
|
+
} from "@/components/ui/menubar";
|
|
17
|
+
|
|
18
|
+
export default function MenubarDemo() {
|
|
19
|
+
const [autosave, setAutosave] = useState(true);
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Menubar>
|
|
23
|
+
<Menu>
|
|
24
|
+
<MenuTrigger>File</MenuTrigger>
|
|
25
|
+
<MenuPopup>
|
|
26
|
+
<MenuItem>
|
|
27
|
+
New <MenuShortcut>⌘N</MenuShortcut>
|
|
28
|
+
</MenuItem>
|
|
29
|
+
<MenuItem>
|
|
30
|
+
Open <MenuShortcut>⌘O</MenuShortcut>{" "}
|
|
31
|
+
</MenuItem>
|
|
32
|
+
<MenuSeparator />
|
|
33
|
+
<MenuItem>
|
|
34
|
+
Exit <MenuShortcut>⌘Q</MenuShortcut>
|
|
35
|
+
</MenuItem>
|
|
36
|
+
</MenuPopup>
|
|
37
|
+
</Menu>
|
|
38
|
+
<Menu>
|
|
39
|
+
<MenuTrigger>Edit</MenuTrigger>
|
|
40
|
+
<MenuPopup>
|
|
41
|
+
<MenuItem>
|
|
42
|
+
Undo <MenuShortcut>⌘N</MenuShortcut>
|
|
43
|
+
</MenuItem>
|
|
44
|
+
<MenuItem>
|
|
45
|
+
Redo <MenuShortcut>⇧⌘R</MenuShortcut>
|
|
46
|
+
</MenuItem>
|
|
47
|
+
<MenuSeparator />
|
|
48
|
+
<MenuItem>
|
|
49
|
+
Cut <MenuShortcut>⌘X</MenuShortcut>
|
|
50
|
+
</MenuItem>
|
|
51
|
+
<MenuItem>
|
|
52
|
+
Copy <MenuShortcut>⌘C</MenuShortcut>
|
|
53
|
+
</MenuItem>
|
|
54
|
+
<MenuItem>
|
|
55
|
+
Paste <MenuShortcut>⌘V</MenuShortcut>
|
|
56
|
+
</MenuItem>
|
|
57
|
+
<MenuSeparator />
|
|
58
|
+
<MenuSub>
|
|
59
|
+
<MenuSubTrigger>
|
|
60
|
+
<FolderIcon />
|
|
61
|
+
Open recent
|
|
62
|
+
</MenuSubTrigger>
|
|
63
|
+
<MenuSubPopup>
|
|
64
|
+
<MenuItem>
|
|
65
|
+
<FileCode2Icon />
|
|
66
|
+
button.tsx
|
|
67
|
+
</MenuItem>
|
|
68
|
+
<MenuItem>
|
|
69
|
+
<FileCode2Icon />
|
|
70
|
+
build-script.ts
|
|
71
|
+
</MenuItem>
|
|
72
|
+
<MenuItem>
|
|
73
|
+
<FileTextIcon />
|
|
74
|
+
feature-spec.md
|
|
75
|
+
</MenuItem>
|
|
76
|
+
</MenuSubPopup>
|
|
77
|
+
</MenuSub>
|
|
78
|
+
</MenuPopup>
|
|
79
|
+
</Menu>
|
|
80
|
+
<Menu>
|
|
81
|
+
<MenuTrigger>View</MenuTrigger>
|
|
82
|
+
<MenuPopup>
|
|
83
|
+
<MenuCheckboxItem checked={autosave} onCheckedChange={setAutosave}>
|
|
84
|
+
Auto Save
|
|
85
|
+
</MenuCheckboxItem>
|
|
86
|
+
<MenuItem>Full Screen</MenuItem>
|
|
87
|
+
</MenuPopup>
|
|
88
|
+
</Menu>
|
|
89
|
+
</Menubar>
|
|
90
|
+
);
|
|
91
|
+
}
|
package/examples/meter-demo.tsx
CHANGED
|
@@ -1,26 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { Meter } from "@/components/ui/meter";
|
|
1
|
+
import { Meter, MeterLabel, MeterValue, MeterIndicator, MeterTrack } from "@/components/ui/meter";
|
|
4
2
|
|
|
5
3
|
export default function MeterDemo() {
|
|
6
|
-
const [value, setValue] = useState(65);
|
|
7
|
-
|
|
8
4
|
return (
|
|
9
|
-
<
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
value={value}
|
|
17
|
-
onChange={(e) => setValue(Number(e.target.value))}
|
|
18
|
-
className="mt-4 w-80"
|
|
19
|
-
/>
|
|
20
|
-
</div>
|
|
21
|
-
<div>
|
|
22
|
-
<Meter value={75} label="Memory" showLabel showValue />
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
5
|
+
<Meter className={"w-72"} value={54}>
|
|
6
|
+
<MeterLabel>Progress</MeterLabel>
|
|
7
|
+
<MeterValue />
|
|
8
|
+
<MeterTrack>
|
|
9
|
+
<MeterIndicator />
|
|
10
|
+
</MeterTrack>
|
|
11
|
+
</Meter>
|
|
25
12
|
);
|
|
26
13
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Meter, MeterIndicator, MeterLabel, MeterTrack, MeterValue } from "@/components/ui/meter";
|
|
2
|
+
|
|
3
|
+
export default function MeterIndicatorDemo() {
|
|
4
|
+
return (
|
|
5
|
+
<Meter className={"w-72"} value={32}>
|
|
6
|
+
<MeterTrack>
|
|
7
|
+
<MeterIndicator />
|
|
8
|
+
</MeterTrack>
|
|
9
|
+
<MeterLabel>Progress</MeterLabel>
|
|
10
|
+
<MeterValue />
|
|
11
|
+
</Meter>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Meter, MeterIndicator, MeterTrack, MeterValue } from "@/components/ui/meter";
|
|
2
|
+
|
|
3
|
+
export default function MeterNoLabelDemo() {
|
|
4
|
+
return (
|
|
5
|
+
<Meter className={"w-72"} value={54}>
|
|
6
|
+
<MeterValue className={"col-span-2 text-left"} />
|
|
7
|
+
<MeterTrack>
|
|
8
|
+
<MeterIndicator />
|
|
9
|
+
</MeterTrack>
|
|
10
|
+
</Meter>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Meter, MeterIndicator, MeterLabel, MeterTrack } from "@/components/ui/meter";
|
|
2
|
+
|
|
3
|
+
export default function MeterNoValueDemo() {
|
|
4
|
+
return (
|
|
5
|
+
<Meter className={"w-72"} value={54}>
|
|
6
|
+
<MeterLabel>File transfer</MeterLabel>
|
|
7
|
+
<MeterTrack>
|
|
8
|
+
<MeterIndicator />
|
|
9
|
+
</MeterTrack>
|
|
10
|
+
</Meter>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
@@ -1,3 +1,115 @@
|
|
|
1
|
+
import {
|
|
2
|
+
NavigationMenu,
|
|
3
|
+
NavigationMenuTrigger,
|
|
4
|
+
NavigationMenuItem,
|
|
5
|
+
NavigationMenuContent,
|
|
6
|
+
NavigationMenuLink,
|
|
7
|
+
NavigationMenuPopup,
|
|
8
|
+
NavigationMenuList,
|
|
9
|
+
} from "@/components/ui/navigation-menu";
|
|
10
|
+
|
|
1
11
|
export default function NavigationMenuDemo() {
|
|
2
|
-
return
|
|
12
|
+
return (
|
|
13
|
+
<div>
|
|
14
|
+
<NavigationMenu>
|
|
15
|
+
<NavigationMenuList>
|
|
16
|
+
<NavigationMenuItem>
|
|
17
|
+
<NavigationMenuTrigger>Overview</NavigationMenuTrigger>
|
|
18
|
+
<NavigationMenuContent>
|
|
19
|
+
<ul className="grid max-w-md grid-cols-2 gap-4 p-2">
|
|
20
|
+
{overviewLinks.map((item) => (
|
|
21
|
+
<li key={item.href}>
|
|
22
|
+
<NavigationMenuLink href={item.href}>
|
|
23
|
+
<div className="flex flex-col">
|
|
24
|
+
<h3 className="text-sm leading-5 font-medium">{item.title}</h3>
|
|
25
|
+
<p className="text-xs leading-tight text-muted-foreground">
|
|
26
|
+
{item.description}
|
|
27
|
+
</p>
|
|
28
|
+
</div>
|
|
29
|
+
</NavigationMenuLink>
|
|
30
|
+
</li>
|
|
31
|
+
))}
|
|
32
|
+
</ul>
|
|
33
|
+
</NavigationMenuContent>
|
|
34
|
+
</NavigationMenuItem>
|
|
35
|
+
|
|
36
|
+
<NavigationMenuItem>
|
|
37
|
+
<NavigationMenuTrigger>Handbook</NavigationMenuTrigger>
|
|
38
|
+
<NavigationMenuContent>
|
|
39
|
+
<ul className="grid max-w-md grid-cols-2 gap-2 p-2">
|
|
40
|
+
{handbookLinks.map((item) => (
|
|
41
|
+
<li key={item.href}>
|
|
42
|
+
<NavigationMenuLink href={item.href}>
|
|
43
|
+
<div className="flex flex-col">
|
|
44
|
+
<h3 className="text-sm leading-5 font-medium">{item.title}</h3>
|
|
45
|
+
<p className="text-xs leading-tight text-muted-foreground">
|
|
46
|
+
{item.description}
|
|
47
|
+
</p>
|
|
48
|
+
</div>
|
|
49
|
+
</NavigationMenuLink>
|
|
50
|
+
</li>
|
|
51
|
+
))}
|
|
52
|
+
</ul>
|
|
53
|
+
</NavigationMenuContent>
|
|
54
|
+
</NavigationMenuItem>
|
|
55
|
+
|
|
56
|
+
<NavigationMenuItem>
|
|
57
|
+
<NavigationMenuLink
|
|
58
|
+
className={
|
|
59
|
+
"flex items-center gap-1 rounded-lg px-3 py-1.5 text-sm font-medium transition-all duration-50 hover:bg-accent/60 hover:text-accent-foreground focus:bg-accent/60"
|
|
60
|
+
}
|
|
61
|
+
>
|
|
62
|
+
About
|
|
63
|
+
</NavigationMenuLink>
|
|
64
|
+
</NavigationMenuItem>
|
|
65
|
+
</NavigationMenuList>
|
|
66
|
+
|
|
67
|
+
<NavigationMenuPopup />
|
|
68
|
+
</NavigationMenu>
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
3
71
|
}
|
|
72
|
+
|
|
73
|
+
const overviewLinks = [
|
|
74
|
+
{
|
|
75
|
+
href: "/react/overview/quick-start",
|
|
76
|
+
title: "Quick Start",
|
|
77
|
+
description: "Install and assemble your first component.",
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
href: "/react/overview/accessibility",
|
|
81
|
+
title: "Accessibility",
|
|
82
|
+
description: "Learn how we build accessible components.",
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
href: "/react/overview/releases",
|
|
86
|
+
title: "Releases",
|
|
87
|
+
description: "See what’s new in the latest Base UI versions.",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
href: "/react/overview/about",
|
|
91
|
+
title: "About",
|
|
92
|
+
description: "Learn more about Base UI and our mission.",
|
|
93
|
+
},
|
|
94
|
+
] as const;
|
|
95
|
+
|
|
96
|
+
const handbookLinks = [
|
|
97
|
+
{
|
|
98
|
+
href: "/react/handbook/styling",
|
|
99
|
+
title: "Styling",
|
|
100
|
+
description:
|
|
101
|
+
"Base UI components can be styled with plain CSS, Tailwind CSS, CSS-in-JS, or CSS Modules.",
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
href: "/react/handbook/animation",
|
|
105
|
+
title: "Animation",
|
|
106
|
+
description:
|
|
107
|
+
"Base UI components can be animated with CSS transitions, CSS animations, or JavaScript libraries.",
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
href: "/react/handbook/composition",
|
|
111
|
+
title: "Composition",
|
|
112
|
+
description:
|
|
113
|
+
"Base UI components can be replaced and composed with your own existing components.",
|
|
114
|
+
},
|
|
115
|
+
] as const;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
NumberField,
|
|
3
|
+
NumberFieldGroup,
|
|
4
|
+
NumberFieldInput,
|
|
5
|
+
NumberFieldDecrement,
|
|
6
|
+
NumberFieldIncrement,
|
|
7
|
+
} from "@/components/ui/number-field";
|
|
8
|
+
|
|
9
|
+
export default function NumberFieldButtonsEndExample() {
|
|
10
|
+
return (
|
|
11
|
+
<NumberField defaultValue={8} className="w-40">
|
|
12
|
+
<NumberFieldGroup>
|
|
13
|
+
<NumberFieldInput />
|
|
14
|
+
{/* align props aren't required — data-align/read-order handled by props in component */}
|
|
15
|
+
<NumberFieldDecrement align="end" />
|
|
16
|
+
<NumberFieldIncrement align="end" />
|
|
17
|
+
</NumberFieldGroup>
|
|
18
|
+
</NumberField>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
NumberField,
|
|
3
|
+
NumberFieldDecrement,
|
|
4
|
+
NumberFieldGroup,
|
|
5
|
+
NumberFieldIncrement,
|
|
6
|
+
NumberFieldInput,
|
|
7
|
+
} from "@/components/ui/number-field";
|
|
8
|
+
|
|
1
9
|
export default function NumberFieldDemo() {
|
|
2
|
-
return
|
|
10
|
+
return (
|
|
11
|
+
<NumberField defaultValue={21}>
|
|
12
|
+
<NumberFieldGroup>
|
|
13
|
+
<NumberFieldDecrement data-align="start" />
|
|
14
|
+
<NumberFieldInput />
|
|
15
|
+
<NumberFieldIncrement data-align="end" />
|
|
16
|
+
</NumberFieldGroup>
|
|
17
|
+
</NumberField>
|
|
18
|
+
);
|
|
3
19
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ChevronsLeftRightEllipsis } from "lucide-react";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
NumberField,
|
|
6
|
+
NumberFieldGroup,
|
|
7
|
+
NumberFieldInput,
|
|
8
|
+
NumberFieldIncrement,
|
|
9
|
+
NumberFieldDecrement,
|
|
10
|
+
NumberFieldScrubArea,
|
|
11
|
+
NumberFieldScrubAreaCursor,
|
|
12
|
+
} from "@/components/ui/number-field";
|
|
13
|
+
|
|
14
|
+
export default function NumberFieldScrubExample() {
|
|
15
|
+
const id = React.useId();
|
|
16
|
+
const [value, setValue] = React.useState<number | null>(120);
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="flex flex-col gap-2">
|
|
20
|
+
<NumberField id={id} value={value} onValueChange={(v) => setValue(v)}>
|
|
21
|
+
<NumberFieldScrubArea>
|
|
22
|
+
<label htmlFor={id} className="text-sm font-medium">
|
|
23
|
+
Amount
|
|
24
|
+
</label>
|
|
25
|
+
<NumberFieldScrubAreaCursor>
|
|
26
|
+
<ChevronsLeftRightEllipsis className="size-4" />
|
|
27
|
+
</NumberFieldScrubAreaCursor>
|
|
28
|
+
|
|
29
|
+
<NumberFieldGroup>
|
|
30
|
+
<NumberFieldDecrement data-align="start" />
|
|
31
|
+
<NumberFieldInput />
|
|
32
|
+
<NumberFieldIncrement data-align="end" />
|
|
33
|
+
</NumberFieldGroup>
|
|
34
|
+
</NumberFieldScrubArea>
|
|
35
|
+
</NumberField>
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
import { Button } from "@/components/ui/button";
|
|
2
|
+
import {
|
|
3
|
+
Popover,
|
|
4
|
+
PopoverDescription,
|
|
5
|
+
PopoverPopup,
|
|
6
|
+
PopoverTitle,
|
|
7
|
+
PopoverTrigger,
|
|
8
|
+
} from "@/components/ui/popover";
|
|
9
|
+
|
|
1
10
|
export default function PopoverDemo() {
|
|
2
|
-
return
|
|
11
|
+
return (
|
|
12
|
+
<Popover>
|
|
13
|
+
<PopoverTrigger render={<Button variant={"secondary"}>Open popover</Button>} />
|
|
14
|
+
<PopoverPopup>
|
|
15
|
+
<PopoverTitle>Popover component</PopoverTitle>
|
|
16
|
+
<PopoverDescription>This is the popover description content.</PopoverDescription>
|
|
17
|
+
</PopoverPopup>
|
|
18
|
+
</Popover>
|
|
19
|
+
);
|
|
3
20
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Button } from "@/components/ui/button";
|
|
4
|
+
import { Field, FieldLabel, FieldControl } from "@/components/ui/field";
|
|
5
|
+
import {
|
|
6
|
+
Popover,
|
|
7
|
+
PopoverTrigger,
|
|
8
|
+
PopoverPopup,
|
|
9
|
+
PopoverTitle,
|
|
10
|
+
PopoverClose,
|
|
11
|
+
} from "@/components/ui/popover";
|
|
12
|
+
|
|
13
|
+
export default function PopoverFormExample() {
|
|
14
|
+
return (
|
|
15
|
+
<Popover>
|
|
16
|
+
<PopoverTrigger render={<Button>Open Form</Button>} />
|
|
17
|
+
<PopoverPopup>
|
|
18
|
+
<PopoverTitle>User Information</PopoverTitle>
|
|
19
|
+
<div className="space-y-3">
|
|
20
|
+
<Field name="firstName" className="w-full">
|
|
21
|
+
<FieldLabel>First Name</FieldLabel>
|
|
22
|
+
<FieldControl type="text" placeholder="John" />
|
|
23
|
+
</Field>
|
|
24
|
+
<Field name="lastName" className="w-full">
|
|
25
|
+
<FieldLabel>Last Name</FieldLabel>
|
|
26
|
+
<FieldControl type="text" placeholder="Doe" />
|
|
27
|
+
</Field>
|
|
28
|
+
<Field name="email" className="w-full">
|
|
29
|
+
<FieldLabel>Email</FieldLabel>
|
|
30
|
+
<FieldControl type="email" placeholder="john@example.com" />
|
|
31
|
+
</Field>
|
|
32
|
+
<div className="flex justify-end gap-2 pt-2">
|
|
33
|
+
<Button size="sm">Submit</Button>
|
|
34
|
+
<PopoverClose
|
|
35
|
+
render={
|
|
36
|
+
<Button variant="outline" size="sm">
|
|
37
|
+
Cancel
|
|
38
|
+
</Button>
|
|
39
|
+
}
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</PopoverPopup>
|
|
44
|
+
</Popover>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
|
|
5
|
+
import { Button } from "@/components/ui/button";
|
|
6
|
+
import { ButtonGroup } from "@/components/ui/button-group";
|
|
7
|
+
import {
|
|
8
|
+
Popover,
|
|
9
|
+
PopoverTrigger,
|
|
10
|
+
PopoverPopup,
|
|
11
|
+
PopoverTitle,
|
|
12
|
+
PopoverDescription,
|
|
13
|
+
PopoverClose,
|
|
14
|
+
} from "@/components/ui/popover";
|
|
15
|
+
|
|
16
|
+
export default function PopoverPositionsExample() {
|
|
17
|
+
const [activePosition, setActivePosition] = React.useState(positions[0]);
|
|
18
|
+
return (
|
|
19
|
+
<div className="flex flex-wrap gap-4">
|
|
20
|
+
<Popover>
|
|
21
|
+
<ButtonGroup>
|
|
22
|
+
{positions.map((pos) => (
|
|
23
|
+
<PopoverTrigger
|
|
24
|
+
key={pos.side}
|
|
25
|
+
render={<Button variant={"outline"}>{pos.label}</Button>}
|
|
26
|
+
onClick={() => setActivePosition(pos)}
|
|
27
|
+
/>
|
|
28
|
+
))}
|
|
29
|
+
</ButtonGroup>
|
|
30
|
+
<PopoverPopup side={activePosition.side}>
|
|
31
|
+
<PopoverTitle>Position Example</PopoverTitle>
|
|
32
|
+
<PopoverDescription>
|
|
33
|
+
This popover is positioned on the {activePosition.label.toLowerCase()} side.
|
|
34
|
+
</PopoverDescription>
|
|
35
|
+
<PopoverClose
|
|
36
|
+
render={
|
|
37
|
+
<Button variant="ghost" size="sm" className={"ml-auto"}>
|
|
38
|
+
Close
|
|
39
|
+
</Button>
|
|
40
|
+
}
|
|
41
|
+
/>
|
|
42
|
+
</PopoverPopup>
|
|
43
|
+
</Popover>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const positions: Position[] = [
|
|
49
|
+
{ label: "Left", side: "left" },
|
|
50
|
+
{ label: "Center", side: "bottom" },
|
|
51
|
+
{ label: "Right", side: "right" },
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
type Position = { label: string; side: "top" | "right" | "bottom" | "left" };
|
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
import { PreviewCard, PreviewCardPopup, PreviewCardTrigger } from "@/components/ui/preview-card";
|
|
2
|
+
|
|
1
3
|
export default function PreviewCardDemo() {
|
|
2
|
-
return
|
|
4
|
+
return (
|
|
5
|
+
<PreviewCard>
|
|
6
|
+
<p className={' text-sm'}>
|
|
7
|
+
Apple's{" "}
|
|
8
|
+
<PreviewCardTrigger
|
|
9
|
+
target={"_blank"}
|
|
10
|
+
href={"https://developer.apple.com/documentation/TechnologyOverviews/liquid-glass"}
|
|
11
|
+
>
|
|
12
|
+
Liquid Glass
|
|
13
|
+
</PreviewCardTrigger>{" "}
|
|
14
|
+
has been a controversial release.
|
|
15
|
+
</p>
|
|
16
|
+
<PreviewCardPopup className={"flex w-fit flex-col gap-2 items-center justify-center p-3"}>
|
|
17
|
+
<img
|
|
18
|
+
alt={"Liquid Glass UI"}
|
|
19
|
+
className={"w-72 rounded-lg bg-muted object-cover p-2"}
|
|
20
|
+
src={
|
|
21
|
+
"https://docs-assets.developer.apple.com/published/2299e5e8eafedded6947927a8f704c34/landing-page-intoducing-liquid-glass-hero~dark%402x.png"
|
|
22
|
+
}
|
|
23
|
+
/>
|
|
24
|
+
<p className={"text-xs"}>Liquid glass affects SwiftUI, UIKit, and AppKit.</p>
|
|
25
|
+
</PreviewCardPopup>
|
|
26
|
+
</PreviewCard>
|
|
27
|
+
);
|
|
3
28
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Card,
|
|
3
|
+
CardContent,
|
|
4
|
+
CardDescription,
|
|
5
|
+
CardHeader,
|
|
6
|
+
CardTitle,
|
|
7
|
+
} from "@/components/ui/card.tsx";
|
|
8
|
+
import { Meter } from "@/components/ui/meter.tsx";
|
|
9
|
+
import { PreviewCard, PreviewCardPopup, PreviewCardTrigger } from "@/components/ui/preview-card";
|
|
10
|
+
import { Button } from "@/components/ui/button.tsx";
|
|
11
|
+
import { Badge } from "@/components/ui/badge.tsx";
|
|
12
|
+
|
|
13
|
+
export default function PreviewCardLinks() {
|
|
14
|
+
return (
|
|
15
|
+
<PreviewCard>
|
|
16
|
+
<Card size={"sm"} className={"w-md"}>
|
|
17
|
+
<CardHeader className={"flex flex-row items-center justify-between"}>
|
|
18
|
+
<CardTitle>Quote usage</CardTitle>
|
|
19
|
+
<Badge variant={'warning'}>Basic</Badge>
|
|
20
|
+
</CardHeader>
|
|
21
|
+
<CardContent className={'space-y-3'}>
|
|
22
|
+
<Meter value={72} className={"w-full"} />
|
|
23
|
+
<div className={'flex flex-col'}>
|
|
24
|
+
<CardDescription>
|
|
25
|
+
72 out of 100 requests used this <PreviewCardTrigger>month</PreviewCardTrigger>.
|
|
26
|
+
</CardDescription>
|
|
27
|
+
</div>
|
|
28
|
+
</CardContent>
|
|
29
|
+
</Card>
|
|
30
|
+
<PreviewCardPopup side={"bottom"} className={'w-sm p-4'}>
|
|
31
|
+
<div className="flex flex-col gap-2">
|
|
32
|
+
<p className={'text-xs text-muted-foreground'}>Usage resets {new Date(Date.now() + 4 * 7 * 24 * 60 * 60 * 1000).toLocaleDateString()} (4 weeks from now).</p>
|
|
33
|
+
<Button variant={'secondary'} className={'ml-auto'} size={'sm'}>Upgrade to Pro</Button>
|
|
34
|
+
</div>
|
|
35
|
+
</PreviewCardPopup>
|
|
36
|
+
</PreviewCard>
|
|
37
|
+
);
|
|
38
|
+
}
|