From f3c24ee3c6a392df46801b2df2116142866ebf6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= <43071496+adam-kov@users.noreply.github.com> Date: Fri, 24 Mar 2023 18:26:16 +0100 Subject: [PATCH] feat(frontend): Add quick style settings to app editor (#1308) * feat(frontend): Add app secondary settings menu * refactor(frontend): Separate color picker * save * feat(frontend): Add quick style options * fix(frontend): Handle overflow * feat(frontend): Add suggestions to quick styles * save wip * feat(frontend): Add UI for quick styling * fix(frontend): Handle multi value properties * fix(frontend): Convenience updates * feat(frontend): Add styling properties to components * fix(frontend): Parse inner colors * fix(frontend): Multi value sync * fix(frontend): Correct unit handling * fix(frontend): Correct multivalue handling * remove comments * fix color picker label * feat(frontend): Add box-shadow property * feat(frontend): Add concise unit selector * feat(frontend): Update app labels * remove unused imports * fix width * fix(frontend): App freezing * fix(frontend): Remove unused imports * fix(frontend): Conditional chaining * fix * revert * minor updates * feat(frontend): Add 'apply style to all' button * fix(frontend): Update styling properties * fix(frontend): Styling menu typography update --- frontend/package-lock.json | 31 + frontend/package.json | 1 + .../components/apps/editor/AppEditor.svelte | 26 +- .../components/apps/editor/AppPreview.svelte | 3 +- .../apps/editor/component/README.md | 4 + .../editor/componentsPanel/CssProperty.svelte | 144 ++-- .../componentsPanel/QuickStyleMenu.svelte | 183 +++++ .../componentsPanel/QuickStyleProperty.svelte | 141 ++++ .../componentsPanel/quickStyleProperties.ts | 644 ++++++++++++++++++ .../settingsPanel/ComponentPanel.svelte | 40 +- .../editor/settingsPanel/StylePanel.svelte | 26 + .../inputEditor/ColorInput.svelte | 24 +- .../inputEditor/StaticInputEditor.svelte | 2 +- .../secondaryMenu/SecondaryMenu.svelte | 51 ++ .../settingsPanel/secondaryMenu/index.ts | 2 + .../settingsPanel/secondaryMenu/menuStore.ts | 20 + frontend/src/lib/components/apps/types.ts | 7 +- .../common/button/ButtonPopup.svelte | 7 +- .../common/button/ButtonPopupItem.svelte | 3 +- .../clearableInput/ClearableInput.svelte | 61 ++ frontend/src/lib/components/common/index.ts | 1 + .../src/lib/components/common/kbd/Kbd.svelte | 6 +- .../lib/components/common/menu/Menu.svelte | 10 +- frontend/src/lib/utils.ts | 4 + 24 files changed, 1342 insertions(+), 99 deletions(-) create mode 100644 frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleMenu.svelte create mode 100644 frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleProperty.svelte create mode 100644 frontend/src/lib/components/apps/editor/componentsPanel/quickStyleProperties.ts create mode 100644 frontend/src/lib/components/apps/editor/settingsPanel/StylePanel.svelte create mode 100644 frontend/src/lib/components/apps/editor/settingsPanel/secondaryMenu/SecondaryMenu.svelte create mode 100644 frontend/src/lib/components/apps/editor/settingsPanel/secondaryMenu/index.ts create mode 100644 frontend/src/lib/components/apps/editor/settingsPanel/secondaryMenu/menuStore.ts create mode 100644 frontend/src/lib/components/common/clearableInput/ClearableInput.svelte diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 3d1600632a..a30cc58edc 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -66,6 +66,7 @@ "prettier": "^2.8.3", "prettier-plugin-svelte": "^2.9.0", "simple-svelte-autocomplete": "^2.5.1", + "style-to-object": "^0.4.1", "stylelint-config-recommended": "^9.0.0", "svelte": "^3.55.1", "svelte-awesome": "^3.0.0", @@ -4079,6 +4080,12 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", + "dev": true + }, "node_modules/internmap": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", @@ -6959,6 +6966,15 @@ "dev": true, "peer": true }, + "node_modules/style-to-object": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.1.tgz", + "integrity": "sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==", + "dev": true, + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, "node_modules/stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", @@ -11127,6 +11143,12 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, + "inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", + "dev": true + }, "internmap": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", @@ -13222,6 +13244,15 @@ "dev": true, "peer": true }, + "style-to-object": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.1.tgz", + "integrity": "sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==", + "dev": true, + "requires": { + "inline-style-parser": "0.1.1" + } + }, "stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index 0a856c04e9..179987b40b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -44,6 +44,7 @@ "prettier": "^2.8.3", "prettier-plugin-svelte": "^2.9.0", "simple-svelte-autocomplete": "^2.5.1", + "style-to-object": "^0.4.1", "stylelint-config-recommended": "^9.0.0", "svelte": "^3.55.1", "svelte-awesome": "^3.0.0", diff --git a/frontend/src/lib/components/apps/editor/AppEditor.svelte b/frontend/src/lib/components/apps/editor/AppEditor.svelte index 1fcf6d1f1e..91a919b9fd 100644 --- a/frontend/src/lib/components/apps/editor/AppEditor.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditor.svelte @@ -23,8 +23,7 @@ import TabContent from '$lib/components/common/tabs/TabContent.svelte' import { Alert, Button, Tab } from '$lib/components/common' import ComponentList from './componentsPanel/ComponentList.svelte' - import Icon from 'svelte-awesome' - import { faCode, faPlus, faSliders } from '@fortawesome/free-solid-svg-icons' + import { faPlus } from '@fortawesome/free-solid-svg-icons' import ContextPanel from './contextPanel/ContextPanel.svelte' import { classNames, encodeState } from '$lib/utils' import AppPreview from './AppPreview.svelte' @@ -41,6 +40,8 @@ import ComponentNavigation from './component/ComponentNavigation.svelte' import ItemPicker from '$lib/components/ItemPicker.svelte' import VariableEditor from '$lib/components/VariableEditor.svelte' + import { SecondaryMenu } from './settingsPanel/secondaryMenu' + import { Component, Paintbrush, Plus } from 'lucide-svelte' export let app: App export let path: string @@ -192,7 +193,7 @@ - + @@ -233,31 +234,32 @@ - +
-
- +
+ Insert
-
- - Settings +
+ + Component
-
- - CSS +
+ + Styling
{#if $selectedComponent !== undefined} + {:else}
Select a component to see the settings for it diff --git a/frontend/src/lib/components/apps/editor/AppPreview.svelte b/frontend/src/lib/components/apps/editor/AppPreview.svelte index 3cb54c149f..31678700e2 100644 --- a/frontend/src/lib/components/apps/editor/AppPreview.svelte +++ b/frontend/src/lib/components/apps/editor/AppPreview.svelte @@ -100,8 +100,7 @@ )} >

