+
{resolvedConfig?.value}
diff --git a/frontend/src/lib/components/apps/editor/component/components.ts b/frontend/src/lib/components/apps/editor/component/components.ts
index 4416ff8c6d..77f1263fe2 100644
--- a/frontend/src/lib/components/apps/editor/component/components.ts
+++ b/frontend/src/lib/components/apps/editor/component/components.ts
@@ -2721,7 +2721,22 @@ This is a paragraph.
icon: FileBarChart,
documentationLink: `${documentationBaseUrl}/statistic_card`,
dims: '2:4-3:4' as AppComponentDimensions,
- customCss: {},
+ customCss: {
+ title: {
+ class: '',
+ style: '',
+ quickCss: ['font-size: 1rem', 'font-size: 1.5rem', 'font-size: 2rem'],
+ quickTailwindClasses: ['text-xs', 'text-sm', 'text-base', 'text-lg', 'text-xl', 'text-2xl']
+ },
+ container: { class: '', style: '' },
+ value: {
+ class: '',
+ style: '',
+ quickCss: ['font-size: 1rem', 'font-size: 1.5rem', 'font-size: 2rem'],
+ quickTailwindClasses: ['text-xs', 'text-sm', 'text-base', 'text-lg', 'text-xl', 'text-2xl']
+ },
+ media: { class: '', style: '' }
+ },
initialData: {
configuration: {
title: {
@@ -2739,11 +2754,40 @@ This is a paragraph.
value: 0,
fieldType: 'number'
},
- icon: {
- type: 'static',
- value: undefined,
- fieldType: 'icon-select'
- }
+ media: {
+ type: 'oneOf',
+ selected: 'image',
+ labels: {
+ icon: 'Icon',
+ image: 'Image'
+ },
+ configuration: {
+ icon: {
+ icon: {
+ type: 'static',
+ value: undefined,
+ fieldType: 'icon-select'
+ }
+ },
+ image: {
+ source: {
+ type: 'static',
+ value: '/logo.svg',
+ fieldType: 'text',
+ fileUpload: {
+ accept: 'image/*',
+ convertTo: 'base64'
+ }
+ },
+ sourceKind: {
+ fieldType: 'select',
+ type: 'static',
+ selectOptions: selectOptions.imageSourceKind,
+ value: 'url' as (typeof selectOptions.imageSourceKind)[number]
+ }
+ }
+ }
+ } as const
}
}
}
diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/CssProperty.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/CssProperty.svelte
index f8f5246085..5de6011b88 100644
--- a/frontend/src/lib/components/apps/editor/componentsPanel/CssProperty.svelte
+++ b/frontend/src/lib/components/apps/editor/componentsPanel/CssProperty.svelte
@@ -47,173 +47,207 @@
}
let dynamicClass: boolean = value?.evalClass !== undefined
+ let render = 0
-
-
-
-
- {addWhitespaceBeforeCapitals(name)}
-
- {#if shouldDisplayLeft}
-
- {/if}
- {#if shouldDisplayRight}
-
- {/if}
-
- {#if wmClass}
-
-
- {wmClass}
+{#key render}
+
+
+
+
+ {addWhitespaceBeforeCapitals(name)}
+
+ {#if shouldDisplayLeft}
-
-
- {/if}
-
-
-
-{#if value}
-
- {#if tooltip}
-
{tooltip}
- {/if}
- {#if value.style !== undefined || forceStyle}
-
-
-
-{/if}
+
+ {#if value}
+
+ {#if tooltip}
+
{tooltip}
+ {/if}
+ {#if value.style !== undefined || forceStyle}
+
+
+
+
+
Plain CSS
+ {#if overriden}
+
Overriden by local
+ {:else if overridding}
+
Overriding global
+ {/if}
+
+
+
+
+
+
+
+ {#if quickStyleProperties?.length}
+
+
+
+
+
+ {isQuickMenuOpen ? 'Close' : 'Open'} styling menu
+
+
+ {/if}
+
+
+
+ {#if quickStyleProperties?.length && isQuickMenuOpen}
+
+
+
+ {/if}
+ {#if value.quickCss}
+
+ {#each value.quickCss as v}
+ {
+ value.style = value.style === '' ? `${v};` : `${value.style} ${v};`
+ }}
+ >
+ {v}
+
+ {/each}
+
+ {/if}
+
+ {/if}
+
+ {#if value.class !== undefined || forceClass}
+
+
+
+ Tailwind classes
+
+ Use any tailwind classes to style your component
+
+
+
+
+
+ {#if value.quickTailwindClasses}
+
+ {#each value.quickTailwindClasses as cls}
+ {
+ value.class = value.class === '' ? cls : `${value.class} ${cls}`
+ render++
+ }}
+ >
+ {cls}
+
+ {/each}
+
+ {/if}
+
+ {/if}
+
+
{
+ if (e.detail && !value.evalClass) {
+ value.evalClass = {
+ type: 'evalv2',
+ expr: '',
+ connections: [],
+ fieldType: 'text'
+ }
+ } else {
+ value.evalClass = undefined
+ }
+ }}
+ />
+
+ {#if value?.evalClass && dynamicClass}
+
+ {/if}
+
+ {/if}
+{/key}
diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte
index 9cfa89e862..0fbdf8596d 100644
--- a/frontend/src/lib/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte
+++ b/frontend/src/lib/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte
@@ -89,6 +89,7 @@
placeholder={config?.['placeholder']}
customTitle={config?.['customTitle']}
tooltip={config?.['tooltip']}
+ fileUpload={config?.['fileUpload']}
/>
{/if}
{/each}
diff --git a/frontend/src/lib/components/apps/types.ts b/frontend/src/lib/components/apps/types.ts
index 3799bd808b..a36692601b 100644
--- a/frontend/src/lib/components/apps/types.ts
+++ b/frontend/src/lib/components/apps/types.ts
@@ -44,6 +44,8 @@ export type ComponentCssProperty = {
class?: string
style?: string
evalClass?: RichConfiguration
+ quickCss?: readonly string[] | undefined
+ quickTailwindClasses?: readonly string[] | undefined
}
export type ComponentCustomCSS
= Partial<
@@ -173,7 +175,7 @@ export type ListContext = Writable<{
disabled: boolean
}>
-export type ListInputs = {set: (id: string, value: any) => void, remove: (id: string) => void}
+export type ListInputs = { set: (id: string, value: any) => void; remove: (id: string) => void }
export type GroupContext = Writable>
diff --git a/frontend/src/lib/components/apps/utils.ts b/frontend/src/lib/components/apps/utils.ts
index dcc0c462da..b7eee7c3f7 100644
--- a/frontend/src/lib/components/apps/utils.ts
+++ b/frontend/src/lib/components/apps/utils.ts
@@ -365,3 +365,20 @@ export function transformBareBase64IfNecessary(source: string | undefined) {
return `data:application/octet-stream;base64,${source}`
}
}
+
+export function getImageDataURL(imageKind: string | undefined, image: string | undefined) {
+ if (!imageKind || !image) {
+ return null
+ }
+
+ switch (imageKind) {
+ case 'png encoded as base64':
+ return 'data:image/png;base64,' + image
+ case 'jpeg encoded as base64':
+ return 'data:image/jpeg;base64,' + image
+ case 'svg encoded as base64':
+ return 'data:image/svg+xml;base64,' + image
+ default:
+ return image
+ }
+}