@refraction-ui/react 0.19.2 → 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.
Files changed (59) hide show
  1. package/dist/{chunk-UJ6BBWQM.js → chunk-TOZBR4GL.js} +3 -3
  2. package/dist/{chunk-UJ6BBWQM.js.map → chunk-TOZBR4GL.js.map} +1 -1
  3. package/dist/chunk-WSPJTQAV.js +59 -0
  4. package/dist/chunk-WSPJTQAV.js.map +7 -0
  5. package/dist/form.cjs.map +1 -1
  6. package/dist/form.js.map +1 -1
  7. package/dist/index.cjs +2590 -33429
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.cts +1 -0
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.js +1 -0
  12. package/dist/internal/react-badge/index.d.cts +5 -0
  13. package/dist/internal/react-badge/index.d.ts +5 -0
  14. package/dist/internal/react-callout/index.d.cts +4 -0
  15. package/dist/internal/react-callout/index.d.ts +4 -0
  16. package/dist/internal/react-card/index.d.cts +8 -1
  17. package/dist/internal/react-card/index.d.ts +8 -1
  18. package/dist/internal/react-form/index.d.cts +2 -21
  19. package/dist/internal/react-form/index.d.ts +2 -21
  20. package/dist/internal/react-link-card/index.d.cts +8 -2
  21. package/dist/internal/react-link-card/index.d.ts +8 -2
  22. package/dist/internal/react-slot/index.d.cts +23 -0
  23. package/dist/internal/react-slot/index.d.ts +23 -0
  24. package/dist/react-analytics.js +6 -6
  25. package/dist/react-analytics.js.map +3 -3
  26. package/dist/react-avatar-group.js +5 -5
  27. package/dist/react-avatar-group.js.map +1 -1
  28. package/dist/react-badge.js +17 -1
  29. package/dist/react-badge.js.map +2 -2
  30. package/dist/react-callout.js +19 -3
  31. package/dist/react-callout.js.map +2 -2
  32. package/dist/react-card.js +18 -2
  33. package/dist/react-card.js.map +2 -2
  34. package/dist/react-empty-state.js +2 -2
  35. package/dist/react-empty-state.js.map +1 -1
  36. package/dist/react-input.js +1 -1
  37. package/dist/react-link-card.js +15 -1
  38. package/dist/react-link-card.js.map +2 -2
  39. package/dist/react-password-input.js +1 -1
  40. package/dist/react-presence-indicator.js +5 -5
  41. package/dist/react-presence-indicator.js.map +1 -1
  42. package/dist/react-progress-display.js +2 -2
  43. package/dist/react-progress-display.js.map +1 -1
  44. package/dist/react-slot.js +7 -0
  45. package/dist/react-slot.js.map +7 -0
  46. package/dist/react-status-indicator.js +12 -12
  47. package/dist/react-status-indicator.js.map +1 -1
  48. package/dist/react-toast.js +3 -3
  49. package/dist/react-toast.js.map +2 -2
  50. package/dist/styles.css +15 -0
  51. package/package.json +2 -1
  52. package/dist/applicationinsights-web-H7OBLIVJ.js +0 -23393
  53. package/dist/applicationinsights-web-H7OBLIVJ.js.map +0 -1
  54. package/dist/chunk-GFXGXZDB.js +0 -23543
  55. package/dist/chunk-GFXGXZDB.js.map +0 -7
  56. package/dist/chunk-O4R4W2KY.js +0 -6460
  57. package/dist/chunk-O4R4W2KY.js.map +0 -7
  58. package/dist/module-X3HTTRQK.js +0 -6438
  59. package/dist/module-X3HTTRQK.js.map +0 -1
@@ -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-green-500',\n error: 'bg-red-500',\n warning: 'bg-yellow-500',\n info: 'bg-blue-500',\n pending: 'bg-orange-500',\n neutral: 'bg-gray-400',\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-green-500',\n error: 'bg-red-500',\n warning: 'bg-yellow-500',\n info: 'bg-blue-500',\n pending: 'bg-orange-500',\n neutral: 'bg-gray-400',\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"],
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
  }
