@adea-ai/ui 0.61.1 → 0.63.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/README.md +94 -6
- package/dist/LICENSE +201 -0
- package/dist/NOTICE +101 -0
- package/dist/components/composites/account-menu/index.js +2 -0
- package/dist/components/composites/appearance-editor/appearance-choices.d.ts +5 -0
- package/dist/components/composites/appearance-editor/appearance-choices.d.ts.map +1 -0
- package/dist/components/composites/appearance-editor/appearance-choices.js +211 -0
- package/dist/components/composites/appearance-editor/appearance-choices.js.map +1 -0
- package/dist/components/composites/appearance-editor/appearance-editor.d.ts +15 -0
- package/dist/components/composites/appearance-editor/appearance-editor.d.ts.map +1 -0
- package/dist/components/composites/appearance-editor/appearance-editor.js +280 -0
- package/dist/components/composites/appearance-editor/appearance-editor.js.map +1 -0
- package/dist/components/composites/appearance-editor/appearance-rows.d.ts +18 -0
- package/dist/components/composites/appearance-editor/appearance-rows.d.ts.map +1 -0
- package/dist/components/composites/appearance-editor/appearance-rows.js +101 -0
- package/dist/components/composites/appearance-editor/appearance-rows.js.map +1 -0
- package/dist/components/composites/appearance-editor/appearance-types.d.ts +42 -0
- package/dist/components/composites/appearance-editor/appearance-types.d.ts.map +1 -0
- package/dist/components/composites/appearance-editor/index.d.ts +4 -0
- package/dist/components/composites/appearance-editor/index.d.ts.map +1 -0
- package/dist/components/composites/appearance-editor/index.js +3 -0
- package/dist/components/composites/appearance-editor/theme-preview.d.ts +17 -0
- package/dist/components/composites/appearance-editor/theme-preview.d.ts.map +1 -0
- package/dist/components/composites/appearance-editor/theme-preview.js +158 -0
- package/dist/components/composites/appearance-editor/theme-preview.js.map +1 -0
- package/dist/components/composites/list-row/index.js +2 -0
- package/dist/components/composites/settings/index.js +2 -0
- package/dist/components/composites/stat/index.js +2 -0
- package/dist/components/composites/update-dialog/index.js +2 -0
- package/dist/components/composites/workspace-mark/index.js +2 -0
- package/dist/components/conversation/index.js +6 -0
- package/dist/components/layout/app-shell/index.js +2 -0
- package/dist/components/layout/page/index.js +2 -0
- package/dist/components/layout/panel/index.js +2 -0
- package/dist/components/layout/side-rail/index.js +3 -0
- package/dist/components/layout/sidebar-nav/index.js +2 -0
- package/dist/components/layout/status-bar/index.js +2 -0
- package/dist/components/layout/top-bar/index.js +2 -0
- package/dist/components/motion/index.js +2 -2
- package/dist/components/theme/index.js +5 -0
- package/dist/components/ui/accordion/index.js +2 -0
- package/dist/components/ui/alert/index.js +2 -0
- package/dist/components/ui/alert-dialog/index.js +2 -0
- package/dist/components/ui/aspect-ratio/index.js +2 -0
- package/dist/components/ui/avatar/index.js +2 -0
- package/dist/components/ui/badge/index.js +2 -0
- package/dist/components/ui/board/index.js +2 -0
- package/dist/components/ui/breadcrumb/index.js +2 -0
- package/dist/components/ui/button/index.js +2 -0
- package/dist/components/ui/button-group/index.js +2 -0
- package/dist/components/ui/calendar/index.js +2 -0
- package/dist/components/ui/card/index.js +2 -0
- package/dist/components/ui/carousel/index.js +2 -0
- package/dist/components/ui/chart/index.js +2 -0
- package/dist/components/ui/checkbox/index.js +2 -0
- package/dist/components/ui/code-block/index.js +2 -0
- package/dist/components/ui/collapsible/index.js +2 -0
- package/dist/components/ui/combobox/index.js +2 -0
- package/dist/components/ui/command/index.js +2 -0
- package/dist/components/ui/context-menu/index.js +2 -0
- package/dist/components/ui/detail-panel/index.js +2 -0
- package/dist/components/ui/dialog/index.js +2 -0
- package/dist/components/ui/diff-block/index.js +2 -0
- package/dist/components/ui/drawer/index.js +2 -0
- package/dist/components/ui/dropdown-menu/index.js +2 -0
- package/dist/components/ui/empty/index.js +2 -0
- package/dist/components/ui/entity-icon/index.js +2 -0
- package/dist/components/ui/field/index.js +2 -0
- package/dist/components/ui/hover-card/index.js +2 -0
- package/dist/components/ui/input/index.js +2 -0
- package/dist/components/ui/input-group/index.js +2 -0
- package/dist/components/ui/input-otp/index.js +2 -0
- package/dist/components/ui/item/index.js +2 -0
- package/dist/components/ui/kbd/index.js +2 -0
- package/dist/components/ui/label/index.js +2 -0
- package/dist/components/ui/menubar/index.js +2 -0
- package/dist/components/ui/modal-dialog/index.js +2 -0
- package/dist/components/ui/navigation-menu/index.js +2 -0
- package/dist/components/ui/pagination/index.js +2 -0
- package/dist/components/ui/popover/index.js +2 -0
- package/dist/components/ui/progress/index.js +2 -0
- package/dist/components/ui/radio-group/index.js +2 -0
- package/dist/components/ui/resizable/index.js +2 -0
- package/dist/components/ui/scroll-area/index.js +2 -0
- package/dist/components/ui/select/index.js +2 -0
- package/dist/components/ui/select/select.d.ts +5 -1
- package/dist/components/ui/select/select.d.ts.map +1 -1
- package/dist/components/ui/select/select.js +24 -20
- package/dist/components/ui/select/select.js.map +1 -1
- package/dist/components/ui/separator/index.js +2 -0
- package/dist/components/ui/sheet/index.js +2 -0
- package/dist/components/ui/skeleton/index.js +2 -0
- package/dist/components/ui/slider/index.js +2 -0
- package/dist/components/ui/spinner/index.js +2 -0
- package/dist/components/ui/status-chip/index.js +2 -0
- package/dist/components/ui/switch/index.js +2 -0
- package/dist/components/ui/table/index.js +2 -0
- package/dist/components/ui/tabs/index.js +2 -0
- package/dist/components/ui/textarea/index.js +2 -0
- package/dist/components/ui/toast/index.js +2 -0
- package/dist/components/ui/toggle/index.js +2 -0
- package/dist/components/ui/toggle-group/index.js +2 -0
- package/dist/components/ui/tooltip/index.js +2 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/r/appearance-editor.json +51 -0
- package/dist/r/lib.json +1 -1
- package/dist/r/registry.json +52 -1
- package/dist/r/src/components/composites/appearance-editor/appearance-choices.tsx +173 -0
- package/dist/r/src/components/composites/appearance-editor/appearance-editor.tsx +239 -0
- package/dist/r/src/components/composites/appearance-editor/appearance-rows.tsx +122 -0
- package/dist/r/src/components/composites/appearance-editor/appearance-types.ts +40 -0
- package/dist/r/src/components/composites/appearance-editor/index.ts +12 -0
- package/dist/r/src/components/composites/appearance-editor/theme-preview.tsx +128 -0
- package/dist/r/src/components/ui/select/select.tsx +8 -3
- package/package.json +11 -9
- package/registry.json +52 -1
- package/src/components/composites/appearance-editor/appearance-choices.tsx +173 -0
- package/src/components/composites/appearance-editor/appearance-editor.tsx +239 -0
- package/src/components/composites/appearance-editor/appearance-rows.tsx +122 -0
- package/src/components/composites/appearance-editor/appearance-types.ts +40 -0
- package/src/components/composites/appearance-editor/index.ts +12 -0
- package/src/components/composites/appearance-editor/theme-preview.tsx +128 -0
- package/src/components/ui/select/select.tsx +8 -3
- package/src/index.ts +3 -4
- package/dist/components/ui/diff-block/diff-block.test.d.ts +0 -2
- package/dist/components/ui/diff-block/diff-block.test.d.ts.map +0 -1
- package/dist/lib/keyed-rows.test.d.ts +0 -2
- package/dist/lib/keyed-rows.test.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appearance-choices.js","names":["RadioGroup","Radio","For","Show","AppearanceEditorProps","ThemeMiniature","ThemeMiniatureSplit","MODES","value","label","const","SURFACES","ModeChoices","props","_$createComponent","draft","mode","disabled","saving","orientation","onChange","option","find","candidate","children","each","Item","data-mode","ItemInput","ItemLabel","_el$","_tmpl$","_$insert","when","fallback","theme","_$memo","lightTheme","darkTheme","light","dark","_el$2","_tmpl$2","AccentChoices","custom","accent","accentOptions","some","id","accentSelection","customAccentValue","_el$3","_tmpl$3","_$effect","_$p","_$setStyleProperty","resolvedAppearance","_el$4","_tmpl$4","GlassChoices","surface","surfaceCapability","frosted","_$createComponent","Radio","_$memo","_$setStyleProperty"],"sources":["../../../../src/components/composites/appearance-editor/appearance-choices.tsx"],"sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2026 Wing\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n// Pinned mode-card, accent-swatch, and glass-chip composition. Kobalte replaces\n// the app port's manual roving focus; it does not replace the donor hierarchy.\nimport { RadioGroup as Radio } from '@kobalte/core/radio-group'\nimport { For, Show } from 'solid-js'\nimport type { AppearanceEditorProps } from './appearance-types'\nimport { ThemeMiniature, ThemeMiniatureSplit } from './theme-preview'\n\nconst MODES = [\n { value: 'system', label: 'System' },\n { value: 'light', label: 'Light' },\n { value: 'dark', label: 'Dark' },\n] as const\nconst SURFACES = [\n { value: 'theme', label: 'Theme default' },\n { value: 'frosted', label: 'Frosted' },\n { value: 'opaque', label: 'Opaque' },\n] as const\n\nexport function ModeChoices(props: AppearanceEditorProps) {\n return (\n <Radio\n value={props.draft.mode}\n disabled={props.saving}\n orientation=\"horizontal\"\n aria-label=\"Appearance mode\"\n onChange={(mode) => {\n const option = MODES.find((candidate) => candidate.value === mode)\n if (option) props.onChange({ mode: option.value })\n }}\n class=\"grid grid-cols-1 gap-3 px-4 py-4 sm:grid-cols-3\"\n >\n <For each={MODES}>\n {(option) => (\n <Radio.Item\n value={option.value}\n data-mode={option.value}\n class=\"min-w-0 rounded-lg focus-within:ring-3 focus-within:ring-ring/50\"\n >\n <Radio.ItemInput />\n <Radio.ItemLabel class=\"flex cursor-pointer flex-col gap-2 rounded-lg border p-2 text-center text-xs data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50\">\n <span class=\"block h-20 w-full\">\n <Show\n when={option.value === 'system'}\n fallback={\n <ThemeMiniature\n theme={option.value === 'light' ? props.lightTheme : props.darkTheme}\n />\n }\n >\n <ThemeMiniatureSplit light={props.lightTheme} dark={props.darkTheme} />\n </Show>\n </span>\n <span>{option.label}</span>\n </Radio.ItemLabel>\n </Radio.Item>\n )}\n </For>\n </Radio>\n )\n}\n\nexport function AccentChoices(props: AppearanceEditorProps) {\n const custom = () =>\n props.draft.accent !== 'theme' &&\n !props.accentOptions.some((option) => option.id === props.draft.accent)\n const accentSelection = () => (custom() ? 'custom' : props.draft.accent)\n return (\n <Radio\n value={accentSelection()}\n disabled={props.saving}\n orientation=\"horizontal\"\n aria-label=\"Accent\"\n class=\"flex flex-wrap items-center gap-2\"\n onChange={(accent) =>\n props.onChange({\n accent: accent === 'custom' ? (props.customAccentValue ?? '') : accent,\n })\n }\n >\n <Radio.Item value=\"theme\">\n <Radio.ItemInput />\n <Radio.ItemLabel class=\"flex h-7 cursor-pointer items-center rounded-md border px-2 text-xs data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary\">\n Theme default\n </Radio.ItemLabel>\n </Radio.Item>\n <For each={props.accentOptions}>\n {(option) => (\n <Radio.Item\n value={option.id}\n class=\"rounded-full focus-within:ring-3 focus-within:ring-ring/50\"\n >\n <Radio.ItemInput />\n <Radio.ItemLabel class=\"block size-7 cursor-pointer rounded-full border p-0.5 data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary\">\n <span\n class=\"block size-full rounded-full\"\n aria-hidden=\"true\"\n style={{\n 'background-color':\n (props.draft.mode === 'system'\n ? props.resolvedAppearance\n : props.draft.mode) === 'light'\n ? option.light\n : option.dark,\n }}\n />\n <span class=\"sr-only\">{option.label}</span>\n </Radio.ItemLabel>\n </Radio.Item>\n )}\n </For>\n <Radio.Item value=\"custom\">\n <Radio.ItemInput />\n <Radio.ItemLabel class=\"flex h-7 cursor-pointer items-center rounded-md border px-2 text-xs data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary\">\n Custom\n </Radio.ItemLabel>\n </Radio.Item>\n </Radio>\n )\n}\n\nexport function GlassChoices(props: AppearanceEditorProps) {\n return (\n <Radio\n value={props.draft.surface}\n disabled={props.saving}\n orientation=\"horizontal\"\n aria-label=\"Glass\"\n class=\"flex flex-wrap gap-1\"\n onChange={(surface) => {\n const option = SURFACES.find((candidate) => candidate.value === surface)\n if (option) props.onChange({ surface: option.value })\n }}\n >\n <For each={SURFACES}>\n {(option) => (\n <Radio.Item\n value={option.value}\n disabled={option.value === 'frosted' && !props.surfaceCapability.frosted}\n class=\"rounded-md focus-within:ring-3 focus-within:ring-ring/50\"\n >\n <Radio.ItemInput />\n <Radio.ItemLabel class=\"flex h-7 cursor-pointer items-center rounded-md border px-2 text-xs data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50\">\n {option.label}\n </Radio.ItemLabel>\n </Radio.Item>\n )}\n </For>\n </Radio>\n )\n}\n"],"mappings":";;;;;;;;;AA8BA,IAAMO,QAAQ;CACZ;EAAEC,OAAO;EAAUC,OAAO;CAAS;CACnC;EAAED,OAAO;EAASC,OAAO;CAAQ;CACjC;EAAED,OAAO;EAAQC,OAAO;CAAO;AAAC;AAElC,IAAME,WAAW;CACf;EAAEH,OAAO;EAASC,OAAO;CAAgB;CACzC;EAAED,OAAO;EAAWC,OAAO;CAAU;CACrC;EAAED,OAAO;EAAUC,OAAO;CAAS;AAAC;AAGtC,SAAgBG,YAAYC,OAA8B;CACxD,OAAAC,gBACGb,YAAK;EAAA,IACJO,QAAK;GAAA,OAAEK,MAAME,MAAMC;EAAI;EAAA,IACvBC,WAAQ;GAAA,OAAEJ,MAAMK;EAAM;EACtBC,aAAW;EAAA,cAAA;EAEXC,WAAWJ,SAAS;GAClB,MAAMK,SAASd,MAAMe,MAAMC,cAAcA,UAAUf,UAAUQ,IAAI;GACjE,IAAIK,QAAQR,MAAMO,SAAS,EAAEJ,MAAMK,OAAOb,MAAM,CAAC;EACnD;EAAC,SAAA;EAAA,IAAAgB,WAAA;GAAA,OAAAV,gBAGAZ,KAAG;IAACuB,MAAMlB;IAAKiB,WACZH,WAAMP,gBACLb,WAAMyB,MAAI;KAAA,IACTlB,QAAK;MAAA,OAAEa,OAAOb;KAAK;KAAA,KAAA,eAAA;MAAA,OACRa,OAAOb;KAAK;KAAA,SAAA;KAAA,IAAAgB,WAAA;MAAA,OAAA,CAAAV,gBAGtBb,WAAM2B,WAAS,CAAA,CAAA,GAAAd,gBACfb,WAAM4B,WAAS;OAAA,SAAA;OAAA,IAAAL,WAAA;QAAA,OAAA,QAAA;SAAA,IAAAM,OAAAC,OAAA;SAAAC,OAAAF,MAAAhB,gBAEXX,MAAI;UAAA,IACH8B,OAAI;WAAA,OAAEZ,OAAOb,UAAU;UAAQ;UAAA,IAC/B0B,WAAQ;WAAA,OAAApB,gBACLT,gBAAc,EAAA,IACb8B,QAAK;YAAA,OAAEC,WAAAf,OAAOb,UAAU,OAAO,CAAA,CAAA,IAAGK,MAAMwB,aAAaxB,MAAMyB;WAAS,EAAA,CAAA;UAAA;UAAA,IAAAd,WAAA;WAAA,OAAAV,gBAIvER,qBAAmB;YAAA,IAACiC,QAAK;aAAA,OAAE1B,MAAMwB;YAAU;YAAA,IAAEG,OAAI;aAAA,OAAE3B,MAAMyB;YAAS;WAAA,CAAA;UAAA;SAAA,CAAA,CAAA;SAAA,OAAAR;QAAA,EAAA,CAAA,UAAA;SAAA,IAAAW,QAAAC,QAAA;SAAAV,OAAAS,aAGhEpB,OAAOZ,KAAK;SAAA,OAAAgC;QAAA,EAAA,CAAA,CAAA;OAAA;MAAA,CAAA,CAAA;KAAA;IAAA,CAAA;GAGxB,CAAA;EAAA;CAAA,CAAA;AAIT;AAEA,SAAgBE,cAAc9B,OAA8B;CAC1D,MAAM+B,eACJ/B,MAAME,MAAM8B,WAAW,WACvB,CAAChC,MAAMiC,cAAcC,MAAM1B,WAAWA,OAAO2B,OAAOnC,MAAME,MAAM8B,MAAM;CACxE,MAAMI,wBAAyBL,OAAO,IAAI,WAAW/B,MAAME,MAAM8B;CACjE,OAAA/B,gBACGb,YAAK;EAAA,IACJO,QAAK;GAAA,OAAEyC,gBAAgB;EAAC;EAAA,IACxBhC,WAAQ;GAAA,OAAEJ,MAAMK;EAAM;EACtBC,aAAW;EAAA,cAAA;EAAA,SAAA;EAGXC,WAAWyB,WACThC,MAAMO,SAAS,EACbyB,QAAQA,WAAW,WAAYhC,MAAMqC,qBAAqB,KAAML,OAClE,CAAC;EAAC,IAAArB,WAAA;GAAA,OAAA;IAAAV,gBAGHb,WAAMyB,MAAI;KAAClB,OAAK;KAAA,IAAAgB,WAAA;MAAA,OAAA,CAAAV,gBACdb,WAAM2B,WAAS,CAAA,CAAA,GAAAd,gBACfb,WAAM4B,WAAS;OAAA,SAAA;OAAAL,UAAA;MAAA,CAAA,CAAA;KAAA;IAAA,CAAA;IAAAV,gBAIjBZ,KAAG;KAAA,IAACuB,OAAI;MAAA,OAAEZ,MAAMiC;KAAa;KAAAtB,WAC1BH,WAAMP,gBACLb,WAAMyB,MAAI;MAAA,IACTlB,QAAK;OAAA,OAAEa,OAAO2B;MAAE;MAAA,SAAA;MAAA,IAAAxB,WAAA;OAAA,OAAA,CAAAV,gBAGfb,WAAM2B,WAAS,CAAA,CAAA,GAAAd,gBACfb,WAAM4B,WAAS;QAAA,SAAA;QAAA,IAAAL,WAAA;SAAA,OAAA,QAAA;UAAA,IAAA2B,QAAAC,QAAA;UAAAC,QAAAC,QAAAC,iBAAAJ,OAAA,qBAMPtC,MAAME,MAAMC,SAAS,WAClBH,MAAM2C,qBACN3C,MAAME,MAAMC,UAAU,UACtBK,OAAOkB,QACPlB,OAAOmB,IAAI,CAAA;UAAA,OAAAW;SAAA,EAAA,CAAA,UAAA;UAAA,IAAAM,QAAAC,QAAA;UAAA1B,OAAAyB,aAGEpC,OAAOZ,KAAK;UAAA,OAAAgD;SAAA,EAAA,CAAA,CAAA;QAAA;OAAA,CAAA,CAAA;MAAA;KAAA,CAAA;IAGxC,CAAA;IAAA3C,gBAEFb,WAAMyB,MAAI;KAAClB,OAAK;KAAA,IAAAgB,WAAA;MAAA,OAAA,CAAAV,gBACdb,WAAM2B,WAAS,CAAA,CAAA,GAAAd,gBACfb,WAAM4B,WAAS;OAAA,SAAA;OAAAL,UAAA;MAAA,CAAA,CAAA;KAAA;IAAA,CAAA;GAAA;EAAA;CAAA,CAAA;AAMxB;AAEA,SAAgBmC,aAAa9C,OAA8B;CACzD,OAAAC,gBACGb,YAAK;EAAA,IACJO,QAAK;GAAA,OAAEK,MAAME,MAAM6C;EAAO;EAAA,IAC1B3C,WAAQ;GAAA,OAAEJ,MAAMK;EAAM;EACtBC,aAAW;EAAA,cAAA;EAAA,SAAA;EAGXC,WAAWwC,YAAY;GACrB,MAAMvC,SAASV,SAASW,MAAMC,cAAcA,UAAUf,UAAUoD,OAAO;GACvE,IAAIvC,QAAQR,MAAMO,SAAS,EAAEwC,SAASvC,OAAOb,MAAM,CAAC;EACtD;EAAC,IAAAgB,WAAA;GAAA,OAAAV,gBAEAZ,KAAG;IAACuB,MAAMd;IAAQa,WACfH,WAAMP,gBACLb,WAAMyB,MAAI;KAAA,IACTlB,QAAK;MAAA,OAAEa,OAAOb;KAAK;KAAA,IACnBS,WAAQ;MAAA,OAAEmB,WAAAf,OAAOb,UAAU,SAAS,CAAA,CAAA,KAAI,CAACK,MAAMgD,kBAAkBC;KAAO;KAAA,SAAA;KAAA,IAAAtC,WAAA;MAAA,OAAA,CAAAV,gBAGvEb,WAAM2B,WAAS,CAAA,CAAA,GAAAd,gBACfb,WAAM4B,WAAS;OAAA,SAAA;OAAA,IAAAL,WAAA;QAAA,OACbH,OAAOZ;OAAK;MAAA,CAAA,CAAA;KAAA;IAAA,CAAA;GAGlB,CAAA;EAAA;CAAA,CAAA;AAIT"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AppearanceEditorProps, AppearancePopoverProps } from './appearance-types';
|
|
2
|
+
/**
|
|
3
|
+
* A live editor whose persistence and preview authority belong to its host.
|
|
4
|
+
* No ThemeProvider is required, and no catalogue, renderer engine or storage is
|
|
5
|
+
* imported. Hosts normalize unknown IDs and custom colors, report recovery,
|
|
6
|
+
* snapshot on open, preview on changes, commit on Save, and restore on dismissal.
|
|
7
|
+
* Both theme rows remain mounted when mode changes. Typeface/density axes are
|
|
8
|
+
* deliberately absent from Adea #425's accepted surface.
|
|
9
|
+
*/
|
|
10
|
+
export declare function AppearanceEditor(props: AppearanceEditorProps): import("solid-js").JSX.Element;
|
|
11
|
+
/** Modal anchoring/dismissal and nested-listbox behavior come from Kobalte.
|
|
12
|
+
* Its measured available height also bounds scrolling, keeping footer actions
|
|
13
|
+
* reachable when a narrow popup begins below its trigger. */
|
|
14
|
+
export declare function AppearancePopover(props: AppearancePopoverProps): import("solid-js").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=appearance-editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appearance-editor.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/appearance-editor.tsx"],"names":[],"mappings":"AA+CA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAIvF;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,kCAqJ5D;AAED;;6DAE6D;AAC7D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,kCAyB9D"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { Button } from "../../ui/button/button.js";
|
|
3
|
+
import { Input } from "../../ui/input/input.js";
|
|
4
|
+
import { Popover, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger } from "../../ui/popover/popover.js";
|
|
5
|
+
import { Switch } from "../../ui/switch/switch.js";
|
|
6
|
+
import { AccentChoices, GlassChoices, ModeChoices } from "./appearance-choices.js";
|
|
7
|
+
import { SettingsRow, ThemeRow } from "./appearance-rows.js";
|
|
8
|
+
import { className, createComponent, effect, insert, memo, setAttribute, template } from "solid-js/web";
|
|
9
|
+
import { EyeOff, Palette, PanelsTopLeft, SlidersHorizontal } from "lucide-solid";
|
|
10
|
+
import { Show, createUniqueId } from "solid-js";
|
|
11
|
+
//#region src/components/composites/appearance-editor/appearance-editor.tsx
|
|
12
|
+
var _tmpl$ = /*#__PURE__*/ template(`<p role=status class="px-4 py-2 text-sm text-muted-foreground">`);
|
|
13
|
+
var _tmpl$2 = /*#__PURE__*/ template(`<p role=alert class="mt-1 text-xs text-destructive">`);
|
|
14
|
+
var _tmpl$3 = /*#__PURE__*/ template(`<div class="px-4 py-3"><label class="mb-2 block text-xs font-medium">Custom accent`);
|
|
15
|
+
var _tmpl$4 = /*#__PURE__*/ template(`<p role=status class="px-4 py-2 text-xs text-muted-foreground">`);
|
|
16
|
+
var _tmpl$5 = /*#__PURE__*/ template(`<p role=status class="px-4 pt-3 text-xs text-muted-foreground">`);
|
|
17
|
+
var _tmpl$6 = /*#__PURE__*/ template(`<div data-appearance-editor><div class="divide-y divide-border rounded-lg border"></div><div class="flex flex-wrap items-center gap-2 px-4 py-4"><div class="ml-auto flex gap-2">`);
|
|
18
|
+
/**
|
|
19
|
+
* A live editor whose persistence and preview authority belong to its host.
|
|
20
|
+
* No ThemeProvider is required, and no catalogue, renderer engine or storage is
|
|
21
|
+
* imported. Hosts normalize unknown IDs and custom colors, report recovery,
|
|
22
|
+
* snapshot on open, preview on changes, commit on Save, and restore on dismissal.
|
|
23
|
+
* Both theme rows remain mounted when mode changes. Typeface/density axes are
|
|
24
|
+
* deliberately absent from Adea #425's accepted surface.
|
|
25
|
+
*/
|
|
26
|
+
function AppearanceEditor(props) {
|
|
27
|
+
const errorId = createUniqueId();
|
|
28
|
+
const saveReasonId = createUniqueId();
|
|
29
|
+
const custom = () => props.draft.accent !== "theme" && !props.accentOptions.some((option) => option.id === props.draft.accent);
|
|
30
|
+
const accentDescription = () => {
|
|
31
|
+
if (props.draft.accent === "theme") return "Theme default · Uses the palette's intended color.";
|
|
32
|
+
return `${props.accentOptions.find((option) => option.id === props.draft.accent)?.label ?? "Custom"} · Controls, glyphs, selections, code, and activity.`;
|
|
33
|
+
};
|
|
34
|
+
const glassDescription = () => props.draft.surface === "opaque" ? "Solid surfaces for every theme." : props.draft.surface === "frosted" ? "Theme-colored glass where supported." : props.surfaceCapability.themeDefaultDescription ?? "Uses this theme's default surface.";
|
|
35
|
+
return (() => {
|
|
36
|
+
var _el$ = _tmpl$6(), _el$3 = _el$.firstChild, _el$9 = _el$3.nextSibling, _el$0 = _el$9.firstChild;
|
|
37
|
+
insert(_el$, createComponent(Show, {
|
|
38
|
+
get when() {
|
|
39
|
+
return props.recoveryNotice;
|
|
40
|
+
},
|
|
41
|
+
get children() {
|
|
42
|
+
var _el$2 = _tmpl$();
|
|
43
|
+
insert(_el$2, () => props.recoveryNotice);
|
|
44
|
+
return _el$2;
|
|
45
|
+
}
|
|
46
|
+
}), _el$3);
|
|
47
|
+
insert(_el$, createComponent(ModeChoices, props), _el$3);
|
|
48
|
+
insert(_el$3, createComponent(ThemeRow, {
|
|
49
|
+
appearance: "light",
|
|
50
|
+
get selectedId() {
|
|
51
|
+
return props.draft.lightThemeId;
|
|
52
|
+
},
|
|
53
|
+
get preview() {
|
|
54
|
+
return props.lightTheme;
|
|
55
|
+
},
|
|
56
|
+
get themes() {
|
|
57
|
+
return props.themes;
|
|
58
|
+
},
|
|
59
|
+
get disabled() {
|
|
60
|
+
return props.saving;
|
|
61
|
+
},
|
|
62
|
+
onSelect: (lightThemeId) => props.onChange({ lightThemeId })
|
|
63
|
+
}), null);
|
|
64
|
+
insert(_el$3, createComponent(ThemeRow, {
|
|
65
|
+
appearance: "dark",
|
|
66
|
+
get selectedId() {
|
|
67
|
+
return props.draft.darkThemeId;
|
|
68
|
+
},
|
|
69
|
+
get preview() {
|
|
70
|
+
return props.darkTheme;
|
|
71
|
+
},
|
|
72
|
+
get themes() {
|
|
73
|
+
return props.themes;
|
|
74
|
+
},
|
|
75
|
+
get disabled() {
|
|
76
|
+
return props.saving;
|
|
77
|
+
},
|
|
78
|
+
onSelect: (darkThemeId) => props.onChange({ darkThemeId })
|
|
79
|
+
}), null);
|
|
80
|
+
insert(_el$3, createComponent(SettingsRow, {
|
|
81
|
+
stacked: true,
|
|
82
|
+
title: "Accent",
|
|
83
|
+
get icon() {
|
|
84
|
+
return createComponent(SlidersHorizontal, {});
|
|
85
|
+
},
|
|
86
|
+
get description() {
|
|
87
|
+
return accentDescription();
|
|
88
|
+
},
|
|
89
|
+
get children() {
|
|
90
|
+
return createComponent(AccentChoices, props);
|
|
91
|
+
}
|
|
92
|
+
}), null);
|
|
93
|
+
insert(_el$3, createComponent(Show, {
|
|
94
|
+
get when() {
|
|
95
|
+
return custom();
|
|
96
|
+
},
|
|
97
|
+
get children() {
|
|
98
|
+
var _el$4 = _tmpl$3(), _el$5 = _el$4.firstChild;
|
|
99
|
+
setAttribute(_el$5, "for", `${errorId}-input`);
|
|
100
|
+
insert(_el$4, createComponent(Input, {
|
|
101
|
+
id: `${errorId}-input`,
|
|
102
|
+
get value() {
|
|
103
|
+
return props.draft.accent;
|
|
104
|
+
},
|
|
105
|
+
get disabled() {
|
|
106
|
+
return props.saving;
|
|
107
|
+
},
|
|
108
|
+
get ["aria-invalid"]() {
|
|
109
|
+
return !!props.customAccentError;
|
|
110
|
+
},
|
|
111
|
+
get ["aria-describedby"]() {
|
|
112
|
+
return props.customAccentError ? errorId : void 0;
|
|
113
|
+
},
|
|
114
|
+
onInput: (event) => props.onChange({ accent: event.currentTarget.value })
|
|
115
|
+
}), null);
|
|
116
|
+
insert(_el$4, createComponent(Show, {
|
|
117
|
+
get when() {
|
|
118
|
+
return props.customAccentError;
|
|
119
|
+
},
|
|
120
|
+
get children() {
|
|
121
|
+
var _el$6 = _tmpl$2();
|
|
122
|
+
setAttribute(_el$6, "id", errorId);
|
|
123
|
+
insert(_el$6, () => props.customAccentError);
|
|
124
|
+
return _el$6;
|
|
125
|
+
}
|
|
126
|
+
}), null);
|
|
127
|
+
return _el$4;
|
|
128
|
+
}
|
|
129
|
+
}), null);
|
|
130
|
+
insert(_el$3, createComponent(SettingsRow, {
|
|
131
|
+
title: "Glass",
|
|
132
|
+
get icon() {
|
|
133
|
+
return createComponent(PanelsTopLeft, {});
|
|
134
|
+
},
|
|
135
|
+
get description() {
|
|
136
|
+
return glassDescription();
|
|
137
|
+
},
|
|
138
|
+
get children() {
|
|
139
|
+
return createComponent(GlassChoices, props);
|
|
140
|
+
}
|
|
141
|
+
}), null);
|
|
142
|
+
insert(_el$3, createComponent(Show, {
|
|
143
|
+
get when() {
|
|
144
|
+
return memo(() => !!!props.surfaceCapability.frosted)() && props.surfaceCapability.reason;
|
|
145
|
+
},
|
|
146
|
+
get children() {
|
|
147
|
+
var _el$7 = _tmpl$4();
|
|
148
|
+
insert(_el$7, () => props.surfaceCapability.reason);
|
|
149
|
+
return _el$7;
|
|
150
|
+
}
|
|
151
|
+
}), null);
|
|
152
|
+
insert(_el$3, createComponent(SettingsRow, {
|
|
153
|
+
title: "Reduce transparency",
|
|
154
|
+
get icon() {
|
|
155
|
+
return createComponent(EyeOff, {});
|
|
156
|
+
},
|
|
157
|
+
description: "Prefer solid surfaces, including during live preview.",
|
|
158
|
+
get children() {
|
|
159
|
+
return createComponent(Switch, {
|
|
160
|
+
get checked() {
|
|
161
|
+
return props.draft.reduceTransparency;
|
|
162
|
+
},
|
|
163
|
+
get disabled() {
|
|
164
|
+
return props.saving;
|
|
165
|
+
},
|
|
166
|
+
onChange: (reduceTransparency) => props.onChange({ reduceTransparency }),
|
|
167
|
+
"aria-label": "Reduce transparency"
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}), null);
|
|
171
|
+
insert(_el$3, createComponent(SettingsRow, {
|
|
172
|
+
title: "Theme library",
|
|
173
|
+
get icon() {
|
|
174
|
+
return createComponent(Palette, {});
|
|
175
|
+
},
|
|
176
|
+
get description() {
|
|
177
|
+
return props.onManageThemes ? "Manage themes through the application." : "Theme import is unavailable.";
|
|
178
|
+
},
|
|
179
|
+
get children() {
|
|
180
|
+
return createComponent(Button, {
|
|
181
|
+
type: "button",
|
|
182
|
+
size: "sm",
|
|
183
|
+
variant: "outline",
|
|
184
|
+
get disabled() {
|
|
185
|
+
return !props.onManageThemes || props.saving;
|
|
186
|
+
},
|
|
187
|
+
onClick: () => props.onManageThemes?.(),
|
|
188
|
+
children: "Manage themes"
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}), null);
|
|
192
|
+
insert(_el$, createComponent(Show, {
|
|
193
|
+
get when() {
|
|
194
|
+
return props.saveDisabledReason;
|
|
195
|
+
},
|
|
196
|
+
get children() {
|
|
197
|
+
var _el$8 = _tmpl$5();
|
|
198
|
+
setAttribute(_el$8, "id", saveReasonId);
|
|
199
|
+
insert(_el$8, () => props.saveDisabledReason);
|
|
200
|
+
return _el$8;
|
|
201
|
+
}
|
|
202
|
+
}), _el$9);
|
|
203
|
+
insert(_el$9, createComponent(Button, {
|
|
204
|
+
type: "button",
|
|
205
|
+
size: "sm",
|
|
206
|
+
variant: "ghost",
|
|
207
|
+
get disabled() {
|
|
208
|
+
return props.saving;
|
|
209
|
+
},
|
|
210
|
+
onClick: () => props.onReset(),
|
|
211
|
+
children: "Reset"
|
|
212
|
+
}), _el$0);
|
|
213
|
+
insert(_el$0, createComponent(Button, {
|
|
214
|
+
type: "button",
|
|
215
|
+
size: "sm",
|
|
216
|
+
variant: "outline",
|
|
217
|
+
get disabled() {
|
|
218
|
+
return props.saving;
|
|
219
|
+
},
|
|
220
|
+
onClick: () => props.onCancel(),
|
|
221
|
+
children: "Cancel"
|
|
222
|
+
}), null);
|
|
223
|
+
insert(_el$0, createComponent(Button, {
|
|
224
|
+
type: "button",
|
|
225
|
+
size: "sm",
|
|
226
|
+
get disabled() {
|
|
227
|
+
return props.saving || !!props.customAccentError || !!props.saveDisabledReason;
|
|
228
|
+
},
|
|
229
|
+
get ["aria-busy"]() {
|
|
230
|
+
return props.saving;
|
|
231
|
+
},
|
|
232
|
+
get ["aria-describedby"]() {
|
|
233
|
+
return props.saveDisabledReason ? saveReasonId : void 0;
|
|
234
|
+
},
|
|
235
|
+
onClick: () => props.onSave(),
|
|
236
|
+
get children() {
|
|
237
|
+
return props.saving ? "Saving…" : "Save";
|
|
238
|
+
}
|
|
239
|
+
}), null);
|
|
240
|
+
effect(() => className(_el$, cn("min-w-0", props.class)));
|
|
241
|
+
return _el$;
|
|
242
|
+
})();
|
|
243
|
+
}
|
|
244
|
+
/** Modal anchoring/dismissal and nested-listbox behavior come from Kobalte.
|
|
245
|
+
* Its measured available height also bounds scrolling, keeping footer actions
|
|
246
|
+
* reachable when a narrow popup begins below its trigger. */
|
|
247
|
+
function AppearancePopover(props) {
|
|
248
|
+
return createComponent(Popover, {
|
|
249
|
+
get open() {
|
|
250
|
+
return props.open;
|
|
251
|
+
},
|
|
252
|
+
modal: true,
|
|
253
|
+
onOpenChange: (open) => open ? props.onOpen() : props.onDismiss(),
|
|
254
|
+
get children() {
|
|
255
|
+
return [createComponent(PopoverTrigger, {
|
|
256
|
+
as: Button,
|
|
257
|
+
type: "button",
|
|
258
|
+
variant: "ghost",
|
|
259
|
+
size: "icon-sm",
|
|
260
|
+
"aria-label": "Appearance settings",
|
|
261
|
+
get children() {
|
|
262
|
+
return createComponent(Palette, {});
|
|
263
|
+
}
|
|
264
|
+
}), createComponent(PopoverContent, {
|
|
265
|
+
"class": "w-lg max-w-[calc(100vw-2rem)] max-h-(--kb-popper-content-available-height) overflow-y-auto",
|
|
266
|
+
get children() {
|
|
267
|
+
return [
|
|
268
|
+
createComponent(PopoverTitle, { children: "Appearance" }),
|
|
269
|
+
createComponent(PopoverDescription, { children: "Changes preview immediately. Save keeps them; Cancel restores the previous appearance." }),
|
|
270
|
+
createComponent(AppearanceEditor, props)
|
|
271
|
+
];
|
|
272
|
+
}
|
|
273
|
+
})];
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
//#endregion
|
|
278
|
+
export { AppearanceEditor, AppearancePopover };
|
|
279
|
+
|
|
280
|
+
//# sourceMappingURL=appearance-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appearance-editor.js","names":["EyeOff","Palette","PanelsTopLeft","SlidersHorizontal","Show","createUniqueId","cn","Button","Input","Switch","Popover","PopoverContent","PopoverDescription","PopoverTitle","PopoverTrigger","AppearanceEditorProps","AppearancePopoverProps","ModeChoices","AccentChoices","GlassChoices","SettingsRow","ThemeRow","AppearanceEditor","props","errorId","saveReasonId","custom","draft","accent","accentOptions","some","option","id","accentDescription","name","find","label","glassDescription","surface","surfaceCapability","themeDefaultDescription","_el$","_tmpl$6","_el$3","firstChild","_el$9","nextSibling","_el$0","_$insert","_$createComponent","when","recoveryNotice","children","_el$2","_tmpl$","appearance","selectedId","lightThemeId","preview","lightTheme","themes","disabled","saving","onSelect","onChange","darkThemeId","darkTheme","stacked","title","icon","description","_el$4","_tmpl$3","_el$5","_$setAttribute","value","aria-invalid","customAccentError","aria-describedby","undefined","onInput","event","currentTarget","_el$6","_tmpl$2","_$memo","frosted","reason","_el$7","_tmpl$4","checked","reduceTransparency","onManageThemes","type","size","variant","onClick","saveDisabledReason","_el$8","_tmpl$5","onReset","onCancel","aria-busy","onSave","_$effect","_$className","class","AppearancePopover","open","modal","onOpenChange","onOpen","onDismiss","as","_$createComponent","_$memo","_$className"],"sources":["../../../../src/components/composites/appearance-editor/appearance-editor.tsx"],"sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2026 Wing\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n/*\n * Composition substantially translated from Zeron settings/appearance.rs and\n * settings/widgets.rs, pinned at 30a9a9537c5ec96226c87f4bf349b6f77c5dfb59,\n * preserving Adea's existing appearance-surface.tsx port: System/Light/Dark\n * miniatures, compact independent theme rows, accent swatches and helper copy,\n * glass chips, and theme library affordance. Kobalte replaces the port's manual\n * radio keyboard model. The controlled draft and explicit action ports replace\n * GPUI globals and app-specific storage/native authority. Save/Cancel/Reset and\n * custom accent/reduced-transparency are accepted Adea divergences (#425).\n */\nimport { EyeOff, Palette, PanelsTopLeft, SlidersHorizontal } from 'lucide-solid'\nimport { Show, createUniqueId } from 'solid-js'\nimport { cn } from '#lib/utils'\nimport { Button } from '../../ui/button/button'\nimport { Input } from '../../ui/input/input'\n\nimport { Switch } from '../../ui/switch/switch'\nimport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverTitle,\n PopoverTrigger,\n} from '../../ui/popover/popover'\nimport type { AppearanceEditorProps, AppearancePopoverProps } from './appearance-types'\nimport { ModeChoices, AccentChoices, GlassChoices } from './appearance-choices'\nimport { SettingsRow, ThemeRow } from './appearance-rows'\n\n/**\n * A live editor whose persistence and preview authority belong to its host.\n * No ThemeProvider is required, and no catalogue, renderer engine or storage is\n * imported. Hosts normalize unknown IDs and custom colors, report recovery,\n * snapshot on open, preview on changes, commit on Save, and restore on dismissal.\n * Both theme rows remain mounted when mode changes. Typeface/density axes are\n * deliberately absent from Adea #425's accepted surface.\n */\nexport function AppearanceEditor(props: AppearanceEditorProps) {\n const errorId = createUniqueId()\n const saveReasonId = createUniqueId()\n const custom = () =>\n props.draft.accent !== 'theme' &&\n !props.accentOptions.some((option) => option.id === props.draft.accent)\n const accentDescription = () => {\n if (props.draft.accent === 'theme') return \"Theme default · Uses the palette's intended color.\"\n const name = props.accentOptions.find((option) => option.id === props.draft.accent)?.label\n return `${name ?? 'Custom'} · Controls, glyphs, selections, code, and activity.`\n }\n const glassDescription = () =>\n props.draft.surface === 'opaque'\n ? 'Solid surfaces for every theme.'\n : props.draft.surface === 'frosted'\n ? 'Theme-colored glass where supported.'\n : (props.surfaceCapability.themeDefaultDescription ?? \"Uses this theme's default surface.\")\n return (\n <div data-appearance-editor class={cn('min-w-0', props.class)}>\n <Show when={props.recoveryNotice}>\n <p role=\"status\" class=\"px-4 py-2 text-sm text-muted-foreground\">\n {props.recoveryNotice}\n </p>\n </Show>\n <ModeChoices {...props} />\n <div class=\"divide-y divide-border rounded-lg border\">\n <ThemeRow\n appearance=\"light\"\n selectedId={props.draft.lightThemeId}\n preview={props.lightTheme}\n themes={props.themes}\n disabled={props.saving}\n onSelect={(lightThemeId) => props.onChange({ lightThemeId })}\n />\n <ThemeRow\n appearance=\"dark\"\n selectedId={props.draft.darkThemeId}\n preview={props.darkTheme}\n themes={props.themes}\n disabled={props.saving}\n onSelect={(darkThemeId) => props.onChange({ darkThemeId })}\n />\n <SettingsRow\n stacked\n title=\"Accent\"\n icon={<SlidersHorizontal />}\n description={accentDescription()}\n >\n <AccentChoices {...props} />\n </SettingsRow>\n <Show when={custom()}>\n <div class=\"px-4 py-3\">\n <label class=\"mb-2 block text-xs font-medium\" for={`${errorId}-input`}>\n Custom accent\n </label>\n <Input\n id={`${errorId}-input`}\n value={props.draft.accent}\n disabled={props.saving}\n aria-invalid={!!props.customAccentError}\n aria-describedby={props.customAccentError ? errorId : undefined}\n onInput={(event) => props.onChange({ accent: event.currentTarget.value })}\n />\n <Show when={props.customAccentError}>\n <p id={errorId} role=\"alert\" class=\"mt-1 text-xs text-destructive\">\n {props.customAccentError}\n </p>\n </Show>\n </div>\n </Show>\n <SettingsRow title=\"Glass\" icon={<PanelsTopLeft />} description={glassDescription()}>\n <GlassChoices {...props} />\n </SettingsRow>\n <Show when={!props.surfaceCapability.frosted && props.surfaceCapability.reason}>\n <p role=\"status\" class=\"px-4 py-2 text-xs text-muted-foreground\">\n {props.surfaceCapability.reason}\n </p>\n </Show>\n <SettingsRow\n title=\"Reduce transparency\"\n icon={<EyeOff />}\n description=\"Prefer solid surfaces, including during live preview.\"\n >\n <Switch\n checked={props.draft.reduceTransparency}\n disabled={props.saving}\n onChange={(reduceTransparency: boolean) => props.onChange({ reduceTransparency })}\n aria-label=\"Reduce transparency\"\n />\n </SettingsRow>\n <SettingsRow\n title=\"Theme library\"\n icon={<Palette />}\n description={\n props.onManageThemes\n ? 'Manage themes through the application.'\n : 'Theme import is unavailable.'\n }\n >\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={!props.onManageThemes || props.saving}\n onClick={() => props.onManageThemes?.()}\n >\n Manage themes\n </Button>\n </SettingsRow>\n </div>\n <Show when={props.saveDisabledReason}>\n <p id={saveReasonId} role=\"status\" class=\"px-4 pt-3 text-xs text-muted-foreground\">\n {props.saveDisabledReason}\n </p>\n </Show>\n <div class=\"flex flex-wrap items-center gap-2 px-4 py-4\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n disabled={props.saving}\n onClick={() => props.onReset()}\n >\n Reset\n </Button>\n <div class=\"ml-auto flex gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={props.saving}\n onClick={() => props.onCancel()}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={props.saving || !!props.customAccentError || !!props.saveDisabledReason}\n aria-busy={props.saving}\n aria-describedby={props.saveDisabledReason ? saveReasonId : undefined}\n onClick={() => props.onSave()}\n >\n {props.saving ? 'Saving…' : 'Save'}\n </Button>\n </div>\n </div>\n </div>\n )\n}\n\n/** Modal anchoring/dismissal and nested-listbox behavior come from Kobalte.\n * Its measured available height also bounds scrolling, keeping footer actions\n * reachable when a narrow popup begins below its trigger. */\nexport function AppearancePopover(props: AppearancePopoverProps) {\n return (\n <Popover\n open={props.open}\n modal\n onOpenChange={(open) => (open ? props.onOpen() : props.onDismiss())}\n >\n <PopoverTrigger\n as={Button}\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label=\"Appearance settings\"\n >\n <Palette />\n </PopoverTrigger>\n <PopoverContent class=\"w-lg max-w-[calc(100vw-2rem)] max-h-(--kb-popper-content-available-height) overflow-y-auto\">\n <PopoverTitle>Appearance</PopoverTitle>\n <PopoverDescription>\n Changes preview immediately. Save keeps them; Cancel restores the previous appearance.\n </PopoverDescription>\n <AppearanceEditor {...props} />\n </PopoverContent>\n </Popover>\n )\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AdeaTheme, AdeaThemeRecord } from '@adea-ai/themes';
|
|
2
|
+
import { type JSX } from 'solid-js';
|
|
3
|
+
export declare function SettingsRow(props: {
|
|
4
|
+
title: string;
|
|
5
|
+
icon: JSX.Element;
|
|
6
|
+
description?: JSX.Element;
|
|
7
|
+
stacked?: boolean;
|
|
8
|
+
children: JSX.Element;
|
|
9
|
+
}): JSX.Element;
|
|
10
|
+
export declare function ThemeRow(props: {
|
|
11
|
+
appearance: 'light' | 'dark';
|
|
12
|
+
selectedId: string;
|
|
13
|
+
preview: AdeaTheme;
|
|
14
|
+
themes: readonly AdeaThemeRecord[];
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
onSelect: (id: string) => void;
|
|
17
|
+
}): JSX.Element;
|
|
18
|
+
//# sourceMappingURL=appearance-rows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appearance-rows.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/appearance-rows.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAkC,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAYnE,wBAAgB,WAAW,CAAC,KAAK,EAAE;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,GAAG,CAAC,OAAO,CAAA;IACjB,WAAW,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACzB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;CACtB,eAsBA;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAC9B,UAAU,EAAE,OAAO,GAAG,MAAM,CAAA;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,SAAS,CAAA;IAClB,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B,eA8CA"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../ui/select/select.js";
|
|
3
|
+
import { PalettePreview } from "./theme-preview.js";
|
|
4
|
+
import { className, createComponent, effect, insert, memo, template, use } from "solid-js/web";
|
|
5
|
+
import { Palette } from "lucide-solid";
|
|
6
|
+
import { Show, createMemo, createSignal } from "solid-js";
|
|
7
|
+
//#region src/components/composites/appearance-editor/appearance-rows.tsx
|
|
8
|
+
var _tmpl$ = /*#__PURE__*/ template(`<div class="mt-0.5 text-xs text-muted-foreground">`);
|
|
9
|
+
var _tmpl$2 = /*#__PURE__*/ template(`<section><div class="flex min-w-0 flex-1 items-center gap-3"><span class="flex size-9 shrink-0 items-center justify-center rounded-lg border bg-foreground/5 text-muted-foreground [&_svg]:size-4"aria-hidden=true></span><div class=min-w-0><h3 class="text-sm font-medium"></h3></div></div><div class="min-w-0 shrink-0">`);
|
|
10
|
+
var _tmpl$3 = /*#__PURE__*/ template(`<div>`);
|
|
11
|
+
var _tmpl$4 = /*#__PURE__*/ template(`<span>`);
|
|
12
|
+
function SettingsRow(props) {
|
|
13
|
+
return (() => {
|
|
14
|
+
var _el$ = _tmpl$2(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$4.firstChild, _el$7 = _el$2.nextSibling;
|
|
15
|
+
insert(_el$3, () => props.icon);
|
|
16
|
+
insert(_el$5, () => props.title);
|
|
17
|
+
insert(_el$4, createComponent(Show, {
|
|
18
|
+
get when() {
|
|
19
|
+
return props.description;
|
|
20
|
+
},
|
|
21
|
+
get children() {
|
|
22
|
+
var _el$6 = _tmpl$();
|
|
23
|
+
insert(_el$6, () => props.description);
|
|
24
|
+
return _el$6;
|
|
25
|
+
}
|
|
26
|
+
}), null);
|
|
27
|
+
insert(_el$7, () => props.children);
|
|
28
|
+
effect(() => className(_el$, cn("flex flex-col gap-3 px-4 py-4", { "sm:flex-row sm:items-center": !props.stacked })));
|
|
29
|
+
return _el$;
|
|
30
|
+
})();
|
|
31
|
+
}
|
|
32
|
+
function ThemeRow(props) {
|
|
33
|
+
const [portalMount, setPortalMount] = createSignal();
|
|
34
|
+
const options = createMemo(() => props.themes.filter((theme) => theme.appearance === props.appearance));
|
|
35
|
+
const selected = createMemo(() => options().find((theme) => theme.id === props.selectedId) ?? options().find((theme) => theme.id === props.preview.id));
|
|
36
|
+
const label = () => props.appearance === "light" ? "Light theme" : "Dark theme";
|
|
37
|
+
return createComponent(SettingsRow, {
|
|
38
|
+
get title() {
|
|
39
|
+
return label();
|
|
40
|
+
},
|
|
41
|
+
get icon() {
|
|
42
|
+
return createComponent(Palette, {});
|
|
43
|
+
},
|
|
44
|
+
get children() {
|
|
45
|
+
var _el$8 = _tmpl$3();
|
|
46
|
+
use(setPortalMount, _el$8);
|
|
47
|
+
insert(_el$8, createComponent(Select, {
|
|
48
|
+
modal: false,
|
|
49
|
+
get options() {
|
|
50
|
+
return options();
|
|
51
|
+
},
|
|
52
|
+
get value() {
|
|
53
|
+
return selected();
|
|
54
|
+
},
|
|
55
|
+
optionValue: "id",
|
|
56
|
+
optionTextValue: "name",
|
|
57
|
+
get disabled() {
|
|
58
|
+
return props.disabled || options().length === 0;
|
|
59
|
+
},
|
|
60
|
+
onChange: (theme) => {
|
|
61
|
+
if (theme) props.onSelect(theme.id);
|
|
62
|
+
},
|
|
63
|
+
itemComponent: (item) => createComponent(SelectItem, {
|
|
64
|
+
get item() {
|
|
65
|
+
return item.item;
|
|
66
|
+
},
|
|
67
|
+
get children() {
|
|
68
|
+
return [createComponent(PalettePreview, { get theme() {
|
|
69
|
+
return item.item.rawValue;
|
|
70
|
+
} }), memo(() => item.item.rawValue.name)];
|
|
71
|
+
}
|
|
72
|
+
}),
|
|
73
|
+
get children() {
|
|
74
|
+
return [createComponent(SelectTrigger, {
|
|
75
|
+
size: "sm",
|
|
76
|
+
get ["aria-label"]() {
|
|
77
|
+
return label();
|
|
78
|
+
},
|
|
79
|
+
"class": "w-full sm:w-52",
|
|
80
|
+
get children() {
|
|
81
|
+
return createComponent(SelectValue, { children: () => [createComponent(PalettePreview, { get theme() {
|
|
82
|
+
return props.preview;
|
|
83
|
+
} }), (() => {
|
|
84
|
+
var _el$9 = _tmpl$4();
|
|
85
|
+
insert(_el$9, () => selected()?.name ?? props.preview.name);
|
|
86
|
+
return _el$9;
|
|
87
|
+
})()] });
|
|
88
|
+
}
|
|
89
|
+
}), createComponent(SelectContent, { get portalMount() {
|
|
90
|
+
return portalMount();
|
|
91
|
+
} })];
|
|
92
|
+
}
|
|
93
|
+
}));
|
|
94
|
+
return _el$8;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
export { SettingsRow, ThemeRow };
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=appearance-rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appearance-rows.js","names":["AdeaTheme","AdeaThemeRecord","Show","createMemo","createSignal","JSX","Palette","cn","Select","SelectContent","SelectItem","SelectTrigger","SelectValue","PalettePreview","SettingsRow","props","title","icon","Element","description","stacked","children","_el$","_tmpl$2","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_el$7","_$insert","_$createComponent","when","_el$6","_tmpl$","_$effect","_$className","ThemeRow","appearance","selectedId","preview","themes","disabled","onSelect","id","portalMount","setPortalMount","HTMLDivElement","options","filter","theme","selected","find","label","_el$8","_tmpl$3","_$use","modal","value","optionValue","optionTextValue","length","onChange","itemComponent","item","rawValue","_$memo","name","size","aria-label","_el$9","_tmpl$4","_$createComponent","_$className","_$memo"],"sources":["../../../../src/components/composites/appearance-editor/appearance-rows.tsx"],"sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2026 Wing\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n// Retains the compact divided row and palette-preview selector from the pinned\n// Zeron/Adea composition; Kobalte owns option navigation and nested dismissal.\nimport type { AdeaTheme, AdeaThemeRecord } from '@adea-ai/themes'\nimport { Show, createMemo, createSignal, type JSX } from 'solid-js'\nimport { Palette } from 'lucide-solid'\nimport { cn } from '#lib/utils'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../../ui/select/select'\nimport { PalettePreview } from './theme-preview'\n\nexport function SettingsRow(props: {\n title: string\n icon: JSX.Element\n description?: JSX.Element\n stacked?: boolean\n children: JSX.Element\n}) {\n return (\n <section\n class={cn('flex flex-col gap-3 px-4 py-4', { 'sm:flex-row sm:items-center': !props.stacked })}\n >\n <div class=\"flex min-w-0 flex-1 items-center gap-3\">\n <span\n class=\"flex size-9 shrink-0 items-center justify-center rounded-lg border bg-foreground/5 text-muted-foreground [&_svg]:size-4\"\n aria-hidden=\"true\"\n >\n {props.icon}\n </span>\n <div class=\"min-w-0\">\n <h3 class=\"text-sm font-medium\">{props.title}</h3>\n <Show when={props.description}>\n <div class=\"mt-0.5 text-xs text-muted-foreground\">{props.description}</div>\n </Show>\n </div>\n </div>\n <div class=\"min-w-0 shrink-0\">{props.children}</div>\n </section>\n )\n}\n\nexport function ThemeRow(props: {\n appearance: 'light' | 'dark'\n selectedId: string\n preview: AdeaTheme\n themes: readonly AdeaThemeRecord[]\n disabled?: boolean\n onSelect: (id: string) => void\n}) {\n const [portalMount, setPortalMount] = createSignal<HTMLDivElement>()\n const options = createMemo(() =>\n props.themes.filter((theme) => theme.appearance === props.appearance)\n )\n const selected = createMemo(\n () =>\n options().find((theme) => theme.id === props.selectedId) ??\n options().find((theme) => theme.id === props.preview.id)\n )\n const label = () => (props.appearance === 'light' ? 'Light theme' : 'Dark theme')\n return (\n <SettingsRow title={label()} icon={<Palette />}>\n <div ref={setPortalMount}>\n <Select\n modal={false}\n options={options()}\n value={selected()}\n optionValue=\"id\"\n optionTextValue=\"name\"\n disabled={props.disabled || options().length === 0}\n onChange={(theme) => {\n if (theme) props.onSelect(theme.id)\n }}\n itemComponent={(item) => (\n <SelectItem item={item.item}>\n <PalettePreview theme={item.item.rawValue} />\n {item.item.rawValue.name}\n </SelectItem>\n )}\n >\n <SelectTrigger size=\"sm\" aria-label={label()} class=\"w-full sm:w-52\">\n <SelectValue>\n {() => (\n <>\n <PalettePreview theme={props.preview} />\n <span>{selected()?.name ?? props.preview.name}</span>\n </>\n )}\n </SelectValue>\n </SelectTrigger>\n <SelectContent portalMount={portalMount()} />\n </Select>\n </div>\n </SettingsRow>\n )\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { AccentPreset, AdeaTheme, AdeaThemeRecord } from '@adea-ai/themes';
|
|
2
|
+
export type AppearanceDraft = Readonly<{
|
|
3
|
+
mode: 'system' | 'light' | 'dark';
|
|
4
|
+
lightThemeId: string;
|
|
5
|
+
darkThemeId: string;
|
|
6
|
+
/** Theme default, a canonical preset id, or the host's custom accent draft. */
|
|
7
|
+
accent: string;
|
|
8
|
+
surface: 'theme' | 'frosted' | 'opaque';
|
|
9
|
+
reduceTransparency: boolean;
|
|
10
|
+
}>;
|
|
11
|
+
export type AppearanceEditorProps = {
|
|
12
|
+
draft: AppearanceDraft;
|
|
13
|
+
/** Resolved preview themes, including the host's validated accent overlay. */
|
|
14
|
+
lightTheme: AdeaTheme;
|
|
15
|
+
darkTheme: AdeaTheme;
|
|
16
|
+
resolvedAppearance: 'light' | 'dark';
|
|
17
|
+
themes: readonly AdeaThemeRecord[];
|
|
18
|
+
accentOptions: readonly AccentPreset[];
|
|
19
|
+
onChange: (patch: Partial<AppearanceDraft>) => void;
|
|
20
|
+
onSave: () => void;
|
|
21
|
+
onCancel: () => void;
|
|
22
|
+
onReset: () => void;
|
|
23
|
+
customAccentError?: string;
|
|
24
|
+
customAccentValue?: string;
|
|
25
|
+
saveDisabledReason?: string;
|
|
26
|
+
saving?: boolean;
|
|
27
|
+
recoveryNotice?: string;
|
|
28
|
+
surfaceCapability: {
|
|
29
|
+
frosted: boolean;
|
|
30
|
+
reason?: string;
|
|
31
|
+
themeDefaultDescription?: string;
|
|
32
|
+
};
|
|
33
|
+
/** Undefined means theme import is unavailable, never a working-looking action. */
|
|
34
|
+
onManageThemes?: () => void;
|
|
35
|
+
class?: string;
|
|
36
|
+
};
|
|
37
|
+
export type AppearancePopoverProps = AppearanceEditorProps & {
|
|
38
|
+
open: boolean;
|
|
39
|
+
onOpen: () => void;
|
|
40
|
+
onDismiss: () => void;
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=appearance-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appearance-types.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/appearance-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAE/E,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAA;IACvC,kBAAkB,EAAE,OAAO,CAAA;CAC5B,CAAC,CAAA;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,eAAe,CAAA;IACtB,8EAA8E;IAC9E,UAAU,EAAE,SAAS,CAAA;IACrB,SAAS,EAAE,SAAS,CAAA;IACpB,kBAAkB,EAAE,OAAO,GAAG,MAAM,CAAA;IACpC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAClC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAA;IACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,CAAA;IACnD,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iBAAiB,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,uBAAuB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1F,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG,qBAAqB,GAAG;IAC3D,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { AppearanceEditor, AppearancePopover } from './appearance-editor';
|
|
2
|
+
export type { AppearanceDraft, AppearanceEditorProps, AppearancePopoverProps, } from './appearance-types';
|
|
3
|
+
export { ThemeMiniature, ThemeMiniatureSplit, PalettePreview, type ThemeMiniatureProps, } from './theme-preview';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACzE,YAAY,EACV,eAAe,EACf,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AdeaTheme } from '@adea-ai/themes';
|
|
2
|
+
export type ThemeMiniatureProps = {
|
|
3
|
+
theme: AdeaTheme;
|
|
4
|
+
corners?: 'all' | 'left' | 'right';
|
|
5
|
+
class?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function ThemeMiniature(props: ThemeMiniatureProps): import("solid-js").JSX.Element;
|
|
8
|
+
export declare function ThemeMiniatureSplit(props: {
|
|
9
|
+
light: AdeaTheme;
|
|
10
|
+
dark: AdeaTheme;
|
|
11
|
+
class?: string;
|
|
12
|
+
}): import("solid-js").JSX.Element;
|
|
13
|
+
export declare function PalettePreview(props: {
|
|
14
|
+
theme: AdeaTheme;
|
|
15
|
+
class?: string;
|
|
16
|
+
}): import("solid-js").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=theme-preview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-preview.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/theme-preview.tsx"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAIhD,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,SAAS,CAAA;IAChB,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAA;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAeD,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,kCAoCxD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,kCAW/F;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,kCAoBzE"}
|