it works!
This commit is contained in:
parent
2a98ea6ddc
commit
9753db1c67
|
@ -10,9 +10,15 @@ 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 Popover from 'src/components/popover/popover.vue'
|
||||
import ContrastRatio from 'src/components/contrast_ratio/contrast_ratio.vue'
|
||||
|
||||
import { init } from 'src/services/theme_data/theme_data_3.service.js'
|
||||
import { getCssRules } from 'src/services/theme_data/css_utils.js'
|
||||
import {
|
||||
// rgb2hex,
|
||||
hex2rgb,
|
||||
getContrastRatio
|
||||
} from 'src/services/color_convert/color_convert.js'
|
||||
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import { faFloppyDisk, faFolderOpen, faFile } from '@fortawesome/free-solid-svg-icons'
|
||||
|
@ -40,7 +46,8 @@ export default {
|
|||
TabSwitcher,
|
||||
ShadowControl,
|
||||
ColorInput,
|
||||
OpacityInput
|
||||
OpacityInput,
|
||||
ContrastRatio
|
||||
},
|
||||
setup () {
|
||||
// Meta stuff
|
||||
|
@ -153,7 +160,10 @@ export default {
|
|||
return scoped.join('\n')
|
||||
})
|
||||
|
||||
// Rules stuff aka meat and potatoes
|
||||
// ### Rules stuff aka meat and potatoes
|
||||
// The native structure of separate rules and the child -> parent
|
||||
// relation isn't very convenient for editor, we replace the array
|
||||
// and child -> parent structure with map and parent -> child structure
|
||||
const editorFriendlyFallbackStructure = computed(() => {
|
||||
const root = {}
|
||||
|
||||
|
@ -251,27 +261,66 @@ export default {
|
|||
|
||||
const editedBackgroundColor = getEditedElement(null, 'background')
|
||||
const editedOpacity = getEditedElement(null, 'opacity')
|
||||
const editedTextColor = getEditedElement('Text', 'color')
|
||||
const editedLinkColor = getEditedElement('Link', 'color')
|
||||
const editedIconColor = getEditedElement('Icon', 'color')
|
||||
const editedTextColor = getEditedElement('Text', 'textColor')
|
||||
const editedTextAuto = getEditedElement('Text', 'textAuto')
|
||||
const editedLinkColor = getEditedElement('Link', 'textColor')
|
||||
const editedIconColor = getEditedElement('Icon', 'textColor')
|
||||
const editedShadow = getEditedElement(null, 'shadow')
|
||||
|
||||
const isBackgroundColorPresent = isElementPresent(null, 'background', '#FFFFFF')
|
||||
const isOpacityPresent = isElementPresent(null, 'opacity', 1)
|
||||
const isTextColorPresent = isElementPresent('Text', 'color', '#000000')
|
||||
const isLinkColorPresent = isElementPresent('Link', 'color', '#000080')
|
||||
const isIconColorPresent = isElementPresent('Icon', 'color', '#909090')
|
||||
const isTextColorPresent = isElementPresent('Text', 'textColor', '#000000')
|
||||
const isTextAutoPresent = isElementPresent('Text', 'textAuto', '#000000')
|
||||
const isLinkColorPresent = isElementPresent('Link', 'textColor', '#000080')
|
||||
const isIconColorPresent = isElementPresent('Icon', 'textColor', '#909090')
|
||||
const isShadowPresent = isElementPresent(null, 'shadow', [])
|
||||
|
||||
const updateSelectedComponent = () => {
|
||||
selectedVariant.value = 'normal'
|
||||
selectedState.clear()
|
||||
const editorFriendlyToOriginal = computed(() => {
|
||||
const resultRules = []
|
||||
|
||||
const convert = (component, data = {}, parent) => {
|
||||
const variants = Object.entries(data || {})
|
||||
|
||||
variants.forEach(([variant, variantData]) => {
|
||||
const states = Object.entries(variantData)
|
||||
|
||||
states.forEach(([jointState, stateData]) => {
|
||||
const state = jointState.split(/:/g)
|
||||
const result = {
|
||||
component,
|
||||
variant,
|
||||
state,
|
||||
directives: stateData.directives || {}
|
||||
}
|
||||
|
||||
console.log('PARENT', parent)
|
||||
if (parent) {
|
||||
result.parent = {
|
||||
component: parent
|
||||
}
|
||||
}
|
||||
|
||||
resultRules.push(result)
|
||||
|
||||
// Currently we only support single depth for simplicity's sake
|
||||
if (!parent) {
|
||||
Object.entries(stateData._children || {}).forEach(([cName, child]) => convert(cName, child, component))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
convert(selectedComponentName.value, allEditedRules[selectedComponentName.value])
|
||||
console.log(toValue(allEditedRules))
|
||||
console.log(toValue(resultRules))
|
||||
|
||||
return resultRules
|
||||
})
|
||||
|
||||
const updatePreview = () => {
|
||||
previewRules.splice(0, previewRules.length)
|
||||
previewRules.push(...init({
|
||||
inputRuleset: [{
|
||||
component: selectedComponentName.value
|
||||
}],
|
||||
inputRuleset: editorFriendlyToOriginal.value,
|
||||
initialStaticVars: {
|
||||
...palette
|
||||
},
|
||||
|
@ -282,13 +331,48 @@ export default {
|
|||
}).eager)
|
||||
}
|
||||
|
||||
const updateSelectedComponent = () => {
|
||||
selectedVariant.value = 'normal'
|
||||
selectedState.clear()
|
||||
updatePreview()
|
||||
}
|
||||
updateSelectedComponent()
|
||||
|
||||
watch(
|
||||
allEditedRules,
|
||||
updatePreview
|
||||
)
|
||||
|
||||
watch(
|
||||
selectedComponentName,
|
||||
updateSelectedComponent
|
||||
)
|
||||
|
||||
// TODO this is VERY primitive right now, need to make it
|
||||
// support variables, fallbacks etc.
|
||||
const getContrast = (bg, text) => {
|
||||
console.log('CONTRAST', bg, text)
|
||||
try {
|
||||
const bgRgb = hex2rgb(bg)
|
||||
const textRgb = hex2rgb(text)
|
||||
|
||||
const ratio = getContrastRatio(bgRgb, textRgb)
|
||||
return {
|
||||
ratio,
|
||||
text: ratio.toPrecision(3) + ':1',
|
||||
// AA level, AAA level
|
||||
aa: ratio >= 4.5,
|
||||
aaa: ratio >= 7,
|
||||
// same but for 18pt+ texts
|
||||
laa: ratio >= 3,
|
||||
laaa: ratio >= 4.5
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Failure computing contrast', e)
|
||||
return { error: e }
|
||||
}
|
||||
}
|
||||
|
||||
const isShadowTabOpen = ref(false)
|
||||
const onTabSwitch = (tab) => {
|
||||
isShadowTabOpen.value = tab === 'shadow'
|
||||
|
@ -318,12 +402,15 @@ export default {
|
|||
editedBackgroundColor,
|
||||
editedOpacity,
|
||||
editedTextColor,
|
||||
editedTextAuto,
|
||||
editedLinkColor,
|
||||
editedIconColor,
|
||||
editedShadow,
|
||||
getContrast,
|
||||
isBackgroundColorPresent,
|
||||
isOpacityPresent,
|
||||
isTextColorPresent,
|
||||
isTextAutoPresent,
|
||||
isLinkColorPresent,
|
||||
isIconColorPresent,
|
||||
isShadowPresent,
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
line-height: 2;
|
||||
}
|
||||
|
||||
&.suboption {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.opt {
|
||||
margin: 0.5em;
|
||||
}
|
||||
|
|
|
@ -183,6 +183,47 @@
|
|||
{{ $t('settings.style.themes3.editor.include_in_rule') }}
|
||||
</template>
|
||||
</Popover>
|
||||
<div class="style-control suboption">
|
||||
<label
|
||||
for="textAuto"
|
||||
class="label"
|
||||
:class="{ faint: disabled || !present }"
|
||||
>
|
||||
{{ $t('settings.style.themes3.editor.text_auto.label') }}
|
||||
</label>
|
||||
<Select
|
||||
id="textAuto"
|
||||
v-model="editedTextAuto"
|
||||
:disabled="!isTextAutoPresent"
|
||||
>
|
||||
<option value="no-preserve">
|
||||
{{ $t('settings.style.themes3.editor.text_auto.no-preserve') }}
|
||||
</option>
|
||||
<option value="no-auto">
|
||||
{{ $t('settings.style.themes3.editor.text_auto.no-auto') }}
|
||||
</option>
|
||||
<option value="preserve">
|
||||
{{ $t('settings.style.themes3.editor.text_auto.preserve') }}
|
||||
</option>
|
||||
</Select>
|
||||
</div>
|
||||
<Popover
|
||||
trigger="hover"
|
||||
v-if="componentHas('Text')"
|
||||
>
|
||||
<template #trigger>
|
||||
<Checkbox v-model="isTextAutoPresent" />
|
||||
</template>
|
||||
<template #content>
|
||||
{{ $t('settings.style.themes3.editor.include_in_rule') }}
|
||||
</template>
|
||||
</Popover>
|
||||
<div>
|
||||
<ContrastRatio :contrast="getContrast(editedBackgroundColor, editedTextColor)" />
|
||||
</div>
|
||||
<div>
|
||||
<!-- spacer for missing checkbox -->
|
||||
</div>
|
||||
<ColorInput
|
||||
v-model="editedLinkColor"
|
||||
:label="$t('settings.style.themes3.editor.link_color')"
|
||||
|
|
|
@ -772,6 +772,12 @@
|
|||
"icon_color": "Icon color",
|
||||
"link_color": "Link color",
|
||||
"include_in_rule": "Add to rule",
|
||||
"text_auto": {
|
||||
"label": "Auto-contrast",
|
||||
"no-preserve": "Black or White",
|
||||
"preserve": "Keep color",
|
||||
"no-auto": "Disabled"
|
||||
},
|
||||
"components": {
|
||||
"normal": {
|
||||
"state": "Normal",
|
||||
|
|
Loading…
Reference in a new issue