it works!

This commit is contained in:
Henry Jameson 2024-09-29 03:20:14 +03:00
parent 2a98ea6ddc
commit 9753db1c67
4 changed files with 152 additions and 14 deletions

View file

@ -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,

View file

@ -11,6 +11,10 @@
line-height: 2;
}
&.suboption {
margin-left: 1em;
}
.opt {
margin: 0.5em;
}

View file

@ -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')"

View file

@ -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",