Skip to content

Commit

Permalink
Refactored AppDesigner
Browse files Browse the repository at this point in the history
  • Loading branch information
cagataycivici committed Dec 26, 2024
1 parent 96abb53 commit b3f30c3
Show file tree
Hide file tree
Showing 27 changed files with 840 additions and 510 deletions.
347 changes: 49 additions & 298 deletions apps/showcase/components/layout/AppDesigner.vue

Large diffs are not rendered by default.

169 changes: 169 additions & 0 deletions apps/showcase/components/layout/designer/create/DesignCreateTheme.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<template>
<section class="mb-6">
<span class="block text-lg font-semibold mb-2">Theme Name</span>
<input v-model="themeName" type="text" autocomplete="off" class="px-3 py-2 rounded-md border border-surface-300 dark:border-surface-700 flex-1" />
</section>

<section class="mb-6">
<div class="text-lg font-semibold mb-2">Foundation</div>
<span class="block text-muted-color leading-6 mb-4">Start by choosing a built-in theme as a foundation, or import your own design by uploading a tokens.json file created with the Prime UI Kit and Tokens Studio.</span>
<div class="flex flex-col">
<div class="flex flex-col gap-4 border border-surface-200 dark:border-surface-700 rounded-md p-4">
<span class="font-semibold">Base Theme</span>
<span class="text-muted-color">Variety of built-in themes with distinct characteristics.</span>
<div class="flex justify-between">
<SelectButton v-model="basePreset" :options="presetOptions" optionLabel="label" optionValue="value" :allowEmpty="false" />
<button
type="button"
@click="createThemeFromPreset"
icon="pi pi-download"
class="px-3 py-2 bg-zinc-950 hover:bg-zinc-800 text-white dark:bg-white dark:hover:bg-gray-100 dark:text-black rounded-md font-medium cursor-pointer transition-colors duration-200 focus:outline focus:outline-offset-2 focus:outline-zinc-950 focus:dark:outline-white"
>
Create
</button>
</div>
</div>

<Divider>OR</Divider>

<div class="flex flex-col gap-4 border border-surface-200 dark:border-surface-700 rounded-md p-4">
<span class="font-semibold">Import Figma Tokens </span>
<span class="text-muted-color leading-6">Export the token.json file from Figma Token Studio and import to the Visual Editor.</span>
<div class="flex justify-between">
<FileUpload mode="basic" pt:root:class="!justify-start" @select="onFileSelect($event)" />
<button
type="button"
@click="createThemeFromFigma"
icon="pi pi-download"
class="px-3 py-2 bg-zinc-950 hover:bg-zinc-800 text-white dark:bg-white dark:hover:bg-gray-100 dark:text-black rounded-md font-medium cursor-pointer transition-colors duration-200 focus:outline focus:outline-offset-2 focus:outline-zinc-950 focus:dark:outline-white"
>
Create
</button>
</div>
</div>
</div>
</section>
</template>

<script>
import { usePreset } from '@primevue/themes';
import Aura from '@primevue/themes/aura';
import Lara from '@primevue/themes/lara';
import Material from '@primevue/themes/material';
import Nora from '@primevue/themes/nora';
const presets = {
Aura,
Material,
Lara,
Nora
};
export default {
setup() {
const runtimeConfig = useRuntimeConfig();
return {
designerApiBase: runtimeConfig.public.designerApiBase
};
},
data() {
return {
themeName: null,
basePreset: 'Aura',
figmaData: null,
presetOptions: [
{ label: 'Aura', value: 'Aura' },
{ label: 'Material', value: 'Material' },
{ label: 'Lara', value: 'Lara' },
{ label: 'Nora', value: 'Nora' }
]
};
},
methods: {
replaceColorPalette() {
this.$appState.designer.theme.preset.semantic.primary = this.$appState.designer.theme.preset.primitive.emerald;
this.$appState.designer.theme.preset.semantic.colorScheme.light.surface = { ...{ 0: '#ffffff' }, ...this.$appState.designer.theme.preset.primitive.slate };
this.$appState.designer.theme.preset.semantic.colorScheme.dark.surface = { ...{ 0: '#ffffff' }, ...this.$appState.designer.theme.preset.primitive.zinc };
},
async createThemeFromPreset() {
const newPreset = presets[this.basePreset];
if (this.basePreset === 'Material') {
document.body.classList.add('material');
this.$primevue.config.ripple = true;
} else {
document.body.classList.remove('material');
}
const { error } = await $fetch(this.designerApiBase + '/theme/create', {
method: 'POST',
body: {
name: this.themeName,
preset: newPreset,
license_key: this.$appState.designer.licenseKey
}
});
if (error) {
this.$toast.add({ severity: 'error', summary: 'An error occured', detail: error.message, life: 3000 });
} else {
this.$appState.designer.theme = {
name: this.themeName,
preset: newPreset,
customTokens: [],
acTokens: []
};
this.replaceColorPalette();
usePreset(newPreset);
this.$appState.designer.activeView = 'editor';
}
},
onFileSelect(event) {
const file = event.files[0];
if (!file) {
return;
}
const reader = new FileReader();
reader.onload = (e) => {
this.figmaData = e.target.result;
};
reader.onerror = (e) => {
this.$toast.add({ severity: 'error', summary: 'An error occured', detail: 'Unable to read file', life: 3000 });
};
reader.readAsText(file);
},
async createThemeFromFigma() {
const { data: newPreset, error } = await $fetch(this.designerApiBase + '/theme/figma', {
method: 'POST',
body: {
name: this.themeName,
figma_tokens: this.figmaData,
license_key: this.$appState.designer.licenseKey
}
});
if (error) {
this.$toast.add({ severity: 'error', summary: 'An error occured', detail: error.message, life: 3000 });
} else {
this.$appState.designer.theme = {
name: this.themeName,
preset: newPreset,
customTokens: [],
acTokens: []
};
this.replaceColorPalette();
usePreset(newPreset);
this.$appState.designer.activeView = 'editor';
}
}
}
};
</script>
Loading

0 comments on commit b3f30c3

Please sign in to comment.