{summary}

diff --git a/frontend/src/lib/components/apps/editor/component/README.md b/frontend/src/lib/components/apps/editor/component/README.md index 0c6a264d25..174eb908f1 100644 --- a/frontend/src/lib/components/apps/editor/component/README.md +++ b/frontend/src/lib/components/apps/editor/component/README.md @@ -8,6 +8,10 @@ 1. Add the component to one of the component sets: `layout`, `buttons`, `inputs` or `display` _(this controls which group the component will be placed in in the **Insert** menu)_ +1. [**`quickStyleProperties.ts`**](../componentsPanel/quickStyleProperties.ts): + 1. Add the component to the `quickStyleProperties` record + 1. _(optional)_ Add the CSS properties that could be applied to the component + parts 1. [**`Component.svelte`**](./Component.svelte): 1. Add the new component in the Svelte `if` statement 1. [**`default-codes.ts`**](./default-codes.ts): diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/CssProperty.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/CssProperty.svelte index 2cfad65c9a..e3bdf59e0f 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/CssProperty.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/CssProperty.svelte @@ -1,71 +1,119 @@ -
+
{addWhitespaceBeforeCapitals(name)}
{#if value} -
+
{#if value.style !== undefined || forceStyle} - +
+ + + {#if quickStyleProperties?.length && isQuickMenuOpen} +
+ +
+ {/if} +
{/if} {#if value.class !== undefined || forceClass} + {/if} diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleMenu.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleMenu.svelte new file mode 100644 index 0000000000..a855c177b6 --- /dev/null +++ b/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleMenu.svelte @@ -0,0 +1,183 @@ + + +
+ {#each $styleStore.style as { prop }, index} +
+
{prop.key}
+
+ {#if Array.isArray(prop.value)} +
+ {#each prop.value as value, i} + setMultiValueProperty(index)} + /> + {/each} +
+ {:else} + + {/if} +
+
+ {/each} +
diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleProperty.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleProperty.svelte new file mode 100644 index 0000000000..34a548f874 --- /dev/null +++ b/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleProperty.svelte @@ -0,0 +1,141 @@ + + +
+ {#if prop.value['title']} +
+ {prop.value['title']} +
+ {/if} +
+ {#if type === StylePropertyType.color} + + {#each $styleStore.topColors as color} + + +
    + {#each StylePropertyUnits as u} +
  • + +
  • + {/each} +
+ + + {:else if type === StylePropertyType.text} + {#each prop.value?.['options'] || [] as option} + + + {option.text} + + {:else} + + {/each} + {/if} +
+
diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/quickStyleProperties.ts b/frontend/src/lib/components/apps/editor/componentsPanel/quickStyleProperties.ts new file mode 100644 index 0000000000..52287f685d --- /dev/null +++ b/frontend/src/lib/components/apps/editor/componentsPanel/quickStyleProperties.ts @@ -0,0 +1,644 @@ +import { get, writable } from 'svelte/store' +import { + AlignCenter, + AlignJustify, + AlignLeft, + AlignRight, + Asterisk, + Eye, + EyeOff, + Grid, + Italic, + Mouse, + MousePointer, + Pointer, + RectangleHorizontal, + Slash, + Square, + StretchVertical, + Strikethrough, + Type, + Underline +} from 'lucide-svelte' +import type { components } from '../component' + +export const STYLE_STORE_KEY = 'style_store' as const + +export type StyleStore = ReturnType +export type StyleStoreValue = { + style: { + prop: (typeof StyleProperty)[number] + value: string | undefined + }[] + topColors: TopColors +} + +export function createStyleStore(properties: StylePropertyKey[]) { + const style = StyleProperty.filter((p) => properties.includes(p.key)).map((p) => ({ + prop: p, + value: '' as string | undefined + })) + const store = writable({ + style: [...style], + topColors: [] as TopColors + }) + + return { + subscribe: store.subscribe, + set: store.set, + update: store.update, + updatePropValue: (key: StylePropertyKey, value?: string) => { + if (!key) { + return + } + store.update((s) => { + const index = s.style.findIndex((p) => p.prop.key === key) + if (index !== -1) { + s.style[index].value = value || '' + } + return s + }) + }, + getProp(key: StylePropertyKey) { + const s = get(store) + const index = s.style.findIndex((p) => p.prop.key === key) + return { + prop: s.style[index], + index: index === -1 ? undefined : index + } + }, + resetStyle: () => { + store.update((s) => { + s.style = style.map((s) => ({ ...s, value: '' })) + return s + }) + }, + setTopColors: (colors: TopColors) => { + store.update((s) => { + s.topColors = colors + return s + }) + } + } +} + +export enum StylePropertyType { + 'color' = 'color', // color value + 'unit' = 'unit', // number with unit like px, em, rem, etc. + 'number' = 'number', // bare number like the value of 'font-weight' + 'text' = 'text' // text like the value of 'display' +} + +export const StylePropertyUnits = ['px', 'em', 'rem', '%', 'vh', 'vw'] + +export type TopColors = [] | [string] | [string, string] | [string, string, string] + +export type StylePropertyKey = (typeof StyleProperty)[number]['key'] + +// Using an array instead of an object to preserve the order of the properties +export const StyleProperty = [ + { + key: 'display', + value: { + type: StylePropertyType.text, + options: [ + { + text: 'block', + icon: Square + }, + { + text: 'inline-block', + icon: RectangleHorizontal + }, + { + text: 'flex', + icon: StretchVertical + }, + { + text: 'grid', + icon: Grid + } + ] + } + }, + { + key: 'padding', + value: [ + { + type: StylePropertyType.unit, + title: 'top' + }, + { + type: StylePropertyType.unit, + title: 'right' + }, + { + type: StylePropertyType.unit, + title: 'bottom' + }, + { + type: StylePropertyType.unit, + title: 'left' + } + ] + }, + { + key: 'opacity', + value: { + type: StylePropertyType.number, + step: 0.1, + min: 0, + max: 1 + } + }, + { + key: 'cursor', + value: { + type: StylePropertyType.text, + options: [ + { + text: 'default', + icon: MousePointer + }, + { + text: 'pointer', + icon: Pointer + } + ] + } + }, + { + key: 'width', + value: { + type: StylePropertyType.unit + } + }, + { + key: 'min-width', + value: { + type: StylePropertyType.unit + } + }, + { + key: 'max-width', + value: { + type: StylePropertyType.unit + } + }, + { + key: 'height', + value: { + type: StylePropertyType.unit + } + }, + { + key: 'min-height', + value: { + type: StylePropertyType.unit + } + }, + { + key: 'max-height', + value: { + type: StylePropertyType.unit + } + }, + { + key: 'border', + value: [ + { + type: StylePropertyType.unit, + title: 'width' + }, + { + type: StylePropertyType.text, + title: 'style', + options: [ + { + text: 'solid', + icon: '___' + }, + { + text: 'dashed', + icon: '_ _' + }, + { + text: 'dotted', + icon: '. .' + } + ] + }, + { + type: StylePropertyType.color, + title: 'color' + } + ] + }, + { + key: 'border-radius', + value: { + type: StylePropertyType.unit + } + }, + { + key: 'box-shadow', + value: [ + { + type: StylePropertyType.unit, + title: 'offset-x' + }, + { + type: StylePropertyType.unit, + title: 'offset-y' + }, + { + type: StylePropertyType.unit, + title: 'blur' + }, + { + type: StylePropertyType.unit, + title: 'spread' + }, + { + type: StylePropertyType.color, + title: 'color' + } + ] + }, + { + key: 'background-color', + value: { + type: StylePropertyType.color + } + }, + { + key: 'color', + value: { + type: StylePropertyType.color + } + }, + { + key: 'font-size', + value: { + type: StylePropertyType.unit + } + }, + { + key: 'font-family', + value: { + type: StylePropertyType.text + } + }, + { + key: 'font-weight', + value: { + type: StylePropertyType.number + } + }, + { + key: 'font-style', + value: { + type: StylePropertyType.text, + options: [ + { + text: 'normal', + icon: Type + }, + { + text: 'italic', + icon: Italic + } + ] + } + }, + { + key: 'text-align', + value: { + type: StylePropertyType.text, + options: [ + { + text: 'left', + icon: AlignLeft + }, + { + text: 'center', + icon: AlignCenter + }, + { + text: 'right', + icon: AlignRight + }, + { + text: 'justify', + icon: AlignJustify + } + ] + } + }, + { + key: 'text-decoration', + value: { + type: StylePropertyType.text, + options: [ + { + text: 'none', + icon: Slash + }, + { + text: 'underline', + icon: Underline + }, + { + text: 'line-through', + icon: Strikethrough + } + ] + } + }, + { + key: 'text-transform', + value: { + type: StylePropertyType.text, + options: [ + { + text: 'none', + icon: Slash + }, + { + text: 'capitalize', + icon: 'Aa' + }, + { + text: 'uppercase', + icon: 'AA' + }, + { + text: 'lowercase', + icon: 'aa' + } + ] + } + }, + { + key: 'line-height', + value: { + type: StylePropertyType.unit + } + }, + { + key: 'letter-spacing', + value: { + type: StylePropertyType.unit + } + }, + { + key: 'word-spacing', + value: { + type: StylePropertyType.unit + } + }, + { + key: 'overflow', + value: { + type: StylePropertyType.text, + options: [ + { + text: 'auto', + icon: Asterisk + }, + { + text: 'visible', + icon: Eye + }, + { + text: 'hidden', + icon: EyeOff + }, + { + text: 'scroll', + icon: Mouse + } + ] + } + } +] as const + +const allDefaultProps = StyleProperty.map(({ key }) => key) + +const containerDefaultProps: StylePropertyKey[] = [ + 'padding', + 'opacity', + 'border', + 'border-radius', + 'box-shadow', + 'background-color', + 'overflow' +] + +const textDefaultProps: StylePropertyKey[] = [ + 'padding', + 'opacity', + 'background-color', + 'color', + 'font-size', + 'font-family', + 'font-weight', + 'font-style', + 'text-align', + 'text-decoration', + 'text-transform', + 'line-height', + 'letter-spacing', + 'word-spacing' +] + +const sizeDefaultProps: StylePropertyKey[] = [ + 'width', + 'min-width', + 'max-width', + 'height', + 'min-height', + 'max-height' +] + +const buttonDefaultProps: StylePropertyKey[] = [ + 'cursor', + 'border', + 'border-radius', + 'box-shadow', + ...textDefaultProps +] + +const inputDefaultProps: StylePropertyKey[] = [ + 'cursor', + 'border', + 'border-radius', + ...textDefaultProps +] + +export const quickStyleProperties: Record< + keyof typeof components, + Record +> = { + mapcomponent: { + map: containerDefaultProps + }, + pdfcomponent: { + container: containerDefaultProps + }, + formcomponent: { + container: containerDefaultProps, + button: buttonDefaultProps + }, + htmlcomponent: { + container: allDefaultProps + }, + iconcomponent: { + container: containerDefaultProps, + icon: [ + 'padding', + 'opacity', + 'cursor', + 'width', + 'min-width', + 'max-width', + 'height', + 'min-height', + 'max-height', + 'color' + ] + }, + tabscomponent: { + tabRow: containerDefaultProps, + allTabs: [...textDefaultProps, ...sizeDefaultProps], + selectedTab: [...textDefaultProps, ...sizeDefaultProps], + container: containerDefaultProps + }, + textcomponent: { + text: textDefaultProps + }, + imagecomponent: { + image: containerDefaultProps + }, + rangecomponent: { + handles: ['opacity', 'cursor', 'border', 'border-radius', 'background-color'], + bar: ['opacity', 'cursor', 'border', 'border-radius', 'background-color'], + limits: textDefaultProps, + values: textDefaultProps + }, + tablecomponent: { + tableHeader: containerDefaultProps, + tableBody: containerDefaultProps, + tableFooter: containerDefaultProps, + container: containerDefaultProps + }, + aggridcomponent: {}, + buttoncomponent: { + button: buttonDefaultProps + }, + drawercomponent: { + container: containerDefaultProps + }, + plotlycomponent: {}, + selectcomponent: { + input: inputDefaultProps + }, + slidercomponent: { + handles: ['opacity', 'cursor', 'border', 'border-radius', 'background-color'], + bar: ['opacity', 'cursor', 'border', 'border-radius', 'background-color'], + limits: textDefaultProps, + values: textDefaultProps + }, + displaycomponent: { + header: [...containerDefaultProps, ...textDefaultProps], + container: containerDefaultProps + }, + barchartcomponent: { + container: containerDefaultProps + }, + checkboxcomponent: { + text: textDefaultProps + }, + currencycomponent: { + input: inputDefaultProps + }, + piechartcomponent: { + container: containerDefaultProps + }, + vegalitecomponent: {}, + containercomponent: { + container: containerDefaultProps + }, + dateinputcomponent: { + input: inputDefaultProps + }, + fileinputcomponent: { + container: containerDefaultProps + }, + textinputcomponent: { + input: inputDefaultProps + }, + emailinputcomponent: { + input: inputDefaultProps + }, + formbuttoncomponent: { + button: buttonDefaultProps, + popup: containerDefaultProps + }, + timeseriescomponent: { + container: containerDefaultProps + }, + multiselectcomponent: { + input: inputDefaultProps + }, + numberinputcomponent: { + input: inputDefaultProps + }, + scatterchartcomponent: { + container: containerDefaultProps + }, + passwordinputcomponent: { + input: inputDefaultProps + }, + resourceselectcomponent: { + input: inputDefaultProps + }, + verticaldividercomponent: { + divider: [ + 'padding', + 'opacity', + 'width', + 'min-width', + 'max-width', + 'height', + 'min-height', + 'max-height', + 'border', + 'border-radius', + 'background-color' + ], + container: containerDefaultProps + }, + horizontaldividercomponent: { + divider: [ + 'padding', + 'opacity', + 'width', + 'min-width', + 'max-width', + 'height', + 'min-height', + 'max-height', + 'border', + 'border-radius', + 'background-color' + ], + container: containerDefaultProps + }, + verticalsplitpanescomponent: { + container: containerDefaultProps + }, + horizontalsplitpanescomponent: { + container: containerDefaultProps + } +} diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/ComponentPanel.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/ComponentPanel.svelte index 0392ffbb0c..5211c90017 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/ComponentPanel.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/ComponentPanel.svelte @@ -1,6 +1,6 @@ + +{#if component && component.customCss !== undefined} + {#each Object.keys(ccomponents[component.type].customCss ?? {}) as name} +
+ app.set($app)} + /> +
+ {/each} +{/if} diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/ColorInput.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/ColorInput.svelte index fb4759fa17..1186a2d99a 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/ColorInput.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/ColorInput.svelte @@ -1,22 +1,21 @@ -
- (isOpen = true)} - /> +
+ (isOpen = true)} />