commit: d772f6cfeb66fca3e8947819620f450b590382e9
parent f4d29b5d5ec741991a5228c478f2dc4a7e24f2d1
Author: Henry Jameson <me@hjkos.com>
Date: Sat, 19 Oct 2024 17:19:54 +0300
fix shadow control misbehaving in style tab
Diffstat:
7 files changed, 83 insertions(+), 31 deletions(-)
diff --git a/src/components/component_preview/component_preview.vue b/src/components/component_preview/component_preview.vue
@@ -3,6 +3,12 @@
class="ComponentPreview"
:class="{ '-shadow-controls': shadowControl }"
>
+ <!-- eslint-disable vue/no-v-html vue/no-v-text-v-html-on-component -->
+ <component
+ :is="'style'"
+ v-html="previewCss"
+ />
+ <!-- eslint-enable vue/no-v-html vue/no-v-text-v-html-on-component -->
<label
v-show="shadowControl"
class="header"
@@ -11,7 +17,7 @@
{{ $t('settings.style.shadows.offset') }}
</label>
<input
- v-show="shadowControl"
+ v-show="shadowControl && !hideControls"
:value="shadow?.y"
:disabled="disabled"
:class="{ disabled }"
@@ -20,7 +26,7 @@
@input="e => updateProperty('y', e.target.value)"
>
<input
- v-show="shadowControl"
+ v-show="shadowControl && !hideControls"
:value="shadow?.y"
:disabled="disabled"
:class="{ disabled }"
@@ -41,9 +47,14 @@
>
{{ $t('settings.style.themes3.editor.test_string') }}
</div>
+ <div v-if="invalid" class="invalid-container">
+ <div class="alert error invalid-label">
+ {{ $t('settings.style.themes3.editor.invalid') }}
+ </div>
+ </div>
</div>
<input
- v-show="shadowControl"
+ v-show="shadowControl && !hideControls"
:value="shadow?.x"
:disabled="disabled"
:class="{ disabled }"
@@ -52,7 +63,7 @@
@input="e => updateProperty('x', e.target.value)"
>
<input
- v-show="shadowControl"
+ v-show="shadowControl && !hideControls"
:value="shadow?.x"
:disabled="disabled"
:class="{ disabled }"
@@ -85,7 +96,9 @@ export default {
'shadowControl',
'previewClass',
'previewStyle',
- 'disabled'
+ 'previewCss',
+ 'disabled',
+ 'invalid'
],
emits: ['update:shadow'],
data () {
@@ -93,9 +106,14 @@ export default {
lightGrid: false
}
},
+ computed: {
+ hideControls () {
+ return typeof this.shadow === 'string'
+ }
+ },
methods: {
updateProperty (axis, value) {
- this.$emit('update:shadow', { axis, value })
+ this.$emit('update:shadow', { axis, value: Number(value) })
}
}
}
@@ -121,6 +139,22 @@ export default {
line-height: 2;
}
+ .invalid-container {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ display: grid;
+ align-items: center;
+ justify-items: center;
+ background-color: rgba(100 0 0 / 50%);
+
+ .alert {
+ padding: 0.5em 1em;
+ }
+ }
+
.input-light-grid {
grid-area: options;
justify-self: center;
@@ -170,6 +204,7 @@ export default {
--__grid-color2-disabled: rgba(255 255 255 / 20%);
}
+ position: relative;
grid-area: preview;
aspect-ratio: 1;
display: flex;
diff --git a/src/components/settings_modal/tabs/style_tab/style_tab.vue b/src/components/settings_modal/tabs/style_tab/style_tab.vue
@@ -148,6 +148,7 @@
:shadow-control="isShadowTabOpen"
:preview-class="previewClass"
:preview-style="editorHintStyle"
+ :preview-css="previewCss"
:disabled="!editedSubShadow && typeof editedShadow !== 'string'"
:shadow="editedSubShadow"
@update:shadow="({ axis, value }) => updateSubShadow(axis, value)"
@@ -285,7 +286,7 @@
:disabled="!isShadowPresent"
:no-preview="true"
:compact="true"
- :compute-color="computeColor"
+ :static-vars="selectedPalette"
@subShadowSelected="onSubShadow"
/>
</div>
@@ -409,7 +410,7 @@
<ShadowControl
v-if="selectedVirtualDirectiveValType === 'shadow'"
v-model="draftVirtualDirective"
- :compute-color="computeColor"
+ :static-vars="selectedPalette"
:compact="true"
/>
<ColorInput
diff --git a/src/components/shadow_control/shadow_control.js b/src/components/shadow_control/shadow_control.js
@@ -5,9 +5,13 @@ import SelectMotion from 'src/components/select/select_motion.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue'
import Popover from 'src/components/popover/popover.vue'
import ComponentPreview from 'src/components/component_preview/component_preview.vue'
-import { getCssShadow, getCssShadowFilter } from '../../services/theme_data/theme_data.service.js'
+import { rgb2hex } from 'src/services/color_convert/color_convert.js'
+import { serializeShadow } from 'src/services/theme_data/iss_serializer.js'
+import { deserializeShadow } from 'src/services/theme_data/iss_deserializer.js'
+import { getCssShadow, getCssShadowFilter } from 'src/services/theme_data/css_utils.js'
+import { findShadow, findColor } from 'src/services/theme_data/theme_data_3.service.js'
import { library } from '@fortawesome/fontawesome-svg-core'
-import { throttle } from 'lodash'
+import { throttle, flattenDeep } from 'lodash'
import {
faTimes,
faChevronDown,
@@ -46,13 +50,14 @@ export default {
'separateInset',
'noPreview',
'disabled',
- 'computeColor',
+ 'staticVars',
'compact'
],
emits: ['update:modelValue', 'subShadowSelected'],
data () {
return {
- selectedId: 0
+ selectedId: 0,
+ invalid: false
}
},
components: {
@@ -97,7 +102,7 @@ export default {
}
},
present () {
- return this.selected != null && !this.usingFallback
+ return this.selected != null && this.modelValue != null
},
shadowsAreNull () {
return this.modelValue == null
@@ -105,31 +110,38 @@ export default {
currentFallback () {
return this.fallback?.[this.selectedId]
},
- usingFallback () {
- return this.modelValue == null
- },
- getFallback () {
- if (typeof this.computeColor === 'function' && this.selected?.color) {
- return this.computeColor(this.selected.color)
+ getColorFallback () {
+ if (this.staticVars && this.selected?.color) {
+ const computedColor = findColor(this.selected.color, { dynamicVars: {}, staticVars: this.staticVars }, true)
+ if (computedColor) return rgb2hex(computedColor)
+ return null
} else {
return this.currentFallback?.color
}
},
style () {
try {
+ let result
+ const serialized = this.cValue.map(x => serializeShadow(x)).join(',')
+ deserializeShadow(serialized) // validate
+ const expandedShadow = flattenDeep(findShadow(this.cValue, { dynamicVars: {}, staticVars: this.staticVars }))
+ const fixedShadows = expandedShadow.map(x => ({ ...x, color: console.log(x) || rgb2hex(x.color) }))
+
if (this.separateInset) {
- return {
- filter: getCssShadowFilter(this.cValue),
- boxShadow: getCssShadow(this.cValue, true)
+ result = {
+ filter: getCssShadowFilter(fixedShadows),
+ boxShadow: getCssShadow(fixedShadows, true)
+ }
+ } else {
+ result = {
+ boxShadow: getCssShadow(fixedShadows)
}
}
- return {
- boxShadow: getCssShadow(this.cValue)
- }
+ this.invalid = false
+ return result
} catch (e) {
- return {
- border: '1px solid red'
- }
+ console.error('Invalid shadow', e)
+ this.invalid = true
}
}
},
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
@@ -5,9 +5,11 @@
>
<ComponentPreview
v-if="!noPreview"
+ :invalid="invalid"
class="shadow-preview"
:shadow-control="true"
:shadow="selected"
+ :preview-style="style"
:disabled="disabled || !present"
@update:shadow="({ axis, value }) => updateProperty(axis, value)"
/>
@@ -165,7 +167,7 @@
:model-value="selected?.color"
:disabled="disabled || !present"
:label="$t('settings.style.common.color')"
- :fallback="getFallback"
+ :fallback="getColorFallback"
:show-optional-tickbox="false"
name="shadow"
@update:modelValue="e => updateProperty('color', e)"
diff --git a/src/i18n/en.json b/src/i18n/en.json
@@ -793,8 +793,10 @@
"text_color": "Text color",
"icon_color": "Icon color",
"link_color": "Link color",
+ "border_color": "Border color",
"include_in_rule": "Add to rule",
"test_string": "TEST",
+ "invalid": "Invalid",
"refresh_preview": "Refresh preview",
"apply_preview": "Apply",
"text_auto": {
diff --git a/src/services/theme_data/iss_deserializer.js b/src/services/theme_data/iss_deserializer.js
@@ -28,7 +28,7 @@ export const deserializeShadow = string => {
if (string.startsWith('$') || string.startsWith('--')) {
return string
} else {
- throw new Error(`Invalid shadow definition: ${string}`)
+ throw new Error(`Invalid shadow definition: '${string}'`)
}
} else {
const numeric = new Set(['x', 'y', 'blur', 'spread', 'alpha'])
diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js
@@ -37,7 +37,7 @@ const components = {
ChatMessage: null
}
-const findShadow = (shadows, { dynamicVars, staticVars }) => {
+export const findShadow = (shadows, { dynamicVars, staticVars }) => {
return (shadows || []).map(shadow => {
let targetShadow
if (typeof shadow === 'string') {