@loworbitstudio/visor 1.12.0 → 1.13.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 +2 -2
- package/dist/visor-manifest.json +2 -2
- package/package.json +1 -1
package/dist/CHANGELOG.json
CHANGED
package/dist/registry.json
CHANGED
|
@@ -468,7 +468,7 @@
|
|
|
468
468
|
{
|
|
469
469
|
"path": "components/ui/avatar/avatar.tsx",
|
|
470
470
|
"type": "registry:ui",
|
|
471
|
-
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\"\nimport { cn } from \"../../../lib/utils\"\nimport styles from \"./avatar.module.css\"\nimport stackStyles from \"./avatar-stack.module.css\"\n\n// ─── AvatarStack item type ───────────────────────────────────────────────────\n\n/**\n * Rich item form for AvatarStack. A plain string or `undefined` is also\n * accepted (backward-compatible shorthand for an image-src-only item).\n */\nexport interface AvatarStackItem {\n /** Initials rendered as fallback (and primary) content — e.g. \"AR\". */\n initials?: React.ReactNode\n /** Optional image source. When present, the image covers the disc. */\n src?: string\n /** Accessible label for the disc — e.g. the member name. */\n alt?: string\n /**\n * Per-avatar style escape hatch — carries the gradient `background` + text\n * `color` for the editorial gradient discs (see `getMemberAvatarStyle`).\n */\n style?: React.CSSProperties\n}\n\nexport interface AvatarProps\n extends React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> {\n size?: \"sm\" | \"default\" | \"lg\"\n}\n\nconst Avatar = React.forwardRef<\n React.ElementRef<typeof AvatarPrimitive.Root>,\n AvatarProps\n>(({ className, size = \"default\", ...props }, ref) => {\n return (\n <AvatarPrimitive.Root\n ref={ref}\n data-slot=\"avatar\"\n data-size={size}\n className={cn(\n styles.avatar,\n size === \"sm\" && styles.avatarSm,\n size === \"lg\" && styles.avatarLg,\n className\n )}\n {...props}\n />\n )\n})\nAvatar.displayName = \"Avatar\"\n\nconst AvatarImage = React.forwardRef<\n React.ElementRef<typeof AvatarPrimitive.Image>,\n React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>\n>(({ className, ...props }, ref) => {\n return (\n <AvatarPrimitive.Image\n ref={ref}\n data-slot=\"avatar-image\"\n className={cn(styles.avatarImage, className)}\n {...props}\n />\n )\n})\nAvatarImage.displayName = \"AvatarImage\"\n\nconst AvatarFallback = React.forwardRef<\n React.ElementRef<typeof AvatarPrimitive.Fallback>,\n React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>\n>(({ className, ...props }, ref) => {\n return (\n <AvatarPrimitive.Fallback\n ref={ref}\n data-slot=\"avatar-fallback\"\n className={cn(styles.avatarFallback, className)}\n {...props}\n />\n )\n})\nAvatarFallback.displayName = \"AvatarFallback\"\n\nexport interface AvatarStackProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"role\" | \"aria-label\"> {\n /**\n * Avatars to render, in display order. Each entry is either:\n * - A plain image URL string (backward-compatible shorthand)\n * - `undefined` — renders the `·` fallback disc, useful for server-truncated lists\n * - An `AvatarStackItem` object with `initials`, `src`, `alt`, and/or `style`\n */\n avatars: (string | undefined | AvatarStackItem)[]\n /**\n * Total member count. May exceed `avatars.length` when the caller has\n * server-truncated the avatar URLs and only knows the count. The overflow\n * indicator is computed against this value.\n */\n total: number\n /**\n * Maximum number of avatar slots rendered before the `+N` overflow\n * indicator. Defaults to `6`.\n */\n max?: number\n /**\n * Explicit \"+N\" override. When provided, this value is used verbatim\n * instead of the value derived from `total - visible.length`. Useful\n * when the caller has a pre-computed overflow count.\n */\n overflowCount?: number\n /** Avatar size. Defaults to `\"sm\"`. */\n size?: \"sm\" | \"default\" | \"lg\"\n /**\n * Accessible label override. Defaults to ``${total} members``.\n */\n label?: string\n}\n\n/** Normalize a raw avatar entry to an `AvatarStackItem`. */\nfunction toItem(entry: string | undefined | AvatarStackItem): AvatarStackItem {\n if (entry === undefined || entry === null) return {}\n if (typeof entry === \"string\") return { src: entry, alt: \"\" }\n return entry\n}\n\nconst AvatarStack = React.forwardRef<HTMLDivElement, AvatarStackProps>(\n function AvatarStack(\n {\n avatars,\n total,\n max = 6,\n overflowCount,\n size = \"sm\",\n label,\n className,\n ...rest\n },\n ref,\n ) {\n const visible = avatars.slice(0, max)\n const derivedOverflow = Math.max(0, total - visible.length)\n const overflow = overflowCount ?? derivedOverflow\n const ariaLabel = label ?? `${total} members`\n\n return (\n <div\n ref={ref}\n role=\"img\"\n aria-label={ariaLabel}\n data-slot=\"avatar-stack\"\n data-size={size}\n className={cn(stackStyles.root, className)}\n {...rest}\n >\n {visible.map((entry, index) => {\n const item = toItem(entry)\n return (\n <Avatar\n key={index}\n size={size}\n className={stackStyles.avatar}\n style={item.style}\n data-stack-item=\"\"\n >\n {item.src ? (\n <AvatarImage src={item.src} alt={item.alt ?? \"\"} />\n ) : item.initials != null ? (\n <AvatarFallback className={stackStyles.initialsDisc}>\n {item.initials}\n </AvatarFallback>\n ) : (\n <AvatarFallback>·</AvatarFallback>\n )}\n </Avatar>\n )\n })}\n {overflow > 0 ? (\n <Avatar\n size={size}\n className={stackStyles.avatar}\n data-stack-overflow=\"\"\n >\n <AvatarFallback
|
|
471
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\"\nimport { cn } from \"../../../lib/utils\"\nimport styles from \"./avatar.module.css\"\nimport stackStyles from \"./avatar-stack.module.css\"\n\n// ─── AvatarStack item type ───────────────────────────────────────────────────\n\n/**\n * Rich item form for AvatarStack. A plain string or `undefined` is also\n * accepted (backward-compatible shorthand for an image-src-only item).\n */\nexport interface AvatarStackItem {\n /** Initials rendered as fallback (and primary) content — e.g. \"AR\". */\n initials?: React.ReactNode\n /** Optional image source. When present, the image covers the disc. */\n src?: string\n /** Accessible label for the disc — e.g. the member name. */\n alt?: string\n /**\n * Per-avatar style escape hatch — carries the gradient `background` + text\n * `color` for the editorial gradient discs (see `getMemberAvatarStyle`).\n */\n style?: React.CSSProperties\n}\n\nexport interface AvatarProps\n extends React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> {\n size?: \"sm\" | \"default\" | \"lg\"\n}\n\nconst Avatar = React.forwardRef<\n React.ElementRef<typeof AvatarPrimitive.Root>,\n AvatarProps\n>(({ className, size = \"default\", ...props }, ref) => {\n return (\n <AvatarPrimitive.Root\n ref={ref}\n data-slot=\"avatar\"\n data-size={size}\n className={cn(\n styles.avatar,\n size === \"sm\" && styles.avatarSm,\n size === \"lg\" && styles.avatarLg,\n className\n )}\n {...props}\n />\n )\n})\nAvatar.displayName = \"Avatar\"\n\nconst AvatarImage = React.forwardRef<\n React.ElementRef<typeof AvatarPrimitive.Image>,\n React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>\n>(({ className, ...props }, ref) => {\n return (\n <AvatarPrimitive.Image\n ref={ref}\n data-slot=\"avatar-image\"\n className={cn(styles.avatarImage, className)}\n {...props}\n />\n )\n})\nAvatarImage.displayName = \"AvatarImage\"\n\nconst AvatarFallback = React.forwardRef<\n React.ElementRef<typeof AvatarPrimitive.Fallback>,\n React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>\n>(({ className, ...props }, ref) => {\n return (\n <AvatarPrimitive.Fallback\n ref={ref}\n data-slot=\"avatar-fallback\"\n className={cn(styles.avatarFallback, className)}\n {...props}\n />\n )\n})\nAvatarFallback.displayName = \"AvatarFallback\"\n\nexport interface AvatarStackProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"role\" | \"aria-label\"> {\n /**\n * Avatars to render, in display order. Each entry is either:\n * - A plain image URL string (backward-compatible shorthand)\n * - `undefined` — renders the `·` fallback disc, useful for server-truncated lists\n * - An `AvatarStackItem` object with `initials`, `src`, `alt`, and/or `style`\n */\n avatars: (string | undefined | AvatarStackItem)[]\n /**\n * Total member count. May exceed `avatars.length` when the caller has\n * server-truncated the avatar URLs and only knows the count. The overflow\n * indicator is computed against this value.\n */\n total: number\n /**\n * Maximum number of avatar slots rendered before the `+N` overflow\n * indicator. Defaults to `6`.\n */\n max?: number\n /**\n * Explicit \"+N\" override. When provided, this value is used verbatim\n * instead of the value derived from `total - visible.length`. Useful\n * when the caller has a pre-computed overflow count.\n */\n overflowCount?: number\n /** Avatar size. Defaults to `\"sm\"`. */\n size?: \"sm\" | \"default\" | \"lg\"\n /**\n * Accessible label override. Defaults to ``${total} members``.\n */\n label?: string\n}\n\n/** Normalize a raw avatar entry to an `AvatarStackItem`. */\nfunction toItem(entry: string | undefined | AvatarStackItem): AvatarStackItem {\n if (entry === undefined || entry === null) return {}\n if (typeof entry === \"string\") return { src: entry, alt: \"\" }\n return entry\n}\n\nconst AvatarStack = React.forwardRef<HTMLDivElement, AvatarStackProps>(\n function AvatarStack(\n {\n avatars,\n total,\n max = 6,\n overflowCount,\n size = \"sm\",\n label,\n className,\n ...rest\n },\n ref,\n ) {\n const visible = avatars.slice(0, max)\n const derivedOverflow = Math.max(0, total - visible.length)\n const overflow = overflowCount ?? derivedOverflow\n const ariaLabel = label ?? `${total} members`\n\n return (\n <div\n ref={ref}\n role=\"img\"\n aria-label={ariaLabel}\n data-slot=\"avatar-stack\"\n data-size={size}\n className={cn(stackStyles.root, className)}\n {...rest}\n >\n {visible.map((entry, index) => {\n const item = toItem(entry)\n return (\n <Avatar\n key={index}\n size={size}\n className={stackStyles.avatar}\n style={item.style}\n data-stack-item=\"\"\n >\n {item.src ? (\n <AvatarImage src={item.src} alt={item.alt ?? \"\"} />\n ) : item.initials != null ? (\n <AvatarFallback className={stackStyles.initialsDisc}>\n {item.initials}\n </AvatarFallback>\n ) : (\n <AvatarFallback>·</AvatarFallback>\n )}\n </Avatar>\n )\n })}\n {overflow > 0 ? (\n <Avatar\n size={size}\n className={stackStyles.avatar}\n data-stack-overflow=\"\"\n >\n <AvatarFallback className={stackStyles.overflowDisc}>\n +{overflow}\n </AvatarFallback>\n </Avatar>\n ) : null}\n </div>\n )\n },\n)\n\nAvatarStack.displayName = \"AvatarStack\"\n\nexport { Avatar, AvatarImage, AvatarFallback, AvatarStack }\n"
|
|
472
472
|
},
|
|
473
473
|
{
|
|
474
474
|
"path": "components/ui/avatar/avatar.module.css",
|
|
@@ -478,7 +478,7 @@
|
|
|
478
478
|
{
|
|
479
479
|
"path": "components/ui/avatar/avatar-stack.module.css",
|
|
480
480
|
"type": "registry:ui",
|
|
481
|
-
"content": "/* AvatarStack root */\n.root {\n display: inline-flex;\n flex-direction: row;\n align-items: center;\n isolation: isolate;\n}\n\n/* Each avatar gets a ring matching the parent surface so adjacent avatars\n read as separate circles. Avatar's own `overflow: hidden` clips inner\n shadows, so the ring is projected outward via box-shadow. */\n.avatar {\n box-shadow: 0 0 0 var(--stroke-width-medium, 2px) var(--surface-default, #ffffff);\n}\n\n/* Overlap every avatar except the first. Later siblings stack on top of\n earlier ones because `isolation: isolate` establishes a single stacking\n context and DOM order wins inside it. */\n.avatar:not(:first-child) {\n margin-inline-start: calc(-1 * var(--spacing-2, 0.5rem));\n}\n\n/* When an AvatarStackItem carries a per-item `style` with gradient\n background + color, the fallback must be transparent so the gradient\n on the parent Avatar shows through. Only applied to the initials\n fallback inside a stack disc — plain Avatar usage is unaffected. */\n.initialsDisc {\n background-color: transparent;\n color: inherit;\n}\n"
|
|
481
|
+
"content": "/* AvatarStack root */\n.root {\n display: inline-flex;\n flex-direction: row;\n align-items: center;\n isolation: isolate;\n}\n\n/* Each avatar gets a ring matching the parent surface so adjacent avatars\n read as separate circles. Avatar's own `overflow: hidden` clips inner\n shadows, so the ring is projected outward via box-shadow.\n\n `--avatar-stack-ring` is the per-surface role hook: it defaults to\n `--surface-default` (byte-identical for existing consumers). A stack that\n sits on a different tier sets ONE custom property on a wrapper — for example\n `--avatar-stack-ring: var(--surface-card)` — instead of reaching into the\n component's `data-slot` internals (VI-578). */\n.avatar {\n box-shadow: 0 0 0 var(--stroke-width-medium, 2px) var(--avatar-stack-ring, var(--surface-default, #ffffff));\n}\n\n/* Overlap every avatar except the first. Later siblings stack on top of\n earlier ones because `isolation: isolate` establishes a single stacking\n context and DOM order wins inside it. */\n.avatar:not(:first-child) {\n margin-inline-start: calc(-1 * var(--spacing-2, 0.5rem));\n}\n\n/* When an AvatarStackItem carries a per-item `style` with gradient\n background + color, the fallback must be transparent so the gradient\n on the parent Avatar shows through. Only applied to the initials\n fallback inside a stack disc — plain Avatar usage is unaffected. */\n.initialsDisc {\n background-color: transparent;\n color: inherit;\n}\n\n/* The \"+N\" overflow disc carries 3–4 glyphs. Editorial density shrinks the\n default disc to 28px, but the base avatar stylesheet only adds explicit\n fallback font-sizes for the sm and lg sizes, so a default-size overflow\n count keeps the 14px base and clips behind overflow:hidden. Pin it to 11px\n here (matching the blessed avatar overflow treatment), absorbing the\n consumer's former font-size-sm overlay hack (VI-578). Default density is\n unchanged; the more specific lg fallback rule still wins for lg discs. */\n:global([data-density=\"editorial\"]) .overflowDisc {\n font-size: 11px;\n}\n"
|
|
482
482
|
}
|
|
483
483
|
]
|
|
484
484
|
},
|
package/dist/visor-manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.4.0",
|
|
3
|
-
"generated_at": "2026-06-
|
|
3
|
+
"generated_at": "2026-06-25T19:22:02.080Z",
|
|
4
4
|
"components": {
|
|
5
5
|
"accessibility-specimen": {
|
|
6
6
|
"category": "specimen",
|
|
@@ -311,7 +311,7 @@
|
|
|
311
311
|
},
|
|
312
312
|
{
|
|
313
313
|
"name": "AvatarStack",
|
|
314
|
-
"description": "Compound primitive for overlapping avatar groups with a `+N` overflow indicator. Each entry in `avatars` is a plain image-URL string, `undefined` (renders a placeholder disc), or an `AvatarStackItem` object with `initials`, `src`, `alt`, and an optional `style` escape hatch for per-disc gradient backgrounds. Accepts a `total` count (supports server-truncated lists), a `max` cap (default 6), an explicit `overflowCount` override, a `size` pass-through (`\"sm\" | \"default\" | \"lg\"`, default `\"sm\"`), and an optional accessible `label` override. Renders `role=\"img\"` with `data-slot=\"avatar-stack\"
|
|
314
|
+
"description": "Compound primitive for overlapping avatar groups with a `+N` overflow indicator. Each entry in `avatars` is a plain image-URL string, `undefined` (renders a placeholder disc), or an `AvatarStackItem` object with `initials`, `src`, `alt`, and an optional `style` escape hatch for per-disc gradient backgrounds. Accepts a `total` count (supports server-truncated lists), a `max` cap (default 6), an explicit `overflowCount` override, a `size` pass-through (`\"sm\" | \"default\" | \"lg\"`, default `\"sm\"`), and an optional accessible `label` override. Renders `role=\"img\"` with `data-slot=\"avatar-stack\"`. Each disc rings itself against the parent surface via the `--avatar-stack-ring` role hook (defaults to `--surface-default`); a stack sitting on a different tier sets that one custom property on a wrapper (e.g. `--avatar-stack-ring: var(--surface-card)`) rather than reaching into `data-slot` internals. Under `data-density=\"editorial\"` the `+N` overflow disc font drops to 11px so the count never clips in the smaller disc.\n"
|
|
315
315
|
}
|
|
316
316
|
],
|
|
317
317
|
"dependencies": [
|