Initiate component tokens for Visual Designer

master
Cagatay Civici 2024-12-13 23:19:49 +03:00
parent 537772da64
commit 6b90a89033
4 changed files with 161 additions and 17 deletions

View File

@ -50,7 +50,7 @@
</div>
</TabPanel>
<TabPanel value="1">
<div class="flex flex-col gap-3">
<div>
<form @keydown="onKeyDown" class="flex flex-col gap-3">
<DesignBorderRadius />
<DesignColors />
@ -62,7 +62,7 @@
<AccordionPanel value="0">
<AccordionHeader>Common</AccordionHeader>
<AccordionContent>
<div class="flex flex-col gap-3">
<div>
<form @keydown="onKeyDown" class="flex flex-col gap-3">
<DesignGeneral />
<DesignFormField />
@ -100,7 +100,9 @@
</Accordion>
</TabPanel>
<TabPanel value="3">
<span class="leading-6 text-muted-color">Component tokens are not supported by the Visual Editor at the moment and will be available with a future update. </span>
<form @keydown="onKeyDown">
<DesignComponent />
</form>
</TabPanel>
<TabPanel value="4">
<span class="leading-6 text-muted-color">Extend the theming system with your own design tokens e.g. <span class="font-medium">accent.color</span>. Do not use curly braces in the name field.</span>
@ -204,13 +206,7 @@ export default {
},
mounted() {
if (!this.$appState.designer.preset) {
const defaultPreset = presets.Aura;
this.$appState.designer.preset = {
primitive: defaultPreset.primitive,
semantic: defaultPreset.semantic
};
this.$appState.designer.preset = presets.Aura;
this.replaceColorPalette();
this.generateACTokens(null, this.$appState.designer.preset);
}
@ -265,10 +261,7 @@ app.mount("#app");
document.body.classList.remove('material');
}
this.$appState.designer.preset = {
primitive: newPreset.primitive,
semantic: newPreset.semantic
};
this.$appState.designer.preset = newPreset;
this.replaceColorPalette();
@ -351,7 +344,7 @@ app.mount("#app");
},
generateACTokens(parentPath, obj) {
for (let key in obj) {
if (key === 'dark') {
if (key === 'dark' || key === 'components') {
continue;
}

View File

@ -1,6 +1,6 @@
<template>
<div>
<label :for="inputId" class="text-sm text-zinc-700 dark:text-white">{{ label }}</label>
<label :for="inputId" class="text-sm text-zinc-700 dark:text-white capitalize">{{ label }}</label>
<div :id="id" class="relative">
<AutoComplete
:modelValue="modelValue"
@ -13,7 +13,7 @@
:showEmptyMessage="false"
:pt="{
pcInputText: {
root: ['border border-surface-300 dark:border-surface-600 rounded-lg py-2 px-2 w-full', { 'pr-8': type === 'color' }]
root: ['border border-surface-300 dark:border-surface-600 rounded-lg py-2 px-2 w-full text-sm', { 'pr-8': type === 'color' }]
},
overlay: 'border border-surface-200 dark:border-surface-700 bg-surface-0 dark:bg-surface-950 shadow-2 rounded-md',
listContainer: 'max-h-40 overflow-auto',

View File

@ -0,0 +1,49 @@
<template>
<section class="flex flex-col gap-3">
<div class="text-lg font-semibold capitalize">{{ componentKey }}</div>
<template v-for="(value, name) in tokens" :key="name">
<DesignComponentSection v-if="name !== 'colorScheme'" :componentKey="componentKey" :name="name" />
</template>
<Tabs v-if="hasColorScheme" value="cs-0">
<TabList>
<Tab value="cs-0">Light</Tab>
<Tab value="cs-1">Dark</Tab>
</TabList>
<TabPanels class="!px-0">
<TabPanel value="cs-0">
<div class="flex flex-col gap-3">
<DesignComponentSection v-for="(value, name) in lightTokens" :key="name" :componentKey="componentKey" :name="name" colorScheme="light" />
</div>
</TabPanel>
<TabPanel value="cs-1">
<div class="flex flex-col gap-3">
<DesignComponentSection v-for="(value, name) in darkTokens" :key="name" :componentKey="componentKey" :name="name" colorScheme="dark" />
</div>
</TabPanel>
</TabPanels>
</Tabs>
</section>
</template>
<script>
export default {
inject: ['$preset'],
computed: {
componentKey() {
return this.$route.name;
},
tokens() {
return this.$preset.components[this.componentKey];
},
lightTokens() {
return this.$preset.components[this.componentKey].colorScheme.light;
},
darkTokens() {
return this.$preset.components[this.componentKey].colorScheme.dark;
},
hasColorScheme() {
return this.tokens.colorScheme != undefined;
}
}
};
</script>

View File

@ -0,0 +1,102 @@
<template>
<section>
<div class="text-sm mb-1 font-semibold text-surface-950 dark:text-surface-0 capitalize">{{ sectionName }}</div>
<div class="grid grid-cols-4 gap-2">
<template v-for="(t_value, t_name) in tokens" :key="t_name">
<DesignTokenField v-if="!isObject(t_value)" v-model="tokens[t_name]" :label="camelCaseToSpaces(t_name)" :type="isColor(t_name) ? 'color' : null" />
</template>
</div>
<template v-if="hasNestedTokens">
<DesignComponentSection v-for="(n_value, n_name) in nestedTokens" :key="n_name" :componentKey="componentKey" :name="n_name" :parentPath="fullPath" class="mt-3" />
</template>
</section>
</template>
<script>
export default {
props: {
componentKey: {
type: null,
default: null
},
name: {
type: null,
default: null
},
parentPath: {
type: null,
default: null
},
colorScheme: {
type: null,
default: null
}
},
inject: ['$preset'],
methods: {
camelCaseToSpaces(val) {
return val.replace(/([a-z])([A-Z])/g, '$1 $2');
},
isColor(val) {
return val.toLowerCase().includes('color') || val.toLowerCase().includes('background');
},
isObject(val) {
return val !== null && typeof val === 'object';
},
getObjectProperty(obj, path) {
const keys = path.split('.');
let current = obj;
for (const key of keys) {
if (current[key] !== undefined) {
current = current[key];
} else {
return undefined;
}
}
return current;
},
capitalize(str) {
if (typeof str !== 'string' || str.length === 0) {
return str;
}
return str.charAt(0).toUpperCase() + str.slice(1);
}
},
computed: {
fullPath() {
return this.parentPath ? this.parentPath + '.' + this.name : this.name;
},
sectionName() {
const names = this.fullPath.split('.');
return names.map((n) => this.capitalize(this.camelCaseToSpaces(n))).join(' ');
},
tokens() {
if (this.colorScheme) return this.getObjectProperty(this.$preset.components[this.componentKey].colorScheme[this.colorScheme], this.fullPath);
else return this.getObjectProperty(this.$preset.components[this.componentKey], this.fullPath);
},
nestedTokens() {
const groups = {};
const obj = this.tokens;
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
if (this.isObject(value)) {
groups[key] = value;
}
}
}
return groups;
},
hasNestedTokens() {
return Object.keys(this.nestedTokens).length > 0;
}
}
};
</script>