@refraction-ui/react 0.20.0 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/react-avatar-group.js +1 -1
- package/dist/react-avatar-group.js.map +1 -1
- package/dist/react-presence-indicator.js +1 -1
- package/dist/react-presence-indicator.js.map +1 -1
- package/dist/react-status-indicator.js +4 -4
- package/dist/react-status-indicator.js.map +1 -1
- package/dist/styles.css +8 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../avatar-group/src/avatar-group.ts", "../../avatar-group/src/avatar-group.styles.ts", "../../react-avatar-group/src/avatar-group.tsx"],
|
|
4
|
-
"sourcesContent": ["import type { AccessibilityProps } from '@refraction-ui/shared'\nimport { generateId } from '@refraction-ui/shared'\n\nexport type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\nexport type PresenceStatus = 'online' | 'offline' | 'away' | 'busy' | 'dnd'\n\nexport interface AvatarUser {\n /** Unique identifier */\n id: string\n /** Display name */\n name: string\n /** Avatar image URL */\n src?: string\n /** Online presence status */\n status?: PresenceStatus\n}\n\nexport interface AvatarGroupProps {\n /** Array of users to display */\n users: AvatarUser[]\n /** Maximum number of visible avatars */\n max?: number\n /** Avatar size */\n size?: AvatarSize\n}\n\nexport interface AvatarGroupAPI {\n /** Users that are visible (within max limit) */\n visibleUsers: AvatarUser[]\n /** Number of overflow users */\n overflowCount: number\n /** All overflow users (for tooltip/popup) */\n overflowUsers: AvatarUser[]\n /** ARIA props for the group container */\n ariaProps: Partial<AccessibilityProps> & Record<string, unknown>\n /** Get ARIA props for an individual avatar */\n getAvatarAriaProps(user: AvatarUser): Record<string, unknown>\n /** Get initials from a user's name */\n getInitials(name: string): string\n /** Get the overflow badge ARIA props */\n overflowBadgeProps: Record<string, unknown>\n /** Generated IDs */\n ids: {\n group: string\n label: string\n }\n}\n\nexport const AVATAR_SIZES: Record<AvatarSize, { width: number; fontSize: number }> = {\n xs: { width: 24, fontSize: 10 },\n sm: { width: 32, fontSize: 12 },\n md: { width: 40, fontSize: 14 },\n lg: { width: 48, fontSize: 16 },\n xl: { width: 64, fontSize: 20 },\n}\n\nexport function getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/)\n if (parts.length === 0) return ''\n if (parts.length === 1) return parts[0].charAt(0).toUpperCase()\n return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase()\n}\n\nexport function createAvatarGroup(props: AvatarGroupProps): AvatarGroupAPI {\n const { users, max, size = 'md' } = props\n\n const visibleUsers = max && max > 0 ? users.slice(0, max) : users\n const overflowUsers = max && max > 0 ? users.slice(max) : []\n const overflowCount = overflowUsers.length\n\n const groupId = generateId('rfr-avatar-group')\n const labelId = generateId('rfr-avatar-group-label')\n\n const ariaProps: Partial<AccessibilityProps> & Record<string, unknown> = {\n role: 'group',\n 'aria-label': `${users.length} users`,\n id: groupId,\n }\n\n function getAvatarAriaProps(user: AvatarUser): Record<string, unknown> {\n const label = user.status ? `${user.name} (${user.status})` : user.name\n return {\n role: 'img',\n 'aria-label': label,\n }\n }\n\n const overflowBadgeProps: Record<string, unknown> = {\n role: 'button',\n 'aria-label': `${overflowCount} more users`,\n }\n\n return {\n visibleUsers,\n overflowCount,\n overflowUsers,\n ariaProps,\n getAvatarAriaProps,\n getInitials,\n overflowBadgeProps,\n ids: {\n group: groupId,\n label: labelId,\n },\n }\n}\n", "import { cva } from '@refraction-ui/shared'\n\nexport const avatarGroupStyles =\n 'flex items-center -space-x-2'\n\nexport const avatarVariants = cva({\n base: 'relative inline-flex items-center justify-center rounded-full border-2 border-background bg-muted text-muted-foreground font-medium overflow-hidden ring-2 ring-background',\n variants: {\n size: {\n xs: 'h-6 w-6 text-[10px]',\n sm: 'h-8 w-8 text-xs',\n md: 'h-10 w-10 text-sm',\n lg: 'h-12 w-12 text-base',\n xl: 'h-16 w-16 text-xl',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n})\n\nexport const avatarOverflowBadgeVariants = cva({\n base: 'relative inline-flex items-center justify-center rounded-full border-2 border-background bg-muted text-muted-foreground font-medium ring-2 ring-background',\n variants: {\n size: {\n xs: 'h-6 w-6 text-[10px]',\n sm: 'h-8 w-8 text-xs',\n md: 'h-10 w-10 text-sm',\n lg: 'h-12 w-12 text-base',\n xl: 'h-16 w-16 text-xl',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n})\n\nexport const avatarImageStyles =\n 'h-full w-full object-cover'\n\nexport const avatarPresenceDotVariants = cva({\n base: 'absolute bottom-0 right-0 rounded-full border-2 border-background',\n variants: {\n size: {\n xs: 'h-2 w-2',\n sm: 'h-2.5 w-2.5',\n md: 'h-3 w-3',\n lg: 'h-3.5 w-3.5',\n xl: 'h-4 w-4',\n },\n status: {\n online: 'bg-success',\n offline: 'bg-
|
|
4
|
+
"sourcesContent": ["import type { AccessibilityProps } from '@refraction-ui/shared'\nimport { generateId } from '@refraction-ui/shared'\n\nexport type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\nexport type PresenceStatus = 'online' | 'offline' | 'away' | 'busy' | 'dnd'\n\nexport interface AvatarUser {\n /** Unique identifier */\n id: string\n /** Display name */\n name: string\n /** Avatar image URL */\n src?: string\n /** Online presence status */\n status?: PresenceStatus\n}\n\nexport interface AvatarGroupProps {\n /** Array of users to display */\n users: AvatarUser[]\n /** Maximum number of visible avatars */\n max?: number\n /** Avatar size */\n size?: AvatarSize\n}\n\nexport interface AvatarGroupAPI {\n /** Users that are visible (within max limit) */\n visibleUsers: AvatarUser[]\n /** Number of overflow users */\n overflowCount: number\n /** All overflow users (for tooltip/popup) */\n overflowUsers: AvatarUser[]\n /** ARIA props for the group container */\n ariaProps: Partial<AccessibilityProps> & Record<string, unknown>\n /** Get ARIA props for an individual avatar */\n getAvatarAriaProps(user: AvatarUser): Record<string, unknown>\n /** Get initials from a user's name */\n getInitials(name: string): string\n /** Get the overflow badge ARIA props */\n overflowBadgeProps: Record<string, unknown>\n /** Generated IDs */\n ids: {\n group: string\n label: string\n }\n}\n\nexport const AVATAR_SIZES: Record<AvatarSize, { width: number; fontSize: number }> = {\n xs: { width: 24, fontSize: 10 },\n sm: { width: 32, fontSize: 12 },\n md: { width: 40, fontSize: 14 },\n lg: { width: 48, fontSize: 16 },\n xl: { width: 64, fontSize: 20 },\n}\n\nexport function getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/)\n if (parts.length === 0) return ''\n if (parts.length === 1) return parts[0].charAt(0).toUpperCase()\n return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase()\n}\n\nexport function createAvatarGroup(props: AvatarGroupProps): AvatarGroupAPI {\n const { users, max, size = 'md' } = props\n\n const visibleUsers = max && max > 0 ? users.slice(0, max) : users\n const overflowUsers = max && max > 0 ? users.slice(max) : []\n const overflowCount = overflowUsers.length\n\n const groupId = generateId('rfr-avatar-group')\n const labelId = generateId('rfr-avatar-group-label')\n\n const ariaProps: Partial<AccessibilityProps> & Record<string, unknown> = {\n role: 'group',\n 'aria-label': `${users.length} users`,\n id: groupId,\n }\n\n function getAvatarAriaProps(user: AvatarUser): Record<string, unknown> {\n const label = user.status ? `${user.name} (${user.status})` : user.name\n return {\n role: 'img',\n 'aria-label': label,\n }\n }\n\n const overflowBadgeProps: Record<string, unknown> = {\n role: 'button',\n 'aria-label': `${overflowCount} more users`,\n }\n\n return {\n visibleUsers,\n overflowCount,\n overflowUsers,\n ariaProps,\n getAvatarAriaProps,\n getInitials,\n overflowBadgeProps,\n ids: {\n group: groupId,\n label: labelId,\n },\n }\n}\n", "import { cva } from '@refraction-ui/shared'\n\nexport const avatarGroupStyles =\n 'flex items-center -space-x-2'\n\nexport const avatarVariants = cva({\n base: 'relative inline-flex items-center justify-center rounded-full border-2 border-background bg-muted text-muted-foreground font-medium overflow-hidden ring-2 ring-background',\n variants: {\n size: {\n xs: 'h-6 w-6 text-[10px]',\n sm: 'h-8 w-8 text-xs',\n md: 'h-10 w-10 text-sm',\n lg: 'h-12 w-12 text-base',\n xl: 'h-16 w-16 text-xl',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n})\n\nexport const avatarOverflowBadgeVariants = cva({\n base: 'relative inline-flex items-center justify-center rounded-full border-2 border-background bg-muted text-muted-foreground font-medium ring-2 ring-background',\n variants: {\n size: {\n xs: 'h-6 w-6 text-[10px]',\n sm: 'h-8 w-8 text-xs',\n md: 'h-10 w-10 text-sm',\n lg: 'h-12 w-12 text-base',\n xl: 'h-16 w-16 text-xl',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n})\n\nexport const avatarImageStyles =\n 'h-full w-full object-cover'\n\nexport const avatarPresenceDotVariants = cva({\n base: 'absolute bottom-0 right-0 rounded-full border-2 border-background',\n variants: {\n size: {\n xs: 'h-2 w-2',\n sm: 'h-2.5 w-2.5',\n md: 'h-3 w-3',\n lg: 'h-3.5 w-3.5',\n xl: 'h-4 w-4',\n },\n status: {\n online: 'bg-success',\n offline: 'bg-neutral',\n away: 'bg-warning',\n busy: 'bg-destructive',\n dnd: 'bg-destructive',\n },\n },\n defaultVariants: {\n size: 'md',\n status: 'offline',\n },\n})\n", "import * as React from 'react'\nimport {\n createAvatarGroup,\n avatarGroupStyles,\n avatarVariants,\n avatarOverflowBadgeVariants,\n avatarImageStyles,\n avatarPresenceDotVariants,\n type AvatarUser,\n type AvatarSize,\n} from '@refraction-ui/avatar-group'\nimport { cn } from '@refraction-ui/shared'\n\nexport interface AvatarGroupProps {\n users: AvatarUser[]\n max?: number\n size?: AvatarSize\n className?: string\n}\n\nexport const AvatarGroup = React.forwardRef<HTMLDivElement, AvatarGroupProps>(\n function AvatarGroup({ users, max, size = 'md', className }, ref) {\n const api = createAvatarGroup({ users, max, size })\n\n return React.createElement(\n 'div',\n { ref, ...api.ariaProps, className: cn(avatarGroupStyles, className) },\n api.visibleUsers.map((user) =>\n React.createElement(\n 'div',\n {\n key: user.id,\n className: avatarVariants({ size }),\n ...api.getAvatarAriaProps(user),\n },\n user.src\n ? React.createElement('img', {\n src: user.src,\n alt: user.name,\n className: avatarImageStyles,\n })\n : React.createElement('span', null, api.getInitials(user.name)),\n user.status &&\n React.createElement('span', {\n className: avatarPresenceDotVariants({ size, status: user.status }),\n }),\n ),\n ),\n api.overflowCount > 0 &&\n React.createElement(\n 'div',\n {\n className: avatarOverflowBadgeVariants({ size }),\n ...api.overflowBadgeProps,\n },\n `+${api.overflowCount}`,\n ),\n )\n },\n)\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;AAwDO,SAAS,YAAY,MAAsB;AAChD,QAAM,QAAQ,KAAK,KAAA,EAAO,MAAM,KAAK;AACrC,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,YAAA;AAClD,UAAQ,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,MAAM,MAAM,SAAS,CAAC,EAAE,OAAO,CAAC,GAAG,YAAA;AAClE;AAEO,SAAS,kBAAkB,OAAyC;AACzE,QAAM,EAAE,OAAO,KAAK,OAAO,KAAA,IAAS;AAEpC,QAAM,eAAe,OAAO,MAAM,IAAI,MAAM,MAAM,GAAG,GAAG,IAAI;AAC5D,QAAM,gBAAgB,OAAO,MAAM,IAAI,MAAM,MAAM,GAAG,IAAI,CAAA;AAC1D,QAAM,gBAAgB,cAAc;AAEpC,QAAM,UAAU,WAAW,kBAAkB;AAC7C,QAAM,UAAU,WAAW,wBAAwB;AAEnD,QAAM,YAAmE;IACvE,MAAM;IACN,cAAc,GAAG,MAAM,MAAM;IAC7B,IAAI;EAAA;AAGN,WAAS,mBAAmB,MAA2C;AACrE,UAAM,QAAQ,KAAK,SAAS,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,MAAM,KAAK;AACnE,WAAO;MACL,MAAM;MACN,cAAc;IAAA;EAElB;AAEA,QAAM,qBAA8C;IAClD,MAAM;IACN,cAAc,GAAG,aAAa;EAAA;AAGhC,SAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA,KAAK;MACH,OAAO;MACP,OAAO;IAAA;EACT;AAEJ;ACvGO,IAAM,oBACX;AAEK,IAAM,iBAAiB,IAAI;EAChC,MAAM;EACN,UAAU;IACR,MAAM;MACJ,IAAI;MACJ,IAAI;MACJ,IAAI;MACJ,IAAI;MACJ,IAAI;IAAA;EACN;EAEF,iBAAiB;IACf,MAAM;EAAA;AAEV,CAAC;AAEM,IAAM,8BAA8B,IAAI;EAC7C,MAAM;EACN,UAAU;IACR,MAAM;MACJ,IAAI;MACJ,IAAI;MACJ,IAAI;MACJ,IAAI;MACJ,IAAI;IAAA;EACN;EAEF,iBAAiB;IACf,MAAM;EAAA;AAEV,CAAC;AAEM,IAAM,oBACX;AAEK,IAAM,4BAA4B,IAAI;EAC3C,MAAM;EACN,UAAU;IACR,MAAM;MACJ,IAAI;MACJ,IAAI;MACJ,IAAI;MACJ,IAAI;MACJ,IAAI;IAAA;IAEN,QAAQ;MACN,QAAQ;MACR,SAAS;MACT,MAAM;MACN,MAAM;MACN,KAAK;IAAA;EACP;EAEF,iBAAiB;IACf,MAAM;IACN,QAAQ;EAAA;AAEZ,CAAC;;;AC1CM,IAAM,cAAoB;EAC/B,SAASA,aAAY,EAAE,OAAO,KAAK,OAAO,MAAM,UAAA,GAAa,KAAK;AAClE,UAAM,MAAM,kBAAkB,EAAE,OAAO,KAAK,KAAA,CAAM;AAElD,WAAa;MACX;MACA,EAAE,KAAK,GAAG,IAAI,WAAW,WAAW,GAAG,mBAAmB,SAAS,EAAA;MACnE,IAAI,aAAa;QAAI,CAAC,SACd;UACJ;UACA;YACE,KAAK,KAAK;YACV,WAAW,eAAe,EAAE,KAAA,CAAM;YAClC,GAAG,IAAI,mBAAmB,IAAI;UAAA;UAEhC,KAAK,MACK,oBAAc,OAAO;YACzB,KAAK,KAAK;YACV,KAAK,KAAK;YACV,WAAW;UAAA,CACZ,IACK,oBAAc,QAAQ,MAAM,IAAI,YAAY,KAAK,IAAI,CAAC;UAChE,KAAK,UACG,oBAAc,QAAQ;YAC1B,WAAW,0BAA0B,EAAE,MAAM,QAAQ,KAAK,OAAA,CAAQ;UAAA,CACnE;QAAA;MACL;MAEF,IAAI,gBAAgB,KACZ;QACJ;QACA;UACE,WAAW,4BAA4B,EAAE,KAAA,CAAM;UAC/C,GAAG,IAAI;QAAA;QAET,IAAI,IAAI,aAAa;MAAA;IACvB;EAEJ;AACF;",
|
|
6
6
|
"names": ["AvatarGroup"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../presence-indicator/src/presence-indicator.ts", "../../presence-indicator/src/presence-indicator.styles.ts", "../../react-presence-indicator/src/presence-indicator.tsx"],
|
|
4
|
-
"sourcesContent": ["export type PresenceStatus = 'online' | 'offline' | 'away' | 'busy' | 'dnd'\n\nexport interface PresenceProps {\n /** The presence status to display */\n status: PresenceStatus\n /** Show a text label alongside the indicator */\n showLabel?: boolean\n /** Custom label override */\n label?: string\n}\n\nexport interface PresenceAPI {\n /** ARIA attributes for the indicator */\n ariaProps: Record<string, string | number | boolean>\n /** CSS color for the status dot */\n color: string\n /** Human-readable label for the status */\n label: string\n /** Whether to show the label text */\n showLabel: boolean\n /** The current status */\n status: PresenceStatus\n}\n\nconst STATUS_COLORS: Record<PresenceStatus, string> = {\n online: 'green',\n offline: 'gray',\n away: 'yellow',\n busy: 'red',\n dnd: 'red',\n}\n\nconst STATUS_LABELS: Record<PresenceStatus, string> = {\n online: 'Online',\n offline: 'Offline',\n away: 'Away',\n busy: 'Busy',\n dnd: 'Do Not Disturb',\n}\n\nexport { STATUS_COLORS, STATUS_LABELS }\n\nexport function createPresence(props: PresenceProps): PresenceAPI {\n const { status, showLabel: showLabelProp = false, label: labelOverride } = props\n\n const color = STATUS_COLORS[status]\n const label = labelOverride ?? STATUS_LABELS[status]\n\n const ariaProps: Record<string, string | number | boolean> = {\n role: 'status',\n 'aria-label': label,\n }\n\n return {\n ariaProps,\n color,\n label,\n showLabel: showLabelProp,\n status,\n }\n}\n", "import { cva } from '@refraction-ui/shared'\n\nexport const presenceDotVariants = cva({\n base: 'inline-block rounded-full',\n variants: {\n status: {\n online: 'bg-success',\n offline: 'bg-
|
|
4
|
+
"sourcesContent": ["export type PresenceStatus = 'online' | 'offline' | 'away' | 'busy' | 'dnd'\n\nexport interface PresenceProps {\n /** The presence status to display */\n status: PresenceStatus\n /** Show a text label alongside the indicator */\n showLabel?: boolean\n /** Custom label override */\n label?: string\n}\n\nexport interface PresenceAPI {\n /** ARIA attributes for the indicator */\n ariaProps: Record<string, string | number | boolean>\n /** CSS color for the status dot */\n color: string\n /** Human-readable label for the status */\n label: string\n /** Whether to show the label text */\n showLabel: boolean\n /** The current status */\n status: PresenceStatus\n}\n\nconst STATUS_COLORS: Record<PresenceStatus, string> = {\n online: 'green',\n offline: 'gray',\n away: 'yellow',\n busy: 'red',\n dnd: 'red',\n}\n\nconst STATUS_LABELS: Record<PresenceStatus, string> = {\n online: 'Online',\n offline: 'Offline',\n away: 'Away',\n busy: 'Busy',\n dnd: 'Do Not Disturb',\n}\n\nexport { STATUS_COLORS, STATUS_LABELS }\n\nexport function createPresence(props: PresenceProps): PresenceAPI {\n const { status, showLabel: showLabelProp = false, label: labelOverride } = props\n\n const color = STATUS_COLORS[status]\n const label = labelOverride ?? STATUS_LABELS[status]\n\n const ariaProps: Record<string, string | number | boolean> = {\n role: 'status',\n 'aria-label': label,\n }\n\n return {\n ariaProps,\n color,\n label,\n showLabel: showLabelProp,\n status,\n }\n}\n", "import { cva } from '@refraction-ui/shared'\n\nexport const presenceDotVariants = cva({\n base: 'inline-block rounded-full',\n variants: {\n status: {\n online: 'bg-success',\n offline: 'bg-neutral',\n away: 'bg-warning',\n busy: 'bg-destructive',\n dnd: 'bg-destructive',\n },\n size: {\n sm: 'h-2 w-2',\n md: 'h-2.5 w-2.5',\n lg: 'h-3 w-3',\n },\n },\n defaultVariants: {\n status: 'offline',\n size: 'md',\n },\n})\n\nexport const presenceContainerStyles =\n 'inline-flex items-center gap-1.5'\n\nexport const presenceLabelStyles =\n 'text-sm text-muted-foreground'\n", "import * as React from 'react'\nimport {\n createPresence,\n presenceDotVariants,\n presenceContainerStyles,\n presenceLabelStyles,\n type PresenceStatus,\n} from '@refraction-ui/presence-indicator'\nimport { cn } from '@refraction-ui/shared'\n\nexport interface PresenceIndicatorProps {\n status: PresenceStatus\n showLabel?: boolean\n label?: string\n size?: 'sm' | 'md' | 'lg'\n className?: string\n}\n\nexport const PresenceIndicator = React.forwardRef<HTMLSpanElement, PresenceIndicatorProps>(\n function PresenceIndicator({ status, showLabel = false, label, size = 'md', className }, ref) {\n const api = createPresence({ status, showLabel, label })\n\n return React.createElement(\n 'span',\n { ref, ...api.ariaProps, className: cn(presenceContainerStyles, className) },\n React.createElement('span', {\n className: presenceDotVariants({ status, size }),\n }),\n api.showLabel &&\n React.createElement('span', { className: presenceLabelStyles }, api.label),\n )\n },\n)\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;AAwBA,IAAM,gBAAgD;EACpD,QAAQ;EACR,SAAS;EACT,MAAM;EACN,MAAM;EACN,KAAK;AACP;AAEA,IAAM,gBAAgD;EACpD,QAAQ;EACR,SAAS;EACT,MAAM;EACN,MAAM;EACN,KAAK;AACP;AAIO,SAAS,eAAe,OAAmC;AAChE,QAAM,EAAE,QAAQ,WAAW,gBAAgB,OAAO,OAAO,cAAA,IAAkB;AAE3E,QAAM,QAAQ,cAAc,MAAM;AAClC,QAAM,QAAQ,iBAAiB,cAAc,MAAM;AAEnD,QAAM,YAAuD;IAC3D,MAAM;IACN,cAAc;EAAA;AAGhB,SAAO;IACL;IACA;IACA;IACA,WAAW;IACX;EAAA;AAEJ;AC1DO,IAAM,sBAAsB,IAAI;EACrC,MAAM;EACN,UAAU;IACR,QAAQ;MACN,QAAQ;MACR,SAAS;MACT,MAAM;MACN,MAAM;MACN,KAAK;IAAA;IAEP,MAAM;MACJ,IAAI;MACJ,IAAI;MACJ,IAAI;IAAA;EACN;EAEF,iBAAiB;IACf,QAAQ;IACR,MAAM;EAAA;AAEV,CAAC;AAEM,IAAM,0BACX;AAEK,IAAM,sBACX;;;ACVK,IAAM,oBAA0B;EACrC,SAASA,mBAAkB,EAAE,QAAQ,YAAY,OAAO,OAAO,OAAO,MAAM,UAAA,GAAa,KAAK;AAC9F,UAAM,MAAM,eAAe,EAAE,QAAQ,WAAW,MAAA,CAAO;AAEvD,WAAa;MACX;MACA,EAAE,KAAK,GAAG,IAAI,WAAW,WAAW,GAAG,yBAAyB,SAAS,EAAA;MACnE,oBAAc,QAAQ;QAC1B,WAAW,oBAAoB,EAAE,QAAQ,KAAA,CAAM;MAAA,CAChD;MACD,IAAI,aACI,oBAAc,QAAQ,EAAE,WAAW,oBAAA,GAAuB,IAAI,KAAK;IAAA;EAE7E;AACF;",
|
|
6
6
|
"names": ["PresenceIndicator"]
|
|
7
7
|
}
|
|
@@ -49,8 +49,8 @@ var statusDotVariants = cva({
|
|
|
49
49
|
error: "bg-destructive",
|
|
50
50
|
warning: "bg-warning",
|
|
51
51
|
info: "bg-info",
|
|
52
|
-
pending: "bg-
|
|
53
|
-
neutral: "bg-
|
|
52
|
+
pending: "bg-pending",
|
|
53
|
+
neutral: "bg-neutral"
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
56
|
defaultVariants: {
|
|
@@ -65,8 +65,8 @@ var statusPulseVariants = cva({
|
|
|
65
65
|
error: "bg-destructive",
|
|
66
66
|
warning: "bg-warning",
|
|
67
67
|
info: "bg-info",
|
|
68
|
-
pending: "bg-
|
|
69
|
-
neutral: "bg-
|
|
68
|
+
pending: "bg-pending",
|
|
69
|
+
neutral: "bg-neutral"
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
defaultVariants: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../status-indicator/src/status-indicator.ts", "../../status-indicator/src/status-indicator.styles.ts", "../../react-status-indicator/src/status-indicator.tsx"],
|
|
4
|
-
"sourcesContent": ["export type StatusType = 'success' | 'error' | 'warning' | 'info' | 'pending' | 'neutral'\n\nexport interface StatusProps {\n /** The status type */\n type: StatusType\n /** Label to display alongside the status dot */\n label?: string\n /** Whether to show a pulse animation (primarily for 'pending' status) */\n pulse?: boolean\n}\n\nexport interface StatusAPI {\n /** ARIA attributes for the status indicator */\n ariaProps: Record<string, string | number | boolean>\n /** The status type */\n type: StatusType\n /** The display label */\n label: string\n /** Whether to show pulse animation */\n pulse: boolean\n /** CSS color class name for the dot */\n color: string\n}\n\nconst STATUS_INDICATOR_COLORS: Record<StatusType, string> = {\n success: 'green',\n error: 'red',\n warning: 'yellow',\n info: 'blue',\n pending: 'orange',\n neutral: 'gray',\n}\n\nconst STATUS_INDICATOR_LABELS: Record<StatusType, string> = {\n success: 'Success',\n error: 'Error',\n warning: 'Warning',\n info: 'Info',\n pending: 'Pending',\n neutral: 'Neutral',\n}\n\nexport {\n STATUS_INDICATOR_COLORS as STATUS_COLORS,\n STATUS_INDICATOR_LABELS as STATUS_LABELS,\n}\n\nexport function createStatusIndicator(props: StatusProps): StatusAPI {\n const { type, label: labelOverride, pulse: pulseOverride } = props\n\n const color = STATUS_INDICATOR_COLORS[type]\n const label = labelOverride ?? STATUS_INDICATOR_LABELS[type]\n const pulse = pulseOverride ?? (type === 'pending')\n\n const ariaProps: Record<string, string | number | boolean> = {\n role: 'status',\n 'aria-label': label,\n }\n\n return {\n ariaProps,\n type,\n label,\n pulse,\n color,\n }\n}\n", "import { cva } from '@refraction-ui/shared'\n\nexport const statusContainerStyles =\n 'inline-flex items-center gap-1.5'\n\nexport const statusDotVariants = cva({\n base: 'inline-block h-2 w-2 rounded-full',\n variants: {\n type: {\n success: 'bg-success',\n error: 'bg-destructive',\n warning: 'bg-warning',\n info: 'bg-info',\n pending: 'bg-
|
|
4
|
+
"sourcesContent": ["export type StatusType = 'success' | 'error' | 'warning' | 'info' | 'pending' | 'neutral'\n\nexport interface StatusProps {\n /** The status type */\n type: StatusType\n /** Label to display alongside the status dot */\n label?: string\n /** Whether to show a pulse animation (primarily for 'pending' status) */\n pulse?: boolean\n}\n\nexport interface StatusAPI {\n /** ARIA attributes for the status indicator */\n ariaProps: Record<string, string | number | boolean>\n /** The status type */\n type: StatusType\n /** The display label */\n label: string\n /** Whether to show pulse animation */\n pulse: boolean\n /** CSS color class name for the dot */\n color: string\n}\n\nconst STATUS_INDICATOR_COLORS: Record<StatusType, string> = {\n success: 'green',\n error: 'red',\n warning: 'yellow',\n info: 'blue',\n pending: 'orange',\n neutral: 'gray',\n}\n\nconst STATUS_INDICATOR_LABELS: Record<StatusType, string> = {\n success: 'Success',\n error: 'Error',\n warning: 'Warning',\n info: 'Info',\n pending: 'Pending',\n neutral: 'Neutral',\n}\n\nexport {\n STATUS_INDICATOR_COLORS as STATUS_COLORS,\n STATUS_INDICATOR_LABELS as STATUS_LABELS,\n}\n\nexport function createStatusIndicator(props: StatusProps): StatusAPI {\n const { type, label: labelOverride, pulse: pulseOverride } = props\n\n const color = STATUS_INDICATOR_COLORS[type]\n const label = labelOverride ?? STATUS_INDICATOR_LABELS[type]\n const pulse = pulseOverride ?? (type === 'pending')\n\n const ariaProps: Record<string, string | number | boolean> = {\n role: 'status',\n 'aria-label': label,\n }\n\n return {\n ariaProps,\n type,\n label,\n pulse,\n color,\n }\n}\n", "import { cva } from '@refraction-ui/shared'\n\nexport const statusContainerStyles =\n 'inline-flex items-center gap-1.5'\n\nexport const statusDotVariants = cva({\n base: 'inline-block h-2 w-2 rounded-full',\n variants: {\n type: {\n success: 'bg-success',\n error: 'bg-destructive',\n warning: 'bg-warning',\n info: 'bg-info',\n pending: 'bg-pending',\n neutral: 'bg-neutral',\n },\n },\n defaultVariants: {\n type: 'neutral',\n },\n})\n\nexport const statusPulseVariants = cva({\n base: 'animate-pulse inline-block h-2 w-2 rounded-full',\n variants: {\n type: {\n success: 'bg-success',\n error: 'bg-destructive',\n warning: 'bg-warning',\n info: 'bg-info',\n pending: 'bg-pending',\n neutral: 'bg-neutral',\n },\n },\n defaultVariants: {\n type: 'pending',\n },\n})\n\nexport const statusLabelStyles =\n 'text-sm text-muted-foreground'\n", "import * as React from 'react'\nimport {\n createStatusIndicator,\n statusContainerStyles,\n statusDotVariants,\n statusPulseVariants,\n statusLabelStyles,\n type StatusType,\n} from '@refraction-ui/status-indicator'\nimport { cn } from '@refraction-ui/shared'\n\nexport interface StatusIndicatorProps {\n type: StatusType\n /** Explicit text label. Takes precedence over `children`. */\n label?: string\n /** Composable label content. Used when `label` is omitted. */\n children?: React.ReactNode\n pulse?: boolean\n showLabel?: boolean\n className?: string\n}\n\n/** Best ARIA-label: explicit prop wins, then string children, else headless default. */\nfunction deriveAriaLabel(\n label: string | undefined,\n children: React.ReactNode,\n fallback: string,\n): string {\n if (label) return label\n if (typeof children === 'string' || typeof children === 'number') {\n return String(children)\n }\n return fallback\n}\n\nexport const StatusIndicator = React.forwardRef<HTMLSpanElement, StatusIndicatorProps>(\n function StatusIndicator({ type, label, children, pulse, showLabel = true, className }, ref) {\n const api = createStatusIndicator({ type, label, pulse })\n const ariaLabel = deriveAriaLabel(label, children, api.label)\n const visibleLabel: React.ReactNode = label ?? children ?? api.label\n\n const dotClassName = api.pulse\n ? statusPulseVariants({ type })\n : statusDotVariants({ type })\n\n return (\n <span\n ref={ref}\n {...api.ariaProps}\n aria-label={ariaLabel}\n className={cn(statusContainerStyles, className)}\n >\n <span className={dotClassName} />\n {showLabel && <span className={statusLabelStyles}>{visibleLabel}</span>}\n </span>\n )\n },\n)\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;AAwBA,IAAM,0BAAsD;EAC1D,SAAS;EACT,OAAO;EACP,SAAS;EACT,MAAM;EACN,SAAS;EACT,SAAS;AACX;AAEA,IAAM,0BAAsD;EAC1D,SAAS;EACT,OAAO;EACP,SAAS;EACT,MAAM;EACN,SAAS;EACT,SAAS;AACX;AAOO,SAAS,sBAAsB,OAA+B;AACnE,QAAM,EAAE,MAAM,OAAO,eAAe,OAAO,cAAA,IAAkB;AAE7D,QAAM,QAAQ,wBAAwB,IAAI;AAC1C,QAAM,QAAQ,iBAAiB,wBAAwB,IAAI;AAC3D,QAAM,QAAQ,iBAAkB,SAAS;AAEzC,QAAM,YAAuD;IAC3D,MAAM;IACN,cAAc;EAAA;AAGhB,SAAO;IACL;IACA;IACA;IACA;IACA;EAAA;AAEJ;AChEO,IAAM,wBACX;AAEK,IAAM,oBAAoB,IAAI;EACnC,MAAM;EACN,UAAU;IACR,MAAM;MACJ,SAAS;MACT,OAAO;MACP,SAAS;MACT,MAAM;MACN,SAAS;MACT,SAAS;IAAA;EACX;EAEF,iBAAiB;IACf,MAAM;EAAA;AAEV,CAAC;AAEM,IAAM,sBAAsB,IAAI;EACrC,MAAM;EACN,UAAU;IACR,MAAM;MACJ,SAAS;MACT,OAAO;MACP,SAAS;MACT,MAAM;MACN,SAAS;MACT,SAAS;IAAA;EACX;EAEF,iBAAiB;IACf,MAAM;EAAA;AAEV,CAAC;AAEM,IAAM,oBACX;;;;ACjBF,SAAS,gBACP,OACA,UACA,UACQ;AACR,MAAI,MAAO,QAAO;AAClB,MAAI,OAAO,aAAa,YAAY,OAAO,aAAa,UAAU;AAChE,WAAO,OAAO,QAAQ;EACxB;AACA,SAAO;AACT;AAEO,IAAM,kBAAwB;EACnC,SAASA,iBAAgB,EAAE,MAAM,OAAO,UAAU,OAAO,YAAY,MAAM,UAAA,GAAa,KAAK;AAC7F,UAAM,MAAM,sBAAsB,EAAE,MAAM,OAAO,MAAA,CAAO;AACxD,UAAM,YAAY,gBAAgB,OAAO,UAAU,IAAI,KAAK;AAC5D,UAAM,eAAgC,SAAS,YAAY,IAAI;AAE/D,UAAM,eAAe,IAAI,QACrB,oBAAoB,EAAE,KAAA,CAAM,IAC5B,kBAAkB,EAAE,KAAA,CAAM;AAE9B,WACE;MAAC;MAAA;QACC;QACC,GAAG,IAAI;QACR,cAAY;QACZ,WAAW,GAAG,uBAAuB,SAAS;QAE9C,UAAA;UAAA,oBAAC,QAAA,EAAK,WAAW,aAAA,CAAc;UAC9B,aAAa,oBAAC,QAAA,EAAK,WAAW,mBAAoB,UAAA,aAAA,CAAa;QAAA;MAAA;IAAA;EAGpE;AACF;",
|
|
6
6
|
"names": ["StatusIndicator"]
|
|
7
7
|
}
|
package/dist/styles.css
CHANGED
|
@@ -65,6 +65,10 @@
|
|
|
65
65
|
(Material blue) — a deliberate small cross-framework delta. */
|
|
66
66
|
--info: 217 91% 60%;
|
|
67
67
|
--info-foreground: 0 0% 100%;
|
|
68
|
+
--pending: 25 95% 53%;
|
|
69
|
+
--pending-foreground: 0 0% 100%;
|
|
70
|
+
--neutral: 220 9% 64%;
|
|
71
|
+
--neutral-foreground: 240 10% 10%;
|
|
68
72
|
|
|
69
73
|
--border: 240 6% 92%;
|
|
70
74
|
--input: 240 6% 92%;
|
|
@@ -276,6 +280,10 @@
|
|
|
276
280
|
/* Lightened from 60% (light) to 65% lightness for contrast on dark surfaces */
|
|
277
281
|
--info: 217 91% 65%;
|
|
278
282
|
--info-foreground: 0 0% 98%;
|
|
283
|
+
--pending: 25 95% 53%;
|
|
284
|
+
--pending-foreground: 0 0% 100%;
|
|
285
|
+
--neutral: 220 9% 64%;
|
|
286
|
+
--neutral-foreground: 240 10% 10%;
|
|
279
287
|
|
|
280
288
|
--border: 240 5% 16%;
|
|
281
289
|
--input: 240 5% 16%;
|
package/package.json
CHANGED