@adea-ai/ui 0.100.2 → 0.101.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/composites/about-dialog/about-dialog.d.ts.map +1 -1
- package/dist/components/composites/about-dialog/about-dialog.js +2 -1
- package/dist/components/composites/about-dialog/about-dialog.js.map +1 -1
- package/dist/components/composites/account-menu/account-menu.d.ts +7 -0
- package/dist/components/composites/account-menu/account-menu.d.ts.map +1 -1
- package/dist/components/composites/account-menu/account-menu.js +116 -89
- package/dist/components/composites/account-menu/account-menu.js.map +1 -1
- package/dist/components/composites/help-center/help-center.d.ts.map +1 -1
- package/dist/components/composites/help-center/help-center.js +26 -21
- package/dist/components/composites/help-center/help-center.js.map +1 -1
- package/dist/components/composites/settings/settings.d.ts.map +1 -1
- package/dist/components/composites/settings/settings.js +43 -36
- package/dist/components/composites/settings/settings.js.map +1 -1
- package/dist/components/composites/stat/stat.d.ts.map +1 -1
- package/dist/components/composites/stat/stat.js +46 -35
- package/dist/components/composites/stat/stat.js.map +1 -1
- package/dist/components/composites/update-dialog/update-dialog.d.ts.map +1 -1
- package/dist/components/composites/update-dialog/update-dialog.js +73 -58
- package/dist/components/composites/update-dialog/update-dialog.js.map +1 -1
- package/dist/components/layout/page/page.d.ts.map +1 -1
- package/dist/components/layout/page/page.js +19 -13
- package/dist/components/layout/page/page.js.map +1 -1
- package/dist/components/theme/appearance-panel.d.ts.map +1 -1
- package/dist/components/theme/appearance-panel.js +37 -18
- package/dist/components/theme/appearance-panel.js.map +1 -1
- package/dist/components/ui/alert-dialog/alert-dialog.d.ts.map +1 -1
- package/dist/components/ui/alert-dialog/alert-dialog.js +5 -1
- package/dist/components/ui/alert-dialog/alert-dialog.js.map +1 -1
- package/dist/components/ui/card/card.d.ts.map +1 -1
- package/dist/components/ui/card/card.js +5 -1
- package/dist/components/ui/card/card.js.map +1 -1
- package/dist/components/ui/chart/chart-options.d.ts +3 -2
- package/dist/components/ui/chart/chart-options.d.ts.map +1 -1
- package/dist/components/ui/chart/chart-options.js +30 -9
- package/dist/components/ui/chart/chart-options.js.map +1 -1
- package/dist/components/ui/chart/chart.d.ts +4 -9
- package/dist/components/ui/chart/chart.d.ts.map +1 -1
- package/dist/components/ui/chart/chart.js +65 -10
- package/dist/components/ui/chart/chart.js.map +1 -1
- package/dist/components/ui/dialog/dialog.d.ts.map +1 -1
- package/dist/components/ui/dialog/dialog.js +5 -1
- package/dist/components/ui/dialog/dialog.js.map +1 -1
- package/dist/components/ui/drawer/drawer.d.ts.map +1 -1
- package/dist/components/ui/drawer/drawer.js +5 -1
- package/dist/components/ui/drawer/drawer.js.map +1 -1
- package/dist/components/ui/field/field.d.ts.map +1 -1
- package/dist/components/ui/field/field.js +2 -1
- package/dist/components/ui/field/field.js.map +1 -1
- package/dist/components/ui/item/item.d.ts +1 -1
- package/dist/components/ui/sheet/sheet.d.ts.map +1 -1
- package/dist/components/ui/sheet/sheet.js +5 -1
- package/dist/components/ui/sheet/sheet.js.map +1 -1
- package/dist/components/ui/typography/index.d.ts +3 -0
- package/dist/components/ui/typography/index.d.ts.map +1 -0
- package/dist/components/ui/typography/index.js +2 -0
- package/dist/components/ui/typography/typography.d.ts +84 -0
- package/dist/components/ui/typography/typography.d.ts.map +1 -0
- package/dist/components/ui/typography/typography.js +179 -0
- package/dist/components/ui/typography/typography.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/r/account-menu.json +1 -0
- package/dist/r/alert-dialog.json +1 -0
- package/dist/r/card.json +1 -0
- package/dist/r/dialog.json +1 -0
- package/dist/r/drawer.json +1 -0
- package/dist/r/field.json +1 -0
- package/dist/r/help-center.json +1 -0
- package/dist/r/page.json +1 -0
- package/dist/r/registry.json +37 -0
- package/dist/r/settings.json +1 -0
- package/dist/r/sheet.json +1 -0
- package/dist/r/src/components/composites/about-dialog/about-dialog.tsx +3 -2
- package/dist/r/src/components/composites/account-menu/account-menu.tsx +105 -66
- package/dist/r/src/components/composites/help-center/help-center.tsx +2 -1
- package/dist/r/src/components/composites/settings/settings.tsx +4 -1
- package/dist/r/src/components/composites/stat/stat.tsx +7 -2
- package/dist/r/src/components/composites/update-dialog/update-dialog.tsx +36 -24
- package/dist/r/src/components/layout/page/page.tsx +3 -2
- package/dist/r/src/components/theme/appearance-panel.tsx +13 -4
- package/dist/r/src/components/ui/alert-dialog/alert-dialog.tsx +2 -1
- package/dist/r/src/components/ui/card/card.tsx +2 -1
- package/dist/r/src/components/ui/chart/chart-options.ts +35 -7
- package/dist/r/src/components/ui/chart/chart.tsx +65 -12
- package/dist/r/src/components/ui/dialog/dialog.tsx +2 -1
- package/dist/r/src/components/ui/drawer/drawer.tsx +2 -1
- package/dist/r/src/components/ui/field/field.tsx +2 -3
- package/dist/r/src/components/ui/sheet/sheet.tsx +5 -1
- package/dist/r/src/components/ui/typography/index.ts +9 -0
- package/dist/r/src/components/ui/typography/typography.tsx +205 -0
- package/dist/r/stat.json +1 -0
- package/dist/r/theming.json +1 -0
- package/dist/r/typography.json +24 -0
- package/dist/r/update-dialog.json +1 -0
- package/package.json +1 -1
- package/registry.json +37 -0
- package/src/components/composites/about-dialog/about-dialog.tsx +3 -2
- package/src/components/composites/account-menu/account-menu.tsx +105 -66
- package/src/components/composites/help-center/help-center.tsx +2 -1
- package/src/components/composites/settings/settings.tsx +4 -1
- package/src/components/composites/stat/stat.tsx +7 -2
- package/src/components/composites/update-dialog/update-dialog.tsx +36 -24
- package/src/components/layout/page/page.tsx +3 -2
- package/src/components/theme/appearance-panel.tsx +13 -4
- package/src/components/ui/alert-dialog/alert-dialog.tsx +2 -1
- package/src/components/ui/card/card.tsx +2 -1
- package/src/components/ui/chart/chart-options.ts +35 -7
- package/src/components/ui/chart/chart.tsx +65 -12
- package/src/components/ui/dialog/dialog.tsx +2 -1
- package/src/components/ui/drawer/drawer.tsx +2 -1
- package/src/components/ui/field/field.tsx +2 -3
- package/src/components/ui/sheet/sheet.tsx +5 -1
- package/src/components/ui/typography/index.ts +9 -0
- package/src/components/ui/typography/typography.tsx +205 -0
- package/src/index.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page.js","names":["ComponentProps","JSX","Show","splitProps","cn","PageHeader","props","local","rest","_el$","_tmpl$","_$spread","_$mergeProps","class","PageHeaderContent","_el$2","_tmpl$2","PageHeaderTitle","_el$3","_tmpl$3","PageHeaderDescription","_el$4","_tmpl$4","PageHeaderActions","_el$5","_tmpl$5","PageSection","title","description","action","Element","_el$6","_tmpl$9","_$insert","_$createComponent","when","children","_el$7","_tmpl$8","_el$8","firstChild","_el$9","
|
|
1
|
+
{"version":3,"file":"page.js","names":["ComponentProps","JSX","Show","splitProps","cn","Heading","headingVariants","PageHeader","props","local","rest","_el$","_tmpl$","_$spread","_$mergeProps","class","PageHeaderContent","_el$2","_tmpl$2","PageHeaderTitle","_el$3","_tmpl$3","size","PageHeaderDescription","_el$4","_tmpl$4","PageHeaderActions","_el$5","_tmpl$5","PageSection","title","description","action","Element","_el$6","_tmpl$9","_$insert","_$createComponent","when","children","_el$7","_tmpl$8","_el$8","firstChild","_el$9","_tmpl$6","_el$0","_tmpl$7","Page","_el$1","_tmpl$0","_$mergeProps","_$createComponent"],"sources":["../../../../src/components/layout/page/page.tsx"],"sourcesContent":["import type { ComponentProps, JSX } from 'solid-js'\nimport { Show, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\nimport { Heading, headingVariants } from '../../ui/typography'\n\n/**\n * PageHeader.\n *\n * The title block at the top of a scrollable page: where the user is, what this\n * page is, and the actions that apply to the whole of it.\n *\n * The action slot is single and singular on purpose. A page header with four\n * equally-weighted buttons has not decided what the page is for; the design\n * system can only make that look tidy, not make it true. Put the primary action\n * here and the rest in an overflow menu or on the rows they belong to.\n */\nexport function PageHeader(props: ComponentProps<'header'>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <header\n data-slot=\"page-header\"\n class={cn(\n 'flex shrink-0 flex-wrap items-start justify-between gap-x-4 gap-y-3 px-5 pt-5 pb-4',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function PageHeaderContent(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"page-header-content\"\n class={cn('flex min-w-0 flex-col gap-1', local.class)}\n {...rest}\n />\n )\n}\n\nexport function PageHeaderTitle(props: ComponentProps<'h1'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <h1\n data-slot=\"page-header-title\"\n class={cn(headingVariants({ size: 'page' }), local.class)}\n {...rest}\n />\n )\n}\n\nexport function PageHeaderDescription(props: ComponentProps<'p'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <p\n data-slot=\"page-header-description\"\n class={cn('max-w-prose text-sm text-muted-foreground text-pretty', local.class)}\n {...rest}\n />\n )\n}\n\n/** The trailing action group. One primary action, at most. */\nexport function PageHeaderActions(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"page-header-actions\"\n class={cn('flex shrink-0 items-center gap-2', local.class)}\n {...rest}\n />\n )\n}\n\n/**\n * A section inside a page, with an optional title and a description.\n * Sections are separated by space rather than by rules — a page of boxed\n * sections reads as a dashboard, and most pages are not one.\n */\nexport function PageSection(\n props: ComponentProps<'section'> & { title?: string; description?: string; action?: JSX.Element }\n) {\n const [local, rest] = splitProps(props, ['class', 'title', 'description', 'action', 'children'])\n\n return (\n <section\n data-slot=\"page-section\"\n class={cn('flex flex-col gap-3 px-5 py-4', local.class)}\n {...rest}\n >\n <Show when={local.title}>\n <div class=\"flex items-baseline justify-between gap-3\">\n <div class=\"flex min-w-0 flex-col gap-0.5\">\n <Heading size=\"section\">{local.title}</Heading>\n <Show when={local.description}>\n <p class=\"max-w-prose text-sm text-muted-foreground text-pretty\">\n {local.description}\n </p>\n </Show>\n </div>\n <Show when={local.action}>\n <div class=\"flex shrink-0 items-center gap-2\">{local.action}</div>\n </Show>\n </div>\n </Show>\n {local.children}\n </section>\n )\n}\n\n/** The scroll container a page's header and sections sit in. */\nexport function Page(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"page\"\n class={cn('flex min-h-0 flex-1 flex-col overflow-y-auto', local.class)}\n {...rest}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,SAAgBO,WAAWC,OAAiC;CAC1D,MAAM,CAACC,OAAOC,QAAQP,WAAWK,OAAO,CAAC,OAAO,CAAC;CAEjD,cAAA;EAAA,IAAAG,OAAAC,OAAA;EAAAC,OAAAF,MAAAG,WAAA,EAAA,KAAA,WAAA;GAAA,OAGWV,GACL,sFACAK,MAAMM,KACR;EAAC,EAAA,GACGL,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAC;CAAA,EAAA,CAAA;AAGd;AAEA,SAAgBK,kBAAkBR,OAA8B;CAC9D,MAAM,CAACC,OAAOC,QAAQP,WAAWK,OAAO,CAAC,OAAO,CAAC;CACjD,cAAA;EAAA,IAAAS,QAAAC,QAAA;EAAAL,OAAAI,OAAAH,WAAA,EAAA,KAAA,WAAA;GAAA,OAGWV,GAAG,+BAA+BK,MAAMM,KAAK;EAAC,EAAA,GACjDL,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAO;CAAA,EAAA,CAAA;AAGd;AAEA,SAAgBE,gBAAgBX,OAA6B;CAC3D,MAAM,CAACC,OAAOC,QAAQP,WAAWK,OAAO,CAAC,OAAO,CAAC;CACjD,cAAA;EAAA,IAAAY,QAAAC,QAAA;EAAAR,OAAAO,OAAAN,WAAA,EAAA,KAAA,WAAA;GAAA,OAGWV,GAAGE,gBAAgB,EAAEgB,MAAM,OAAO,CAAC,GAAGb,MAAMM,KAAK;EAAC,EAAA,GACrDL,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAU;CAAA,EAAA,CAAA;AAGd;AAEA,SAAgBG,sBAAsBf,OAA4B;CAChE,MAAM,CAACC,OAAOC,QAAQP,WAAWK,OAAO,CAAC,OAAO,CAAC;CACjD,cAAA;EAAA,IAAAgB,QAAAC,QAAA;EAAAZ,OAAAW,OAAAV,WAAA,EAAA,KAAA,WAAA;GAAA,OAGWV,GAAG,yDAAyDK,MAAMM,KAAK;EAAC,EAAA,GAC3EL,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAc;CAAA,EAAA,CAAA;AAGd;;AAGA,SAAgBE,kBAAkBlB,OAA8B;CAC9D,MAAM,CAACC,OAAOC,QAAQP,WAAWK,OAAO,CAAC,OAAO,CAAC;CACjD,cAAA;EAAA,IAAAmB,QAAAC,QAAA;EAAAf,OAAAc,OAAAb,WAAA,EAAA,KAAA,WAAA;GAAA,OAGWV,GAAG,oCAAoCK,MAAMM,KAAK;EAAC,EAAA,GACtDL,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAiB;CAAA,EAAA,CAAA;AAGd;;;;;;AAOA,SAAgBE,YACdrB,OACA;CACA,MAAM,CAACC,OAAOC,QAAQP,WAAWK,OAAO;EAAC;EAAS;EAAS;EAAe;EAAU;CAAU,CAAC;CAE/F,cAAA;EAAA,IAAA0B,QAAAC,QAAA;EAAAtB,OAAAqB,OAAApB,WAAA,EAAA,KAAA,WAAA;GAAA,OAGWV,GAAG,iCAAiCK,MAAMM,KAAK;EAAC,EAAA,GACnDL,IAAI,GAAA,OAAA,IAAA;EAAA0B,OAAAF,OAAAG,gBAEPnC,MAAI;GAAA,IAACoC,OAAI;IAAA,OAAE7B,MAAMqB;GAAK;GAAA,IAAAS,WAAA;IAAA,IAAAC,QAAAC,QAAA,GAAAC,QAAAF,MAAAG;IAAAP,OAAAM,OAAAL,gBAGhBhC,SAAO;KAACiB,MAAI;KAAA,IAAAiB,WAAA;MAAA,OAAY9B,MAAMqB;KAAK;IAAA,CAAA,GAAA,IAAA;IAAAM,OAAAM,OAAAL,gBACnCnC,MAAI;KAAA,IAACoC,OAAI;MAAA,OAAE7B,MAAMsB;KAAW;KAAA,IAAAQ,WAAA;MAAA,IAAAK,QAAAC,QAAA;MAAAT,OAAAQ,aAExBnC,MAAMsB,WAAW;MAAA,OAAAa;KAAA;IAAA,CAAA,GAAA,IAAA;IAAAR,OAAAI,OAAAH,gBAIvBnC,MAAI;KAAA,IAACoC,OAAI;MAAA,OAAE7B,MAAMuB;KAAM;KAAA,IAAAO,WAAA;MAAA,IAAAO,QAAAC,QAAA;MAAAX,OAAAU,aACyBrC,MAAMuB,MAAM;MAAA,OAAAc;KAAA;IAAA,CAAA,GAAA,IAAA;IAAA,OAAAN;GAAA;EAAA,CAAA,GAAA,IAAA;EAAAJ,OAAAF,aAIhEzB,MAAM8B,UAAQ,IAAA;EAAA,OAAAL;CAAA,EAAA,CAAA;AAGrB;;AAGA,SAAgBc,KAAKxC,OAA8B;CACjD,MAAM,CAACC,OAAOC,QAAQP,WAAWK,OAAO,CAAC,OAAO,CAAC;CACjD,cAAA;EAAA,IAAAyC,QAAAC,QAAA;EAAArC,OAAAoC,OAAAnC,WAAA,EAAA,KAAA,WAAA;GAAA,OAGWV,GAAG,gDAAgDK,MAAMM,KAAK;EAAC,EAAA,GAClEL,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAuC;CAAA,EAAA,CAAA;AAGd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appearance-panel.d.ts","sourceRoot":"","sources":["../../../src/components/theme/appearance-panel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"appearance-panel.d.ts","sourceRoot":"","sources":["../../../src/components/theme/appearance-panel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAW9C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;AAKxD,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,kCA8H1D"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { cn } from "../../lib/utils.js";
|
|
2
|
+
import { Heading } from "../ui/typography/typography.js";
|
|
2
3
|
import { Button } from "../ui/button/button.js";
|
|
3
4
|
import { RadioGroup, RadioGroupItem } from "../ui/radio-group/radio-group.js";
|
|
4
5
|
import { accentPresets, fontOptions } from "../../lib/tokens.js";
|
|
@@ -8,22 +9,24 @@ import { useTheme } from "./theme-provider.js";
|
|
|
8
9
|
import { createComponent, effect, insert, memo, mergeProps, setStyleProperty, spread, template } from "solid-js/web";
|
|
9
10
|
import { For, Show, splitProps } from "solid-js";
|
|
10
11
|
//#region src/components/theme/appearance-panel.tsx
|
|
11
|
-
var _tmpl$ = /*#__PURE__*/ template(`<div data-slot=appearance-panel><section class="flex flex-col gap-3"><header class="flex flex-col gap-0.5"><
|
|
12
|
+
var _tmpl$ = /*#__PURE__*/ template(`<div data-slot=appearance-panel><section class="flex flex-col gap-3"><header class="flex flex-col gap-0.5"><p class="max-w-prose text-sm text-muted-foreground">Follow the system, or pin one. The theme below is chosen per appearance, so switching at sunset does not make you choose again.</p></header></section><section class="flex flex-col gap-3"><header class="flex flex-col gap-0.5"><p class="max-w-prose text-sm text-muted-foreground">Colours the interactive roles — the primary button, the focus ring, a selected row — on top of the theme above. Every preset is measured against the surface it lands on, so none of them can make a label unreadable.</p></header><div role=radiogroup aria-label=Accent class="flex flex-wrap gap-2"></div></section><section class="flex flex-col gap-3"><header class="flex flex-col gap-0.5"><p class="max-w-prose text-sm text-muted-foreground">The interface face. Every option is self-hosted, so nothing is fetched at runtime and the choice survives going offline.`);
|
|
12
13
|
var _tmpl$2 = /*#__PURE__*/ template(`<span aria-hidden=true class="size-3 rounded-full border border-border">`);
|
|
13
|
-
var _tmpl$3 = /*#__PURE__*/ template(`<section class="flex flex-col gap-3"><header class="flex flex-col gap-0.5"><
|
|
14
|
+
var _tmpl$3 = /*#__PURE__*/ template(`<section class="flex flex-col gap-3"><header class="flex flex-col gap-0.5"><p class="max-w-prose text-sm text-muted-foreground">`);
|
|
14
15
|
var LIGHT_THEMES = themesForAppearance("light");
|
|
15
16
|
var DARK_THEMES = themesForAppearance("dark");
|
|
16
17
|
function AppearancePanel(props) {
|
|
17
18
|
const [local, rest] = splitProps(props, ["class"]);
|
|
18
19
|
const { selection, setSelection, resolvedAppearance } = useTheme();
|
|
19
20
|
return (() => {
|
|
20
|
-
var _el$ = _tmpl$(), _el$2 = _el$.firstChild;
|
|
21
|
-
_el$2.firstChild;
|
|
22
|
-
var _el$4 = _el$2.nextSibling, _el$6 = _el$4.firstChild.nextSibling, _el$7 = _el$4.nextSibling;
|
|
23
|
-
_el$7.firstChild;
|
|
21
|
+
var _el$ = _tmpl$(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$2.nextSibling, _el$6 = _el$5.firstChild, _el$7 = _el$6.firstChild, _el$8 = _el$6.nextSibling, _el$9 = _el$5.nextSibling, _el$0 = _el$9.firstChild, _el$1 = _el$0.firstChild;
|
|
24
22
|
spread(_el$, mergeProps({ get ["class"]() {
|
|
25
23
|
return cn("flex flex-col gap-8", local.class);
|
|
26
24
|
} }, rest), false, true);
|
|
25
|
+
insert(_el$3, createComponent(Heading, {
|
|
26
|
+
as: "h2",
|
|
27
|
+
size: "card",
|
|
28
|
+
children: "Appearance"
|
|
29
|
+
}), _el$4);
|
|
27
30
|
insert(_el$2, createComponent(RadioGroup, {
|
|
28
31
|
get value() {
|
|
29
32
|
return selection().appearance;
|
|
@@ -67,7 +70,7 @@ function AppearancePanel(props) {
|
|
|
67
70
|
onThemeSelect: (theme) => setSelection({ lightThemeId: theme.id })
|
|
68
71
|
});
|
|
69
72
|
}
|
|
70
|
-
}), _el$
|
|
73
|
+
}), _el$5);
|
|
71
74
|
insert(_el$, createComponent(Show, {
|
|
72
75
|
get when() {
|
|
73
76
|
return resolvedAppearance() === "dark";
|
|
@@ -83,8 +86,13 @@ function AppearancePanel(props) {
|
|
|
83
86
|
onThemeSelect: (theme) => setSelection({ darkThemeId: theme.id })
|
|
84
87
|
});
|
|
85
88
|
}
|
|
86
|
-
}), _el$
|
|
87
|
-
insert(_el$6, createComponent(
|
|
89
|
+
}), _el$5);
|
|
90
|
+
insert(_el$6, createComponent(Heading, {
|
|
91
|
+
as: "h2",
|
|
92
|
+
size: "card",
|
|
93
|
+
children: "Accent"
|
|
94
|
+
}), _el$7);
|
|
95
|
+
insert(_el$8, createComponent(For, {
|
|
88
96
|
each: accentPresets,
|
|
89
97
|
children: (preset) => createComponent(Button, {
|
|
90
98
|
as: "button",
|
|
@@ -104,14 +112,19 @@ function AppearancePanel(props) {
|
|
|
104
112
|
onClick: () => setSelection({ accent: preset.id }),
|
|
105
113
|
get children() {
|
|
106
114
|
return [(() => {
|
|
107
|
-
var _el$
|
|
108
|
-
effect((_$p) => setStyleProperty(_el$
|
|
109
|
-
return _el$
|
|
115
|
+
var _el$10 = _tmpl$2();
|
|
116
|
+
effect((_$p) => setStyleProperty(_el$10, "background-color", preset.id === "theme" ? "var(--primary)" : `var(--accent-${preset.id}, ${preset.dark})`));
|
|
117
|
+
return _el$10;
|
|
110
118
|
})(), memo(() => preset.label)];
|
|
111
119
|
}
|
|
112
120
|
})
|
|
113
121
|
}));
|
|
114
|
-
insert(_el$
|
|
122
|
+
insert(_el$0, createComponent(Heading, {
|
|
123
|
+
as: "h2",
|
|
124
|
+
size: "card",
|
|
125
|
+
children: "Typeface"
|
|
126
|
+
}), _el$1);
|
|
127
|
+
insert(_el$9, createComponent(RadioGroup, {
|
|
115
128
|
get value() {
|
|
116
129
|
return selection().font;
|
|
117
130
|
},
|
|
@@ -139,10 +152,16 @@ function AppearancePanel(props) {
|
|
|
139
152
|
}
|
|
140
153
|
function ThemeSection(props) {
|
|
141
154
|
return (() => {
|
|
142
|
-
var _el$
|
|
143
|
-
insert(_el$
|
|
144
|
-
|
|
145
|
-
|
|
155
|
+
var _el$11 = _tmpl$3(), _el$12 = _el$11.firstChild, _el$13 = _el$12.firstChild;
|
|
156
|
+
insert(_el$12, createComponent(Heading, {
|
|
157
|
+
as: "h2",
|
|
158
|
+
size: "card",
|
|
159
|
+
get children() {
|
|
160
|
+
return props.title;
|
|
161
|
+
}
|
|
162
|
+
}), _el$13);
|
|
163
|
+
insert(_el$13, () => props.description);
|
|
164
|
+
insert(_el$11, createComponent(ThemePicker, {
|
|
146
165
|
get themes() {
|
|
147
166
|
return props.themes;
|
|
148
167
|
},
|
|
@@ -153,7 +172,7 @@ function ThemeSection(props) {
|
|
|
153
172
|
return props.onThemeSelect;
|
|
154
173
|
}
|
|
155
174
|
}), null);
|
|
156
|
-
return _el$
|
|
175
|
+
return _el$11;
|
|
157
176
|
})();
|
|
158
177
|
}
|
|
159
178
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appearance-panel.js","names":["ComponentProps","For","Show","splitProps","accentPresets","fontOptions","themesForAppearance","cn","Button","RadioGroup","RadioGroupItem","ThemePicker","useTheme","AppearancePanelProps","LIGHT_THEMES","DARK_THEMES","AppearancePanel","props","local","rest","selection","setSelection","resolvedAppearance","_el$","_tmpl$","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_el$6","_el$7","_el$8","_$spread","_$mergeProps","class","_$insert","_$createComponent","value","appearance","onChange","children","label","description","when","ThemeSection","title","themes","selectedId","lightThemeId","onThemeSelect","theme","id","darkThemeId","each","preset","as","type","variant","size","role","aria-checked","accent","aria-label","onClick","_el$9","_tmpl$2","_$effect","_$p","_$setStyleProperty","dark","_$memo","font","option","ReturnType","_el$0","_tmpl$3","_el$1","_el$10","_el$11","_$mergeProps","_$createComponent","_$setStyleProperty","_$memo"],"sources":["../../../src/components/theme/appearance-panel.tsx"],"sourcesContent":["import type { ComponentProps } from 'solid-js'\nimport { For, Show, splitProps } from 'solid-js'\nimport { accentPresets, fontOptions } from '#lib/tokens'\nimport { themesForAppearance } from '#lib/themes'\nimport { cn } from '#lib/utils'\nimport { Button } from '../ui/button/button'\nimport { RadioGroup, RadioGroupItem } from '../ui/radio-group/radio-group'\nimport { ThemePicker } from './theme-picker'\nimport { useTheme } from './theme-provider'\n\n/**\n * AppearancePanel.\n *\n * The appearance page, as a component rather than as a screen each application\n * draws for itself. Two applications that both let a user choose a theme should\n * offer the *same* choices in the *same* arrangement — otherwise \"Adea\" and\n * \"Cortana\" are two products that happen to share a component library, which is\n * the opposite of what this system is for.\n *\n * Four axes, in the order a user thinks about them:\n *\n * 1. **Appearance** — light, dark, or follow the system.\n * 2. **Themes** — one for each appearance. Both are shown at once, because the\n * choice is per-appearance and hiding the other half makes it feel like one\n * setting that keeps changing.\n * 3. **Accent** — adea's presets, layered on whichever theme is active.\n * 4. **Font** — the interface face.\n *\n * The panel reads and writes the provider's preference and keeps no state of its\n * own, so it cannot disagree with what is applied.\n */\nexport type AppearancePanelProps = ComponentProps<'div'>\n\nconst LIGHT_THEMES = themesForAppearance('light')\nconst DARK_THEMES = themesForAppearance('dark')\n\nexport function AppearancePanel(props: AppearancePanelProps) {\n const [local, rest] = splitProps(props, ['class'])\n const { selection, setSelection, resolvedAppearance } = useTheme()\n\n return (\n <div data-slot=\"appearance-panel\" class={cn('flex flex-col gap-8', local.class)} {...rest}>\n {/* --- 1. Appearance ------------------------------------------------- */}\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <h2 class=\"text-base font-semibold tracking-tight\">Appearance</h2>\n <p class=\"max-w-prose text-sm text-muted-foreground\">\n Follow the system, or pin one. The theme below is chosen per appearance, so switching at\n sunset does not make you choose again.\n </p>\n </header>\n <RadioGroup\n value={selection().appearance}\n onChange={(value) => setSelection({ appearance: value as 'light' | 'dark' | 'system' })}\n aria-label=\"Appearance\"\n >\n <RadioGroupItem value=\"light\" label=\"Light\" description=\"Always the light theme.\" />\n <RadioGroupItem value=\"dark\" label=\"Dark\" description=\"Always the dark theme.\" />\n <RadioGroupItem\n value=\"system\"\n label=\"Match the system\"\n description={`Currently resolving to ${resolvedAppearance()}.`}\n />\n </RadioGroup>\n </section>\n\n {/* --- 2. Themes ------------------------------------------------------ */}\n <Show when={resolvedAppearance() === 'light'}>\n <ThemeSection\n title=\"Light theme\"\n description=\"Shown when the appearance resolves to light.\"\n themes={LIGHT_THEMES}\n selectedId={selection().lightThemeId}\n onThemeSelect={(theme) => setSelection({ lightThemeId: theme.id })}\n />\n </Show>\n <Show when={resolvedAppearance() === 'dark'}>\n <ThemeSection\n title=\"Dark theme\"\n description=\"Shown when the appearance resolves to dark.\"\n themes={DARK_THEMES}\n selectedId={selection().darkThemeId}\n onThemeSelect={(theme) => setSelection({ darkThemeId: theme.id })}\n />\n </Show>\n\n {/* --- 3. Accent ------------------------------------------------------ */}\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <h2 class=\"text-base font-semibold tracking-tight\">Accent</h2>\n <p class=\"max-w-prose text-sm text-muted-foreground\">\n Colours the interactive roles — the primary button, the focus ring, a selected row — on\n top of the theme above. Every preset is measured against the surface it lands on, so\n none of them can make a label unreadable.\n </p>\n </header>\n <div role=\"radiogroup\" aria-label=\"Accent\" class=\"flex flex-wrap gap-2\">\n <For each={accentPresets}>\n {(preset) => (\n <Button\n as=\"button\"\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n role=\"radio\"\n aria-checked={selection().accent === preset.id}\n aria-label={preset.label}\n class={cn({\n 'border-ring ring-3 ring-primary-subtle': selection().accent === preset.id,\n })}\n onClick={() => setSelection({ accent: preset.id })}\n >\n <span\n aria-hidden=\"true\"\n class=\"size-3 rounded-full border border-border\"\n style={{\n 'background-color':\n preset.id === 'theme'\n ? 'var(--primary)'\n : `var(--accent-${preset.id}, ${preset.dark})`,\n }}\n />\n {preset.label}\n </Button>\n )}\n </For>\n </div>\n </section>\n\n {/* --- 4. Font -------------------------------------------------------- */}\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <h2 class=\"text-base font-semibold tracking-tight\">Typeface</h2>\n <p class=\"max-w-prose text-sm text-muted-foreground\">\n The interface face. Every option is self-hosted, so nothing is fetched at runtime and\n the choice survives going offline.\n </p>\n </header>\n <RadioGroup\n value={selection().font}\n onChange={(value) => setSelection({ font: value as string })}\n aria-label=\"Typeface\"\n >\n <For each={fontOptions}>\n {(option) => (\n <RadioGroupItem\n value={option.id}\n label={option.label}\n description={option.description}\n />\n )}\n </For>\n </RadioGroup>\n </section>\n </div>\n )\n}\n\nfunction ThemeSection(props: {\n title: string\n description: string\n themes: ReturnType<typeof themesForAppearance>\n selectedId: string\n onThemeSelect: (theme: ReturnType<typeof themesForAppearance>[number]) => void\n}) {\n return (\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <h2 class=\"text-base font-semibold tracking-tight\">{props.title}</h2>\n <p class=\"max-w-prose text-sm text-muted-foreground\">{props.description}</p>\n </header>\n <ThemePicker\n themes={props.themes}\n selectedId={props.selectedId}\n onThemeSelect={props.onThemeSelect}\n />\n </section>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"appearance-panel.js","names":["ComponentProps","For","Show","splitProps","accentPresets","fontOptions","themesForAppearance","cn","Button","RadioGroup","RadioGroupItem","ThemePicker","useTheme","Heading","AppearancePanelProps","LIGHT_THEMES","DARK_THEMES","AppearancePanel","props","local","rest","selection","setSelection","resolvedAppearance","_el$","_tmpl$","_el$2","firstChild","_el$3","_el$4","_el$5","nextSibling","_el$6","_el$7","_el$8","_el$9","_el$0","_el$1","_$spread","_$mergeProps","class","_$insert","_$createComponent","as","size","children","value","appearance","onChange","label","description","when","ThemeSection","title","themes","selectedId","lightThemeId","onThemeSelect","theme","id","darkThemeId","each","preset","type","variant","role","aria-checked","accent","aria-label","onClick","_el$10","_tmpl$2","_$effect","_$p","_$setStyleProperty","dark","_$memo","font","option","ReturnType","_el$11","_tmpl$3","_el$12","_el$13","_$mergeProps","_$createComponent","_$setStyleProperty","_$memo"],"sources":["../../../src/components/theme/appearance-panel.tsx"],"sourcesContent":["import type { ComponentProps } from 'solid-js'\nimport { For, Show, splitProps } from 'solid-js'\nimport { accentPresets, fontOptions } from '#lib/tokens'\nimport { themesForAppearance } from '#lib/themes'\nimport { cn } from '#lib/utils'\nimport { Button } from '../ui/button/button'\nimport { RadioGroup, RadioGroupItem } from '../ui/radio-group/radio-group'\nimport { ThemePicker } from './theme-picker'\nimport { useTheme } from './theme-provider'\nimport { Heading } from '../ui/typography'\n\n/**\n * AppearancePanel.\n *\n * The appearance page, as a component rather than as a screen each application\n * draws for itself. Two applications that both let a user choose a theme should\n * offer the *same* choices in the *same* arrangement — otherwise \"Adea\" and\n * \"Cortana\" are two products that happen to share a component library, which is\n * the opposite of what this system is for.\n *\n * Four axes, in the order a user thinks about them:\n *\n * 1. **Appearance** — light, dark, or follow the system.\n * 2. **Themes** — one for each appearance. Both are shown at once, because the\n * choice is per-appearance and hiding the other half makes it feel like one\n * setting that keeps changing.\n * 3. **Accent** — adea's presets, layered on whichever theme is active.\n * 4. **Font** — the interface face.\n *\n * The panel reads and writes the provider's preference and keeps no state of its\n * own, so it cannot disagree with what is applied.\n */\nexport type AppearancePanelProps = ComponentProps<'div'>\n\nconst LIGHT_THEMES = themesForAppearance('light')\nconst DARK_THEMES = themesForAppearance('dark')\n\nexport function AppearancePanel(props: AppearancePanelProps) {\n const [local, rest] = splitProps(props, ['class'])\n const { selection, setSelection, resolvedAppearance } = useTheme()\n\n return (\n <div data-slot=\"appearance-panel\" class={cn('flex flex-col gap-8', local.class)} {...rest}>\n {/* --- 1. Appearance ------------------------------------------------- */}\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <Heading as=\"h2\" size=\"card\">\n Appearance\n </Heading>\n <p class=\"max-w-prose text-sm text-muted-foreground\">\n Follow the system, or pin one. The theme below is chosen per appearance, so switching at\n sunset does not make you choose again.\n </p>\n </header>\n <RadioGroup\n value={selection().appearance}\n onChange={(value) => setSelection({ appearance: value as 'light' | 'dark' | 'system' })}\n aria-label=\"Appearance\"\n >\n <RadioGroupItem value=\"light\" label=\"Light\" description=\"Always the light theme.\" />\n <RadioGroupItem value=\"dark\" label=\"Dark\" description=\"Always the dark theme.\" />\n <RadioGroupItem\n value=\"system\"\n label=\"Match the system\"\n description={`Currently resolving to ${resolvedAppearance()}.`}\n />\n </RadioGroup>\n </section>\n\n {/* --- 2. Themes ------------------------------------------------------ */}\n <Show when={resolvedAppearance() === 'light'}>\n <ThemeSection\n title=\"Light theme\"\n description=\"Shown when the appearance resolves to light.\"\n themes={LIGHT_THEMES}\n selectedId={selection().lightThemeId}\n onThemeSelect={(theme) => setSelection({ lightThemeId: theme.id })}\n />\n </Show>\n <Show when={resolvedAppearance() === 'dark'}>\n <ThemeSection\n title=\"Dark theme\"\n description=\"Shown when the appearance resolves to dark.\"\n themes={DARK_THEMES}\n selectedId={selection().darkThemeId}\n onThemeSelect={(theme) => setSelection({ darkThemeId: theme.id })}\n />\n </Show>\n\n {/* --- 3. Accent ------------------------------------------------------ */}\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <Heading as=\"h2\" size=\"card\">\n Accent\n </Heading>\n <p class=\"max-w-prose text-sm text-muted-foreground\">\n Colours the interactive roles — the primary button, the focus ring, a selected row — on\n top of the theme above. Every preset is measured against the surface it lands on, so\n none of them can make a label unreadable.\n </p>\n </header>\n <div role=\"radiogroup\" aria-label=\"Accent\" class=\"flex flex-wrap gap-2\">\n <For each={accentPresets}>\n {(preset) => (\n <Button\n as=\"button\"\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n role=\"radio\"\n aria-checked={selection().accent === preset.id}\n aria-label={preset.label}\n class={cn({\n 'border-ring ring-3 ring-primary-subtle': selection().accent === preset.id,\n })}\n onClick={() => setSelection({ accent: preset.id })}\n >\n <span\n aria-hidden=\"true\"\n class=\"size-3 rounded-full border border-border\"\n style={{\n 'background-color':\n preset.id === 'theme'\n ? 'var(--primary)'\n : `var(--accent-${preset.id}, ${preset.dark})`,\n }}\n />\n {preset.label}\n </Button>\n )}\n </For>\n </div>\n </section>\n\n {/* --- 4. Font -------------------------------------------------------- */}\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <Heading as=\"h2\" size=\"card\">\n Typeface\n </Heading>\n <p class=\"max-w-prose text-sm text-muted-foreground\">\n The interface face. Every option is self-hosted, so nothing is fetched at runtime and\n the choice survives going offline.\n </p>\n </header>\n <RadioGroup\n value={selection().font}\n onChange={(value) => setSelection({ font: value as string })}\n aria-label=\"Typeface\"\n >\n <For each={fontOptions}>\n {(option) => (\n <RadioGroupItem\n value={option.id}\n label={option.label}\n description={option.description}\n />\n )}\n </For>\n </RadioGroup>\n </section>\n </div>\n )\n}\n\nfunction ThemeSection(props: {\n title: string\n description: string\n themes: ReturnType<typeof themesForAppearance>\n selectedId: string\n onThemeSelect: (theme: ReturnType<typeof themesForAppearance>[number]) => void\n}) {\n return (\n <section class=\"flex flex-col gap-3\">\n <header class=\"flex flex-col gap-0.5\">\n <Heading as=\"h2\" size=\"card\">\n {props.title}\n </Heading>\n <p class=\"max-w-prose text-sm text-muted-foreground\">{props.description}</p>\n </header>\n <ThemePicker\n themes={props.themes}\n selectedId={props.selectedId}\n onThemeSelect={props.onThemeSelect}\n />\n </section>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;AAkCA,IAAMe,eAAeT,oBAAoB,OAAO;AAChD,IAAMU,cAAcV,oBAAoB,MAAM;AAE9C,SAAgBW,gBAAgBC,OAA6B;CAC3D,MAAM,CAACC,OAAOC,QAAQjB,WAAWe,OAAO,CAAC,OAAO,CAAC;CACjD,MAAM,EAAEG,WAAWC,cAAcC,uBAAuBX,SAAS;CAEjE,cAAA;EAAA,IAAAY,OAAAC,OAAA,GAAAC,QAAAF,KAAAG,YAAAC,QAAAF,MAAAC,YAAAE,QAAAD,MAAAD,YAAAG,QAAAJ,MAAAK,aAAAC,QAAAF,MAAAH,YAAAM,QAAAD,MAAAL,YAAAO,QAAAF,MAAAD,aAAAI,QAAAL,MAAAC,aAAAK,QAAAD,MAAAR,YAAAU,QAAAD,MAAAT;EAAAW,OAAAd,MAAAe,WAAA,EAAA,KAAA,WAAA;GAAA,OAC2ChC,GAAG,uBAAuBY,MAAMqB,KAAK;EAAC,EAAA,GAAMpB,IAAI,GAAA,OAAA,IAAA;EAAAqB,OAAAb,OAAAc,gBAIlF7B,SAAO;GAAC8B,IAAE;GAAMC,MAAI;GAAAC,UAAA;EAAA,CAAA,GAAAhB,KAAA;EAAAY,OAAAf,OAAAgB,gBAQtBjC,YAAU;GAAA,IACTqC,QAAK;IAAA,OAAEzB,UAAU,CAAC,CAAC0B;GAAU;GAC7BC,WAAWF,UAAUxB,aAAa,EAAEyB,YAAYD,MAAqC,CAAC;GAAC,cAAA;GAAA,IAAAD,WAAA;IAAA,OAAA;KAAAH,gBAGtFhC,gBAAc;MAACoC,OAAK;MAASG,OAAK;MAASC,aAAW;KAAA,CAAA;KAAAR,gBACtDhC,gBAAc;MAACoC,OAAK;MAAQG,OAAK;MAAQC,aAAW;KAAA,CAAA;KAAAR,gBACpDhC,gBAAc;MACboC,OAAK;MACLG,OAAK;MAAA,IACLC,cAAW;OAAA,OAAE,0BAA0B3B,mBAAmB,EAAC;MAAG;KAAA,CAAA;IAAA;GAAA;EAAA,CAAA,GAAA,IAAA;EAAAkB,OAAAjB,MAAAkB,gBAMnExC,MAAI;GAAA,IAACiD,OAAI;IAAA,OAAE5B,mBAAmB,MAAM;GAAO;GAAA,IAAAsB,WAAA;IAAA,OAAAH,gBACzCU,cAAY;KACXC,OAAK;KACLH,aAAW;KACXI,QAAQvC;KAAY,IACpBwC,aAAU;MAAA,OAAElC,UAAU,CAAC,CAACmC;KAAY;KACpCC,gBAAgBC,UAAUpC,aAAa,EAAEkC,cAAcE,MAAMC,GAAG,CAAC;IAAC,CAAA;GAAA;EAAA,CAAA,GAAA7B,KAAA;EAAAW,OAAAjB,MAAAkB,gBAGrExC,MAAI;GAAA,IAACiD,OAAI;IAAA,OAAE5B,mBAAmB,MAAM;GAAM;GAAA,IAAAsB,WAAA;IAAA,OAAAH,gBACxCU,cAAY;KACXC,OAAK;KACLH,aAAW;KACXI,QAAQtC;KAAW,IACnBuC,aAAU;MAAA,OAAElC,UAAU,CAAC,CAACuC;KAAW;KACnCH,gBAAgBC,UAAUpC,aAAa,EAAEsC,aAAaF,MAAMC,GAAG,CAAC;IAAC,CAAA;GAAA;EAAA,CAAA,GAAA7B,KAAA;EAAAW,OAAAT,OAAAU,gBAOhE7B,SAAO;GAAC8B,IAAE;GAAMC,MAAI;GAAAC,UAAA;EAAA,CAAA,GAAAZ,KAAA;EAAAQ,OAAAP,OAAAQ,gBAUpBzC,KAAG;GAAC4D,MAAMzD;GAAayC,WACpBiB,WAAMpB,gBACLlC,QAAM;IACLmC,IAAE;IACFoB,MAAI;IACJC,SAAO;IACPpB,MAAI;IACJqB,MAAI;IAAA,KAAA,kBAAA;KAAA,OACU5C,UAAU,CAAC,CAAC8C,WAAWL,OAAOH;IAAE;IAAA,KAAA,gBAAA;KAAA,OAClCG,OAAOb;IAAK;IAAA,KAAA,WAAA;KAAA,OACjB1C,GAAG,EACR,0CAA0Cc,UAAU,CAAC,CAAC8C,WAAWL,OAAOH,GAC1E,CAAC;IAAC;IACFU,eAAe/C,aAAa,EAAE6C,QAAQL,OAAOH,GAAG,CAAC;IAAC,IAAAd,WAAA;KAAA,OAAA,QAAA;MAAA,IAAAyB,SAAAC,QAAA;MAAAC,QAAAC,QAAAC,iBAAAJ,QAAA,oBAO5CR,OAAOH,OAAO,UACV,mBACA,gBAAgBG,OAAOH,GAAE,IAAKG,OAAOa,KAAI,EAAG,CAAA;MAAA,OAAAL;KAAA,EAAA,CAAA,GAAAM,WAGrDd,OAAOb,KAAK,CAAA;IAAA;GAAA,CAAA;EAEhB,CAAA,CAAA;EAAAR,OAAAL,OAAAM,gBAQF7B,SAAO;GAAC8B,IAAE;GAAMC,MAAI;GAAAC,UAAA;EAAA,CAAA,GAAAR,KAAA;EAAAI,OAAAN,OAAAO,gBAQtBjC,YAAU;GAAA,IACTqC,QAAK;IAAA,OAAEzB,UAAU,CAAC,CAACwD;GAAI;GACvB7B,WAAWF,UAAUxB,aAAa,EAAEuD,MAAM/B,MAAgB,CAAC;GAAC,cAAA;GAAA,IAAAD,WAAA;IAAA,OAAAH,gBAG3DzC,KAAG;KAAC4D,MAAMxD;KAAWwC,WAClBiC,WAAMpC,gBACLhC,gBAAc;MAAA,IACboC,QAAK;OAAA,OAAEgC,OAAOnB;MAAE;MAAA,IAChBV,QAAK;OAAA,OAAE6B,OAAO7B;MAAK;MAAA,IACnBC,cAAW;OAAA,OAAE4B,OAAO5B;MAAW;KAAA,CAAA;IAElC,CAAA;GAAA;EAAA,CAAA,GAAA,IAAA;EAAA,OAAA1B;CAAA,EAAA,CAAA;AAMb;AAEA,SAAS4B,aAAalC,OAMnB;CACD,cAAA;EAAA,IAAA8D,SAAAC,QAAA,GAAAC,SAAAF,OAAArD,YAAAwD,SAAAD,OAAAvD;EAAAc,OAAAyC,QAAAxC,gBAGO7B,SAAO;GAAC8B,IAAE;GAAMC,MAAI;GAAA,IAAAC,WAAA;IAAA,OAClB3B,MAAMmC;GAAK;EAAA,CAAA,GAAA8B,MAAA;EAAA1C,OAAA0C,cAEwCjE,MAAMgC,WAAW;EAAAT,OAAAuC,QAAAtC,gBAExE/B,aAAW;GAAA,IACV2C,SAAM;IAAA,OAAEpC,MAAMoC;GAAM;GAAA,IACpBC,aAAU;IAAA,OAAErC,MAAMqC;GAAU;GAAA,IAC5BE,gBAAa;IAAA,OAAEvC,MAAMuC;GAAa;EAAA,CAAA,GAAA,IAAA;EAAA,OAAAuB;CAAA,EAAA,CAAA;AAI1C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alert-dialog.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/alert-dialog/alert-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,IAAI,kBAAkB,EACjC,OAAO,IAAI,yBAAyB,EACrC,MAAM,4BAA4B,CAAA;AAEnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"alert-dialog.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/alert-dialog/alert-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,IAAI,kBAAkB,EACjC,OAAO,IAAI,yBAAyB,EACrC,MAAM,4BAA4B,CAAA;AAEnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAM9C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,kBAAkB,CAAC,kCAE3E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,kBAAkB,CAAC,OAAO,CAAC,kCAE1F;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,kBAAkB,CAAC,MAAM,CAAC,kCAExF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,kBAAkB,CAAC,OAAO,CAAC,kCAY1F;AA2BD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,yBAAyB,CAAC,kCAezF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,kCAS7D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,kCAS7D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,kBAAkB,CAAC,KAAK,CAAC,kCAQtF;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,cAAc,CAAC,OAAO,kBAAkB,CAAC,WAAW,CAAC,kCAS7D;AAsCD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,kBAAkB,CAAC,WAAW,CAAC,kCAE7F;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,kBAAkB,CAAC,WAAW,CAAC,kCAE7F"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { cn } from "../../../lib/utils.js";
|
|
2
2
|
import { overlayMotion, overlayPositioner, overlayScrim, overlaySurface } from "../../../lib/overlay.js";
|
|
3
|
+
import { headingVariants } from "../typography/typography.js";
|
|
3
4
|
import { className, createComponent, insert, mergeProps, spread, template, use } from "solid-js/web";
|
|
4
5
|
import { createEffect, createSignal, splitProps } from "solid-js";
|
|
5
6
|
import { AlertDialog, Content } from "@kobalte/core/alert-dialog";
|
|
@@ -98,7 +99,10 @@ function AlertDialogFooter(props) {
|
|
|
98
99
|
function AlertDialogTitle(props) {
|
|
99
100
|
const [local, rest] = splitProps(props, ["class"]);
|
|
100
101
|
return createComponent(AlertDialog.Title, mergeProps({ get ["class"]() {
|
|
101
|
-
return cn(
|
|
102
|
+
return cn(headingVariants({
|
|
103
|
+
size: "card",
|
|
104
|
+
leading: "none"
|
|
105
|
+
}), local.class);
|
|
102
106
|
} }, rest));
|
|
103
107
|
}
|
|
104
108
|
function AlertDialogDescription(props) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alert-dialog.js","names":["AlertDialog","KobalteAlertDialog","Content","KobalteAlertDialogContent","ComponentProps","createEffect","createSignal","splitProps","overlayMotion","overlayPositioner","overlayScrim","overlaySurface","cn","props","_$createComponent","AlertDialogTrigger","Trigger","AlertDialogPortal","Portal","AlertDialogOverlay","Overlay","local","rest","_$mergeProps","class","blockDismissal","onEscapeKeyDown","event","KeyboardEvent","preventDefault","onPointerDownOutside","Event","onFocusOutside","onInteractOutside","const","AlertDialogContent","children","_el$","_tmpl$","_$className","_$insert","AlertDialogHeader","_el$2","_tmpl$2","_$spread","AlertDialogFooter","_el$3","_tmpl$3","AlertDialogTitle","Title","AlertDialogDescription","Description","AlertDialogChoice","CloseButton","wrapper","setWrapper","HTMLSpanElement","root","undefined","querySelector","removeAttribute","_el$4","_tmpl$4","_$use","AlertDialogAction","AlertDialogCancel","AlertDialog","_$createComponent","KobalteAlertDialog","_$mergeProps","KobalteAlertDialogContent"],"sources":["../../../../src/components/ui/alert-dialog/alert-dialog.tsx"],"sourcesContent":["import {\n AlertDialog as KobalteAlertDialog,\n Content as KobalteAlertDialogContent,\n} from '@kobalte/core/alert-dialog'\n// Use the alert-specific export rather than DialogRoot.Content, which other imports can replace.\nimport type { ComponentProps } from 'solid-js'\nimport { createEffect, createSignal, splitProps } from 'solid-js'\nimport { overlayMotion, overlayPositioner, overlayScrim, overlaySurface } from '#lib/overlay'\nimport { cn } from '#lib/utils'\n\n/**\n * AlertDialog.\n *\n * A dialog that cannot be dismissed by accident: Escape and a click on the scrim\n * do nothing, and the user must choose one of the actions. That is the whole\n * difference from Dialog, and it is why this exists as its own component rather\n * than a prop — a caller has to reach for it deliberately.\n *\n * The consequence is a rule of use: this is for confirming a destructive or\n * irreversible step. Wrapping an ordinary form in an AlertDialog traps someone who\n * wants to back out.\n *\n * There is deliberately no close button in the corner. An X has no label, and the\n * point of this surface is that every exit is a named choice.\n */\nexport function AlertDialog(props: ComponentProps<typeof KobalteAlertDialog>) {\n return <KobalteAlertDialog {...props} />\n}\n\nexport function AlertDialogTrigger(props: ComponentProps<typeof KobalteAlertDialog.Trigger>) {\n return <KobalteAlertDialog.Trigger {...props} />\n}\n\nexport function AlertDialogPortal(props: ComponentProps<typeof KobalteAlertDialog.Portal>) {\n return <KobalteAlertDialog.Portal {...props} />\n}\n\nexport function AlertDialogOverlay(props: ComponentProps<typeof KobalteAlertDialog.Overlay>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteAlertDialog.Overlay\n class={cn(\n overlayScrim,\n 'data-expanded:animate-in data-expanded:fade-in-0 data-closed:animate-out data-closed:fade-out-0',\n local.class\n )}\n {...rest}\n />\n )\n}\n\n/**\n * The panel.\n *\n * Kobalte's `AlertDialog.Content` is `Dialog.Content` with `role=\"alertdialog\"`\n * and nothing else — Escape and an outside click dismiss it exactly as they\n * dismiss a Dialog. That is a real gap in the primitive, so the blocking is\n * implemented here, and it is the whole difference between this component and a\n * Dialog:\n *\n * - Escape is prevented, because a key that closes a confirmation is a key that\n * makes \"confirm\" meaningless.\n * - Pointer and focus interactions outside are prevented, including the scrim\n * click, for the same reason.\n *\n * There is deliberately no prop to turn this off. A surface that can be escaped\n * accidentally does not need to be an AlertDialog; it is a Dialog, and using this\n * one would be a claim about the flow that is not true.\n */\nconst blockDismissal = {\n onEscapeKeyDown: (event: KeyboardEvent) => event.preventDefault(),\n onPointerDownOutside: (event: Event) => event.preventDefault(),\n onFocusOutside: (event: Event) => event.preventDefault(),\n onInteractOutside: (event: Event) => event.preventDefault(),\n} as const\n\nexport function AlertDialogContent(props: ComponentProps<typeof KobalteAlertDialogContent>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <KobalteAlertDialog.Portal>\n <AlertDialogOverlay />\n <div class={overlayPositioner}>\n <KobalteAlertDialogContent\n {...blockDismissal}\n class={cn(overlaySurface, overlayMotion, 'grid w-full max-w-md gap-4 p-5', local.class)}\n {...rest}\n />\n </div>\n </KobalteAlertDialog.Portal>\n )\n}\n\nexport function AlertDialogHeader(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"alert-dialog-header\"\n class={cn('flex flex-col gap-1.5 text-start', local.class)}\n {...rest}\n />\n )\n}\n\nexport function AlertDialogFooter(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"alert-dialog-footer\"\n class={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', local.class)}\n {...rest}\n />\n )\n}\n\nexport function AlertDialogTitle(props: ComponentProps<typeof KobalteAlertDialog.Title>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteAlertDialog.Title\n class={cn('text-base leading-none font-semibold tracking-tight', local.class)}\n {...rest}\n />\n )\n}\n\nexport function AlertDialogDescription(\n props: ComponentProps<typeof KobalteAlertDialog.Description>\n) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteAlertDialog.Description\n class={cn('text-muted-foreground text-sm', local.class)}\n {...rest}\n />\n )\n}\n\n/**\n * One of the dialog's two named choices.\n *\n * Kobalte labels its close button \"Dismiss\" by default, because a generic close\n * button is usually an icon with no text of its own. In an AlertDialog it is\n * something else: the named choices. An `aria-label` there *replaces* the visible\n * text, so a screen reader hears \"Dismiss\" twice and the user cannot tell the\n * destructive action from the safe one.\n *\n * The injected label is removed rather than overridden with an empty one. An empty\n * `aria-label` is not reliably ignored — some name computations treat its presence\n * as an explicit empty name, which leaves the button unnamed — so the attribute\n * has to go, and the visible text becomes the name. A caller whose button is an\n * icon passes its own `aria-label`, and that one is left alone.\n *\n * Applied through a layout-neutral wrapper because Kobalte keeps the `ref` for its\n * own dismissable layer and does not forward it. The wrapper is `display: contents`\n * so the button remains the flex item its parent lays out.\n */\nfunction AlertDialogChoice(props: ComponentProps<typeof KobalteAlertDialog.CloseButton>) {\n const [local, rest] = splitProps(props, ['class', 'aria-label'])\n const [wrapper, setWrapper] = createSignal<HTMLSpanElement>()\n\n createEffect(() => {\n const root = wrapper()\n if (!root || local['aria-label'] !== undefined) return\n root.querySelector('button')?.removeAttribute('aria-label')\n })\n\n return (\n <span ref={setWrapper} class=\"contents\">\n <KobalteAlertDialog.CloseButton class={cn(local.class)} {...rest} />\n </span>\n )\n}\n\nexport function AlertDialogAction(props: ComponentProps<typeof KobalteAlertDialog.CloseButton>) {\n return <AlertDialogChoice {...props} />\n}\n\nexport function AlertDialogCancel(props: ComponentProps<typeof KobalteAlertDialog.CloseButton>) {\n return <AlertDialogChoice {...props} />\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"alert-dialog.js","names":["AlertDialog","KobalteAlertDialog","Content","KobalteAlertDialogContent","ComponentProps","createEffect","createSignal","splitProps","overlayMotion","overlayPositioner","overlayScrim","overlaySurface","cn","headingVariants","props","_$createComponent","AlertDialogTrigger","Trigger","AlertDialogPortal","Portal","AlertDialogOverlay","Overlay","local","rest","_$mergeProps","class","blockDismissal","onEscapeKeyDown","event","KeyboardEvent","preventDefault","onPointerDownOutside","Event","onFocusOutside","onInteractOutside","const","AlertDialogContent","children","_el$","_tmpl$","_$className","_$insert","AlertDialogHeader","_el$2","_tmpl$2","_$spread","AlertDialogFooter","_el$3","_tmpl$3","AlertDialogTitle","Title","size","leading","AlertDialogDescription","Description","AlertDialogChoice","CloseButton","wrapper","setWrapper","HTMLSpanElement","root","undefined","querySelector","removeAttribute","_el$4","_tmpl$4","_$use","AlertDialogAction","AlertDialogCancel","AlertDialog","_$createComponent","KobalteAlertDialog","_$mergeProps","KobalteAlertDialogContent"],"sources":["../../../../src/components/ui/alert-dialog/alert-dialog.tsx"],"sourcesContent":["import {\n AlertDialog as KobalteAlertDialog,\n Content as KobalteAlertDialogContent,\n} from '@kobalte/core/alert-dialog'\n// Use the alert-specific export rather than DialogRoot.Content, which other imports can replace.\nimport type { ComponentProps } from 'solid-js'\nimport { createEffect, createSignal, splitProps } from 'solid-js'\nimport { overlayMotion, overlayPositioner, overlayScrim, overlaySurface } from '#lib/overlay'\nimport { cn } from '#lib/utils'\nimport { headingVariants } from '../typography'\n\n/**\n * AlertDialog.\n *\n * A dialog that cannot be dismissed by accident: Escape and a click on the scrim\n * do nothing, and the user must choose one of the actions. That is the whole\n * difference from Dialog, and it is why this exists as its own component rather\n * than a prop — a caller has to reach for it deliberately.\n *\n * The consequence is a rule of use: this is for confirming a destructive or\n * irreversible step. Wrapping an ordinary form in an AlertDialog traps someone who\n * wants to back out.\n *\n * There is deliberately no close button in the corner. An X has no label, and the\n * point of this surface is that every exit is a named choice.\n */\nexport function AlertDialog(props: ComponentProps<typeof KobalteAlertDialog>) {\n return <KobalteAlertDialog {...props} />\n}\n\nexport function AlertDialogTrigger(props: ComponentProps<typeof KobalteAlertDialog.Trigger>) {\n return <KobalteAlertDialog.Trigger {...props} />\n}\n\nexport function AlertDialogPortal(props: ComponentProps<typeof KobalteAlertDialog.Portal>) {\n return <KobalteAlertDialog.Portal {...props} />\n}\n\nexport function AlertDialogOverlay(props: ComponentProps<typeof KobalteAlertDialog.Overlay>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteAlertDialog.Overlay\n class={cn(\n overlayScrim,\n 'data-expanded:animate-in data-expanded:fade-in-0 data-closed:animate-out data-closed:fade-out-0',\n local.class\n )}\n {...rest}\n />\n )\n}\n\n/**\n * The panel.\n *\n * Kobalte's `AlertDialog.Content` is `Dialog.Content` with `role=\"alertdialog\"`\n * and nothing else — Escape and an outside click dismiss it exactly as they\n * dismiss a Dialog. That is a real gap in the primitive, so the blocking is\n * implemented here, and it is the whole difference between this component and a\n * Dialog:\n *\n * - Escape is prevented, because a key that closes a confirmation is a key that\n * makes \"confirm\" meaningless.\n * - Pointer and focus interactions outside are prevented, including the scrim\n * click, for the same reason.\n *\n * There is deliberately no prop to turn this off. A surface that can be escaped\n * accidentally does not need to be an AlertDialog; it is a Dialog, and using this\n * one would be a claim about the flow that is not true.\n */\nconst blockDismissal = {\n onEscapeKeyDown: (event: KeyboardEvent) => event.preventDefault(),\n onPointerDownOutside: (event: Event) => event.preventDefault(),\n onFocusOutside: (event: Event) => event.preventDefault(),\n onInteractOutside: (event: Event) => event.preventDefault(),\n} as const\n\nexport function AlertDialogContent(props: ComponentProps<typeof KobalteAlertDialogContent>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <KobalteAlertDialog.Portal>\n <AlertDialogOverlay />\n <div class={overlayPositioner}>\n <KobalteAlertDialogContent\n {...blockDismissal}\n class={cn(overlaySurface, overlayMotion, 'grid w-full max-w-md gap-4 p-5', local.class)}\n {...rest}\n />\n </div>\n </KobalteAlertDialog.Portal>\n )\n}\n\nexport function AlertDialogHeader(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"alert-dialog-header\"\n class={cn('flex flex-col gap-1.5 text-start', local.class)}\n {...rest}\n />\n )\n}\n\nexport function AlertDialogFooter(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"alert-dialog-footer\"\n class={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', local.class)}\n {...rest}\n />\n )\n}\n\nexport function AlertDialogTitle(props: ComponentProps<typeof KobalteAlertDialog.Title>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteAlertDialog.Title\n class={cn(headingVariants({ size: 'card', leading: 'none' }), local.class)}\n {...rest}\n />\n )\n}\n\nexport function AlertDialogDescription(\n props: ComponentProps<typeof KobalteAlertDialog.Description>\n) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteAlertDialog.Description\n class={cn('text-muted-foreground text-sm', local.class)}\n {...rest}\n />\n )\n}\n\n/**\n * One of the dialog's two named choices.\n *\n * Kobalte labels its close button \"Dismiss\" by default, because a generic close\n * button is usually an icon with no text of its own. In an AlertDialog it is\n * something else: the named choices. An `aria-label` there *replaces* the visible\n * text, so a screen reader hears \"Dismiss\" twice and the user cannot tell the\n * destructive action from the safe one.\n *\n * The injected label is removed rather than overridden with an empty one. An empty\n * `aria-label` is not reliably ignored — some name computations treat its presence\n * as an explicit empty name, which leaves the button unnamed — so the attribute\n * has to go, and the visible text becomes the name. A caller whose button is an\n * icon passes its own `aria-label`, and that one is left alone.\n *\n * Applied through a layout-neutral wrapper because Kobalte keeps the `ref` for its\n * own dismissable layer and does not forward it. The wrapper is `display: contents`\n * so the button remains the flex item its parent lays out.\n */\nfunction AlertDialogChoice(props: ComponentProps<typeof KobalteAlertDialog.CloseButton>) {\n const [local, rest] = splitProps(props, ['class', 'aria-label'])\n const [wrapper, setWrapper] = createSignal<HTMLSpanElement>()\n\n createEffect(() => {\n const root = wrapper()\n if (!root || local['aria-label'] !== undefined) return\n root.querySelector('button')?.removeAttribute('aria-label')\n })\n\n return (\n <span ref={setWrapper} class=\"contents\">\n <KobalteAlertDialog.CloseButton class={cn(local.class)} {...rest} />\n </span>\n )\n}\n\nexport function AlertDialogAction(props: ComponentProps<typeof KobalteAlertDialog.CloseButton>) {\n return <AlertDialogChoice {...props} />\n}\n\nexport function AlertDialogCancel(props: ComponentProps<typeof KobalteAlertDialog.CloseButton>) {\n return <AlertDialogChoice {...props} />\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/card/card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/card/card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAKnD;;;;;;;;;;;;GAYG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,eAYhD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,eAKtD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,eASrD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,eAS3D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,eAStD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,eAGvD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,eAGtD;AAED,MAAM,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { headingVariants } from "../typography/typography.js";
|
|
2
3
|
import { mergeProps, spread, template } from "solid-js/web";
|
|
3
4
|
import { splitProps } from "solid-js";
|
|
4
5
|
//#region src/components/ui/card/card.tsx
|
|
@@ -47,7 +48,10 @@ function CardTitle(props) {
|
|
|
47
48
|
return (() => {
|
|
48
49
|
var _el$3 = _tmpl$3();
|
|
49
50
|
spread(_el$3, mergeProps({ get ["class"]() {
|
|
50
|
-
return cn(
|
|
51
|
+
return cn(headingVariants({
|
|
52
|
+
size: "card",
|
|
53
|
+
leading: "none"
|
|
54
|
+
}), local.class);
|
|
51
55
|
} }, rest), false, false);
|
|
52
56
|
return _el$3;
|
|
53
57
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.js","names":["ComponentProps","JSX","splitProps","cn","Card","props","local","rest","_el$","_tmpl$","_$spread","_$mergeProps","class","CardHeader","_el$2","_tmpl$2","CardTitle","_el$3","_tmpl$3","CardDescription","_el$4","_tmpl$4","CardAction","_el$5","_tmpl$5","CardContent","_el$6","_tmpl$6","CardFooter","_el$7","_tmpl$7","CardProps","HTMLAttributes","HTMLDivElement","_$mergeProps"],"sources":["../../../../src/components/ui/card/card.tsx"],"sourcesContent":["import type { ComponentProps, JSX } from 'solid-js'\nimport { splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/**\n * Card.\n *\n * A surface that sits on the canvas. Every card carries its own edge — a\n * border — because in the light theme `--card` is one faint step off a white\n * `--background`, and a borderless card there all but disappears. Making the border\n * structural rather than optional is what stops one app's cards from reading\n * as floating panels and another's as nothing at all.\n *\n * The parts are separate components rather than a template because a card's\n * header, content and footer have different padding on purpose: the header and\n * footer are tight, the content breathes.\n */\nexport function Card(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"card\"\n class={cn(\n 'bg-card text-card-foreground flex flex-col gap-4 rounded-xl border border-border py-4 shadow-xs',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function CardHeader(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div data-slot=\"card-header\" class={cn('flex flex-col gap-1 px-4', local.class)} {...rest} />\n )\n}\n\nexport function CardTitle(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"card-title\"\n class={cn('
|
|
1
|
+
{"version":3,"file":"card.js","names":["ComponentProps","JSX","splitProps","cn","headingVariants","Card","props","local","rest","_el$","_tmpl$","_$spread","_$mergeProps","class","CardHeader","_el$2","_tmpl$2","CardTitle","_el$3","_tmpl$3","size","leading","CardDescription","_el$4","_tmpl$4","CardAction","_el$5","_tmpl$5","CardContent","_el$6","_tmpl$6","CardFooter","_el$7","_tmpl$7","CardProps","HTMLAttributes","HTMLDivElement","_$mergeProps"],"sources":["../../../../src/components/ui/card/card.tsx"],"sourcesContent":["import type { ComponentProps, JSX } from 'solid-js'\nimport { splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\nimport { headingVariants } from '../typography'\n\n/**\n * Card.\n *\n * A surface that sits on the canvas. Every card carries its own edge — a\n * border — because in the light theme `--card` is one faint step off a white\n * `--background`, and a borderless card there all but disappears. Making the border\n * structural rather than optional is what stops one app's cards from reading\n * as floating panels and another's as nothing at all.\n *\n * The parts are separate components rather than a template because a card's\n * header, content and footer have different padding on purpose: the header and\n * footer are tight, the content breathes.\n */\nexport function Card(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"card\"\n class={cn(\n 'bg-card text-card-foreground flex flex-col gap-4 rounded-xl border border-border py-4 shadow-xs',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function CardHeader(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div data-slot=\"card-header\" class={cn('flex flex-col gap-1 px-4', local.class)} {...rest} />\n )\n}\n\nexport function CardTitle(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"card-title\"\n class={cn(headingVariants({ size: 'card', leading: 'none' }), local.class)}\n {...rest}\n />\n )\n}\n\nexport function CardDescription(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"card-description\"\n class={cn('text-muted-foreground text-sm', local.class)}\n {...rest}\n />\n )\n}\n\nexport function CardAction(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"card-action\"\n class={cn('col-start-2 row-span-2 row-start-1 self-start justify-self-end', local.class)}\n {...rest}\n />\n )\n}\n\nexport function CardContent(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return <div data-slot=\"card-content\" class={cn('px-4', local.class)} {...rest} />\n}\n\nexport function CardFooter(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return <div data-slot=\"card-footer\" class={cn('flex items-center px-4', local.class)} {...rest} />\n}\n\nexport type CardProps = ComponentProps<'div'> & JSX.HTMLAttributes<HTMLDivElement>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,SAAgBK,KAAKC,OAA8B;CACjD,MAAM,CAACC,OAAOC,QAAQN,WAAWI,OAAO,CAAC,OAAO,CAAC;CACjD,cAAA;EAAA,IAAAG,OAAAC,OAAA;EAAAC,OAAAF,MAAAG,WAAA,EAAA,KAAA,WAAA;GAAA,OAGWT,GACL,mGACAI,MAAMM,KACR;EAAC,EAAA,GACGL,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAC;CAAA,EAAA,CAAA;AAGd;AAEA,SAAgBK,WAAWR,OAA8B;CACvD,MAAM,CAACC,OAAOC,QAAQN,WAAWI,OAAO,CAAC,OAAO,CAAC;CACjD,cAAA;EAAA,IAAAS,QAAAC,QAAA;EAAAL,OAAAI,OAAAH,WAAA,EAAA,KAAA,WAAA;GAAA,OACsCT,GAAG,4BAA4BI,MAAMM,KAAK;EAAC,EAAA,GAAML,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAO;CAAA,EAAA,CAAA;AAE7F;AAEA,SAAgBE,UAAUX,OAA8B;CACtD,MAAM,CAACC,OAAOC,QAAQN,WAAWI,OAAO,CAAC,OAAO,CAAC;CACjD,cAAA;EAAA,IAAAY,QAAAC,QAAA;EAAAR,OAAAO,OAAAN,WAAA,EAAA,KAAA,WAAA;GAAA,OAGWT,GAAGC,gBAAgB;IAAEgB,MAAM;IAAQC,SAAS;GAAO,CAAC,GAAGd,MAAMM,KAAK;EAAC,EAAA,GACtEL,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAU;CAAA,EAAA,CAAA;AAGd;AAEA,SAAgBI,gBAAgBhB,OAA8B;CAC5D,MAAM,CAACC,OAAOC,QAAQN,WAAWI,OAAO,CAAC,OAAO,CAAC;CACjD,cAAA;EAAA,IAAAiB,QAAAC,QAAA;EAAAb,OAAAY,OAAAX,WAAA,EAAA,KAAA,WAAA;GAAA,OAGWT,GAAG,iCAAiCI,MAAMM,KAAK;EAAC,EAAA,GACnDL,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAe;CAAA,EAAA,CAAA;AAGd;AAEA,SAAgBE,WAAWnB,OAA8B;CACvD,MAAM,CAACC,OAAOC,QAAQN,WAAWI,OAAO,CAAC,OAAO,CAAC;CACjD,cAAA;EAAA,IAAAoB,QAAAC,QAAA;EAAAhB,OAAAe,OAAAd,WAAA,EAAA,KAAA,WAAA;GAAA,OAGWT,GAAG,kEAAkEI,MAAMM,KAAK;EAAC,EAAA,GACpFL,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAkB;CAAA,EAAA,CAAA;AAGd;AAEA,SAAgBE,YAAYtB,OAA8B;CACxD,MAAM,CAACC,OAAOC,QAAQN,WAAWI,OAAO,CAAC,OAAO,CAAC;CACjD,cAAA;EAAA,IAAAuB,QAAAC,QAAA;EAAAnB,OAAAkB,OAAAjB,WAAA,EAAA,KAAA,WAAA;GAAA,OAA4CT,GAAG,QAAQI,MAAMM,KAAK;EAAC,EAAA,GAAML,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAqB;CAAA,EAAA,CAAA;AAC/E;AAEA,SAAgBE,WAAWzB,OAA8B;CACvD,MAAM,CAACC,OAAOC,QAAQN,WAAWI,OAAO,CAAC,OAAO,CAAC;CACjD,cAAA;EAAA,IAAA0B,QAAAC,QAAA;EAAAtB,OAAAqB,OAAApB,WAAA,EAAA,KAAA,WAAA;GAAA,OAA2CT,GAAG,0BAA0BI,MAAMM,KAAK;EAAC,EAAA,GAAML,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAwB;CAAA,EAAA,CAAA;AAChG"}
|
|
@@ -41,10 +41,11 @@ export declare function mergeChartOptions(...sources: (ChartOptions | undefined)
|
|
|
41
41
|
export declare function chartOptions(overrides?: ChartOptions, shape?: ChartScaleShape): ChartOptions;
|
|
42
42
|
/**
|
|
43
43
|
* Replace every `var(--token)` string in `value` — options, datasets, nested
|
|
44
|
-
* arrays — with what `read` returns for the token
|
|
44
|
+
* arrays — with what `read` returns for the token, which may be a number (a
|
|
45
|
+
* length token read as pixels). A token `read` cannot
|
|
45
46
|
* resolve falls back to the `var()`'s own fallback, then to the string as
|
|
46
47
|
* written. Functions and class instances pass through untouched, so scriptable
|
|
47
48
|
* options and gradients keep working.
|
|
48
49
|
*/
|
|
49
|
-
export declare function resolveCssVariables<T>(value: T, read: (name: string) => string | undefined): T;
|
|
50
|
+
export declare function resolveCssVariables<T>(value: T, read: (name: string) => string | number | undefined): T;
|
|
50
51
|
//# sourceMappingURL=chart-options.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-options.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/chart/chart-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAE5C;;;;;;;;;;GAUG;AAEH,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,qGAMpB,CAAA;AAkBV;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"chart-options.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/chart/chart-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAE5C;;;;;;;;;;GAUG;AAEH,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,qGAMpB,CAAA;AAkBV;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAA;AA6E7D;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,OAAO,EAAE,CAAC,YAAY,GAAG,SAAS,CAAC,EAAE,GAAG,YAAY,CAMxF;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,SAAS,CAAC,EAAE,YAAY,EACxB,KAAK,GAAE,eAA6B,GACnC,YAAY,CAsCd;AAID;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,KAAK,EAAE,CAAC,EACR,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,GAAG,SAAS,GAClD,CAAC,CAmBH"}
|
|
@@ -33,7 +33,29 @@ var furniture = {
|
|
|
33
33
|
label: "var(--muted-foreground)",
|
|
34
34
|
surface: "var(--card)"
|
|
35
35
|
};
|
|
36
|
-
|
|
36
|
+
/**
|
|
37
|
+
* The chart's type: the UI face from the font axis and a rung of the type scale,
|
|
38
|
+
* declared as tokens like the colours.
|
|
39
|
+
*
|
|
40
|
+
* Chart.js does not inherit the page's font — it paints in its own default
|
|
41
|
+
* family — so every text a chart draws names `--font-sans` explicitly, and the
|
|
42
|
+
* chart follows `data-font` the same way it follows `.dark`. Everything is
|
|
43
|
+
* `--text-2xs`, the rung `ChartLegend` and the frame's metadata already use, so
|
|
44
|
+
* a canvas legend and an HTML one beside it are the same size.
|
|
45
|
+
*
|
|
46
|
+
* Chart.js types `size` as a number of pixels. The token is a `rem` length, so
|
|
47
|
+
* it is written as `var(--text-2xs)` here and the component resolves it to
|
|
48
|
+
* pixels with the colours (see `resolveCssVariables` and `chart.tsx`); the cast
|
|
49
|
+
* is that declaration, not a number.
|
|
50
|
+
*/
|
|
51
|
+
function chartFont(weight) {
|
|
52
|
+
return {
|
|
53
|
+
family: "var(--font-sans)",
|
|
54
|
+
size: "var(--text-2xs)",
|
|
55
|
+
...weight === void 0 ? {} : { weight }
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
var tickFont = chartFont();
|
|
37
59
|
function scalesFor(shape) {
|
|
38
60
|
if (shape === "cartesian") return {
|
|
39
61
|
x: {
|
|
@@ -124,7 +146,7 @@ function chartOptions(overrides, shape = "cartesian") {
|
|
|
124
146
|
boxHeight: 8,
|
|
125
147
|
usePointStyle: true,
|
|
126
148
|
pointStyle: "circle",
|
|
127
|
-
font:
|
|
149
|
+
font: chartFont()
|
|
128
150
|
} },
|
|
129
151
|
tooltip: {
|
|
130
152
|
backgroundColor: "var(--popover)",
|
|
@@ -138,11 +160,9 @@ function chartOptions(overrides, shape = "cartesian") {
|
|
|
138
160
|
boxWidth: 8,
|
|
139
161
|
boxHeight: 8,
|
|
140
162
|
usePointStyle: true,
|
|
141
|
-
titleFont:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
},
|
|
145
|
-
bodyFont: { size: 11 }
|
|
163
|
+
titleFont: chartFont(600),
|
|
164
|
+
bodyFont: chartFont(),
|
|
165
|
+
footerFont: chartFont()
|
|
146
166
|
}
|
|
147
167
|
},
|
|
148
168
|
scales: scalesFor(shape)
|
|
@@ -151,7 +171,8 @@ function chartOptions(overrides, shape = "cartesian") {
|
|
|
151
171
|
var cssVariable = /^\s*var\(\s*(--[\w-]+)\s*(?:,\s*(.*?))?\s*\)\s*$/;
|
|
152
172
|
/**
|
|
153
173
|
* Replace every `var(--token)` string in `value` — options, datasets, nested
|
|
154
|
-
* arrays — with what `read` returns for the token
|
|
174
|
+
* arrays — with what `read` returns for the token, which may be a number (a
|
|
175
|
+
* length token read as pixels). A token `read` cannot
|
|
155
176
|
* resolve falls back to the `var()`'s own fallback, then to the string as
|
|
156
177
|
* written. Functions and class instances pass through untouched, so scriptable
|
|
157
178
|
* options and gradients keep working.
|
|
@@ -161,7 +182,7 @@ function resolveCssVariables(value, read) {
|
|
|
161
182
|
const match = cssVariable.exec(value);
|
|
162
183
|
if (!match) return value;
|
|
163
184
|
const resolved = read(match[1]);
|
|
164
|
-
if (resolved) return resolved;
|
|
185
|
+
if (resolved !== void 0 && resolved !== "") return resolved;
|
|
165
186
|
return match[2] ? resolveCssVariables(match[2], read) : value;
|
|
166
187
|
}
|
|
167
188
|
if (Array.isArray(value)) return value.map((entry) => resolveCssVariables(entry, read));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-options.js","names":[],"sources":["../../../../src/components/ui/chart/chart-options.ts"],"sourcesContent":["import type { ChartOptions } from 'chart.js'\n\n/**\n * The chart's options, as data: no Chart.js runtime and no DOM, so the theme's\n * defaults and the merge rules are testable on their own.\n *\n * Every colour here is written as `var(--token)`. A canvas cannot read a custom\n * property — `fillStyle = 'var(--chart-1)'` is an invalid colour, which the\n * canvas ignores and paints in its default black — so these strings are the\n * *declaration* of which token a colour comes from. The components resolve them\n * against their own element at render time (see `resolveCssVariables` and the\n * resolver in `chart.tsx`).\n */\n\n/** The five series colours, in the order a multi-series chart should use them. */\nexport const chartSeriesColors = [\n 'var(--chart-1)',\n 'var(--chart-2)',\n 'var(--chart-3)',\n 'var(--chart-4)',\n 'var(--chart-5)',\n] as const\n\n/**\n * The chart furniture, mapped onto existing semantic tokens rather than given\n * tokens of its own. A grid line is a line, so it is `--border`; an axis tick and\n * a legend label are secondary text, so they are `--muted-foreground`, whose\n * contrast on `--card` (the frame's surface) is already measured in\n * `tests/tokens.test.ts`. Dedicated `--chart-grid`/`--chart-axis`/`--chart-label`\n * tokens would be three more values to keep in step with these in every theme\n * for no difference anyone has asked for.\n */\nconst furniture = {\n grid: 'var(--border)',\n axis: 'var(--muted-foreground)',\n label: 'var(--muted-foreground)',\n surface: 'var(--card)',\n} as const\n\n/**\n * Which scales a chart type draws. Chart.js creates a scale for every key under\n * `options.scales` whatever the chart type, so cartesian defaults handed to a\n * doughnut draw an x and a y axis and a grid behind it. The shape keeps each\n * type's defaults to the scales it actually has.\n */\nexport type ChartScaleShape = 'cartesian' | 'radial' | 'none'\n\nconst tickFont = { size: 10 }\n\nfunction scalesFor(shape: ChartScaleShape): ChartOptions['scales'] {\n if (shape === 'cartesian') {\n return {\n x: {\n border: { color: furniture.grid },\n grid: { color: furniture.grid, drawTicks: false },\n ticks: { color: furniture.axis, font: tickFont },\n },\n y: {\n border: { display: false },\n grid: { color: furniture.grid, drawTicks: false },\n ticks: { color: furniture.axis, font: tickFont },\n },\n }\n }\n if (shape === 'radial') {\n return {\n r: {\n grid: { color: furniture.grid },\n angleLines: { color: furniture.grid },\n pointLabels: { color: furniture.axis, font: tickFont },\n // The default backdrop is a translucent white box, which is a white box\n // on a dark card. The frame's own surface makes it disappear in both.\n ticks: { color: furniture.axis, backdropColor: furniture.surface, font: tickFont },\n },\n }\n }\n return undefined\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false\n const prototype = Object.getPrototypeOf(value)\n return prototype === Object.prototype || prototype === null\n}\n\nfunction mergeInto(target: Record<string, unknown>, source: Record<string, unknown>) {\n for (const [key, value] of Object.entries(source)) {\n if (value === undefined) continue\n const current = target[key]\n target[key] =\n isPlainObject(value) && isPlainObject(current)\n ? mergeInto({ ...current }, value)\n : isPlainObject(value)\n ? mergeInto({}, value)\n : value\n }\n return target\n}\n\n/**\n * Merge Chart.js options, later sources winning, object by object.\n *\n * Deep, because Chart.js options are deep: `{ scales: { x: { stacked: true } } }`\n * means \"also stack x\", and a spread would replace the whole axis — its grid,\n * its tick colour, its font — with that one flag. Arrays, functions (scriptable\n * options) and class instances (gradients, patterns) are values and replace\n * rather than merge. No source is mutated.\n */\nexport function mergeChartOptions(...sources: (ChartOptions | undefined)[]): ChartOptions {\n const merged: Record<string, unknown> = {}\n for (const source of sources) {\n if (source) mergeInto(merged, source as Record<string, unknown>)\n }\n return merged as ChartOptions\n}\n\n/**\n * The theme's defaults as Chart.js options.\n *\n * Exported so a caller can spread it and change one thing, rather than\n * restating every colour. Everything a chart draws that is not data — grid,\n * ticks, legend, tooltip — is decided here once, which is what makes two charts\n * in one application look like they came from the same place. `overrides` is\n * merged deeply; `shape` selects the scales the chart type has.\n */\nexport function chartOptions(\n overrides?: ChartOptions,\n shape: ChartScaleShape = 'cartesian'\n): ChartOptions {\n return mergeChartOptions(\n {\n responsive: true,\n maintainAspectRatio: false,\n interaction: { mode: 'nearest', intersect: false },\n plugins: {\n legend: {\n labels: {\n color: furniture.label,\n boxWidth: 8,\n boxHeight: 8,\n usePointStyle: true,\n pointStyle: 'circle',\n font: { size: 11 },\n },\n },\n tooltip: {\n backgroundColor: 'var(--popover)',\n titleColor: 'var(--popover-foreground)',\n bodyColor: 'var(--popover-foreground)',\n borderColor: 'var(--border)',\n borderWidth: 1,\n padding: 8,\n cornerRadius: 6,\n displayColors: true,\n boxWidth: 8,\n boxHeight: 8,\n usePointStyle: true,\n titleFont: { size: 11, weight: 600 },\n bodyFont: { size: 11 },\n },\n },\n scales: scalesFor(shape),\n },\n overrides\n )\n}\n\nconst cssVariable = /^\\s*var\\(\\s*(--[\\w-]+)\\s*(?:,\\s*(.*?))?\\s*\\)\\s*$/\n\n/**\n * Replace every `var(--token)` string in `value` — options, datasets, nested\n * arrays — with what `read` returns for the token. A token `read` cannot\n * resolve falls back to the `var()`'s own fallback, then to the string as\n * written. Functions and class instances pass through untouched, so scriptable\n * options and gradients keep working.\n */\nexport function resolveCssVariables<T>(value: T, read: (name: string) => string | undefined): T {\n if (typeof value === 'string') {\n const match = cssVariable.exec(value)\n if (!match) return value\n const resolved = read(match[1]!)\n if (resolved) return resolved as T\n return (match[2] ? resolveCssVariables(match[2], read) : value) as T\n }\n if (Array.isArray(value)) {\n return value.map((entry: unknown) => resolveCssVariables(entry, read)) as T\n }\n if (isPlainObject(value)) {\n const resolved: Record<string, unknown> = {}\n for (const [key, entry] of Object.entries(value)) {\n resolved[key] = resolveCssVariables(entry, read)\n }\n return resolved as T\n }\n return value\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chart-options.js","names":[],"sources":["../../../../src/components/ui/chart/chart-options.ts"],"sourcesContent":["import type { ChartOptions } from 'chart.js'\n\n/**\n * The chart's options, as data: no Chart.js runtime and no DOM, so the theme's\n * defaults and the merge rules are testable on their own.\n *\n * Every colour here is written as `var(--token)`. A canvas cannot read a custom\n * property — `fillStyle = 'var(--chart-1)'` is an invalid colour, which the\n * canvas ignores and paints in its default black — so these strings are the\n * *declaration* of which token a colour comes from. The components resolve them\n * against their own element at render time (see `resolveCssVariables` and the\n * resolver in `chart.tsx`).\n */\n\n/** The five series colours, in the order a multi-series chart should use them. */\nexport const chartSeriesColors = [\n 'var(--chart-1)',\n 'var(--chart-2)',\n 'var(--chart-3)',\n 'var(--chart-4)',\n 'var(--chart-5)',\n] as const\n\n/**\n * The chart furniture, mapped onto existing semantic tokens rather than given\n * tokens of its own. A grid line is a line, so it is `--border`; an axis tick and\n * a legend label are secondary text, so they are `--muted-foreground`, whose\n * contrast on `--card` (the frame's surface) is already measured in\n * `tests/tokens.test.ts`. Dedicated `--chart-grid`/`--chart-axis`/`--chart-label`\n * tokens would be three more values to keep in step with these in every theme\n * for no difference anyone has asked for.\n */\nconst furniture = {\n grid: 'var(--border)',\n axis: 'var(--muted-foreground)',\n label: 'var(--muted-foreground)',\n surface: 'var(--card)',\n} as const\n\n/**\n * Which scales a chart type draws. Chart.js creates a scale for every key under\n * `options.scales` whatever the chart type, so cartesian defaults handed to a\n * doughnut draw an x and a y axis and a grid behind it. The shape keeps each\n * type's defaults to the scales it actually has.\n */\nexport type ChartScaleShape = 'cartesian' | 'radial' | 'none'\n\n/**\n * The chart's type: the UI face from the font axis and a rung of the type scale,\n * declared as tokens like the colours.\n *\n * Chart.js does not inherit the page's font — it paints in its own default\n * family — so every text a chart draws names `--font-sans` explicitly, and the\n * chart follows `data-font` the same way it follows `.dark`. Everything is\n * `--text-2xs`, the rung `ChartLegend` and the frame's metadata already use, so\n * a canvas legend and an HTML one beside it are the same size.\n *\n * Chart.js types `size` as a number of pixels. The token is a `rem` length, so\n * it is written as `var(--text-2xs)` here and the component resolves it to\n * pixels with the colours (see `resolveCssVariables` and `chart.tsx`); the cast\n * is that declaration, not a number.\n */\nfunction chartFont(weight?: number) {\n return {\n family: 'var(--font-sans)',\n size: 'var(--text-2xs)' as unknown as number,\n ...(weight === undefined ? {} : { weight }),\n }\n}\n\nconst tickFont = chartFont()\n\nfunction scalesFor(shape: ChartScaleShape): ChartOptions['scales'] {\n if (shape === 'cartesian') {\n return {\n x: {\n border: { color: furniture.grid },\n grid: { color: furniture.grid, drawTicks: false },\n ticks: { color: furniture.axis, font: tickFont },\n },\n y: {\n border: { display: false },\n grid: { color: furniture.grid, drawTicks: false },\n ticks: { color: furniture.axis, font: tickFont },\n },\n }\n }\n if (shape === 'radial') {\n return {\n r: {\n grid: { color: furniture.grid },\n angleLines: { color: furniture.grid },\n pointLabels: { color: furniture.axis, font: tickFont },\n // The default backdrop is a translucent white box, which is a white box\n // on a dark card. The frame's own surface makes it disappear in both.\n ticks: { color: furniture.axis, backdropColor: furniture.surface, font: tickFont },\n },\n }\n }\n return undefined\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false\n const prototype = Object.getPrototypeOf(value)\n return prototype === Object.prototype || prototype === null\n}\n\nfunction mergeInto(target: Record<string, unknown>, source: Record<string, unknown>) {\n for (const [key, value] of Object.entries(source)) {\n if (value === undefined) continue\n const current = target[key]\n target[key] =\n isPlainObject(value) && isPlainObject(current)\n ? mergeInto({ ...current }, value)\n : isPlainObject(value)\n ? mergeInto({}, value)\n : value\n }\n return target\n}\n\n/**\n * Merge Chart.js options, later sources winning, object by object.\n *\n * Deep, because Chart.js options are deep: `{ scales: { x: { stacked: true } } }`\n * means \"also stack x\", and a spread would replace the whole axis — its grid,\n * its tick colour, its font — with that one flag. Arrays, functions (scriptable\n * options) and class instances (gradients, patterns) are values and replace\n * rather than merge. No source is mutated.\n */\nexport function mergeChartOptions(...sources: (ChartOptions | undefined)[]): ChartOptions {\n const merged: Record<string, unknown> = {}\n for (const source of sources) {\n if (source) mergeInto(merged, source as Record<string, unknown>)\n }\n return merged as ChartOptions\n}\n\n/**\n * The theme's defaults as Chart.js options.\n *\n * Exported so a caller can spread it and change one thing, rather than\n * restating every colour. Everything a chart draws that is not data — grid,\n * ticks, legend, tooltip — is decided here once, which is what makes two charts\n * in one application look like they came from the same place. `overrides` is\n * merged deeply; `shape` selects the scales the chart type has.\n */\nexport function chartOptions(\n overrides?: ChartOptions,\n shape: ChartScaleShape = 'cartesian'\n): ChartOptions {\n return mergeChartOptions(\n {\n responsive: true,\n maintainAspectRatio: false,\n interaction: { mode: 'nearest', intersect: false },\n plugins: {\n legend: {\n labels: {\n color: furniture.label,\n boxWidth: 8,\n boxHeight: 8,\n usePointStyle: true,\n pointStyle: 'circle',\n font: chartFont(),\n },\n },\n tooltip: {\n backgroundColor: 'var(--popover)',\n titleColor: 'var(--popover-foreground)',\n bodyColor: 'var(--popover-foreground)',\n borderColor: 'var(--border)',\n borderWidth: 1,\n padding: 8,\n cornerRadius: 6,\n displayColors: true,\n boxWidth: 8,\n boxHeight: 8,\n usePointStyle: true,\n titleFont: chartFont(600),\n bodyFont: chartFont(),\n footerFont: chartFont(),\n },\n },\n scales: scalesFor(shape),\n },\n overrides\n )\n}\n\nconst cssVariable = /^\\s*var\\(\\s*(--[\\w-]+)\\s*(?:,\\s*(.*?))?\\s*\\)\\s*$/\n\n/**\n * Replace every `var(--token)` string in `value` — options, datasets, nested\n * arrays — with what `read` returns for the token, which may be a number (a\n * length token read as pixels). A token `read` cannot\n * resolve falls back to the `var()`'s own fallback, then to the string as\n * written. Functions and class instances pass through untouched, so scriptable\n * options and gradients keep working.\n */\nexport function resolveCssVariables<T>(\n value: T,\n read: (name: string) => string | number | undefined\n): T {\n if (typeof value === 'string') {\n const match = cssVariable.exec(value)\n if (!match) return value\n const resolved = read(match[1]!)\n if (resolved !== undefined && resolved !== '') return resolved as T\n return (match[2] ? resolveCssVariables(match[2], read) : value) as T\n }\n if (Array.isArray(value)) {\n return value.map((entry: unknown) => resolveCssVariables(entry, read)) as T\n }\n if (isPlainObject(value)) {\n const resolved: Record<string, unknown> = {}\n for (const [key, entry] of Object.entries(value)) {\n resolved[key] = resolveCssVariables(entry, read)\n }\n return resolved as T\n }\n return value\n}\n"],"mappings":"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"}
|
|
@@ -39,7 +39,9 @@ import { chartOptions, chartSeriesColors } from './chart-options';
|
|
|
39
39
|
* A canvas cannot read a custom property, so the options and datasets carry
|
|
40
40
|
* `var(--token)` strings and each chart resolves them against its own element
|
|
41
41
|
* when it renders, and again whenever the root's attributes change — the
|
|
42
|
-
* `.dark` class, `data-accent`, an inline override.
|
|
42
|
+
* `.dark` class, `data-accent`, `data-font`, an inline override. The type is
|
|
43
|
+
* resolved the same way: `--font-sans` for the family and a type-scale rung for
|
|
44
|
+
* the size, so a chart follows the font axis too. See `createThemeResolver`.
|
|
43
45
|
*/
|
|
44
46
|
/**
|
|
45
47
|
* Register a piece with Chart.js. The escape hatch for a caller's own chart type.
|
|
@@ -114,14 +116,7 @@ export declare function BubbleChart(props: {
|
|
|
114
116
|
}): JSX.Element;
|
|
115
117
|
/** A radar chart, for a profile across fixed axes. */
|
|
116
118
|
export declare function RadarChart(props: SeriesChartProps): JSX.Element;
|
|
117
|
-
/**
|
|
118
|
-
* A polar area chart: radial bars, for a composition.
|
|
119
|
-
*
|
|
120
|
-
* Its scale is left to Chart.js's polar-area defaults (`'none'` rather than
|
|
121
|
-
* `'radial'`): `solid-chartjs` deletes `options.scales.r` for every chart type
|
|
122
|
-
* but radar when it first creates the chart, so radial styling here would apply
|
|
123
|
-
* only after the first theme change — a chart that restyles itself on a toggle.
|
|
124
|
-
*/
|
|
119
|
+
/** A polar area chart: radial bars, for a composition. */
|
|
125
120
|
export declare function PolarAreaChart(props: {
|
|
126
121
|
labels: readonly string[];
|
|
127
122
|
data: readonly number[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/chart/chart.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA2D,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAG5F,OAAO,EACL,KAAK,IAAI,OAAO,EAYjB,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/chart/chart.tsx"],"names":[],"mappings":"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"}
|