basic colors / settings present

This commit is contained in:
Henry Jameson 2024-09-26 22:31:28 +03:00
parent ef795becf6
commit fb40694e8e
10 changed files with 256 additions and 80 deletions

View file

@ -14,6 +14,10 @@ export default {
warning: '.warning', warning: '.warning',
success: '.success' success: '.success'
}, },
editor: {
border: 1,
aspect: '3 / 1'
},
defaultRules: [ defaultRules: [
{ {
directives: { directives: {

View file

@ -23,8 +23,7 @@ export default {
// This (currently) is further multipled by number of places where component can exist. // This (currently) is further multipled by number of places where component can exist.
}, },
editor: { editor: {
aspect: '6:1', aspect: '2 / 1'
border: 0
}, },
// This lists all other components that can possibly exist within one. Recursion is currently not supported (and probably won't be supported ever). // This lists all other components that can possibly exist within one. Recursion is currently not supported (and probably won't be supported ever).
validInnerComponents: [ validInnerComponents: [

View file

@ -168,12 +168,13 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 33%; min-width: 33%;
height: 33%; min-height: 33%;
border-radius: var(--roundness); max-width: 80%;
background: var(--background); max-height: 80%;
box-shadow: var(--shadow); border-width: 0;
border: 1px solid var(--border); border-style: solid;
border-color: var(--border);
} }
} }
} }

View file

@ -1,6 +1,7 @@
export default { export default {
name: 'Root', name: 'Root',
selector: ':root', selector: ':root',
notEditable: true,
validInnerComponents: [ validInnerComponents: [
'Underlay', 'Underlay',
'Modals', 'Modals',

View file

@ -1,11 +1,15 @@
import { ref, reactive, computed, watch } from 'vue' import { ref, reactive, computed, watch } from 'vue'
import { get } from 'lodash'
import Select from 'src/components/select/select.vue' import Select from 'src/components/select/select.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue' import Checkbox from 'src/components/checkbox/checkbox.vue'
import ComponentPreview from 'src/components/component_preview/component_preview.vue' import ComponentPreview from 'src/components/component_preview/component_preview.vue'
import StringSetting from '../../helpers/string_setting.vue' import StringSetting from '../../helpers/string_setting.vue'
import ShadowControl from 'src/components/shadow_control/shadow_control.vue' import ShadowControl from 'src/components/shadow_control/shadow_control.vue'
import ColorInput from 'src/components/color_input/color_input.vue'
import OpacityInput from 'src/components/opacity_input/opacity_input.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
import Popover from 'src/components/popover/popover.vue'
import { init } from 'src/services/theme_data/theme_data_3.service.js' import { init } from 'src/services/theme_data/theme_data_3.service.js'
import { getCssRules } from 'src/services/theme_data/css_utils.js' import { getCssRules } from 'src/services/theme_data/css_utils.js'
@ -25,10 +29,13 @@ export default {
components: { components: {
Select, Select,
Checkbox, Checkbox,
Popover,
StringSetting, StringSetting,
ComponentPreview, ComponentPreview,
TabSwitcher, TabSwitcher,
ShadowControl ShadowControl,
ColorInput,
OpacityInput
}, },
setup () { setup () {
// Meta stuff // Meta stuff
@ -168,6 +175,60 @@ export default {
return selectedComponentRulesObject.value[component]?.[variant]?.[states] return selectedComponentRulesObject.value[component]?.[variant]?.[states]
}) })
const editedSubrulesFallback = computed(() => {
const parentComponent = selectedComponentName.value
const subrules = {}
selectedComponentRulesList.forEach(sr => {
console.log('SR', toValue(sr))
if (!sr.parent) return
if (sr.parent.component === parentComponent) {
const component = sr.component
const { variant = 'normal', state = [] } = sr
subrules[component] = {} || subrules[component]
subrules[component][variant] = {} || subrules[component][variant]
subrules[component][variant][state.join(':')] = sr
}
})
return subrules
})
const componentHas = (subComponent) => {
return !!selectedComponent.value.validInnerComponents?.find(x => x === subComponent)
}
const editedTextColor = computed(() => get(
editedSubrulesFallback.value,
'Text.normal.normal.directives.textColor',
null
))
const editedLinkColor = computed(() => get(
editedSubrulesFallback.value,
'Link.normal.normal.directives.linkColor',
null
))
const editedIconColor = computed(() => get(
editedSubrulesFallback.value,
'Icon.normal.normal.directives.iconColor',
null
))
const editedBackground = computed(() => get(
editedRuleFallback.value,
'directives.background',
null
))
const editedOpacity = computed(() => get(
editedSubrulesFallback.value,
'Link.normal.normal.directives.linkColor',
null
))
const editedShadow = computed(() => { const editedShadow = computed(() => {
return editedRuleFallback.value?.directives.shadow return editedRuleFallback.value?.directives.shadow
}) })
@ -189,8 +250,6 @@ export default {
selectedComponentRulesList.splice(0, selectedComponentRulesList.length) selectedComponentRulesList.splice(0, selectedComponentRulesList.length)
selectedComponentRulesList.push(...processedRulesList) selectedComponentRulesList.push(...processedRulesList)
console.log('FALLBACK', toValue(editedRuleFallback.value))
previewRules.splice(0, previewRules.length) previewRules.splice(0, previewRules.length)
previewRules.push(...init({ previewRules.push(...init({
inputRuleset: [{ inputRuleset: [{
@ -213,6 +272,11 @@ export default {
updateSelectedComponent updateSelectedComponent
) )
const isShadowTabOpen = ref(false)
const onTabSwitch = (tab) => {
isShadowTabOpen.value = tab === 'shadow'
}
return { return {
name, name,
author, author,
@ -236,6 +300,12 @@ export default {
} }
}, },
editedRuleFallback, editedRuleFallback,
editedSubrulesFallback,
editedBackground,
editedOpacity,
editedTextColor,
editedLinkColor,
editedIconColor,
editedShadow, editedShadow,
previewCss, previewCss,
previewClass, previewClass,
@ -243,6 +313,9 @@ export default {
getFriendlyNamePath, getFriendlyNamePath,
getVariantPath, getVariantPath,
getStatePath, getStatePath,
componentHas,
isShadowTabOpen,
onTabSwitch,
fallbackI18n (translated, fallback) { fallbackI18n (translated, fallback) {
if (translated.startsWith('settings.style.themes3')) { if (translated.startsWith('settings.style.themes3')) {
return fallback return fallback

View file

@ -6,8 +6,8 @@
margin-bottom: 0.5em; margin-bottom: 0.5em;
.label { .label {
margin-right: 1em; margin-right: 0.5em;
flex: 1 1 10em; flex: 1 1 0;
line-height: 2; line-height: 2;
} }
@ -26,14 +26,18 @@
flex: 0; flex: 0;
&[type="number"] { &[type="number"] {
min-width: 5em; min-width: 9em;
&.-small {
min-width: 5em;
}
} }
&[type="range"] { &[type="range"] {
flex: 1; flex: 1;
min-width: 2em; min-width: 9em;
align-self: center; align-self: center;
margin: 0 0.5em; margin: 0 0.25em;
} }
&[type="checkbox"] + i { &[type="checkbox"] + i {
@ -84,42 +88,38 @@
.component-editor { .component-editor {
display: grid; display: grid;
grid-template-columns: 10em 2fr 3fr; grid-template-columns: 4fr 3fr 5fr;
grid-template-rows: auto auto 1fr; grid-template-rows: auto auto 1fr;
grid-gap: 0.5em; grid-gap: 0.5em;
grid-template-areas: grid-template-areas:
"component-label component ." "component component variant"
"variant preview settings" "state state state"
"state preview settings"; "preview settings settings";
.compopnent-selector { .component-selector {
grid-area: component; grid-area: component;
align-self: center; align-self: center;
} }
.component-selector-label { .component-selector,
grid-area: component-label;
align-self: center;
text-align: right;
font-weight: bold;
}
.state-selector, .state-selector,
.variant-selector { .variant-selector {
display: grid; display: grid;
grid-template-rows: auto auto; grid-template-columns: 1fr minmax(1fr, 10em);
grid-auto-flow: rows; grid-template-rows: auto;
grid-auto-flow: column;
grid-gap: 0.5em; grid-gap: 0.5em;
align-items: baseline;
> label { > label:not(.Select) {
font-weight: bold; font-weight: bold;
justify-self: right;
} }
} }
.state-selector { .state-selector {
grid-area: state; grid-area: state;
align-content: flex-start; grid-template-columns: minmax(min-content, 7em) 1fr;
align-items: flex-start;
} }
.variant-selector { .variant-selector {
@ -129,13 +129,19 @@
.state-selector-list { .state-selector-list {
display: grid; display: grid;
list-style: none; list-style: none;
grid-template-rows: auto; grid-auto-flow: dense;
grid-template-columns: repeat(5, minmax(min-content, 1fr));
grid-auto-rows: 1fr;
grid-gap: 0.5em; grid-gap: 0.5em;
padding: 0; padding: 0;
margin: 0; margin: 0;
} }
.preview-container { .preview-container {
--border: none;
--shadow: none;
--roundness: none;
grid-area: preview; grid-area: preview;
} }
@ -144,10 +150,21 @@
} }
.editor-tab { .editor-tab {
display: grid;
grid-template-columns: 1fr 2em;
grid-column-gap: 0.5em;
align-items: center;
grid-auto-rows: min-content;
grid-auto-flow: dense;
border-left: 1px solid var(--border); border-left: 1px solid var(--border);
border-right: 1px solid var(--border); border-right: 1px solid var(--border);
border-bottom: 1px solid var(--border); border-bottom: 1px solid var(--border);
padding: 0.5em; padding: 0.5em;
} }
.shadow-tab {
grid-template-columns: 1fr;
justify-items: center;
}
} }
} }

View file

@ -52,38 +52,32 @@
</ul> </ul>
</div> </div>
<div class="setting-item component-editor"> <div class="setting-item component-editor">
<label <div class="component-selector">
for="component-selector" <label for="component-selector">
class="component-selector-label"
>
{{ $t('settings.style.themes3.editor.component_selector') }}
{{ ' ' }}
</label>
<Select
v-model="selectedComponentKey"
id="component-selector"
class="component-selector"
>
<option
v-for="key in componentKeys"
:key="'component-' + key"
:value="key"
>
{{ fallbackI18n($t(getFriendlyNamePath(componentsMap.get(key).name)), componentsMap.get(key).name) }}
</option>
</Select>
<label
for="component-selector"
class="component-selector-label"
>
{{ $t('settings.style.themes3.editor.component_selector') }} {{ $t('settings.style.themes3.editor.component_selector') }}
{{ ' ' }}
</label> </label>
<div class="variant-selector"> <Select
v-model="selectedComponentKey"
id="component-selector"
>
<option
v-for="key in componentKeys"
:key="'component-' + key"
:value="key"
>
{{ fallbackI18n($t(getFriendlyNamePath(componentsMap.get(key).name)), componentsMap.get(key).name) }}
</option>
</Select>
</div>
<div
class="variant-selector"
v-if="selectedComponentVariantsAll.length > 1"
>
<label for="variant-selector"> <label for="variant-selector">
{{ $t('settings.style.themes3.editor.variant_selector') }} {{ $t('settings.style.themes3.editor.variant_selector') }}
</label> </label>
<Select <Select
v-if="selectedComponentVariantsAll.length > 1"
v-model="selectedVariant" v-model="selectedVariant"
> >
<option <option
@ -94,16 +88,15 @@
{{ fallbackI18n($t(getVariantPath(selectedComponentName, variant)), variant) }} {{ fallbackI18n($t(getVariantPath(selectedComponentName, variant)), variant) }}
</option> </option>
</Select> </Select>
<div v-else>
{{ $t('settings.style.themes3.editor.only_variant') }}
</div>
</div> </div>
<div class="state-selector"> <div
<label for="variant-selector"> class="state-selector"
v-if="selectedComponentStates.length > 0"
>
<label>
{{ $t('settings.style.themes3.editor.states_selector') }} {{ $t('settings.style.themes3.editor.states_selector') }}
</label> </label>
<ul <ul
v-if="selectedComponentStates.length > 0"
class="state-selector-list" class="state-selector-list"
> >
<li <li
@ -118,9 +111,6 @@
</Checkbox> </Checkbox>
</li> </li>
</ul> </ul>
<div v-else>
{{ $t('settings.style.themes3.editor.only_state') }}
</div>
</div> </div>
<div class="preview-container"> <div class="preview-container">
<!-- eslint-disable vue/no-v-html vue/no-v-text-v-html-on-component --> <!-- eslint-disable vue/no-v-html vue/no-v-text-v-html-on-component -->
@ -131,6 +121,8 @@
<!-- eslint-enable vue/no-v-html vue/no-v-text-v-html-on-component --> <!-- eslint-enable vue/no-v-html vue/no-v-text-v-html-on-component -->
<ComponentPreview <ComponentPreview
class="component-preview" class="component-preview"
showText="componentHas('Text')"
:shadowControl="isShadowTabOpen && editedShadow"
:previewClass="previewClass" :previewClass="previewClass"
:previewStyle="editorHintStyle" :previewStyle="editorHintStyle"
@update:shadow="({ axis, value }) => updateProperty(axis, value)" @update:shadow="({ axis, value }) => updateProperty(axis, value)"
@ -144,15 +136,97 @@
<div <div
class="editor-tab" class="editor-tab"
:label="$t('settings.style.themes3.editor.main_tab')" :label="$t('settings.style.themes3.editor.main_tab')"
:data-tab-name="main" key="main"
> >
lol <ColorInput
v-model="editedBackground"
:disabled="!editedBackgroundPresent"
:label="$t('settings.style.themes3.editor.background')"
/>
<Popover trigger="hover">
<template #trigger>
<Checkbox v-model="editedBackgroundPresent" />
</template>
<template #content>
{{ $t('settings.style.themes3.editor.include_in_rule') }}
</template>
</Popover>
<OpacityInput
v-model="editedOpacity"
:disabled="!editedOpacityPresent"
:label="$t('settings.style.themes3.editor.opacity')"
/>
<Popover trigger="hover">
<template #trigger>
<Checkbox v-model="editedOpacityPresent" />
</template>
<template #content>
{{ $t('settings.style.themes3.editor.include_in_rule') }}
</template>
</Popover>
<ColorInput
v-model="editedTextColor"
:label="$t('settings.style.themes3.editor.text_color')"
:disabled="!editedTextPresent"
v-if="componentHas('Text')"
/>
<Popover
trigger="hover"
v-if="componentHas('Text')"
>
<template #trigger>
<Checkbox v-model="editedTextPresent" />
</template>
<template #content>
{{ $t('settings.style.themes3.editor.include_in_rule') }}
</template>
</Popover>
<ColorInput
v-model="editedLinkColor"
:label="$t('settings.style.themes3.editor.link_color')"
:disabled="!editedLinkPresent"
v-if="componentHas('Link')"
/>
<Popover
trigger="hover"
v-if="componentHas('Link')"
>
<template #trigger>
<Checkbox v-model="editedLinkPresent" />
</template>
<template #content>
{{ $t('settings.style.themes3.editor.include_in_rule') }}
</template>
</Popover>
<ColorInput
v-model="editedIconColor"
:label="$t('settings.style.themes3.editor.icon_color')"
:disabled="!editedOpacityPresent"
v-if="componentHas('Icon')"
/>
<Popover
trigger="hover"
v-if="componentHas('Icon')"
>
<template #trigger>
<Checkbox v-model="editedIconPresent" />
</template>
<template #content>
{{ $t('settings.style.themes3.editor.include_in_rule') }}
</template>
</Popover>
</div> </div>
<div <div
class="editor-tab" class="editor-tab shadow-tab"
:label="$t('settings.style.themes3.editor.shadows_tab')" :label="$t('settings.style.themes3.editor.shadows_tab')"
:data-tab-name="shadow" key="shadow"
> >
<Checkbox
class="style-control"
v-model="editedOpacityPresent"
>
{{ $t('settings.style.themes3.editor.include_in_rule') }}
</checkbox>
<ShadowControl <ShadowControl
v-model="editedShadow" v-model="editedShadow"
:no-preview="true" :no-preview="true"

View file

@ -45,12 +45,16 @@
flex: 0; flex: 0;
&[type="number"] { &[type="number"] {
min-width: 5em; min-width: 9em;
&.-small {
min-width: 5em;
}
} }
&[type="range"] { &[type="range"] {
flex: 1; flex: 1;
min-width: 2em; min-width: 9em;
align-self: center; align-self: center;
margin: 0 0.5em; margin: 0 0.5em;
} }

View file

@ -144,7 +144,7 @@
:value="selected?.blur" :value="selected?.blur"
:disabled="!present" :disabled="!present"
:class="{ disabled: !present }" :class="{ disabled: !present }"
class="input input-number" class="input input-number -small"
type="number" type="number"
min="0" min="0"
@input="e => updateProperty('blur', e.target.value)" @input="e => updateProperty('blur', e.target.value)"
@ -167,7 +167,7 @@
:disabled="!present || (separateInset && !selected?.inset)" :disabled="!present || (separateInset && !selected?.inset)"
:class="{ disabled: !present || (separateInset && !selected?.inset) }" :class="{ disabled: !present || (separateInset && !selected?.inset) }"
name="spread" name="spread"
class="input input-range" class="input input-number -small"
type="range" type="range"
max="20" max="20"
min="-20" min="-20"
@ -177,7 +177,7 @@
:value="selected?.spread" :value="selected?.spread"
:disabled="{ disabled: !present || (separateInset && !selected?.inset) }" :disabled="{ disabled: !present || (separateInset && !selected?.inset) }"
:class="{ disabled: !present || (separateInset && !selected?.inset) }" :class="{ disabled: !present || (separateInset && !selected?.inset) }"
class="input input-number" class="input input-number -small"
type="number" type="number"
@input="e => updateProperty('spread', e.target.value)" @input="e => updateProperty('spread', e.target.value)"
> >

View file

@ -765,10 +765,13 @@
"component_selector": "Component", "component_selector": "Component",
"variant_selector": "Variant", "variant_selector": "Variant",
"states_selector": "States", "states_selector": "States",
"only_variant": "Component doesn't have any variants",
"only_state": "Component only has default state",
"main_tab": "Main", "main_tab": "Main",
"shadows_tab": "Shadows", "shadows_tab": "Shadows",
"background": "Background color",
"text_color": "Text color",
"icon_color": "Icon color",
"link_color": "Link color",
"include_in_rule": "Add to rule",
"components": { "components": {
"normal": { "normal": {
"state": "Normal", "state": "Normal",