fix: improve app css consistency

This commit is contained in:
Ruben Fiszel
2025-05-22 14:40:53 +02:00
parent 57762c8b52
commit 44021e7fe2
6 changed files with 184 additions and 126 deletions
@@ -229,7 +229,8 @@
css?.button?.class ?? '',
isMenuItem ? 'flex items-center justify-start' : '',
isMenuItem ? '!border-0' : '',
'wm-button'
'wm-button',
`wm-button-${resolvedConfig.color}`
)}
variant={isMenuItem ? 'border' : 'contained'}
style={css?.button?.style}
@@ -237,7 +238,8 @@
css?.container?.class ?? '',
resolvedConfig.fillContainer ? 'w-full h-full' : '',
isMenuItem ? 'w-full' : '',
'wm-button-container'
'wm-button-container',
`wm-button-container-${resolvedConfig.color}`
)}
wrapperStyle={css?.container?.style}
disabled={resolvedConfig.disabled}
@@ -10,6 +10,7 @@
import InitializeComponent from '../helpers/InitializeComponent.svelte'
import { Alert } from '$lib/components/common'
import AlignWrapper from '../helpers/AlignWrapper.svelte'
import { appendClass } from '../../editor/componentsPanel/cssUtils'
export let id: string
export let configuration: RichConfigurations
@@ -63,13 +64,13 @@
tooltip={resolvedConfig.tooltip}
size={resolvedConfig.size}
collapsible={resolvedConfig.collapsible}
bgClass={css?.background?.class}
bgClass={appendClass(css?.background?.class, 'wm-alert-card-background')}
bgStyle={css?.background?.style}
iconClass={css?.icon?.class}
iconClass={appendClass(css?.icon?.class, 'wm-alert-card-icon')}
iconStyle={css?.icon?.style}
titleClass={css?.title?.class}
titleClass={appendClass(css?.title?.class, 'wm-alert-card-title')}
titleStyle={css?.title?.style}
descriptionClass={css?.description?.class}
descriptionClass={appendClass(css?.description?.class, 'wm-alert-card-description')}
descriptionStyle={css?.description?.style}
isCollapsed={resolvedConfig.initiallyCollapsed}
>
@@ -179,7 +179,7 @@
>
<div
style={css?.popup?.style}
class={twMerge('mx-24 mt-8 bg-surface rounded-lg relative', css?.popup?.class)}
class={twMerge('mx-24 mt-8 bg-surface wm-modal rounded-lg relative', css?.popup?.class)}
use:clickOutside={{
capture: false,
stopPropagation: false,
@@ -209,7 +209,7 @@
</div>
<div
class={twMerge('wm-modal h-full', 'overflow-y-auto')}
class={twMerge('wm-modal-container h-full', 'overflow-y-auto', css?.container?.class)}
on:pointerdown={(e) => {
e?.stopPropagation()
if (!$connectingInput.opened) {
@@ -3410,7 +3410,8 @@ See date-fns format for more information. By default, it is 'dd.MM.yyyy HH:mm'
customCss: {
button: { class: '', style: '' },
buttonContainer: { class: '', style: '' },
popup: { class: '', style: '' }
popup: { class: '', style: '' },
container: { class: '', style: '' }
},
initialData: {
horizontalAlignment: 'center',
@@ -20,20 +20,38 @@
const dispatch = createEventDispatcher()
interface CustomCSSEntry {
type: CustomCSSType
type?: CustomCSSType
name: string
icon: any
ids: { id: string; forceStyle: boolean; forceClass: boolean }[]
ids?: { id: string; forceStyle: boolean; forceClass: boolean }[]
description?: string
order?: number
}
const { app } = getContext<AppViewerContext>('AppViewerContext')
const descriptions = {
buttoncomponent:
'The button component also has additional color specific classes to allow customizing classes by color. wm-button-wrapper-blue, wm-button-container-blue, ...'
}
const entries: CustomCSSEntry[] = [
{
name: 'Dark Mode',
icon: LayoutDashboardIcon,
description:
'When in dark mode, the entire document has the .dark class applied to it. You can apply selective styling by using the .dark class: e.g. .dark .my-element { color: white; }',
order: 3
},
{
type: 'app',
name: 'App',
icon: LayoutDashboardIcon,
ids: ['viewer', 'grid', 'component'].map((id) => ({ id, forceStyle: true, forceClass: true }))
ids: ['viewer', 'grid', 'component'].map((id) => ({
id,
forceStyle: true,
forceClass: true
})),
order: 2
},
{
type: 'quillcomponent',
@@ -51,11 +69,12 @@
id,
forceStyle: v?.style != undefined,
forceClass: v?.['class'] != undefined
}))
})),
description: descriptions[type as keyof typeof descriptions]
}))
]
entries.sort((a, b) => a.name.localeCompare(b.name))
entries.sort((a, b) => (b.order ?? 0) - (a.order ?? 0) + a.name.localeCompare(b.name))
let search = ''
</script>
@@ -66,15 +85,15 @@
<div class="h-[calc(100%-50px)] overflow-auto relative">
{#each search != '' ? entries.filter((x) => x.name
.toLowerCase()
.includes(search.toLowerCase())) : entries as { type, name, icon, ids } (name + type)}
{#if ids.length > 0}
.includes(search.toLowerCase())) : entries as { type, name, icon, ids, description } (name + type)}
{#if description || (ids && ids.length > 0)}
<ListItem
title={name}
prefix={TITLE_PREFIX}
on:open={(e) => {
if ($app.css != undefined) {
if (e.detail && $app.css[type] == undefined) {
$app.css[type] = Object.fromEntries(ids.map(({ id }) => [id, {}]))
if (type && e.detail && $app.css[type] == undefined) {
$app.css[type] = Object.fromEntries((ids ?? []).map(({ id }) => [id, {}]))
}
}
}}
@@ -85,115 +104,120 @@
{name}
</span>
</div>
<div class="py-2">
{#each customisationByComponent.filter( (c) => c.components.includes(type) ) as customisation (customisation.components.join('-'))}
{#if customisation.link}
<a
href={customisation.link}
target="_blank"
class="text-frost-500 dark:text-frost-300 font-semibold text-xs"
>
<div class="flex flex-row gap-2">
See documentation
<ExternalLink size="16" />
</div>
</a>
{/if}
<Tabs selected="selectors">
{#if customisation.selectors.length > 0}
<Tab value="selectors" size="xs">
Selectors ({customisation.selectors.length})
</Tab>
{/if}
{#if customisation.variables.length > 0}
<Tab value="variables" size="xs">
<div class="flex flex-row gap-2 justify-center-center items-center">
Variables ({customisation.variables.length})
{#if description}
<div class="py-2 text-xs text-gray-500">{description}</div>
{/if}
{#if type}
<div class="py-2">
{#each customisationByComponent.filter( (c) => c.components.includes(type) ) as customisation (customisation.components.join('-'))}
{#if customisation.link}
<a
href={customisation.link}
target="_blank"
class="text-frost-500 dark:text-frost-300 font-semibold text-xs"
>
<div class="flex flex-row gap-2">
See documentation
<ExternalLink size="16" />
</div>
</Tab>
</a>
{/if}
<div slot="content" class="h-full">
<TabContent value="selectors" class="h-full mt-2 ">
<DataTable size="sm">
<Head>
<tr>
<Cell head first>Selector</Cell>
<Cell head>Comment</Cell>
<Cell head last />
</tr>
</Head>
{#each customisation.selectors as { selector, comment }}
<Row>
<Cell first>
<Badge color="gray">{selector}</Badge>
</Cell>
<Cell>
{#if comment}
<div class="max-w-24 whitespace-pre-wrap">{comment}</div>
{/if}
</Cell>
<Cell>
<Button
size="xs2"
color="light"
on:click={() => {
dispatch('insertSelector', `${selector} {}`)
}}
>
<ArrowUpSquare size={16} />
</Button>
</Cell>
</Row>
{/each}
</DataTable>
</TabContent>
<TabContent value="variables" class="h-full mt-2">
<DataTable>
<Head>
<tr>
<Cell head first>Variable</Cell>
<Cell head>Default value</Cell>
<Cell head>Comment</Cell>
<Cell head last />
</tr>
</Head>
{#each customisation.variables as { variable, value, comment }}
<Row>
<Cell first>
<Badge color="gray">{variable}</Badge>
</Cell>
<Cell>
<Badge color="gray">{value}</Badge>
</Cell>
<Cell>
{#if comment}
<div class="w-80 whitespace-pre-wrap">{comment}</div>
{/if}
</Cell>
<Cell sticky>
<Button
size="xs2"
color="light"
on:click={() => {
dispatch(
'insertSelector',
`${customisation.root} { ${variable}: ${value};}`
)
}}
wrapperClasses="px-2 py-3.5 bg-surface"
>
<ArrowUpSquare size={16} />
</Button>
</Cell>
</Row>
{/each}
</DataTable>
</TabContent>
</div>
</Tabs>
{/each}
</div>
<Tabs selected="selectors">
{#if customisation.selectors.length > 0}
<Tab value="selectors" size="xs">
Selectors ({customisation.selectors.length})
</Tab>
{/if}
{#if customisation.variables.length > 0}
<Tab value="variables" size="xs">
<div class="flex flex-row gap-2 justify-center-center items-center">
Variables ({customisation.variables.length})
</div>
</Tab>
{/if}
<div slot="content" class="h-full">
<TabContent value="selectors" class="h-full mt-2 ">
<DataTable size="sm">
<Head>
<tr>
<Cell head first>Selector</Cell>
<Cell head>Comment</Cell>
<Cell head last />
</tr>
</Head>
{#each customisation.selectors as { selector, comment }}
<Row>
<Cell first>
<Badge color="gray">{selector}</Badge>
</Cell>
<Cell>
{#if comment}
<div class="max-w-24 whitespace-pre-wrap">{comment}</div>
{/if}
</Cell>
<Cell>
<Button
size="xs2"
color="light"
on:click={() => {
dispatch('insertSelector', `${selector} {}`)
}}
>
<ArrowUpSquare size={16} />
</Button>
</Cell>
</Row>
{/each}
</DataTable>
</TabContent>
<TabContent value="variables" class="h-full mt-2">
<DataTable>
<Head>
<tr>
<Cell head first>Variable</Cell>
<Cell head>Default value</Cell>
<Cell head>Comment</Cell>
<Cell head last />
</tr>
</Head>
{#each customisation.variables as { variable, value, comment }}
<Row>
<Cell first>
<Badge color="gray">{variable}</Badge>
</Cell>
<Cell>
<Badge color="gray">{value}</Badge>
</Cell>
<Cell>
{#if comment}
<div class="w-80 whitespace-pre-wrap">{comment}</div>
{/if}
</Cell>
<Cell sticky>
<Button
size="xs2"
color="light"
on:click={() => {
dispatch(
'insertSelector',
`${customisation.root} { ${variable}: ${value};}`
)
}}
wrapperClasses="px-2 py-3.5 bg-surface"
>
<ArrowUpSquare size={16} />
</Button>
</Cell>
</Row>
{/each}
</DataTable>
</TabContent>
</div>
</Tabs>
{/each}
</div>
{/if}
</ListItem>
{/if}
{/each}
@@ -185,7 +185,11 @@ export const customisationByComponent: Customisation[] = [
components: ['modalcomponent'],
selectors: [
{ selector: '.wm-modal', comment: 'main modal element', customCssKey: 'popup' },
{ selector: '.wm-modal-button', comment: 'button to open modal', customCssKey: 'button' },
{
selector: '.wm-modal-container',
comment: 'container for modal',
customCssKey: 'container'
},
{
selector: '.wm-modal-button-container',
comment: 'container for button to open modal',
@@ -826,6 +830,26 @@ export const customisationByComponent: Customisation[] = [
selector: 'wm-alert-card-container',
comment: 'Alert container',
customCssKey: 'container'
},
{
selector: 'wm-alert-card-background',
comment: 'Alert background',
customCssKey: 'background'
},
{
selector: 'wm-alert-card-icon',
comment: 'Alert icon',
customCssKey: 'icon'
},
{
selector: 'wm-alert-card-title',
comment: 'Alert title',
customCssKey: 'title'
},
{
selector: 'wm-alert-card-description',
comment: 'Alert description',
customCssKey: 'description'
}
],
variables: []
@@ -860,3 +884,9 @@ export function hasStyleValue(obj: ComponentCssProperty | undefined) {
return obj.style !== ''
}
export function appendClass(className: string | undefined, customCssKey: string) {
if (!className) return customCssKey
return `${className} ${customCssKey}`
}