@@ -129,9 +129,9 @@ var toastVariants = cva({
129
129
  variants: {
130
130
  variant: {
131
131
  default: "border bg-background text-foreground",
132
- success: "border-l-4 border-green-500/50 bg-green-50 text-green-900 dark:bg-green-950 dark:text-green-100",
133
- error: "border-l-4 border-red-500/50 bg-red-50 text-red-900 dark:bg-red-950 dark:text-red-100",
134
- warning: "border-l-4 border-amber-500/50 bg-amber-50 text-amber-900 dark:bg-amber-950 dark:text-amber-100"
132
+ success: "border-l-4 border-success/50 bg-success/10 text-success",
133
+ error: "border-l-4 border-destructive/50 bg-destructive/10 text-destructive",
134
+ warning: "border-l-4 border-warning/50 bg-warning/10 text-warning"
135
135
  }
136
136
  },
137
137
  defaultVariants: {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../toast/src/toast.ts", "../../toast/src/toast.styles.ts", "../../react-toast/src/toast.tsx"],
4
- "sourcesContent": ["import type { AccessibilityProps } from '@refraction-ui/shared'\nimport { generateId } from '@refraction-ui/shared'\n\nexport type ToastVariant = 'default' | 'success' | 'error' | 'warning'\n\n/** Icon name for each toast variant — non-color indicator for colorblind safety */\nconst TOAST_ICONS: Record<ToastVariant, string> = {\n default: 'info-circle',\n success: 'check-circle',\n error: 'x-circle',\n warning: 'alert-triangle',\n}\n\n/** Get the icon name for a toast variant (colorblind-safe: meaning not conveyed by color alone) */\nexport function getToastIcon(variant: ToastVariant): string {\n return TOAST_ICONS[variant]\n}\n\nexport interface ToastProps {\n /** Visual variant */\n variant?: ToastVariant\n /** Auto-dismiss duration in ms (default: 3000). Set to 0 to disable. */\n duration?: number\n /** Whether the toast is open (controlled) */\n open?: boolean\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void\n /** Elapsed-time clock for timer pause/resume math (ms). Default: ambient `Date.now()` — inject for deterministic tests. */\n now?: () => number\n}\n\nexport interface ToastState {\n open: boolean\n variant: ToastVariant\n}\n\nexport interface ToastAPI {\n /** Current toast state */\n state: ToastState\n /** ARIA attributes for the toast element */\n ariaProps: Partial<AccessibilityProps>\n /** Dismiss the toast */\n dismiss(): void\n /** Start the auto-dismiss timer */\n startTimer(): void\n /** Pause the auto-dismiss timer (e.g. on hover) */\n pauseTimer(): void\n /** Resume the auto-dismiss timer */\n resumeTimer(): void\n}\n\nexport function createToast(props: ToastProps = {}): ToastAPI {\n const {\n variant = 'default',\n duration = 3000,\n open: controlledOpen,\n onOpenChange,\n } = props\n\n // Injection boundary: ambient time is the default; inject `now` for deterministic timer math.\n const now = props.now ?? (() => Date.now())\n let isOpen = controlledOpen ?? true\n let timerId: ReturnType<typeof setTimeout> | null = null\n let remaining = duration\n let startedAt = 0\n\n function dismiss(): void {\n clearTimer()\n isOpen = false\n onOpenChange?.(false)\n }\n\n function clearTimer(): void {\n if (timerId !== null) {\n clearTimeout(timerId)\n timerId = null\n }\n }\n\n function startTimer(): void {\n if (duration <= 0) return\n clearTimer()\n remaining = duration\n startedAt = now()\n timerId = setTimeout(dismiss, remaining)\n }\n\n function pauseTimer(): void {\n if (timerId === null) return\n clearTimer()\n remaining = remaining - (now() - startedAt)\n if (remaining < 0) remaining = 0\n }\n\n function resumeTimer(): void {\n if (duration <= 0 || remaining <= 0) return\n clearTimer()\n startedAt = now()\n timerId = setTimeout(dismiss, remaining)\n }\n\n const ariaProps: Partial<AccessibilityProps> = {\n role: 'alert',\n 'aria-live': 'assertive',\n 'aria-atomic': true,\n }\n\n return {\n state: {\n get open() {\n return controlledOpen !== undefined ? controlledOpen : isOpen\n },\n variant,\n },\n ariaProps,\n dismiss,\n startTimer,\n pauseTimer,\n resumeTimer,\n }\n}\n\n/** Entry in the toast manager */\nexport interface ToastEntry {\n id: string\n message: string\n variant: ToastVariant\n duration: number\n createdAt: number\n}\n\nexport interface ToastManagerAPI {\n /** Add a new toast. Returns the toast id. */\n toast(message: string, opts?: { variant?: ToastVariant; duration?: number }): string\n /** Dismiss a toast by id */\n dismiss(id: string): void\n /** Current toast list (read-only) */\n readonly toasts: ReadonlyArray<ToastEntry>\n /** Subscribe to toast list changes. Returns unsubscribe function. */\n subscribe(fn: (toasts: ReadonlyArray<ToastEntry>) => void): () => void\n}\n\nexport interface ToastManagerConfig {\n /** Clock for entry `createdAt` stamps (ms). Default: ambient `Date.now()` — inject for deterministic tests. */\n now?: () => number\n}\n\nexport function createToastManager(config: ToastManagerConfig = {}): ToastManagerAPI {\n // Injection boundary: ambient time is the default; inject `now` for deterministic createdAt.\n const now = config.now ?? (() => Date.now())\n let toasts: ToastEntry[] = []\n const listeners = new Set<(toasts: ReadonlyArray<ToastEntry>) => void>()\n const timers = new Map<string, ReturnType<typeof setTimeout>>()\n\n function notify(): void {\n const snapshot = [...toasts]\n for (const fn of listeners) {\n fn(snapshot)\n }\n }\n\n function dismiss(id: string): void {\n const timer = timers.get(id)\n if (timer) {\n clearTimeout(timer)\n timers.delete(id)\n }\n toasts = toasts.filter((t) => t.id !== id)\n notify()\n }\n\n function toast(\n message: string,\n opts?: { variant?: ToastVariant; duration?: number },\n ): string {\n const id = generateId('rfr-toast')\n const variant = opts?.variant ?? 'default'\n const duration = opts?.duration ?? 3000\n\n const entry: ToastEntry = {\n id,\n message,\n variant,\n duration,\n createdAt: now(),\n }\n\n toasts = [...toasts, entry]\n notify()\n\n if (duration > 0) {\n const timer = setTimeout(() => dismiss(id), duration)\n timers.set(id, timer)\n }\n\n return id\n }\n\n function subscribe(fn: (toasts: ReadonlyArray<ToastEntry>) => void): () => void {\n listeners.add(fn)\n return () => {\n listeners.delete(fn)\n }\n }\n\n return {\n toast,\n dismiss,\n get toasts() {\n return toasts\n },\n subscribe,\n }\n}\n", "import { cva } from '@refraction-ui/shared'\n\nexport const toastVariants = cva({\n base: 'pointer-events-auto relative flex w-full items-center justify-between gap-2 overflow-hidden rounded-lg border p-4 shadow-lg transition-all',\n variants: {\n variant: {\n default: 'border bg-background text-foreground',\n success:\n 'border-l-4 border-green-500/50 bg-green-50 text-green-900 dark:bg-green-950 dark:text-green-100',\n error:\n 'border-l-4 border-red-500/50 bg-red-50 text-red-900 dark:bg-red-950 dark:text-red-100',\n warning:\n 'border-l-4 border-amber-500/50 bg-amber-50 text-amber-900 dark:bg-amber-950 dark:text-amber-100',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n})\n", "import * as React from 'react'\nimport {\n createToast,\n createToastManager,\n toastVariants,\n type ToastVariant,\n type ToastEntry,\n type ToastManagerAPI,\n} from '@refraction-ui/toast'\nimport { cn, devWarn } from '@refraction-ui/shared'\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\ninterface ToastContextValue {\n manager: ToastManagerAPI\n}\n\nconst ToastContext = React.createContext<ToastContextValue | null>(null)\n\nfunction useToastContext(): ToastContextValue {\n const ctx = React.useContext(ToastContext)\n if (!ctx) {\n devWarn(\n 'react-toast/use-toast-outside-provider',\n 'useToast() was called outside a <ToastProvider>. Wrap your app (or the consuming subtree) in <ToastProvider> so the toast context is available.',\n )\n throw new Error('useToast must be used within a <ToastProvider>')\n }\n return ctx\n}\n\n// ---------------------------------------------------------------------------\n// ToastProvider\n// ---------------------------------------------------------------------------\n\nexport interface ToastProviderProps {\n children?: React.ReactNode\n}\n\nexport function ToastProvider({ children }: ToastProviderProps) {\n const managerRef = React.useRef<ToastManagerAPI | null>(null)\n if (managerRef.current === null) {\n managerRef.current = createToastManager()\n }\n\n const ctx = React.useMemo<ToastContextValue>(\n () => ({ manager: managerRef.current! }),\n [],\n )\n\n return React.createElement(ToastContext.Provider, { value: ctx }, children)\n}\n\n// ---------------------------------------------------------------------------\n// useToast hook\n// ---------------------------------------------------------------------------\n\nexport interface UseToastReturn {\n /** Show a new toast */\n toast: (message: string, opts?: { variant?: ToastVariant; duration?: number }) => string\n /** Dismiss a toast by id */\n dismiss: (id: string) => void\n /** Current toast entries */\n toasts: ReadonlyArray<ToastEntry>\n}\n\nexport function useToast(): UseToastReturn {\n const { manager } = useToastContext()\n const [toasts, setToasts] = React.useState<ReadonlyArray<ToastEntry>>(manager.toasts)\n\n React.useEffect(() => {\n // Sync initial state\n setToasts(manager.toasts)\n const unsub = manager.subscribe(setToasts)\n return unsub\n }, [manager])\n\n return {\n toast: manager.toast,\n dismiss: manager.dismiss,\n toasts,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Toast (individual toast component)\n// ---------------------------------------------------------------------------\n\nexport interface ToastProps extends React.HTMLAttributes<HTMLDivElement> {\n entry: ToastEntry\n onDismiss?: (id: string) => void\n}\n\nexport const Toast = React.forwardRef<HTMLDivElement, ToastProps>(\n function Toast({ entry, onDismiss, className, children, onMouseEnter, onMouseLeave, ...props }, ref) {\n const api = React.useMemo(\n () => createToast({ variant: entry.variant, duration: entry.duration }),\n [entry.variant, entry.duration],\n )\n\n // Start auto-dismiss timer on mount\n React.useEffect(() => {\n api.startTimer()\n return () => api.pauseTimer()\n }, [api])\n\n const handleMouseEnter = (e: React.MouseEvent<HTMLDivElement>) => {\n api.pauseTimer()\n onMouseEnter?.(e)\n }\n\n const handleMouseLeave = (e: React.MouseEvent<HTMLDivElement>) => {\n api.resumeTimer()\n onMouseLeave?.(e)\n }\n\n return React.createElement(\n 'div',\n {\n ref,\n className: cn(toastVariants({ variant: entry.variant }), className),\n ...api.ariaProps,\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n ...props,\n },\n React.createElement('div', { className: 'flex-1' }, entry.message),\n children,\n onDismiss &&\n React.createElement(\n 'button',\n {\n type: 'button',\n className: 'shrink-0',\n onClick: () => onDismiss(entry.id),\n 'aria-label': 'Dismiss',\n },\n '\\u00d7',\n ),\n )\n },\n)\n\n// ---------------------------------------------------------------------------\n// Toaster (container that renders all active toasts)\n// ---------------------------------------------------------------------------\n\nexport interface ToasterProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport const Toaster = React.forwardRef<HTMLDivElement, ToasterProps>(\n function Toaster({ className, ...props }, ref) {\n const { toasts, dismiss } = useToast()\n\n return React.createElement(\n 'div',\n {\n ref,\n className: cn(\n 'fixed bottom-4 right-4 z-50 flex flex-col gap-2 w-full max-w-sm pointer-events-none',\n className,\n ),\n ...props,\n },\n toasts.map((entry) =>\n React.createElement(Toast, {\n key: entry.id,\n entry,\n onDismiss: dismiss,\n }),\n ),\n )\n },\n)\n"],
5
- "mappings": ";;;;;;;;;;;AAmDO,SAAS,YAAY,QAAoB,CAAA,GAAc;AAC5D,QAAM;IACJ,UAAU;IACV,WAAW;IACX,MAAM;IACN;EAAA,IACE;AAGJ,QAAM,MAAM,MAAM,QAAQ,MAAM,KAAK,IAAA;AACrC,MAAI,SAAS,kBAAkB;AAC/B,MAAI,UAAgD;AACpD,MAAI,YAAY;AAChB,MAAI,YAAY;AAEhB,WAAS,UAAgB;AACvB,eAAA;AACA,aAAS;AACT,mBAAe,KAAK;EACtB;AAEA,WAAS,aAAmB;AAC1B,QAAI,YAAY,MAAM;AACpB,mBAAa,OAAO;AACpB,gBAAU;IACZ;EACF;AAEA,WAAS,aAAmB;AAC1B,QAAI,YAAY,EAAG;AACnB,eAAA;AACA,gBAAY;AACZ,gBAAY,IAAA;AACZ,cAAU,WAAW,SAAS,SAAS;EACzC;AAEA,WAAS,aAAmB;AAC1B,QAAI,YAAY,KAAM;AACtB,eAAA;AACA,gBAAY,aAAa,IAAA,IAAQ;AACjC,QAAI,YAAY,EAAG,aAAY;EACjC;AAEA,WAAS,cAAoB;AAC3B,QAAI,YAAY,KAAK,aAAa,EAAG;AACrC,eAAA;AACA,gBAAY,IAAA;AACZ,cAAU,WAAW,SAAS,SAAS;EACzC;AAEA,QAAM,YAAyC;IAC7C,MAAM;IACN,aAAa;IACb,eAAe;EAAA;AAGjB,SAAO;IACL,OAAO;MACL,IAAI,OAAO;AACT,eAAO,mBAAmB,SAAY,iBAAiB;MACzD;MACA;IAAA;IAEF;IACA;IACA;IACA;IACA;EAAA;AAEJ;AA2BO,SAAS,mBAAmB,SAA6B,CAAA,GAAqB;AAEnF,QAAM,MAAM,OAAO,QAAQ,MAAM,KAAK,IAAA;AACtC,MAAI,SAAuB,CAAA;AAC3B,QAAM,YAAA,oBAAgB,IAAA;AACtB,QAAM,SAAA,oBAAa,IAAA;AAEnB,WAAS,SAAe;AACtB,UAAM,WAAW,CAAC,GAAG,MAAM;AAC3B,eAAW,MAAM,WAAW;AAC1B,SAAG,QAAQ;IACb;EACF;AAEA,WAAS,QAAQ,IAAkB;AACjC,UAAM,QAAQ,OAAO,IAAI,EAAE;AAC3B,QAAI,OAAO;AACT,mBAAa,KAAK;AAClB,aAAO,OAAO,EAAE;IAClB;AACA,aAAS,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AACzC,WAAA;EACF;AAEA,WAAS,MACP,SACA,MACQ;AACR,UAAM,KAAK,WAAW,WAAW;AACjC,UAAM,UAAU,MAAM,WAAW;AACjC,UAAM,WAAW,MAAM,YAAY;AAEnC,UAAM,QAAoB;MACxB;MACA;MACA;MACA;MACA,WAAW,IAAA;IAAI;AAGjB,aAAS,CAAC,GAAG,QAAQ,KAAK;AAC1B,WAAA;AAEA,QAAI,WAAW,GAAG;AAChB,YAAM,QAAQ,WAAW,MAAM,QAAQ,EAAE,GAAG,QAAQ;AACpD,aAAO,IAAI,IAAI,KAAK;IACtB;AAEA,WAAO;EACT;AAEA,WAAS,UAAU,IAA6D;AAC9E,cAAU,IAAI,EAAE;AAChB,WAAO,MAAM;AACX,gBAAU,OAAO,EAAE;IACrB;EACF;AAEA,SAAO;IACL;IACA;IACA,IAAI,SAAS;AACX,aAAO;IACT;IACA;EAAA;AAEJ;ACnNO,IAAM,gBAAgB,IAAI;EAC/B,MAAM;EACN,UAAU;IACR,SAAS;MACP,SAAS;MACT,SACE;MACF,OACE;MACF,SACE;IAAA;EACJ;EAEF,iBAAiB;IACf,SAAS;EAAA;AAEb,CAAC;;;ACCD,IAAM,eAAqB,oBAAwC,IAAI;AAEvE,SAAS,kBAAqC;AAC5C,QAAM,MAAY,iBAAW,YAAY;AACzC,MAAI,CAAC,KAAK;AACR;MACE;MACA;IAAA;AAEF,UAAM,IAAI,MAAM,gDAAgD;EAClE;AACA,SAAO;AACT;AAUO,SAAS,cAAc,EAAE,SAAA,GAAgC;AAC9D,QAAM,aAAmB,aAA+B,IAAI;AAC5D,MAAI,WAAW,YAAY,MAAM;AAC/B,eAAW,UAAU,mBAAA;EACvB;AAEA,QAAM,MAAY;IAChB,OAAO,EAAE,SAAS,WAAW,QAAA;IAC7B,CAAA;EAAC;AAGH,SAAa,oBAAc,aAAa,UAAU,EAAE,OAAO,IAAA,GAAO,QAAQ;AAC5E;AAeO,SAAS,WAA2B;AACzC,QAAM,EAAE,QAAA,IAAY,gBAAA;AACpB,QAAM,CAAC,QAAQ,SAAS,IAAU,eAAoC,QAAQ,MAAM;AAE9E,EAAA,gBAAU,MAAM;AAEpB,cAAU,QAAQ,MAAM;AACxB,UAAM,QAAQ,QAAQ,UAAU,SAAS;AACzC,WAAO;EACT,GAAG,CAAC,OAAO,CAAC;AAEZ,SAAO;IACL,OAAO,QAAQ;IACf,SAAS,QAAQ;IACjB;EAAA;AAEJ;AAWO,IAAM,QAAc;EACzB,SAASA,OAAM,EAAE,OAAO,WAAW,WAAW,UAAU,cAAc,cAAc,GAAG,MAAA,GAAS,KAAK;AACnG,UAAM,MAAY;MAChB,MAAM,YAAY,EAAE,SAAS,MAAM,SAAS,UAAU,MAAM,SAAA,CAAU;MACtE,CAAC,MAAM,SAAS,MAAM,QAAQ;IAAA;AAI1B,IAAA,gBAAU,MAAM;AACpB,UAAI,WAAA;AACJ,aAAO,MAAM,IAAI,WAAA;IACnB,GAAG,CAAC,GAAG,CAAC;AAER,UAAM,mBAAmB,CAAC,MAAwC;AAChE,UAAI,WAAA;AACJ,qBAAe,CAAC;IAClB;AAEA,UAAM,mBAAmB,CAAC,MAAwC;AAChE,UAAI,YAAA;AACJ,qBAAe,CAAC;IAClB;AAEA,WAAa;MACX;MACA;QACE;QACA,WAAW,GAAG,cAAc,EAAE,SAAS,MAAM,QAAA,CAAS,GAAG,SAAS;QAClE,GAAG,IAAI;QACP,cAAc;QACd,cAAc;QACd,GAAG;MAAA;MAEC,oBAAc,OAAO,EAAE,WAAW,SAAA,GAAY,MAAM,OAAO;MACjE;MACA,aACQ;QACJ;QACA;UACE,MAAM;UACN,WAAW;UACX,SAAS,MAAM,UAAU,MAAM,EAAE;UACjC,cAAc;QAAA;QAEhB;MAAA;IACF;EAEN;AACF;AAQO,IAAM,UAAgB;EAC3B,SAASC,SAAQ,EAAE,WAAW,GAAG,MAAA,GAAS,KAAK;AAC7C,UAAM,EAAE,QAAQ,QAAA,IAAY,SAAA;AAE5B,WAAa;MACX;MACA;QACE;QACA,WAAW;UACT;UACA;QAAA;QAEF,GAAG;MAAA;MAEL,OAAO;QAAI,CAAC,UACJ,oBAAc,OAAO;UACzB,KAAK,MAAM;UACX;UACA,WAAW;QAAA,CACZ;MAAA;IACH;EAEJ;AACF;",
4
+ "sourcesContent": ["import type { AccessibilityProps } from '@refraction-ui/shared'\nimport { generateId } from '@refraction-ui/shared'\n\nexport type ToastVariant = 'default' | 'success' | 'error' | 'warning'\n\n/** Icon name for each toast variant — non-color indicator for colorblind safety */\nconst TOAST_ICONS: Record<ToastVariant, string> = {\n default: 'info-circle',\n success: 'check-circle',\n error: 'x-circle',\n warning: 'alert-triangle',\n}\n\n/** Get the icon name for a toast variant (colorblind-safe: meaning not conveyed by color alone) */\nexport function getToastIcon(variant: ToastVariant): string {\n return TOAST_ICONS[variant]\n}\n\nexport interface ToastProps {\n /** Visual variant */\n variant?: ToastVariant\n /** Auto-dismiss duration in ms (default: 3000). Set to 0 to disable. */\n duration?: number\n /** Whether the toast is open (controlled) */\n open?: boolean\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void\n /** Elapsed-time clock for timer pause/resume math (ms). Default: ambient `Date.now()` — inject for deterministic tests. */\n now?: () => number\n}\n\nexport interface ToastState {\n open: boolean\n variant: ToastVariant\n}\n\nexport interface ToastAPI {\n /** Current toast state */\n state: ToastState\n /** ARIA attributes for the toast element */\n ariaProps: Partial<AccessibilityProps>\n /** Dismiss the toast */\n dismiss(): void\n /** Start the auto-dismiss timer */\n startTimer(): void\n /** Pause the auto-dismiss timer (e.g. on hover) */\n pauseTimer(): void\n /** Resume the auto-dismiss timer */\n resumeTimer(): void\n}\n\nexport function createToast(props: ToastProps = {}): ToastAPI {\n const {\n variant = 'default',\n duration = 3000,\n open: controlledOpen,\n onOpenChange,\n } = props\n\n // Injection boundary: ambient time is the default; inject `now` for deterministic timer math.\n const now = props.now ?? (() => Date.now())\n let isOpen = controlledOpen ?? true\n let timerId: ReturnType<typeof setTimeout> | null = null\n let remaining = duration\n let startedAt = 0\n\n function dismiss(): void {\n clearTimer()\n isOpen = false\n onOpenChange?.(false)\n }\n\n function clearTimer(): void {\n if (timerId !== null) {\n clearTimeout(timerId)\n timerId = null\n }\n }\n\n function startTimer(): void {\n if (duration <= 0) return\n clearTimer()\n remaining = duration\n startedAt = now()\n timerId = setTimeout(dismiss, remaining)\n }\n\n function pauseTimer(): void {\n if (timerId === null) return\n clearTimer()\n remaining = remaining - (now() - startedAt)\n if (remaining < 0) remaining = 0\n }\n\n function resumeTimer(): void {\n if (duration <= 0 || remaining <= 0) return\n clearTimer()\n startedAt = now()\n timerId = setTimeout(dismiss, remaining)\n }\n\n const ariaProps: Partial<AccessibilityProps> = {\n role: 'alert',\n 'aria-live': 'assertive',\n 'aria-atomic': true,\n }\n\n return {\n state: {\n get open() {\n return controlledOpen !== undefined ? controlledOpen : isOpen\n },\n variant,\n },\n ariaProps,\n dismiss,\n startTimer,\n pauseTimer,\n resumeTimer,\n }\n}\n\n/** Entry in the toast manager */\nexport interface ToastEntry {\n id: string\n message: string\n variant: ToastVariant\n duration: number\n createdAt: number\n}\n\nexport interface ToastManagerAPI {\n /** Add a new toast. Returns the toast id. */\n toast(message: string, opts?: { variant?: ToastVariant; duration?: number }): string\n /** Dismiss a toast by id */\n dismiss(id: string): void\n /** Current toast list (read-only) */\n readonly toasts: ReadonlyArray<ToastEntry>\n /** Subscribe to toast list changes. Returns unsubscribe function. */\n subscribe(fn: (toasts: ReadonlyArray<ToastEntry>) => void): () => void\n}\n\nexport interface ToastManagerConfig {\n /** Clock for entry `createdAt` stamps (ms). Default: ambient `Date.now()` — inject for deterministic tests. */\n now?: () => number\n}\n\nexport function createToastManager(config: ToastManagerConfig = {}): ToastManagerAPI {\n // Injection boundary: ambient time is the default; inject `now` for deterministic createdAt.\n const now = config.now ?? (() => Date.now())\n let toasts: ToastEntry[] = []\n const listeners = new Set<(toasts: ReadonlyArray<ToastEntry>) => void>()\n const timers = new Map<string, ReturnType<typeof setTimeout>>()\n\n function notify(): void {\n const snapshot = [...toasts]\n for (const fn of listeners) {\n fn(snapshot)\n }\n }\n\n function dismiss(id: string): void {\n const timer = timers.get(id)\n if (timer) {\n clearTimeout(timer)\n timers.delete(id)\n }\n toasts = toasts.filter((t) => t.id !== id)\n notify()\n }\n\n function toast(\n message: string,\n opts?: { variant?: ToastVariant; duration?: number },\n ): string {\n const id = generateId('rfr-toast')\n const variant = opts?.variant ?? 'default'\n const duration = opts?.duration ?? 3000\n\n const entry: ToastEntry = {\n id,\n message,\n variant,\n duration,\n createdAt: now(),\n }\n\n toasts = [...toasts, entry]\n notify()\n\n if (duration > 0) {\n const timer = setTimeout(() => dismiss(id), duration)\n timers.set(id, timer)\n }\n\n return id\n }\n\n function subscribe(fn: (toasts: ReadonlyArray<ToastEntry>) => void): () => void {\n listeners.add(fn)\n return () => {\n listeners.delete(fn)\n }\n }\n\n return {\n toast,\n dismiss,\n get toasts() {\n return toasts\n },\n subscribe,\n }\n}\n", "import { cva } from '@refraction-ui/shared'\n\nexport const toastVariants = cva({\n base: 'pointer-events-auto relative flex w-full items-center justify-between gap-2 overflow-hidden rounded-lg border p-4 shadow-lg transition-all',\n variants: {\n variant: {\n default: 'border bg-background text-foreground',\n success: 'border-l-4 border-success/50 bg-success/10 text-success',\n error: 'border-l-4 border-destructive/50 bg-destructive/10 text-destructive',\n warning: 'border-l-4 border-warning/50 bg-warning/10 text-warning',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n})\n", "import * as React from 'react'\nimport {\n createToast,\n createToastManager,\n toastVariants,\n type ToastVariant,\n type ToastEntry,\n type ToastManagerAPI,\n} from '@refraction-ui/toast'\nimport { cn, devWarn } from '@refraction-ui/shared'\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\ninterface ToastContextValue {\n manager: ToastManagerAPI\n}\n\nconst ToastContext = React.createContext<ToastContextValue | null>(null)\n\nfunction useToastContext(): ToastContextValue {\n const ctx = React.useContext(ToastContext)\n if (!ctx) {\n devWarn(\n 'react-toast/use-toast-outside-provider',\n 'useToast() was called outside a <ToastProvider>. Wrap your app (or the consuming subtree) in <ToastProvider> so the toast context is available.',\n )\n throw new Error('useToast must be used within a <ToastProvider>')\n }\n return ctx\n}\n\n// ---------------------------------------------------------------------------\n// ToastProvider\n// ---------------------------------------------------------------------------\n\nexport interface ToastProviderProps {\n children?: React.ReactNode\n}\n\nexport function ToastProvider({ children }: ToastProviderProps) {\n const managerRef = React.useRef<ToastManagerAPI | null>(null)\n if (managerRef.current === null) {\n managerRef.current = createToastManager()\n }\n\n const ctx = React.useMemo<ToastContextValue>(\n () => ({ manager: managerRef.current! }),\n [],\n )\n\n return React.createElement(ToastContext.Provider, { value: ctx }, children)\n}\n\n// ---------------------------------------------------------------------------\n// useToast hook\n// ---------------------------------------------------------------------------\n\nexport interface UseToastReturn {\n /** Show a new toast */\n toast: (message: string, opts?: { variant?: ToastVariant; duration?: number }) => string\n /** Dismiss a toast by id */\n dismiss: (id: string) => void\n /** Current toast entries */\n toasts: ReadonlyArray<ToastEntry>\n}\n\nexport function useToast(): UseToastReturn {\n const { manager } = useToastContext()\n const [toasts, setToasts] = React.useState<ReadonlyArray<ToastEntry>>(manager.toasts)\n\n React.useEffect(() => {\n // Sync initial state\n setToasts(manager.toasts)\n const unsub = manager.subscribe(setToasts)\n return unsub\n }, [manager])\n\n return {\n toast: manager.toast,\n dismiss: manager.dismiss,\n toasts,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Toast (individual toast component)\n// ---------------------------------------------------------------------------\n\nexport interface ToastProps extends React.HTMLAttributes<HTMLDivElement> {\n entry: ToastEntry\n onDismiss?: (id: string) => void\n}\n\nexport const Toast = React.forwardRef<HTMLDivElement, ToastProps>(\n function Toast({ entry, onDismiss, className, children, onMouseEnter, onMouseLeave, ...props }, ref) {\n const api = React.useMemo(\n () => createToast({ variant: entry.variant, duration: entry.duration }),\n [entry.variant, entry.duration],\n )\n\n // Start auto-dismiss timer on mount\n React.useEffect(() => {\n api.startTimer()\n return () => api.pauseTimer()\n }, [api])\n\n const handleMouseEnter = (e: React.MouseEvent<HTMLDivElement>) => {\n api.pauseTimer()\n onMouseEnter?.(e)\n }\n\n const handleMouseLeave = (e: React.MouseEvent<HTMLDivElement>) => {\n api.resumeTimer()\n onMouseLeave?.(e)\n }\n\n return React.createElement(\n 'div',\n {\n ref,\n className: cn(toastVariants({ variant: entry.variant }), className),\n ...api.ariaProps,\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n ...props,\n },\n React.createElement('div', { className: 'flex-1' }, entry.message),\n children,\n onDismiss &&\n React.createElement(\n 'button',\n {\n type: 'button',\n className: 'shrink-0',\n onClick: () => onDismiss(entry.id),\n 'aria-label': 'Dismiss',\n },\n '\\u00d7',\n ),\n )\n },\n)\n\n// ---------------------------------------------------------------------------\n// Toaster (container that renders all active toasts)\n// ---------------------------------------------------------------------------\n\nexport interface ToasterProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport const Toaster = React.forwardRef<HTMLDivElement, ToasterProps>(\n function Toaster({ className, ...props }, ref) {\n const { toasts, dismiss } = useToast()\n\n return React.createElement(\n 'div',\n {\n ref,\n className: cn(\n 'fixed bottom-4 right-4 z-50 flex flex-col gap-2 w-full max-w-sm pointer-events-none',\n className,\n ),\n ...props,\n },\n toasts.map((entry) =>\n React.createElement(Toast, {\n key: entry.id,\n entry,\n onDismiss: dismiss,\n }),\n ),\n )\n },\n)\n"],
5
+ "mappings": "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",
6
6
  "names": ["Toast", "Toaster"]
7
7
  }
package/dist/styles.css CHANGED
@@ -61,6 +61,14 @@
61
61
  --success-foreground: 0 0% 100%;
62
62
  --warning: 38 92% 50%;
63
63
  --warning-foreground: 240 10% 10%;
64
+ /* #3B82F6 (Tailwind blue-500). The Flutter package's info token is #2196F3
65
+ (Material blue) — a deliberate small cross-framework delta. */
66
+ --info: 217 91% 60%;
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%;
64
72
 
65
73
  --border: 240 6% 92%;
66
74
  --input: 240 6% 92%;
@@ -269,6 +277,13 @@
269
277
  --success-foreground: 0 0% 98%;
270
278
  --warning: 38 92% 50%;
271
279
  --warning-foreground: 240 10% 4%;
280
+ /* Lightened from 60% (light) to 65% lightness for contrast on dark surfaces */
281
+ --info: 217 91% 65%;
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%;
272
287
 
273
288
  --border: 240 5% 16%;
274
289
  --input: 240 5% 16%;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@refraction-ui/react",
3
- "version": "0.19.2",
3
+ "version": "0.20.1",
4
4
  "description": "All Refraction UI React components in one package — headless, accessible, zero-dependency",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -151,6 +151,7 @@
151
151
  "@refraction-ui/react-skip-to-content": "workspace:*",
152
152
  "@refraction-ui/react-slide-viewer": "workspace:*",
153
153
  "@refraction-ui/react-slider": "workspace:*",
154
+ "@refraction-ui/react-slot": "workspace:*",
154
155
  "@refraction-ui/react-slot-picker": "workspace:*",
155
156
  "@refraction-ui/react-social-auth-button": "workspace:*",
156
157
  "@refraction-ui/react-sortable-list": "workspace:*",