@epilot/spark-ui 1.0.0-alpha.7 → 1.0.0-alpha.9

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 (153) hide show
  1. package/dist/components/badge.cjs +2 -2
  2. package/dist/components/badge.cjs.map +1 -1
  3. package/dist/components/badge.d.ts +1 -1
  4. package/dist/components/badge.js +1 -1
  5. package/dist/components/battery-progress-row.d.cts +1 -1
  6. package/dist/components/battery-progress-row.d.ts +1 -1
  7. package/dist/components/bubble.d.cts +1 -1
  8. package/dist/components/bubble.d.ts +1 -1
  9. package/dist/components/button.cjs +5 -4
  10. package/dist/components/button.cjs.map +1 -1
  11. package/dist/components/button.d.cts +4 -17
  12. package/dist/components/button.d.ts +5 -18
  13. package/dist/components/button.js +5 -4
  14. package/dist/components/button.js.map +1 -1
  15. package/dist/components/callout.cjs +4 -4
  16. package/dist/components/callout.cjs.map +1 -1
  17. package/dist/components/callout.d.cts +6 -1
  18. package/dist/components/callout.d.ts +6 -1
  19. package/dist/components/callout.js +4 -4
  20. package/dist/components/callout.js.map +1 -1
  21. package/dist/components/card.cjs +25 -11
  22. package/dist/components/card.cjs.map +1 -1
  23. package/dist/components/card.d.cts +6 -0
  24. package/dist/components/card.d.ts +7 -1
  25. package/dist/components/card.js +25 -11
  26. package/dist/components/card.js.map +1 -1
  27. package/dist/components/checkbox.cjs +2 -2
  28. package/dist/components/checkbox.cjs.map +1 -1
  29. package/dist/components/checkbox.d.ts +1 -1
  30. package/dist/components/checkbox.js +1 -1
  31. package/dist/components/circular-gauge.d.cts +1 -1
  32. package/dist/components/circular-gauge.d.ts +1 -1
  33. package/dist/components/device-card.d.cts +1 -1
  34. package/dist/components/device-card.d.ts +1 -1
  35. package/dist/components/empty-state.cjs +9 -2
  36. package/dist/components/empty-state.cjs.map +1 -1
  37. package/dist/components/empty-state.d.cts +8 -2
  38. package/dist/components/empty-state.d.ts +8 -2
  39. package/dist/components/empty-state.js +10 -2
  40. package/dist/components/empty-state.js.map +1 -1
  41. package/dist/components/energy-bar-chart.d.cts +1 -1
  42. package/dist/components/energy-bar-chart.d.ts +1 -1
  43. package/dist/components/feed-in-hero.d.cts +1 -1
  44. package/dist/components/feed-in-hero.d.ts +1 -1
  45. package/dist/components/field.cjs +3 -3
  46. package/dist/components/field.cjs.map +1 -1
  47. package/dist/components/field.d.ts +1 -1
  48. package/dist/components/field.js +1 -1
  49. package/dist/components/info-block.d.cts +1 -1
  50. package/dist/components/info-block.d.ts +1 -1
  51. package/dist/components/input-group.cjs +2 -2
  52. package/dist/components/input-group.cjs.map +1 -1
  53. package/dist/components/input-group.d.cts +1 -1
  54. package/dist/components/input-group.d.ts +1 -1
  55. package/dist/components/input-group.js +1 -1
  56. package/dist/components/input-otp.cjs +10 -10
  57. package/dist/components/input-otp.cjs.map +1 -1
  58. package/dist/components/input-otp.js +1 -1
  59. package/dist/components/input.cjs +10 -10
  60. package/dist/components/input.cjs.map +1 -1
  61. package/dist/components/input.d.ts +1 -1
  62. package/dist/components/input.js +1 -1
  63. package/dist/components/marker.d.cts +1 -1
  64. package/dist/components/marker.d.ts +1 -1
  65. package/dist/components/message-scroller.cjs +1 -1
  66. package/dist/components/message-scroller.cjs.map +1 -1
  67. package/dist/components/message-scroller.js +1 -1
  68. package/dist/components/message-scroller.js.map +1 -1
  69. package/dist/components/metering-row.d.cts +1 -1
  70. package/dist/components/metering-row.d.ts +1 -1
  71. package/dist/components/number-flow.d.cts +1 -1
  72. package/dist/components/number-flow.d.ts +1 -1
  73. package/dist/components/page-header.d.cts +1 -1
  74. package/dist/components/page-header.d.ts +1 -1
  75. package/dist/components/radio.cjs +3 -3
  76. package/dist/components/radio.cjs.map +1 -1
  77. package/dist/components/radio.d.ts +1 -1
  78. package/dist/components/radio.js +1 -1
  79. package/dist/components/sankey-chart.d.cts +1 -1
  80. package/dist/components/sankey-chart.d.ts +1 -1
  81. package/dist/components/segmented-control.d.ts +1 -1
  82. package/dist/components/select.cjs +2 -2
  83. package/dist/components/select.cjs.map +1 -1
  84. package/dist/components/select.d.ts +1 -1
  85. package/dist/components/select.js +1 -1
  86. package/dist/components/switch.cjs +2 -2
  87. package/dist/components/switch.cjs.map +1 -1
  88. package/dist/components/switch.d.ts +1 -1
  89. package/dist/components/switch.js +1 -1
  90. package/dist/components/theme.cjs +119 -3
  91. package/dist/components/theme.cjs.map +1 -0
  92. package/dist/components/theme.d.cts +1 -3
  93. package/dist/components/theme.d.ts +2 -4
  94. package/dist/components/theme.js +115 -1
  95. package/dist/components/theme.js.map +1 -0
  96. package/dist/components/toast.cjs +158 -65
  97. package/dist/components/toast.cjs.map +1 -1
  98. package/dist/components/toast.d.cts +51 -9
  99. package/dist/components/toast.d.ts +51 -9
  100. package/dist/components/toast.js +158 -65
  101. package/dist/components/toast.js.map +1 -1
  102. package/dist/components/tooltip.cjs +1 -1
  103. package/dist/components/tooltip.cjs.map +1 -1
  104. package/dist/components/tooltip.js +1 -1
  105. package/dist/components/tooltip.js.map +1 -1
  106. package/dist/generate-radix-colors-BW09KT9m.d.ts +33 -0
  107. package/dist/generate-radix-colors-C5mWRWnQ.d.cts +33 -0
  108. package/dist/{accent-colors-CjHCf8fH.cjs → lib/accent-colors.cjs} +3 -7
  109. package/dist/lib/accent-colors.cjs.map +1 -0
  110. package/dist/lib/accent-colors.d.cts +8 -0
  111. package/dist/lib/accent-colors.d.ts +8 -0
  112. package/dist/{accent-colors-Ch2J0EEY.js → lib/accent-colors.js} +2 -2
  113. package/dist/lib/accent-colors.js.map +1 -0
  114. package/dist/lib/accent-theme.cjs +130 -0
  115. package/dist/lib/accent-theme.cjs.map +1 -0
  116. package/dist/lib/accent-theme.d.cts +35 -0
  117. package/dist/lib/accent-theme.d.ts +35 -0
  118. package/dist/lib/accent-theme.js +122 -0
  119. package/dist/lib/accent-theme.js.map +1 -0
  120. package/dist/{theme-ClRJhexF.cjs → lib/generate-radix-colors.cjs} +12 -240
  121. package/dist/lib/generate-radix-colors.cjs.map +1 -0
  122. package/dist/lib/generate-radix-colors.d.cts +4 -0
  123. package/dist/lib/generate-radix-colors.d.ts +4 -0
  124. package/dist/{theme-8PDO9E0S.js → lib/generate-radix-colors.js} +8 -225
  125. package/dist/lib/generate-radix-colors.js.map +1 -0
  126. package/dist/{input-box-variants-ZCtgs-1S.cjs → lib/input-box-variants.cjs} +5 -14
  127. package/dist/lib/input-box-variants.cjs.map +1 -0
  128. package/dist/lib/input-box-variants.d.cts +10 -0
  129. package/dist/lib/input-box-variants.d.ts +10 -0
  130. package/dist/{input-box-variants-DcajYXvo.js → lib/input-box-variants.js} +3 -3
  131. package/dist/lib/input-box-variants.js.map +1 -0
  132. package/dist/lib/theme-types.cjs +1 -0
  133. package/dist/lib/theme-types.d.cts +4 -0
  134. package/dist/lib/theme-types.d.ts +4 -0
  135. package/dist/lib/theme-types.js +2 -0
  136. package/dist/lib/tones.cjs +14 -0
  137. package/dist/lib/tones.cjs.map +1 -0
  138. package/dist/{tones-PXJGlSpe.d.ts → lib/tones.d.cts} +2 -2
  139. package/dist/{tones-DjgKOX3s.d.cts → lib/tones.d.ts} +2 -2
  140. package/dist/lib/tones.js +13 -0
  141. package/dist/lib/tones.js.map +1 -0
  142. package/dist/{number-flow-DMJouddg.d.cts → number-flow-CVIvQhZn.d.cts} +1 -1
  143. package/dist/{number-flow-D9zsxH0-.d.ts → number-flow-DVUHTv9D.d.ts} +1 -1
  144. package/dist/styles/index.css +158 -0
  145. package/dist/styles/spark-default.css +1 -0
  146. package/dist/{theme-types-BDdoRxXa.d.ts → theme-types-BKlzRiyw.d.ts} +1 -1
  147. package/package.json +18 -3
  148. package/dist/accent-colors-Ch2J0EEY.js.map +0 -1
  149. package/dist/accent-colors-CjHCf8fH.cjs.map +0 -1
  150. package/dist/input-box-variants-DcajYXvo.js.map +0 -1
  151. package/dist/input-box-variants-ZCtgs-1S.cjs.map +0 -1
  152. package/dist/theme-8PDO9E0S.js.map +0 -1
  153. package/dist/theme-ClRJhexF.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"toast.cjs","names":["MaterialSymbol","Spinner","Sonner"],"sources":["../../src/components/toast.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { Toaster as Sonner, toast, type ToasterProps } from 'sonner'\nimport {\n MaterialSymbol,\n type MaterialSymbolIconName,\n} from '../icons/material-symbol'\nimport { cn } from '../utils/cn'\nimport { Spinner } from './spinner'\n\n// sonner's icon slot is a fixed 16px box that does not scale, so the glyphs\n// are pinned to 16px rather than the usual --spark-scaling formula\nconst TOAST_ICONS: Record<\n 'success' | 'info' | 'warning' | 'error',\n { name: MaterialSymbolIconName; className: string }\n> = {\n success: { name: 'check_circle', className: 'text-success-light' },\n info: { name: 'info', className: 'text-info-light' },\n warning: { name: 'warning', className: 'text-warning-light' },\n error: { name: 'cancel', className: 'text-error-light' },\n}\n\nconst ICONS: ToasterProps['icons'] = Object.fromEntries(\n Object.entries(TOAST_ICONS).map(([type, icon]) => [\n type,\n <MaterialSymbol\n className={cn(\n 'inline-flex shrink-0 items-center [--spark-icon-size:16px]',\n icon.className,\n )}\n key={type}\n name={icon.name}\n />,\n ]),\n)\n// decorative: the toast itself announces the loading message, so the spinner\n// must not add its own status live region; `flex` kills the inline baseline\n// gap that pushes it off-center inside sonner's loader wrapper\nICONS.loading = (\n <Spinner\n aria-hidden=\"true\"\n className=\"flex text-gray-11\"\n label=\"\"\n role=\"presentation\"\n size=\"sm\"\n />\n)\n\nconst STYLE_VARS = {\n '--normal-bg': 'var(--color-gray-2)',\n '--normal-text': 'var(--color-gray-12)',\n '--normal-border': 'var(--color-gray-a1)',\n '--border-radius': 'var(--radius-lg)',\n // sonner's own gray scale (close button, cancel button) — remapped so it\n // follows the spark theme instead of sonner's hardcoded light-only values\n '--gray1': 'var(--color-gray-1)',\n '--gray2': 'var(--color-gray-2)',\n '--gray3': 'var(--color-gray-3)',\n '--gray4': 'var(--color-gray-4)',\n '--gray5': 'var(--color-gray-5)',\n '--gray11': 'var(--color-gray-11)',\n '--gray12': 'var(--color-gray-12)',\n // close button on the top-right corner (sonner defaults to top-left in ltr)\n '--toast-close-button-start': 'unset',\n '--toast-close-button-end': '0',\n '--toast-close-button-transform': 'translate(35%, -35%)',\n // rich-color palette — opaque radix steps (bg 2, text 11) so floating\n // toasts don't let page content bleed through the way alpha `-soft`\n // tokens would; borders off per design\n '--success-bg': 'var(--color-green-2)',\n '--success-border': 'transparent',\n '--success-text': 'var(--color-green-11)',\n '--info-bg': 'var(--color-blue-2)',\n '--info-border': 'transparent',\n '--info-text': 'var(--color-blue-11)',\n '--warning-bg': 'var(--color-orange-2)',\n '--warning-border': 'transparent',\n '--warning-text': 'var(--color-orange-11)',\n '--error-bg': 'var(--color-red-2)',\n '--error-border': 'transparent',\n '--error-text': 'var(--color-red-11)',\n} as React.CSSProperties\n\nconst CLASS_NAMES = {\n // sonner hardcodes the description color (#3f3f3f) and its styles are\n // unlayered, so only important utilities win; typed rich toasts restore\n // the tinted inherit (untyped toasts carry data-rich-colors too, so the\n // guard needs both attributes)\n description:\n 'text-gray-11! [[data-rich-colors=true][data-type]_&]:text-inherit!',\n actionButton:\n 'bg-spark-9! text-spark-contrast! hover:bg-spark-10! rounded-md!',\n cancelButton: 'bg-gray-a3! text-gray-12! hover:bg-gray-a4! rounded-md!',\n}\n\n// consumer props merge with (not replace) the spark theming — React itself\n// would wholesale-replace object props like `style`\nconst Toaster = ({\n className,\n closeButton = true,\n icons,\n richColors = true,\n style,\n toastOptions,\n ...props\n}: ToasterProps) => (\n <Sonner\n className={cn('toaster group', className)}\n closeButton={closeButton}\n icons={{ ...ICONS, ...icons }}\n richColors={richColors}\n style={{ ...STYLE_VARS, ...style }}\n toastOptions={{\n ...toastOptions,\n classNames: { ...CLASS_NAMES, ...toastOptions?.classNames },\n }}\n {...props}\n />\n)\n\nexport { Toaster, toast }\nexport type { ToasterProps }\n"],"mappings":";;;;;;;;;;;;AAuBA,MAAM,QAA+B,OAAO,YAC1C,OAAO,QAAQ;CAPf,SAAS;EAAE,MAAM;EAAgB,WAAW;EAAsB;CAClE,MAAM;EAAE,MAAM;EAAQ,WAAW;EAAmB;CACpD,SAAS;EAAE,MAAM;EAAW,WAAW;EAAsB;CAC7D,OAAO;EAAE,MAAM;EAAU,WAAW;EAAoB;CAI9B,CAAC,CAAC,KAAK,CAAC,MAAM,UAAU,CAChD,MACA,iBAAA,GAAA,kBAAA,KAACA,8BAAAA,gBAAD;CACE,YAAA,GAAA,OAAA,IACE,8DACA,KAAK,UACN;CAED,MAAM,KAAK;CACX,EAFK,KAEL,CACH,CAAC,CACH;AAID,MAAM,UACJ,iBAAA,GAAA,kBAAA,KAACC,2BAAAA,SAAD;CACE,eAAY;CACZ,WAAU;CACV,OAAM;CACN,MAAK;CACL,MAAK;CACL,CAAA;AAGJ,MAAM,aAAa;CACjB,eAAe;CACf,iBAAiB;CACjB,mBAAmB;CACnB,mBAAmB;CAGnB,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,YAAY;CACZ,YAAY;CAEZ,8BAA8B;CAC9B,4BAA4B;CAC5B,kCAAkC;CAIlC,gBAAgB;CAChB,oBAAoB;CACpB,kBAAkB;CAClB,aAAa;CACb,iBAAiB;CACjB,eAAe;CACf,gBAAgB;CAChB,oBAAoB;CACpB,kBAAkB;CAClB,cAAc;CACd,kBAAkB;CAClB,gBAAgB;CACjB;AAED,MAAM,cAAc;CAKlB,aACE;CACF,cACE;CACF,cAAc;CACf;AAID,MAAM,WAAW,EACf,WACA,cAAc,MACd,OACA,aAAa,MACb,OACA,cACA,GAAG,YAEH,iBAAA,GAAA,kBAAA,KAACC,OAAAA,SAAD;CACE,YAAA,GAAA,OAAA,IAAc,iBAAiB,UAAU;CAC5B;CACb,OAAO;EAAE,GAAG;EAAO,GAAG;EAAO;CACjB;CACZ,OAAO;EAAE,GAAG;EAAY,GAAG;EAAO;CAClC,cAAc;EACZ,GAAG;EACH,YAAY;GAAE,GAAG;GAAa,GAAG,cAAc;GAAY;EAC5D;CACD,GAAI;CACJ,CAAA"}
