Update deep watcher for `config.theme` and Improve designer

pull/6798/head
Mert Sincan 2024-11-14 03:58:28 +00:00
parent a0e2a60d50
commit cfa9435d26
5 changed files with 237 additions and 9 deletions

View File

@ -156,7 +156,8 @@
</template> </template>
<script> <script>
import { updatePreset, usePreset } from '@primevue/themes'; import { NoirPreset } from '@/themes/app-theme.js';
import { $t, updatePreset, usePreset } from '@primevue/themes';
import Aura from '@primevue/themes/aura'; import Aura from '@primevue/themes/aura';
import Lara from '@primevue/themes/lara'; import Lara from '@primevue/themes/lara';
import Material from '@primevue/themes/material'; import Material from '@primevue/themes/material';
@ -181,8 +182,8 @@ export default {
return { return {
activeTab: '0', activeTab: '0',
preset: { preset: {
primitive: Aura.primitive, primitive: NoirPreset.primitive,
semantic: Aura.semantic semantic: NoirPreset.semantic
}, },
presetOptions: [ presetOptions: [
{ label: 'Aura', value: 'Aura' }, { label: 'Aura', value: 'Aura' },
@ -199,6 +200,173 @@ export default {
this.generateACTokens(null, this.preset); this.generateACTokens(null, this.preset);
}, },
methods: { methods: {
getPresetExt() {
const color = this.primaryColors.find((c) => c.name === this.selectedPrimaryColor);
if (color.name === 'noir') {
document.documentElement.style.setProperty('--logo-color', 'var(--text-secondary-color)');
return {
semantic: {
primary: {
50: '{surface.50}',
100: '{surface.100}',
200: '{surface.200}',
300: '{surface.300}',
400: '{surface.400}',
500: '{surface.500}',
600: '{surface.600}',
700: '{surface.700}',
800: '{surface.800}',
900: '{surface.900}',
950: '{surface.950}'
},
colorScheme: {
light: {
primary: {
color: '{primary.950}',
contrastColor: '#ffffff',
hoverColor: '{primary.800}',
activeColor: '{primary.700}'
},
highlight: {
background: '{primary.950}',
focusBackground: '{primary.700}',
color: '#ffffff',
focusColor: '#ffffff'
}
},
dark: {
primary: {
color: '{primary.50}',
contrastColor: '{primary.950}',
hoverColor: '{primary.200}',
activeColor: '{primary.300}'
},
highlight: {
background: '{primary.50}',
focusBackground: '{primary.300}',
color: '{primary.950}',
focusColor: '{primary.950}'
}
}
}
}
};
} else {
document.documentElement.style.setProperty('--logo-color', 'var(--primary-color)');
if (this.$appState.preset === 'Nora') {
return {
semantic: {
primary: color.palette,
colorScheme: {
light: {
primary: {
color: '{primary.600}',
contrastColor: '#ffffff',
hoverColor: '{primary.700}',
activeColor: '{primary.800}'
},
highlight: {
background: '{primary.600}',
focusBackground: '{primary.700}',
color: '#ffffff',
focusColor: '#ffffff'
}
},
dark: {
primary: {
color: '{primary.500}',
contrastColor: '{surface.900}',
hoverColor: '{primary.400}',
activeColor: '{primary.300}'
},
highlight: {
background: '{primary.500}',
focusBackground: '{primary.400}',
color: '{surface.900}',
focusColor: '{surface.900}'
}
}
}
}
};
} else if (this.$appState.preset === 'Material') {
return {
semantic: {
primary: color.palette,
colorScheme: {
light: {
primary: {
color: '{primary.500}',
contrastColor: '#ffffff',
hoverColor: '{primary.400}',
activeColor: '{primary.300}'
},
highlight: {
background: 'color-mix(in srgb, {primary.color}, transparent 88%)',
focusBackground: 'color-mix(in srgb, {primary.color}, transparent 76%)',
color: '{primary.700}',
focusColor: '{primary.800}'
}
},
dark: {
primary: {
color: '{primary.400}',
contrastColor: '{surface.900}',
hoverColor: '{primary.300}',
activeColor: '{primary.200}'
},
highlight: {
background: 'color-mix(in srgb, {primary.400}, transparent 84%)',
focusBackground: 'color-mix(in srgb, {primary.400}, transparent 76%)',
color: 'rgba(255,255,255,.87)',
focusColor: 'rgba(255,255,255,.87)'
}
}
}
}
};
} else {
return {
semantic: {
primary: color.palette,
colorScheme: {
light: {
primary: {
color: '{primary.500}',
contrastColor: '#ffffff',
hoverColor: '{primary.600}',
activeColor: '{primary.700}'
},
highlight: {
background: '{primary.50}',
focusBackground: '{primary.100}',
color: '{primary.700}',
focusColor: '{primary.800}'
}
},
dark: {
primary: {
color: '{primary.400}',
contrastColor: '{surface.900}',
hoverColor: '{primary.300}',
activeColor: '{primary.200}'
},
highlight: {
background: 'color-mix(in srgb, {primary.400}, transparent 84%)',
focusBackground: 'color-mix(in srgb, {primary.400}, transparent 76%)',
color: 'rgba(255,255,255,.87)',
focusColor: 'rgba(255,255,255,.87)'
}
}
}
}
};
}
}
},
apply() { apply() {
this.saveTheme(); this.saveTheme();
updatePreset(this.preset); updatePreset(this.preset);
@ -247,6 +415,8 @@ app.mount("#app");
document.body.classList.remove('material'); document.body.classList.remove('material');
} }
/*
@todo: ask to the team about this
this.preset = { this.preset = {
primitive: newPreset.primitive, primitive: newPreset.primitive,
semantic: newPreset.semantic semantic: newPreset.semantic
@ -257,6 +427,13 @@ app.mount("#app");
this.preset.semantic.colorScheme.dark.surface = { ...{ 0: '#ffffff' }, ...this.preset.primitive.zinc }; this.preset.semantic.colorScheme.dark.surface = { ...{ 0: '#ffffff' }, ...this.preset.primitive.zinc };
usePreset(this.preset); usePreset(this.preset);
*/
const currentPreset = $t().preset(newPreset).preset(this.getPresetExt()).use({ useDefaultOptions: true }).preset;
this.preset = {
primitive: currentPreset.primitive,
semantic: currentPreset.semantic
};
}, },
saveTheme() { saveTheme() {
const localState = { const localState = {
@ -310,9 +487,12 @@ app.mount("#app");
this.$toast.add({ severity: 'success', summary: 'Success', detail: 'Tokens saved', life: 3000 }); this.$toast.add({ severity: 'success', summary: 'Success', detail: 'Tokens saved', life: 3000 });
}, },
replaceColorPalette() { replaceColorPalette() {
/*
@todo: ask to the team about this
this.preset.semantic.primary = this.preset.primitive.emerald; this.preset.semantic.primary = this.preset.primitive.emerald;
this.preset.semantic.colorScheme.light.surface = { ...{ 0: '#ffffff' }, ...this.preset.primitive.slate }; this.preset.semantic.colorScheme.light.surface = { ...{ 0: '#ffffff' }, ...this.preset.primitive.slate };
this.preset.semantic.colorScheme.dark.surface = { ...{ 0: '#ffffff' }, ...this.preset.primitive.zinc }; this.preset.semantic.colorScheme.dark.surface = { ...{ 0: '#ffffff' }, ...this.preset.primitive.zinc };
*/
}, },
transformTokenName(name) { transformTokenName(name) {
if (name && name.trim().length) { if (name && name.trim().length) {
@ -358,6 +538,28 @@ app.mount("#app");
event.preventDefault(); event.preventDefault();
} }
} }
},
computed: {
selectedPrimaryColor() {
return this.$appState.primary;
},
selectedSurfaceColor() {
return this.$appState.surface;
},
primaryColors() {
const presetPalette = presets[this.$appState.preset].primitive;
const colors = ['emerald', 'green', 'lime', 'orange', 'amber', 'yellow', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'fuchsia', 'pink', 'rose'];
const palettes = [{ name: 'noir', palette: {} }];
colors.forEach((color) => {
palettes.push({
name: color,
palette: presetPalette[color]
});
});
return palettes;
}
} }
}; };
</script> </script>

View File

@ -1,16 +1,29 @@
<template> <template>
<div class="flex border border-surface rounded-l-lg rounded-r-lg overflow-hidden"> <div class="flex border border-surface rounded-l-lg rounded-r-lg overflow-hidden">
<div v-for="color of value" :key="color" class="w-8 h-8" :style="{ backgroundColor: color }" :title="color"></div> <div v-for="(color, i) of value" :key="i + '_' + color" class="w-8 h-8" :style="getStyle(color)" :title="color"></div>
</div> </div>
</template> </template>
<script> <script>
import { isObject } from '@primeuix/utils';
import { $dt } from '@primevue/themes';
export default { export default {
props: { props: {
value: { value: {
type: Object, type: Object,
default: null default: null
} }
},
methods: {
getStyle(color) {
const colorScheme = this.$appState.darkTheme ? 'light' : 'dark';
const token = color?.replace(/{|}/g, '');
const tokenValue = $dt(token)?.value;
const backgroundColor = (isObject(tokenValue) ? tokenValue[colorScheme]?.value : tokenValue) ?? color;
return { backgroundColor };
}
} }
}; };
</script> </script>

View File

@ -3,7 +3,7 @@
<section class="flex justify-between items-center mb-4"> <section class="flex justify-between items-center mb-4">
<div class="flex gap-2 items-center"> <div class="flex gap-2 items-center">
<span class="text-sm">Primary</span> <span class="text-sm">Primary</span>
<input :value="$preset.semantic.primary['500']" @input="onPrimaryColorChange($event)" type="color" /> <input :defaultValue="primaryColor" @input="onPrimaryColorChange($event)" type="color" :title="$preset.semantic.primary['500']" />
</div> </div>
<DesignColorPalette :value="$preset.semantic.primary" /> <DesignColorPalette :value="$preset.semantic.primary" />
</section> </section>
@ -49,13 +49,26 @@
</template> </template>
<script> <script>
import { palette } from '@primevue/themes'; import { isObject } from '@primeuix/utils';
import { $dt, palette } from '@primevue/themes';
export default { export default {
inject: ['$preset'], inject: ['$preset'],
data() {
return {
primaryColor: this.getColor('{primary.500}')
};
},
methods: { methods: {
onPrimaryColorChange(event) { onPrimaryColorChange(event) {
this.$preset.semantic.primary = palette(event.target.value); this.$preset.semantic.primary = palette(event.target.value);
},
getColor(color) {
const colorScheme = this.$appState.darkTheme ? 'light' : 'dark';
const token = color?.replace(/{|}/g, '');
const tokenValue = $dt(token)?.value;
return (isObject(tokenValue) ? tokenValue[colorScheme]?.value : tokenValue) ?? color;
} }
} }
}; };

View File

@ -1,7 +1,7 @@
import { definePreset } from '@primevue/themes'; import { definePreset } from '@primevue/themes';
import Aura from '@primevue/themes/aura'; import Aura from '@primevue/themes/aura';
const Noir = definePreset(Aura, { export const NoirPreset = definePreset(Aura, {
semantic: { semantic: {
primary: { primary: {
50: '{surface.50}', 50: '{surface.50}',
@ -50,7 +50,7 @@ const Noir = definePreset(Aura, {
}); });
export default { export default {
preset: Noir, preset: NoirPreset,
options: { options: {
darkModeSelector: '.p-dark' darkModeSelector: '.p-dark'
} }

View File

@ -247,7 +247,7 @@ export function setupConfig(app, PrimeVue) {
isThemeChanged.value = false; isThemeChanged.value = false;
PrimeVueService.emit('config:theme:change', { newValue, oldValue }); PrimeVueService.emit('config:theme:change', { newValue, oldValue });
}, },
{ immediate: true, deep: true } { immediate: true, deep: false }
); );
const stopUnstyledWatcher = watch( const stopUnstyledWatcher = watch(