@tangle-network/ui 11.35.0 → 11.36.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/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -1
- package/dist/lib/control-presentation.d.ts +34 -1
- package/dist/lib/control-presentation.js +1 -1
- package/dist/lib/focus.d.ts +2 -2
- package/dist/lib/focus.js +3 -2
- package/dist/lib/motion.d.ts +4 -0
- package/dist/lib/motion.js +7 -0
- package/dist/lib/surface-motion.js +84 -0
- package/dist/presentation.d.ts +88 -0
- package/dist/presentation.js +183 -0
- package/dist/primitives/alert-dialog.js +1 -1
- package/dist/primitives/alert.d.ts +1 -2
- package/dist/primitives/button.d.ts +2 -5
- package/dist/primitives/button.js +3 -30
- package/dist/primitives/card.js +3 -7
- package/dist/primitives/date-picker.d.ts +1 -1
- package/dist/primitives/dialog.js +29 -16
- package/dist/primitives/empty-state.js +6 -5
- package/dist/primitives/heading.d.ts +1 -0
- package/dist/primitives/heading.js +3 -2
- package/dist/primitives/help-text.js +2 -1
- package/dist/primitives/input.d.ts +1 -4
- package/dist/primitives/input.js +3 -24
- package/dist/primitives/label.js +1 -2
- package/dist/primitives/metric-strip.js +7 -12
- package/dist/primitives/page-header.d.ts +1 -0
- package/dist/primitives/page-header.js +7 -6
- package/dist/primitives/page-shell.d.ts +8 -2
- package/dist/primitives/page-shell.js +21 -2
- package/dist/primitives/pagination.js +1 -1
- package/dist/primitives/sheet.js +29 -19
- package/dist/primitives/skeleton.js +1 -1
- package/dist/primitives/status-pill.d.ts +3 -1
- package/dist/primitives/status-pill.js +12 -3
- package/dist/primitives/table.js +10 -9
- package/dist/primitives/tabs.js +3 -12
- package/dist/primitives/tooltip.js +11 -3
- package/dist/primitives.d.ts +3 -2
- package/dist/primitives.js +2 -1
- package/dist/utils.d.ts +1 -1
- package/package.json +15 -5
- package/src/lib/control-presentation.ts +2 -4
- package/src/lib/focus.ts +3 -2
- package/src/lib/motion.ts +7 -0
- package/src/lib/surface-motion.tsx +78 -0
- package/src/presentation.ts +205 -0
- package/src/primitives/alert.tsx +1 -2
- package/src/primitives/button.tsx +4 -40
- package/src/primitives/card.tsx +5 -10
- package/src/primitives/checkbox-separator-sheet-tooltip.test.tsx +2 -1
- package/src/primitives/control-presentation.test.tsx +2 -7
- package/src/primitives/dialog.tsx +19 -18
- package/src/primitives/empty-state.tsx +6 -5
- package/src/primitives/heading.tsx +4 -2
- package/src/primitives/help-text.tsx +3 -2
- package/src/primitives/input.tsx +3 -31
- package/src/primitives/label.tsx +2 -4
- package/src/primitives/metric-strip.tsx +8 -17
- package/src/primitives/page-header.tsx +8 -5
- package/src/primitives/page-shell.tsx +13 -2
- package/src/primitives/sheet.tsx +16 -11
- package/src/primitives/skeleton.tsx +1 -1
- package/src/primitives/status-pill.test.tsx +1 -0
- package/src/primitives/status-pill.tsx +10 -4
- package/src/primitives/table.tsx +10 -9
- package/src/primitives/tabs.tsx +5 -17
- package/src/primitives/tooltip.tsx +6 -5
- package/src/styles/compat.css +12 -0
- package/src/styles/presentation.css +30 -0
- package/src/primitives/page-shell.test.tsx +0 -24
|
@@ -1,40 +1,11 @@
|
|
|
1
1
|
import { ixControl, ixControlSoft, ixSelected } from "../lib/interaction.js";
|
|
2
2
|
import { focusRing } from "../lib/focus.js";
|
|
3
3
|
import { cn } from "../lib/utils.js";
|
|
4
|
-
import {
|
|
4
|
+
import { buttonVariants } from "../presentation.js";
|
|
5
5
|
import { Slot } from "@radix-ui/react-slot";
|
|
6
|
-
import { cva } from "class-variance-authority";
|
|
7
6
|
import * as React from "react";
|
|
8
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
8
|
//#region src/primitives/button.tsx
|
|
10
|
-
const buttonVariants = cva(`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg font-medium transition-[color,background-color,border-color,box-shadow,transform,scale] ${controlMotion} ${focusRing} disabled:pointer-events-none disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 motion-reduce:active:scale-100 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0`, {
|
|
11
|
-
variants: {
|
|
12
|
-
variant: {
|
|
13
|
-
default: `bg-primary text-primary-foreground hover:bg-primary/90 active:scale-[0.97] ${ixControl}`,
|
|
14
|
-
destructive: `bg-destructive text-destructive-foreground hover:bg-destructive/90 active:scale-[0.97] ${ixControl}`,
|
|
15
|
-
outline: `border border-border bg-card hover:bg-muted active:scale-[0.97] text-foreground ${ixControl}`,
|
|
16
|
-
secondary: `bg-muted border border-border text-foreground hover:bg-muted/80 active:scale-[0.97] ${ixControl}`,
|
|
17
|
-
ghost: `hover:text-foreground text-muted-foreground border border-transparent ${ixControlSoft}`,
|
|
18
|
-
link: `text-[var(--accent-text)] underline-offset-4 hover:underline ${ixControlSoft}`,
|
|
19
|
-
sandbox: `bg-[var(--btn-primary-bg)] text-[var(--btn-primary-text)] border border-[var(--border-accent)] hover:bg-[var(--btn-primary-hover)] active:scale-[0.97] ${ixControl}`
|
|
20
|
-
},
|
|
21
|
-
size: {
|
|
22
|
-
default: `${controlHeight.md} ${controlText.md} ${controlRadius.md} px-4 py-2`,
|
|
23
|
-
md: `${controlHeight.md} ${controlText.md} ${controlRadius.md} px-4 py-2`,
|
|
24
|
-
sm: `${controlHeight.sm} ${controlText.sm} ${controlRadius.sm} px-3`,
|
|
25
|
-
lg: `${controlHeight.lg} ${controlText.lg} ${controlRadius.lg} px-7`,
|
|
26
|
-
xl: "h-13 rounded-xl px-9 text-base",
|
|
27
|
-
icon: `${controlSquare.md} ${controlText.md} ${controlRadius.md}`,
|
|
28
|
-
"icon-sm": `${controlSquare.sm} ${controlText.sm} ${controlRadius.sm}`,
|
|
29
|
-
"icon-lg": `${controlSquare.lg} ${controlText.lg} ${controlRadius.lg}`,
|
|
30
|
-
...controlSizes
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
defaultVariants: {
|
|
34
|
-
variant: "default",
|
|
35
|
-
size: "default"
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
9
|
const bareButton = `${focusRing} ${ixControlSoft} disabled:pointer-events-none disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50`;
|
|
39
10
|
/** One Button render's classes: variant and size, the toggle states, then the caller's. */
|
|
40
11
|
function buttonClassName(variant, size, pressed, className) {
|
|
@@ -72,6 +43,7 @@ const Button = React.forwardRef(({ className, variant, size, asChild = false, lo
|
|
|
72
43
|
return /* @__PURE__ */ jsx(Slot, {
|
|
73
44
|
className: buttonClassName(variant, size, props["aria-pressed"], className),
|
|
74
45
|
ref,
|
|
46
|
+
"data-variant": size === "display" ? variant ?? "default" : void 0,
|
|
75
47
|
...props,
|
|
76
48
|
...isDisabled ? disabledHandlers(props) : {},
|
|
77
49
|
children: child ? React.cloneElement(child, {
|
|
@@ -91,6 +63,7 @@ const Button = React.forwardRef(({ className, variant, size, asChild = false, lo
|
|
|
91
63
|
return /* @__PURE__ */ jsxs("button", {
|
|
92
64
|
className: buttonClassName(variant, size, props["aria-pressed"], className),
|
|
93
65
|
ref,
|
|
66
|
+
"data-variant": size === "display" ? variant ?? "default" : void 0,
|
|
94
67
|
...props,
|
|
95
68
|
disabled: disabled || loading,
|
|
96
69
|
"aria-busy": loading || props["aria-busy"],
|
package/dist/primitives/card.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "../lib/interaction.js";
|
|
2
2
|
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { cardPresentation } from "../presentation.js";
|
|
3
4
|
import { Heading } from "./heading.js";
|
|
4
5
|
import * as React from "react";
|
|
5
6
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -15,12 +16,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
15
16
|
const Card = React.forwardRef(({ className, variant = "default", hover = false, interactive = false, ...props }, ref) => {
|
|
16
17
|
return /* @__PURE__ */ jsx("div", {
|
|
17
18
|
ref,
|
|
18
|
-
className: cn("
|
|
19
|
-
default: "bg-card border-border shadow-[var(--edge-highlight),var(--shadow-card)]",
|
|
20
|
-
elevated: "bg-muted/50 border-border shadow-[var(--shadow-card)]",
|
|
21
|
-
glass: "bg-card/80 backdrop-blur-xl border-border shadow-[var(--shadow-card)]",
|
|
22
|
-
sandbox: "bg-muted/50 border-primary/20 shadow-[var(--shadow-accent)]"
|
|
23
|
-
}[variant], (hover || interactive) && "hover:border-[var(--ix-hover-border)] hover:shadow-[var(--ix-hover)] focus:not-focus-visible:border-[var(--ix-hover-border)] focus:not-focus-visible:shadow-[var(--ix-after)] active:border-[hsl(var(--hsl-ring))] active:shadow-[var(--ix-press)] focus-visible:shadow-none", className),
|
|
19
|
+
className: cn(cardPresentation.root, cardPresentation.variants[variant], (hover || interactive) && "hover:border-[var(--ix-hover-border)] hover:shadow-[var(--ix-hover)] focus:not-focus-visible:border-[var(--ix-hover-border)] focus:not-focus-visible:shadow-[var(--ix-after)] active:border-[hsl(var(--hsl-ring))] active:shadow-[var(--ix-press)] focus-visible:shadow-none", className),
|
|
24
20
|
"data-slot": "card",
|
|
25
21
|
...props
|
|
26
22
|
});
|
|
@@ -48,7 +44,7 @@ const CardDescription = React.forwardRef(({ className, ...props }, ref) => /* @_
|
|
|
48
44
|
CardDescription.displayName = "CardDescription";
|
|
49
45
|
const CardContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
|
|
50
46
|
ref,
|
|
51
|
-
className: cn("
|
|
47
|
+
className: cn(cardPresentation.padding, "[&:not(:first-child)]:pt-0", className),
|
|
52
48
|
...props
|
|
53
49
|
}));
|
|
54
50
|
CardContent.displayName = "CardContent";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CalendarDate, CalendarProps } from "./calendar.js";
|
|
2
1
|
import { ControlSize } from "../lib/control-presentation.js";
|
|
2
|
+
import { CalendarDate, CalendarProps } from "./calendar.js";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
//#region src/primitives/date-picker.d.ts
|
|
5
5
|
export interface DatePickerProps extends Pick<CalendarProps, "min" | "max" | "isDateDisabled" | "today" | "weekStartsOn" | "locale" | "defaultMonth"> {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { focusRing } from "../lib/focus.js";
|
|
2
2
|
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { dialogPresentation } from "../presentation.js";
|
|
4
|
+
import { SurfaceMotion } from "../lib/surface-motion.js";
|
|
3
5
|
import * as React from "react";
|
|
4
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
7
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
@@ -9,49 +11,60 @@ const Dialog = DialogPrimitive.Root;
|
|
|
9
11
|
const DialogTrigger = DialogPrimitive.Trigger;
|
|
10
12
|
const DialogPortal = DialogPrimitive.Portal;
|
|
11
13
|
const DialogClose = DialogPrimitive.Close;
|
|
12
|
-
const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Overlay, {
|
|
14
|
+
const DialogOverlay = React.forwardRef(({ className, asChild, children, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Overlay, {
|
|
13
15
|
ref,
|
|
14
|
-
className: cn(
|
|
15
|
-
...props
|
|
16
|
+
className: cn(dialogPresentation.overlay, dialogPresentation.transition, className),
|
|
17
|
+
...props,
|
|
18
|
+
asChild: true,
|
|
19
|
+
children: /* @__PURE__ */ jsx(SurfaceMotion, {
|
|
20
|
+
kind: "overlay",
|
|
21
|
+
asChild,
|
|
22
|
+
children
|
|
23
|
+
})
|
|
16
24
|
}));
|
|
17
25
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
18
|
-
const DialogContent = React.forwardRef(({ className, children, variant = "default", hideCloseButton = false, ...props }, ref) => {
|
|
19
|
-
return /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */
|
|
26
|
+
const DialogContent = React.forwardRef(({ className, children, variant = "default", hideCloseButton = false, asChild, ...props }, ref) => {
|
|
27
|
+
return /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsx(DialogPrimitive.Content, {
|
|
20
28
|
ref,
|
|
21
|
-
className: cn(
|
|
29
|
+
className: cn(dialogPresentation.position, dialogPresentation.surface, dialogPresentation.transition, {
|
|
22
30
|
default: "border-border",
|
|
23
31
|
sandbox: "border-[var(--border-accent)] shadow-[var(--shadow-accent)]"
|
|
24
32
|
}[variant], className),
|
|
25
33
|
...props,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
asChild: true,
|
|
35
|
+
children: /* @__PURE__ */ jsxs(SurfaceMotion, {
|
|
36
|
+
kind: "dialog",
|
|
37
|
+
asChild,
|
|
38
|
+
children: [children, !hideCloseButton && /* @__PURE__ */ jsxs(DialogPrimitive.Close, {
|
|
39
|
+
className: cn(dialogPresentation.close, focusRing),
|
|
40
|
+
children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
|
|
41
|
+
className: "sr-only",
|
|
42
|
+
children: "Close"
|
|
43
|
+
})]
|
|
31
44
|
})]
|
|
32
|
-
})
|
|
45
|
+
})
|
|
33
46
|
})] });
|
|
34
47
|
});
|
|
35
48
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
36
49
|
const DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
37
|
-
className: cn(
|
|
50
|
+
className: cn(dialogPresentation.header, className),
|
|
38
51
|
...props
|
|
39
52
|
});
|
|
40
53
|
DialogHeader.displayName = "DialogHeader";
|
|
41
54
|
const DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
42
|
-
className: cn(
|
|
55
|
+
className: cn(dialogPresentation.footer, className),
|
|
43
56
|
...props
|
|
44
57
|
});
|
|
45
58
|
DialogFooter.displayName = "DialogFooter";
|
|
46
59
|
const DialogTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, {
|
|
47
60
|
ref,
|
|
48
|
-
className: cn(
|
|
61
|
+
className: cn(dialogPresentation.title, className),
|
|
49
62
|
...props
|
|
50
63
|
}));
|
|
51
64
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
52
65
|
const DialogDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, {
|
|
53
66
|
ref,
|
|
54
|
-
className: cn(
|
|
67
|
+
className: cn(dialogPresentation.description, className),
|
|
55
68
|
...props
|
|
56
69
|
}));
|
|
57
70
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { emptyStatePresentation } from "../presentation.js";
|
|
2
3
|
import * as React from "react";
|
|
3
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
5
|
//#region src/primitives/empty-state.tsx
|
|
5
6
|
const EmptyState = React.forwardRef(({ className, icon, title, description, action, titleAs: Title = "h3", ...props }, ref) => {
|
|
6
7
|
return /* @__PURE__ */ jsxs("div", {
|
|
7
8
|
ref,
|
|
8
|
-
className: cn(
|
|
9
|
+
className: cn(emptyStatePresentation.root, className),
|
|
9
10
|
...props,
|
|
10
11
|
children: [
|
|
11
12
|
icon && /* @__PURE__ */ jsx("div", {
|
|
12
|
-
className:
|
|
13
|
+
className: emptyStatePresentation.icon,
|
|
13
14
|
children: icon
|
|
14
15
|
}),
|
|
15
16
|
/* @__PURE__ */ jsx(Title, {
|
|
16
|
-
className:
|
|
17
|
+
className: emptyStatePresentation.title,
|
|
17
18
|
children: title
|
|
18
19
|
}),
|
|
19
20
|
description && /* @__PURE__ */ jsx("p", {
|
|
20
|
-
className:
|
|
21
|
+
className: emptyStatePresentation.description,
|
|
21
22
|
children: description
|
|
22
23
|
}),
|
|
23
24
|
action && /* @__PURE__ */ jsx("div", {
|
|
24
|
-
className:
|
|
25
|
+
className: emptyStatePresentation.action,
|
|
25
26
|
children: action
|
|
26
27
|
})
|
|
27
28
|
]
|
|
@@ -5,6 +5,7 @@ export type HeadingVariant = "display" | "hero" | "page" | "section" | "subsecti
|
|
|
5
5
|
export interface HeadingProps extends Omit<React.HTMLAttributes<HTMLElement>, "role"> {
|
|
6
6
|
/** Visual treatment, independent of the rendered element. Defaults to section. */
|
|
7
7
|
variant?: HeadingVariant;
|
|
8
|
+
presentation?: "operational" | "expressive";
|
|
8
9
|
/** Semantic element; changing it does not change the visual variant. */
|
|
9
10
|
as?: React.ElementType;
|
|
10
11
|
/**
|
|
@@ -22,13 +22,14 @@ const DEFAULT_TAG = {
|
|
|
22
22
|
* One renderer for page, section and card titles. Use at most one default
|
|
23
23
|
* display/page h1 per page; choose `as` according to the document hierarchy.
|
|
24
24
|
*/
|
|
25
|
-
const Heading = React.forwardRef(({ variant, role, as, className, ...props }, ref) => {
|
|
25
|
+
const Heading = React.forwardRef(({ variant, role, as, className, presentation, ...props }, ref) => {
|
|
26
26
|
const legacyVariant = role && Object.prototype.hasOwnProperty.call(VARIANT_CLASS, role) ? role : void 0;
|
|
27
27
|
const visualVariant = variant ?? legacyVariant ?? "section";
|
|
28
28
|
const Tag = as ?? DEFAULT_TAG[visualVariant];
|
|
29
29
|
return /* @__PURE__ */ jsx(Tag, {
|
|
30
30
|
ref,
|
|
31
|
-
className: cn("[overflow-wrap:anywhere]", VARIANT_CLASS[visualVariant], className),
|
|
31
|
+
className: cn("[overflow-wrap:anywhere]", presentation ? presentation === "expressive" ? "tangle-display" : "tangle-heading" : VARIANT_CLASS[visualVariant], className),
|
|
32
|
+
"data-variant": presentation ? visualVariant : void 0,
|
|
32
33
|
role: legacyVariant ? void 0 : role,
|
|
33
34
|
...props
|
|
34
35
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { helpPresentation } from "../presentation.js";
|
|
2
3
|
import * as React from "react";
|
|
3
4
|
import { jsx } from "react/jsx-runtime";
|
|
4
5
|
//#region src/primitives/help-text.tsx
|
|
@@ -10,7 +11,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
10
11
|
const HelpText = React.forwardRef(({ className, tone = "hint", ...props }, ref) => /* @__PURE__ */ jsx("p", {
|
|
11
12
|
ref,
|
|
12
13
|
"data-tone": tone,
|
|
13
|
-
className: cn(
|
|
14
|
+
className: cn(helpPresentation.root, helpPresentation[tone], className),
|
|
14
15
|
...props
|
|
15
16
|
}));
|
|
16
17
|
HelpText.displayName = "HelpText";
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
+
import { inputVariants } from "../presentation.js";
|
|
1
2
|
import { VariantProps } from "class-variance-authority";
|
|
2
3
|
import * as React from "react";
|
|
3
4
|
//#region src/primitives/input.d.ts
|
|
4
|
-
declare const inputVariants: (props?: ({
|
|
5
|
-
variant?: "default" | "error" | "sandbox" | null | undefined;
|
|
6
|
-
size?: "compact" | "default" | "lg" | "md" | "sm" | "touch" | null | undefined;
|
|
7
|
-
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
8
5
|
export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">, VariantProps<typeof inputVariants> {
|
|
9
6
|
label?: string;
|
|
10
7
|
error?: string;
|
package/dist/primitives/input.js
CHANGED
|
@@ -1,34 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import
|
|
2
|
+
import "../lib/focus.js";
|
|
3
3
|
import { cn } from "../lib/utils.js";
|
|
4
|
-
import { controlRadius,
|
|
4
|
+
import { controlRadius, controlText, fieldPresentation, fieldTouchText } from "../lib/control-presentation.js";
|
|
5
|
+
import { inputVariants } from "../presentation.js";
|
|
5
6
|
import { HelpText } from "./help-text.js";
|
|
6
7
|
import { Label } from "./label.js";
|
|
7
|
-
import { cva } from "class-variance-authority";
|
|
8
8
|
import * as React from "react";
|
|
9
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
//#region src/primitives/input.tsx
|
|
11
|
-
const inputVariants = cva(cn("flex w-full border py-1 placeholder:text-[var(--text-dim)] disabled:cursor-not-allowed disabled:opacity-50 file:border-0 file:bg-transparent file:font-medium", fieldPresentation, fieldTouchText), {
|
|
12
|
-
variants: {
|
|
13
|
-
variant: {
|
|
14
|
-
default: "",
|
|
15
|
-
sandbox: "",
|
|
16
|
-
error: focusFieldInvalid
|
|
17
|
-
},
|
|
18
|
-
size: {
|
|
19
|
-
default: fieldSizes.md,
|
|
20
|
-
md: fieldSizes.md,
|
|
21
|
-
sm: fieldSizes.sm,
|
|
22
|
-
lg: fieldSizes.lg,
|
|
23
|
-
compact: cn(fieldSizes.md, controlSizes.compact),
|
|
24
|
-
touch: cn(fieldSizes.md, controlSizes.touch)
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
defaultVariants: {
|
|
28
|
-
variant: "default",
|
|
29
|
-
size: "default"
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
11
|
function descriptionIds(...ids) {
|
|
33
12
|
return [...new Set(ids.join(" ").split(/\s+/).filter(Boolean))].join(" ") || void 0;
|
|
34
13
|
}
|
package/dist/primitives/label.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/utils.js";
|
|
3
|
-
import {
|
|
3
|
+
import { labelVariants } from "../presentation.js";
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
7
7
|
//#region src/primitives/label.tsx
|
|
8
|
-
const labelVariants = cva("font-medium text-[length:var(--font-size-label,0.875rem)] leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
|
|
9
8
|
const Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(LabelPrimitive.Root, {
|
|
10
9
|
ref,
|
|
11
10
|
className: cn(labelVariants(), className),
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { metricLayouts, metricPresentation } from "../presentation.js";
|
|
2
3
|
import { StatusPill } from "./status-pill.js";
|
|
3
4
|
import * as React from "react";
|
|
4
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
//#region src/primitives/metric-strip.tsx
|
|
6
|
-
const layouts = {
|
|
7
|
-
3: "grid-cols-2 sm:grid-cols-3 max-sm:[&>div:not(:nth-child(2n+1))]:border-l sm:[&>div:not(:nth-child(3n+1))]:border-l",
|
|
8
|
-
4: "grid-cols-2 sm:grid-cols-4 max-sm:[&>div:not(:nth-child(2n+1))]:border-l sm:[&>div:not(:nth-child(4n+1))]:border-l",
|
|
9
|
-
5: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 max-sm:[&>div:not(:nth-child(2n+1))]:border-l sm:max-lg:[&>div:not(:nth-child(3n+1))]:border-l lg:[&>div:not(:nth-child(5n+1))]:border-l",
|
|
10
|
-
6: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 max-sm:[&>div:not(:nth-child(2n+1))]:border-l sm:max-lg:[&>div:not(:nth-child(3n+1))]:border-l lg:[&>div:not(:nth-child(6n+1))]:border-l"
|
|
11
|
-
};
|
|
12
7
|
const MetricStrip = React.forwardRef(({ className, children, columns = 4, ...props }, ref) => /* @__PURE__ */ jsx("dl", {
|
|
13
8
|
ref,
|
|
14
|
-
className: cn(
|
|
9
|
+
className: cn(metricPresentation.strip, metricLayouts[columns], className),
|
|
15
10
|
...props,
|
|
16
11
|
children
|
|
17
12
|
}));
|
|
@@ -19,11 +14,11 @@ MetricStrip.displayName = "MetricStrip";
|
|
|
19
14
|
/** A described term; the strip, not this item, decides where separators belong. */
|
|
20
15
|
const Metric = React.forwardRef(({ className, label, value, hint, attention, icon, ...props }, ref) => /* @__PURE__ */ jsxs("div", {
|
|
21
16
|
ref,
|
|
22
|
-
className: cn(
|
|
17
|
+
className: cn(metricPresentation.item, className),
|
|
23
18
|
...props,
|
|
24
19
|
children: [
|
|
25
20
|
/* @__PURE__ */ jsxs("dt", {
|
|
26
|
-
className:
|
|
21
|
+
className: metricPresentation.label,
|
|
27
22
|
children: [
|
|
28
23
|
icon != null && icon !== false && /* @__PURE__ */ jsx("span", {
|
|
29
24
|
"aria-hidden": "true",
|
|
@@ -31,7 +26,7 @@ const Metric = React.forwardRef(({ className, label, value, hint, attention, ico
|
|
|
31
26
|
children: icon
|
|
32
27
|
}),
|
|
33
28
|
/* @__PURE__ */ jsx("span", {
|
|
34
|
-
className:
|
|
29
|
+
className: metricPresentation.labelText,
|
|
35
30
|
children: label
|
|
36
31
|
}),
|
|
37
32
|
attention && /* @__PURE__ */ jsx(StatusPill, {
|
|
@@ -41,12 +36,12 @@ const Metric = React.forwardRef(({ className, label, value, hint, attention, ico
|
|
|
41
36
|
]
|
|
42
37
|
}),
|
|
43
38
|
/* @__PURE__ */ jsx("dd", {
|
|
44
|
-
className: cn(
|
|
39
|
+
className: cn(metricPresentation.value, attention?.tone === "danger" && "text-[var(--surface-danger-text)]"),
|
|
45
40
|
title: typeof value === "string" ? value : void 0,
|
|
46
41
|
children: value
|
|
47
42
|
}),
|
|
48
43
|
hint !== void 0 && hint !== null && hint !== false && hint !== "" && /* @__PURE__ */ jsx("dd", {
|
|
49
|
-
className:
|
|
44
|
+
className: metricPresentation.hint,
|
|
50
45
|
title: typeof hint === "string" ? hint : void 0,
|
|
51
46
|
children: hint
|
|
52
47
|
})
|
|
@@ -7,6 +7,7 @@ import * as React from "react";
|
|
|
7
7
|
*/
|
|
8
8
|
export interface PageHeaderProps extends Omit<React.HTMLAttributes<HTMLElement>, "title"> {
|
|
9
9
|
title: React.ReactNode;
|
|
10
|
+
presentation?: "operational" | "expressive";
|
|
10
11
|
description?: React.ReactNode;
|
|
11
12
|
/** Canonical action slot. If supplied (even null), takes precedence over action. */
|
|
12
13
|
actions?: React.ReactNode;
|
|
@@ -4,14 +4,14 @@ import * as React from "react";
|
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
//#region src/primitives/page-header.tsx
|
|
6
6
|
const hasContent = (node) => Boolean(node) || node === 0;
|
|
7
|
-
const PageHeader = React.forwardRef(({ className, title, description, actions, action, eyebrow, meta, titleId, titleAs, level = 1, ...props }, ref) => {
|
|
7
|
+
const PageHeader = React.forwardRef(({ className, presentation, title, description, actions, action, eyebrow, meta, titleId, titleAs, level = 1, ...props }, ref) => {
|
|
8
8
|
const resolvedActions = actions === void 0 ? action : actions;
|
|
9
9
|
return /* @__PURE__ */ jsxs("header", {
|
|
10
10
|
ref,
|
|
11
|
-
className: cn("mb-6 min-w-0", className),
|
|
11
|
+
className: cn(presentation === "expressive" ? "tangle-intro" : presentation === "operational" ? "tangle-page-header" : "mb-6 min-w-0", className),
|
|
12
12
|
...props,
|
|
13
13
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
14
|
-
className: "flex min-w-0 flex-wrap items-start justify-between gap-x-6 gap-y-3",
|
|
14
|
+
className: presentation ? "tangle-page-header-main" : "flex min-w-0 flex-wrap items-start justify-between gap-x-6 gap-y-3",
|
|
15
15
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
16
16
|
className: "min-w-0 flex-[1_1_16rem]",
|
|
17
17
|
children: [
|
|
@@ -22,18 +22,19 @@ const PageHeader = React.forwardRef(({ className, title, description, actions, a
|
|
|
22
22
|
}),
|
|
23
23
|
/* @__PURE__ */ jsx(Heading, {
|
|
24
24
|
id: titleId,
|
|
25
|
-
variant: level === 1 ? "page" : "section",
|
|
25
|
+
variant: presentation === "expressive" ? "display" : level === 1 ? "page" : "section",
|
|
26
|
+
presentation,
|
|
26
27
|
as: titleAs ?? (level === 1 ? "h1" : "h2"),
|
|
27
28
|
className: "text-balance",
|
|
28
29
|
children: title
|
|
29
30
|
}),
|
|
30
31
|
hasContent(description) && /* @__PURE__ */ jsx("p", {
|
|
31
|
-
className: "mt-1 max-w-prose text-muted-foreground text-sm [overflow-wrap:anywhere]",
|
|
32
|
+
className: presentation === "expressive" ? "tangle-intro-description" : presentation ? "tangle-page-description" : "mt-1 max-w-prose text-muted-foreground text-sm [overflow-wrap:anywhere]",
|
|
32
33
|
children: description
|
|
33
34
|
})
|
|
34
35
|
]
|
|
35
36
|
}), hasContent(resolvedActions) && /* @__PURE__ */ jsx("div", {
|
|
36
|
-
className: "flex min-w-0 max-w-full flex-wrap items-center gap-2 [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full",
|
|
37
|
+
className: presentation === "expressive" ? "tangle-intro-actions" : "flex min-w-0 max-w-full flex-wrap items-center gap-2 [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full",
|
|
37
38
|
children: resolvedActions
|
|
38
39
|
})]
|
|
39
40
|
}), hasContent(meta) && /* @__PURE__ */ jsx("div", {
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
//#region src/primitives/page-shell.d.ts
|
|
3
3
|
export interface PageShellProps {
|
|
4
|
-
children
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
/** Optional reading layout. Content, routing and navigation interaction stay caller-owned. */
|
|
6
|
+
navigation?: ReactNode;
|
|
7
|
+
article?: ReactNode;
|
|
8
|
+
outline?: ReactNode;
|
|
9
|
+
navigationLabel?: string;
|
|
10
|
+
outlineLabel?: string;
|
|
5
11
|
className?: string;
|
|
6
12
|
}
|
|
7
13
|
/**
|
|
@@ -10,5 +16,5 @@ export interface PageShellProps {
|
|
|
10
16
|
* The caller owns landmarks, routing, auth, navigation and data state. Use
|
|
11
17
|
* className to override the bound/gutters, or omit it for a workbench layout.
|
|
12
18
|
*/
|
|
13
|
-
export declare function PageShell({ children, className }: PageShellProps): import("react").JSX.Element;
|
|
19
|
+
export declare function PageShell({ children, className, navigation, article, outline, navigationLabel, outlineLabel }: PageShellProps): import("react").JSX.Element;
|
|
14
20
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cn } from "../lib/utils.js";
|
|
2
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
//#region src/primitives/page-shell.tsx
|
|
4
4
|
/**
|
|
5
5
|
* Ported from sandbox-ui/src/primitives/page-shell.tsx. An optional bounded
|
|
@@ -7,7 +7,26 @@ import { jsx } from "react/jsx-runtime";
|
|
|
7
7
|
* The caller owns landmarks, routing, auth, navigation and data state. Use
|
|
8
8
|
* className to override the bound/gutters, or omit it for a workbench layout.
|
|
9
9
|
*/
|
|
10
|
-
function PageShell({ children, className }) {
|
|
10
|
+
function PageShell({ children, className, navigation, article, outline, navigationLabel = "Sections", outlineLabel = "On this page" }) {
|
|
11
|
+
if (navigation || article || outline) return /* @__PURE__ */ jsxs("div", {
|
|
12
|
+
className: cn("tangle-reading-shell", className),
|
|
13
|
+
children: [
|
|
14
|
+
navigation && /* @__PURE__ */ jsx("nav", {
|
|
15
|
+
"aria-label": navigationLabel,
|
|
16
|
+
className: "tangle-reading-nav",
|
|
17
|
+
children: navigation
|
|
18
|
+
}),
|
|
19
|
+
/* @__PURE__ */ jsx("article", {
|
|
20
|
+
className: "tangle-reading-article",
|
|
21
|
+
children: article ?? children
|
|
22
|
+
}),
|
|
23
|
+
outline && /* @__PURE__ */ jsx("aside", {
|
|
24
|
+
"aria-label": outlineLabel,
|
|
25
|
+
className: "tangle-reading-outline",
|
|
26
|
+
children: outline
|
|
27
|
+
})
|
|
28
|
+
]
|
|
29
|
+
});
|
|
11
30
|
return /* @__PURE__ */ jsx("div", {
|
|
12
31
|
className: cn("mx-auto min-w-0 w-full max-w-6xl space-y-8 px-6 py-8 lg:px-8", className),
|
|
13
32
|
children
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cn } from "../lib/utils.js";
|
|
2
|
-
import { buttonVariants } from "
|
|
2
|
+
import { buttonVariants } from "../presentation.js";
|
|
3
3
|
import "react";
|
|
4
4
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { ChevronLeft, ChevronRight } from "lucide-react";
|
package/dist/primitives/sheet.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { surfaceMotion } from "../lib/motion.js";
|
|
2
3
|
import { focusRing } from "../lib/focus.js";
|
|
3
4
|
import { cn } from "../lib/utils.js";
|
|
5
|
+
import { SurfaceMotion } from "../lib/surface-motion.js";
|
|
4
6
|
import { cva } from "class-variance-authority";
|
|
5
7
|
import * as React from "react";
|
|
6
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -12,36 +14,44 @@ const Sheet = SheetPrimitive.Root;
|
|
|
12
14
|
const SheetTrigger = SheetPrimitive.Trigger;
|
|
13
15
|
const SheetClose = SheetPrimitive.Close;
|
|
14
16
|
const SheetPortal = SheetPrimitive.Portal;
|
|
15
|
-
const SheetOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SheetPrimitive.Overlay, {
|
|
17
|
+
const SheetOverlay = React.forwardRef(({ className, asChild, children, ...props }, ref) => /* @__PURE__ */ jsx(SheetPrimitive.Overlay, {
|
|
16
18
|
ref,
|
|
17
|
-
className: cn("fixed inset-0 z-50 bg-black/40",
|
|
18
|
-
...props
|
|
19
|
+
className: cn("fixed inset-0 z-50 bg-black/40", surfaceMotion, className),
|
|
20
|
+
...props,
|
|
21
|
+
asChild: true,
|
|
22
|
+
children: /* @__PURE__ */ jsx(SurfaceMotion, {
|
|
23
|
+
kind: "overlay",
|
|
24
|
+
asChild,
|
|
25
|
+
children
|
|
26
|
+
})
|
|
19
27
|
}));
|
|
20
28
|
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
|
|
21
|
-
const sheetVariants = cva([
|
|
22
|
-
"fixed z-50 flex flex-col gap-4 border-border bg-card shadow-lg",
|
|
23
|
-
"data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
24
|
-
"data-[state=closed]:duration-200 data-[state=open]:duration-300 ease-out motion-reduce:animate-none"
|
|
25
|
-
], {
|
|
29
|
+
const sheetVariants = cva(["fixed z-50 flex flex-col gap-4 border-border bg-card shadow-lg", surfaceMotion], {
|
|
26
30
|
variants: { side: {
|
|
27
|
-
right: "inset-y-0 right-0 h-full w-3/4 border-l
|
|
28
|
-
left: "inset-y-0 left-0 h-full w-3/4 border-r
|
|
29
|
-
top: "inset-x-0 top-0 h-auto border-b
|
|
30
|
-
bottom: "inset-x-0 bottom-0 h-auto border-t
|
|
31
|
+
right: "inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
|
|
32
|
+
left: "inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
|
|
33
|
+
top: "inset-x-0 top-0 h-auto border-b",
|
|
34
|
+
bottom: "inset-x-0 bottom-0 h-auto border-t"
|
|
31
35
|
} },
|
|
32
36
|
defaultVariants: { side: "right" }
|
|
33
37
|
});
|
|
34
|
-
const SheetContent = React.forwardRef(({ className, children, side = "right", hideCloseButton = false, ...props }, ref) => /* @__PURE__ */ jsxs(SheetPortal, { children: [/* @__PURE__ */ jsx(SheetOverlay, {}), /* @__PURE__ */
|
|
38
|
+
const SheetContent = React.forwardRef(({ className, children, side = "right", hideCloseButton = false, asChild, ...props }, ref) => /* @__PURE__ */ jsxs(SheetPortal, { children: [/* @__PURE__ */ jsx(SheetOverlay, {}), /* @__PURE__ */ jsx(SheetPrimitive.Content, {
|
|
35
39
|
ref,
|
|
36
40
|
className: cn(sheetVariants({ side }), className),
|
|
37
41
|
...props,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
asChild: true,
|
|
43
|
+
children: /* @__PURE__ */ jsxs(SurfaceMotion, {
|
|
44
|
+
kind: "sheet",
|
|
45
|
+
side: side ?? "right",
|
|
46
|
+
asChild,
|
|
47
|
+
children: [children, !hideCloseButton && /* @__PURE__ */ jsxs(SheetPrimitive.Close, {
|
|
48
|
+
className: cn("absolute top-4 right-4 rounded-sm text-muted-foreground opacity-70 transition-[opacity,box-shadow] hover:opacity-100 focus-visible:opacity-100 disabled:pointer-events-none", "[transition:color_var(--motion-control),background-color_var(--motion-control),border-color_var(--motion-control),box-shadow_var(--motion-control),transform_var(--motion-control),scale_var(--motion-control),opacity_var(--motion-control)] motion-reduce:transition-none", focusRing),
|
|
49
|
+
children: [/* @__PURE__ */ jsx(X, { className: "size-4" }), /* @__PURE__ */ jsx("span", {
|
|
50
|
+
className: "sr-only",
|
|
51
|
+
children: "Close"
|
|
52
|
+
})]
|
|
43
53
|
})]
|
|
44
|
-
})
|
|
54
|
+
})
|
|
45
55
|
})] }));
|
|
46
56
|
SheetContent.displayName = SheetPrimitive.Content.displayName;
|
|
47
57
|
const SheetHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
@@ -3,7 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
//#region src/primitives/skeleton.tsx
|
|
4
4
|
function Skeleton({ className, ...props }) {
|
|
5
5
|
return /* @__PURE__ */ jsx("div", {
|
|
6
|
-
className: cn("animate-pulse rounded-lg bg-muted/50", className),
|
|
6
|
+
className: cn("animate-pulse motion-reduce:animate-none rounded-lg bg-muted/50", className),
|
|
7
7
|
...props
|
|
8
8
|
});
|
|
9
9
|
}
|
|
@@ -19,7 +19,7 @@ import * as React from "react";
|
|
|
19
19
|
* that always brings its own background cannot be placed onto a plane that
|
|
20
20
|
* breaks it.
|
|
21
21
|
*/
|
|
22
|
-
export type StatusTone = "success" | "warning" | "danger" | "info" | "neutral" | "running";
|
|
22
|
+
export type StatusTone = "success" | "warning" | "danger" | "info" | "neutral" | "running" | "violet";
|
|
23
23
|
export interface StatusPillProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
|
|
24
24
|
tone: StatusTone;
|
|
25
25
|
children: React.ReactNode;
|
|
@@ -37,6 +37,8 @@ export interface StatusPillProps extends Omit<React.HTMLAttributes<HTMLSpanEleme
|
|
|
37
37
|
* For a control that supplies its own surface (a chip, a selected row).
|
|
38
38
|
*/
|
|
39
39
|
bare?: boolean;
|
|
40
|
+
/** Decorative caller glyph; the visible text remains the accessible status. */
|
|
41
|
+
icon?: React.ReactNode;
|
|
40
42
|
size?: "sm" | "md";
|
|
41
43
|
}
|
|
42
44
|
declare const StatusPill: React.ForwardRefExoticComponent<StatusPillProps & React.RefAttributes<HTMLSpanElement>>;
|