From a586b9f6d241c879f7081aa3e0116fd720d6e026 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 12 Sep 2024 12:46:47 +0300 Subject: [PATCH 01/38] fix themes3 specificity sorting --- src/components/button.style.js | 11 +++++ src/components/input.style.js | 43 ++++++++++++++++--- .../theme_data/theme_data_3.service.js | 36 ++++++++++++---- 3 files changed, 74 insertions(+), 16 deletions(-) diff --git a/src/components/button.style.js b/src/components/button.style.js index 6fec67a0..c31b0a3e 100644 --- a/src/components/button.style.js +++ b/src/components/button.style.js @@ -96,6 +96,17 @@ export default { textOpacity: 0.25, textOpacityMode: 'blend' } + }, + { + component: 'Icon', + parent: { + component: 'Button', + state: ['disabled'] + }, + directives: { + textOpacity: 0.25, + textOpacityMode: 'blend' + } } ] } diff --git a/src/components/input.style.js b/src/components/input.style.js index 139a0034..fb89414a 100644 --- a/src/components/input.style.js +++ b/src/components/input.style.js @@ -10,17 +10,18 @@ const hoverGlow = { export default { name: 'Input', selector: '.input', - variant: { + states: { + hover: ':hover:not(.disabled)', + focused: ':focus-within', + disabled: '.disabled' + }, + variants: { checkbox: '.-checkbox', radio: '.-radio' }, - states: { - disabled: ':disabled', - hover: ':hover:not(:disabled)', - focused: ':focus-within' - }, validInnerComponents: [ - 'Text' + 'Text', + 'Icon' ], defaultRules: [ { @@ -55,6 +56,34 @@ export default { directives: { shadow: [hoverGlow, '--defaultInputBevel'] } + }, + { + state: ['disabled'], + directives: { + background: '$blend(--inheritedBackground, 0.25, --parent)' + } + }, + { + component: 'Text', + parent: { + component: 'Input', + state: ['disabled'] + }, + directives: { + textOpacity: 0.25, + textOpacityMode: 'blend' + } + }, + { + component: 'Icon', + parent: { + component: 'Input', + state: ['disabled'] + }, + directives: { + textOpacity: 0.25, + textOpacityMode: 'blend' + } } ] } diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js index cf58da11..8a0c170b 100644 --- a/src/services/theme_data/theme_data_3.service.js +++ b/src/services/theme_data/theme_data_3.service.js @@ -182,7 +182,7 @@ export const init = ({ const rulesetUnsorted = [ ...Object.values(components) - .map(c => (c.defaultRules || []).map(r => ({ component: c.name, ...r, source: 'Built-in' }))) + .map(c => (c.defaultRules || []).map(r => ({ source: 'Built-in', component: c.name, ...r }))) .reduce((acc, arr) => [...acc, ...arr], []), ...inputRuleset ].map(rule => { @@ -198,18 +198,33 @@ export const init = ({ const ruleset = rulesetUnsorted .map((data, index) => ({ data, index })) - .sort(({ data: a, index: ai }, { data: b, index: bi }) => { + .toSorted(({ data: a, index: ai }, { data: b, index: bi }) => { const parentsA = unroll(a).length const parentsB = unroll(b).length - if (parentsA === parentsB) { - if (a.component === 'Text') return -1 - if (b.component === 'Text') return 1 + let aScore = 0 + let bScore = 0 + + aScore += parentsA * 1000 + bScore += parentsB * 1000 + + aScore += a.variant !== 'normal' ? 100 : 0 + bScore += b.variant !== 'normal' ? 100 : 0 + + aScore += a.state.filter(x => x !== 'normal').length * 1000 + bScore += b.state.filter(x => x !== 'normal').length * 1000 + + aScore += a.component === 'Text' ? 1 : 0 + bScore += b.component === 'Text' ? 1 : 0 + + // Debug + a.specifityScore = aScore + b.specifityScore = bScore + + if (aScore === bScore) { return ai - bi } - if (parentsA === 0 && parentsB !== 0) return -1 - if (parentsB === 0 && parentsA !== 0) return 1 - return parentsA - parentsB + return aScore - bScore }) .map(({ data }) => data) @@ -235,7 +250,10 @@ export const init = ({ // Inheriting all of the applicable rules const existingRules = ruleset.filter(findRules(combination)) - const computedDirectives = existingRules.map(r => r.directives).reduce((acc, directives) => ({ ...acc, ...directives }), {}) + const computedDirectives = + existingRules + .map(r => r.directives) + .reduce((acc, directives) => ({ ...acc, ...directives }), {}) const computedRule = { ...combination, directives: computedDirectives From a044dc377e77aade4696984fb42f7aa5db8c2561 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 12 Sep 2024 15:47:48 +0300 Subject: [PATCH 02/38] Massively upgraded shadow control, added sorting by specificity in themes3, added/fixed disabled inputs --- src/components/checkbox/checkbox.vue | 32 +- src/components/color_input/color_input.scss | 24 +- src/components/color_input/color_input.vue | 8 +- src/components/input.style.js | 2 +- .../opacity_input/opacity_input.vue | 2 + src/components/select/select.vue | 23 +- .../tabs/theme_tab/theme_tab.scss | 15 +- .../shadow_control/shadow_control.js | 5 +- .../shadow_control/shadow_control.scss | 178 +++++++++++ .../shadow_control/shadow_control.vue | 291 +++++++----------- src/i18n/en.json | 3 + 11 files changed, 375 insertions(+), 208 deletions(-) create mode 100644 src/components/shadow_control/shadow_control.scss diff --git a/src/components/checkbox/checkbox.vue b/src/components/checkbox/checkbox.vue index 6261bf3a..494605cf 100644 --- a/src/components/checkbox/checkbox.vue +++ b/src/components/checkbox/checkbox.vue @@ -3,6 +3,13 @@ class="checkbox" :class="{ disabled, indeterminate, 'indeterminate-fix': indeterminateTransitionFix }" > + + + @@ -93,14 +102,9 @@ export default { box-sizing: border-box; } - &.disabled { - .checkbox-indicator::before, - .label { - opacity: 0.5; - } - - .label { - color: var(--text); + .disabled { + .checkbox-indicator::before { + background-color: var(--background); } } @@ -121,8 +125,14 @@ export default { } } - & > span { - margin-left: 0.5em; + & > .label { + &.-after { + margin-left: 0.5em; + } + + &.-before { + margin-right: 0.5em; + } } } diff --git a/src/components/color_input/color_input.scss b/src/components/color_input/color_input.scss index b0fc879f..19c88a69 100644 --- a/src/components/color_input/color_input.scss +++ b/src/components/color_input/color_input.scss @@ -1,12 +1,15 @@ .color-input { display: inline-flex; + .label { + flex: 1 1 auto; + } + &-field.input { display: inline-flex; flex: 0 0 0; max-width: 9em; align-items: stretch; - padding: 0.2em 8px; input { color: var(--text); @@ -25,6 +28,7 @@ .nativeColor { cursor: pointer; flex: 0 0 auto; + padding: 0; input { appearance: none; @@ -41,10 +45,10 @@ .invalidIndicator, .transparentIndicator { flex: 0 0 2em; - margin: 0 0.5em; + margin: 0.2em 0.5em; min-width: 2em; align-self: stretch; - min-height: 1.5em; + min-height: 1.1em; border-radius: var(--roundness); } @@ -81,9 +85,17 @@ border-bottom-right-radius: var(--roundness); } } - } - .label { - flex: 1 1 auto; + &.disabled, + &:disabled { + .nativeColor input, + .computedIndicator, + .validIndicator, + .invalidIndicator, + .transparentIndicator { + /* stylelint-disable-next-line declaration-no-important */ + opacity: 0.25 !important; + } + } } } diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue index 66ee9d53..200b8631 100644 --- a/src/components/color_input/color_input.vue +++ b/src/components/color_input/color_input.vue @@ -6,6 +6,7 @@ @@ -16,10 +17,14 @@ class="opt" @update:modelValue="$emit('update:modelValue', typeof modelValue === 'undefined' ? fallback : undefined)" /> -
+
diff --git a/src/components/input.style.js b/src/components/input.style.js index fb89414a..e06dc7cb 100644 --- a/src/components/input.style.js +++ b/src/components/input.style.js @@ -60,7 +60,7 @@ export default { { state: ['disabled'], directives: { - background: '$blend(--inheritedBackground, 0.25, --parent)' + background: '--parent' } }, { diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue index a45bdd92..5a80b100 100644 --- a/src/components/opacity_input/opacity_input.vue +++ b/src/components/opacity_input/opacity_input.vue @@ -6,6 +6,7 @@ @@ -22,6 +23,7 @@ type="number" :value="modelValue || fallback" :disabled="!present || disabled" + :class="{ disabled: !present || disabled }" max="1" min="0" step=".05" diff --git a/src/components/select/select.vue b/src/components/select/select.vue index 32832126..7494f7d3 100644 --- a/src/components/select/select.vue +++ b/src/components/select/select.vue @@ -6,13 +6,14 @@ {{ ' ' }} @@ -26,6 +27,11 @@ label.Select { padding: 0; + &.disabled, + &:disabled { + background-color: var(--background); + } + select { appearance: none; background: transparent; @@ -39,6 +45,21 @@ label.Select { z-index: 1; height: 2em; line-height: 16px; + + &[multiple], + &[size] { + height: 100%; + padding: 0.2em; + + option { + background: transparent; + + &.-active { + color: var(--selectionText); + background-color: var(--selectionBackground); + } + } + } } .select-down-icon { diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.scss b/src/components/settings_modal/tabs/theme_tab/theme_tab.scss index 84933fb8..e86e61da 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.scss +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.scss @@ -25,7 +25,9 @@ margin-bottom: 5px; .label { + margin-right: 1em; flex: 1; + line-height: 2; } .opt { @@ -48,15 +50,14 @@ &[type="range"] { flex: 1; - min-width: 3em; - align-self: flex-start; + min-width: 2em; + align-self: center; + margin: 0 0.5em; } - } - &.disabled { - input, - select { - opacity: 0.5; + &[type="checkbox"] + i { + height: 1.1em; + align-self: center; } } } diff --git a/src/components/shadow_control/shadow_control.js b/src/components/shadow_control/shadow_control.js index f8e12dbf..e653854a 100644 --- a/src/components/shadow_control/shadow_control.js +++ b/src/components/shadow_control/shadow_control.js @@ -1,6 +1,7 @@ import ColorInput from '../color_input/color_input.vue' import OpacityInput from '../opacity_input/opacity_input.vue' import Select from '../select/select.vue' +import Checkbox from '../checkbox/checkbox.vue' import { getCssShadow } from '../../services/theme_data/theme_data.service.js' import { hex2rgb } from '../../services/color_convert/color_convert.js' import { library } from '@fortawesome/fontawesome-svg-core' @@ -40,6 +41,7 @@ export default { emits: ['update:modelValue'], data () { return { + lightGrid: false, selectedId: 0, // TODO there are some bugs regarding display of array (it's not getting updated when deleting for some reason) cValue: (this.modelValue || this.fallback || []).map(toModel) @@ -48,7 +50,8 @@ export default { components: { ColorInput, OpacityInput, - Select + Select, + Checkbox }, methods: { add () { diff --git a/src/components/shadow_control/shadow_control.scss b/src/components/shadow_control/shadow_control.scss new file mode 100644 index 00000000..0fba39f3 --- /dev/null +++ b/src/components/shadow_control/shadow_control.scss @@ -0,0 +1,178 @@ +.settings-modal .settings-modal-panel .shadow-control { + display: flex; + flex-wrap: wrap; + justify-content: stretch; + grid-gap: 0.25em; + margin-bottom: 1em; + + .shadow-switcher { + order: 1; + flex: 1 0 6em; + min-width: 6em; + margin-right: 0.125em; + display: flex; + flex-direction: column; + + .shadow-list { + flex: 1 0 auto; + } + + .arrange-buttons { + flex: 0 0 auto; + display: grid; + grid-auto-columns: 1fr; + grid-auto-flow: column; + grid-gap: 0.125em; + margin-top: 0.25em; + + .button-default { + margin: 0; + padding: 0; + } + } + } + + .shadow-tweak { + order: 3; + flex: 2 0 10em; + min-width: 10em; + margin-left: 0.125em; + margin-right: 0.125em; + + /* hack */ + .input-boolean { + flex: 1; + display: flex; + + .label { + flex: 1; + } + } + + .input-string { + flex: 1 0 5em; + } + + .id-control { + align-items: stretch; + + .shadow-switcher, + .btn { + min-width: 1px; + margin-right: 5px; + } + + .btn { + padding: 0 0.4em; + margin: 0 0.1em; + } + } + } + + .shadow-preview { + order: 2; + flex: 3 3 15em; + min-width: 10em; + display: grid; + margin-left: 0.125em; + align-self: start; + grid-template-columns: 3em 1fr 3em; + grid-template-rows: 2em 1fr 2em; + grid-template-areas: + ". header y-num " + ". preview y-slide" + "x-num x-slide . " + "options options options"; + grid-gap: 0.5em; + + .header { + grid-area: header; + justify-self: center; + align-self: baseline; + line-height: 2; + } + + .input-light-grid { + grid-area: options; + justify-self: end; + } + + .input-number { + min-width: 2em; + } + + .x-shift-number { + grid-area: x-num; + } + + .x-shift-slider { + grid-area: x-slide; + height: auto; + align-self: start; + min-width: 10em; + } + + .y-shift-number { + grid-area: y-num; + } + + .y-shift-slider { + grid-area: y-slide; + writing-mode: vertical-lr; + justify-self: left; + min-height: 10em; + } + + .x-shift-slider, + .y-shift-slider { + padding: 0; + } + + .preview-window { + --__grid-color1: rgb(102 102 102); + --__grid-color2: rgb(153 153 153); + --__grid-color1-disabled: rgba(102 102 102 / 20%); + --__grid-color2-disabled: rgba(153 153 153 / 20%); + + &.-light-grid { + --__grid-color1: rgb(205 205 205); + --__grid-color2: rgb(255 255 255); + --__grid-color1-disabled: rgba(205 205 205 / 20%); + --__grid-color2-disabled: rgba(255 255 255 / 20%); + } + + grid-area: preview; + aspect-ratio: 1; + display: flex; + align-items: center; + justify-content: center; + min-width: 10em; + min-height: 10em; + background-color: var(--__grid-color2); + background-image: + linear-gradient(45deg, var(--__grid-color1) 25%, transparent 25%), + linear-gradient(-45deg, var(--__grid-color1) 25%, transparent 25%), + linear-gradient(45deg, transparent 75%, var(--__grid-color1) 75%), + linear-gradient(-45deg, transparent 75%, var(--__grid-color1) 75%); + background-size: 20px 20px; + background-position: 0 0, 0 10px, 10px -10px, -10px 0; + border-radius: var(--roundness); + + &.disabled { + background-color: var(--__grid-color2-disabled); + background-image: + linear-gradient(45deg, var(--__grid-color1-disabled) 25%, transparent 25%), + linear-gradient(-45deg, var(--__grid-color1-disabled) 25%, transparent 25%), + linear-gradient(45deg, transparent 75%, var(--__grid-color1-disabled) 75%), + linear-gradient(-45deg, transparent 75%, var(--__grid-color1-disabled) 75%); + } + + .preview-block { + width: 33%; + height: 33%; + border-radius: var(--roundness); + background: var(--background); + } + } + } +} diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue index c3b956cd..77d7c15a 100644 --- a/src/components/shadow_control/shadow_control.vue +++ b/src/components/shadow_control/shadow_control.vue @@ -1,81 +1,92 @@