@momentumworld/ui-react 0.17.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/dist/chunk-2HQPCV2L.js +895 -0
- package/dist/chunk-2HQPCV2L.js.map +1 -0
- package/dist/form.d.ts +175 -0
- package/dist/form.js +356 -0
- package/dist/form.js.map +1 -0
- package/dist/index.d.ts +2162 -0
- package/dist/index.js +11640 -0
- package/dist/index.js.map +1 -0
- package/dist/input-JCZs61MO.d.ts +24 -0
- package/package.json +90 -0
- package/src/components/form/checkbox-group-field.tsx +101 -0
- package/src/components/form/date-field.tsx +79 -0
- package/src/components/form/date-range-field.tsx +106 -0
- package/src/components/form/form-context.ts +10 -0
- package/src/components/form/form.tsx +54 -0
- package/src/components/form/number-field.tsx +69 -0
- package/src/components/form/select-field.tsx +76 -0
- package/src/components/form/submit-button.tsx +28 -0
- package/src/components/form/text-field.tsx +107 -0
- package/src/components/layout/dashboard-header.tsx +54 -0
- package/src/components/layout/dashboard-panel.tsx +34 -0
- package/src/components/layout/dashboard-topbar.tsx +221 -0
- package/src/components/theme-provider.tsx +403 -0
- package/src/components/ui/accordion.tsx +69 -0
- package/src/components/ui/alert-dialog.tsx +169 -0
- package/src/components/ui/alert.tsx +80 -0
- package/src/components/ui/animated-counter.tsx +109 -0
- package/src/components/ui/animated-theme-toggler.tsx +265 -0
- package/src/components/ui/app-store-buttons.tsx +182 -0
- package/src/components/ui/aspect-ratio.tsx +23 -0
- package/src/components/ui/aurora-orb.tsx +163 -0
- package/src/components/ui/aurora-text.tsx +76 -0
- package/src/components/ui/autocomplete.tsx +296 -0
- package/src/components/ui/avatar-group.tsx +150 -0
- package/src/components/ui/avatar.tsx +285 -0
- package/src/components/ui/badge-group.tsx +160 -0
- package/src/components/ui/badge.tsx +172 -0
- package/src/components/ui/breadcrumb.tsx +112 -0
- package/src/components/ui/button.tsx +77 -0
- package/src/components/ui/calendar.tsx +137 -0
- package/src/components/ui/card.tsx +244 -0
- package/src/components/ui/carousel.tsx +258 -0
- package/src/components/ui/chart.tsx +379 -0
- package/src/components/ui/chat-divider.tsx +67 -0
- package/src/components/ui/chat.tsx +494 -0
- package/src/components/ui/checkbox-group.tsx +16 -0
- package/src/components/ui/checkbox.tsx +82 -0
- package/src/components/ui/collapsible.tsx +45 -0
- package/src/components/ui/color-picker.tsx +389 -0
- package/src/components/ui/combobox.tsx +411 -0
- package/src/components/ui/command.tsx +264 -0
- package/src/components/ui/confetti.tsx +196 -0
- package/src/components/ui/context-menu.tsx +271 -0
- package/src/components/ui/context-meter.tsx +134 -0
- package/src/components/ui/credit-card.tsx +214 -0
- package/src/components/ui/data-table-paged.tsx +163 -0
- package/src/components/ui/date-picker.tsx +154 -0
- package/src/components/ui/dialog.tsx +196 -0
- package/src/components/ui/drawer.tsx +135 -0
- package/src/components/ui/empty.tsx +127 -0
- package/src/components/ui/fab.tsx +45 -0
- package/src/components/ui/featured-icon.tsx +149 -0
- package/src/components/ui/field.tsx +88 -0
- package/src/components/ui/fieldset.tsx +29 -0
- package/src/components/ui/form.tsx +17 -0
- package/src/components/ui/frame.tsx +82 -0
- package/src/components/ui/generic-empty.tsx +142 -0
- package/src/components/ui/group.tsx +97 -0
- package/src/components/ui/help-tip.tsx +94 -0
- package/src/components/ui/horizontal-scroll-fader.tsx +228 -0
- package/src/components/ui/input-group.tsx +102 -0
- package/src/components/ui/input-otp.tsx +96 -0
- package/src/components/ui/input.tsx +66 -0
- package/src/components/ui/item.tsx +198 -0
- package/src/components/ui/kbd.tsx +30 -0
- package/src/components/ui/label.tsx +28 -0
- package/src/components/ui/markdown.tsx +188 -0
- package/src/components/ui/menu.tsx +312 -0
- package/src/components/ui/menubar.tsx +93 -0
- package/src/components/ui/meter.tsx +67 -0
- package/src/components/ui/multi-select.tsx +308 -0
- package/src/components/ui/navigation-menu.tsx +143 -0
- package/src/components/ui/number-field.tsx +160 -0
- package/src/components/ui/pagination-controls.tsx +74 -0
- package/src/components/ui/pagination.tsx +149 -0
- package/src/components/ui/pipeline.tsx +102 -0
- package/src/components/ui/popover.tsx +119 -0
- package/src/components/ui/preview-card.tsx +55 -0
- package/src/components/ui/progress.tsx +289 -0
- package/src/components/ui/qr-code.tsx +150 -0
- package/src/components/ui/radio-group.tsx +103 -0
- package/src/components/ui/resizable.tsx +56 -0
- package/src/components/ui/scroll-area.tsx +90 -0
- package/src/components/ui/scroller.tsx +38 -0
- package/src/components/ui/section-header.tsx +118 -0
- package/src/components/ui/segmented-control.tsx +83 -0
- package/src/components/ui/select.tsx +181 -0
- package/src/components/ui/separator.tsx +23 -0
- package/src/components/ui/sheet.tsx +224 -0
- package/src/components/ui/sidebar.tsx +774 -0
- package/src/components/ui/skeleton.tsx +16 -0
- package/src/components/ui/slider.tsx +108 -0
- package/src/components/ui/smooth-scroll.tsx +206 -0
- package/src/components/ui/social-button.tsx +247 -0
- package/src/components/ui/spinner-on-demand.tsx +32 -0
- package/src/components/ui/spinner.tsx +18 -0
- package/src/components/ui/stat.tsx +187 -0
- package/src/components/ui/stepper.tsx +167 -0
- package/src/components/ui/switch.tsx +56 -0
- package/src/components/ui/table.tsx +126 -0
- package/src/components/ui/tabs.tsx +90 -0
- package/src/components/ui/tag.tsx +242 -0
- package/src/components/ui/target-countdown.tsx +46 -0
- package/src/components/ui/text-editor.tsx +313 -0
- package/src/components/ui/textarea.tsx +51 -0
- package/src/components/ui/thinking-orb.tsx +6 -0
- package/src/components/ui/time-picker.tsx +308 -0
- package/src/components/ui/timeline.tsx +116 -0
- package/src/components/ui/toast.tsx +268 -0
- package/src/components/ui/toggle-group.tsx +101 -0
- package/src/components/ui/toggle.tsx +45 -0
- package/src/components/ui/toolbar.tsx +89 -0
- package/src/components/ui/tooltip.tsx +102 -0
- package/src/components/ui/vertical-scroll-fader.tsx +250 -0
- package/src/components/ui/video-player.tsx +275 -0
- package/src/components/upload/avatar-upload-base.tsx +131 -0
- package/src/components/upload/image-upload-base.tsx +112 -0
- package/src/form.ts +17 -0
- package/src/index.ts +143 -0
- package/src/lib/hooks/use-callback-ref.ts +15 -0
- package/src/lib/hooks/use-first-render.ts +11 -0
- package/src/lib/hooks/use-hover.ts +53 -0
- package/src/lib/hooks/use-is-tab-active.ts +17 -0
- package/src/lib/hooks/use-media-query.ts +164 -0
- package/src/lib/utils/css.ts +6 -0
- package/src/styles.css +329 -0
- package/src/types/helpers.ts +24 -0
- package/src/types/react.d.ts +7 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Field as FieldPrimitive } from "@base-ui/react/field";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../../lib/utils/css";
|
|
6
|
+
|
|
7
|
+
function Field({ className, ...props }: FieldPrimitive.Root.Props) {
|
|
8
|
+
return (
|
|
9
|
+
<FieldPrimitive.Root
|
|
10
|
+
className={cn("flex flex-col items-start gap-2", className)}
|
|
11
|
+
data-slot="field"
|
|
12
|
+
{...props}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function FieldLabel({ className, ...props }: FieldPrimitive.Label.Props) {
|
|
18
|
+
return (
|
|
19
|
+
<FieldPrimitive.Label
|
|
20
|
+
className={cn(
|
|
21
|
+
"inline-flex items-center gap-2 font-medium text-base/4.5 text-foreground sm:text-sm/4",
|
|
22
|
+
className,
|
|
23
|
+
)}
|
|
24
|
+
data-slot="field-label"
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function FieldItem({ className, ...props }: FieldPrimitive.Item.Props) {
|
|
31
|
+
return (
|
|
32
|
+
<FieldPrimitive.Item
|
|
33
|
+
className={cn("flex", className)}
|
|
34
|
+
data-slot="field-item"
|
|
35
|
+
{...props}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function FieldDescription({
|
|
41
|
+
className,
|
|
42
|
+
...props
|
|
43
|
+
}: FieldPrimitive.Description.Props) {
|
|
44
|
+
return (
|
|
45
|
+
<FieldPrimitive.Description
|
|
46
|
+
className={cn("text-muted-foreground text-xs", className)}
|
|
47
|
+
data-slot="field-description"
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function FieldError({ className, ...props }: FieldPrimitive.Error.Props) {
|
|
54
|
+
return (
|
|
55
|
+
<FieldPrimitive.Error
|
|
56
|
+
className={cn("text-destructive-foreground text-xs", className)}
|
|
57
|
+
data-slot="field-error"
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
64
|
+
return (
|
|
65
|
+
<div
|
|
66
|
+
data-slot="field-group"
|
|
67
|
+
className={cn(
|
|
68
|
+
"gap-5 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4 group/field-group @container/field-group flex w-full flex-col",
|
|
69
|
+
className,
|
|
70
|
+
)}
|
|
71
|
+
{...props}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const FieldControl = FieldPrimitive.Control;
|
|
77
|
+
const FieldValidity = FieldPrimitive.Validity;
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
Field,
|
|
81
|
+
FieldLabel,
|
|
82
|
+
FieldDescription,
|
|
83
|
+
FieldError,
|
|
84
|
+
FieldControl,
|
|
85
|
+
FieldItem,
|
|
86
|
+
FieldValidity,
|
|
87
|
+
FieldGroup,
|
|
88
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Fieldset as FieldsetPrimitive } from "@base-ui/react/fieldset";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../../lib/utils/css";
|
|
6
|
+
|
|
7
|
+
function Fieldset({ className, ...props }: FieldsetPrimitive.Root.Props) {
|
|
8
|
+
return (
|
|
9
|
+
<FieldsetPrimitive.Root
|
|
10
|
+
className={cn("flex w-full max-w-64 flex-col gap-6", className)}
|
|
11
|
+
data-slot="fieldset"
|
|
12
|
+
{...props}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
function FieldsetLegend({
|
|
17
|
+
className,
|
|
18
|
+
...props
|
|
19
|
+
}: FieldsetPrimitive.Legend.Props) {
|
|
20
|
+
return (
|
|
21
|
+
<FieldsetPrimitive.Legend
|
|
22
|
+
className={cn("font-semibold text-foreground", className)}
|
|
23
|
+
data-slot="fieldset-legend"
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { Fieldset, FieldsetLegend };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Form as FormPrimitive } from "@base-ui/react/form";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../../lib/utils/css";
|
|
6
|
+
|
|
7
|
+
function Form({ className, ...props }: FormPrimitive.Props) {
|
|
8
|
+
return (
|
|
9
|
+
<FormPrimitive
|
|
10
|
+
className={cn("flex w-full flex-col gap-4", className)}
|
|
11
|
+
data-slot="form"
|
|
12
|
+
{...props}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { Form };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils/css";
|
|
4
|
+
|
|
5
|
+
function Frame({ className, ...props }: React.ComponentProps<"div">) {
|
|
6
|
+
return (
|
|
7
|
+
<div
|
|
8
|
+
className={cn(
|
|
9
|
+
"relative flex flex-col rounded-2xl bg-muted/72 p-1",
|
|
10
|
+
"*:[[data-slot=frame-panel]+[data-slot=frame-panel]]:mt-1",
|
|
11
|
+
className,
|
|
12
|
+
)}
|
|
13
|
+
data-slot="frame"
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function FramePanel({ className, ...props }: React.ComponentProps<"div">) {
|
|
20
|
+
return (
|
|
21
|
+
<div
|
|
22
|
+
className={cn(
|
|
23
|
+
"relative rounded-xl border bg-background bg-clip-padding p-5 shadow-xs/5 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-xl)-1px)] before:shadow-[0_1px_--theme(--color-black/6%)] dark:before:shadow-[0_-1px_--theme(--color-white/6%)]",
|
|
24
|
+
className,
|
|
25
|
+
)}
|
|
26
|
+
data-slot="frame-panel"
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function FrameHeader({ className, ...props }: React.ComponentProps<"header">) {
|
|
33
|
+
return (
|
|
34
|
+
<header
|
|
35
|
+
className={cn("flex flex-col px-5 py-4", className)}
|
|
36
|
+
data-slot="frame-panel-header"
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function FrameTitle({ className, ...props }: React.ComponentProps<"div">) {
|
|
43
|
+
return (
|
|
44
|
+
<div
|
|
45
|
+
className={cn("font-semibold text-sm", className)}
|
|
46
|
+
data-slot="frame-panel-title"
|
|
47
|
+
{...props}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function FrameDescription({
|
|
53
|
+
className,
|
|
54
|
+
...props
|
|
55
|
+
}: React.ComponentProps<"div">) {
|
|
56
|
+
return (
|
|
57
|
+
<div
|
|
58
|
+
className={cn("text-muted-foreground text-sm", className)}
|
|
59
|
+
data-slot="frame-panel-description"
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function FrameFooter({ className, ...props }: React.ComponentProps<"footer">) {
|
|
66
|
+
return (
|
|
67
|
+
<footer
|
|
68
|
+
className={cn("px-5 py-4", className)}
|
|
69
|
+
data-slot="frame-panel-footer"
|
|
70
|
+
{...props}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export {
|
|
76
|
+
Frame,
|
|
77
|
+
FramePanel,
|
|
78
|
+
FrameHeader,
|
|
79
|
+
FrameTitle,
|
|
80
|
+
FrameDescription,
|
|
81
|
+
FrameFooter,
|
|
82
|
+
};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FileQuestionIcon,
|
|
3
|
+
ShieldAlertIcon,
|
|
4
|
+
ShieldXIcon,
|
|
5
|
+
TriangleAlertIcon,
|
|
6
|
+
} from "lucide-react";
|
|
7
|
+
import type React from "react";
|
|
8
|
+
import {
|
|
9
|
+
Empty,
|
|
10
|
+
EmptyContent,
|
|
11
|
+
EmptyDescription,
|
|
12
|
+
EmptyHeader,
|
|
13
|
+
EmptyMedia,
|
|
14
|
+
EmptyTitle,
|
|
15
|
+
} from "./empty";
|
|
16
|
+
|
|
17
|
+
interface ErrorOrEmptyStateProps
|
|
18
|
+
extends Omit<React.ComponentProps<"div">, "title"> {
|
|
19
|
+
title?: React.ReactNode;
|
|
20
|
+
description?: React.ReactNode;
|
|
21
|
+
actions?: React.ReactNode;
|
|
22
|
+
media?: React.ReactNode;
|
|
23
|
+
mediaVariant?: "icon" | "default";
|
|
24
|
+
compact?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function ErrorOrEmptyState({
|
|
28
|
+
title,
|
|
29
|
+
description,
|
|
30
|
+
actions,
|
|
31
|
+
className,
|
|
32
|
+
media,
|
|
33
|
+
mediaVariant = "default",
|
|
34
|
+
compact,
|
|
35
|
+
...props
|
|
36
|
+
}: ErrorOrEmptyStateProps) {
|
|
37
|
+
return (
|
|
38
|
+
<Empty {...props}>
|
|
39
|
+
<EmptyHeader>
|
|
40
|
+
{!compact && <EmptyMedia variant={mediaVariant}>{media}</EmptyMedia>}
|
|
41
|
+
<EmptyTitle>{title}</EmptyTitle>
|
|
42
|
+
<EmptyDescription>{description}</EmptyDescription>
|
|
43
|
+
</EmptyHeader>
|
|
44
|
+
<EmptyContent>{actions}</EmptyContent>
|
|
45
|
+
</Empty>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type ErrorTemplateProps = Omit<
|
|
50
|
+
ErrorOrEmptyStateProps,
|
|
51
|
+
"image" | "title" | "description"
|
|
52
|
+
> & {
|
|
53
|
+
mediaClassName?: string;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
function NotFoundErrorState({ mediaClassName, ...props }: ErrorTemplateProps) {
|
|
57
|
+
return (
|
|
58
|
+
<ErrorOrEmptyState
|
|
59
|
+
media={<FileQuestionIcon className={mediaClassName} />}
|
|
60
|
+
mediaVariant="icon"
|
|
61
|
+
title="Not found"
|
|
62
|
+
description="The requested resource was not found."
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function UnauthorizedErrorState({
|
|
69
|
+
mediaClassName,
|
|
70
|
+
...props
|
|
71
|
+
}: ErrorTemplateProps) {
|
|
72
|
+
return (
|
|
73
|
+
<ErrorOrEmptyState
|
|
74
|
+
media={<ShieldAlertIcon className={mediaClassName} />}
|
|
75
|
+
mediaVariant="icon"
|
|
76
|
+
title="Unauthorized"
|
|
77
|
+
description="You are not authorized to access this resource."
|
|
78
|
+
{...props}
|
|
79
|
+
/>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function ForbiddenErrorState({ mediaClassName, ...props }: ErrorTemplateProps) {
|
|
84
|
+
return (
|
|
85
|
+
<ErrorOrEmptyState
|
|
86
|
+
media={<ShieldXIcon className={mediaClassName} />}
|
|
87
|
+
mediaVariant="icon"
|
|
88
|
+
title="Forbidden"
|
|
89
|
+
description="You are not allowed to access this resource."
|
|
90
|
+
{...props}
|
|
91
|
+
/>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function InternalServerErrorState({
|
|
96
|
+
mediaClassName,
|
|
97
|
+
...props
|
|
98
|
+
}: ErrorTemplateProps) {
|
|
99
|
+
return (
|
|
100
|
+
<ErrorOrEmptyState
|
|
101
|
+
media={<ShieldXIcon className={mediaClassName} />}
|
|
102
|
+
mediaVariant="icon"
|
|
103
|
+
title="Internal server error"
|
|
104
|
+
description="An error occurred while processing your request."
|
|
105
|
+
{...props}
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function OfflineErrorState({ mediaClassName, ...props }: ErrorTemplateProps) {
|
|
111
|
+
return (
|
|
112
|
+
<ErrorOrEmptyState
|
|
113
|
+
media={<ShieldXIcon className={mediaClassName} />}
|
|
114
|
+
mediaVariant="icon"
|
|
115
|
+
title="Offline"
|
|
116
|
+
description="Please check your internet connection and try again."
|
|
117
|
+
{...props}
|
|
118
|
+
/>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function GeneralErrorState({ mediaClassName, ...props }: ErrorTemplateProps) {
|
|
123
|
+
return (
|
|
124
|
+
<ErrorOrEmptyState
|
|
125
|
+
media={<TriangleAlertIcon className={mediaClassName} />}
|
|
126
|
+
mediaVariant="icon"
|
|
127
|
+
title="Error"
|
|
128
|
+
description="An error occurred while processing your request."
|
|
129
|
+
{...props}
|
|
130
|
+
/>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export {
|
|
135
|
+
ErrorOrEmptyState,
|
|
136
|
+
NotFoundErrorState,
|
|
137
|
+
UnauthorizedErrorState,
|
|
138
|
+
ForbiddenErrorState,
|
|
139
|
+
InternalServerErrorState,
|
|
140
|
+
OfflineErrorState,
|
|
141
|
+
GeneralErrorState,
|
|
142
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
4
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
5
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
6
|
+
import type * as React from "react";
|
|
7
|
+
import { Separator } from "./separator";
|
|
8
|
+
import { cn } from "../../lib/utils/css";
|
|
9
|
+
|
|
10
|
+
const groupVariants = cva(
|
|
11
|
+
"flex w-fit *:focus-visible:z-1 has-[>[data-slot=group]]:gap-2 *:has-focus-visible:z-1 dark:*:[[data-slot=button]:hover~[data-slot=separator]:not([data-slot]:hover~[data-slot=separator]~[data-slot=separator]),[data-slot][data-pressed]~[data-slot=separator]:not([data-slot][data-pressed]~[data-slot=separator]~[data-slot=separator])]:before:bg-input/64 dark:*:[[data-slot=separator]:has(~[data-slot=button]:hover):not(:has(~[data-slot=separator]~[data-slot]:hover)),[data-slot=separator]:has(~[data-slot][data-pressed]):not(:has(~[data-slot=separator]~[data-slot][data-pressed]))]:before:bg-input/64",
|
|
12
|
+
{
|
|
13
|
+
defaultVariants: {
|
|
14
|
+
orientation: "horizontal",
|
|
15
|
+
},
|
|
16
|
+
variants: {
|
|
17
|
+
orientation: {
|
|
18
|
+
horizontal:
|
|
19
|
+
"*:[[data-slot]~[data-slot]:not([data-slot=separator])]:before:-start-[0.5px] *:data-slot:not-data-[slot=separator]:has-[~[data-slot]]:before:-end-[0.5px] *:pointer-coarse:after:min-w-auto *:data-slot:has-[~[data-slot]]:rounded-e-none *:data-slot:has-[~[data-slot]]:border-e-0 *:data-slot:has-[~[data-slot]]:before:rounded-e-none *:[[data-slot]~[data-slot]]:rounded-s-none *:[[data-slot]~[data-slot]]:border-s-0 *:[[data-slot]~[data-slot]]:before:rounded-s-none",
|
|
20
|
+
vertical:
|
|
21
|
+
"*:[[data-slot]~[data-slot]:not([data-slot=separator])]:before:-top-[0.5px] *:data-slot:not-data-[slot=separator]:has-[~[data-slot]]:before:-bottom-[0.5px] flex-col *:pointer-coarse:after:min-h-auto *:data-slot:has-[~[data-slot]]:rounded-b-none *:data-slot:has-[~[data-slot]]:border-b-0 *:data-slot:not-data-[slot=separator]:has-[~[data-slot]]:before:hidden *:data-slot:has-[~[data-slot]]:before:rounded-b-none dark:*:last:before:hidden dark:*:first:before:block *:[[data-slot]~[data-slot]]:rounded-t-none *:[[data-slot]~[data-slot]]:border-t-0 *:[[data-slot]~[data-slot]]:before:rounded-t-none",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
function Group({
|
|
28
|
+
className,
|
|
29
|
+
orientation,
|
|
30
|
+
children,
|
|
31
|
+
...props
|
|
32
|
+
}: {
|
|
33
|
+
className?: string;
|
|
34
|
+
orientation?: VariantProps<typeof groupVariants>["orientation"];
|
|
35
|
+
children: React.ReactNode;
|
|
36
|
+
} & React.ComponentProps<"div">) {
|
|
37
|
+
return (
|
|
38
|
+
// biome-ignore lint/a11y/useSemanticElements: Imported from library
|
|
39
|
+
<div
|
|
40
|
+
className={cn(groupVariants({ orientation }), className)}
|
|
41
|
+
data-orientation={orientation}
|
|
42
|
+
data-slot="group"
|
|
43
|
+
role="group"
|
|
44
|
+
{...props}
|
|
45
|
+
>
|
|
46
|
+
{children}
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function GroupText({
|
|
52
|
+
className,
|
|
53
|
+
render,
|
|
54
|
+
...props
|
|
55
|
+
}: useRender.ComponentProps<"div">) {
|
|
56
|
+
const defaultProps = {
|
|
57
|
+
className: cn(
|
|
58
|
+
"relative inline-flex items-center whitespace-nowrap gap-2 rounded-lg border border-input bg-muted not-dark:bg-clip-padding px-[calc(--spacing(3)-1px)] text-muted-foreground text-base sm:text-sm shadow-xs/5 outline-none transition-shadow before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] before:shadow-[0_1px_--theme(--color-black/6%)] dark:bg-input/64 dark:before:shadow-[0_-1px_--theme(--color-white/6%)] [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 [&_svg]:-mx-0.5",
|
|
59
|
+
className,
|
|
60
|
+
),
|
|
61
|
+
"data-slot": "group-text",
|
|
62
|
+
};
|
|
63
|
+
return useRender({
|
|
64
|
+
defaultTagName: "div",
|
|
65
|
+
props: mergeProps(defaultProps, props),
|
|
66
|
+
render,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function GroupSeparator({
|
|
71
|
+
className,
|
|
72
|
+
orientation = "vertical",
|
|
73
|
+
...props
|
|
74
|
+
}: {
|
|
75
|
+
className?: string;
|
|
76
|
+
} & React.ComponentProps<typeof Separator>) {
|
|
77
|
+
return (
|
|
78
|
+
<Separator
|
|
79
|
+
className={cn(
|
|
80
|
+
"[[data-slot=input-control]:focus-within+&,[data-slot=input-group]:focus-within+&,[data-slot=select-trigger]:focus-visible+*+&,[data-slot=number-field]:focus-within+input+&]:-translate-x-px pointer-events-none relative z-2 bg-input before:absolute before:inset-0 has-[+[data-slot=input-control]:focus-within,+[data-slot=input-group]:focus-within,+[data-slot=select-trigger]:focus-visible+*,+[data-slot=number-field]:focus-within]:translate-x-px has-[+[data-slot=input-control]:focus-within,+[data-slot=input-group]:focus-within,+[data-slot=select-trigger]:focus-visible+*,+[data-slot=number-field]:focus-within]:bg-ring dark:before:bg-input/32 [[data-slot=input-control]:focus-within+&,[data-slot=input-group]:focus-within+&,[data-slot=select-trigger]:focus-visible+*+&,[data-slot=number-field]:focus-within+&,[data-slot=number-field]:focus-within+input+&]:bg-ring",
|
|
81
|
+
className,
|
|
82
|
+
)}
|
|
83
|
+
orientation={orientation}
|
|
84
|
+
{...props}
|
|
85
|
+
/>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
Group,
|
|
91
|
+
Group as ButtonGroup,
|
|
92
|
+
GroupText,
|
|
93
|
+
GroupText as ButtonGroupText,
|
|
94
|
+
GroupSeparator,
|
|
95
|
+
GroupSeparator as ButtonGroupSeparator,
|
|
96
|
+
groupVariants,
|
|
97
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { CircleHelp } from "lucide-react";
|
|
4
|
+
import type * as React from "react";
|
|
5
|
+
|
|
6
|
+
import { cn } from "../../lib/utils/css";
|
|
7
|
+
import {
|
|
8
|
+
Tooltip,
|
|
9
|
+
TooltipDescription,
|
|
10
|
+
TooltipPopup,
|
|
11
|
+
TooltipProvider,
|
|
12
|
+
TooltipTitle,
|
|
13
|
+
TooltipTrigger,
|
|
14
|
+
} from "./tooltip";
|
|
15
|
+
|
|
16
|
+
export interface HelpTipProps {
|
|
17
|
+
/** The help text shown in the tooltip. */
|
|
18
|
+
children?: React.ReactNode;
|
|
19
|
+
/** Optional bold heading rendered above the description text. */
|
|
20
|
+
title?: React.ReactNode;
|
|
21
|
+
/** Which side of the trigger the tooltip opens on. Default "top". */
|
|
22
|
+
side?: React.ComponentProps<typeof TooltipPopup>["side"];
|
|
23
|
+
/** Alignment of the tooltip along the trigger. Default "center". */
|
|
24
|
+
align?: React.ComponentProps<typeof TooltipPopup>["align"];
|
|
25
|
+
/** Accessible label for the icon button. Default "More information". */
|
|
26
|
+
label?: string;
|
|
27
|
+
/** Hover / focus open delay in ms. Default 150. */
|
|
28
|
+
delay?: number;
|
|
29
|
+
/** Icon size in px. Default 16. */
|
|
30
|
+
iconSize?: number;
|
|
31
|
+
/** Extra classes for the trigger button. */
|
|
32
|
+
className?: string;
|
|
33
|
+
/** Extra classes for the tooltip popup. */
|
|
34
|
+
popupClassName?: string;
|
|
35
|
+
/** Render the little arrow pointing at the icon. Default false. */
|
|
36
|
+
arrow?: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A small "?" help affordance: an unobtrusive circular icon that reveals
|
|
41
|
+
* supporting text in a tooltip on hover / focus. Use it next to a label,
|
|
42
|
+
* heading, or field when a short explanation would help but shouldn't take up
|
|
43
|
+
* permanent space.
|
|
44
|
+
*
|
|
45
|
+
* ```tsx
|
|
46
|
+
* <span className="flex items-center gap-1.5">
|
|
47
|
+
* My Events
|
|
48
|
+
* <HelpTip>Every event Country Club has surfaced for you…</HelpTip>
|
|
49
|
+
* </span>
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export function HelpTip({
|
|
53
|
+
children,
|
|
54
|
+
title,
|
|
55
|
+
side = "top",
|
|
56
|
+
align = "center",
|
|
57
|
+
label = "More information",
|
|
58
|
+
delay = 150,
|
|
59
|
+
iconSize = 16,
|
|
60
|
+
className,
|
|
61
|
+
popupClassName,
|
|
62
|
+
arrow = false,
|
|
63
|
+
}: HelpTipProps) {
|
|
64
|
+
return (
|
|
65
|
+
<TooltipProvider delay={delay}>
|
|
66
|
+
<Tooltip>
|
|
67
|
+
<TooltipTrigger
|
|
68
|
+
aria-label={label}
|
|
69
|
+
className={cn(
|
|
70
|
+
"inline-flex shrink-0 cursor-help items-center justify-center rounded-full text-muted-foreground outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring",
|
|
71
|
+
className,
|
|
72
|
+
)}
|
|
73
|
+
>
|
|
74
|
+
<CircleHelp aria-hidden size={iconSize} />
|
|
75
|
+
</TooltipTrigger>
|
|
76
|
+
<TooltipPopup
|
|
77
|
+
align={align}
|
|
78
|
+
arrow={arrow}
|
|
79
|
+
className={cn("max-w-64 [--viewport-inline-padding:--spacing(3)]", popupClassName)}
|
|
80
|
+
side={side}
|
|
81
|
+
>
|
|
82
|
+
{title ? (
|
|
83
|
+
<div className="flex flex-col gap-0.5 py-0.5">
|
|
84
|
+
<TooltipTitle>{title}</TooltipTitle>
|
|
85
|
+
<TooltipDescription className="text-popover-foreground">{children}</TooltipDescription>
|
|
86
|
+
</div>
|
|
87
|
+
) : (
|
|
88
|
+
<div className="py-0.5 leading-snug">{children}</div>
|
|
89
|
+
)}
|
|
90
|
+
</TooltipPopup>
|
|
91
|
+
</Tooltip>
|
|
92
|
+
</TooltipProvider>
|
|
93
|
+
);
|
|
94
|
+
}
|