1
+ {"version":3,"file":"toast.cjs","names":["ToastPrimitive","Spinner","MaterialSymbol","buttonVariants"],"sources":["../../src/components/toast.tsx"],"sourcesContent":["'use client'\n\nimport { Toast as ToastPrimitive } from '@base-ui/react/toast'\nimport * as React from 'react'\nimport {\n MaterialSymbol,\n type MaterialSymbolIconName,\n} from '../icons/material-symbol'\nimport { cn } from '../utils/cn'\nimport { buttonVariants } from './button'\nimport { Spinner } from './spinner'\n\ntype ToastType = 'success' | 'info' | 'warning' | 'error' | 'loading'\n\ntype ToastPosition =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right'\n\n// Per-toast overrides Base UI carries through untouched as opaque `data`.\ntype ToastData = { closeButton?: boolean }\n\n// `label` is the button's content; everything else a `<button>` takes passes\n// straight through, so a caller can set `className`, `disabled`, `type`, and\n// the rest without a new prop for each one.\ntype ToastAction = Omit<\n React.ComponentPropsWithoutRef<'button'>,\n 'children'\n> & {\n label: React.ReactNode\n}\n\ntype ToastOptions = {\n description?: React.ReactNode\n /** Auto-dismiss time in ms. `0` keeps the toast until dismissed. */\n duration?: number\n /** Reuse an id to update a toast in place instead of stacking a new one. */\n id?: string\n closeButton?: boolean\n action?: ToastAction\n onDismiss?: () => void\n /** `high` announces urgently (assertive); the default is polite. */\n priority?: 'low' | 'high'\n}\n\ntype ToastPromiseMessages<Value> = {\n loading: string\n success: string | ((value: Value) => string)\n error: string | ((error: unknown) => string)\n}\n\nconst TOAST_ICONS: Record<\n Exclude<ToastType, 'loading'>,\n { name: MaterialSymbolIconName; className: string }\n> = {\n success: { name: 'check_circle', className: 'text-success-light' },\n info: { name: 'info', className: 'text-info-light' },\n warning: { name: 'warning', className: 'text-warning-light' },\n error: { name: 'cancel', className: 'text-error-light' },\n}\n\n// Opaque radix steps (bg 2, border 6, text 11) so a floating toast never lets\n// page content bleed through the way the alpha `-soft` tokens would. The border\n// carries the tone too, otherwise a tinted toast keeps a grey outline.\nconst TONE_CLASSES: Record<Exclude<ToastType, 'loading'>, string> = {\n success: 'border-green-6 bg-green-2 text-green-11',\n info: 'border-blue-6 bg-blue-2 text-blue-11',\n warning: 'border-orange-6 bg-orange-2 text-orange-11',\n error: 'border-red-6 bg-red-2 text-red-11',\n}\n\n// Mobile-first: every position drops to a full-width stack at the top, which\n// is what the end-customer portal ships. `position` only takes effect from the\n// `sm` breakpoint up.\nconst POSITION_CLASSES: Record<ToastPosition, string> = {\n 'top-left': 'sm:top-4 sm:right-auto sm:bottom-auto sm:left-4',\n 'top-center':\n 'sm:top-4 sm:right-auto sm:bottom-auto sm:left-1/2 sm:-translate-x-1/2',\n 'top-right': 'sm:top-4 sm:right-4 sm:bottom-auto sm:left-auto',\n 'bottom-left': 'sm:top-auto sm:right-auto sm:bottom-4 sm:left-4',\n 'bottom-center':\n 'sm:top-auto sm:right-auto sm:bottom-4 sm:left-1/2 sm:-translate-x-1/2',\n 'bottom-right': 'sm:top-auto sm:right-4 sm:bottom-4 sm:left-auto',\n}\n\nconst manager = ToastPrimitive.createToastManager<ToastData>()\n\nlet sequence = 0\n\n// `label` names the content and `onClick` is wrapped, so neither reaches the\n// DOM button as-is; everything else does.\nfunction actionRest({\n label: _label,\n onClick: _onClick,\n ...rest\n}: ToastAction) {\n return rest\n}\n\nfunction toManagerOptions(\n id: string,\n title: React.ReactNode,\n type: ToastType | undefined,\n options: ToastOptions | undefined,\n) {\n const action = options?.action\n return {\n id,\n title,\n type,\n description: options?.description,\n timeout: options?.duration,\n priority: options?.priority,\n onClose: options?.onDismiss,\n // Base UI leaves the toast open after an action; dismissing matches what\n // callers expect from an \"Undo\" button.\n actionProps: action && {\n ...actionRest(action),\n children: action.label,\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => {\n action.onClick?.(event)\n manager.close(id)\n },\n },\n data: { closeButton: options?.closeButton },\n }\n}\n\nconst emit =\n (type?: ToastType) =>\n (message: React.ReactNode, options?: ToastOptions): string => {\n // an id up front lets the action handler close the toast it belongs to\n const id = options?.id ?? `spark-toast-${(sequence += 1)}`\n return manager.add(toManagerOptions(id, message, type, options))\n }\n\n// A string phase becomes a titled toast of that type; an object phase keeps\n// whatever the caller set and only fills in the type.\nconst phase =\n <Value,>(\n value: ToastPromiseMessages<Value>[keyof ToastPromiseMessages<Value>],\n type: ToastType,\n ) =>\n (result: Value) => {\n const resolved = typeof value === 'function' ? value(result) : value\n return { title: resolved, type }\n }\n\nconst toast = Object.assign(emit(), {\n success: emit('success'),\n info: emit('info'),\n warning: emit('warning'),\n error: emit('error'),\n loading: emit('loading'),\n /** Dismiss one toast, or every toast when called without an id. */\n dismiss: (id?: string) => manager.close(id),\n promise: <Value,>(\n promiseValue: Promise<Value>,\n messages: ToastPromiseMessages<Value>,\n ) =>\n manager.promise(promiseValue, {\n loading: { title: messages.loading, type: 'loading' as const },\n success: phase(messages.success, 'success'),\n error: phase(messages.error as never, 'error'),\n }),\n})\n\nfunction ToastIcon({ type }: { type?: string }) {\n const icon = TOAST_ICONS[type as Exclude<ToastType, 'loading'>]\n if (type !== 'loading' && !icon) return null\n\n // Fixed box matching the title's line height, so the glyph and the spinner\n // both centre on the first line whether or not a description follows.\n return (\n <span\n aria-hidden=\"true\"\n className=\"flex h-5 w-5 shrink-0 items-center justify-center\"\n >\n {type === 'loading' ? (\n // Decorative: the toast already announces the loading message, so the\n // spinner must not add a second status live region.\n <Spinner\n className=\"text-gray-11\"\n label=\"\"\n role=\"presentation\"\n size=\"sm\"\n />\n ) : (\n <MaterialSymbol\n className={cn('[--spark-icon-size:20px]', icon.className)}\n name={icon.name}\n />\n )}\n </span>\n )\n}\n\nfunction ToastItem({\n closeButton,\n richColors,\n toast: toastObject,\n}: {\n closeButton: boolean\n richColors: boolean\n toast: ToastPrimitive.Root.ToastObject<ToastData>\n}) {\n const tone = TONE_CLASSES[toastObject.type as Exclude<ToastType, 'loading'>]\n const showClose = toastObject.data?.closeButton ?? closeButton\n\n return (\n <ToastPrimitive.Root\n data-slot=\"toast\"\n className={cn(\n // Skin only. All geometry (position, stacking, transitions, the\n // pointer bridge) lives in styles/index.css, because Tailwind's\n // `utilities` layer outranks `components` and a stray `bottom-0` here\n // would beat the stylesheet's `bottom: auto` on top-anchored stacks.\n // The border is what makes the cards behind the front one legible.\n 'flex items-start gap-2 rounded-md border border-gray-a5 bg-gray-1 p-3 text-gray shadow-md select-none',\n richColors && tone,\n )}\n // the stack is top-anchored on mobile and bottom-anchored above `sm`, so\n // both vertical directions have to dismiss\n swipeDirection={['up', 'down', 'right']}\n toast={toastObject}\n >\n <ToastIcon type={toastObject.type} />\n <ToastPrimitive.Content className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <ToastPrimitive.Title\n className=\"text-sm font-medium\"\n data-slot=\"toast-title\"\n />\n <ToastPrimitive.Description\n className={cn(\n 'text-sm',\n richColors && tone ? 'text-inherit' : 'text-gray-11',\n )}\n data-slot=\"toast-description\"\n />\n </ToastPrimitive.Content>\n {toastObject.actionProps ? (\n <ToastPrimitive.Action\n // -my-2 keeps the 36px control from stretching a single-line row past\n // the 20px text; self-center then lands it on the title when there is\n // no description, and mid-block when there is one\n className={cn(\n buttonVariants({ size: 'small', variant: 'primary' }),\n '-my-2 shrink-0 self-center rounded-full',\n )}\n data-slot=\"toast-action\"\n />\n ) : null}\n {showClose ? (\n <ToastPrimitive.Close\n aria-label=\"Close\"\n className={cn(\n buttonVariants({ size: 'icon-small', variant: 'tertiary' }),\n // -my-1: same reason as the action, for a 28px control\n '-my-1 -mr-1 size-7 shrink-0 self-center text-gray-11',\n )}\n data-slot=\"toast-close\"\n >\n <MaterialSymbol\n aria-hidden=\"true\"\n className=\"[--spark-icon-size:18px]\"\n name=\"close\"\n />\n </ToastPrimitive.Close>\n ) : null}\n </ToastPrimitive.Root>\n )\n}\n\nfunction ToastList({\n closeButton,\n richColors,\n}: {\n closeButton: boolean\n richColors: boolean\n}) {\n const { toasts } = ToastPrimitive.useToastManager<ToastData>()\n\n return toasts.map((toastObject) => (\n <ToastItem\n closeButton={closeButton}\n key={toastObject.id}\n richColors={richColors}\n toast={toastObject}\n />\n ))\n}\n\ntype ToasterProps = {\n className?: string\n /** Corner or edge the toasts stack in. */\n position?: ToastPosition\n /** Close button on every toast; a per-toast `closeButton` wins. */\n closeButton?: boolean\n /** Tinted surfaces for success/info/warning/error toasts. */\n richColors?: boolean\n /** Default auto-dismiss time in ms. `0` disables auto-dismiss. */\n duration?: number\n /** Toasts visible at once before older ones are marked `data-limited`. */\n limit?: number\n /**\n * Vertical edge below the `sm` breakpoint, where the stack is always\n * full-width and `position` does not apply. Defaults to `top`, matching the\n * end-customer portal.\n */\n mobilePosition?: 'top' | 'bottom'\n}\n\nfunction Toaster({\n className,\n closeButton = true,\n duration = 4000,\n limit,\n mobilePosition = 'top',\n position = 'bottom-right',\n richColors = true,\n}: ToasterProps) {\n return (\n <ToastPrimitive.Provider\n limit={limit}\n timeout={duration}\n toastManager={manager}\n >\n <ToastPrimitive.Portal>\n <ToastPrimitive.Viewport\n // block + zero height: the toasts are absolutely positioned against\n // this box's bottom edge, the way Base UI's stacked example works\n className={cn(\n 'fixed inset-x-4 z-50 block h-0 outline-none',\n mobilePosition === 'top' ? 'top-4' : 'bottom-4',\n 'sm:inset-x-auto sm:w-96 sm:max-w-[calc(100vw-2rem)]',\n POSITION_CLASSES[position],\n className,\n )}\n data-mobile-side={mobilePosition}\n data-side={position.startsWith('top') ? 'top' : 'bottom'}\n data-slot=\"toaster\"\n >\n <ToastList closeButton={closeButton} richColors={richColors} />\n </ToastPrimitive.Viewport>\n </ToastPrimitive.Portal>\n </ToastPrimitive.Provider>\n )\n}\n\nexport { Toaster, toast }\nexport type {\n ToastAction,\n ToasterProps,\n ToastOptions,\n ToastPosition,\n ToastPromiseMessages,\n ToastType,\n}\n"],"mappings":"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"}
@@ -1,18 +1,60 @@
1
1
  "use client";
