proper fallbacks and contrast ratio for component style editor
This commit is contained in:
parent
7e4fe93c7f
commit
030a2127ee
|
@ -11,7 +11,7 @@
|
||||||
{{ label }}
|
{{ label }}
|
||||||
</label>
|
</label>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
v-if="typeof fallback !== 'undefined' && showOptionalTickbox"
|
v-if="typeof fallback !== 'undefined' && showOptionalCheckbox && !hideOptionalCheckbox"
|
||||||
:model-value="present"
|
:model-value="present"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
class="opt"
|
class="opt"
|
||||||
|
@ -112,10 +112,16 @@ export default {
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
// Show "optional" tickbox, for when value might become mandatory
|
// Show "optional" tickbox, for when value might become mandatory
|
||||||
showOptionalTickbox: {
|
showOptionalCheckbox: {
|
||||||
required: false,
|
required: false,
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
// Force "optional" tickbox to hide
|
||||||
|
hideOptionalCheckbox: {
|
||||||
|
required: false,
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['update:modelValue'],
|
emits: ['update:modelValue'],
|
||||||
|
|
|
@ -3,39 +3,44 @@
|
||||||
v-if="contrast"
|
v-if="contrast"
|
||||||
class="contrast-ratio"
|
class="contrast-ratio"
|
||||||
>
|
>
|
||||||
<span
|
<span v-if="showRatio">
|
||||||
:title="hint"
|
{{ contrast.text }}
|
||||||
|
</span>
|
||||||
|
<Tooltip
|
||||||
|
:text="hint"
|
||||||
class="rating"
|
class="rating"
|
||||||
>
|
>
|
||||||
<span v-if="contrast.aaa">
|
<span v-if="contrast.aaa">
|
||||||
<FAIcon icon="thumbs-up" />
|
<FAIcon icon="thumbs-up" :size="showRatio ? 'lg' : ''" />
|
||||||
</span>
|
</span>
|
||||||
<span v-if="!contrast.aaa && contrast.aa">
|
<span v-if="!contrast.aaa && contrast.aa">
|
||||||
<FAIcon icon="adjust" />
|
<FAIcon icon="adjust" :size="showRatio ? 'lg' : ''" />
|
||||||
</span>
|
</span>
|
||||||
<span v-if="!contrast.aaa && !contrast.aa">
|
<span v-if="!contrast.aaa && !contrast.aa">
|
||||||
<FAIcon icon="exclamation-triangle" />
|
<FAIcon icon="exclamation-triangle" :size="showRatio ? 'lg' : ''" />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</Tooltip>
|
||||||
<span
|
<Tooltip
|
||||||
v-if="contrast && large"
|
v-if="contrast && large"
|
||||||
|
:text="hint_18pt"
|
||||||
class="rating"
|
class="rating"
|
||||||
:title="hint_18pt"
|
|
||||||
>
|
>
|
||||||
<span v-if="contrast.laaa">
|
<span v-if="contrast.laaa">
|
||||||
<FAIcon icon="thumbs-up" />
|
<FAIcon icon="thumbs-up" :size="showRatio ? 'large' : ''" />
|
||||||
</span>
|
</span>
|
||||||
<span v-if="!contrast.laaa && contrast.laa">
|
<span v-if="!contrast.laaa && contrast.laa">
|
||||||
<FAIcon icon="adjust" />
|
<FAIcon icon="adjust" :size="showRatio ? 'lg' : ''" />
|
||||||
</span>
|
</span>
|
||||||
<span v-if="!contrast.laaa && !contrast.laa">
|
<span v-if="!contrast.laaa && !contrast.laa">
|
||||||
<FAIcon icon="exclamation-triangle" />
|
<FAIcon icon="exclamation-triangle" :size="showRatio ? 'lg' : ''" />
|
||||||
</span>
|
|
||||||
</span>
|
</span>
|
||||||
|
</Tooltip>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Tooltip from 'src/components/tooltip/tooltip.vue'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faAdjust,
|
faAdjust,
|
||||||
|
@ -62,8 +67,16 @@ export default {
|
||||||
required: false,
|
required: false,
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
|
},
|
||||||
|
showRatio: {
|
||||||
|
required: false,
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
components: {
|
||||||
|
Tooltip
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
hint () {
|
hint () {
|
||||||
const levelVal = this.contrast.aaa ? 'aaa' : (this.contrast.aa ? 'aa' : 'bad')
|
const levelVal = this.contrast.aaa ? 'aaa' : (this.contrast.aa ? 'aa' : 'bad')
|
||||||
|
@ -87,8 +100,7 @@ export default {
|
||||||
.contrast-ratio {
|
.contrast-ratio {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
margin-top: -4px;
|
align-items: baseline;
|
||||||
margin-bottom: 5px;
|
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
|
@ -96,7 +108,6 @@ export default {
|
||||||
|
|
||||||
.rating {
|
.rating {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-align: center;
|
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -340,9 +340,7 @@ export default {
|
||||||
exports.editedBorderColor = getEditedElement('Border', 'textColor')
|
exports.editedBorderColor = getEditedElement('Border', 'textColor')
|
||||||
exports.isBorderColorPresent = isElementPresent('Border', 'textColor', '#909090')
|
exports.isBorderColorPresent = isElementPresent('Border', 'textColor', '#909090')
|
||||||
|
|
||||||
// TODO this is VERY primitive right now, need to make it
|
const getContrast = (bg, text) => {
|
||||||
// support variables, fallbacks etc.
|
|
||||||
exports.getContrast = (bg, text) => {
|
|
||||||
try {
|
try {
|
||||||
const bgRgb = hex2rgb(bg)
|
const bgRgb = hex2rgb(bg)
|
||||||
const textRgb = hex2rgb(text)
|
const textRgb = hex2rgb(text)
|
||||||
|
@ -464,6 +462,24 @@ export default {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const applicablePreviewRules = computed(() => {
|
||||||
|
return previewRules.filter(rule => {
|
||||||
|
const filterable = rule.parent ? rule.parent : rule
|
||||||
|
const variantMatches = filterable.variant === selectedVariant.value
|
||||||
|
const stateMatches = filterable.state.filter(x => x !== 'normal').every(x => selectedState.has(x))
|
||||||
|
return variantMatches && stateMatches
|
||||||
|
})
|
||||||
|
})
|
||||||
|
const previewColors = computed(() => ({
|
||||||
|
text: applicablePreviewRules.value.find(r => r.component === 'Text').virtualDirectives['--text'],
|
||||||
|
link: applicablePreviewRules.value.find(r => r.component === 'Link').virtualDirectives['--link'],
|
||||||
|
border: applicablePreviewRules.value.find(r => r.component === 'Border').virtualDirectives['--border'],
|
||||||
|
icon: applicablePreviewRules.value.find(r => r.component === 'Icon').virtualDirectives['--icon'],
|
||||||
|
background: applicablePreviewRules.value.find(r => r.parent == null).dynamicVars.stacked
|
||||||
|
}))
|
||||||
|
exports.previewColors = previewColors
|
||||||
|
|
||||||
const editorFriendlyToOriginal = computed(() => {
|
const editorFriendlyToOriginal = computed(() => {
|
||||||
const resultRules = []
|
const resultRules = []
|
||||||
|
|
||||||
|
@ -678,6 +694,14 @@ export default {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.contrast = computed(() => {
|
||||||
|
console.log('APR', applicablePreviewRules.value)
|
||||||
|
return getContrast(
|
||||||
|
exports.computeColor(previewColors.value.background),
|
||||||
|
exports.computeColor(previewColors.value.text)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
const overallPreviewRules = ref()
|
const overallPreviewRules = ref()
|
||||||
exports.overallPreviewRules = overallPreviewRules
|
exports.overallPreviewRules = overallPreviewRules
|
||||||
exports.updateOverallPreview = () => {
|
exports.updateOverallPreview = () => {
|
||||||
|
|
|
@ -166,27 +166,21 @@
|
||||||
>
|
>
|
||||||
<ColorInput
|
<ColorInput
|
||||||
v-model="editedBackgroundColor"
|
v-model="editedBackgroundColor"
|
||||||
:fallback="computeColor(editedBackgroundColor)"
|
:fallback="computeColor(editedBackgroundColor) ?? previewColors.background"
|
||||||
:disabled="!isBackgroundColorPresent"
|
:disabled="!isBackgroundColorPresent"
|
||||||
:label="$t('settings.style.themes3.editor.background')"
|
:label="$t('settings.style.themes3.editor.background')"
|
||||||
|
:hide-optional-checkbox="true"
|
||||||
/>
|
/>
|
||||||
<Tooltip :text="$t('settings.style.themes3.editor.include_in_rule')">
|
<Tooltip :text="$t('settings.style.themes3.editor.include_in_rule')">
|
||||||
<Checkbox v-model="isBackgroundColorPresent" />
|
<Checkbox v-model="isBackgroundColorPresent" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<OpacityInput
|
|
||||||
v-model="editedOpacity"
|
|
||||||
:disabled="!isOpacityPresent"
|
|
||||||
:label="$t('settings.style.themes3.editor.opacity')"
|
|
||||||
/>
|
|
||||||
<Tooltip :text="$t('settings.style.themes3.editor.include_in_rule')">
|
|
||||||
<Checkbox v-model="isOpacityPresent" />
|
|
||||||
</Tooltip>
|
|
||||||
<ColorInput
|
<ColorInput
|
||||||
v-if="componentHas('Text')"
|
v-if="componentHas('Text')"
|
||||||
v-model="editedTextColor"
|
v-model="editedTextColor"
|
||||||
:fallback="computeColor(editedTextColor)"
|
:fallback="computeColor(editedTextColor) ?? previewColors.text"
|
||||||
:label="$t('settings.style.themes3.editor.text_color')"
|
:label="$t('settings.style.themes3.editor.text_color')"
|
||||||
:disabled="!isTextColorPresent"
|
:disabled="!isTextColorPresent"
|
||||||
|
:hide-optional-checkbox="true"
|
||||||
/>
|
/>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
v-if="componentHas('Text')"
|
v-if="componentHas('Text')"
|
||||||
|
@ -194,7 +188,10 @@
|
||||||
>
|
>
|
||||||
<Checkbox v-model="isTextColorPresent" />
|
<Checkbox v-model="isTextColorPresent" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<div class="style-control suboption">
|
<div
|
||||||
|
v-if="componentHas('Text')"
|
||||||
|
class="style-control suboption"
|
||||||
|
>
|
||||||
<label
|
<label
|
||||||
for="textAuto"
|
for="textAuto"
|
||||||
class="label"
|
class="label"
|
||||||
|
@ -224,18 +221,27 @@
|
||||||
>
|
>
|
||||||
<Checkbox v-model="isTextAutoPresent" />
|
<Checkbox v-model="isTextAutoPresent" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<div>
|
<div
|
||||||
<ContrastRatio :contrast="getContrast(editedBackgroundColor, editedTextColor)" />
|
class="style-control suboption"
|
||||||
|
v-if="componentHas('Text')"
|
||||||
|
>
|
||||||
|
<label class="label">
|
||||||
|
{{$t('settings.style.themes3.editor.contrast') }}
|
||||||
|
</label>
|
||||||
|
<ContrastRatio
|
||||||
|
:show-ratio="true"
|
||||||
|
:contrast="contrast"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div v-if="componentHas('Text')">
|
||||||
<!-- spacer for missing checkbox -->
|
|
||||||
</div>
|
</div>
|
||||||
<ColorInput
|
<ColorInput
|
||||||
v-if="componentHas('Link')"
|
v-if="componentHas('Link')"
|
||||||
v-model="editedLinkColor"
|
v-model="editedLinkColor"
|
||||||
:fallback="computeColor(editedLinkColor)"
|
:fallback="computeColor(editedLinkColor) ?? previewColors.link"
|
||||||
:label="$t('settings.style.themes3.editor.link_color')"
|
:label="$t('settings.style.themes3.editor.link_color')"
|
||||||
:disabled="!isLinkColorPresent"
|
:disabled="!isLinkColorPresent"
|
||||||
|
:hide-optional-checkbox="true"
|
||||||
/>
|
/>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
v-if="componentHas('Link')"
|
v-if="componentHas('Link')"
|
||||||
|
@ -246,9 +252,10 @@
|
||||||
<ColorInput
|
<ColorInput
|
||||||
v-if="componentHas('Icon')"
|
v-if="componentHas('Icon')"
|
||||||
v-model="editedIconColor"
|
v-model="editedIconColor"
|
||||||
:fallback="computeColor(editedIconColor)"
|
:fallback="computeColor(editedIconColor) ?? previewColors.icon"
|
||||||
:label="$t('settings.style.themes3.editor.icon_color')"
|
:label="$t('settings.style.themes3.editor.icon_color')"
|
||||||
:disabled="!isIconColorPresent"
|
:disabled="!isIconColorPresent"
|
||||||
|
:hide-optional-checkbox="true"
|
||||||
/>
|
/>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
v-if="componentHas('Icon')"
|
v-if="componentHas('Icon')"
|
||||||
|
@ -259,9 +266,10 @@
|
||||||
<ColorInput
|
<ColorInput
|
||||||
v-if="componentHas('Border')"
|
v-if="componentHas('Border')"
|
||||||
v-model="editedBorderColor"
|
v-model="editedBorderColor"
|
||||||
:fallback="computeColor(editedBorderColor)"
|
:fallback="computeColor(editedBorderColor) ?? previewColors.border"
|
||||||
:label="$t('settings.style.themes3.editor.Border_color')"
|
:label="$t('settings.style.themes3.editor.border_color')"
|
||||||
:disabled="!isBorderColorPresent"
|
:disabled="!isBorderColorPresent"
|
||||||
|
:hide-optional-checkbox="true"
|
||||||
/>
|
/>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
v-if="componentHas('Border')"
|
v-if="componentHas('Border')"
|
||||||
|
@ -269,6 +277,14 @@
|
||||||
>
|
>
|
||||||
<Checkbox v-model="isBorderColorPresent" />
|
<Checkbox v-model="isBorderColorPresent" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<OpacityInput
|
||||||
|
v-model="editedOpacity"
|
||||||
|
:disabled="!isOpacityPresent"
|
||||||
|
:label="$t('settings.style.themes3.editor.opacity')"
|
||||||
|
/>
|
||||||
|
<Tooltip :text="$t('settings.style.themes3.editor.include_in_rule')">
|
||||||
|
<Checkbox v-model="isOpacityPresent" />
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
key="shadow"
|
key="shadow"
|
||||||
|
@ -418,6 +434,7 @@
|
||||||
v-model="draftVirtualDirective"
|
v-model="draftVirtualDirective"
|
||||||
:fallback="computeColor(draftVirtualDirective)"
|
:fallback="computeColor(draftVirtualDirective)"
|
||||||
:label="$t('settings.style.themes3.editor.variables.virtual_color')"
|
:label="$t('settings.style.themes3.editor.variables.virtual_color')"
|
||||||
|
:hide-optional-checkbox="true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -187,14 +187,14 @@
|
||||||
name="accentColor"
|
name="accentColor"
|
||||||
:fallback="previewTheme.colors?.link"
|
:fallback="previewTheme.colors?.link"
|
||||||
:label="$t('settings.accent')"
|
:label="$t('settings.accent')"
|
||||||
:show-optional-tickbox="typeof linkColorLocal !== 'undefined'"
|
:show-optional-checkbox="typeof linkColorLocal !== 'undefined'"
|
||||||
/>
|
/>
|
||||||
<ColorInput
|
<ColorInput
|
||||||
v-model="linkColorLocal"
|
v-model="linkColorLocal"
|
||||||
name="linkColor"
|
name="linkColor"
|
||||||
:fallback="previewTheme.colors?.accent"
|
:fallback="previewTheme.colors?.accent"
|
||||||
:label="$t('settings.links')"
|
:label="$t('settings.links')"
|
||||||
:show-optional-tickbox="typeof accentColorLocal !== 'undefined'"
|
:show-optional-checkbox="typeof accentColorLocal !== 'undefined'"
|
||||||
/>
|
/>
|
||||||
<ContrastRatio :contrast="previewContrast.bgLink" />
|
<ContrastRatio :contrast="previewContrast.bgLink" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -168,7 +168,7 @@
|
||||||
:disabled="disabled || !present"
|
:disabled="disabled || !present"
|
||||||
:label="$t('settings.style.common.color')"
|
:label="$t('settings.style.common.color')"
|
||||||
:fallback="getColorFallback"
|
:fallback="getColorFallback"
|
||||||
:show-optional-tickbox="false"
|
:show-optional-checkbox="false"
|
||||||
name="shadow"
|
name="shadow"
|
||||||
@update:modelValue="e => updateProperty('color', e)"
|
@update:modelValue="e => updateProperty('color', e)"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -793,6 +793,7 @@
|
||||||
"text_color": "Text color",
|
"text_color": "Text color",
|
||||||
"icon_color": "Icon color",
|
"icon_color": "Icon color",
|
||||||
"link_color": "Link color",
|
"link_color": "Link color",
|
||||||
|
"contrast": "Text contrast",
|
||||||
"border_color": "Border color",
|
"border_color": "Border color",
|
||||||
"include_in_rule": "Add to rule",
|
"include_in_rule": "Add to rule",
|
||||||
"test_string": "TEST",
|
"test_string": "TEST",
|
||||||
|
|
Loading…
Reference in a new issue