@loworbitstudio/visor 1.20.0 → 1.21.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/CHANGELOG.json +1 -1
- package/dist/registry.json +5 -4
- package/dist/visor-manifest.json +1 -1
- package/package.json +1 -1
package/dist/CHANGELOG.json
CHANGED
package/dist/registry.json
CHANGED
|
@@ -4117,12 +4117,12 @@
|
|
|
4117
4117
|
{
|
|
4118
4118
|
"path": "blocks/dialog-form/dialog-form.tsx",
|
|
4119
4119
|
"type": "registry:block",
|
|
4120
|
-
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"../../lib/utils\"\nimport {\n Dialog,\n DialogTrigger,\n DialogClose,\n DialogContent,\n DialogTitle,\n DialogDescription,\n} from \"../../components/ui/dialog/dialog\"\nimport styles from \"./dialog-form.module.css\"\n\n/**\n * DialogForm — the Animal dialog substrate shell (VI-620).\n *\n * A mid-tier block that composes the `dialog` atom into the compact admin\n * modal shell the app's 10 hand-rolled modals converge onto: backdrop +\n * centered panel + header + footer. Everything is token-driven; the active\n * theme swaps the surface, hairline, radius, and title scale.\n *\n * The root pieces (open state, trigger, close) are re-exported straight from\n * the atom so a modal imports its whole substrate from one place.\n */\nconst DialogForm = Dialog\nconst DialogFormTrigger = DialogTrigger\nconst DialogFormClose = DialogClose\nconst DialogFormDescription = DialogDescription\n\n/* ─── Content — the compact panel ───────────────────────────────────── */\n\nexport
|
|
4120
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"../../lib/utils\"\nimport {\n Dialog,\n DialogTrigger,\n DialogClose,\n DialogContent,\n DialogTitle,\n DialogDescription,\n} from \"../../components/ui/dialog/dialog\"\nimport styles from \"./dialog-form.module.css\"\n\n/**\n * DialogForm — the Animal dialog substrate shell (VI-620).\n *\n * A mid-tier block that composes the `dialog` atom into the compact admin\n * modal shell the app's 10 hand-rolled modals converge onto: backdrop +\n * centered panel + header + footer. Everything is token-driven; the active\n * theme swaps the surface, hairline, radius, and title scale.\n *\n * The root pieces (open state, trigger, close) are re-exported straight from\n * the atom so a modal imports its whole substrate from one place.\n */\nconst DialogForm = Dialog\nconst DialogFormTrigger = DialogTrigger\nconst DialogFormClose = DialogClose\nconst DialogFormDescription = DialogDescription\n\n/* ─── Content — the compact panel ───────────────────────────────────── */\n\n/* Panel axes: `width` sets the max-width (token-backed --dialog-form-width-*,\n * default 30rem) and `border` toggles the hairline seam (default keeps it;\n * \"none\" nulls --dialog-form-panel-border for a borderless panel). Both default\n * to the VI-620 rendering, so existing call sites are unchanged. */\nconst panelVariants = cva(styles.panel, {\n variants: {\n width: {\n sm: styles.widthSm,\n md: styles.widthMd,\n lg: styles.widthLg,\n },\n border: {\n default: \"\",\n none: styles.panelBorderless,\n },\n },\n defaultVariants: {\n width: \"md\",\n border: \"default\",\n },\n})\n\nexport interface DialogFormContentProps\n extends React.ComponentProps<typeof DialogContent>,\n VariantProps<typeof panelVariants> {}\n\nconst DialogFormContent = React.forwardRef<\n React.ComponentRef<typeof DialogContent>,\n DialogFormContentProps\n>(({ className, width, border, ...props }, ref) => (\n <DialogContent\n ref={ref}\n className={cn(panelVariants({ width, border }), className)}\n {...props}\n />\n))\nDialogFormContent.displayName = \"DialogFormContent\"\n\n/* ─── Header ─────────────────────────────────────────────────────────── */\n\nfunction DialogFormHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-form-header\"\n className={cn(styles.header, className)}\n {...props}\n />\n )\n}\nDialogFormHeader.displayName = \"DialogFormHeader\"\n\n/* ─── Title (size axis: sm 13px default, md 16px) ────────────────────── */\n\nconst titleVariants = cva(styles.title, {\n variants: {\n size: {\n sm: styles.titleSm,\n md: styles.titleMd,\n },\n },\n defaultVariants: {\n size: \"sm\",\n },\n})\n\nexport interface DialogFormTitleProps\n extends React.ComponentProps<typeof DialogTitle>,\n VariantProps<typeof titleVariants> {}\n\nconst DialogFormTitle = React.forwardRef<\n React.ComponentRef<typeof DialogTitle>,\n DialogFormTitleProps\n>(({ className, size, ...props }, ref) => (\n <DialogTitle\n ref={ref}\n className={cn(titleVariants({ size }), className)}\n {...props}\n />\n))\nDialogFormTitle.displayName = \"DialogFormTitle\"\n\n/* ─── Body — vertical stack of DialogField blocks ────────────────────── */\n\nfunction DialogFormBody({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-form-body\"\n className={cn(styles.body, className)}\n {...props}\n />\n )\n}\nDialogFormBody.displayName = \"DialogFormBody\"\n\n/* ─── Footer — the right-aligned dlg-btn action row ──────────────────── */\n\nfunction DialogFormFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-form-footer\"\n className={cn(styles.footer, className)}\n {...props}\n />\n )\n}\nDialogFormFooter.displayName = \"DialogFormFooter\"\n\nexport {\n DialogForm,\n DialogFormTrigger,\n DialogFormClose,\n DialogFormContent,\n DialogFormHeader,\n DialogFormTitle,\n DialogFormBody,\n DialogFormFooter,\n DialogFormDescription,\n titleVariants,\n panelVariants,\n}\n"
|
|
4121
4121
|
},
|
|
4122
4122
|
{
|
|
4123
4123
|
"path": "blocks/dialog-form/dialog-form.module.css",
|
|
4124
4124
|
"type": "registry:block",
|
|
4125
|
-
"content": "/* DialogForm block — Animal dialog substrate shell (VI-620).\n *\n * Restyles the `dialog` atom's DialogContent into the compact admin modal\n * panel, then adds the header / title / body / footer chrome the 10 hand-rolled\n * Animal modals converge onto. Every value traces to a Visor token so the\n * active theme (Animal, or any other) swaps the whole shell — no bespoke CSS.\n */\n\n/* Compact panel — overrides the atom's default 32rem / spacing-6 content. */\n.panel {\n
|
|
4125
|
+
"content": "/* DialogForm block — Animal dialog substrate shell (VI-620).\n *\n * Restyles the `dialog` atom's DialogContent into the compact admin modal\n * panel, then adds the header / title / body / footer chrome the 10 hand-rolled\n * Animal modals converge onto. Every value traces to a Visor token so the\n * active theme (Animal, or any other) swaps the whole shell — no bespoke CSS.\n */\n\n/* Compact panel — overrides the atom's default 32rem / spacing-6 content. The\n * max-width is the `width` axis (--widthSm/Md/Lg below); the hairline border is a\n * token seam (--dialog-form-panel-border) a theme or the `border=\"none\"` variant\n * can null out — AN-237 removed it (the hairline reads as chrome the design\n * doesn't want) without editing this copy. */\n.panel {\n border-radius: var(--radius-xl, 0.75rem);\n padding: var(--spacing-5, 1.25rem);\n background: var(--surface-card, #ffffff);\n border: var(\n --dialog-form-panel-border,\n var(--stroke-width-thin, 1px) solid\n var(--hairline, var(--border-default, #e5e7eb))\n );\n box-shadow: var(--shadow-lg);\n}\n\n/* Width axis — max-width only. Token-backed so a theme can retune each step;\n * `md` (default) preserves the VI-620 30rem panel. */\n.widthSm {\n max-width: var(--dialog-form-width-sm, 24rem);\n}\n\n.widthMd {\n max-width: var(--dialog-form-width-md, 30rem);\n}\n\n.widthLg {\n max-width: var(--dialog-form-width-lg, 40rem);\n}\n\n/* Borderless variant — nulls the panel-border seam (border=\"none\"). Consumers\n * can equivalently set --dialog-form-panel-border: none in a theme. */\n.panelBorderless {\n --dialog-form-panel-border: none;\n}\n\n/* Header — title + optional description, tight stack above the body. */\n.header {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-1, 0.25rem);\n margin-bottom: var(--spacing-4, 1rem);\n}\n\n/* Title — dlg-title. Bold, primary ink. Size axis reconciles the two AN\n * sources: the 13.5px surface scale (default `sm`) and reuse.html's 15px\n * shared/confirm dialogs (`md`). Normalized onto the --text-N chrome scale. */\n.title {\n font-weight: var(--font-weight-bold, 700);\n color: var(--text-primary, #111827);\n margin: 0;\n line-height: 1.3;\n}\n\n.titleSm {\n font-size: var(--text-13, 0.8125rem);\n}\n\n.titleMd {\n font-size: var(--text-16, 1rem);\n}\n\n/* Body — vertical stack of DialogField blocks. */\n.body {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-4, 1rem);\n}\n\n/* Footer — right-aligned dlg-btn action row. */\n.footer {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n margin-top: var(--spacing-5, 1.25rem);\n}\n"
|
|
4126
4126
|
}
|
|
4127
4127
|
]
|
|
4128
4128
|
},
|
|
@@ -4133,6 +4133,7 @@
|
|
|
4133
4133
|
"category": "form",
|
|
4134
4134
|
"dependencies": [
|
|
4135
4135
|
"@radix-ui/react-label",
|
|
4136
|
+
"class-variance-authority",
|
|
4136
4137
|
"@loworbitstudio/visor-core"
|
|
4137
4138
|
],
|
|
4138
4139
|
"registryDependencies": [
|
|
@@ -4143,12 +4144,12 @@
|
|
|
4143
4144
|
{
|
|
4144
4145
|
"path": "blocks/dialog-field/dialog-field.tsx",
|
|
4145
4146
|
"type": "registry:block",
|
|
4146
|
-
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\nimport { Label } from \"../../components/ui/label/label\"\nimport styles from \"./dialog-field.module.css\"\n\n/**\n * DialogField — the Animal dialog substrate field block (dlg-field, VI-620).\n *\n * A flex-column field (label over control) with the compact dialog treatment:\n * 5px label→control gap, an 11px/600 primary-ink label, and the standard Visor\n * medium field (md size, themed form-control surface, borderless) that hosts a\n * leading icon slot, the control itself, and a trailing control/caret slot.\n * Composes the `label` atom for the label. Every value traces to a Visor token\n * so the active theme swaps the whole treatment.\n */\n\n/* ─── Field root — flex column, 5px gap ──────────────────────────────── */\n\nconst DialogField = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n data-slot=\"dialog-field\"\n className={cn(styles.field, className)}\n ref={ref}\n {...props}\n />\n))\nDialogField.displayName = \"DialogField\"\n\n/* ─── Label — 11px / 600 / primary ink (dlg-label) ───────────────────── */\n\nexport type DialogFieldLabelProps = React.ComponentPropsWithoutRef<typeof Label>\n\nconst DialogFieldLabel = React.forwardRef<\n React.ElementRef<typeof Label>,\n DialogFieldLabelProps\n>(({ className, ...props }, ref) => (\n <Label\n data-slot=\"dialog-field-label\"\n className={cn(styles.label, className)}\n ref={ref}\n {...props}\n />\n))\nDialogFieldLabel.displayName = \"DialogFieldLabel\"\n\n/* ─── Control — the recessed well with icon + trailing slots ─────────── */\n\nexport interface DialogFieldControlProps\n extends React.HTMLAttributes<HTMLDivElement> {\n /** Leading icon rendered before the control (aria-hidden decoration). */\n icon?: React.ReactNode\n /** Trailing control / caret slot rendered after the control. */\n trailing?: React.ReactNode\n}\n\nconst DialogFieldControl = React.forwardRef<\n HTMLDivElement,\n DialogFieldControlProps\n>(({ className, icon, trailing, children, ...props }, ref) => (\n <div\n data-slot=\"dialog-field-control\"\n className={cn(
|
|
4147
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"../../lib/utils\"\nimport { Label } from \"../../components/ui/label/label\"\nimport styles from \"./dialog-field.module.css\"\n\n/**\n * DialogField — the Animal dialog substrate field block (dlg-field, VI-620).\n *\n * A flex-column field (label over control) with the compact dialog treatment:\n * 5px label→control gap, an 11px/600 primary-ink label, and the standard Visor\n * medium field (md size, themed form-control surface, borderless) that hosts a\n * leading icon slot, the control itself, and a trailing control/caret slot.\n * Composes the `label` atom for the label. Every value traces to a Visor token\n * so the active theme swaps the whole treatment.\n */\n\n/* ─── Field root — flex column, 5px gap ──────────────────────────────── */\n\nconst DialogField = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n data-slot=\"dialog-field\"\n className={cn(styles.field, className)}\n ref={ref}\n {...props}\n />\n))\nDialogField.displayName = \"DialogField\"\n\n/* ─── Label — 11px / 600 / primary ink (dlg-label) ───────────────────── */\n\nexport type DialogFieldLabelProps = React.ComponentPropsWithoutRef<typeof Label>\n\nconst DialogFieldLabel = React.forwardRef<\n React.ElementRef<typeof Label>,\n DialogFieldLabelProps\n>(({ className, ...props }, ref) => (\n <Label\n data-slot=\"dialog-field-label\"\n className={cn(styles.label, className)}\n ref={ref}\n {...props}\n />\n))\nDialogFieldLabel.displayName = \"DialogFieldLabel\"\n\n/* ─── Control — the recessed well with icon + trailing slots ─────────── */\n\n/* Size axis drives the well padding only (label typography unchanged), matching\n * Visor's input-only `size` semantics. Default `md` preserves the VI-620 medium\n * well; `sm` is the compact Animal modal-form well. */\nconst controlVariants = cva(styles.control, {\n variants: {\n size: {\n sm: styles.controlSm,\n md: styles.controlMd,\n },\n },\n defaultVariants: {\n size: \"md\",\n },\n})\n\nexport interface DialogFieldControlProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof controlVariants> {\n /** Leading icon rendered before the control (aria-hidden decoration). */\n icon?: React.ReactNode\n /** Trailing control / caret slot rendered after the control. */\n trailing?: React.ReactNode\n}\n\nconst DialogFieldControl = React.forwardRef<\n HTMLDivElement,\n DialogFieldControlProps\n>(({ className, size, icon, trailing, children, ...props }, ref) => (\n <div\n data-slot=\"dialog-field-control\"\n className={cn(controlVariants({ size }), className)}\n ref={ref}\n {...props}\n >\n {icon ? (\n <span className={styles.icon} aria-hidden=\"true\">\n {icon}\n </span>\n ) : null}\n <span className={styles.controlInner}>{children}</span>\n {trailing ? <span className={styles.trailing}>{trailing}</span> : null}\n </div>\n))\nDialogFieldControl.displayName = \"DialogFieldControl\"\n\nexport { DialogField, DialogFieldLabel, DialogFieldControl, controlVariants }\n"
|
|
4147
4148
|
},
|
|
4148
4149
|
{
|
|
4149
4150
|
"path": "blocks/dialog-field/dialog-field.module.css",
|
|
4150
4151
|
"type": "registry:block",
|
|
4151
|
-
"content": "/* DialogField block — Animal dialog substrate field (dlg-field, VI-620).\n *\n * flex column, 5px gap · 11px/600 primary-ink label · the standard Visor medium\n * field (md size, themed form-control surface, borderless) hosting a leading\n * icon, the control, and a trailing control/caret. Every value traces to a Visor\n * token; the active theme swaps the whole treatment (no bespoke CSS).\n */\n\n/* Field — flex column. 5px label→control gap (dlg-field spec): the 4px grid\n * has no 5px step, so derive it from --spacing-1 (the same calc idiom the\n * field atom uses for its 6px icon gap). */\n.field {\n display: flex;\n flex-direction: column;\n gap: calc(var(--spacing-1, 0.25rem) + var(--spacing-1, 0.25rem) / 4);\n}\n\n/* Label — dlg-label: 11px / 600 / --ink (primary). */\n.label {\n font-size: var(--text-11, 0.6875rem);\n font-weight: var(--font-weight-semibold, 600);\n color: var(--text-primary, #111827);\n line-height: 1.4;\n}\n\n/* Control — the standard Visor
|
|
4152
|
+
"content": "/* DialogField block — Animal dialog substrate field (dlg-field, VI-620).\n *\n * flex column, 5px gap · 11px/600 primary-ink label · the standard Visor medium\n * field (md size, themed form-control surface, borderless) hosting a leading\n * icon, the control, and a trailing control/caret. Every value traces to a Visor\n * token; the active theme swaps the whole treatment (no bespoke CSS).\n */\n\n/* Field — flex column. 5px label→control gap (dlg-field spec): the 4px grid\n * has no 5px step, so derive it from --spacing-1 (the same calc idiom the\n * field atom uses for its 6px icon gap). */\n.field {\n display: flex;\n flex-direction: column;\n gap: calc(var(--spacing-1, 0.25rem) + var(--spacing-1, 0.25rem) / 4);\n}\n\n/* Label — dlg-label: 11px / 600 / --ink (primary). */\n.label {\n font-size: var(--text-11, 0.6875rem);\n font-weight: var(--font-weight-semibold, 600);\n color: var(--text-primary, #111827);\n line-height: 1.4;\n}\n\n/* Control — the standard Visor field well on the shared form-control surface role\n * (--field-control-bg), borderless. The surface color is theme-driven — a dialog\n * context may lift it with --field-control-bg (the documented in-dialog hook on\n * the input atom); we do not hand-roll it here. Borderless per the dlg-field\n * direction; focus shows a tokenized ring. The well padding is the `size` axis\n * (--controlSm / --controlMd below) so a compact Animal modal field and the\n * default medium field share one well — matching Visor's input-only `size`\n * semantics (padding varies; the label typography does not). */\n.control {\n display: flex;\n align-items: center;\n gap: var(--spacing-2, 0.5rem);\n border-radius: var(--input-radius-md, var(--radius-sm, 0.5rem));\n /* Borderless field → the surface must contrast with the card on its own. A\n * fixed surface token (--surface-subtle) can't guarantee that: some themes\n * pin it almost on the card (e.g. space/light). Instead derive it from the\n * card mixed a few percent toward --text-primary — which is legible on the\n * card by definition, so the field reads as a subtle-but-visible step in\n * every theme and both modes. Overridable per theme via --field-control-bg. */\n background: var(\n --field-control-bg,\n color-mix(in srgb, var(--surface-card, #ffffff), var(--text-primary, #111827) 7%)\n );\n color: var(--text-primary, #111827);\n transition: box-shadow var(--motion-duration-150, 150ms)\n var(--motion-easing-default, ease-in-out);\n}\n\n.control:focus-within {\n box-shadow: 0 0 0 var(--focus-ring-width, 2px)\n color-mix(in srgb, var(--border-focus, var(--primary, #111827)) 15%, transparent);\n}\n\n/* Size axis — well/control padding only (label typography unchanged). Mirrors the\n * input atom's --input-padding-{sm,md} seams so the field well tracks the input\n * size scale. `md` (default) preserves the VI-620 medium well; `sm` is the\n * compact Animal modal-form well (opted into per-field via size=\"sm\"). */\n.controlSm {\n padding: var(--input-padding-sm, var(--spacing-1, 0.25rem) var(--spacing-3, 0.75rem));\n}\n\n.controlMd {\n padding: var(--input-padding-md, var(--spacing-3_5, 0.875rem) var(--spacing-4, 1rem));\n}\n\n/* Leading icon slot. */\n.icon {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n color: var(--text-tertiary, #9ca3af);\n}\n\n/* The control itself sits on the well surface — transparent, borderless, so a\n * plain <input>/<select>/<textarea> dropped in reads as part of the well. */\n.controlInner {\n flex: 1;\n min-width: 0;\n display: flex;\n}\n\n.controlInner :global(input),\n.controlInner :global(select),\n.controlInner :global(textarea) {\n flex: 1;\n min-width: 0;\n border: 0;\n padding: 0;\n background: transparent;\n outline: none;\n color: var(--text-primary, #111827);\n}\n\n/* Trailing control / caret slot. */\n.trailing {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n color: var(--text-tertiary, #9ca3af);\n}\n"
|
|
4152
4153
|
}
|
|
4153
4154
|
]
|
|
4154
4155
|
},
|
package/dist/visor-manifest.json
CHANGED