2
2
 
3
3
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
- import { ToasterProps, toast } from "sonner";
4
+ import * as React$1 from "react";
5
5
 
6
6
  //#region src/components/toast.d.ts
7
- declare const Toaster: ({
7
+ type ToastType = 'success' | 'info' | 'warning' | 'error' | 'loading';
8
+ type ToastPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
9
+ type ToastAction = Omit<React$1.ComponentPropsWithoutRef<'button'>, 'children'> & {
10
+ label: React$1.ReactNode;
11
+ };
12
+ type ToastOptions = {
13
+ description?: React$1.ReactNode; /** Auto-dismiss time in ms. `0` keeps the toast until dismissed. */
14
+ duration?: number; /** Reuse an id to update a toast in place instead of stacking a new one. */
15
+ id?: string;
16
+ closeButton?: boolean;
17
+ action?: ToastAction;
18
+ onDismiss?: () => void; /** `high` announces urgently (assertive); the default is polite. */
19
+ priority?: 'low' | 'high';
20
+ };
21
+ type ToastPromiseMessages<Value> = {
22
+ loading: string;
23
+ success: string | ((value: Value) => string);
24
+ error: string | ((error: unknown) => string);
25
+ };
26
+ declare const toast: ((message: React$1.ReactNode, options?: ToastOptions) => string) & {
27
+ success: (message: React$1.ReactNode, options?: ToastOptions) => string;
28
+ info: (message: React$1.ReactNode, options?: ToastOptions) => string;
29
+ warning: (message: React$1.ReactNode, options?: ToastOptions) => string;
30
+ error: (message: React$1.ReactNode, options?: ToastOptions) => string;
31
+ loading: (message: React$1.ReactNode, options?: ToastOptions) => string; /** Dismiss one toast, or every toast when called without an id. */
32
+ dismiss: (id?: string) => void;
33
+ promise: <Value>(promiseValue: Promise<Value>, messages: ToastPromiseMessages<Value>) => Promise<Value>;
34
+ };
35
+ type ToasterProps = {
36
+ className?: string; /** Corner or edge the toasts stack in. */
37
+ position?: ToastPosition; /** Close button on every toast; a per-toast `closeButton` wins. */
38
+ closeButton?: boolean; /** Tinted surfaces for success/info/warning/error toasts. */
39
+ richColors?: boolean; /** Default auto-dismiss time in ms. `0` disables auto-dismiss. */
40
+ duration?: number; /** Toasts visible at once before older ones are marked `data-limited`. */
41
+ limit?: number;
42
+ /**
43
+ * Vertical edge below the `sm` breakpoint, where the stack is always
44
+ * full-width and `position` does not apply. Defaults to `top`, matching the
45
+ * end-customer portal.
46
+ */
47
+ mobilePosition?: 'top' | 'bottom';
48
+ };
49
+ declare function Toaster({
8
50
  className,
9
51
  closeButton,
10
- icons,
11
- richColors,
12
- style,
13
- toastOptions,
14
- ...props
15
- }: ToasterProps) => _$react_jsx_runtime0.JSX.Element;
52
+ duration,
53
+ limit,
54
+ mobilePosition,
55
+ position,
56
+ richColors
57
+ }: ToasterProps): _$react_jsx_runtime0.JSX.Element;
16
58
  //#endregion
17
- export { Toaster, type ToasterProps, toast };
59
+ export { type ToastAction, type ToastOptions, type ToastPosition, type ToastPromiseMessages, type ToastType, Toaster, type ToasterProps, toast };
18
60
  //# sourceMappingURL=toast.d.cts.map
@@ -1,18 +1,60 @@
1
1
  "use client";
2
2
 
3
+ import * as React$1 from "react";
3
4
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
- import { ToasterProps, toast } from "sonner";
5
5
 
6
6
  //#region src/components/toast.d.ts
7
- declare const Toaster: ({
7
+ type ToastType = 'success' | 'info' | 'warning' | 'error' | 'loading';
8
+ type ToastPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
9
+ type ToastAction = Omit<React$1.ComponentPropsWithoutRef<'button'>, 'children'> & {
10
+ label: React$1.ReactNode;
11
+ };
12
+ type ToastOptions = {
13
+ description?: React$1.ReactNode; /** Auto-dismiss time in ms. `0` keeps the toast until dismissed. */
14
+ duration?: number; /** Reuse an id to update a toast in place instead of stacking a new one. */
15
+ id?: string;
16
+ closeButton?: boolean;
17
+ action?: ToastAction;
18
+ onDismiss?: () => void; /** `high` announces urgently (assertive); the default is polite. */
19
+ priority?: 'low' | 'high';
20
+ };
21
+ type ToastPromiseMessages<Value> = {
22
+ loading: string;
23
+ success: string | ((value: Value) => string);
24
+ error: string | ((error: unknown) => string);
25
+ };
26
+ declare const toast: ((message: React$1.ReactNode, options?: ToastOptions) => string) & {
27
+ success: (message: React$1.ReactNode, options?: ToastOptions) => string;
28
+ info: (message: React$1.ReactNode, options?: ToastOptions) => string;
29
+ warning: (message: React$1.ReactNode, options?: ToastOptions) => string;
30
+ error: (message: React$1.ReactNode, options?: ToastOptions) => string;
31
+ loading: (message: React$1.ReactNode, options?: ToastOptions) => string; /** Dismiss one toast, or every toast when called without an id. */
32
+ dismiss: (id?: string) => void;
33
+ promise: <Value>(promiseValue: Promise<Value>, messages: ToastPromiseMessages<Value>) => Promise<Value>;
34
+ };
35
+ type ToasterProps = {
36
+ className?: string; /** Corner or edge the toasts stack in. */
37
+ position?: ToastPosition; /** Close button on every toast; a per-toast `closeButton` wins. */
38
+ closeButton?: boolean; /** Tinted surfaces for success/info/warning/error toasts. */
39
+ richColors?: boolean; /** Default auto-dismiss time in ms. `0` disables auto-dismiss. */
40
+ duration?: number; /** Toasts visible at once before older ones are marked `data-limited`. */
41
+ limit?: number;
42
+ /**
43
+ * Vertical edge below the `sm` breakpoint, where the stack is always
44
+ * full-width and `position` does not apply. Defaults to `top`, matching the
45
+ * end-customer portal.
46
+ */
47
+ mobilePosition?: 'top' | 'bottom';
48
+ };
49
+ declare function Toaster({
8
50
  className,
9
51
  closeButton,
10
- icons,
11
- richColors,
12
- style,
13
- toastOptions,
14
- ...props
15
- }: ToasterProps) => _$react_jsx_runtime0.JSX.Element;
52
+ duration,
53
+ limit,
54
+ mobilePosition,
55
+ position,
56
+ richColors
57
+ }: ToasterProps): _$react_jsx_runtime0.JSX.Element;
16
58
  //#endregion
17
- export { Toaster, type ToasterProps, toast };
59
+ export { type ToastAction, type ToastOptions, type ToastPosition, type ToastPromiseMessages, type ToastType, Toaster, type ToasterProps, toast };
18
60
  //# sourceMappingURL=toast.d.ts.map
@@ -2,12 +2,13 @@
2
2
  "use client";
3
3
  import { cn } from "../utils/cn.js";
4
4
  import { MaterialSymbol } from "../icons/material-symbol.js";
5
+ import { buttonVariants } from "./button.js";
5
6
  import { Spinner } from "./spinner.js";
6
7
  import "react";
7
- import { jsx } from "react/jsx-runtime";
8
- import { Toaster as Toaster$1, toast } from "sonner";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { Toast } from "@base-ui/react/toast";
9
10
  //#region src/components/toast.tsx
