tembro 6.0.3 → 6.1.1
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/CHANGELOG.md +13 -0
- package/dist/components/actions/action-menu.d.ts +11 -1
- package/dist/components/calendar/calendar-range-scheduler.cjs +1 -0
- package/dist/components/calendar/calendar-range-scheduler.d.ts +20 -0
- package/dist/components/calendar/calendar-range-scheduler.js +1 -0
- package/dist/components/calendar/date-time-picker.cjs +1 -0
- package/dist/components/calendar/date-time-picker.d.ts +15 -0
- package/dist/components/calendar/date-time-picker.js +1 -0
- package/dist/components/calendar/index.d.ts +2 -0
- package/dist/components/charts/chart-card.cjs +1 -0
- package/dist/components/charts/chart-card.d.ts +24 -0
- package/dist/components/charts/chart-card.js +1 -0
- package/dist/components/charts/index.d.ts +1 -0
- package/dist/components/command/advanced-command-menu.cjs +1 -0
- package/dist/components/command/advanced-command-menu.d.ts +25 -0
- package/dist/components/command/advanced-command-menu.js +1 -0
- package/dist/components/command/index.d.ts +1 -0
- package/dist/components/data-table/data-grid.cjs +1 -0
- package/dist/components/data-table/data-grid.d.ts +15 -0
- package/dist/components/data-table/data-grid.js +1 -0
- package/dist/components/data-table/index.d.ts +1 -0
- package/dist/components/data-table/public.d.ts +1 -0
- package/dist/components/display/index.d.ts +0 -2
- package/dist/components/feedback/async-boundary.cjs +1 -0
- package/dist/components/feedback/async-boundary.d.ts +12 -0
- package/dist/components/feedback/async-boundary.js +1 -0
- package/dist/components/feedback/index.d.ts +1 -0
- package/dist/components/filters/index.d.ts +0 -1
- package/dist/components/inputs/index.d.ts +1 -0
- package/dist/components/inputs/multi-select.cjs +1 -0
- package/dist/components/inputs/multi-select.d.ts +16 -0
- package/dist/components/inputs/multi-select.js +1 -0
- package/dist/components/inputs/public.d.ts +1 -0
- package/dist/components/inputs/time-picker.d.ts +11 -3
- package/dist/components/modern/file-manager.cjs +1 -0
- package/dist/components/modern/file-manager.d.ts +20 -0
- package/dist/components/modern/file-manager.js +1 -0
- package/dist/components/modern/index.d.ts +4 -1
- package/dist/components/modern/map.cjs +1 -0
- package/dist/components/modern/map.d.ts +29 -0
- package/dist/components/modern/map.js +1 -0
- package/dist/components/modern/media-player.cjs +1 -0
- package/dist/components/modern/media-player.d.ts +21 -0
- package/dist/components/modern/media-player.js +1 -0
- package/dist/components/modern/spreadsheet.cjs +1 -0
- package/dist/components/modern/spreadsheet.d.ts +35 -0
- package/dist/components/modern/spreadsheet.js +1 -0
- package/dist/components/notifications/action-toast.cjs +1 -0
- package/dist/components/notifications/action-toast.d.ts +16 -0
- package/dist/components/notifications/action-toast.js +1 -0
- package/dist/components/notifications/index.d.ts +1 -0
- package/dist/components/overlay/drawer.d.ts +3 -1
- package/dist/components/patterns/index.d.ts +1 -0
- package/dist/components/patterns/permissions-matrix.cjs +1 -0
- package/dist/components/patterns/permissions-matrix.d.ts +19 -0
- package/dist/components/patterns/permissions-matrix.js +1 -0
- package/dist/components/patterns/public.d.ts +1 -0
- package/dist/index.d.ts +0 -2
- package/dist/src/components/actions/action-menu.cjs +1 -1
- package/dist/src/components/actions/action-menu.js +47 -39
- package/dist/src/components/actions/copy-button.cjs +1 -1
- package/dist/src/components/actions/copy-button.js +4 -1
- package/dist/src/components/calendar/calendar-range-scheduler.cjs +1 -0
- package/dist/src/components/calendar/calendar-range-scheduler.js +75 -0
- package/dist/src/components/calendar/date-picker.cjs +1 -1
- package/dist/src/components/calendar/date-picker.js +5 -8
- package/dist/src/components/calendar/date-range-picker.cjs +1 -1
- package/dist/src/components/calendar/date-range-picker.js +12 -27
- package/dist/src/components/calendar/date-time-picker.cjs +1 -0
- package/dist/src/components/calendar/date-time-picker.js +36 -0
- package/dist/src/components/calendar/index.cjs +1 -1
- package/dist/src/components/calendar/index.js +5 -3
- package/dist/src/components/charts/chart-card.cjs +1 -0
- package/dist/src/components/charts/chart-card.js +55 -0
- package/dist/src/components/charts/index.cjs +1 -1
- package/dist/src/components/charts/index.js +3 -2
- package/dist/src/components/command/advanced-command-menu.cjs +1 -0
- package/dist/src/components/command/advanced-command-menu.js +57 -0
- package/dist/src/components/command/index.cjs +1 -1
- package/dist/src/components/command/index.js +3 -2
- package/dist/src/components/data-table/data-grid.cjs +1 -0
- package/dist/src/components/data-table/data-grid.js +32 -0
- package/dist/src/components/data-table/data-table-saved-filters.cjs +1 -1
- package/dist/src/components/data-table/data-table-saved-filters.js +11 -11
- package/dist/src/components/data-table/data-table.cjs +1 -1
- package/dist/src/components/data-table/data-table.js +175 -174
- package/dist/src/components/data-table/index.cjs +1 -1
- package/dist/src/components/data-table/index.js +15 -14
- package/dist/src/components/data-table/public.cjs +1 -1
- package/dist/src/components/data-table/public.js +3 -2
- package/dist/src/components/display/index.cjs +1 -1
- package/dist/src/components/display/index.js +9 -11
- package/dist/src/components/feedback/async-boundary.cjs +1 -0
- package/dist/src/components/feedback/async-boundary.js +22 -0
- package/dist/src/components/feedback/index.cjs +1 -1
- package/dist/src/components/feedback/index.js +2 -1
- package/dist/src/components/filters/index.cjs +1 -1
- package/dist/src/components/filters/index.js +2 -3
- package/dist/src/components/inputs/color-picker.cjs +1 -1
- package/dist/src/components/inputs/color-picker.js +63 -46
- package/dist/src/components/inputs/index.cjs +1 -1
- package/dist/src/components/inputs/index.js +13 -12
- package/dist/src/components/inputs/multi-select.cjs +1 -0
- package/dist/src/components/inputs/multi-select.js +80 -0
- package/dist/src/components/inputs/public.cjs +1 -1
- package/dist/src/components/inputs/public.js +13 -12
- package/dist/src/components/inputs/slider.cjs +1 -1
- package/dist/src/components/inputs/slider.js +3 -3
- package/dist/src/components/inputs/tag-input.cjs +1 -1
- package/dist/src/components/inputs/tag-input.js +7 -4
- package/dist/src/components/inputs/time-picker.cjs +1 -1
- package/dist/src/components/inputs/time-picker.js +90 -34
- package/dist/src/components/modern/file-manager.cjs +1 -0
- package/dist/src/components/modern/file-manager.js +75 -0
- package/dist/src/components/modern/index.cjs +1 -1
- package/dist/src/components/modern/index.js +7 -4
- package/dist/src/components/modern/map.cjs +1 -0
- package/dist/src/components/modern/map.js +158 -0
- package/dist/src/components/modern/media-player.cjs +1 -0
- package/dist/src/components/modern/media-player.js +176 -0
- package/dist/src/components/modern/resizable-panel.cjs +1 -1
- package/dist/src/components/modern/resizable-panel.js +39 -32
- package/dist/src/components/modern/spreadsheet.cjs +1 -0
- package/dist/src/components/modern/spreadsheet.js +97 -0
- package/dist/src/components/navigation/pagination.cjs +1 -1
- package/dist/src/components/navigation/pagination.js +5 -5
- package/dist/src/components/notifications/action-toast.cjs +1 -0
- package/dist/src/components/notifications/action-toast.js +49 -0
- package/dist/src/components/notifications/index.cjs +1 -1
- package/dist/src/components/notifications/index.js +3 -2
- package/dist/src/components/notifications/toast.cjs +1 -1
- package/dist/src/components/notifications/toast.js +68 -63
- package/dist/src/components/overlay/alert-dialog.cjs +1 -1
- package/dist/src/components/overlay/alert-dialog.js +8 -6
- package/dist/src/components/overlay/drawer.cjs +1 -1
- package/dist/src/components/overlay/drawer.js +38 -20
- package/dist/src/components/patterns/index.cjs +1 -1
- package/dist/src/components/patterns/index.js +2 -1
- package/dist/src/components/patterns/permissions-matrix.cjs +1 -0
- package/dist/src/components/patterns/permissions-matrix.js +43 -0
- package/dist/src/components/patterns/public.cjs +1 -1
- package/dist/src/components/patterns/public.js +2 -1
- package/dist/src/components/ui/checkbox/index.cjs +1 -1
- package/dist/src/components/ui/checkbox/index.js +2 -1
- package/dist/src/components/ui/dialog/index.cjs +1 -1
- package/dist/src/components/ui/dialog/index.js +8 -8
- package/dist/src/components/ui/dropdown-menu/index.cjs +1 -1
- package/dist/src/components/ui/dropdown-menu/index.js +21 -19
- package/dist/src/components/ui/input/group.cjs +1 -1
- package/dist/src/components/ui/input/group.js +8 -8
- package/dist/src/components/ui/popover/index.cjs +1 -1
- package/dist/src/components/ui/popover/index.js +10 -10
- package/dist/src/components/ui/tabs/index.cjs +1 -1
- package/dist/src/components/ui/tabs/index.js +6 -6
- package/dist/src/components/ui/toggle-group/index.cjs +1 -1
- package/dist/src/components/ui/toggle-group/index.js +2 -2
- package/dist/src/index.cjs +1 -1
- package/dist/src/index.js +111 -104
- package/dist/src/public-component-surface.cjs +1 -1
- package/dist/src/public-component-surface.js +59 -14
- package/package.json +1 -2
- package/packages/cli/dist/index.cjs +45 -165
- package/packages/cli/vendor/src/components/actions/action-menu.tsx +47 -19
- package/packages/cli/vendor/src/components/actions/copy-button.tsx +2 -2
- package/packages/cli/vendor/src/components/calendar/calendar-range-scheduler.tsx +72 -0
- package/packages/cli/vendor/src/components/calendar/date-picker.tsx +2 -5
- package/packages/cli/vendor/src/components/calendar/date-range-picker.tsx +5 -12
- package/packages/cli/vendor/src/components/calendar/date-time-picker.tsx +53 -0
- package/packages/cli/vendor/src/components/calendar/index.ts +5 -3
- package/packages/cli/vendor/src/components/charts/chart-card.tsx +81 -0
- package/packages/cli/vendor/src/components/charts/index.ts +1 -0
- package/packages/cli/vendor/src/components/command/advanced-command-menu.tsx +88 -0
- package/packages/cli/vendor/src/components/command/index.ts +2 -1
- package/packages/cli/vendor/src/components/data-table/data-grid.tsx +59 -0
- package/packages/cli/vendor/src/components/data-table/data-table.tsx +45 -34
- package/packages/cli/vendor/src/components/data-table/index.ts +3 -2
- package/packages/cli/vendor/src/components/data-table/public.ts +1 -0
- package/packages/cli/vendor/src/components/display/index.ts +3 -5
- package/packages/cli/vendor/src/components/feedback/async-boundary.tsx +36 -0
- package/packages/cli/vendor/src/components/feedback/index.ts +1 -0
- package/packages/cli/vendor/src/components/filters/index.ts +0 -1
- package/packages/cli/vendor/src/components/inputs/color-picker.tsx +15 -1
- package/packages/cli/vendor/src/components/inputs/index.ts +1 -0
- package/packages/cli/vendor/src/components/inputs/multi-select.tsx +75 -0
- package/packages/cli/vendor/src/components/inputs/public.ts +1 -0
- package/packages/cli/vendor/src/components/inputs/slider.tsx +3 -3
- package/packages/cli/vendor/src/components/inputs/tag-input.tsx +4 -4
- package/packages/cli/vendor/src/components/inputs/time-picker.tsx +91 -38
- package/packages/cli/vendor/src/components/modern/file-manager.tsx +79 -0
- package/packages/cli/vendor/src/components/modern/index.ts +4 -1
- package/packages/cli/vendor/src/components/modern/map.tsx +146 -0
- package/packages/cli/vendor/src/components/modern/media-player.tsx +182 -0
- package/packages/cli/vendor/src/components/modern/resizable-panel.tsx +15 -5
- package/packages/cli/vendor/src/components/modern/spreadsheet.tsx +155 -0
- package/packages/cli/vendor/src/components/navigation/pagination.tsx +9 -5
- package/packages/cli/vendor/src/components/notifications/action-toast.tsx +78 -0
- package/packages/cli/vendor/src/components/notifications/index.ts +2 -1
- package/packages/cli/vendor/src/components/notifications/toast.tsx +20 -10
- package/packages/cli/vendor/src/components/overlay/alert-dialog.tsx +3 -5
- package/packages/cli/vendor/src/components/overlay/drawer.tsx +22 -11
- package/packages/cli/vendor/src/components/patterns/index.ts +1 -0
- package/packages/cli/vendor/src/components/patterns/permissions-matrix.tsx +71 -0
- package/packages/cli/vendor/src/components/patterns/public.ts +1 -0
- package/packages/cli/vendor/src/components/ui/checkbox/index.tsx +3 -1
- package/packages/cli/vendor/src/components/ui/dialog/index.tsx +4 -4
- package/packages/cli/vendor/src/components/ui/dropdown-menu/index.tsx +18 -22
- package/packages/cli/vendor/src/components/ui/popover/index.tsx +4 -4
- package/packages/cli/vendor/src/components/ui/tabs/index.tsx +8 -3
- package/packages/cli/vendor/src/components/ui/toggle-group/index.tsx +6 -6
- package/packages/cli/vendor/src/index.ts +0 -2
- package/packages/cli/vendor/src/public-component-surface.ts +13 -4
- package/packages/cli/vendor/templates/showcase/src/showcase/data/registry.ts +6 -6
- package/packages/cli/vendor/templates/showcase/src/showcase/layout/HeroSection.tsx +23 -8
- package/packages/cli/vendor/templates/showcase/src/showcase/layout/WorkbenchSidebar.tsx +1 -1
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/PatternsSection.tsx +1 -1
- package/packages/cli/vendor/templates/styles/globals.css +0 -120
- package/registry.json +3197 -2794
- package/dist/components/display/info-card.cjs +0 -1
- package/dist/components/display/info-card.d.ts +0 -51
- package/dist/components/display/info-card.js +0 -1
- package/dist/components/display/statistic.cjs +0 -1
- package/dist/components/display/statistic.d.ts +0 -25
- package/dist/components/display/statistic.js +0 -1
- package/dist/components/filters/filter-bar.cjs +0 -1
- package/dist/components/filters/filter-bar.d.ts +0 -28
- package/dist/components/filters/filter-bar.js +0 -1
- package/dist/components/modern/image-cropper.cjs +0 -1
- package/dist/components/modern/image-cropper.d.ts +0 -39
- package/dist/components/modern/image-cropper.js +0 -1
- package/dist/components/ui/number-field/index.cjs +0 -1
- package/dist/components/ui/number-field/index.d.ts +0 -18
- package/dist/components/ui/number-field/index.js +0 -1
- package/dist/components/ui/toolbar/index.cjs +0 -1
- package/dist/components/ui/toolbar/index.d.ts +0 -14
- package/dist/components/ui/toolbar/index.js +0 -1
- package/dist/src/components/display/info-card.cjs +0 -1
- package/dist/src/components/display/info-card.js +0 -124
- package/dist/src/components/display/statistic.cjs +0 -1
- package/dist/src/components/display/statistic.js +0 -104
- package/dist/src/components/filters/filter-bar.cjs +0 -1
- package/dist/src/components/filters/filter-bar.js +0 -103
- package/dist/src/components/modern/image-cropper.cjs +0 -1
- package/dist/src/components/modern/image-cropper.js +0 -143
- package/dist/src/components/ui/number-field/index.cjs +0 -1
- package/dist/src/components/ui/number-field/index.js +0 -73
- package/dist/src/components/ui/toolbar/index.cjs +0 -1
- package/dist/src/components/ui/toolbar/index.js +0 -50
- package/packages/cli/vendor/src/components/display/info-card.tsx +0 -195
- package/packages/cli/vendor/src/components/display/statistic.tsx +0 -114
- package/packages/cli/vendor/src/components/filters/filter-bar.tsx +0 -163
- package/packages/cli/vendor/src/components/modern/image-cropper.tsx +0 -226
- package/packages/cli/vendor/src/components/ui/number-field/index.tsx +0 -89
- package/packages/cli/vendor/src/components/ui/toolbar/index.tsx +0 -67
|
@@ -14,13 +14,15 @@ import { cn } from "@/lib/utils"
|
|
|
14
14
|
|
|
15
15
|
export type DrawerSide = "left" | "right" | "top" | "bottom"
|
|
16
16
|
export type DrawerWidth = "sm" | "md" | "lg" | "xl" | "full"
|
|
17
|
-
|
|
17
|
+
export type DrawerDensity = "compact" | "default" | "comfortable"
|
|
18
|
+
|
|
18
19
|
export type DrawerProps = Omit<React.ComponentProps<typeof Dialog>, "children"> & {
|
|
19
20
|
trigger?: React.ReactNode
|
|
20
21
|
title?: React.ReactNode
|
|
21
22
|
description?: React.ReactNode
|
|
22
23
|
side?: DrawerSide
|
|
23
24
|
width?: DrawerWidth
|
|
25
|
+
density?: DrawerDensity
|
|
24
26
|
footer?: React.ReactNode
|
|
25
27
|
headerClassName?: string
|
|
26
28
|
bodyClassName?: string
|
|
@@ -29,12 +31,12 @@ export type DrawerProps = Omit<React.ComponentProps<typeof Dialog>, "children">
|
|
|
29
31
|
showCloseButton?: boolean
|
|
30
32
|
children?: React.ReactNode
|
|
31
33
|
}
|
|
32
|
-
|
|
34
|
+
|
|
33
35
|
const sideClassName: Record<DrawerSide, string> = {
|
|
34
|
-
right: "left-auto right-0 top-0 h-dvh max-h-dvh w-full translate-x-0 translate-y-0 rounded-none rounded-l-[var(--radius-3xl)] data-open:slide-in-from-right data-closed:slide-out-to-right",
|
|
35
|
-
left: "left-0 top-0 h-dvh max-h-dvh w-full translate-x-0 translate-y-0 rounded-none rounded-r-[var(--radius-3xl)] data-open:slide-in-from-left data-closed:slide-out-to-left",
|
|
36
|
-
top: "left-0 top-0 h-auto max-h-[85dvh] w-full max-w-none translate-x-0 translate-y-0 rounded-none rounded-b-[var(--radius-3xl)] data-open:slide-in-from-top data-closed:slide-out-to-top",
|
|
37
|
-
bottom: "bottom-0 left-0 top-auto h-auto max-h-[85dvh] w-full max-w-none translate-x-0 translate-y-0 rounded-none rounded-t-[var(--radius-3xl)] data-open:slide-in-from-bottom data-closed:slide-out-to-bottom",
|
|
36
|
+
right: "!left-auto !right-0 !top-0 !h-dvh !max-h-dvh !w-full !translate-x-0 !translate-y-0 rounded-none rounded-l-[var(--radius-3xl)] data-open:slide-in-from-right data-closed:slide-out-to-right",
|
|
37
|
+
left: "!left-0 !top-0 !h-dvh !max-h-dvh !w-full !translate-x-0 !translate-y-0 rounded-none rounded-r-[var(--radius-3xl)] data-open:slide-in-from-left data-closed:slide-out-to-left",
|
|
38
|
+
top: "!left-0 !top-0 !h-auto !max-h-[85dvh] !w-full !max-w-none !translate-x-0 !translate-y-0 rounded-none rounded-b-[var(--radius-3xl)] data-open:slide-in-from-top data-closed:slide-out-to-top",
|
|
39
|
+
bottom: "!bottom-0 !left-0 !top-auto !h-auto !max-h-[85dvh] !w-full !max-w-none !translate-x-0 !translate-y-0 rounded-none rounded-t-[var(--radius-3xl)] data-open:slide-in-from-bottom data-closed:slide-out-to-bottom",
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
const widthClassName: Record<DrawerWidth, string> = {
|
|
@@ -44,13 +46,20 @@ const widthClassName: Record<DrawerWidth, string> = {
|
|
|
44
46
|
xl: "sm:max-w-2xl",
|
|
45
47
|
full: "max-w-none sm:max-w-[min(100vw,72rem)]",
|
|
46
48
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
|
|
50
|
+
const densityClassName: Record<DrawerDensity, { header: string; body: string; footer: string }> = {
|
|
51
|
+
compact: { header: "p-4", body: "p-4", footer: "p-4" },
|
|
52
|
+
default: { header: "p-5", body: "p-5", footer: "p-5" },
|
|
53
|
+
comfortable: { header: "p-6", body: "p-6", footer: "p-6" },
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function Drawer({
|
|
49
57
|
trigger,
|
|
50
58
|
title,
|
|
51
59
|
description,
|
|
52
60
|
side = "right",
|
|
53
61
|
width = "lg",
|
|
62
|
+
density = "default",
|
|
54
63
|
footer,
|
|
55
64
|
headerClassName,
|
|
56
65
|
bodyClassName,
|
|
@@ -65,21 +74,23 @@ function Drawer({
|
|
|
65
74
|
{trigger ? <DialogTrigger render={trigger as React.ReactElement} /> : null}
|
|
66
75
|
<DialogContent
|
|
67
76
|
size="full"
|
|
77
|
+
surface="plain"
|
|
68
78
|
showCloseButton={showCloseButton}
|
|
69
79
|
data-side={side}
|
|
70
80
|
data-width={width}
|
|
81
|
+
data-density={density}
|
|
71
82
|
className={cn("fixed grid grid-rows-[auto_minmax(0,1fr)_auto] gap-0 overscroll-contain p-0", sideClassName[side], (side === "left" || side === "right") && widthClassName[width], contentClassName)}
|
|
72
83
|
>
|
|
73
84
|
{(title || description) && (
|
|
74
|
-
<DialogHeader className={cn("border-b border-border/70
|
|
85
|
+
<DialogHeader className={cn("border-b border-border/70 bg-background/95 backdrop-blur", densityClassName[density].header, headerClassName)}>
|
|
75
86
|
{title ? <DialogTitle>{title}</DialogTitle> : null}
|
|
76
87
|
{description ? <DialogDescription>{description}</DialogDescription> : null}
|
|
77
88
|
</DialogHeader>
|
|
78
89
|
)}
|
|
79
|
-
<div data-slot="drawer-body" className={cn("min-h-0 flex-1 overflow-y-auto
|
|
90
|
+
<div data-slot="drawer-body" className={cn("min-h-0 flex-1 overflow-y-auto bg-background", densityClassName[density].body, bodyClassName)}>
|
|
80
91
|
{children}
|
|
81
92
|
</div>
|
|
82
|
-
{footer ? <div data-slot="drawer-footer" className={cn("border-t border-border/70
|
|
93
|
+
{footer ? <div data-slot="drawer-footer" className={cn("border-t border-border/70 bg-background/95 backdrop-blur", densityClassName[density].footer, footerClassName)}>{footer}</div> : null}
|
|
83
94
|
</DialogContent>
|
|
84
95
|
</Dialog>
|
|
85
96
|
)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
|
|
5
|
+
import { Checkbox } from "@/components/ui/checkbox"
|
|
6
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
|
7
|
+
import { cn } from "@/lib/utils"
|
|
8
|
+
|
|
9
|
+
export type PermissionMatrixRole = {
|
|
10
|
+
key: string
|
|
11
|
+
label: React.ReactNode
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type PermissionMatrixPermission = {
|
|
15
|
+
key: string
|
|
16
|
+
label: React.ReactNode
|
|
17
|
+
description?: React.ReactNode
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type PermissionMatrixValue = Record<string, string[]>
|
|
21
|
+
|
|
22
|
+
export type PermissionsMatrixProps = React.ComponentProps<"div"> & {
|
|
23
|
+
roles: PermissionMatrixRole[]
|
|
24
|
+
permissions: PermissionMatrixPermission[]
|
|
25
|
+
value?: PermissionMatrixValue
|
|
26
|
+
onValueChange?: (value: PermissionMatrixValue) => void
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function PermissionsMatrix({ roles, permissions, value = {}, onValueChange, className, ...props }: PermissionsMatrixProps) {
|
|
30
|
+
const toggle = (permissionKey: string, roleKey: string) => {
|
|
31
|
+
const current = value[permissionKey] ?? []
|
|
32
|
+
const next = current.includes(roleKey) ? current.filter((item) => item !== roleKey) : [...current, roleKey]
|
|
33
|
+
onValueChange?.({ ...value, [permissionKey]: next })
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div data-slot="permissions-matrix" className={cn("overflow-hidden rounded-lg border", className)} {...props}>
|
|
38
|
+
<Table>
|
|
39
|
+
<TableHeader>
|
|
40
|
+
<TableRow>
|
|
41
|
+
<TableHead>Permission</TableHead>
|
|
42
|
+
{roles.map((role) => <TableHead key={role.key} className="text-center">{role.label}</TableHead>)}
|
|
43
|
+
</TableRow>
|
|
44
|
+
</TableHeader>
|
|
45
|
+
<TableBody>
|
|
46
|
+
{permissions.map((permission) => (
|
|
47
|
+
<TableRow key={permission.key}>
|
|
48
|
+
<TableCell>
|
|
49
|
+
<span className="grid gap-0.5">
|
|
50
|
+
<span className="font-medium">{permission.label}</span>
|
|
51
|
+
{permission.description ? <span className="text-xs text-muted-foreground">{permission.description}</span> : null}
|
|
52
|
+
</span>
|
|
53
|
+
</TableCell>
|
|
54
|
+
{roles.map((role) => (
|
|
55
|
+
<TableCell key={role.key} className="text-center">
|
|
56
|
+
<Checkbox
|
|
57
|
+
aria-label={`${permission.label} for ${role.label}`}
|
|
58
|
+
checked={(value[permission.key] ?? []).includes(role.key)}
|
|
59
|
+
onCheckedChange={() => toggle(permission.key, role.key)}
|
|
60
|
+
/>
|
|
61
|
+
</TableCell>
|
|
62
|
+
))}
|
|
63
|
+
</TableRow>
|
|
64
|
+
))}
|
|
65
|
+
</TableBody>
|
|
66
|
+
</Table>
|
|
67
|
+
</div>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { PermissionsMatrix }
|
|
@@ -60,6 +60,8 @@ const Checkbox = React.forwardRef<HTMLButtonElement, CheckboxProps>(
|
|
|
60
60
|
const dataState = currentChecked === "indeterminate" ? "indeterminate" : currentChecked ? "checked" : "unchecked"
|
|
61
61
|
|
|
62
62
|
const handleClick: React.MouseEventHandler<HTMLButtonElement> = (event) => {
|
|
63
|
+
event.preventDefault()
|
|
64
|
+
event.stopPropagation()
|
|
63
65
|
const nextChecked = getNextCheckedState(currentChecked, allowIndeterminate)
|
|
64
66
|
|
|
65
67
|
if (!isControlled) {
|
|
@@ -98,7 +100,7 @@ const Checkbox = React.forwardRef<HTMLButtonElement, CheckboxProps>(
|
|
|
98
100
|
disabled={disabled}
|
|
99
101
|
aria-invalid={invalid || undefined}
|
|
100
102
|
className={cn(
|
|
101
|
-
"peer flex shrink-0 items-center justify-center rounded-[10px] border border-input/88 bg-background text-primary-foreground shadow-[inset_0_1px_0_rgba(255,255,255,0.10)] outline-none transition-[background-color,border-color,box-shadow,color,transform] hover:border-ring/30 hover:bg-background focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/45 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/25 data-[size=sm]:size-4 data-[size=md]:size-5 data-[size=lg]:size-6 data-[state=checked]:border-primary/28 data-[state=checked]:bg-primary data-[state=checked]:shadow-[0_10px_24px_color-mix(in_oklch,var(--primary),transparent_82%)] data-[state=indeterminate]:border-primary/28 data-[state=indeterminate]:bg-primary data-[state=indeterminate]:shadow-[0_10px_24px_color-mix(in_oklch,var(--primary),transparent_82%)] dark:border-white/12 dark:bg-white/[0.04] dark:hover:bg-white/[0.08]",
|
|
103
|
+
"peer flex shrink-0 items-center justify-center rounded-[10px] border border-input/88 bg-background text-primary-foreground shadow-[inset_0_1px_0_rgba(255,255,255,0.10)] outline-none transition-[background-color,border-color,box-shadow,color,transform] hover:border-ring/30 hover:bg-background focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/45 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/25 data-[size=sm]:size-4 data-[size=md]:size-5 data-[size=lg]:size-6 data-[state=checked]:border-primary/28 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:shadow-[0_10px_24px_color-mix(in_oklch,var(--primary),transparent_82%)] data-[state=indeterminate]:border-primary/28 data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground data-[state=indeterminate]:shadow-[0_10px_24px_color-mix(in_oklch,var(--primary),transparent_82%)] dark:data-[state=unchecked]:border-white/12 dark:data-[state=unchecked]:bg-white/[0.04] dark:data-[state=unchecked]:hover:bg-white/[0.08] [&_svg]:stroke-[2.6]",
|
|
102
104
|
className
|
|
103
105
|
)}
|
|
104
106
|
onClick={handleClick}
|
|
@@ -47,7 +47,7 @@ function DialogOverlay({
|
|
|
47
47
|
<DialogPrimitive.Backdrop
|
|
48
48
|
data-slot="dialog-overlay"
|
|
49
49
|
className={cn(
|
|
50
|
-
"fixed inset-0 isolate z-50 duration-100 data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
|
|
50
|
+
"fixed inset-0 isolate z-50 bg-black/45 backdrop-blur-[2px] duration-100 data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0 dark:bg-black/62",
|
|
51
51
|
className
|
|
52
52
|
)}
|
|
53
53
|
{...props}
|
|
@@ -73,7 +73,7 @@ function DialogContent({
|
|
|
73
73
|
role="dialog"
|
|
74
74
|
aria-modal="true"
|
|
75
75
|
className={cn(
|
|
76
|
-
"fixed top-1/2 left-1/2 z-50 grid max-h-[min(92vh,calc(100dvh-2rem))] w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 grid-rows-[auto_minmax(0,1fr)_auto] gap-5 overflow-hidden overscroll-contain duration-100 outline-none data-[surface=plain]:overflow-visible data-[size=xs]:sm:max-w-sm data-[size=sm]:sm:max-w-md data-[size=md]:sm:max-w-lg data-[size=lg]:sm:max-w-2xl data-[size=xl]:sm:max-w-4xl data-[size=full]:h-[min(92vh,56rem)] data-[size=full]:max-w-[min(96vw,84rem)] data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
76
|
+
"fixed top-1/2 left-1/2 z-50 grid max-h-[min(92vh,calc(100dvh-2rem))] w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 grid-rows-[auto_minmax(0,1fr)_auto] gap-5 overflow-hidden overscroll-contain rounded-[var(--aui-card-radius,var(--radius-xl))] border border-border/78 bg-background p-6 text-foreground shadow-[0_32px_90px_rgba(15,23,42,0.24)] duration-100 outline-none data-[surface=plain]:overflow-visible data-[surface=plain]:border-0 data-[surface=plain]:bg-transparent data-[surface=plain]:p-0 data-[surface=plain]:shadow-none data-[size=xs]:sm:max-w-sm data-[size=sm]:sm:max-w-md data-[size=md]:sm:max-w-lg data-[size=lg]:sm:max-w-2xl data-[size=xl]:sm:max-w-4xl data-[size=full]:h-[min(92vh,56rem)] data-[size=full]:max-w-[min(96vw,84rem)] data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
77
77
|
className
|
|
78
78
|
)}
|
|
79
79
|
{...props}
|
|
@@ -148,7 +148,7 @@ function DialogTitle({ className, ...props }: DialogTitleProps) {
|
|
|
148
148
|
return (
|
|
149
149
|
<DialogPrimitive.Title
|
|
150
150
|
data-slot="dialog-title"
|
|
151
|
-
className={className}
|
|
151
|
+
className={cn("text-lg font-semibold tracking-tight text-foreground", className)}
|
|
152
152
|
{...props}
|
|
153
153
|
/>
|
|
154
154
|
)
|
|
@@ -161,7 +161,7 @@ function DialogDescription({
|
|
|
161
161
|
return (
|
|
162
162
|
<DialogPrimitive.Description
|
|
163
163
|
data-slot="dialog-description"
|
|
164
|
-
className={className}
|
|
164
|
+
className={cn("mt-1 text-sm leading-6 text-muted-foreground", className)}
|
|
165
165
|
{...props}
|
|
166
166
|
/>
|
|
167
167
|
)
|
|
@@ -38,7 +38,7 @@ export type DropdownMenuShortcutProps = React.ComponentProps<"span">
|
|
|
38
38
|
export type DropdownMenuItemDescriptionProps = React.ComponentProps<"span">
|
|
39
39
|
|
|
40
40
|
const menuItemClassName =
|
|
41
|
-
"relative group/dropdown-menu-item [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
|
41
|
+
"relative group/dropdown-menu-item flex min-h-9 w-full cursor-default select-none items-center gap-2 rounded-[var(--radius-md)] px-2.5 py-2 text-sm text-popover-foreground outline-none transition-[background-color,color] data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[inset=true]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:data-[highlighted]:bg-destructive/10 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
|
42
42
|
|
|
43
43
|
function DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {
|
|
44
44
|
return <MenuPrimitive.Root data-slot="dropdown-menu" {...props} />
|
|
@@ -76,7 +76,7 @@ function DropdownMenuContent({
|
|
|
76
76
|
>
|
|
77
77
|
<MenuPrimitive.Popup
|
|
78
78
|
data-slot="dropdown-menu-content"
|
|
79
|
-
className={cn("z-50 max-h-(--available-height) w-(--anchor-width) min-w-56 origin-(--transform-origin) overflow-x-hidden overflow-y-auto
|
|
79
|
+
className={cn("z-50 max-h-[min(var(--available-height),24rem)] w-(--anchor-width) min-w-56 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-[var(--aui-card-radius,var(--radius-lg))] border border-border/78 bg-popover p-1 text-popover-foreground shadow-[0_18px_50px_rgba(15,23,42,0.18)] outline-none backdrop-blur duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95", className)}
|
|
80
80
|
{...props}
|
|
81
81
|
/>
|
|
82
82
|
</MenuPrimitive.Positioner>
|
|
@@ -97,7 +97,7 @@ function DropdownMenuLabel({
|
|
|
97
97
|
<div
|
|
98
98
|
data-slot="dropdown-menu-label"
|
|
99
99
|
data-inset={inset}
|
|
100
|
-
className={className}
|
|
100
|
+
className={cn("px-2.5 py-1.5 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground data-[inset=true]:pl-8", className)}
|
|
101
101
|
{...props}
|
|
102
102
|
/>
|
|
103
103
|
)
|
|
@@ -118,6 +118,7 @@ function DropdownMenuItem({
|
|
|
118
118
|
data-variant={variant}
|
|
119
119
|
className={cn(
|
|
120
120
|
menuItemClassName,
|
|
121
|
+
"pl-8 pr-8",
|
|
121
122
|
className
|
|
122
123
|
)}
|
|
123
124
|
onSelect={(event) => {
|
|
@@ -147,6 +148,7 @@ function DropdownMenuSubTrigger({
|
|
|
147
148
|
data-inset={inset}
|
|
148
149
|
className={cn(
|
|
149
150
|
menuItemClassName,
|
|
151
|
+
"pl-8",
|
|
150
152
|
className
|
|
151
153
|
)}
|
|
152
154
|
{...props}
|
|
@@ -204,14 +206,11 @@ function DropdownMenuCheckboxItem({
|
|
|
204
206
|
}}
|
|
205
207
|
{...props}
|
|
206
208
|
>
|
|
207
|
-
<span
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
/>
|
|
213
|
-
</MenuPrimitive.CheckboxItemIndicator>
|
|
214
|
-
</span>
|
|
209
|
+
<span data-slot="dropdown-menu-checkbox-item-indicator" className="absolute left-2 grid size-4 place-items-center">
|
|
210
|
+
<MenuPrimitive.CheckboxItemIndicator>
|
|
211
|
+
<CheckIcon className="size-4" />
|
|
212
|
+
</MenuPrimitive.CheckboxItemIndicator>
|
|
213
|
+
</span>
|
|
215
214
|
{children}
|
|
216
215
|
</MenuPrimitive.CheckboxItem>
|
|
217
216
|
)
|
|
@@ -250,14 +249,11 @@ function DropdownMenuRadioItem({
|
|
|
250
249
|
}}
|
|
251
250
|
{...props}
|
|
252
251
|
>
|
|
253
|
-
<span
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
/>
|
|
259
|
-
</MenuPrimitive.RadioItemIndicator>
|
|
260
|
-
</span>
|
|
252
|
+
<span data-slot="dropdown-menu-radio-item-indicator" className="absolute left-2 grid size-4 place-items-center">
|
|
253
|
+
<MenuPrimitive.RadioItemIndicator>
|
|
254
|
+
<CheckIcon className="size-4" />
|
|
255
|
+
</MenuPrimitive.RadioItemIndicator>
|
|
256
|
+
</span>
|
|
261
257
|
{children}
|
|
262
258
|
</MenuPrimitive.RadioItem>
|
|
263
259
|
)
|
|
@@ -270,7 +266,7 @@ function DropdownMenuSeparator({
|
|
|
270
266
|
return (
|
|
271
267
|
<MenuPrimitive.Separator
|
|
272
268
|
data-slot="dropdown-menu-separator"
|
|
273
|
-
className={className}
|
|
269
|
+
className={cn("-mx-1 my-1 h-px bg-border/72", className)}
|
|
274
270
|
{...props}
|
|
275
271
|
/>
|
|
276
272
|
)
|
|
@@ -283,7 +279,7 @@ function DropdownMenuShortcut({
|
|
|
283
279
|
return (
|
|
284
280
|
<span
|
|
285
281
|
data-slot="dropdown-menu-shortcut"
|
|
286
|
-
className={className}
|
|
282
|
+
className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)}
|
|
287
283
|
{...props}
|
|
288
284
|
/>
|
|
289
285
|
)
|
|
@@ -296,7 +292,7 @@ function DropdownMenuItemDescription({
|
|
|
296
292
|
return (
|
|
297
293
|
<span
|
|
298
294
|
data-slot="dropdown-menu-item-description"
|
|
299
|
-
className={className}
|
|
295
|
+
className={cn("block text-xs leading-5 text-muted-foreground group-data-[highlighted]/dropdown-menu-item:text-accent-foreground/75", className)}
|
|
300
296
|
{...props}
|
|
301
297
|
/>
|
|
302
298
|
)
|
|
@@ -46,7 +46,7 @@ function PopoverContent({
|
|
|
46
46
|
<PopoverPrimitive.Popup
|
|
47
47
|
data-slot="popover-content"
|
|
48
48
|
className={cn(
|
|
49
|
-
"z-50 flex max-h-[min(var(--available-height),calc(100dvh-1rem))] w-[min(var(--anchor-width),20rem)] min-w-60 max-w-[calc(100vw-1rem)] origin-(--transform-origin) flex-col gap-3 overflow-y-auto rounded-[var(--radius-lg)] border border-border bg-popover text-popover-foreground shadow-
|
|
49
|
+
"z-50 flex max-h-[min(var(--available-height),calc(100dvh-1rem))] w-[min(var(--anchor-width),20rem)] min-w-60 max-w-[calc(100vw-1rem)] origin-(--transform-origin) flex-col gap-3 overflow-y-auto rounded-[var(--aui-card-radius,var(--radius-lg))] border border-border/78 bg-popover p-3 text-popover-foreground shadow-[0_18px_50px_rgba(15,23,42,0.18)] outline-hidden backdrop-blur duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
50
50
|
className
|
|
51
51
|
)}
|
|
52
52
|
{...props}
|
|
@@ -60,7 +60,7 @@ function PopoverHeader({ className, ...props }: PopoverHeaderProps) {
|
|
|
60
60
|
return (
|
|
61
61
|
<div
|
|
62
62
|
data-slot="popover-header"
|
|
63
|
-
className={className}
|
|
63
|
+
className={cn("grid gap-1", className)}
|
|
64
64
|
{...props}
|
|
65
65
|
/>
|
|
66
66
|
)
|
|
@@ -70,7 +70,7 @@ function PopoverTitle({ className, ...props }: PopoverTitleProps) {
|
|
|
70
70
|
return (
|
|
71
71
|
<PopoverPrimitive.Title
|
|
72
72
|
data-slot="popover-title"
|
|
73
|
-
className={className}
|
|
73
|
+
className={cn("text-sm font-semibold text-foreground", className)}
|
|
74
74
|
{...props}
|
|
75
75
|
/>
|
|
76
76
|
)
|
|
@@ -83,7 +83,7 @@ function PopoverDescription({
|
|
|
83
83
|
return (
|
|
84
84
|
<PopoverPrimitive.Description
|
|
85
85
|
data-slot="popover-description"
|
|
86
|
-
className={className}
|
|
86
|
+
className={cn("text-sm leading-6 text-muted-foreground", className)}
|
|
87
87
|
{...props}
|
|
88
88
|
/>
|
|
89
89
|
)
|
|
@@ -25,7 +25,9 @@ const TabsList = React.forwardRef<
|
|
|
25
25
|
data-variant={variant}
|
|
26
26
|
data-overflow={overflow}
|
|
27
27
|
className={cn(
|
|
28
|
-
"inline-flex max-w-full items-center justify-start",
|
|
28
|
+
"inline-flex max-w-full items-center justify-start gap-1 rounded-[var(--radius-lg)] border border-border/72 bg-muted/45 p-1",
|
|
29
|
+
variant === "underline" && "gap-4 rounded-none border-x-0 border-t-0 bg-transparent p-0",
|
|
30
|
+
variant === "compact" && "rounded-[var(--radius-md)] p-0.5",
|
|
29
31
|
overflow === "scroll" && "overflow-x-auto overflow-y-hidden overscroll-x-contain [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
30
32
|
overflow === "wrap" && "flex-wrap",
|
|
31
33
|
className
|
|
@@ -44,7 +46,10 @@ const TabsTrigger = React.forwardRef<
|
|
|
44
46
|
data-slot="tabs-trigger"
|
|
45
47
|
data-variant={variant}
|
|
46
48
|
className={cn(
|
|
47
|
-
"inline-flex shrink-0 items-center justify-center whitespace-nowrap disabled:pointer-events-none",
|
|
49
|
+
"inline-flex h-9 shrink-0 items-center justify-center whitespace-nowrap rounded-[var(--radius-md)] px-3 text-sm font-medium text-muted-foreground outline-none transition-[background-color,border-color,color,box-shadow] hover:bg-background/72 hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[selected]:bg-background data-[selected]:text-foreground data-[selected]:shadow-sm",
|
|
50
|
+
variant === "pills" && "rounded-full px-4 data-[selected]:bg-primary data-[selected]:text-primary-foreground",
|
|
51
|
+
variant === "underline" && "h-10 rounded-none border-b-2 border-transparent bg-transparent px-0 shadow-none hover:bg-transparent data-[selected]:border-primary data-[selected]:bg-transparent data-[selected]:shadow-none",
|
|
52
|
+
variant === "compact" && "h-8 rounded-[calc(var(--radius-md)-2px)] px-2.5 text-xs",
|
|
48
53
|
className
|
|
49
54
|
)}
|
|
50
55
|
{...props}
|
|
@@ -59,7 +64,7 @@ const TabsContent = React.forwardRef<
|
|
|
59
64
|
<BaseTabs.Panel
|
|
60
65
|
ref={ref}
|
|
61
66
|
data-slot="tabs-content"
|
|
62
|
-
className={className}
|
|
67
|
+
className={cn("mt-3 outline-none focus-visible:ring-2 focus-visible:ring-ring", className)}
|
|
63
68
|
{...props}
|
|
64
69
|
/>
|
|
65
70
|
))
|
|
@@ -35,8 +35,8 @@ function ToggleGroup<TValue extends string = string>({
|
|
|
35
35
|
orientation={orientation}
|
|
36
36
|
className={cn(
|
|
37
37
|
"inline-flex items-center gap-1 rounded-[var(--radius-lg)]",
|
|
38
|
-
variant === "default" && "border border-border bg-muted/
|
|
39
|
-
variant === "outline" && "gap-0 overflow-hidden rounded-[var(--radius-lg)] border border-border",
|
|
38
|
+
variant === "default" && "border border-border/72 bg-muted/45 p-1 shadow-[inset_0_1px_0_rgba(255,255,255,0.18)]",
|
|
39
|
+
variant === "outline" && "gap-0 overflow-hidden rounded-[var(--radius-lg)] border border-border/78 bg-background",
|
|
40
40
|
orientation === "vertical" && "flex-col items-stretch",
|
|
41
41
|
className
|
|
42
42
|
)}
|
|
@@ -57,11 +57,11 @@ function ToggleGroupItem<TValue extends string = string>({
|
|
|
57
57
|
data-variant={variant}
|
|
58
58
|
data-size={size}
|
|
59
59
|
className={cn(
|
|
60
|
-
"inline-flex items-center justify-center gap-1.5 whitespace-nowrap font-medium outline-none transition-[background-color,color,border-color,box-shadow] disabled:pointer-events-none disabled:opacity-50 data-[pressed]:text-foreground focus-visible:ring-2 focus-visible:ring-ring [&_svg]:size-4 [&_svg]:shrink-0",
|
|
60
|
+
"inline-flex items-center justify-center gap-1.5 whitespace-nowrap font-medium outline-none transition-[background-color,color,border-color,box-shadow,transform] disabled:pointer-events-none disabled:opacity-50 data-[pressed]:text-foreground focus-visible:ring-2 focus-visible:ring-ring [&_svg]:size-4 [&_svg]:shrink-0",
|
|
61
61
|
sizeClassName[size],
|
|
62
|
-
variant === "default" && "rounded-[calc(var(--radius-md)-1px)] text-muted-foreground hover:bg-background/70 data-[pressed]:bg-background data-[pressed]:shadow-sm",
|
|
63
|
-
variant === "outline" && "-m-px border border-border text-muted-foreground hover:bg-muted/60 data-[pressed]:bg-
|
|
64
|
-
variant === "ghost" && "rounded-[var(--radius-md)] text-muted-foreground hover:bg-muted/70 data-[pressed]:bg-
|
|
62
|
+
variant === "default" && "rounded-[calc(var(--radius-md)-1px)] text-muted-foreground hover:bg-background/70 hover:text-foreground data-[pressed]:-translate-y-px data-[pressed]:bg-background data-[pressed]:shadow-sm",
|
|
63
|
+
variant === "outline" && "-m-px border border-border/78 text-muted-foreground hover:bg-muted/60 hover:text-foreground data-[pressed]:bg-primary data-[pressed]:text-primary-foreground data-[pressed]:shadow-inner first:rounded-l-[var(--radius-md)] last:rounded-r-[var(--radius-md)]",
|
|
64
|
+
variant === "ghost" && "rounded-[var(--radius-md)] text-muted-foreground hover:bg-muted/70 hover:text-foreground data-[pressed]:bg-accent data-[pressed]:text-accent-foreground",
|
|
65
65
|
className
|
|
66
66
|
)}
|
|
67
67
|
{...props}
|
|
@@ -27,9 +27,7 @@ export * from './components/ui/kbd'
|
|
|
27
27
|
export * from './components/ui/radio-group'
|
|
28
28
|
export * from './components/ui/scroll-box'
|
|
29
29
|
export * from './components/ui/right-click-menu'
|
|
30
|
-
export * from './components/ui/number-field'
|
|
31
30
|
export * from './components/ui/toggle-group'
|
|
32
|
-
export * from './components/ui/toolbar'
|
|
33
31
|
|
|
34
32
|
// Reusable groups
|
|
35
33
|
export * from './components/actions/public'
|
|
@@ -16,9 +16,8 @@ export const documentedPublicComponentSurfaces: readonly PublicComponentSurfaceE
|
|
|
16
16
|
{ slug: "checkbox", registryName: "checkbox", surface: "documented" },
|
|
17
17
|
{ slug: "switch", registryName: "switch", surface: "documented" },
|
|
18
18
|
{ slug: "radio-group", registryName: "radio-group", surface: "documented" },
|
|
19
|
-
{ slug: "
|
|
19
|
+
{ slug: "multi-select", registryName: "multi-select", surface: "documented" },
|
|
20
20
|
{ slug: "toggle-group", registryName: "toggle-group", surface: "documented" },
|
|
21
|
-
{ slug: "toolbar", registryName: "toolbar", surface: "documented" },
|
|
22
21
|
{ slug: "overlay", registryName: "dialog", surface: "documented" },
|
|
23
22
|
{ slug: "dropdown-menu", registryName: "dropdown-menu", surface: "documented" },
|
|
24
23
|
{ slug: "popover", registryName: "popover", surface: "documented" },
|
|
@@ -34,11 +33,14 @@ export const documentedPublicComponentSurfaces: readonly PublicComponentSurfaceE
|
|
|
34
33
|
{ slug: "alert", registryName: "alert", surface: "documented" },
|
|
35
34
|
{ slug: "toast", registryName: "toast", surface: "documented" },
|
|
36
35
|
{ slug: "notification-center", registryName: "notification-center", surface: "documented" },
|
|
36
|
+
{ slug: "action-toast", registryName: "action-toast", surface: "documented" },
|
|
37
37
|
{ slug: "bar-chart", registryName: "charts", surface: "documented" },
|
|
38
|
+
{ slug: "chart-card", registryName: "chart-card", surface: "documented" },
|
|
38
39
|
{ slug: "sidebar", registryName: "sidebar", surface: "documented" },
|
|
39
40
|
{ slug: "breadcrumbs", registryName: "breadcrumbs", surface: "documented" },
|
|
40
41
|
{ slug: "workspace-layout", registryName: "workspace-layout", surface: "documented" },
|
|
41
42
|
{ slug: "state-view", registryName: "state-view", surface: "documented" },
|
|
43
|
+
{ slug: "async-boundary", registryName: "async-boundary", surface: "documented" },
|
|
42
44
|
{ slug: "file-upload", registryName: "file-upload", surface: "documented" },
|
|
43
45
|
{ slug: "progress", registryName: "progress", surface: "documented" },
|
|
44
46
|
{ slug: "accordion", registryName: "accordion", surface: "documented" },
|
|
@@ -47,6 +49,7 @@ export const documentedPublicComponentSurfaces: readonly PublicComponentSurfaceE
|
|
|
47
49
|
{ slug: "skeleton", registryName: "skeleton", surface: "documented" },
|
|
48
50
|
{ slug: "spinner", registryName: "spinner", surface: "documented" },
|
|
49
51
|
{ slug: "command-palette", registryName: "command-palette", surface: "documented" },
|
|
52
|
+
{ slug: "advanced-command-menu", registryName: "advanced-command-menu", surface: "documented" },
|
|
50
53
|
{ slug: "inline-editable", registryName: "inline-editable", surface: "documented" },
|
|
51
54
|
{ slug: "avatar", registryName: "avatar", surface: "documented" },
|
|
52
55
|
{ slug: "code-block", registryName: "code-block", surface: "documented" },
|
|
@@ -55,26 +58,32 @@ export const documentedPublicComponentSurfaces: readonly PublicComponentSurfaceE
|
|
|
55
58
|
{ slug: "chat", registryName: "chat", surface: "documented" },
|
|
56
59
|
{ slug: "list", registryName: "list", surface: "documented" },
|
|
57
60
|
{ slug: "description-list", registryName: "description-list", surface: "documented" },
|
|
58
|
-
{ slug: "statistic", registryName: "statistic", surface: "documented" },
|
|
59
61
|
{ slug: "tree-view", registryName: "tree-view", surface: "documented" },
|
|
60
62
|
{ slug: "copy-button", registryName: "copy-button", surface: "documented" },
|
|
61
63
|
{ slug: "section", registryName: "section", surface: "documented" },
|
|
62
64
|
{ slug: "empty-state", registryName: "empty-state", surface: "documented" },
|
|
65
|
+
{ slug: "permissions-matrix", registryName: "permissions-matrix", surface: "documented" },
|
|
63
66
|
{ slug: "calendar-scheduler", registryName: "calendar-scheduler", surface: "documented" },
|
|
67
|
+
{ slug: "calendar-range-scheduler", registryName: "calendar-range-scheduler", surface: "documented" },
|
|
64
68
|
{ slug: "dual-list-picker", registryName: "dual-list-picker", surface: "documented" },
|
|
65
69
|
{ slug: "resizable-panel", registryName: "resizable-panel", surface: "documented" },
|
|
70
|
+
{ slug: "file-manager", registryName: "file-manager", surface: "documented" },
|
|
71
|
+
{ slug: "map", registryName: "map", surface: "documented" },
|
|
72
|
+
{ slug: "media-player", registryName: "media-player", surface: "documented" },
|
|
73
|
+
{ slug: "spreadsheet", registryName: "spreadsheet", surface: "documented" },
|
|
66
74
|
{ slug: "tag", registryName: "tag", surface: "documented" },
|
|
67
75
|
{ slug: "carousel", registryName: "carousel", surface: "documented" },
|
|
68
76
|
{ slug: "typography", registryName: "typography", surface: "documented" },
|
|
69
77
|
{ slug: "json-input", registryName: "json-input", surface: "documented" },
|
|
70
78
|
{ slug: "time-picker", registryName: "time-picker", surface: "documented" },
|
|
79
|
+
{ slug: "date-time-picker", registryName: "date-time-picker", surface: "documented" },
|
|
71
80
|
{ slug: "sortable-list", registryName: "sortable-list", surface: "documented" },
|
|
72
81
|
{ slug: "virtual-list", registryName: "virtual-list", surface: "documented" },
|
|
73
82
|
{ slug: "color-picker", registryName: "color-picker", surface: "documented" },
|
|
74
83
|
{ slug: "signature-pad", registryName: "signature-pad", surface: "documented" },
|
|
75
84
|
{ slug: "qr-code", registryName: "qr-code", surface: "documented" },
|
|
76
85
|
{ slug: "rich-text-editor", registryName: "rich-text-editor", surface: "documented" },
|
|
77
|
-
{ slug: "
|
|
86
|
+
{ slug: "data-grid", registryName: "data-grid", surface: "documented" },
|
|
78
87
|
] as const
|
|
79
88
|
|
|
80
89
|
export const standalonePublicComponentSurfaces: readonly PublicComponentSurfaceEntry[] = [] as const
|
|
@@ -53,7 +53,6 @@ export const registryGroups: RegistryGroup[] = [
|
|
|
53
53
|
component("scroll-box", "stable", "src/components/ui/scroll-box"),
|
|
54
54
|
component("right-click-menu", "stable", "src/components/ui/right-click-menu"),
|
|
55
55
|
component("toggle-group", "preview", "src/components/ui/toggle-group"),
|
|
56
|
-
component("toolbar", "preview", "src/components/ui/toolbar"),
|
|
57
56
|
component("collapse", "preview", "src/components/ui/collapse"),
|
|
58
57
|
component("command", "preview", "src/components/ui/command"),
|
|
59
58
|
component("divider", "preview", "src/components/ui/divider"),
|
|
@@ -82,7 +81,6 @@ export const registryGroups: RegistryGroup[] = [
|
|
|
82
81
|
component("inline-editable", "preview", "src/components/inputs/inline-editable.tsx"),
|
|
83
82
|
component("json-input", "preview", "src/components/inputs/json-input.tsx"),
|
|
84
83
|
component("time-picker", "preview", "src/components/inputs/time-picker.tsx"),
|
|
85
|
-
component("number-field", "preview", "src/components/ui/number-field"),
|
|
86
84
|
],
|
|
87
85
|
},
|
|
88
86
|
{
|
|
@@ -112,8 +110,6 @@ export const registryGroups: RegistryGroup[] = [
|
|
|
112
110
|
component("kanban", "preview", "src/components/display/kanban.tsx"),
|
|
113
111
|
component("list", "preview", "src/components/display/list.tsx"),
|
|
114
112
|
component("progress", "stable", "src/components/display/progress.tsx"),
|
|
115
|
-
component("info-card", "stable", "src/components/display/info-card.tsx"),
|
|
116
|
-
component("statistic", "preview", "src/components/display/statistic.tsx"),
|
|
117
113
|
component("status-dot", "preview", "src/components/display/status-dot.tsx"),
|
|
118
114
|
component("status-legend", "preview", "src/components/display/status-legend.tsx"),
|
|
119
115
|
component("timeline", "stable", "src/components/display/timeline.tsx"),
|
|
@@ -167,7 +163,9 @@ export const registryGroups: RegistryGroup[] = [
|
|
|
167
163
|
component("dual-list-picker", "preview", "src/components/modern/dual-list-picker.tsx"),
|
|
168
164
|
component("resizable-panel", "preview", "src/components/modern/resizable-panel.tsx"),
|
|
169
165
|
component("rich-text-editor", "preview", "src/components/modern/rich-text-editor.tsx"),
|
|
170
|
-
component("
|
|
166
|
+
component("map", "preview", "src/components/modern/map.tsx"),
|
|
167
|
+
component("media-player", "preview", "src/components/modern/media-player.tsx"),
|
|
168
|
+
component("spreadsheet", "preview", "src/components/modern/spreadsheet.tsx"),
|
|
171
169
|
],
|
|
172
170
|
},
|
|
173
171
|
{
|
|
@@ -180,7 +178,6 @@ export const registryGroups: RegistryGroup[] = [
|
|
|
180
178
|
{
|
|
181
179
|
name: "filters",
|
|
182
180
|
components: [
|
|
183
|
-
component("filter-bar", "stable", "src/components/filters/filter-bar.tsx"),
|
|
184
181
|
component("saved-filter-select", "preview", "src/components/filters/saved-filter-select.tsx"),
|
|
185
182
|
],
|
|
186
183
|
},
|
|
@@ -219,6 +216,9 @@ export const componentRows: ComponentRow[] = [
|
|
|
219
216
|
{ id: "cmp-006", component: "wizard", category: "wizard", status: "Review", props: 12 },
|
|
220
217
|
{ id: "cmp-007", component: "button", category: "ui", status: "Ready", props: 9 },
|
|
221
218
|
{ id: "cmp-008", component: "input", category: "ui", status: "Ready", props: 11 },
|
|
219
|
+
{ id: "cmp-009", component: "map", category: "modern", status: "Testing", props: 13 },
|
|
220
|
+
{ id: "cmp-010", component: "media-player", category: "modern", status: "Testing", props: 12 },
|
|
221
|
+
{ id: "cmp-011", component: "spreadsheet", category: "modern", status: "Testing", props: 13 },
|
|
222
222
|
]
|
|
223
223
|
|
|
224
224
|
export const wizardSteps = [
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { PlusIcon, SettingsIcon } from "lucide-react"
|
|
2
2
|
|
|
3
3
|
import { CopyButton } from "@/components/actions/copy-button"
|
|
4
|
-
import { StatisticCard, StatisticGrid } from "@/components/display/statistic"
|
|
5
4
|
import { Badge } from "@/components/ui/badge"
|
|
6
5
|
import { Button } from "@/components/ui/button"
|
|
6
|
+
import { Card, CardContent } from "@/components/ui/card"
|
|
7
7
|
import { moduleCount, registryGroups } from "@/showcase/data/registry"
|
|
8
8
|
|
|
9
|
+
const metrics = [
|
|
10
|
+
{ label: "Registry components", value: moduleCount, change: "visible below", description: "tembro add <name>" },
|
|
11
|
+
{ label: "Local source files", value: "152", change: "with hooks/lib", description: "installed by CLI" },
|
|
12
|
+
{ label: "Categories", value: registryGroups.length, change: "all shown", description: "actions to wizard" },
|
|
13
|
+
{ label: "Build", value: "Pass", change: "doctor pass", description: "tembro@6.1.1" },
|
|
14
|
+
]
|
|
15
|
+
|
|
9
16
|
export function HeroSection() {
|
|
10
17
|
return (
|
|
11
18
|
<section className="border-b bg-card">
|
|
@@ -25,16 +32,24 @@ export function HeroSection() {
|
|
|
25
32
|
<div className="flex flex-wrap gap-2">
|
|
26
33
|
<Button leftIcon={<PlusIcon className="size-4" />}>Create</Button>
|
|
27
34
|
<Button variant="outline" leftIcon={<SettingsIcon className="size-4" />}>Settings</Button>
|
|
28
|
-
<CopyButton value="npx tembro@6.
|
|
35
|
+
<CopyButton value="npx tembro@6.1.1 list --json">Copy list command</CopyButton>
|
|
29
36
|
</div>
|
|
30
37
|
</div>
|
|
31
38
|
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
<div className="mt-8 grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
|
|
40
|
+
{metrics.map((metric) => (
|
|
41
|
+
<Card key={metric.label}>
|
|
42
|
+
<CardContent className="p-4">
|
|
43
|
+
<p className="text-sm text-muted-foreground">{metric.label}</p>
|
|
44
|
+
<p className="mt-5 text-2xl font-semibold tracking-tight">{metric.value}</p>
|
|
45
|
+
<div className="mt-2 flex flex-wrap items-center gap-2 text-xs">
|
|
46
|
+
<Badge tone="success" variant="soft">{metric.change}</Badge>
|
|
47
|
+
<span className="text-muted-foreground">{metric.description}</span>
|
|
48
|
+
</div>
|
|
49
|
+
</CardContent>
|
|
50
|
+
</Card>
|
|
51
|
+
))}
|
|
52
|
+
</div>
|
|
38
53
|
</div>
|
|
39
54
|
</section>
|
|
40
55
|
)
|