diff --git a/src/components/settings_modal/tabs/style_tab/style_tab.js b/src/components/settings_modal/tabs/style_tab/style_tab.js index 87867e7a..1f4ff190 100644 --- a/src/components/settings_modal/tabs/style_tab/style_tab.js +++ b/src/components/settings_modal/tabs/style_tab/style_tab.js @@ -4,6 +4,8 @@ import Select from 'src/components/select/select.vue' import Checkbox from 'src/components/checkbox/checkbox.vue' import ComponentPreview from 'src/components/component_preview/component_preview.vue' import StringSetting from '../../helpers/string_setting.vue' +import ShadowControl from 'src/components/shadow_control/shadow_control.vue' +import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import { init } from 'src/services/theme_data/theme_data_3.service.js' import { getCssRules } from 'src/services/theme_data/css_utils.js' @@ -11,6 +13,8 @@ import { getCssRules } from 'src/services/theme_data/css_utils.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faFloppyDisk, faFolderOpen, faFile } from '@fortawesome/free-solid-svg-icons' +const toValue = (x) => JSON.parse(JSON.stringify(x === undefined ? '"lol"' : x)) + library.add( faFile, faFloppyDisk, @@ -22,14 +26,18 @@ export default { Select, Checkbox, StringSetting, - ComponentPreview + ComponentPreview, + TabSwitcher, + ShadowControl }, setup () { + // Meta stuff const name = ref('') const author = ref('') const license = ref('') const website = ref('') + // Initialization stuff const palette = { // These are here just to establish order, // themes should override those @@ -61,43 +69,54 @@ export default { // Getting existing components const componentsContext = require.context('src', true, /\.style.js(on)?$/) - const componentKeysRaw = componentsContext.keys() + const componentKeysAll = componentsContext.keys() const componentsMap = new Map( - componentKeysRaw + componentKeysAll .map( key => [key, componentsContext(key).default] ).filter(([key, component]) => !component.virtual && !component.notEditable) ) const componentKeys = [...componentsMap.keys()] - // const componentValues = componentsMap.values() - // Initializing selected component and its computed descendants - const selectedComponentKey = ref(componentKeys[0]) - const selectedComponentValue = computed(() => componentsMap.get(selectedComponentKey.value)) - - const selectedComponentName = computed(() => selectedComponentValue.value.name) - const selectedComponentVariants = computed(() => { - return new Set(['normal', ...(Object.keys(selectedComponentValue.value.variants || {}))]) - }) - const selectedComponentStates = computed(() => { - return new Set([...(Object.keys(selectedComponentValue.value.states || {}).filter(x => x !== 'normal'))]) - }) + const selectedComponentKey = ref(componentsMap.keys().next().value) + const selectedComponent = computed(() => componentsMap.get(selectedComponentKey.value)) + const selectedComponentName = computed(() => selectedComponent.value.name) const selectedVariant = ref('normal') - const selectedStates = reactive(new Set()) + const selectedComponentVariantsAll = computed(() => { + return Object.keys({ normal: null, ...(selectedComponent.value.variants || {}) }) + }) + // const selectedComponentVariants = computed(() => { + // return selectedComponentVariantsAll.value.filter(x => x !== 'normal') + // }) - const updateSelectedStates = (state, v) => { - if (v) { - selectedStates.add(state) - } else { - selectedStates.delete(state) + const selectedStates = reactive(new Set()) + const selectedComponentStatesAll = computed(() => { + return Object.keys({ normal: null, ...(selectedComponent.value.states || {}) }) + }) + const selectedComponentStates = computed(() => { + return selectedComponentStatesAll.value.filter(x => x !== 'normal') + }) + + // Preview stuff + const editorHintStyle = computed(() => { + const editorHint = selectedComponent.value.editor + const styles = [] + if (editorHint && Object.keys(editorHint).length > 0) { + if (editorHint.aspect != null) { + styles.push(`aspect-ratio: ${editorHint.aspect} !important;`) + } + if (editorHint.border != null) { + styles.push(`border-width: ${editorHint.border}px !important;`) + } } - } + return styles.join('; ') + }) const simulatePseudoSelectors = css => css - .replace(selectedComponentValue.value.selector, '.ComponentPreview .preview-block') + .replace(selectedComponent.value.selector, '.ComponentPreview .preview-block') .replace(':active', '.preview-active') .replace(':hover', '.preview-hover') .replace(':active', '.preview-active') @@ -108,44 +127,70 @@ export default { const previewRules = reactive([]) const previewClass = computed(() => { const selectors = [] - if (!!selectedComponentValue.value.variants?.normal || selectedVariant.value !== 'normal') { - selectors.push(selectedComponentValue.value.variants[selectedVariant.value]) + if (!!selectedComponent.value.variants?.normal || selectedVariant.value !== 'normal') { + selectors.push(selectedComponent.value.variants[selectedVariant.value]) } if (selectedStates.size > 0) { selectedStates.forEach(state => { - const original = selectedComponentValue.value.states[state] + const original = selectedComponent.value.states[state] selectors.push(simulatePseudoSelectors(original)) }) } return selectors.map(x => x.substring(1)).join('') }) - - const editorHintStyle = computed(() => { - const editorHint = selectedComponentValue.value.editor - const styles = [] - if (editorHint && Object.keys(editorHint).length > 0) { - console.log('EH', editorHint) - if (editorHint.aspect != null) { - styles.push(`aspect-ratio: ${editorHint.aspect} !important;`) - } - if (editorHint.border != null) { - styles.push(`border-width: ${editorHint.border}px !important;`) - } - } - console.log('EH', styles) - return styles.join('; ') - }) - const previewCss = computed(() => { const scoped = getCssRules(previewRules) .map(simulatePseudoSelectors) return scoped.join('\n') }) + // Rules stuff + const selectedComponentRulesList = reactive([]) + const selectedComponentRulesObject = computed(() => { + const result = {} + selectedComponentRulesList.forEach( + (rule) => { + const component = rule.component + const { variant = 'normal', state = [] } = rule + result[component] = result[component] || {} + result[component][variant] = result[component][variant] || {} + result[component][variant][state.join(':')] = rule + } + ) + return result + }) + + // Edited rule + const editedRuleFallback = computed(() => { + const component = selectedComponentName.value + const variant = selectedVariant.value + const states = ['normal', ...selectedStates.keys()].join(':') + return selectedComponentRulesObject.value[component]?.[variant]?.[states] + }) + + const editedShadow = computed(() => { + return editedRuleFallback.value?.directives.shadow + }) + const updateSelectedComponent = () => { selectedVariant.value = 'normal' selectedStates.clear() + const processedRulesList = selectedComponent.value.defaultRules.map(r => { + const rule = { + component: selectedComponentName.value, + variant: 'normal', + ...r, + state: ['normal', ...(r.state || []).filter(x => x !== 'normal')] + } + return rule + }) + + selectedComponentRulesList.splice(0, selectedComponentRulesList.length) + selectedComponentRulesList.push(...processedRulesList) + + console.log('FALLBACK', toValue(editedRuleFallback.value)) + previewRules.splice(0, previewRules.length) previewRules.push(...init({ inputRuleset: [{ @@ -175,21 +220,29 @@ export default { website, componentKeys, componentsMap, - - selectedComponentValue, + selectedComponent, selectedComponentName, selectedComponentKey, - selectedComponentVariants, + selectedComponentVariantsAll, selectedComponentStates, - updateSelectedStates, + selectedComponentRulesObject, selectedVariant, selectedStates, - getFriendlyNamePath, - getStatePath, - getVariantPath, - editorHintStyle, + updateSelectedStates (state, v) { + if (v) { + selectedStates.add(state) + } else { + selectedStates.delete(state) + } + }, + editedRuleFallback, + editedShadow, previewCss, previewClass, + editorHintStyle, + getFriendlyNamePath, + getVariantPath, + getStatePath, fallbackI18n (translated, fallback) { if (translated.startsWith('settings.style.themes3')) { return fallback diff --git a/src/components/settings_modal/tabs/style_tab/style_tab.scss b/src/components/settings_modal/tabs/style_tab/style_tab.scss index 91c5572b..87e12337 100644 --- a/src/components/settings_modal/tabs/style_tab/style_tab.scss +++ b/src/components/settings_modal/tabs/style_tab/style_tab.scss @@ -1,4 +1,48 @@ .StyleTab { + .style-control { + display: flex; + flex-wrap: wrap; + align-items: baseline; + margin-bottom: 0.5em; + + .label { + margin-right: 1em; + flex: 1 1 10em; + line-height: 2; + } + + .opt { + margin: 0.5em; + } + + .color-input { + flex: 0 0 0; + } + + input, + select { + min-width: 3em; + margin: 0; + flex: 0; + + &[type="number"] { + min-width: 5em; + } + + &[type="range"] { + flex: 1; + min-width: 2em; + align-self: center; + margin: 0 0.5em; + } + + &[type="checkbox"] + i { + height: 1.1em; + align-self: center; + } + } + } + .setting-item { padding-bottom: 0; @@ -74,6 +118,8 @@ .state-selector { grid-area: state; + align-content: flex-start; + align-items: flex-start; } .variant-selector { @@ -96,5 +142,12 @@ .component-settings { grid-area: settings; } + + .editor-tab { + border-left: 1px solid var(--border); + border-right: 1px solid var(--border); + border-bottom: 1px solid var(--border); + padding: 0.5em; + } } } diff --git a/src/components/settings_modal/tabs/style_tab/style_tab.vue b/src/components/settings_modal/tabs/style_tab/style_tab.vue index 93ab250d..8e6c7fb1 100644 --- a/src/components/settings_modal/tabs/style_tab/style_tab.vue +++ b/src/components/settings_modal/tabs/style_tab/style_tab.vue @@ -83,44 +83,44 @@ {{ $t('settings.style.themes3.editor.variant_selector') }} -

+

{{ $t('settings.style.themes3.editor.only_variant') }} -

+
-

+

{{ $t('settings.style.themes3.editor.only_state') }} -

+
@@ -136,8 +136,31 @@ @update:shadow="({ axis, value }) => updateProperty(axis, value)" />
-
-
+ +
+ lol +
+
+ +
+
diff --git a/src/i18n/en.json b/src/i18n/en.json index d1cebb67..f97852a5 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -767,6 +767,8 @@ "states_selector": "States", "only_variant": "Component doesn't have any variants", "only_state": "Component only has default state", + "main_tab": "Main", + "shadows_tab": "Shadows", "components": { "normal": { "state": "Normal",