@epilot/spark-ui 0.25.1 → 0.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/accordion.cjs.map +1 -1
- package/dist/components/accordion.d.cts +1 -1
- package/dist/components/accordion.d.ts +1 -1
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/alert-dialog.cjs +5 -3
- package/dist/components/alert-dialog.cjs.map +1 -1
- package/dist/components/alert-dialog.d.cts +4 -1
- package/dist/components/alert-dialog.d.ts +4 -1
- package/dist/components/alert-dialog.js +5 -3
- package/dist/components/alert-dialog.js.map +1 -1
- package/dist/components/autocomplete.cjs +3 -2
- package/dist/components/autocomplete.cjs.map +1 -1
- package/dist/components/autocomplete.js +3 -2
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/avatar.js +1 -1
- package/dist/components/badge.js +1 -1
- package/dist/components/banner.cjs +74 -0
- package/dist/components/banner.cjs.map +1 -0
- package/dist/components/banner.d.cts +27 -0
- package/dist/components/banner.d.ts +27 -0
- package/dist/components/banner.js +72 -0
- package/dist/components/banner.js.map +1 -0
- package/dist/components/box.js +1 -1
- package/dist/components/bubble.d.cts +1 -1
- package/dist/components/bubble.d.ts +1 -1
- package/dist/components/button-group.js +1 -1
- package/dist/components/button.d.cts +2 -2
- package/dist/components/button.d.ts +2 -2
- package/dist/components/button.js +1 -1
- package/dist/components/callout.cjs +1 -1
- package/dist/components/callout.cjs.map +1 -1
- package/dist/components/callout.js +1 -1
- package/dist/components/callout.js.map +1 -1
- package/dist/components/card.js +1 -1
- package/dist/components/checkbox.js +1 -1
- package/dist/components/data-list.cjs +39 -0
- package/dist/components/data-list.cjs.map +1 -0
- package/dist/components/data-list.d.cts +33 -0
- package/dist/components/data-list.d.ts +33 -0
- package/dist/components/data-list.js +35 -0
- package/dist/components/data-list.js.map +1 -0
- package/dist/components/dialog.cjs +5 -3
- package/dist/components/dialog.cjs.map +1 -1
- package/dist/components/dialog.d.cts +4 -1
- package/dist/components/dialog.d.ts +4 -1
- package/dist/components/dialog.js +5 -3
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/drawer.cjs +13 -3
- package/dist/components/drawer.cjs.map +1 -1
- package/dist/components/drawer.d.cts +4 -1
- package/dist/components/drawer.d.ts +4 -1
- package/dist/components/drawer.js +14 -4
- package/dist/components/drawer.js.map +1 -1
- package/dist/components/dropdown-menu.cjs +5 -3
- package/dist/components/dropdown-menu.cjs.map +1 -1
- package/dist/components/dropdown-menu.d.cts +1 -0
- package/dist/components/dropdown-menu.d.ts +1 -0
- package/dist/components/dropdown-menu.js +5 -3
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/empty-state.cjs +97 -25
- package/dist/components/empty-state.cjs.map +1 -1
- package/dist/components/empty-state.d.cts +28 -11
- package/dist/components/empty-state.d.ts +28 -11
- package/dist/components/empty-state.js +94 -26
- package/dist/components/empty-state.js.map +1 -1
- package/dist/components/energy-breakdown.cjs +1 -1
- package/dist/components/energy-breakdown.cjs.map +1 -1
- package/dist/components/energy-breakdown.js +1 -1
- package/dist/components/energy-breakdown.js.map +1 -1
- package/dist/components/entity-card.cjs +1 -1
- package/dist/components/entity-card.cjs.map +1 -1
- package/dist/components/entity-card.js +1 -1
- package/dist/components/entity-card.js.map +1 -1
- package/dist/components/field.cjs +4 -4
- package/dist/components/field.cjs.map +1 -1
- package/dist/components/field.js +4 -4
- package/dist/components/field.js.map +1 -1
- package/dist/components/icon.js +1 -1
- package/dist/components/info-block.d.cts +1 -1
- package/dist/components/info-block.d.ts +1 -1
- package/dist/components/input-otp.cjs +1 -1
- package/dist/components/input-otp.js +1 -1
- package/dist/components/input.cjs +1 -1
- package/dist/components/input.js +1 -1
- package/dist/components/kbd.cjs +14 -0
- package/dist/components/kbd.cjs.map +1 -0
- package/dist/components/kbd.d.cts +13 -0
- package/dist/components/kbd.d.ts +13 -0
- package/dist/components/kbd.js +13 -0
- package/dist/components/kbd.js.map +1 -0
- package/dist/components/marker.d.cts +1 -1
- package/dist/components/marker.d.ts +1 -1
- package/dist/components/message-scroller.cjs +2 -2
- package/dist/components/message-scroller.cjs.map +1 -1
- package/dist/components/message-scroller.js +2 -2
- package/dist/components/message-scroller.js.map +1 -1
- package/dist/components/pill.js +1 -1
- package/dist/components/popover.cjs +3 -2
- package/dist/components/popover.cjs.map +1 -1
- package/dist/components/popover.js +3 -2
- package/dist/components/popover.js.map +1 -1
- package/dist/components/radio.js +1 -1
- package/dist/components/schedule-list.cjs +1 -1
- package/dist/components/schedule-list.cjs.map +1 -1
- package/dist/components/schedule-list.js +1 -1
- package/dist/components/schedule-list.js.map +1 -1
- package/dist/components/select.cjs +4 -3
- package/dist/components/select.cjs.map +1 -1
- package/dist/components/select.js +4 -3
- package/dist/components/select.js.map +1 -1
- package/dist/components/separator.cjs +35 -17
- package/dist/components/separator.cjs.map +1 -1
- package/dist/components/separator.d.cts +1 -0
- package/dist/components/separator.d.ts +1 -0
- package/dist/components/separator.js +35 -17
- package/dist/components/separator.js.map +1 -1
- package/dist/components/sheet.cjs +4 -2
- package/dist/components/sheet.cjs.map +1 -1
- package/dist/components/sheet.d.cts +4 -1
- package/dist/components/sheet.d.ts +4 -1
- package/dist/components/sheet.js +4 -2
- package/dist/components/sheet.js.map +1 -1
- package/dist/components/stat-card.cjs +1 -1
- package/dist/components/stat-card.cjs.map +1 -1
- package/dist/components/stat-card.js +1 -1
- package/dist/components/stat-card.js.map +1 -1
- package/dist/components/switch.js +1 -1
- package/dist/components/textarea.cjs +1 -1
- package/dist/components/textarea.js +1 -1
- package/dist/components/theme.cjs +118 -24
- package/dist/components/theme.cjs.map +1 -1
- package/dist/components/theme.d.cts +7 -1
- package/dist/components/theme.d.ts +7 -1
- package/dist/components/theme.js +120 -27
- package/dist/components/theme.js.map +1 -1
- package/dist/components/toast.cjs +4 -3
- package/dist/components/toast.cjs.map +1 -1
- package/dist/components/toast.js +4 -3
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.js +1 -1
- package/dist/components/toggle.cjs +1 -1
- package/dist/components/toggle.js +2 -2
- package/dist/components/tooltip.cjs +5 -3
- package/dist/components/tooltip.cjs.map +1 -1
- package/dist/components/tooltip.d.cts +1 -0
- package/dist/components/tooltip.d.ts +1 -0
- package/dist/components/tooltip.js +5 -3
- package/dist/components/tooltip.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"separator.js","names":["React"],"sources":["../../src/components/separator.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface SeparatorProps extends React.HTMLAttributes<HTMLDivElement> {\n orientation?: 'horizontal' | 'vertical'\n decorative?: boolean\n}\n\nconst Separator = React.forwardRef<HTMLDivElement, SeparatorProps>(\n (\n {
|
|
1
|
+
{"version":3,"file":"separator.js","names":["React"],"sources":["../../src/components/separator.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface SeparatorProps extends React.HTMLAttributes<HTMLDivElement> {\n orientation?: 'horizontal' | 'vertical'\n decorative?: boolean\n variant?: 'solid' | 'dotted'\n}\n\n// A gradient, not border-dotted: its 1px dots touch and read as a solid line.\n// Forced colors drops background images, so fall back to a dotted border there.\n// a8, not border-gray's a6: sparse dots read lighter than a solid line.\nconst dots =\n 'bg-[radial-gradient(circle_closest-side,var(--neutral-a8)_98%,transparent)] bg-repeat-space forced-colors:bg-none forced-colors:border-dotted'\nconst dottedHorizontal = `h-[2px] bg-size-[6px_2px] forced-colors:border-t ${dots}`\nconst dottedVertical = `w-[2px] bg-size-[2px_6px] forced-colors:border-l ${dots}`\n\nconst plainLine = {\n solid: {\n horizontal: 'border-gray h-px w-full border-t',\n vertical: 'border-gray h-full w-px border-l',\n },\n dotted: {\n horizontal: `w-full ${dottedHorizontal}`,\n vertical: `h-full ${dottedVertical}`,\n },\n}\n\nconst Separator = React.forwardRef<HTMLDivElement, SeparatorProps>(\n (\n {\n className,\n orientation = 'horizontal',\n decorative,\n variant = 'solid',\n children,\n ...props\n },\n ref,\n ) => {\n // A labeled divider (e.g. \"OR\") conveys meaning, so default it to\n // role=\"separator\" unless the caller opts back into decorative.\n const isDecorative = decorative ?? !children\n\n if (children) {\n const labelLine =\n variant === 'dotted'\n ? cn('flex-1', dottedHorizontal)\n : 'h-px flex-1 border-t border-gray'\n return (\n <div\n className={cn('flex items-center gap-4', className)}\n data-orientation={orientation}\n data-variant={variant}\n ref={ref}\n role={isDecorative ? 'none' : 'separator'}\n {...props}\n >\n <div className={labelLine} />\n <span className=\"shrink-0 text-sm text-gray-light\">{children}</span>\n <div className={labelLine} />\n </div>\n )\n }\n\n return (\n <div\n className={cn('shrink-0', plainLine[variant][orientation], className)}\n data-orientation={orientation}\n data-variant={variant}\n ref={ref}\n role={isDecorative ? 'none' : 'separator'}\n {...props}\n />\n )\n },\n)\n\nSeparator.displayName = 'Separator'\n\nexport { Separator }\nexport type { SeparatorProps }\n"],"mappings":";;;;;AAYA,MAAM,OACJ;AACF,MAAM,mBAAmB,oDAAoD;AAC7E,MAAM,iBAAiB,oDAAoD;AAE3E,MAAM,YAAY;CAChB,OAAO;EACL,YAAY;EACZ,UAAU;CACZ;CACA,QAAQ;EACN,YAAY,UAAU;EACtB,UAAU,UAAU;CACtB;AACF;AAEA,MAAM,YAAYA,QAAM,YAEpB,EACE,WACA,cAAc,cACd,YACA,UAAU,SACV,UACA,GAAG,SAEL,QACG;CAGH,MAAM,eAAe,cAAc,CAAC;CAEpC,IAAI,UAAU;EACZ,MAAM,YACJ,YAAY,WACR,GAAG,UAAU,gBAAgB,IAC7B;EACN,OACE,qBAAC,OAAD;GACE,WAAW,GAAG,2BAA2B,SAAS;GAClD,oBAAkB;GAClB,gBAAc;GACT;GACL,MAAM,eAAe,SAAS;GAC9B,GAAI;aANN;IAQE,oBAAC,OAAD,EAAK,WAAW,UAAY,CAAA;IAC5B,oBAAC,QAAD;KAAM,WAAU;KAAoC;IAAe,CAAA;IACnE,oBAAC,OAAD,EAAK,WAAW,UAAY,CAAA;GACzB;;CAET;CAEA,OACE,oBAAC,OAAD;EACE,WAAW,GAAG,YAAY,UAAU,SAAS,cAAc,SAAS;EACpE,oBAAkB;EAClB,gBAAc;EACT;EACL,MAAM,eAAe,SAAS;EAC9B,GAAI;CACL,CAAA;AAEL,CACF;AAEA,UAAU,cAAc"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const require_chunk = require("../chunk-DY84GLCh.cjs");
|
|
4
4
|
const require_components_button = require("./button.cjs");
|
|
5
|
+
const require_components_theme = require("./theme.cjs");
|
|
5
6
|
let react = require("react");
|
|
6
7
|
react = require_chunk.__toESM(react);
|
|
7
8
|
let _epilot_spark_icons = require("@epilot/spark-icons");
|
|
@@ -35,10 +36,11 @@ function SheetClose({ className, children, ...props }) {
|
|
|
35
36
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_epilot_spark_icons.Close, { className: "[--spark-icon-size:calc(20px*var(--spark-scaling,1))]" })
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
|
-
function SheetPortal(props) {
|
|
39
|
+
function SheetPortal({ children, ...props }) {
|
|
39
40
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_dialog.Dialog.Portal, {
|
|
40
41
|
"data-slot": "sheet-portal",
|
|
41
|
-
...props
|
|
42
|
+
...props,
|
|
43
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_theme.PortalTheme, { children })
|
|
42
44
|
});
|
|
43
45
|
}
|
|
44
46
|
function SheetOverlay({ className, ...props }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheet.cjs","names":["SheetPrimitive","buttonVariants","Close"],"sources":["../../src/components/sheet.tsx"],"sourcesContent":["import { Dialog as SheetPrimitive } from '@base-ui/react/dialog'\nimport { Close } from '@epilot/spark-icons'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\nimport { buttonVariants } from './button'\n\nfunction Sheet(props: React.ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root {...props} />\n}\n\nfunction SheetTrigger(\n props: React.ComponentProps<typeof SheetPrimitive.Trigger>,\n) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\n// bare = the ready-made corner X (label is the consumer's, via aria-label);\n// with children or a render prop it stays the bare primitive (footer buttons, labeled closes)\nfunction SheetClose({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n if (children || props.render) {\n return (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className={className}\n {...props}\n >\n {children}\n </SheetPrimitive.Close>\n )\n }\n\n return (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className={cn(\n buttonVariants({ size: 'icon', variant: 'tertiary' }),\n 'absolute top-2.5 right-3 rounded-full',\n className,\n )}\n {...props}\n >\n <Close className=\"[--spark-icon-size:calc(20px*var(--spark-scaling,1))]\" />\n </SheetPrimitive.Close>\n )\n}\n\nfunction SheetPortal(\n props: React.ComponentProps<typeof SheetPrimitive.Portal
|
|
1
|
+
{"version":3,"file":"sheet.cjs","names":["SheetPrimitive","buttonVariants","Close","PortalTheme"],"sources":["../../src/components/sheet.tsx"],"sourcesContent":["import { Dialog as SheetPrimitive } from '@base-ui/react/dialog'\nimport { Close } from '@epilot/spark-icons'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\nimport { buttonVariants } from './button'\nimport { PortalTheme } from './theme'\n\nfunction Sheet(props: React.ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root {...props} />\n}\n\nfunction SheetTrigger(\n props: React.ComponentProps<typeof SheetPrimitive.Trigger>,\n) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\n// bare = the ready-made corner X (label is the consumer's, via aria-label);\n// with children or a render prop it stays the bare primitive (footer buttons, labeled closes)\nfunction SheetClose({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n if (children || props.render) {\n return (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className={className}\n {...props}\n >\n {children}\n </SheetPrimitive.Close>\n )\n }\n\n return (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className={cn(\n buttonVariants({ size: 'icon', variant: 'tertiary' }),\n 'absolute top-2.5 right-3 rounded-full',\n className,\n )}\n {...props}\n >\n <Close className=\"[--spark-icon-size:calc(20px*var(--spark-scaling,1))]\" />\n </SheetPrimitive.Close>\n )\n}\n\nfunction SheetPortal({\n children,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return (\n <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props}>\n <PortalTheme>{children}</PortalTheme>\n </SheetPrimitive.Portal>\n )\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Backdrop>) {\n return (\n <SheetPrimitive.Backdrop\n data-slot=\"sheet-overlay\"\n className={cn(\n 'fixed top-(--spark-viewport-top,0) right-0 left-0 z-50 h-(--spark-viewport-height,100%) bg-(--color-overlay) transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n )\n}\n\ninterface SheetContentProps extends React.ComponentProps<\n typeof SheetPrimitive.Popup\n> {\n side?: 'top' | 'right' | 'bottom' | 'left'\n}\n\nfunction SheetContent({\n side = 'right',\n className,\n ...props\n}: SheetContentProps) {\n return (\n <SheetPrimitive.Popup\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(\n 'fixed z-50 flex flex-col gap-4 border-gray-a1 bg-gray-2 p-safe-offset-4 text-gray shadow-lg transition-[translate] duration-200 ease-in-out data-ending-style:duration-300 motion-reduce:transition-none',\n 'data-[side=top]:inset-x-0 data-[side=top]:top-(--spark-viewport-top,0) data-[side=top]:border-b data-[side=top]:data-ending-style:-translate-y-full data-[side=top]:data-starting-style:-translate-y-full',\n 'data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-(--spark-viewport-bottom-offset,0) data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-full data-[side=bottom]:data-starting-style:translate-y-full',\n 'data-[side=left]:top-(--spark-viewport-top,0) data-[side=left]:left-0 data-[side=left]:h-(--spark-viewport-height,100%) data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:-translate-x-full data-[side=left]:data-starting-style:-translate-x-full data-[side=left]:sm:max-w-sm',\n 'data-[side=right]:top-(--spark-viewport-top,0) data-[side=right]:right-0 data-[side=right]:h-(--spark-viewport-height,100%) data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-full data-[side=right]:data-starting-style:translate-x-full data-[side=right]:sm:max-w-sm',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn('flex flex-col gap-2 text-center sm:text-left', className)}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\n 'mt-auto flex flex-col-reverse gap-2 sm:flex-row sm:justify-end',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn('text-lg font-semibold text-gray', className)}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn('text-sm text-gray-light', className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetOverlay,\n SheetPortal,\n SheetTitle,\n SheetTrigger,\n}\nexport type { SheetContentProps }\n"],"mappings":";;;;;;;;;;;;AAOA,SAAS,MAAM,OAAyD;CACtE,OAAO,iBAAA,GAAA,kBAAA,KAACA,sBAAAA,OAAe,MAAhB,EAAqB,GAAI,MAAQ,CAAA;AAC1C;AAEA,SAAS,aACP,OACA;CACA,OAAO,iBAAA,GAAA,kBAAA,KAACA,sBAAAA,OAAe,SAAhB;EAAwB,aAAU;EAAgB,GAAI;CAAQ,CAAA;AACvE;AAIA,SAAS,WAAW,EAClB,WACA,UACA,GAAG,SACiD;CACpD,IAAI,YAAY,MAAM,QACpB,OACE,iBAAA,GAAA,kBAAA,KAACA,sBAAAA,OAAe,OAAhB;EACE,aAAU;EACC;EACX,GAAI;EAEH;CACmB,CAAA;CAI1B,OACE,iBAAA,GAAA,kBAAA,KAACA,sBAAAA,OAAe,OAAhB;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IACEC,0BAAAA,eAAe;GAAE,MAAM;GAAQ,SAAS;EAAW,CAAC,GACpD,yCACA,SACF;EACA,GAAI;YAEJ,iBAAA,GAAA,kBAAA,KAACC,oBAAAA,OAAD,EAAO,WAAU,wDAAyD,CAAA;CACtD,CAAA;AAE1B;AAEA,SAAS,YAAY,EACnB,UACA,GAAG,SACkD;CACrD,OACE,iBAAA,GAAA,kBAAA,KAACF,sBAAAA,OAAe,QAAhB;EAAuB,aAAU;EAAe,GAAI;YAClD,iBAAA,GAAA,kBAAA,KAACG,yBAAAA,aAAD,EAAc,SAAsB,CAAA;CACf,CAAA;AAE3B;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SACoD;CACvD,OACE,iBAAA,GAAA,kBAAA,KAACH,sBAAAA,OAAe,UAAhB;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IACE,wOACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAQA,SAAS,aAAa,EACpB,OAAO,SACP,WACA,GAAG,SACiB;CACpB,OACE,iBAAA,GAAA,kBAAA,KAACA,sBAAAA,OAAe,OAAhB;EACE,aAAU;EACV,aAAW;EACX,YAAA,GAAA,GAAA,IACE,4MACA,6MACA,uOACA,qTACA,4TACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IAAc,gDAAgD,SAAS;EACvE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IACE,kEACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAClB,WACA,GAAG,SACiD;CACpD,OACE,iBAAA,GAAA,kBAAA,KAACA,sBAAAA,OAAe,OAAhB;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IAAc,mCAAmC,SAAS;EAC1D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EACxB,WACA,GAAG,SACuD;CAC1D,OACE,iBAAA,GAAA,kBAAA,KAACA,sBAAAA,OAAe,aAAhB;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IAAc,2BAA2B,SAAS;EAClD,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -11,7 +11,10 @@ declare function SheetClose({
|
|
|
11
11
|
children,
|
|
12
12
|
...props
|
|
13
13
|
}: React$1.ComponentProps<typeof Dialog.Close>): import("react/jsx-runtime").JSX.Element;
|
|
14
|
-
declare function SheetPortal(
|
|
14
|
+
declare function SheetPortal({
|
|
15
|
+
children,
|
|
16
|
+
...props
|
|
17
|
+
}: React$1.ComponentProps<typeof Dialog.Portal>): import("react/jsx-runtime").JSX.Element;
|
|
15
18
|
declare function SheetOverlay({
|
|
16
19
|
className,
|
|
17
20
|
...props
|
|
@@ -11,7 +11,10 @@ declare function SheetClose({
|
|
|
11
11
|
children,
|
|
12
12
|
...props
|
|
13
13
|
}: React$1.ComponentProps<typeof Dialog.Close>): import("react/jsx-runtime").JSX.Element;
|
|
14
|
-
declare function SheetPortal(
|
|
14
|
+
declare function SheetPortal({
|
|
15
|
+
children,
|
|
16
|
+
...props
|
|
17
|
+
}: React$1.ComponentProps<typeof Dialog.Portal>): import("react/jsx-runtime").JSX.Element;
|
|
15
18
|
declare function SheetOverlay({
|
|
16
19
|
className,
|
|
17
20
|
...props
|
package/dist/components/sheet.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../utils/cn.js";
|
|
3
3
|
import { buttonVariants } from "./button.js";
|
|
4
|
+
import { PortalTheme } from "./theme.js";
|
|
4
5
|
import "react";
|
|
5
6
|
import { Close } from "@epilot/spark-icons";
|
|
6
7
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -32,10 +33,11 @@ function SheetClose({ className, children, ...props }) {
|
|
|
32
33
|
children: /* @__PURE__ */ jsx(Close, { className: "[--spark-icon-size:calc(20px*var(--spark-scaling,1))]" })
|
|
33
34
|
});
|
|
34
35
|
}
|
|
35
|
-
function SheetPortal(props) {
|
|
36
|
+
function SheetPortal({ children, ...props }) {
|
|
36
37
|
return /* @__PURE__ */ jsx(Dialog.Portal, {
|
|
37
38
|
"data-slot": "sheet-portal",
|
|
38
|
-
...props
|
|
39
|
+
...props,
|
|
40
|
+
children: /* @__PURE__ */ jsx(PortalTheme, { children })
|
|
39
41
|
});
|
|
40
42
|
}
|
|
41
43
|
function SheetOverlay({ className, ...props }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheet.js","names":["SheetPrimitive"],"sources":["../../src/components/sheet.tsx"],"sourcesContent":["import { Dialog as SheetPrimitive } from '@base-ui/react/dialog'\nimport { Close } from '@epilot/spark-icons'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\nimport { buttonVariants } from './button'\n\nfunction Sheet(props: React.ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root {...props} />\n}\n\nfunction SheetTrigger(\n props: React.ComponentProps<typeof SheetPrimitive.Trigger>,\n) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\n// bare = the ready-made corner X (label is the consumer's, via aria-label);\n// with children or a render prop it stays the bare primitive (footer buttons, labeled closes)\nfunction SheetClose({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n if (children || props.render) {\n return (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className={className}\n {...props}\n >\n {children}\n </SheetPrimitive.Close>\n )\n }\n\n return (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className={cn(\n buttonVariants({ size: 'icon', variant: 'tertiary' }),\n 'absolute top-2.5 right-3 rounded-full',\n className,\n )}\n {...props}\n >\n <Close className=\"[--spark-icon-size:calc(20px*var(--spark-scaling,1))]\" />\n </SheetPrimitive.Close>\n )\n}\n\nfunction SheetPortal(\n props: React.ComponentProps<typeof SheetPrimitive.Portal
|
|
1
|
+
{"version":3,"file":"sheet.js","names":["SheetPrimitive"],"sources":["../../src/components/sheet.tsx"],"sourcesContent":["import { Dialog as SheetPrimitive } from '@base-ui/react/dialog'\nimport { Close } from '@epilot/spark-icons'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\nimport { buttonVariants } from './button'\nimport { PortalTheme } from './theme'\n\nfunction Sheet(props: React.ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root {...props} />\n}\n\nfunction SheetTrigger(\n props: React.ComponentProps<typeof SheetPrimitive.Trigger>,\n) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\n// bare = the ready-made corner X (label is the consumer's, via aria-label);\n// with children or a render prop it stays the bare primitive (footer buttons, labeled closes)\nfunction SheetClose({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n if (children || props.render) {\n return (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className={className}\n {...props}\n >\n {children}\n </SheetPrimitive.Close>\n )\n }\n\n return (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className={cn(\n buttonVariants({ size: 'icon', variant: 'tertiary' }),\n 'absolute top-2.5 right-3 rounded-full',\n className,\n )}\n {...props}\n >\n <Close className=\"[--spark-icon-size:calc(20px*var(--spark-scaling,1))]\" />\n </SheetPrimitive.Close>\n )\n}\n\nfunction SheetPortal({\n children,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return (\n <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props}>\n <PortalTheme>{children}</PortalTheme>\n </SheetPrimitive.Portal>\n )\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Backdrop>) {\n return (\n <SheetPrimitive.Backdrop\n data-slot=\"sheet-overlay\"\n className={cn(\n 'fixed top-(--spark-viewport-top,0) right-0 left-0 z-50 h-(--spark-viewport-height,100%) bg-(--color-overlay) transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n )\n}\n\ninterface SheetContentProps extends React.ComponentProps<\n typeof SheetPrimitive.Popup\n> {\n side?: 'top' | 'right' | 'bottom' | 'left'\n}\n\nfunction SheetContent({\n side = 'right',\n className,\n ...props\n}: SheetContentProps) {\n return (\n <SheetPrimitive.Popup\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(\n 'fixed z-50 flex flex-col gap-4 border-gray-a1 bg-gray-2 p-safe-offset-4 text-gray shadow-lg transition-[translate] duration-200 ease-in-out data-ending-style:duration-300 motion-reduce:transition-none',\n 'data-[side=top]:inset-x-0 data-[side=top]:top-(--spark-viewport-top,0) data-[side=top]:border-b data-[side=top]:data-ending-style:-translate-y-full data-[side=top]:data-starting-style:-translate-y-full',\n 'data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-(--spark-viewport-bottom-offset,0) data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-full data-[side=bottom]:data-starting-style:translate-y-full',\n 'data-[side=left]:top-(--spark-viewport-top,0) data-[side=left]:left-0 data-[side=left]:h-(--spark-viewport-height,100%) data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:-translate-x-full data-[side=left]:data-starting-style:-translate-x-full data-[side=left]:sm:max-w-sm',\n 'data-[side=right]:top-(--spark-viewport-top,0) data-[side=right]:right-0 data-[side=right]:h-(--spark-viewport-height,100%) data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-full data-[side=right]:data-starting-style:translate-x-full data-[side=right]:sm:max-w-sm',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn('flex flex-col gap-2 text-center sm:text-left', className)}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\n 'mt-auto flex flex-col-reverse gap-2 sm:flex-row sm:justify-end',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn('text-lg font-semibold text-gray', className)}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn('text-sm text-gray-light', className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetOverlay,\n SheetPortal,\n SheetTitle,\n SheetTrigger,\n}\nexport type { SheetContentProps }\n"],"mappings":";;;;;;;;;AAOA,SAAS,MAAM,OAAyD;CACtE,OAAO,oBAACA,OAAe,MAAhB,EAAqB,GAAI,MAAQ,CAAA;AAC1C;AAEA,SAAS,aACP,OACA;CACA,OAAO,oBAACA,OAAe,SAAhB;EAAwB,aAAU;EAAgB,GAAI;CAAQ,CAAA;AACvE;AAIA,SAAS,WAAW,EAClB,WACA,UACA,GAAG,SACiD;CACpD,IAAI,YAAY,MAAM,QACpB,OACE,oBAACA,OAAe,OAAhB;EACE,aAAU;EACC;EACX,GAAI;EAEH;CACmB,CAAA;CAI1B,OACE,oBAACA,OAAe,OAAhB;EACE,aAAU;EACV,WAAW,GACT,eAAe;GAAE,MAAM;GAAQ,SAAS;EAAW,CAAC,GACpD,yCACA,SACF;EACA,GAAI;YAEJ,oBAAC,OAAD,EAAO,WAAU,wDAAyD,CAAA;CACtD,CAAA;AAE1B;AAEA,SAAS,YAAY,EACnB,UACA,GAAG,SACkD;CACrD,OACE,oBAACA,OAAe,QAAhB;EAAuB,aAAU;EAAe,GAAI;YAClD,oBAAC,aAAD,EAAc,SAAsB,CAAA;CACf,CAAA;AAE3B;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SACoD;CACvD,OACE,oBAACA,OAAe,UAAhB;EACE,aAAU;EACV,WAAW,GACT,wOACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAQA,SAAS,aAAa,EACpB,OAAO,SACP,WACA,GAAG,SACiB;CACpB,OACE,oBAACA,OAAe,OAAhB;EACE,aAAU;EACV,aAAW;EACX,WAAW,GACT,4MACA,6MACA,uOACA,qTACA,4TACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,gDAAgD,SAAS;EACvE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,kEACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAClB,WACA,GAAG,SACiD;CACpD,OACE,oBAACA,OAAe,OAAhB;EACE,aAAU;EACV,WAAW,GAAG,mCAAmC,SAAS;EAC1D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EACxB,WACA,GAAG,SACuD;CAC1D,OACE,oBAACA,OAAe,aAAhB;EACE,aAAU;EACV,WAAW,GAAG,2BAA2B,SAAS;EAClD,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -23,7 +23,7 @@ const StatCardContent = ({ className, ...rest }) => {
|
|
|
23
23
|
};
|
|
24
24
|
const StatCardValueContainer = ({ className, ...rest }) => {
|
|
25
25
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
26
|
-
className: (0, cn.cn)("flex flex-col gap-
|
|
26
|
+
className: (0, cn.cn)("flex flex-col gap-1", className),
|
|
27
27
|
...rest
|
|
28
28
|
});
|
|
29
29
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stat-card.cjs","names":[],"sources":["../../src/components/stat-card.tsx"],"sourcesContent":["import { cn } from '../utils/cn'\n\nconst StatCardContainer = ({\n className,\n ...rest\n}: React.ComponentProps<'div'>) => {\n return (\n <div\n className={cn('flex w-full flex-col gap-3 p-4 text-left', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardLabel = ({\n className,\n ...rest\n}: React.ComponentProps<'span'>) => {\n return (\n <span\n className={cn('text-xs font-medium text-gray-light', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardContent = ({\n className,\n ...rest\n}: React.ComponentProps<'div'>) => {\n return (\n <div\n className={cn('flex items-end justify-between gap-px', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardValueContainer = ({\n className,\n ...rest\n}: React.ComponentProps<'div'>) => {\n return <div className={cn('flex flex-col gap-
|
|
1
|
+
{"version":3,"file":"stat-card.cjs","names":[],"sources":["../../src/components/stat-card.tsx"],"sourcesContent":["import { cn } from '../utils/cn'\n\nconst StatCardContainer = ({\n className,\n ...rest\n}: React.ComponentProps<'div'>) => {\n return (\n <div\n className={cn('flex w-full flex-col gap-3 p-4 text-left', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardLabel = ({\n className,\n ...rest\n}: React.ComponentProps<'span'>) => {\n return (\n <span\n className={cn('text-xs font-medium text-gray-light', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardContent = ({\n className,\n ...rest\n}: React.ComponentProps<'div'>) => {\n return (\n <div\n className={cn('flex items-end justify-between gap-px', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardValueContainer = ({\n className,\n ...rest\n}: React.ComponentProps<'div'>) => {\n return <div className={cn('flex flex-col gap-1', className)} {...rest} />\n}\n\nconst StatCardValue = ({\n className,\n ...rest\n}: React.ComponentProps<'span'>) => {\n return (\n <span\n className={cn('text-lg font-bold text-gray tabular-nums', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardSecondaryValue = ({\n className,\n ...rest\n}: React.ComponentProps<'span'>) => {\n return <span className={cn('text-xs text-gray-light', className)} {...rest} />\n}\n\nconst StatCardIcon = ({ className, ...rest }: React.ComponentProps<'div'>) => {\n return (\n <div\n className={cn(\n // max() pill escape (matches Icon): a tile stays rounded-md at low Roundness but\n // becomes a circle at large/full, same as it did pre-harmonization via clamping.\n 'flex size-10 shrink-0 items-center justify-center rounded-[max(var(--spark-rounded-md),var(--spark-rounded-full))]',\n className,\n )}\n {...rest}\n />\n )\n}\n\nexport {\n StatCardContainer,\n StatCardLabel,\n StatCardContent,\n StatCardValueContainer,\n StatCardValue,\n StatCardSecondaryValue,\n StatCardIcon,\n}\n"],"mappings":";;;;;AAEA,MAAM,qBAAqB,EACzB,WACA,GAAG,WAC8B;CACjC,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,YAAA,GAAA,GAAA,IAAc,4CAA4C,SAAS;EACnE,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,iBAAiB,EACrB,WACA,GAAG,WAC+B;CAClC,OACE,iBAAA,GAAA,kBAAA,KAAC,QAAD;EACE,YAAA,GAAA,GAAA,IAAc,uCAAuC,SAAS;EAC9D,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,mBAAmB,EACvB,WACA,GAAG,WAC8B;CACjC,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,YAAA,GAAA,GAAA,IAAc,yCAAyC,SAAS;EAChE,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,0BAA0B,EAC9B,WACA,GAAG,WAC8B;CACjC,OAAO,iBAAA,GAAA,kBAAA,KAAC,OAAD;EAAK,YAAA,GAAA,GAAA,IAAc,uBAAuB,SAAS;EAAG,GAAI;CAAO,CAAA;AAC1E;AAEA,MAAM,iBAAiB,EACrB,WACA,GAAG,WAC+B;CAClC,OACE,iBAAA,GAAA,kBAAA,KAAC,QAAD;EACE,YAAA,GAAA,GAAA,IAAc,4CAA4C,SAAS;EACnE,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,0BAA0B,EAC9B,WACA,GAAG,WAC+B;CAClC,OAAO,iBAAA,GAAA,kBAAA,KAAC,QAAD;EAAM,YAAA,GAAA,GAAA,IAAc,2BAA2B,SAAS;EAAG,GAAI;CAAO,CAAA;AAC/E;AAEA,MAAM,gBAAgB,EAAE,WAAW,GAAG,WAAwC;CAC5E,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,YAAA,GAAA,GAAA,IAGE,sHACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -22,7 +22,7 @@ const StatCardContent = ({ className, ...rest }) => {
|
|
|
22
22
|
};
|
|
23
23
|
const StatCardValueContainer = ({ className, ...rest }) => {
|
|
24
24
|
return /* @__PURE__ */ jsx("div", {
|
|
25
|
-
className: cn("flex flex-col gap-
|
|
25
|
+
className: cn("flex flex-col gap-1", className),
|
|
26
26
|
...rest
|
|
27
27
|
});
|
|
28
28
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stat-card.js","names":[],"sources":["../../src/components/stat-card.tsx"],"sourcesContent":["import { cn } from '../utils/cn'\n\nconst StatCardContainer = ({\n className,\n ...rest\n}: React.ComponentProps<'div'>) => {\n return (\n <div\n className={cn('flex w-full flex-col gap-3 p-4 text-left', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardLabel = ({\n className,\n ...rest\n}: React.ComponentProps<'span'>) => {\n return (\n <span\n className={cn('text-xs font-medium text-gray-light', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardContent = ({\n className,\n ...rest\n}: React.ComponentProps<'div'>) => {\n return (\n <div\n className={cn('flex items-end justify-between gap-px', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardValueContainer = ({\n className,\n ...rest\n}: React.ComponentProps<'div'>) => {\n return <div className={cn('flex flex-col gap-
|
|
1
|
+
{"version":3,"file":"stat-card.js","names":[],"sources":["../../src/components/stat-card.tsx"],"sourcesContent":["import { cn } from '../utils/cn'\n\nconst StatCardContainer = ({\n className,\n ...rest\n}: React.ComponentProps<'div'>) => {\n return (\n <div\n className={cn('flex w-full flex-col gap-3 p-4 text-left', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardLabel = ({\n className,\n ...rest\n}: React.ComponentProps<'span'>) => {\n return (\n <span\n className={cn('text-xs font-medium text-gray-light', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardContent = ({\n className,\n ...rest\n}: React.ComponentProps<'div'>) => {\n return (\n <div\n className={cn('flex items-end justify-between gap-px', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardValueContainer = ({\n className,\n ...rest\n}: React.ComponentProps<'div'>) => {\n return <div className={cn('flex flex-col gap-1', className)} {...rest} />\n}\n\nconst StatCardValue = ({\n className,\n ...rest\n}: React.ComponentProps<'span'>) => {\n return (\n <span\n className={cn('text-lg font-bold text-gray tabular-nums', className)}\n {...rest}\n />\n )\n}\n\nconst StatCardSecondaryValue = ({\n className,\n ...rest\n}: React.ComponentProps<'span'>) => {\n return <span className={cn('text-xs text-gray-light', className)} {...rest} />\n}\n\nconst StatCardIcon = ({ className, ...rest }: React.ComponentProps<'div'>) => {\n return (\n <div\n className={cn(\n // max() pill escape (matches Icon): a tile stays rounded-md at low Roundness but\n // becomes a circle at large/full, same as it did pre-harmonization via clamping.\n 'flex size-10 shrink-0 items-center justify-center rounded-[max(var(--spark-rounded-md),var(--spark-rounded-full))]',\n className,\n )}\n {...rest}\n />\n )\n}\n\nexport {\n StatCardContainer,\n StatCardLabel,\n StatCardContent,\n StatCardValueContainer,\n StatCardValue,\n StatCardSecondaryValue,\n StatCardIcon,\n}\n"],"mappings":";;;;AAEA,MAAM,qBAAqB,EACzB,WACA,GAAG,WAC8B;CACjC,OACE,oBAAC,OAAD;EACE,WAAW,GAAG,4CAA4C,SAAS;EACnE,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,iBAAiB,EACrB,WACA,GAAG,WAC+B;CAClC,OACE,oBAAC,QAAD;EACE,WAAW,GAAG,uCAAuC,SAAS;EAC9D,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,mBAAmB,EACvB,WACA,GAAG,WAC8B;CACjC,OACE,oBAAC,OAAD;EACE,WAAW,GAAG,yCAAyC,SAAS;EAChE,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,0BAA0B,EAC9B,WACA,GAAG,WAC8B;CACjC,OAAO,oBAAC,OAAD;EAAK,WAAW,GAAG,uBAAuB,SAAS;EAAG,GAAI;CAAO,CAAA;AAC1E;AAEA,MAAM,iBAAiB,EACrB,WACA,GAAG,WAC+B;CAClC,OACE,oBAAC,QAAD;EACE,WAAW,GAAG,4CAA4C,SAAS;EACnE,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,0BAA0B,EAC9B,WACA,GAAG,WAC+B;CAClC,OAAO,oBAAC,QAAD;EAAM,WAAW,GAAG,2BAA2B,SAAS;EAAG,GAAI;CAAO,CAAA;AAC/E;AAEA,MAAM,gBAAgB,EAAE,WAAW,GAAG,WAAwC;CAC5E,OACE,oBAAC,OAAD;EACE,WAAW,GAGT,sHACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { accentByColor } from "../lib/accent-colors.js";
|
|
3
2
|
import { cn } from "../utils/cn.js";
|
|
3
|
+
import { accentByColor } from "../lib/accent-colors.js";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
import { Switch as Switch$1 } from "@base-ui/react/switch";
|
|
6
6
|
//#region src/components/switch.tsx
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const require_chunk = require("../chunk-DY84GLCh.cjs");
|
|
4
|
-
const require_lib_input_box_variants = require("../lib/input-box-variants.cjs");
|
|
5
4
|
const require_components_field = require("./field.cjs");
|
|
5
|
+
const require_lib_input_box_variants = require("../lib/input-box-variants.cjs");
|
|
6
6
|
let react = require("react");
|
|
7
7
|
react = require_chunk.__toESM(react);
|
|
8
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../utils/cn.js";
|
|
3
|
-
import { GHOST_UNDERLINE, boxChrome } from "../lib/input-box-variants.js";
|
|
4
3
|
import { useFieldControl } from "./field.js";
|
|
4
|
+
import { GHOST_UNDERLINE, boxChrome } from "../lib/input-box-variants.js";
|
|
5
5
|
import * as React$1 from "react";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
import { cva } from "class-variance-authority";
|
|
@@ -14,6 +14,7 @@ let cn = require("cn");
|
|
|
14
14
|
/** The epilot brand accent — the scale `spark-default.css` ships statically. */
|
|
15
15
|
const DEFAULT_ACCENT = "#005EB4";
|
|
16
16
|
const ThemeContext = react.createContext({});
|
|
17
|
+
const ThemeOutputContext = react.createContext(null);
|
|
17
18
|
/** Merged theme values from enclosing `<Theme>` providers. */
|
|
18
19
|
function useTheme() {
|
|
19
20
|
return react.useContext(ThemeContext);
|
|
@@ -21,6 +22,7 @@ function useTheme() {
|
|
|
21
22
|
/** Optional sugar: writes the theming `data-*` attrs + accent `--spark-*` vars onto a wrapper. */
|
|
22
23
|
const Theme = react.forwardRef(function Theme({ accentColor, backgroundColor, neutralColor, radius, scaling, spacing, styleVariant, highContrast, inverted, labelPosition, inputStyle, inputColor, cardVariant, cardColor, appearance, fontHeading, fontBody, render, className, style, children, ...rest }, ref) {
|
|
23
24
|
const parent = useTheme();
|
|
25
|
+
const parentOutput = react.useContext(ThemeOutputContext);
|
|
24
26
|
const value = react.useMemo(() => ({
|
|
25
27
|
accentColor: accentColor ?? parent.accentColor,
|
|
26
28
|
backgroundColor: backgroundColor ?? parent.backgroundColor,
|
|
@@ -68,6 +70,8 @@ const Theme = react.forwardRef(function Theme({ accentColor, backgroundColor, ne
|
|
|
68
70
|
const accent = react.useMemo(() => {
|
|
69
71
|
const empty = {
|
|
70
72
|
inlineVars: {},
|
|
73
|
+
portalVars: {},
|
|
74
|
+
portalScope: void 0,
|
|
71
75
|
css: "",
|
|
72
76
|
scoped: false
|
|
73
77
|
};
|
|
@@ -89,21 +93,44 @@ const Theme = react.forwardRef(function Theme({ accentColor, backgroundColor, ne
|
|
|
89
93
|
const build = (appearance) => {
|
|
90
94
|
const opts = optsFor(appearance);
|
|
91
95
|
const scale = require_lib_accent_theme.generateAccentScale(hex, appearance, opts);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
scoped: false
|
|
96
|
+
const rendered = emit(inverted ? require_lib_accent_theme.invertAccentScale(scale) : scale, opts != null);
|
|
97
|
+
return {
|
|
98
|
+
rendered,
|
|
99
|
+
plain: inverted ? emit(scale, opts != null) : rendered
|
|
100
|
+
};
|
|
98
101
|
};
|
|
102
|
+
if (value.appearance) {
|
|
103
|
+
const { rendered, plain } = build(value.appearance);
|
|
104
|
+
const inlineVars = toVars(rendered);
|
|
105
|
+
return {
|
|
106
|
+
inlineVars,
|
|
107
|
+
portalVars: inverted ? toVars(plain) : inlineVars,
|
|
108
|
+
portalScope: void 0,
|
|
109
|
+
css: "",
|
|
110
|
+
scoped: false
|
|
111
|
+
};
|
|
112
|
+
}
|
|
99
113
|
const offCanvasNeutrals = backgroundColor ? require_lib_accent_theme.neutralFamilyVars(resolvedNeutralColor ?? "slate") : [];
|
|
100
|
-
const scaleFor = (appearance) =>
|
|
114
|
+
const scaleFor = (appearance) => {
|
|
115
|
+
const { rendered, plain } = build(appearance);
|
|
116
|
+
const extra = bgAppearance === appearance ? [] : offCanvasNeutrals;
|
|
117
|
+
return {
|
|
118
|
+
rendered: [...rendered, ...extra],
|
|
119
|
+
plain: [...plain, ...extra]
|
|
120
|
+
};
|
|
121
|
+
};
|
|
101
122
|
const light = scaleFor("light");
|
|
102
123
|
const dark = scaleFor("dark");
|
|
103
|
-
const
|
|
124
|
+
const rule = (id, lightDecls, darkDecls) => {
|
|
125
|
+
const sel = `[data-spark-scope~="${id}"]`;
|
|
126
|
+
return `${sel}{${lightDecls.join("")}}:is(.dark,.dark-theme) ${sel}{${darkDecls.join("")}}`;
|
|
127
|
+
};
|
|
128
|
+
const portalScope = inverted ? `${scopeId}p` : scopeId;
|
|
104
129
|
return {
|
|
105
130
|
inlineVars: {},
|
|
106
|
-
|
|
131
|
+
portalVars: {},
|
|
132
|
+
portalScope,
|
|
133
|
+
css: rule(scopeId, light.rendered, dark.rendered) + (inverted ? rule(portalScope, light.plain, dark.plain) : ""),
|
|
107
134
|
scoped: true
|
|
108
135
|
};
|
|
109
136
|
} catch (error) {
|
|
@@ -119,41 +146,108 @@ const Theme = react.forwardRef(function Theme({ accentColor, backgroundColor, ne
|
|
|
119
146
|
value.appearance,
|
|
120
147
|
scopeId
|
|
121
148
|
]);
|
|
149
|
+
const attrs = react.useMemo(() => ({
|
|
150
|
+
"data-neutral-color": neutralColorAttr,
|
|
151
|
+
"data-radius": radius,
|
|
152
|
+
"data-scaling": scaling,
|
|
153
|
+
"data-spacing": spacing,
|
|
154
|
+
"data-style": styleVariant,
|
|
155
|
+
"data-high-contrast": highContrast ? "" : void 0,
|
|
156
|
+
"data-label-position": labelPosition,
|
|
157
|
+
"data-input-style": inputStyle,
|
|
158
|
+
"data-input-color": inputColor,
|
|
159
|
+
"data-card-variant": cardVariant,
|
|
160
|
+
"data-card-color": cardColor === "accent" ? "accent" : void 0
|
|
161
|
+
}), [
|
|
162
|
+
neutralColorAttr,
|
|
163
|
+
radius,
|
|
164
|
+
scaling,
|
|
165
|
+
spacing,
|
|
166
|
+
styleVariant,
|
|
167
|
+
highContrast,
|
|
168
|
+
labelPosition,
|
|
169
|
+
inputStyle,
|
|
170
|
+
inputColor,
|
|
171
|
+
cardVariant,
|
|
172
|
+
cardColor
|
|
173
|
+
]);
|
|
174
|
+
const fontVars = react.useMemo(() => ({
|
|
175
|
+
...fontHeading ? { "--spark-font-heading": fontHeading } : null,
|
|
176
|
+
...fontBody ? { "--spark-font-body": fontBody } : null
|
|
177
|
+
}), [fontHeading, fontBody]);
|
|
122
178
|
const element = (0, _base_ui_react_use_render.useRender)({
|
|
123
179
|
defaultTagName: "div",
|
|
124
180
|
render,
|
|
125
181
|
ref,
|
|
126
182
|
props: (0, _base_ui_react_merge_props.mergeProps)({
|
|
127
183
|
className: (0, cn.cn)("spark-theme", appearance, className),
|
|
128
|
-
|
|
129
|
-
"data-radius": radius,
|
|
130
|
-
"data-scaling": scaling,
|
|
131
|
-
"data-spacing": spacing,
|
|
132
|
-
"data-style": styleVariant,
|
|
133
|
-
"data-high-contrast": highContrast ? "" : void 0,
|
|
184
|
+
...attrs,
|
|
134
185
|
"data-inverted": inverted ? "" : void 0,
|
|
135
|
-
"data-label-position": labelPosition,
|
|
136
|
-
"data-input-style": inputStyle,
|
|
137
|
-
"data-input-color": inputColor,
|
|
138
|
-
"data-card-variant": cardVariant,
|
|
139
|
-
"data-card-color": cardColor === "accent" ? "accent" : void 0,
|
|
140
186
|
"data-spark-scope": accent.scoped ? scopeId : void 0,
|
|
141
187
|
style: {
|
|
142
188
|
...accent.inlineVars,
|
|
143
189
|
...backgroundColor ? { backgroundColor: "var(--spark-background)" } : null,
|
|
144
|
-
...
|
|
145
|
-
...fontBody ? { "--spark-font-body": fontBody } : null,
|
|
190
|
+
...fontVars,
|
|
146
191
|
...style
|
|
147
192
|
},
|
|
148
193
|
children
|
|
149
194
|
}, rest)
|
|
150
195
|
});
|
|
151
|
-
|
|
196
|
+
const output = react.useMemo(() => {
|
|
197
|
+
const own = Object.fromEntries(Object.entries(attrs).filter((entry) => entry[1] !== void 0));
|
|
198
|
+
const parentScopes = parentOutput?.scopes ?? [];
|
|
199
|
+
return {
|
|
200
|
+
attrs: {
|
|
201
|
+
...parentOutput?.attrs,
|
|
202
|
+
...own
|
|
203
|
+
},
|
|
204
|
+
vars: {
|
|
205
|
+
...parentOutput?.vars,
|
|
206
|
+
...accent.portalVars,
|
|
207
|
+
...fontVars
|
|
208
|
+
},
|
|
209
|
+
scopes: accent.portalScope ? [...parentScopes, accent.portalScope] : parentScopes
|
|
210
|
+
};
|
|
211
|
+
}, [
|
|
212
|
+
parentOutput,
|
|
213
|
+
attrs,
|
|
214
|
+
accent,
|
|
215
|
+
fontVars
|
|
216
|
+
]);
|
|
217
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeContext.Provider, {
|
|
152
218
|
value,
|
|
153
|
-
children:
|
|
219
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ThemeOutputContext.Provider, {
|
|
220
|
+
value: output,
|
|
221
|
+
children: [accent.css ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: accent.css }) : null, element]
|
|
222
|
+
})
|
|
154
223
|
});
|
|
155
224
|
});
|
|
225
|
+
/** Re-emits what the enclosing Themes rendered inside a portal, where CSS inheritance from them stops. */
|
|
226
|
+
function PortalTheme({ children }) {
|
|
227
|
+
const output = react.useContext(ThemeOutputContext);
|
|
228
|
+
const theme = useTheme();
|
|
229
|
+
const value = react.useMemo(() => ({
|
|
230
|
+
...theme,
|
|
231
|
+
inverted: false
|
|
232
|
+
}), [theme]);
|
|
233
|
+
if (!output) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
|
|
234
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeContext.Provider, {
|
|
235
|
+
value,
|
|
236
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
237
|
+
"data-slot": "portal-theme",
|
|
238
|
+
className: (0, cn.cn)("spark-theme", theme.appearance),
|
|
239
|
+
...output.attrs,
|
|
240
|
+
"data-spark-scope": output.scopes.length ? output.scopes.join(" ") : void 0,
|
|
241
|
+
style: {
|
|
242
|
+
display: "contents",
|
|
243
|
+
...output.vars
|
|
244
|
+
},
|
|
245
|
+
children
|
|
246
|
+
})
|
|
247
|
+
});
|
|
248
|
+
}
|
|
156
249
|
//#endregion
|
|
250
|
+
exports.PortalTheme = PortalTheme;
|
|
157
251
|
exports.Theme = Theme;
|
|
158
252
|
exports.useTheme = useTheme;
|
|
159
253
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.cjs","names":["React","resolveAutoNeutral","isSparkNeutralFamily","isParsableColor","getMatchingNeutral","CURATED_ACCENTS","appearanceForBackground","accentSparkVars","neutralSparkVars","generateAccentScale","invertAccentScale","neutralFamilyVars"],"sources":["../../src/components/theme.tsx"],"sourcesContent":["'use client'\n\nimport { mergeProps } from '@base-ui/react/merge-props'\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport {\n CURATED_ACCENTS,\n accentSparkVars,\n appearanceForBackground,\n generateAccentScale,\n getMatchingNeutral,\n invertAccentScale,\n isParsableColor,\n neutralFamilyVars,\n neutralSparkVars,\n resolveAutoNeutral,\n type Appearance,\n type SparkAccentScale,\n} from '../lib/accent-theme'\nimport {\n isSparkNeutralFamily,\n type SparkCardColor,\n type SparkCardVariant,\n type SparkInputColor,\n type SparkInputStyle,\n type SparkLabelPosition,\n type SparkNeutral,\n type SparkRadius,\n type SparkScaling,\n type SparkSpacing,\n type SparkStyle,\n} from '../lib/theme-types'\nimport { cn } from '../utils/cn'\n\nexport type {\n SparkCardColor,\n SparkCardVariant,\n SparkInputColor,\n SparkInputStyle,\n SparkLabelPosition,\n SparkNeutral,\n SparkNeutralFamily,\n SparkRadius,\n SparkScaling,\n SparkSpacing,\n SparkStyle,\n} from '../lib/theme-types'\n\n/** The epilot brand accent — the scale `spark-default.css` ships statically. */\nconst DEFAULT_ACCENT = '#005EB4'\n\nexport interface ThemeValue {\n /** Curated accent name or a custom hex. */\n accentColor?: string\n /**\n * Page canvas as a custom hex. Regenerates BOTH the accent and neutral scales against\n * it (each alpha step is composited against the canvas, so a saturated colour needs\n * the neutral ramp regenerated too, not just the accent). Unset → the fixed\n * `#ffffff` / `#000000` default, and neutrals stay on the static Radix families.\n */\n backgroundColor?: string\n /**\n * A curated family name, an arbitrary color to seed the neutral scale, or `'auto'` to\n * resolve one — preferring `backgroundColor`'s own hue when it's perceptibly tinted,\n * else pairing with the accent (Radix's `grayColor=\"auto\"`). A custom seed (from `auto`\n * or set directly) only regenerates the scale alongside a `backgroundColor`; without\n * one, `data-neutral-color` falls back to the accent-matched family and that's what\n * actually paints.\n */\n neutralColor?: SparkNeutral\n radius?: SparkRadius\n scaling?: SparkScaling\n spacing?: SparkSpacing\n styleVariant?: SparkStyle\n /** Orthogonal to `styleVariant`: shifts any style toward higher-contrast steps. */\n highContrast?: boolean\n /**\n * Orthogonal to `styleVariant`: re-casts the accent scale for use ON its own solid fill,\n * for controls sitting on a solid accent surface (a `<Card variant=\"solid\" color=\"accent\">`),\n * where a solid control would otherwise paint the same `--spark-9` as the card and vanish.\n * Swaps step 9 with its contrast ink, so the fill/ink pair stays WCAG-safe for any accent.\n */\n inverted?: boolean\n labelPosition?: SparkLabelPosition\n inputStyle?: SparkInputStyle\n inputColor?: SparkInputColor\n /** App-level default `<Card>` chrome; a per-card `variant` prop overrides it. */\n cardVariant?: SparkCardVariant\n /** App-level default `<Card>` palette; a per-card `color` prop overrides it. */\n cardColor?: SparkCardColor\n appearance?: Appearance\n /** Font stack for `h1`–`h6`. Any valid CSS `font-family` value. */\n fontHeading?: string\n /** Font stack for everything else. Any valid CSS `font-family` value. */\n fontBody?: string\n}\n\nconst ThemeContext = React.createContext<ThemeValue>({})\n\n/** Merged theme values from enclosing `<Theme>` providers. */\nexport function useTheme(): ThemeValue {\n return React.useContext(ThemeContext)\n}\n\nexport interface ThemeProps\n extends useRender.ComponentProps<'div'>, ThemeValue {}\n\n/** Optional sugar: writes the theming `data-*` attrs + accent `--spark-*` vars onto a wrapper. */\nexport const Theme = React.forwardRef<HTMLDivElement, ThemeProps>(\n function Theme(\n {\n accentColor,\n backgroundColor,\n neutralColor,\n radius,\n scaling,\n spacing,\n styleVariant,\n highContrast,\n inverted,\n labelPosition,\n inputStyle,\n inputColor,\n cardVariant,\n cardColor,\n appearance,\n fontHeading,\n fontBody,\n render,\n className,\n style,\n children,\n ...rest\n },\n ref,\n ) {\n const parent = useTheme()\n\n const value = React.useMemo<ThemeValue>(\n () => ({\n accentColor: accentColor ?? parent.accentColor,\n backgroundColor: backgroundColor ?? parent.backgroundColor,\n neutralColor: neutralColor ?? parent.neutralColor,\n radius: radius ?? parent.radius,\n scaling: scaling ?? parent.scaling,\n spacing: spacing ?? parent.spacing,\n styleVariant: styleVariant ?? parent.styleVariant,\n highContrast: highContrast ?? parent.highContrast,\n inverted: inverted ?? parent.inverted,\n labelPosition: labelPosition ?? parent.labelPosition,\n inputStyle: inputStyle ?? parent.inputStyle,\n inputColor: inputColor ?? parent.inputColor,\n cardVariant: cardVariant ?? parent.cardVariant,\n cardColor: cardColor ?? parent.cardColor,\n appearance: appearance ?? parent.appearance,\n fontHeading: fontHeading ?? parent.fontHeading,\n fontBody: fontBody ?? parent.fontBody,\n }),\n [\n accentColor,\n backgroundColor,\n neutralColor,\n radius,\n scaling,\n spacing,\n styleVariant,\n highContrast,\n inverted,\n labelPosition,\n inputStyle,\n inputColor,\n cardVariant,\n cardColor,\n appearance,\n fontHeading,\n fontBody,\n parent,\n ],\n )\n\n // Scope id for the ambient-appearance case (both scales emitted in a <style>).\n const scopeId = React.useId()\n\n // 'auto' pairs a neutral with the canvas's own tint when it has one, else the\n // effective accent (Radix's grayColor=\"auto\") — see resolveAutoNeutral. Reads the\n // OWN backgroundColor, not the merged value.backgroundColor: optsFor (below) only\n // ever regenerates against a scope's own canvas too, so preferring an inherited one\n // here would resolve a seed that then gets silently discarded.\n const rawNeutralColor =\n neutralColor === 'auto'\n ? resolveAutoNeutral(\n value.accentColor ?? DEFAULT_ACCENT,\n backgroundColor,\n )\n : neutralColor\n\n // A custom neutral that isn't a recognized family must be a real, parseable color —\n // reject invalid input here (e.g. a typo'd family name like \"slat\") so it can't throw\n // deep inside the shared generator, where the catch below would otherwise blame\n // accentColor/backgroundColor without ever naming neutralColor as the actual cause.\n const neutralColorIsValid =\n rawNeutralColor === undefined ||\n isSparkNeutralFamily(rawNeutralColor) ||\n isParsableColor(rawNeutralColor)\n if (!neutralColorIsValid) {\n console.warn(\n `[Theme] Ignoring invalid neutralColor \"${rawNeutralColor}\" — falling back to the accent-matched family.`,\n )\n }\n const resolvedNeutralColor = neutralColorIsValid\n ? rawNeutralColor\n : getMatchingNeutral(value.accentColor ?? DEFAULT_ACCENT)\n\n // The DOM attribute stays one of the 6 static families `[data-neutral-color]` has CSS\n // for — a raw color (from the canvas-tinted auto path, or an arbitrary neutralColor\n // prop) falls back to its accent-matched family here instead, so the attribute is\n // always CSS-selectable/debuggable rather than a sentinel nothing matches.\n // generateAccentScale still gets the real resolvedNeutralColor for generation, below —\n // this substitution is display-only, and doesn't by itself guarantee the *other*\n // appearance's neutrals in ambient (no explicit `appearance`) mode: that's a\n // pre-existing cross-appearance leak in the same family as review-findings.md #5, not\n // something this attribute fallback fixes or regresses.\n const neutralColorAttr =\n resolvedNeutralColor === undefined\n ? undefined\n : isSparkNeutralFamily(resolvedNeutralColor)\n ? resolvedNeutralColor\n : getMatchingNeutral(value.accentColor ?? DEFAULT_ACCENT)\n\n const accent = React.useMemo(() => {\n const empty = {\n inlineVars: {} as React.CSSProperties,\n css: '',\n scoped: false,\n }\n // A custom canvas generates even with no accent of its own: the neutral ramp is\n // composited against it, and --spark-background has to carry it.\n if (!accentColor && !backgroundColor) return empty\n\n const toVars = (decls: string[]) =>\n Object.fromEntries(\n decls\n .filter((decl) => decl.includes(':'))\n .map((decl) => {\n const i = decl.indexOf(':')\n return [\n decl.slice(0, i).trim(),\n decl\n .slice(i + 1)\n .replace(/;$/, '')\n .trim(),\n ]\n }),\n ) as React.CSSProperties\n\n try {\n const source = value.accentColor ?? DEFAULT_ACCENT\n const hex = CURATED_ACCENTS[source] ?? source\n\n // A canvas has a polarity, unlike an accent hue: a yellow page is a *light*\n // page, and reusing it for the dark scale yields light ink on a light canvas\n // (measured 1.16:1). So the custom canvas applies to the appearance it actually\n // belongs to, and the other keeps its default. One knob still covers the common\n // case — a tenant wanting both sets an explicit appearance per scope.\n const bgAppearance = backgroundColor\n ? appearanceForBackground(backgroundColor)\n : undefined\n\n // Honouring a mismatched canvas would paint light ink on a light page, so it's\n // dropped — but say so, or the prop looks broken.\n if (\n backgroundColor &&\n value.appearance &&\n bgAppearance !== value.appearance\n ) {\n console.warn(\n `[Theme] Ignoring backgroundColor \"${backgroundColor}\": it reads as a ${bgAppearance} canvas on an appearance=\"${value.appearance}\" scope. Pass a ${value.appearance} colour, or set it on a scope whose appearance matches.`,\n )\n }\n\n // Default to slate so a regenerated neutral stays in the family the static\n // `:root` default already points at, rather than the generator's ECP gray seed.\n const optsFor = (appearance: Appearance) =>\n backgroundColor && bgAppearance === appearance\n ? {\n background: backgroundColor,\n neutral: resolvedNeutralColor ?? ('slate' as const),\n }\n : undefined\n\n // Neutrals are only worth regenerating against a custom canvas — see\n // neutralSparkVars. Without one the static Radix families are already correct.\n const emit = (scale: SparkAccentScale, custom: boolean) =>\n custom\n ? [...accentSparkVars(scale), ...neutralSparkVars(scale)]\n : accentSparkVars(scale)\n\n const build = (appearance: Appearance) => {\n const opts = optsFor(appearance)\n const scale = generateAccentScale(hex, appearance, opts)\n // `inverted` re-casts the accent for a solid-accent surface; the neutral ramp is\n // unrelated to that swap, so it passes through untouched.\n return emit(inverted ? invertAccentScale(scale) : scale, opts != null)\n }\n\n // Explicit appearance → single-scale inline vars. Correct for a light\n // island inside a dark page (which must NOT pick up the dark scale).\n if (value.appearance) {\n return {\n inlineVars: toVars(build(value.appearance)),\n css: '',\n scoped: false,\n }\n }\n\n // Ambient appearance → emit BOTH scales in a scoped <style> so the\n // `.dark` class selects the right one. Without this, a single-appearance\n // inline scale (default light) breaks components in dark mode.\n //\n // Both blocks must declare the SAME tokens. A custom canvas only regenerates\n // neutrals for its own appearance (see optsFor), and a custom property the other\n // block leaves undeclared keeps its sibling's value rather than falling back — so\n // the off-canvas appearance would paint this one's canvas-tinted neutrals, and\n // being unlayered they'd beat `[data-neutral-color]`'s @layer base mapping too.\n // Point it at the static family instead: the same seed the canvas side was given,\n // so the two appearances agree on family and differ only in canvas.\n const offCanvasNeutrals = backgroundColor\n ? neutralFamilyVars(resolvedNeutralColor ?? 'slate')\n : []\n const scaleFor = (appearance: Appearance) =>\n bgAppearance === appearance\n ? build(appearance)\n : [...build(appearance), ...offCanvasNeutrals]\n const light = scaleFor('light')\n const dark = scaleFor('dark')\n const sel = `[data-spark-scope=\"${scopeId}\"]`\n const css = `${sel}{${light.join('')}}:is(.dark,.dark-theme) ${sel}{${dark.join('')}}`\n return { inlineVars: {} as React.CSSProperties, css, scoped: true }\n } catch (error) {\n // A bad accentColor/backgroundColor must not throw through render — fall back\n // to the default theme.\n console.warn(\n `[Theme] Ignoring invalid accentColor \"${accentColor}\" / backgroundColor \"${backgroundColor}\".`,\n error,\n )\n return empty\n }\n }, [\n accentColor,\n backgroundColor,\n inverted,\n resolvedNeutralColor,\n value.accentColor,\n value.appearance,\n scopeId,\n ])\n\n const element = useRender({\n defaultTagName: 'div',\n render,\n ref,\n props: mergeProps<'div'>(\n {\n className: cn('spark-theme', appearance, className),\n 'data-neutral-color': neutralColorAttr,\n 'data-radius': radius,\n 'data-scaling': scaling,\n 'data-spacing': spacing,\n 'data-style': styleVariant,\n 'data-high-contrast': highContrast ? '' : undefined,\n 'data-inverted': inverted ? '' : undefined,\n 'data-label-position': labelPosition,\n 'data-input-style': inputStyle,\n 'data-input-color': inputColor,\n 'data-card-variant': cardVariant,\n 'data-card-color': cardColor === 'accent' ? 'accent' : undefined,\n 'data-spark-scope': accent.scoped ? scopeId : undefined,\n style: {\n ...accent.inlineVars,\n // Paint the canvas we were handed, else the prop emits a token and visibly\n // does nothing. Reads the var (not the raw prop) so the scoped <style>'s\n // per-appearance value still wins under ambient appearance.\n ...(backgroundColor\n ? { backgroundColor: 'var(--spark-background)' }\n : null),\n ...(fontHeading ? { '--spark-font-heading': fontHeading } : null),\n ...(fontBody ? { '--spark-font-body': fontBody } : null),\n ...style,\n } as React.CSSProperties,\n children,\n } as React.ComponentProps<'div'>,\n rest,\n ),\n })\n\n return (\n <ThemeContext.Provider value={value}>\n {accent.css ? <style>{accent.css}</style> : null}\n {element}\n </ThemeContext.Provider>\n )\n },\n)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"theme.cjs","names":["React","resolveAutoNeutral","isSparkNeutralFamily","isParsableColor","getMatchingNeutral","CURATED_ACCENTS","appearanceForBackground","accentSparkVars","neutralSparkVars","generateAccentScale","invertAccentScale","neutralFamilyVars"],"sources":["../../src/components/theme.tsx"],"sourcesContent":["'use client'\n\nimport { mergeProps } from '@base-ui/react/merge-props'\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport {\n CURATED_ACCENTS,\n accentSparkVars,\n appearanceForBackground,\n generateAccentScale,\n getMatchingNeutral,\n invertAccentScale,\n isParsableColor,\n neutralFamilyVars,\n neutralSparkVars,\n resolveAutoNeutral,\n type Appearance,\n type SparkAccentScale,\n} from '../lib/accent-theme'\nimport {\n isSparkNeutralFamily,\n type SparkCardColor,\n type SparkCardVariant,\n type SparkInputColor,\n type SparkInputStyle,\n type SparkLabelPosition,\n type SparkNeutral,\n type SparkRadius,\n type SparkScaling,\n type SparkSpacing,\n type SparkStyle,\n} from '../lib/theme-types'\nimport { cn } from '../utils/cn'\n\nexport type {\n SparkCardColor,\n SparkCardVariant,\n SparkInputColor,\n SparkInputStyle,\n SparkLabelPosition,\n SparkNeutral,\n SparkNeutralFamily,\n SparkRadius,\n SparkScaling,\n SparkSpacing,\n SparkStyle,\n} from '../lib/theme-types'\n\n/** The epilot brand accent — the scale `spark-default.css` ships statically. */\nconst DEFAULT_ACCENT = '#005EB4'\n\nexport interface ThemeValue {\n /** Curated accent name or a custom hex. */\n accentColor?: string\n /**\n * Page canvas as a custom hex. Regenerates BOTH the accent and neutral scales against\n * it (each alpha step is composited against the canvas, so a saturated colour needs\n * the neutral ramp regenerated too, not just the accent). Unset → the fixed\n * `#ffffff` / `#000000` default, and neutrals stay on the static Radix families.\n */\n backgroundColor?: string\n /**\n * A curated family name, an arbitrary color to seed the neutral scale, or `'auto'` to\n * resolve one — preferring `backgroundColor`'s own hue when it's perceptibly tinted,\n * else pairing with the accent (Radix's `grayColor=\"auto\"`). A custom seed (from `auto`\n * or set directly) only regenerates the scale alongside a `backgroundColor`; without\n * one, `data-neutral-color` falls back to the accent-matched family and that's what\n * actually paints.\n */\n neutralColor?: SparkNeutral\n radius?: SparkRadius\n scaling?: SparkScaling\n spacing?: SparkSpacing\n styleVariant?: SparkStyle\n /** Orthogonal to `styleVariant`: shifts any style toward higher-contrast steps. */\n highContrast?: boolean\n /**\n * Orthogonal to `styleVariant`: re-casts the accent scale for use ON its own solid fill,\n * for controls sitting on a solid accent surface (a `<Card variant=\"solid\" color=\"accent\">`),\n * where a solid control would otherwise paint the same `--spark-9` as the card and vanish.\n * Swaps step 9 with its contrast ink, so the fill/ink pair stays WCAG-safe for any accent.\n */\n inverted?: boolean\n labelPosition?: SparkLabelPosition\n inputStyle?: SparkInputStyle\n inputColor?: SparkInputColor\n /** App-level default `<Card>` chrome; a per-card `variant` prop overrides it. */\n cardVariant?: SparkCardVariant\n /** App-level default `<Card>` palette; a per-card `color` prop overrides it. */\n cardColor?: SparkCardColor\n appearance?: Appearance\n /** Font stack for `h1`–`h6`. Any valid CSS `font-family` value. */\n fontHeading?: string\n /** Font stack for everything else. Any valid CSS `font-family` value. */\n fontBody?: string\n}\n\nconst ThemeContext = React.createContext<ThemeValue>({})\n\n/** What a Theme actually wrote to the DOM, merged over its ancestors (nearest wins). */\ninterface ThemeOutput {\n attrs: Record<string, string>\n vars: Record<string, string>\n scopes: string[]\n}\n\nconst ThemeOutputContext = React.createContext<ThemeOutput | null>(null)\n\n/** Merged theme values from enclosing `<Theme>` providers. */\nexport function useTheme(): ThemeValue {\n return React.useContext(ThemeContext)\n}\n\nexport interface ThemeProps\n extends useRender.ComponentProps<'div'>, ThemeValue {}\n\n/** Optional sugar: writes the theming `data-*` attrs + accent `--spark-*` vars onto a wrapper. */\nexport const Theme = React.forwardRef<HTMLDivElement, ThemeProps>(\n function Theme(\n {\n accentColor,\n backgroundColor,\n neutralColor,\n radius,\n scaling,\n spacing,\n styleVariant,\n highContrast,\n inverted,\n labelPosition,\n inputStyle,\n inputColor,\n cardVariant,\n cardColor,\n appearance,\n fontHeading,\n fontBody,\n render,\n className,\n style,\n children,\n ...rest\n },\n ref,\n ) {\n const parent = useTheme()\n const parentOutput = React.useContext(ThemeOutputContext)\n\n const value = React.useMemo<ThemeValue>(\n () => ({\n accentColor: accentColor ?? parent.accentColor,\n backgroundColor: backgroundColor ?? parent.backgroundColor,\n neutralColor: neutralColor ?? parent.neutralColor,\n radius: radius ?? parent.radius,\n scaling: scaling ?? parent.scaling,\n spacing: spacing ?? parent.spacing,\n styleVariant: styleVariant ?? parent.styleVariant,\n highContrast: highContrast ?? parent.highContrast,\n inverted: inverted ?? parent.inverted,\n labelPosition: labelPosition ?? parent.labelPosition,\n inputStyle: inputStyle ?? parent.inputStyle,\n inputColor: inputColor ?? parent.inputColor,\n cardVariant: cardVariant ?? parent.cardVariant,\n cardColor: cardColor ?? parent.cardColor,\n appearance: appearance ?? parent.appearance,\n fontHeading: fontHeading ?? parent.fontHeading,\n fontBody: fontBody ?? parent.fontBody,\n }),\n [\n accentColor,\n backgroundColor,\n neutralColor,\n radius,\n scaling,\n spacing,\n styleVariant,\n highContrast,\n inverted,\n labelPosition,\n inputStyle,\n inputColor,\n cardVariant,\n cardColor,\n appearance,\n fontHeading,\n fontBody,\n parent,\n ],\n )\n\n // Scope id for the ambient-appearance case (both scales emitted in a <style>).\n const scopeId = React.useId()\n\n // 'auto' pairs a neutral with the canvas's own tint when it has one, else the\n // effective accent (Radix's grayColor=\"auto\") — see resolveAutoNeutral. Reads the\n // OWN backgroundColor, not the merged value.backgroundColor: optsFor (below) only\n // ever regenerates against a scope's own canvas too, so preferring an inherited one\n // here would resolve a seed that then gets silently discarded.\n const rawNeutralColor =\n neutralColor === 'auto'\n ? resolveAutoNeutral(\n value.accentColor ?? DEFAULT_ACCENT,\n backgroundColor,\n )\n : neutralColor\n\n // A custom neutral that isn't a recognized family must be a real, parseable color —\n // reject invalid input here (e.g. a typo'd family name like \"slat\") so it can't throw\n // deep inside the shared generator, where the catch below would otherwise blame\n // accentColor/backgroundColor without ever naming neutralColor as the actual cause.\n const neutralColorIsValid =\n rawNeutralColor === undefined ||\n isSparkNeutralFamily(rawNeutralColor) ||\n isParsableColor(rawNeutralColor)\n if (!neutralColorIsValid) {\n console.warn(\n `[Theme] Ignoring invalid neutralColor \"${rawNeutralColor}\" — falling back to the accent-matched family.`,\n )\n }\n const resolvedNeutralColor = neutralColorIsValid\n ? rawNeutralColor\n : getMatchingNeutral(value.accentColor ?? DEFAULT_ACCENT)\n\n // The DOM attribute stays one of the 6 static families `[data-neutral-color]` has CSS\n // for — a raw color (from the canvas-tinted auto path, or an arbitrary neutralColor\n // prop) falls back to its accent-matched family here instead, so the attribute is\n // always CSS-selectable/debuggable rather than a sentinel nothing matches.\n // generateAccentScale still gets the real resolvedNeutralColor for generation, below —\n // this substitution is display-only, and doesn't by itself guarantee the *other*\n // appearance's neutrals in ambient (no explicit `appearance`) mode: that's a\n // pre-existing cross-appearance leak in the same family as review-findings.md #5, not\n // something this attribute fallback fixes or regresses.\n const neutralColorAttr =\n resolvedNeutralColor === undefined\n ? undefined\n : isSparkNeutralFamily(resolvedNeutralColor)\n ? resolvedNeutralColor\n : getMatchingNeutral(value.accentColor ?? DEFAULT_ACCENT)\n\n const accent = React.useMemo(() => {\n const empty = {\n inlineVars: {} as React.CSSProperties,\n portalVars: {} as React.CSSProperties,\n portalScope: undefined as string | undefined,\n css: '',\n scoped: false,\n }\n // A custom canvas generates even with no accent of its own: the neutral ramp is\n // composited against it, and --spark-background has to carry it.\n if (!accentColor && !backgroundColor) return empty\n\n const toVars = (decls: string[]) =>\n Object.fromEntries(\n decls\n .filter((decl) => decl.includes(':'))\n .map((decl) => {\n const i = decl.indexOf(':')\n return [\n decl.slice(0, i).trim(),\n decl\n .slice(i + 1)\n .replace(/;$/, '')\n .trim(),\n ]\n }),\n ) as React.CSSProperties\n\n try {\n const source = value.accentColor ?? DEFAULT_ACCENT\n const hex = CURATED_ACCENTS[source] ?? source\n\n // A canvas has a polarity, unlike an accent hue: a yellow page is a *light*\n // page, and reusing it for the dark scale yields light ink on a light canvas\n // (measured 1.16:1). So the custom canvas applies to the appearance it actually\n // belongs to, and the other keeps its default. One knob still covers the common\n // case — a tenant wanting both sets an explicit appearance per scope.\n const bgAppearance = backgroundColor\n ? appearanceForBackground(backgroundColor)\n : undefined\n\n // Honouring a mismatched canvas would paint light ink on a light page, so it's\n // dropped — but say so, or the prop looks broken.\n if (\n backgroundColor &&\n value.appearance &&\n bgAppearance !== value.appearance\n ) {\n console.warn(\n `[Theme] Ignoring backgroundColor \"${backgroundColor}\": it reads as a ${bgAppearance} canvas on an appearance=\"${value.appearance}\" scope. Pass a ${value.appearance} colour, or set it on a scope whose appearance matches.`,\n )\n }\n\n // Default to slate so a regenerated neutral stays in the family the static\n // `:root` default already points at, rather than the generator's ECP gray seed.\n const optsFor = (appearance: Appearance) =>\n backgroundColor && bgAppearance === appearance\n ? {\n background: backgroundColor,\n neutral: resolvedNeutralColor ?? ('slate' as const),\n }\n : undefined\n\n // Neutrals are only worth regenerating against a custom canvas — see\n // neutralSparkVars. Without one the static Radix families are already correct.\n const emit = (scale: SparkAccentScale, custom: boolean) =>\n custom\n ? [...accentSparkVars(scale), ...neutralSparkVars(scale)]\n : accentSparkVars(scale)\n\n const build = (appearance: Appearance) => {\n const opts = optsFor(appearance)\n const scale = generateAccentScale(hex, appearance, opts)\n // `inverted` re-casts the accent for a solid-accent surface; the neutral ramp is\n // unrelated to that swap, so it passes through untouched.\n const rendered = emit(\n inverted ? invertAccentScale(scale) : scale,\n opts != null,\n )\n // Popups sit on their own surface, so they get the scale before the inverted re-cast.\n const plain = inverted ? emit(scale, opts != null) : rendered\n return { rendered, plain }\n }\n\n // Explicit appearance → single-scale inline vars. Correct for a light\n // island inside a dark page (which must NOT pick up the dark scale).\n if (value.appearance) {\n const { rendered, plain } = build(value.appearance)\n const inlineVars = toVars(rendered)\n return {\n inlineVars,\n portalVars: inverted ? toVars(plain) : inlineVars,\n portalScope: undefined,\n css: '',\n scoped: false,\n }\n }\n\n // Ambient appearance → emit BOTH scales in a scoped <style> so the\n // `.dark` class selects the right one. Without this, a single-appearance\n // inline scale (default light) breaks components in dark mode.\n //\n // Both blocks must declare the SAME tokens. A custom canvas only regenerates\n // neutrals for its own appearance (see optsFor), and a custom property the other\n // block leaves undeclared keeps its sibling's value rather than falling back — so\n // the off-canvas appearance would paint this one's canvas-tinted neutrals, and\n // being unlayered they'd beat `[data-neutral-color]`'s @layer base mapping too.\n // Point it at the static family instead: the same seed the canvas side was given,\n // so the two appearances agree on family and differ only in canvas.\n const offCanvasNeutrals = backgroundColor\n ? neutralFamilyVars(resolvedNeutralColor ?? 'slate')\n : []\n const scaleFor = (appearance: Appearance) => {\n const { rendered, plain } = build(appearance)\n const extra = bgAppearance === appearance ? [] : offCanvasNeutrals\n return {\n rendered: [...rendered, ...extra],\n plain: [...plain, ...extra],\n }\n }\n const light = scaleFor('light')\n const dark = scaleFor('dark')\n const rule = (\n id: string,\n lightDecls: string[],\n darkDecls: string[],\n ) => {\n const sel = `[data-spark-scope~=\"${id}\"]`\n return `${sel}{${lightDecls.join('')}}:is(.dark,.dark-theme) ${sel}{${darkDecls.join('')}}`\n }\n const portalScope = inverted ? `${scopeId}p` : scopeId\n const css =\n rule(scopeId, light.rendered, dark.rendered) +\n (inverted ? rule(portalScope, light.plain, dark.plain) : '')\n return {\n inlineVars: {} as React.CSSProperties,\n portalVars: {} as React.CSSProperties,\n portalScope,\n css,\n scoped: true,\n }\n } catch (error) {\n // A bad accentColor/backgroundColor must not throw through render — fall back\n // to the default theme.\n console.warn(\n `[Theme] Ignoring invalid accentColor \"${accentColor}\" / backgroundColor \"${backgroundColor}\".`,\n error,\n )\n return empty\n }\n }, [\n accentColor,\n backgroundColor,\n inverted,\n resolvedNeutralColor,\n value.accentColor,\n value.appearance,\n scopeId,\n ])\n\n const attrs = React.useMemo(\n () => ({\n 'data-neutral-color': neutralColorAttr,\n 'data-radius': radius,\n 'data-scaling': scaling,\n 'data-spacing': spacing,\n 'data-style': styleVariant,\n 'data-high-contrast': highContrast ? '' : undefined,\n 'data-label-position': labelPosition,\n 'data-input-style': inputStyle,\n 'data-input-color': inputColor,\n 'data-card-variant': cardVariant,\n 'data-card-color': cardColor === 'accent' ? 'accent' : undefined,\n }),\n [\n neutralColorAttr,\n radius,\n scaling,\n spacing,\n styleVariant,\n highContrast,\n labelPosition,\n inputStyle,\n inputColor,\n cardVariant,\n cardColor,\n ],\n )\n const fontVars = React.useMemo(\n () => ({\n ...(fontHeading ? { '--spark-font-heading': fontHeading } : null),\n ...(fontBody ? { '--spark-font-body': fontBody } : null),\n }),\n [fontHeading, fontBody],\n )\n\n const element = useRender({\n defaultTagName: 'div',\n render,\n ref,\n props: mergeProps<'div'>(\n {\n className: cn('spark-theme', appearance, className),\n ...attrs,\n 'data-inverted': inverted ? '' : undefined,\n 'data-spark-scope': accent.scoped ? scopeId : undefined,\n style: {\n ...accent.inlineVars,\n // Paint the canvas we were handed, else the prop emits a token and visibly\n // does nothing. Reads the var (not the raw prop) so the scoped <style>'s\n // per-appearance value still wins under ambient appearance.\n ...(backgroundColor\n ? { backgroundColor: 'var(--spark-background)' }\n : null),\n ...fontVars,\n ...style,\n } as React.CSSProperties,\n children,\n } as React.ComponentProps<'div'>,\n rest,\n ),\n })\n\n const output = React.useMemo<ThemeOutput>(() => {\n // An unset own knob must not blank out the ancestor's value it inherits.\n const own = Object.fromEntries(\n Object.entries(attrs).filter(\n (entry): entry is [string, string] => entry[1] !== undefined,\n ),\n )\n const parentScopes = parentOutput?.scopes ?? []\n return {\n attrs: { ...parentOutput?.attrs, ...own },\n vars: {\n ...parentOutput?.vars,\n ...(accent.portalVars as Record<string, string>),\n ...fontVars,\n },\n scopes: accent.portalScope\n ? [...parentScopes, accent.portalScope]\n : parentScopes,\n }\n }, [parentOutput, attrs, accent, fontVars])\n\n return (\n <ThemeContext.Provider value={value}>\n <ThemeOutputContext.Provider value={output}>\n {accent.css ? <style>{accent.css}</style> : null}\n {element}\n </ThemeOutputContext.Provider>\n </ThemeContext.Provider>\n )\n },\n)\n\n/** Re-emits what the enclosing Themes rendered inside a portal, where CSS inheritance from them stops. */\nexport function PortalTheme({ children }: { children: React.ReactNode }) {\n const output = React.useContext(ThemeOutputContext)\n const theme = useTheme()\n // A popup sits on its own surface, never on the solid accent `inverted` is for.\n const value = React.useMemo(() => ({ ...theme, inverted: false }), [theme])\n if (!output) return <>{children}</>\n return (\n <ThemeContext.Provider value={value}>\n <div\n data-slot=\"portal-theme\"\n className={cn('spark-theme', theme.appearance)}\n {...output.attrs}\n data-spark-scope={\n output.scopes.length ? output.scopes.join(' ') : undefined\n }\n style={{ display: 'contents', ...output.vars }}\n >\n {children}\n </div>\n </ThemeContext.Provider>\n )\n}\n"],"mappings":"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"}
|
|
@@ -56,6 +56,12 @@ declare function useTheme(): ThemeValue;
|
|
|
56
56
|
interface ThemeProps extends useRender.ComponentProps<'div'>, ThemeValue {}
|
|
57
57
|
/** Optional sugar: writes the theming `data-*` attrs + accent `--spark-*` vars onto a wrapper. */
|
|
58
58
|
declare const Theme: React$1.ForwardRefExoticComponent<Omit<ThemeProps, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
|
|
59
|
+
/** Re-emits what the enclosing Themes rendered inside a portal, where CSS inheritance from them stops. */
|
|
60
|
+
declare function PortalTheme({
|
|
61
|
+
children
|
|
62
|
+
}: {
|
|
63
|
+
children: React$1.ReactNode;
|
|
64
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
59
65
|
//#endregion
|
|
60
|
-
export { type SparkCardColor, type SparkCardVariant, type SparkInputColor, type SparkInputStyle, type SparkLabelPosition, type SparkNeutral, type SparkNeutralFamily, type SparkRadius, type SparkScaling, type SparkSpacing, type SparkStyle, Theme, ThemeProps, ThemeValue, useTheme };
|
|
66
|
+
export { PortalTheme, type SparkCardColor, type SparkCardVariant, type SparkInputColor, type SparkInputStyle, type SparkLabelPosition, type SparkNeutral, type SparkNeutralFamily, type SparkRadius, type SparkScaling, type SparkSpacing, type SparkStyle, Theme, ThemeProps, ThemeValue, useTheme };
|
|
61
67
|
//# sourceMappingURL=theme.d.cts.map
|
|
@@ -56,6 +56,12 @@ declare function useTheme(): ThemeValue;
|
|
|
56
56
|
interface ThemeProps extends useRender.ComponentProps<'div'>, ThemeValue {}
|
|
57
57
|
/** Optional sugar: writes the theming `data-*` attrs + accent `--spark-*` vars onto a wrapper. */
|
|
58
58
|
declare const Theme: React$1.ForwardRefExoticComponent<Omit<ThemeProps, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
|
|
59
|
+
/** Re-emits what the enclosing Themes rendered inside a portal, where CSS inheritance from them stops. */
|
|
60
|
+
declare function PortalTheme({
|
|
61
|
+
children
|
|
62
|
+
}: {
|
|
63
|
+
children: React$1.ReactNode;
|
|
64
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
59
65
|
//#endregion
|
|
60
|
-
export { type SparkCardColor, type SparkCardVariant, type SparkInputColor, type SparkInputStyle, type SparkLabelPosition, type SparkNeutral, type SparkNeutralFamily, type SparkRadius, type SparkScaling, type SparkSpacing, type SparkStyle, Theme, ThemeProps, ThemeValue, useTheme };
|
|
66
|
+
export { PortalTheme, type SparkCardColor, type SparkCardVariant, type SparkInputColor, type SparkInputStyle, type SparkLabelPosition, type SparkNeutral, type SparkNeutralFamily, type SparkRadius, type SparkScaling, type SparkSpacing, type SparkStyle, Theme, ThemeProps, ThemeValue, useTheme };
|
|
61
67
|
//# sourceMappingURL=theme.d.ts.map
|