10
- const ICONS = Object.fromEntries(Object.entries({
11
+ const TOAST_ICONS = {
11
12
  success: {
12
13
  name: "check_circle",
13
14
  className: "text-success-light"
@@ -24,71 +25,163 @@ const ICONS = Object.fromEntries(Object.entries({
24
25
  name: "cancel",
25
26
  className: "text-error-light"
26
27
  }
27
- }).map(([type, icon]) => [type, /* @__PURE__ */ jsx(MaterialSymbol, {
28
- className: cn("inline-flex shrink-0 items-center [--spark-icon-size:16px]", icon.className),
29
- name: icon.name
30
- }, type)]));
31
- ICONS.loading = /* @__PURE__ */ jsx(Spinner, {
32
- "aria-hidden": "true",
33
- className: "flex text-gray-11",
34
- label: "",
35
- role: "presentation",
36
- size: "sm"
37
- });
38
- const STYLE_VARS = {
39
- "--normal-bg": "var(--color-gray-2)",
40
- "--normal-text": "var(--color-gray-12)",
41
- "--normal-border": "var(--color-gray-a1)",
42
- "--border-radius": "var(--radius-lg)",
43
- "--gray1": "var(--color-gray-1)",
44
- "--gray2": "var(--color-gray-2)",
45
- "--gray3": "var(--color-gray-3)",
46
- "--gray4": "var(--color-gray-4)",
47
- "--gray5": "var(--color-gray-5)",
48
- "--gray11": "var(--color-gray-11)",
49
- "--gray12": "var(--color-gray-12)",
50
- "--toast-close-button-start": "unset",
51
- "--toast-close-button-end": "0",
52
- "--toast-close-button-transform": "translate(35%, -35%)",
53
- "--success-bg": "var(--color-green-2)",
54
- "--success-border": "transparent",
55
- "--success-text": "var(--color-green-11)",
56
- "--info-bg": "var(--color-blue-2)",
57
- "--info-border": "transparent",
58
- "--info-text": "var(--color-blue-11)",
59
- "--warning-bg": "var(--color-orange-2)",
60
- "--warning-border": "transparent",
61
- "--warning-text": "var(--color-orange-11)",
62
- "--error-bg": "var(--color-red-2)",
63
- "--error-border": "transparent",
64
- "--error-text": "var(--color-red-11)"
65
28
  };
66
- const CLASS_NAMES = {
67
- description: "text-gray-11! [[data-rich-colors=true][data-type]_&]:text-inherit!",
68
- actionButton: "bg-spark-9! text-spark-contrast! hover:bg-spark-10! rounded-md!",
69
- cancelButton: "bg-gray-a3! text-gray-12! hover:bg-gray-a4! rounded-md!"
29
+ const TONE_CLASSES = {
30
+ success: "border-green-6 bg-green-2 text-green-11",
31
+ info: "border-blue-6 bg-blue-2 text-blue-11",
32
+ warning: "border-orange-6 bg-orange-2 text-orange-11",
33
+ error: "border-red-6 bg-red-2 text-red-11"
70
34
  };
71
- const Toaster = ({ className, closeButton = true, icons, richColors = true, style, toastOptions, ...props }) => /* @__PURE__ */ jsx(Toaster$1, {
72
- className: cn("toaster group", className),
73
- closeButton,
74
- icons: {
75
- ...ICONS,
76
- ...icons
77
- },
78
- richColors,
79
- style: {
80
- ...STYLE_VARS,
81
- ...style
82
- },
83
- toastOptions: {
84
- ...toastOptions,
85
- classNames: {
86
- ...CLASS_NAMES,
87
- ...toastOptions?.classNames
88
- }
89
- },
90
- ...props
35
+ const POSITION_CLASSES = {
36
+ "top-left": "sm:top-4 sm:right-auto sm:bottom-auto sm:left-4",
37
+ "top-center": "sm:top-4 sm:right-auto sm:bottom-auto sm:left-1/2 sm:-translate-x-1/2",
38
+ "top-right": "sm:top-4 sm:right-4 sm:bottom-auto sm:left-auto",
39
+ "bottom-left": "sm:top-auto sm:right-auto sm:bottom-4 sm:left-4",
40
+ "bottom-center": "sm:top-auto sm:right-auto sm:bottom-4 sm:left-1/2 sm:-translate-x-1/2",
41
+ "bottom-right": "sm:top-auto sm:right-4 sm:bottom-4 sm:left-auto"
42
+ };
43
+ const manager = Toast.createToastManager();
44
+ let sequence = 0;
45
+ function actionRest({ label: _label, onClick: _onClick, ...rest }) {
46
+ return rest;
47
+ }
48
+ function toManagerOptions(id, title, type, options) {
49
+ const action = options?.action;
50
+ return {
51
+ id,
52
+ title,
53
+ type,
54
+ description: options?.description,
55
+ timeout: options?.duration,
56
+ priority: options?.priority,
57
+ onClose: options?.onDismiss,
58
+ actionProps: action && {
59
+ ...actionRest(action),
60
+ children: action.label,
61
+ onClick: (event) => {
62
+ action.onClick?.(event);
63
+ manager.close(id);
64
+ }
65
+ },
66
+ data: { closeButton: options?.closeButton }
67
+ };
68
+ }
69
+ const emit = (type) => (message, options) => {
70
+ const id = options?.id ?? `spark-toast-${sequence += 1}`;
71
+ return manager.add(toManagerOptions(id, message, type, options));
72
+ };
73
+ const phase = (value, type) => (result) => {
74
+ return {
75
+ title: typeof value === "function" ? value(result) : value,
76
+ type
77
+ };
78
+ };
79
+ const toast = Object.assign(emit(), {
80
+ success: emit("success"),
81
+ info: emit("info"),
82
+ warning: emit("warning"),
83
+ error: emit("error"),
84
+ loading: emit("loading"),
85
+ /** Dismiss one toast, or every toast when called without an id. */
86
+ dismiss: (id) => manager.close(id),
87
+ promise: (promiseValue, messages) => manager.promise(promiseValue, {
88
+ loading: {
89
+ title: messages.loading,
90
+ type: "loading"
91
+ },
92
+ success: phase(messages.success, "success"),
93
+ error: phase(messages.error, "error")
94
+ })
91
95
  });
96
+ function ToastIcon({ type }) {
97
+ const icon = TOAST_ICONS[type];
98
+ if (type !== "loading" && !icon) return null;
99
+ return /* @__PURE__ */ jsx("span", {
100
+ "aria-hidden": "true",
101
+ className: "flex h-5 w-5 shrink-0 items-center justify-center",
102
+ children: type === "loading" ? /* @__PURE__ */ jsx(Spinner, {
103
+ className: "text-gray-11",
104
+ label: "",
105
+ role: "presentation",
106
+ size: "sm"
107
+ }) : /* @__PURE__ */ jsx(MaterialSymbol, {
108
+ className: cn("[--spark-icon-size:20px]", icon.className),
109
+ name: icon.name
110
+ })
111
+ });
112
+ }
113
+ function ToastItem({ closeButton, richColors, toast: toastObject }) {
114
+ const tone = TONE_CLASSES[toastObject.type];
115
+ const showClose = toastObject.data?.closeButton ?? closeButton;
116
+ return /* @__PURE__ */ jsxs(Toast.Root, {
117
+ "data-slot": "toast",
118
+ className: cn("flex items-start gap-2 rounded-md border border-gray-a5 bg-gray-1 p-3 text-gray shadow-md select-none", richColors && tone),
119
+ swipeDirection: [
120
+ "up",
121
+ "down",
122
+ "right"
123
+ ],
124
+ toast: toastObject,
125
+ children: [
126
+ /* @__PURE__ */ jsx(ToastIcon, { type: toastObject.type }),
127
+ /* @__PURE__ */ jsxs(Toast.Content, {
128
+ className: "flex min-w-0 flex-1 flex-col gap-0.5",
129
+ children: [/* @__PURE__ */ jsx(Toast.Title, {
130
+ className: "text-sm font-medium",
131
+ "data-slot": "toast-title"
132
+ }), /* @__PURE__ */ jsx(Toast.Description, {
133
+ className: cn("text-sm", richColors && tone ? "text-inherit" : "text-gray-11"),
134
+ "data-slot": "toast-description"
135
+ })]
136
+ }),
137
+ toastObject.actionProps ? /* @__PURE__ */ jsx(Toast.Action, {
138
+ className: cn(buttonVariants({
139
+ size: "small",
140
+ variant: "primary"
141
+ }), "-my-2 shrink-0 self-center rounded-full"),
142
+ "data-slot": "toast-action"
143
+ }) : null,
144
+ showClose ? /* @__PURE__ */ jsx(Toast.Close, {
145
+ "aria-label": "Close",
146
+ className: cn(buttonVariants({
147
+ size: "icon-small",
148
+ variant: "tertiary"
149
+ }), "-my-1 -mr-1 size-7 shrink-0 self-center text-gray-11"),
150
+ "data-slot": "toast-close",
151
+ children: /* @__PURE__ */ jsx(MaterialSymbol, {
152
+ "aria-hidden": "true",
153
+ className: "[--spark-icon-size:18px]",
154
+ name: "close"
155
+ })
156
+ }) : null
157
+ ]
158
+ });
159
+ }
160
+ function ToastList({ closeButton, richColors }) {
161
+ const { toasts } = Toast.useToastManager();
162
+ return toasts.map((toastObject) => /* @__PURE__ */ jsx(ToastItem, {
163
+ closeButton,
164
+ richColors,
165
+ toast: toastObject
166
+ }, toastObject.id));
167
+ }
168
+ function Toaster({ className, closeButton = true, duration = 4e3, limit, mobilePosition = "top", position = "bottom-right", richColors = true }) {
169
+ return /* @__PURE__ */ jsx(Toast.Provider, {
170
+ limit,
171
+ timeout: duration,
172
+ toastManager: manager,
173
+ children: /* @__PURE__ */ jsx(Toast.Portal, { children: /* @__PURE__ */ jsx(Toast.Viewport, {
174
+ className: cn("fixed inset-x-4 z-50 block h-0 outline-none", mobilePosition === "top" ? "top-4" : "bottom-4", "sm:inset-x-auto sm:w-96 sm:max-w-[calc(100vw-2rem)]", POSITION_CLASSES[position], className),
175
+ "data-mobile-side": mobilePosition,
176
+ "data-side": position.startsWith("top") ? "top" : "bottom",
177
+ "data-slot": "toaster",
178
+ children: /* @__PURE__ */ jsx(ToastList, {
179
+ closeButton,
180
+ richColors
181
+ })
182
+ }) })
183
+ });
184
+ }
92
185
  //#endregion
93
186
  export { Toaster, toast };
94
187
 
@@ -1 +1 @@
1
- {"version":3,"file":"toast.js","names":["Sonner"],"sources":["../../src/components/toast.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { Toaster as Sonner, toast, type ToasterProps } from 'sonner'\nimport {\n MaterialSymbol,\n type MaterialSymbolIconName,\n} from '../icons/material-symbol'\nimport { cn } from '../utils/cn'\nimport { Spinner } from './spinner'\n\n// sonner's icon slot is a fixed 16px box that does not scale, so the glyphs\n// are pinned to 16px rather than the usual --spark-scaling formula\nconst TOAST_ICONS: Record<\n 'success' | 'info' | 'warning' | 'error',\n { name: MaterialSymbolIconName; className: string }\n> = {\n success: { name: 'check_circle', className: 'text-success-light' },\n info: { name: 'info', className: 'text-info-light' },\n warning: { name: 'warning', className: 'text-warning-light' },\n error: { name: 'cancel', className: 'text-error-light' },\n}\n\nconst ICONS: ToasterProps['icons'] = Object.fromEntries(\n Object.entries(TOAST_ICONS).map(([type, icon]) => [\n type,\n <MaterialSymbol\n className={cn(\n 'inline-flex shrink-0 items-center [--spark-icon-size:16px]',\n icon.className,\n )}\n key={type}\n name={icon.name}\n />,\n ]),\n)\n// decorative: the toast itself announces the loading message, so the spinner\n// must not add its own status live region; `flex` kills the inline baseline\n// gap that pushes it off-center inside sonner's loader wrapper\nICONS.loading = (\n <Spinner\n aria-hidden=\"true\"\n className=\"flex text-gray-11\"\n label=\"\"\n role=\"presentation\"\n size=\"sm\"\n />\n)\n\nconst STYLE_VARS = {\n '--normal-bg': 'var(--color-gray-2)',\n '--normal-text': 'var(--color-gray-12)',\n '--normal-border': 'var(--color-gray-a1)',\n '--border-radius': 'var(--radius-lg)',\n // sonner's own gray scale (close button, cancel button) — remapped so it\n // follows the spark theme instead of sonner's hardcoded light-only values\n '--gray1': 'var(--color-gray-1)',\n '--gray2': 'var(--color-gray-2)',\n '--gray3': 'var(--color-gray-3)',\n '--gray4': 'var(--color-gray-4)',\n '--gray5': 'var(--color-gray-5)',\n '--gray11': 'var(--color-gray-11)',\n '--gray12': 'var(--color-gray-12)',\n // close button on the top-right corner (sonner defaults to top-left in ltr)\n '--toast-close-button-start': 'unset',\n '--toast-close-button-end': '0',\n '--toast-close-button-transform': 'translate(35%, -35%)',\n // rich-color palette — opaque radix steps (bg 2, text 11) so floating\n // toasts don't let page content bleed through the way alpha `-soft`\n // tokens would; borders off per design\n '--success-bg': 'var(--color-green-2)',\n '--success-border': 'transparent',\n '--success-text': 'var(--color-green-11)',\n '--info-bg': 'var(--color-blue-2)',\n '--info-border': 'transparent',\n '--info-text': 'var(--color-blue-11)',\n '--warning-bg': 'var(--color-orange-2)',\n '--warning-border': 'transparent',\n '--warning-text': 'var(--color-orange-11)',\n '--error-bg': 'var(--color-red-2)',\n '--error-border': 'transparent',\n '--error-text': 'var(--color-red-11)',\n} as React.CSSProperties\n\nconst CLASS_NAMES = {\n // sonner hardcodes the description color (#3f3f3f) and its styles are\n // unlayered, so only important utilities win; typed rich toasts restore\n // the tinted inherit (untyped toasts carry data-rich-colors too, so the\n // guard needs both attributes)\n description:\n 'text-gray-11! [[data-rich-colors=true][data-type]_&]:text-inherit!',\n actionButton:\n 'bg-spark-9! text-spark-contrast! hover:bg-spark-10! rounded-md!',\n cancelButton: 'bg-gray-a3! text-gray-12! hover:bg-gray-a4! rounded-md!',\n}\n\n// consumer props merge with (not replace) the spark theming — React itself\n// would wholesale-replace object props like `style`\nconst Toaster = ({\n className,\n closeButton = true,\n icons,\n richColors = true,\n style,\n toastOptions,\n ...props\n}: ToasterProps) => (\n <Sonner\n className={cn('toaster group', className)}\n closeButton={closeButton}\n icons={{ ...ICONS, ...icons }}\n richColors={richColors}\n style={{ ...STYLE_VARS, ...style }}\n toastOptions={{\n ...toastOptions,\n classNames: { ...CLASS_NAMES, ...toastOptions?.classNames },\n }}\n {...props}\n />\n)\n\nexport { Toaster, toast }\nexport type { ToasterProps }\n"],"mappings":";;;;;;;;;AAuBA,MAAM,QAA+B,OAAO,YAC1C,OAAO,QAAQ;CAPf,SAAS;EAAE,MAAM;EAAgB,WAAW;EAAsB;CAClE,MAAM;EAAE,MAAM;EAAQ,WAAW;EAAmB;CACpD,SAAS;EAAE,MAAM;EAAW,WAAW;EAAsB;CAC7D,OAAO;EAAE,MAAM;EAAU,WAAW;EAAoB;CAI9B,CAAC,CAAC,KAAK,CAAC,MAAM,UAAU,CAChD,MACA,oBAAC,gBAAD;CACE,WAAW,GACT,8DACA,KAAK,UACN;CAED,MAAM,KAAK;CACX,EAFK,KAEL,CACH,CAAC,CACH;AAID,MAAM,UACJ,oBAAC,SAAD;CACE,eAAY;CACZ,WAAU;CACV,OAAM;CACN,MAAK;CACL,MAAK;CACL,CAAA;AAGJ,MAAM,aAAa;CACjB,eAAe;CACf,iBAAiB;CACjB,mBAAmB;CACnB,mBAAmB;CAGnB,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,YAAY;CACZ,YAAY;CAEZ,8BAA8B;CAC9B,4BAA4B;CAC5B,kCAAkC;CAIlC,gBAAgB;CAChB,oBAAoB;CACpB,kBAAkB;CAClB,aAAa;CACb,iBAAiB;CACjB,eAAe;CACf,gBAAgB;CAChB,oBAAoB;CACpB,kBAAkB;CAClB,cAAc;CACd,kBAAkB;CAClB,gBAAgB;CACjB;AAED,MAAM,cAAc;CAKlB,aACE;CACF,cACE;CACF,cAAc;CACf;AAID,MAAM,WAAW,EACf,WACA,cAAc,MACd,OACA,aAAa,MACb,OACA,cACA,GAAG,YAEH,oBAACA,WAAD;CACE,WAAW,GAAG,iBAAiB,UAAU;CAC5B;CACb,OAAO;EAAE,GAAG;EAAO,GAAG;EAAO;CACjB;CACZ,OAAO;EAAE,GAAG;EAAY,GAAG;EAAO;CAClC,cAAc;EACZ,GAAG;EACH,YAAY;GAAE,GAAG;GAAa,GAAG,cAAc;GAAY;EAC5D;CACD,GAAI;CACJ,CAAA"}
1
+ {"version":3,"file":"toast.js","names":["ToastPrimitive"],"sources":["../../src/components/toast.tsx"],"sourcesContent":["'use client'\n\nimport { Toast as ToastPrimitive } from '@base-ui/react/toast'\nimport * as React from 'react'\nimport {\n MaterialSymbol,\n type MaterialSymbolIconName,\n} from '../icons/material-symbol'\nimport { cn } from '../utils/cn'\nimport { buttonVariants } from './button'\nimport { Spinner } from './spinner'\n\ntype ToastType = 'success' | 'info' | 'warning' | 'error' | 'loading'\n\ntype ToastPosition =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right'\n\n// Per-toast overrides Base UI carries through untouched as opaque `data`.\ntype ToastData = { closeButton?: boolean }\n\n// `label` is the button's content; everything else a `<button>` takes passes\n// straight through, so a caller can set `className`, `disabled`, `type`, and\n// the rest without a new prop for each one.\ntype ToastAction = Omit<\n React.ComponentPropsWithoutRef<'button'>,\n 'children'\n> & {\n label: React.ReactNode\n}\n\ntype ToastOptions = {\n description?: React.ReactNode\n /** Auto-dismiss time in ms. `0` keeps the toast until dismissed. */\n duration?: number\n /** Reuse an id to update a toast in place instead of stacking a new one. */\n id?: string\n closeButton?: boolean\n action?: ToastAction\n onDismiss?: () => void\n /** `high` announces urgently (assertive); the default is polite. */\n priority?: 'low' | 'high'\n}\n\ntype ToastPromiseMessages<Value> = {\n loading: string\n success: string | ((value: Value) => string)\n error: string | ((error: unknown) => string)\n}\n\nconst TOAST_ICONS: Record<\n Exclude<ToastType, 'loading'>,\n { name: MaterialSymbolIconName; className: string }\n> = {\n success: { name: 'check_circle', className: 'text-success-light' },\n info: { name: 'info', className: 'text-info-light' },\n warning: { name: 'warning', className: 'text-warning-light' },\n error: { name: 'cancel', className: 'text-error-light' },\n}\n\n// Opaque radix steps (bg 2, border 6, text 11) so a floating toast never lets\n// page content bleed through the way the alpha `-soft` tokens would. The border\n// carries the tone too, otherwise a tinted toast keeps a grey outline.\nconst TONE_CLASSES: Record<Exclude<ToastType, 'loading'>, string> = {\n success: 'border-green-6 bg-green-2 text-green-11',\n info: 'border-blue-6 bg-blue-2 text-blue-11',\n warning: 'border-orange-6 bg-orange-2 text-orange-11',\n error: 'border-red-6 bg-red-2 text-red-11',\n}\n\n// Mobile-first: every position drops to a full-width stack at the top, which\n// is what the end-customer portal ships. `position` only takes effect from the\n// `sm` breakpoint up.\nconst POSITION_CLASSES: Record<ToastPosition, string> = {\n 'top-left': 'sm:top-4 sm:right-auto sm:bottom-auto sm:left-4',\n 'top-center':\n 'sm:top-4 sm:right-auto sm:bottom-auto sm:left-1/2 sm:-translate-x-1/2',\n 'top-right': 'sm:top-4 sm:right-4 sm:bottom-auto sm:left-auto',\n 'bottom-left': 'sm:top-auto sm:right-auto sm:bottom-4 sm:left-4',\n 'bottom-center':\n 'sm:top-auto sm:right-auto sm:bottom-4 sm:left-1/2 sm:-translate-x-1/2',\n 'bottom-right': 'sm:top-auto sm:right-4 sm:bottom-4 sm:left-auto',\n}\n\nconst manager = ToastPrimitive.createToastManager<ToastData>()\n\nlet sequence = 0\n\n// `label` names the content and `onClick` is wrapped, so neither reaches the\n// DOM button as-is; everything else does.\nfunction actionRest({\n label: _label,\n onClick: _onClick,\n ...rest\n}: ToastAction) {\n return rest\n}\n\nfunction toManagerOptions(\n id: string,\n title: React.ReactNode,\n type: ToastType | undefined,\n options: ToastOptions | undefined,\n) {\n const action = options?.action\n return {\n id,\n title,\n type,\n description: options?.description,\n timeout: options?.duration,\n priority: options?.priority,\n onClose: options?.onDismiss,\n // Base UI leaves the toast open after an action; dismissing matches what\n // callers expect from an \"Undo\" button.\n actionProps: action && {\n ...actionRest(action),\n children: action.label,\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => {\n action.onClick?.(event)\n manager.close(id)\n },\n },\n data: { closeButton: options?.closeButton },\n }\n}\n\nconst emit =\n (type?: ToastType) =>\n (message: React.ReactNode, options?: ToastOptions): string => {\n // an id up front lets the action handler close the toast it belongs to\n const id = options?.id ?? `spark-toast-${(sequence += 1)}`\n return manager.add(toManagerOptions(id, message, type, options))\n }\n\n// A string phase becomes a titled toast of that type; an object phase keeps\n// whatever the caller set and only fills in the type.\nconst phase =\n <Value,>(\n value: ToastPromiseMessages<Value>[keyof ToastPromiseMessages<Value>],\n type: ToastType,\n ) =>\n (result: Value) => {\n const resolved = typeof value === 'function' ? value(result) : value\n return { title: resolved, type }\n }\n\nconst toast = Object.assign(emit(), {\n success: emit('success'),\n info: emit('info'),\n warning: emit('warning'),\n error: emit('error'),\n loading: emit('loading'),\n /** Dismiss one toast, or every toast when called without an id. */\n dismiss: (id?: string) => manager.close(id),\n promise: <Value,>(\n promiseValue: Promise<Value>,\n messages: ToastPromiseMessages<Value>,\n ) =>\n manager.promise(promiseValue, {\n loading: { title: messages.loading, type: 'loading' as const },\n success: phase(messages.success, 'success'),\n error: phase(messages.error as never, 'error'),\n }),\n})\n\nfunction ToastIcon({ type }: { type?: string }) {\n const icon = TOAST_ICONS[type as Exclude<ToastType, 'loading'>]\n if (type !== 'loading' && !icon) return null\n\n // Fixed box matching the title's line height, so the glyph and the spinner\n // both centre on the first line whether or not a description follows.\n return (\n <span\n aria-hidden=\"true\"\n className=\"flex h-5 w-5 shrink-0 items-center justify-center\"\n >\n {type === 'loading' ? (\n // Decorative: the toast already announces the loading message, so the\n // spinner must not add a second status live region.\n <Spinner\n className=\"text-gray-11\"\n label=\"\"\n role=\"presentation\"\n size=\"sm\"\n />\n ) : (\n <MaterialSymbol\n className={cn('[--spark-icon-size:20px]', icon.className)}\n name={icon.name}\n />\n )}\n </span>\n )\n}\n\nfunction ToastItem({\n closeButton,\n richColors,\n toast: toastObject,\n}: {\n closeButton: boolean\n richColors: boolean\n toast: ToastPrimitive.Root.ToastObject<ToastData>\n}) {\n const tone = TONE_CLASSES[toastObject.type as Exclude<ToastType, 'loading'>]\n const showClose = toastObject.data?.closeButton ?? closeButton\n\n return (\n <ToastPrimitive.Root\n data-slot=\"toast\"\n className={cn(\n // Skin only. All geometry (position, stacking, transitions, the\n // pointer bridge) lives in styles/index.css, because Tailwind's\n // `utilities` layer outranks `components` and a stray `bottom-0` here\n // would beat the stylesheet's `bottom: auto` on top-anchored stacks.\n // The border is what makes the cards behind the front one legible.\n 'flex items-start gap-2 rounded-md border border-gray-a5 bg-gray-1 p-3 text-gray shadow-md select-none',\n richColors && tone,\n )}\n // the stack is top-anchored on mobile and bottom-anchored above `sm`, so\n // both vertical directions have to dismiss\n swipeDirection={['up', 'down', 'right']}\n toast={toastObject}\n >\n <ToastIcon type={toastObject.type} />\n <ToastPrimitive.Content className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <ToastPrimitive.Title\n className=\"text-sm font-medium\"\n data-slot=\"toast-title\"\n />\n <ToastPrimitive.Description\n className={cn(\n 'text-sm',\n richColors && tone ? 'text-inherit' : 'text-gray-11',\n )}\n data-slot=\"toast-description\"\n />\n </ToastPrimitive.Content>\n {toastObject.actionProps ? (\n <ToastPrimitive.Action\n // -my-2 keeps the 36px control from stretching a single-line row past\n // the 20px text; self-center then lands it on the title when there is\n // no description, and mid-block when there is one\n className={cn(\n buttonVariants({ size: 'small', variant: 'primary' }),\n '-my-2 shrink-0 self-center rounded-full',\n )}\n data-slot=\"toast-action\"\n />\n ) : null}\n {showClose ? (\n <ToastPrimitive.Close\n aria-label=\"Close\"\n className={cn(\n buttonVariants({ size: 'icon-small', variant: 'tertiary' }),\n // -my-1: same reason as the action, for a 28px control\n '-my-1 -mr-1 size-7 shrink-0 self-center text-gray-11',\n )}\n data-slot=\"toast-close\"\n >\n <MaterialSymbol\n aria-hidden=\"true\"\n className=\"[--spark-icon-size:18px]\"\n name=\"close\"\n />\n </ToastPrimitive.Close>\n ) : null}\n </ToastPrimitive.Root>\n )\n}\n\nfunction ToastList({\n closeButton,\n richColors,\n}: {\n closeButton: boolean\n richColors: boolean\n}) {\n const { toasts } = ToastPrimitive.useToastManager<ToastData>()\n\n return toasts.map((toastObject) => (\n <ToastItem\n closeButton={closeButton}\n key={toastObject.id}\n richColors={richColors}\n toast={toastObject}\n />\n ))\n}\n\ntype ToasterProps = {\n className?: string\n /** Corner or edge the toasts stack in. */\n position?: ToastPosition\n /** Close button on every toast; a per-toast `closeButton` wins. */\n closeButton?: boolean\n /** Tinted surfaces for success/info/warning/error toasts. */\n richColors?: boolean\n /** Default auto-dismiss time in ms. `0` disables auto-dismiss. */\n duration?: number\n /** Toasts visible at once before older ones are marked `data-limited`. */\n limit?: number\n /**\n * Vertical edge below the `sm` breakpoint, where the stack is always\n * full-width and `position` does not apply. Defaults to `top`, matching the\n * end-customer portal.\n */\n mobilePosition?: 'top' | 'bottom'\n}\n\nfunction Toaster({\n className,\n closeButton = true,\n duration = 4000,\n limit,\n mobilePosition = 'top',\n position = 'bottom-right',\n richColors = true,\n}: ToasterProps) {\n return (\n <ToastPrimitive.Provider\n limit={limit}\n timeout={duration}\n toastManager={manager}\n >\n <ToastPrimitive.Portal>\n <ToastPrimitive.Viewport\n // block + zero height: the toasts are absolutely positioned against\n // this box's bottom edge, the way Base UI's stacked example works\n className={cn(\n 'fixed inset-x-4 z-50 block h-0 outline-none',\n mobilePosition === 'top' ? 'top-4' : 'bottom-4',\n 'sm:inset-x-auto sm:w-96 sm:max-w-[calc(100vw-2rem)]',\n POSITION_CLASSES[position],\n className,\n )}\n data-mobile-side={mobilePosition}\n data-side={position.startsWith('top') ? 'top' : 'bottom'}\n data-slot=\"toaster\"\n >\n <ToastList closeButton={closeButton} richColors={richColors} />\n </ToastPrimitive.Viewport>\n </ToastPrimitive.Portal>\n </ToastPrimitive.Provider>\n )\n}\n\nexport { Toaster, toast }\nexport type {\n ToastAction,\n ToasterProps,\n ToastOptions,\n ToastPosition,\n ToastPromiseMessages,\n ToastType,\n}\n"],"mappings":"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"}
@@ -39,7 +39,7 @@ const TooltipContent = ({ className, hideArrow = false, variant = "default", chi
39
39
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_base_ui_react_tooltip.Tooltip.Popup, {
40
40
  "data-slot": "tooltip-content",
41
41
  "data-variant": variant,
42
- className: (0, cnfast.cn)("z-50 w-fit origin-(--transform-origin) rounded-lg p-2 text-xs leading-none text-balance transition-[opacity,scale,translate] duration-150", "data-starting-style:scale-95 data-starting-style:opacity-0", "data-[side=bottom]:data-starting-style:-translate-y-1 data-[side=left]:data-starting-style:translate-x-1 data-[side=right]:data-starting-style:-translate-x-1 data-[side=top]:data-starting-style:translate-y-1", "data-ending-style:opacity-0 data-ending-style:duration-0", "data-[variant=default]:bg-gray-12 data-[variant=default]:text-gray-1", "data-[variant=destructive]:bg-red-12 data-[variant=destructive]:text-red-1", className),
42
+ className: (0, cnfast.cn)("z-50 w-fit origin-(--transform-origin) rounded-lg p-2 text-xs leading-none transition-[opacity,scale,translate] duration-150", "data-starting-style:scale-95 data-starting-style:opacity-0", "data-[side=bottom]:data-starting-style:-translate-y-1 data-[side=left]:data-starting-style:translate-x-1 data-[side=right]:data-starting-style:-translate-x-1 data-[side=top]:data-starting-style:translate-y-1", "data-ending-style:opacity-0 data-ending-style:duration-0", "data-[variant=default]:bg-gray-12 data-[variant=default]:text-gray-1", "data-[variant=destructive]:bg-red-12 data-[variant=destructive]:text-red-1", className),
43
43
  ...props,
44
44
  children: [children, !hideArrow && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_tooltip.Tooltip.Arrow, {
45
45
  "data-variant": variant,
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.cjs","names":["TooltipPrimitive","MaterialSymbol"],"sources":["../../src/components/tooltip.tsx"],"sourcesContent":["import { Tooltip as TooltipPrimitive } from '@base-ui/react/tooltip'\nimport * as React from 'react'\nimport { MaterialSymbol } from '../icons/material-symbol'\nimport { cn } from '../utils/cn'\n\nconst TooltipProvider = ({\n delay = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) => {\n return <TooltipPrimitive.Provider delay={delay} {...props} />\n}\n\nconst TooltipPortal = ({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Portal>) => {\n return <TooltipPrimitive.Portal data-slot=\"tooltip-portal\" {...props} />\n}\n\ntype TooltipProps = React.ComponentProps<typeof TooltipPrimitive.Root>\n\nconst Tooltip = ({ ...props }: TooltipProps) => {\n return <TooltipPrimitive.Root {...props} />\n}\n\nconst TooltipTrigger = ({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) => {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\ntype TooltipContentProps = React.ComponentProps<typeof TooltipPrimitive.Popup> &\n Pick<\n TooltipPrimitive.Positioner.Props,\n 'align' | 'alignOffset' | 'side' | 'sideOffset'\n > & {\n hideArrow?: boolean\n variant?: 'default' | 'destructive'\n }\n\nconst TooltipContent = ({\n className,\n hideArrow = false,\n variant = 'default',\n children,\n align,\n alignOffset,\n side,\n sideOffset = 4,\n ...props\n}: TooltipContentProps) => {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n className=\"isolate z-50\"\n side={side}\n sideOffset={sideOffset}\n >\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-content\"\n data-variant={variant}\n className={cn(\n 'z-50 w-fit origin-(--transform-origin) rounded-lg p-2 text-xs leading-none text-balance transition-[opacity,scale,translate] duration-150',\n // enter: fade + zoom + a slight per-side slide (was animate-in)\n 'data-starting-style:scale-95 data-starting-style:opacity-0',\n 'data-[side=bottom]:data-starting-style:-translate-y-1 data-[side=left]:data-starting-style:translate-x-1 data-[side=right]:data-starting-style:-translate-x-1 data-[side=top]:data-starting-style:translate-y-1',\n // exit: instant (was data-[state=closed]:duration-0)\n 'data-ending-style:opacity-0 data-ending-style:duration-0',\n 'data-[variant=default]:bg-gray-12 data-[variant=default]:text-gray-1',\n 'data-[variant=destructive]:bg-red-12 data-[variant=destructive]:text-red-1',\n className,\n )}\n {...props}\n >\n {children}\n {!hideArrow && (\n <TooltipPrimitive.Arrow\n data-variant={variant}\n className={cn(\n 'z-50',\n // svg tip points up; rotate per side, overlap 2px for a seamless join\n 'data-[side=bottom]:top-[-8px]',\n 'data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180',\n 'data-[side=left]:right-[-13px] data-[side=left]:rotate-90',\n 'data-[side=right]:left-[-13px] data-[side=right]:-rotate-90',\n 'data-[variant=default]:text-gray-12',\n 'data-[variant=destructive]:text-red-12',\n )}\n >\n <svg fill=\"none\" height=\"10\" viewBox=\"0 0 20 10\" width=\"20\">\n <path\n d=\"M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z\"\n fill=\"currentColor\"\n />\n </svg>\n </TooltipPrimitive.Arrow>\n )}\n </TooltipPrimitive.Popup>\n </TooltipPrimitive.Positioner>\n </TooltipPrimitive.Portal>\n )\n}\n\ninterface InfoTooltipProps {\n content: string\n label: string\n 'aria-label'?: string\n}\n\nconst InfoTooltip = ({\n content,\n label,\n 'aria-label': ariaLabel,\n}: InfoTooltipProps) => {\n return (\n <Tooltip>\n <TooltipTrigger\n render={\n <button\n aria-label={ariaLabel ?? label}\n className=\"focus-visible:ring-primary relative top-px inline-flex size-4 cursor-help items-center justify-center rounded-full text-gray-light transition-colors hover:text-gray focus-visible:ring-2 focus-visible:outline-none\"\n type=\"button\"\n />\n }\n >\n <MaterialSymbol className=\"text-sm!\" name=\"info\" />\n </TooltipTrigger>\n <TooltipContent className=\"max-w-xs whitespace-pre-line\">\n {content}\n </TooltipContent>\n </Tooltip>\n )\n}\n\nexport {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n TooltipProvider,\n TooltipPortal,\n InfoTooltip,\n}\n"],"mappings":";;;;;;;;;;AAKA,MAAM,mBAAmB,EACvB,QAAQ,GACR,GAAG,YACyD;AAC5D,QAAO,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,UAAlB;EAAkC;EAAO,GAAI;EAAS,CAAA;;AAG/D,MAAM,iBAAiB,EACrB,GAAG,YACuD;AAC1D,QAAO,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,QAAlB;EAAyB,aAAU;EAAiB,GAAI;EAAS,CAAA;;AAK1E,MAAM,WAAW,EAAE,GAAG,YAA0B;AAC9C,QAAO,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,MAAlB,EAAuB,GAAI,OAAS,CAAA;;AAG7C,MAAM,kBAAkB,EACtB,GAAG,YACwD;AAC3D,QAAO,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,SAAlB;EAA0B,aAAU;EAAkB,GAAI;EAAS,CAAA;;AAY5E,MAAM,kBAAkB,EACtB,WACA,YAAY,OACZ,UAAU,WACV,UACA,OACA,aACA,MACA,aAAa,GACb,GAAG,YACsB;AACzB,QACE,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,QAAlB,EAAA,UACE,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,YAAlB;EACS;EACM;EACb,WAAU;EACJ;EACM;YAEZ,iBAAA,GAAA,kBAAA,MAACA,uBAAAA,QAAiB,OAAlB;GACE,aAAU;GACV,gBAAc;GACd,YAAA,GAAA,OAAA,IACE,6IAEA,8DACA,mNAEA,4DACA,wEACA,8EACA,UACD;GACD,GAAI;aAdN,CAgBG,UACA,CAAC,aACA,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,OAAlB;IACE,gBAAc;IACd,YAAA,GAAA,OAAA,IACE,QAEA,iCACA,4DACA,6DACA,+DACA,uCACA,yCACD;cAED,iBAAA,GAAA,kBAAA,KAAC,OAAD;KAAK,MAAK;KAAO,QAAO;KAAK,SAAQ;KAAY,OAAM;eACrD,iBAAA,GAAA,kBAAA,KAAC,QAAD;MACE,GAAE;MACF,MAAK;MACL,CAAA;KACE,CAAA;IACiB,CAAA,CAEJ;;EACG,CAAA,EACN,CAAA;;AAU9B,MAAM,eAAe,EACnB,SACA,OACA,cAAc,gBACQ;AACtB,QACE,iBAAA,GAAA,kBAAA,MAAC,SAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAC,gBAAD;EACE,QACE,iBAAA,GAAA,kBAAA,KAAC,UAAD;GACE,cAAY,aAAa;GACzB,WAAU;GACV,MAAK;GACL,CAAA;YAGJ,iBAAA,GAAA,kBAAA,KAACC,8BAAAA,gBAAD;GAAgB,WAAU;GAAW,MAAK;GAAS,CAAA;EACpC,CAAA,EACjB,iBAAA,GAAA,kBAAA,KAAC,gBAAD;EAAgB,WAAU;YACvB;EACc,CAAA,CACT,EAAA,CAAA"}
1
+ {"version":3,"file":"tooltip.cjs","names":["TooltipPrimitive","MaterialSymbol"],"sources":["../../src/components/tooltip.tsx"],"sourcesContent":["import { Tooltip as TooltipPrimitive } from '@base-ui/react/tooltip'\nimport * as React from 'react'\nimport { MaterialSymbol } from '../icons/material-symbol'\nimport { cn } from '../utils/cn'\n\nconst TooltipProvider = ({\n delay = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) => {\n return <TooltipPrimitive.Provider delay={delay} {...props} />\n}\n\nconst TooltipPortal = ({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Portal>) => {\n return <TooltipPrimitive.Portal data-slot=\"tooltip-portal\" {...props} />\n}\n\ntype TooltipProps = React.ComponentProps<typeof TooltipPrimitive.Root>\n\nconst Tooltip = ({ ...props }: TooltipProps) => {\n return <TooltipPrimitive.Root {...props} />\n}\n\nconst TooltipTrigger = ({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) => {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\ntype TooltipContentProps = React.ComponentProps<typeof TooltipPrimitive.Popup> &\n Pick<\n TooltipPrimitive.Positioner.Props,\n 'align' | 'alignOffset' | 'side' | 'sideOffset'\n > & {\n hideArrow?: boolean\n variant?: 'default' | 'destructive'\n }\n\nconst TooltipContent = ({\n className,\n hideArrow = false,\n variant = 'default',\n children,\n align,\n alignOffset,\n side,\n sideOffset = 4,\n ...props\n}: TooltipContentProps) => {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n className=\"isolate z-50\"\n side={side}\n sideOffset={sideOffset}\n >\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-content\"\n data-variant={variant}\n className={cn(\n 'z-50 w-fit origin-(--transform-origin) rounded-lg p-2 text-xs leading-none transition-[opacity,scale,translate] duration-150',\n // enter: fade + zoom + a slight per-side slide (was animate-in)\n 'data-starting-style:scale-95 data-starting-style:opacity-0',\n 'data-[side=bottom]:data-starting-style:-translate-y-1 data-[side=left]:data-starting-style:translate-x-1 data-[side=right]:data-starting-style:-translate-x-1 data-[side=top]:data-starting-style:translate-y-1',\n // exit: instant (was data-[state=closed]:duration-0)\n 'data-ending-style:opacity-0 data-ending-style:duration-0',\n 'data-[variant=default]:bg-gray-12 data-[variant=default]:text-gray-1',\n 'data-[variant=destructive]:bg-red-12 data-[variant=destructive]:text-red-1',\n className,\n )}\n {...props}\n >\n {children}\n {!hideArrow && (\n <TooltipPrimitive.Arrow\n data-variant={variant}\n className={cn(\n 'z-50',\n // svg tip points up; rotate per side, overlap 2px for a seamless join\n 'data-[side=bottom]:top-[-8px]',\n 'data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180',\n 'data-[side=left]:right-[-13px] data-[side=left]:rotate-90',\n 'data-[side=right]:left-[-13px] data-[side=right]:-rotate-90',\n 'data-[variant=default]:text-gray-12',\n 'data-[variant=destructive]:text-red-12',\n )}\n >\n <svg fill=\"none\" height=\"10\" viewBox=\"0 0 20 10\" width=\"20\">\n <path\n d=\"M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z\"\n fill=\"currentColor\"\n />\n </svg>\n </TooltipPrimitive.Arrow>\n )}\n </TooltipPrimitive.Popup>\n </TooltipPrimitive.Positioner>\n </TooltipPrimitive.Portal>\n )\n}\n\ninterface InfoTooltipProps {\n content: string\n label: string\n 'aria-label'?: string\n}\n\nconst InfoTooltip = ({\n content,\n label,\n 'aria-label': ariaLabel,\n}: InfoTooltipProps) => {\n return (\n <Tooltip>\n <TooltipTrigger\n render={\n <button\n aria-label={ariaLabel ?? label}\n className=\"focus-visible:ring-primary relative top-px inline-flex size-4 cursor-help items-center justify-center rounded-full text-gray-light transition-colors hover:text-gray focus-visible:ring-2 focus-visible:outline-none\"\n type=\"button\"\n />\n }\n >\n <MaterialSymbol className=\"text-sm!\" name=\"info\" />\n </TooltipTrigger>\n <TooltipContent className=\"max-w-xs whitespace-pre-line\">\n {content}\n </TooltipContent>\n </Tooltip>\n )\n}\n\nexport {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n TooltipProvider,\n TooltipPortal,\n InfoTooltip,\n}\n"],"mappings":";;;;;;;;;;AAKA,MAAM,mBAAmB,EACvB,QAAQ,GACR,GAAG,YACyD;AAC5D,QAAO,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,UAAlB;EAAkC;EAAO,GAAI;EAAS,CAAA;;AAG/D,MAAM,iBAAiB,EACrB,GAAG,YACuD;AAC1D,QAAO,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,QAAlB;EAAyB,aAAU;EAAiB,GAAI;EAAS,CAAA;;AAK1E,MAAM,WAAW,EAAE,GAAG,YAA0B;AAC9C,QAAO,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,MAAlB,EAAuB,GAAI,OAAS,CAAA;;AAG7C,MAAM,kBAAkB,EACtB,GAAG,YACwD;AAC3D,QAAO,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,SAAlB;EAA0B,aAAU;EAAkB,GAAI;EAAS,CAAA;;AAY5E,MAAM,kBAAkB,EACtB,WACA,YAAY,OACZ,UAAU,WACV,UACA,OACA,aACA,MACA,aAAa,GACb,GAAG,YACsB;AACzB,QACE,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,QAAlB,EAAA,UACE,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,YAAlB;EACS;EACM;EACb,WAAU;EACJ;EACM;YAEZ,iBAAA,GAAA,kBAAA,MAACA,uBAAAA,QAAiB,OAAlB;GACE,aAAU;GACV,gBAAc;GACd,YAAA,GAAA,OAAA,IACE,gIAEA,8DACA,mNAEA,4DACA,wEACA,8EACA,UACD;GACD,GAAI;aAdN,CAgBG,UACA,CAAC,aACA,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,OAAlB;IACE,gBAAc;IACd,YAAA,GAAA,OAAA,IACE,QAEA,iCACA,4DACA,6DACA,+DACA,uCACA,yCACD;cAED,iBAAA,GAAA,kBAAA,KAAC,OAAD;KAAK,MAAK;KAAO,QAAO;KAAK,SAAQ;KAAY,OAAM;eACrD,iBAAA,GAAA,kBAAA,KAAC,QAAD;MACE,GAAE;MACF,MAAK;MACL,CAAA;KACE,CAAA;IACiB,CAAA,CAEJ;;EACG,CAAA,EACN,CAAA;;AAU9B,MAAM,eAAe,EACnB,SACA,OACA,cAAc,gBACQ;AACtB,QACE,iBAAA,GAAA,kBAAA,MAAC,SAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAC,gBAAD;EACE,QACE,iBAAA,GAAA,kBAAA,KAAC,UAAD;GACE,cAAY,aAAa;GACzB,WAAU;GACV,MAAK;GACL,CAAA;YAGJ,iBAAA,GAAA,kBAAA,KAACC,8BAAAA,gBAAD;GAAgB,WAAU;GAAW,MAAK;GAAS,CAAA;EACpC,CAAA,EACjB,iBAAA,GAAA,kBAAA,KAAC,gBAAD;EAAgB,WAAU;YACvB;EACc,CAAA,CACT,EAAA,CAAA"}
@@ -36,7 +36,7 @@ const TooltipContent = ({ className, hideArrow = false, variant = "default", chi
36
36
  children: /* @__PURE__ */ jsxs(Tooltip$1.Popup, {
37
37
  "data-slot": "tooltip-content",
38
38
  "data-variant": variant,
39
- className: cn("z-50 w-fit origin-(--transform-origin) rounded-lg p-2 text-xs leading-none text-balance transition-[opacity,scale,translate] duration-150", "data-starting-style:scale-95 data-starting-style:opacity-0", "data-[side=bottom]:data-starting-style:-translate-y-1 data-[side=left]:data-starting-style:translate-x-1 data-[side=right]:data-starting-style:-translate-x-1 data-[side=top]:data-starting-style:translate-y-1", "data-ending-style:opacity-0 data-ending-style:duration-0", "data-[variant=default]:bg-gray-12 data-[variant=default]:text-gray-1", "data-[variant=destructive]:bg-red-12 data-[variant=destructive]:text-red-1", className),
39
+ className: cn("z-50 w-fit origin-(--transform-origin) rounded-lg p-2 text-xs leading-none transition-[opacity,scale,translate] duration-150", "data-starting-style:scale-95 data-starting-style:opacity-0", "data-[side=bottom]:data-starting-style:-translate-y-1 data-[side=left]:data-starting-style:translate-x-1 data-[side=right]:data-starting-style:-translate-x-1 data-[side=top]:data-starting-style:translate-y-1", "data-ending-style:opacity-0 data-ending-style:duration-0", "data-[variant=default]:bg-gray-12 data-[variant=default]:text-gray-1", "data-[variant=destructive]:bg-red-12 data-[variant=destructive]:text-red-1", className),
40
40
  ...props,
41
41
  children: [children, !hideArrow && /* @__PURE__ */ jsx(Tooltip$1.Arrow, {
42
42
  "data-variant": variant,
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.js","names":["TooltipPrimitive"],"sources":["../../src/components/tooltip.tsx"],"sourcesContent":["import { Tooltip as TooltipPrimitive } from '@base-ui/react/tooltip'\nimport * as React from 'react'\nimport { MaterialSymbol } from '../icons/material-symbol'\nimport { cn } from '../utils/cn'\n\nconst TooltipProvider = ({\n delay = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) => {\n return <TooltipPrimitive.Provider delay={delay} {...props} />\n}\n\nconst TooltipPortal = ({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Portal>) => {\n return <TooltipPrimitive.Portal data-slot=\"tooltip-portal\" {...props} />\n}\n\ntype TooltipProps = React.ComponentProps<typeof TooltipPrimitive.Root>\n\nconst Tooltip = ({ ...props }: TooltipProps) => {\n return <TooltipPrimitive.Root {...props} />\n}\n\nconst TooltipTrigger = ({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) => {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\ntype TooltipContentProps = React.ComponentProps<typeof TooltipPrimitive.Popup> &\n Pick<\n TooltipPrimitive.Positioner.Props,\n 'align' | 'alignOffset' | 'side' | 'sideOffset'\n > & {\n hideArrow?: boolean\n variant?: 'default' | 'destructive'\n }\n\nconst TooltipContent = ({\n className,\n hideArrow = false,\n variant = 'default',\n children,\n align,\n alignOffset,\n side,\n sideOffset = 4,\n ...props\n}: TooltipContentProps) => {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n className=\"isolate z-50\"\n side={side}\n sideOffset={sideOffset}\n >\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-content\"\n data-variant={variant}\n className={cn(\n 'z-50 w-fit origin-(--transform-origin) rounded-lg p-2 text-xs leading-none text-balance transition-[opacity,scale,translate] duration-150',\n // enter: fade + zoom + a slight per-side slide (was animate-in)\n 'data-starting-style:scale-95 data-starting-style:opacity-0',\n 'data-[side=bottom]:data-starting-style:-translate-y-1 data-[side=left]:data-starting-style:translate-x-1 data-[side=right]:data-starting-style:-translate-x-1 data-[side=top]:data-starting-style:translate-y-1',\n // exit: instant (was data-[state=closed]:duration-0)\n 'data-ending-style:opacity-0 data-ending-style:duration-0',\n 'data-[variant=default]:bg-gray-12 data-[variant=default]:text-gray-1',\n 'data-[variant=destructive]:bg-red-12 data-[variant=destructive]:text-red-1',\n className,\n )}\n {...props}\n >\n {children}\n {!hideArrow && (\n <TooltipPrimitive.Arrow\n data-variant={variant}\n className={cn(\n 'z-50',\n // svg tip points up; rotate per side, overlap 2px for a seamless join\n 'data-[side=bottom]:top-[-8px]',\n 'data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180',\n 'data-[side=left]:right-[-13px] data-[side=left]:rotate-90',\n 'data-[side=right]:left-[-13px] data-[side=right]:-rotate-90',\n 'data-[variant=default]:text-gray-12',\n 'data-[variant=destructive]:text-red-12',\n )}\n >\n <svg fill=\"none\" height=\"10\" viewBox=\"0 0 20 10\" width=\"20\">\n <path\n d=\"M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z\"\n fill=\"currentColor\"\n />\n </svg>\n </TooltipPrimitive.Arrow>\n )}\n </TooltipPrimitive.Popup>\n </TooltipPrimitive.Positioner>\n </TooltipPrimitive.Portal>\n )\n}\n\ninterface InfoTooltipProps {\n content: string\n label: string\n 'aria-label'?: string\n}\n\nconst InfoTooltip = ({\n content,\n label,\n 'aria-label': ariaLabel,\n}: InfoTooltipProps) => {\n return (\n <Tooltip>\n <TooltipTrigger\n render={\n <button\n aria-label={ariaLabel ?? label}\n className=\"focus-visible:ring-primary relative top-px inline-flex size-4 cursor-help items-center justify-center rounded-full text-gray-light transition-colors hover:text-gray focus-visible:ring-2 focus-visible:outline-none\"\n type=\"button\"\n />\n }\n >\n <MaterialSymbol className=\"text-sm!\" name=\"info\" />\n </TooltipTrigger>\n <TooltipContent className=\"max-w-xs whitespace-pre-line\">\n {content}\n </TooltipContent>\n </Tooltip>\n )\n}\n\nexport {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n TooltipProvider,\n TooltipPortal,\n InfoTooltip,\n}\n"],"mappings":";;;;;;;AAKA,MAAM,mBAAmB,EACvB,QAAQ,GACR,GAAG,YACyD;AAC5D,QAAO,oBAACA,UAAiB,UAAlB;EAAkC;EAAO,GAAI;EAAS,CAAA;;AAG/D,MAAM,iBAAiB,EACrB,GAAG,YACuD;AAC1D,QAAO,oBAACA,UAAiB,QAAlB;EAAyB,aAAU;EAAiB,GAAI;EAAS,CAAA;;AAK1E,MAAM,WAAW,EAAE,GAAG,YAA0B;AAC9C,QAAO,oBAACA,UAAiB,MAAlB,EAAuB,GAAI,OAAS,CAAA;;AAG7C,MAAM,kBAAkB,EACtB,GAAG,YACwD;AAC3D,QAAO,oBAACA,UAAiB,SAAlB;EAA0B,aAAU;EAAkB,GAAI;EAAS,CAAA;;AAY5E,MAAM,kBAAkB,EACtB,WACA,YAAY,OACZ,UAAU,WACV,UACA,OACA,aACA,MACA,aAAa,GACb,GAAG,YACsB;AACzB,QACE,oBAACA,UAAiB,QAAlB,EAAA,UACE,oBAACA,UAAiB,YAAlB;EACS;EACM;EACb,WAAU;EACJ;EACM;YAEZ,qBAACA,UAAiB,OAAlB;GACE,aAAU;GACV,gBAAc;GACd,WAAW,GACT,6IAEA,8DACA,mNAEA,4DACA,wEACA,8EACA,UACD;GACD,GAAI;aAdN,CAgBG,UACA,CAAC,aACA,oBAACA,UAAiB,OAAlB;IACE,gBAAc;IACd,WAAW,GACT,QAEA,iCACA,4DACA,6DACA,+DACA,uCACA,yCACD;cAED,oBAAC,OAAD;KAAK,MAAK;KAAO,QAAO;KAAK,SAAQ;KAAY,OAAM;eACrD,oBAAC,QAAD;MACE,GAAE;MACF,MAAK;MACL,CAAA;KACE,CAAA;IACiB,CAAA,CAEJ;;EACG,CAAA,EACN,CAAA;;AAU9B,MAAM,eAAe,EACnB,SACA,OACA,cAAc,gBACQ;AACtB,QACE,qBAAC,SAAD,EAAA,UAAA,CACE,oBAAC,gBAAD;EACE,QACE,oBAAC,UAAD;GACE,cAAY,aAAa;GACzB,WAAU;GACV,MAAK;GACL,CAAA;YAGJ,oBAAC,gBAAD;GAAgB,WAAU;GAAW,MAAK;GAAS,CAAA;EACpC,CAAA,EACjB,oBAAC,gBAAD;EAAgB,WAAU;YACvB;EACc,CAAA,CACT,EAAA,CAAA"}
1
+ {"version":3,"file":"tooltip.js","names":["TooltipPrimitive"],"sources":["../../src/components/tooltip.tsx"],"sourcesContent":["import { Tooltip as TooltipPrimitive } from '@base-ui/react/tooltip'\nimport * as React from 'react'\nimport { MaterialSymbol } from '../icons/material-symbol'\nimport { cn } from '../utils/cn'\n\nconst TooltipProvider = ({\n delay = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) => {\n return <TooltipPrimitive.Provider delay={delay} {...props} />\n}\n\nconst TooltipPortal = ({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Portal>) => {\n return <TooltipPrimitive.Portal data-slot=\"tooltip-portal\" {...props} />\n}\n\ntype TooltipProps = React.ComponentProps<typeof TooltipPrimitive.Root>\n\nconst Tooltip = ({ ...props }: TooltipProps) => {\n return <TooltipPrimitive.Root {...props} />\n}\n\nconst TooltipTrigger = ({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) => {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\ntype TooltipContentProps = React.ComponentProps<typeof TooltipPrimitive.Popup> &\n Pick<\n TooltipPrimitive.Positioner.Props,\n 'align' | 'alignOffset' | 'side' | 'sideOffset'\n > & {\n hideArrow?: boolean\n variant?: 'default' | 'destructive'\n }\n\nconst TooltipContent = ({\n className,\n hideArrow = false,\n variant = 'default',\n children,\n align,\n alignOffset,\n side,\n sideOffset = 4,\n ...props\n}: TooltipContentProps) => {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n className=\"isolate z-50\"\n side={side}\n sideOffset={sideOffset}\n >\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-content\"\n data-variant={variant}\n className={cn(\n 'z-50 w-fit origin-(--transform-origin) rounded-lg p-2 text-xs leading-none transition-[opacity,scale,translate] duration-150',\n // enter: fade + zoom + a slight per-side slide (was animate-in)\n 'data-starting-style:scale-95 data-starting-style:opacity-0',\n 'data-[side=bottom]:data-starting-style:-translate-y-1 data-[side=left]:data-starting-style:translate-x-1 data-[side=right]:data-starting-style:-translate-x-1 data-[side=top]:data-starting-style:translate-y-1',\n // exit: instant (was data-[state=closed]:duration-0)\n 'data-ending-style:opacity-0 data-ending-style:duration-0',\n 'data-[variant=default]:bg-gray-12 data-[variant=default]:text-gray-1',\n 'data-[variant=destructive]:bg-red-12 data-[variant=destructive]:text-red-1',\n className,\n )}\n {...props}\n >\n {children}\n {!hideArrow && (\n <TooltipPrimitive.Arrow\n data-variant={variant}\n className={cn(\n 'z-50',\n // svg tip points up; rotate per side, overlap 2px for a seamless join\n 'data-[side=bottom]:top-[-8px]',\n 'data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180',\n 'data-[side=left]:right-[-13px] data-[side=left]:rotate-90',\n 'data-[side=right]:left-[-13px] data-[side=right]:-rotate-90',\n 'data-[variant=default]:text-gray-12',\n 'data-[variant=destructive]:text-red-12',\n )}\n >\n <svg fill=\"none\" height=\"10\" viewBox=\"0 0 20 10\" width=\"20\">\n <path\n d=\"M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z\"\n fill=\"currentColor\"\n />\n </svg>\n </TooltipPrimitive.Arrow>\n )}\n </TooltipPrimitive.Popup>\n </TooltipPrimitive.Positioner>\n </TooltipPrimitive.Portal>\n )\n}\n\ninterface InfoTooltipProps {\n content: string\n label: string\n 'aria-label'?: string\n}\n\nconst InfoTooltip = ({\n content,\n label,\n 'aria-label': ariaLabel,\n}: InfoTooltipProps) => {\n return (\n <Tooltip>\n <TooltipTrigger\n render={\n <button\n aria-label={ariaLabel ?? label}\n className=\"focus-visible:ring-primary relative top-px inline-flex size-4 cursor-help items-center justify-center rounded-full text-gray-light transition-colors hover:text-gray focus-visible:ring-2 focus-visible:outline-none\"\n type=\"button\"\n />\n }\n >\n <MaterialSymbol className=\"text-sm!\" name=\"info\" />\n </TooltipTrigger>\n <TooltipContent className=\"max-w-xs whitespace-pre-line\">\n {content}\n </TooltipContent>\n </Tooltip>\n )\n}\n\nexport {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n TooltipProvider,\n TooltipPortal,\n InfoTooltip,\n}\n"],"mappings":";;;;;;;AAKA,MAAM,mBAAmB,EACvB,QAAQ,GACR,GAAG,YACyD;AAC5D,QAAO,oBAACA,UAAiB,UAAlB;EAAkC;EAAO,GAAI;EAAS,CAAA;;AAG/D,MAAM,iBAAiB,EACrB,GAAG,YACuD;AAC1D,QAAO,oBAACA,UAAiB,QAAlB;EAAyB,aAAU;EAAiB,GAAI;EAAS,CAAA;;AAK1E,MAAM,WAAW,EAAE,GAAG,YAA0B;AAC9C,QAAO,oBAACA,UAAiB,MAAlB,EAAuB,GAAI,OAAS,CAAA;;AAG7C,MAAM,kBAAkB,EACtB,GAAG,YACwD;AAC3D,QAAO,oBAACA,UAAiB,SAAlB;EAA0B,aAAU;EAAkB,GAAI;EAAS,CAAA;;AAY5E,MAAM,kBAAkB,EACtB,WACA,YAAY,OACZ,UAAU,WACV,UACA,OACA,aACA,MACA,aAAa,GACb,GAAG,YACsB;AACzB,QACE,oBAACA,UAAiB,QAAlB,EAAA,UACE,oBAACA,UAAiB,YAAlB;EACS;EACM;EACb,WAAU;EACJ;EACM;YAEZ,qBAACA,UAAiB,OAAlB;GACE,aAAU;GACV,gBAAc;GACd,WAAW,GACT,gIAEA,8DACA,mNAEA,4DACA,wEACA,8EACA,UACD;GACD,GAAI;aAdN,CAgBG,UACA,CAAC,aACA,oBAACA,UAAiB,OAAlB;IACE,gBAAc;IACd,WAAW,GACT,QAEA,iCACA,4DACA,6DACA,+DACA,uCACA,yCACD;cAED,oBAAC,OAAD;KAAK,MAAK;KAAO,QAAO;KAAK,SAAQ;KAAY,OAAM;eACrD,oBAAC,QAAD;MACE,GAAE;MACF,MAAK;MACL,CAAA;KACE,CAAA;IACiB,CAAA,CAEJ;;EACG,CAAA,EACN,CAAA;;AAU9B,MAAM,eAAe,EACnB,SACA,OACA,cAAc,gBACQ;AACtB,QACE,qBAAC,SAAD,EAAA,UAAA,CACE,oBAAC,gBAAD;EACE,QACE,oBAAC,UAAD;GACE,cAAY,aAAa;GACzB,WAAU;GACV,MAAK;GACL,CAAA;YAGJ,oBAAC,gBAAD;GAAgB,WAAU;GAAW,MAAK;GAAS,CAAA;EACpC,CAAA,EACjB,oBAAC,gBAAD;EAAgB,WAAU;YACvB;EACc,CAAA,CACT,EAAA,CAAA"}
@@ -0,0 +1,33 @@
1
+ "use client";
2
+
3
+ //#region src/lib/generate-radix-colors.d.ts
4
+ type ArrayOf12<T> = [T, T, T, T, T, T, T, T, T, T, T, T];
5
+ declare const generateRadixColors: ({
6
+ appearance,
7
+ ...args
8
+ }: {
9
+ appearance: "light" | "dark";
10
+ accent: string;
11
+ gray: string;
12
+ background: string;
13
+ }) => {
14
+ accentScale: ArrayOf12<string>;
15
+ accentScaleAlpha: ArrayOf12<string>;
16
+ accentScaleWideGamut: ArrayOf12<string>;
17
+ accentScaleAlphaWideGamut: ArrayOf12<string>;
18
+ accentContrast: string;
19
+ grayScale: ArrayOf12<string>;
20
+ grayScaleAlpha: ArrayOf12<string>;
21
+ grayScaleWideGamut: ArrayOf12<string>;
22
+ grayScaleAlphaWideGamut: ArrayOf12<string>;
23
+ graySurface: string;
24
+ graySurfaceWideGamut: string;
25
+ accentSurface: string;
26
+ accentSurfaceWideGamut: string;
27
+ background: string;
28
+ };
29
+ declare function transposeProgressionStart(to: number, arr: number[], curve: [number, number, number, number]): number[];
30
+ declare function transposeProgressionEnd(to: number, arr: number[], curve: [number, number, number, number]): number[];
31
+ //#endregion
32
+ export { transposeProgressionEnd as n, transposeProgressionStart as r, generateRadixColors as t };
33
+ //# sourceMappingURL=generate-radix-colors-BW09KT9m.d.ts.map