From 34aa9136dba6b0e1d54f657e24ea4ae77f6c406e Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 19 Feb 2024 18:48:49 +0200 Subject: refactored most of the CSS stuff into separate file, refactored color functions and added shadow functions, replaced JS functions in button with PISS functions --- src/services/theme_data/css_utils.js | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/services/theme_data/css_utils.js (limited to 'src/services/theme_data/css_utils.js') diff --git a/src/services/theme_data/css_utils.js b/src/services/theme_data/css_utils.js new file mode 100644 index 00000000..8b061f8f --- /dev/null +++ b/src/services/theme_data/css_utils.js @@ -0,0 +1,43 @@ +import { convert } from 'chromatism' + +import { rgba2css } from '../color_convert/color_convert.js' + +export const getCssColorString = (color, alpha) => rgba2css({ ...convert(color).rgb, a: alpha }) + +export const getCssShadow = (input, usesDropShadow) => { + if (input.length === 0) { + return 'none' + } + + return input + .filter(_ => usesDropShadow ? _.inset : _) + .map((shad) => [ + shad.x, + shad.y, + shad.blur, + shad.spread + ].map(_ => _ + 'px ').concat([ + getCssColorString(shad.color, shad.alpha), + shad.inset ? 'inset' : '' + ]).join(' ')).join(', ') +} + +export const getCssShadowFilter = (input) => { + if (input.length === 0) { + return 'none' + } + + return input + // drop-shadow doesn't support inset or spread + .filter((shad) => !shad.inset && Number(shad.spread) === 0) + .map((shad) => [ + shad.x, + shad.y, + // drop-shadow's blur is twice as strong compared to box-shadow + shad.blur / 2 + ].map(_ => _ + 'px').concat([ + getCssColorString(shad.color, shad.alpha) + ]).join(' ')) + .map(_ => `drop-shadow(${_})`) + .join(' ') +} -- cgit v1.2.3-70-g09d2 From 4a10417ed47cdfe08b2ff4939212116dba3e965f Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 19 Feb 2024 19:59:38 +0200 Subject: initial work on dynamic slots + move remaining css stuff into separate file --- src/components/input.style.js | 12 +--- src/services/style_setter/style_setter.js | 3 +- src/services/theme_data/css_utils.js | 72 ++++++++++++++++++++ src/services/theme_data/theme_data_3.service.js | 88 +++---------------------- 4 files changed, 85 insertions(+), 90 deletions(-) (limited to 'src/services/theme_data/css_utils.js') diff --git a/src/components/input.style.js b/src/components/input.style.js index 7db50b66..985d5412 100644 --- a/src/components/input.style.js +++ b/src/components/input.style.js @@ -1,14 +1,4 @@ -const border = (top, shadow) => ({ - x: 0, - y: top ? 1 : -1, - blur: 0, - spread: 0, - color: shadow ? '#000000' : '#FFFFFF', - alpha: 0.2, - inset: true -}) - -const inputInsetFakeBorders = [border(true, true), border(false, false)] +const inputInsetFakeBorders = ['$borderSide(#FFFFFF, bottom, 0.2)', '$borderSide(#000000, top, 0.2)'] const hoverGlow = { x: 0, diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index 3c2a2763..95d1b6c4 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -1,7 +1,8 @@ import { convert } from 'chromatism' import { rgb2hex, hex2rgb, rgba2css, getCssColor, relativeLuminance } from '../color_convert/color_convert.js' import { getColors, computeDynamicColor, getOpacitySlot } from '../theme_data/theme_data.service.js' -import { init, getCssRules } from '../theme_data/theme_data_3.service.js' +import { init } from '../theme_data/theme_data_3.service.js' +import { getCssRules } from '../theme_data/css_utils.js' import { sampleRules } from 'src/services/theme_data/pleromafe.t3.js' diff --git a/src/services/theme_data/css_utils.js b/src/services/theme_data/css_utils.js index 8b061f8f..8395f6a7 100644 --- a/src/services/theme_data/css_utils.js +++ b/src/services/theme_data/css_utils.js @@ -41,3 +41,75 @@ export const getCssShadowFilter = (input) => { .map(_ => `drop-shadow(${_})`) .join(' ') } + +export const getCssRules = (rules) => rules.map(rule => { + let selector = rule.selector + if (!selector) { + selector = 'body' + } + const header = selector + ' {' + const footer = '}' + + const virtualDirectives = Object.entries(rule.virtualDirectives || {}).map(([k, v]) => { + return ' ' + k + ': ' + v + }).join(';\n') + + let directives + if (rule.component !== 'Root') { + directives = Object.entries(rule.directives).map(([k, v]) => { + switch (k) { + case 'roundness': { + return ' ' + [ + '--roundness: ' + v + 'px' + ].join(';\n ') + } + case 'shadow': { + return ' ' + [ + '--shadow: ' + getCssShadow(rule.dynamicVars.shadow), + '--shadowFilter: ' + getCssShadowFilter(rule.dynamicVars.shadow), + '--shadowInset: ' + getCssShadow(rule.dynamicVars.shadow, true) + ].join(';\n ') + } + case 'background': { + if (v === 'transparent') { + return [ + rule.directives.backgroundNoCssColor !== 'yes' ? ('background-color: ' + v) : '', + ' --background: ' + v + ].filter(x => x).join(';\n') + } + const color = getCssColorString(rule.dynamicVars.background, rule.directives.opacity) + return [ + rule.directives.backgroundNoCssColor !== 'yes' ? ('background-color: ' + color) : '', + ' --background: ' + color + ].filter(x => x).join(';\n') + } + case 'textColor': { + if (rule.directives.textNoCssColor === 'yes') { return '' } + return 'color: ' + v + } + default: + if (k.startsWith('--')) { + const [type] = v.split('|').map(x => x.trim()) // woah, Extreme! + switch (type) { + case 'color': + return k + ': ' + rgba2css(rule.dynamicVars[k]) + default: + return '' + } + } + return '' + } + }).filter(x => x).map(x => ' ' + x).join(';\n') + } else { + directives = {} + } + + return [ + header, + directives + ';', + (!rule.virtual && rule.directives.textNoCssColor !== 'yes') ? ' color: var(--text);' : '', + '', + virtualDirectives, + footer + ].join('\n') +}).filter(x => x) diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js index 88bff2aa..af40758c 100644 --- a/src/services/theme_data/theme_data_3.service.js +++ b/src/services/theme_data/theme_data_3.service.js @@ -13,12 +13,6 @@ import { process } from './theme3_slot_functions.js' -import { - getCssShadow, - getCssShadowFilter, - getCssColorString -} from './css_utils.js' - const DEBUG = false // Ensuring the order of components @@ -105,78 +99,6 @@ const getTextColorAlpha = (directives, intendedTextColor, dynamicVars, staticVar } } -export const getCssRules = (rules, staticVars) => rules.map(rule => { - let selector = rule.selector - if (!selector) { - selector = 'body' - } - const header = selector + ' {' - const footer = '}' - - const virtualDirectives = Object.entries(rule.virtualDirectives || {}).map(([k, v]) => { - return ' ' + k + ': ' + v - }).join(';\n') - - let directives - if (rule.component !== 'Root') { - directives = Object.entries(rule.directives).map(([k, v]) => { - switch (k) { - case 'roundness': { - return ' ' + [ - '--roundness: ' + v + 'px' - ].join(';\n ') - } - case 'shadow': { - return ' ' + [ - '--shadow: ' + getCssShadow(rule.dynamicVars.shadow), - '--shadowFilter: ' + getCssShadowFilter(rule.dynamicVars.shadow), - '--shadowInset: ' + getCssShadow(rule.dynamicVars.shadow, true) - ].join(';\n ') - } - case 'background': { - if (v === 'transparent') { - return [ - rule.directives.backgroundNoCssColor !== 'yes' ? ('background-color: ' + v) : '', - ' --background: ' + v - ].filter(x => x).join(';\n') - } - const color = getCssColorString(rule.dynamicVars.background, rule.directives.opacity) - return [ - rule.directives.backgroundNoCssColor !== 'yes' ? ('background-color: ' + color) : '', - ' --background: ' + color - ].filter(x => x).join(';\n') - } - case 'textColor': { - if (rule.directives.textNoCssColor === 'yes') { return '' } - return 'color: ' + v - } - default: - if (k.startsWith('--')) { - const [type, value] = v.split('|').map(x => x.trim()) // woah, Extreme! - switch (type) { - case 'color': - return k + ': ' + rgba2css(findColor(value, rule.dynamicVars, staticVars)) - default: - return '' - } - } - return '' - } - }).filter(x => x).map(x => ' ' + x).join(';\n') - } else { - directives = {} - } - - return [ - header, - directives + ';', - (!rule.virtual && rule.directives.textNoCssColor !== 'yes') ? ' color: var(--text);' : '', - '', - virtualDirectives, - footer - ].join('\n') -}).filter(x => x) - // Loading all style.js[on] files dynamically const componentsContext = require.context('src', true, /\.style.js(on)?$/) componentsContext.keys().forEach(key => { @@ -587,6 +509,16 @@ export const init = (extraRuleset, palette) => { dynamicVars.stacked = lowerLevelStackedBackground dynamicVars.background = computed[selector].background + const dynamicSlots = Object.entries(computedDirectives).filter(([k, v]) => k.startsWith('--')) + + dynamicSlots.forEach(([k, v]) => { + const [type, value] = v.split('|').map(x => x.trim()) // woah, Extreme! + switch (type) { + case 'color': + dynamicVars[k] = findColor(value, dynamicVars, palette) + } + }) + addRule({ dynamicVars, selector: cssSelector, -- cgit v1.2.3-70-g09d2 From 8a21594dbc5075b92d245f4c83530c7dae71c62a Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 21 Feb 2024 22:18:56 +0200 Subject: shadow slots work + minor fixes --- src/boot/after_store.js | 1 + src/components/button.style.js | 43 ++++++-------- src/components/input.style.js | 12 ++-- .../settings_modal/tabs/theme_tab/theme_tab.js | 20 +++---- src/components/shadow_control/shadow_control.js | 2 +- src/services/style_setter/style_setter.js | 26 ++++++--- src/services/theme_data/css_utils.js | 20 +++++++ src/services/theme_data/theme2_to_theme3.js | 29 ++++++++-- src/services/theme_data/theme3_slot_functions.js | 22 ++++---- src/services/theme_data/theme_data_3.service.js | 66 ++++++++++++++-------- 10 files changed, 153 insertions(+), 88 deletions(-) (limited to 'src/services/theme_data/css_utils.js') diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 84fea954..49a8130c 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -359,6 +359,7 @@ const afterStoreSetup = async ({ store, i18n }) => { const { theme } = store.state.instance const customThemePresent = customThemeSource || customTheme + console.log({ ...customThemeSource }, { ...customTheme }) if (customThemePresent) { if (customThemeSource && customThemeSource.themeEngineVersion === CURRENT_VERSION) { applyTheme(customThemeSource) diff --git a/src/components/button.style.js b/src/components/button.style.js index 1404061c..4910a5ac 100644 --- a/src/components/button.style.js +++ b/src/components/button.style.js @@ -1,23 +1,3 @@ -const buttonInsetFakeBorders = ['$borderSide(#FFFFFF, top, 0.2)', '$borderSide(#000000, bottom, 0.2)'] -const inputInsetFakeBorders = ['$borderSide(#FFFFFF, bottom, 0.2)', '$borderSide(#000000, top, 0.2)'] -const buttonOuterShadow = { - x: 0, - y: 0, - blur: 2, - spread: 0, - color: '#000000', - alpha: 1 -} - -const hoverGlow = { - x: 0, - y: 0, - blur: 4, - spread: 0, - color: '--text', - alpha: 1 -} - export default { name: 'Button', // Name of the component selector: '.button-default', // CSS selector/prefix @@ -49,52 +29,61 @@ export default { ], // Default rules, used as "default theme", essentially. defaultRules: [ + { + component: 'Root', + directives: { + '--defaultButtonHoverGlow': 'shadow | 0 0 4 --text', + '--defaultButtonShadow': 'shadow | 0 0 2 #000000', + '--defaultButtonBevel': 'shadow | $borderSide(#FFFFFF, top, 0.2) | $borderSide(#000000, bottom, 0.2)', + '--pressedButtonBevel': 'shadow | $borderSide(#FFFFFF, bottom, 0.2)| $borderSide(#000000, top, 0.2)' + } + }, { // component: 'Button', // no need to specify components every time unless you're specifying how other component should look // like within it directives: { background: '--fg', - shadow: [buttonOuterShadow, ...buttonInsetFakeBorders], + shadow: ['--defaultButtonShadow', '--defaultButtonBevel'], roundness: 3 } }, { state: ['hover'], directives: { - shadow: [hoverGlow, ...buttonInsetFakeBorders] + shadow: ['--defaultButtonHoverGlow', '--defaultButtonBevel'] } }, { state: ['pressed'], directives: { - shadow: [buttonOuterShadow, ...inputInsetFakeBorders] + shadow: ['--defaultButtonShadow', '--pressedButtonBevel'] } }, { state: ['hover', 'pressed'], directives: { - shadow: [hoverGlow, ...inputInsetFakeBorders] + shadow: ['--defaultButtonHoverGlow', '--pressedButtonBevel'] } }, { state: ['toggled'], directives: { background: '--inheritedBackground,-24.2', - shadow: [buttonOuterShadow, ...inputInsetFakeBorders] + shadow: ['--defaultButtonShadow', '--pressedButtonBevel'] } }, { state: ['toggled', 'hover'], directives: { background: '--inheritedBackground,-24.2', - shadow: [hoverGlow, ...inputInsetFakeBorders] + shadow: ['--defaultButtonHoverGlow', '--pressedButtonBevel'] } }, { state: ['disabled'], directives: { background: '$blend(--inheritedBackground, 0.25, --parent)', - shadow: [...buttonInsetFakeBorders] + shadow: ['--defaultButtonBevel'] } }, { diff --git a/src/components/input.style.js b/src/components/input.style.js index b1c9f3db..70c775ad 100644 --- a/src/components/input.style.js +++ b/src/components/input.style.js @@ -1,5 +1,3 @@ -const inputInsetFakeBorders = ['$borderSide(#FFFFFF, bottom, 0.2)', '$borderSide(#000000, top, 0.2)'] - const hoverGlow = { x: 0, y: 0, @@ -25,6 +23,12 @@ export default { 'Text' ], defaultRules: [ + { + component: 'Root', + directives: { + '--defaultInputBevel': 'shadow | $borderSide(#FFFFFF, bottom, 0.2)| $borderSide(#000000, top, 0.2)' + } + }, { variant: 'checkbox', directives: { @@ -42,13 +46,13 @@ export default { spread: 0, color: '#000000', alpha: 1 - }, ...inputInsetFakeBorders] + }, '--defaultInputBevel'] } }, { state: ['hover'], directives: { - shadow: [hoverGlow, ...inputInsetFakeBorders] + shadow: [hoverGlow, '--defaultInputBevel'] } } ] diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js index 58f8d44a..dd525920 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -4,15 +4,7 @@ import { getContrastRatioLayers } from 'src/services/color_convert/color_convert.js' import { - DEFAULT_SHADOWS, - generateColors, - generateShadows, - generateRadii, - generateFonts, - composePreset, - getThemes, - shadows2to3, - colors2to3 + getThemes } from 'src/services/style_setter/style_setter.js' import { newImporter, @@ -25,7 +17,15 @@ import { CURRENT_VERSION, OPACITIES, getLayers, - getOpacitySlot + getOpacitySlot, + DEFAULT_SHADOWS, + generateColors, + generateShadows, + generateRadii, + generateFonts, + composePreset, + shadows2to3, + colors2to3 } from 'src/services/theme_data/theme_data.service.js' import ColorInput from 'src/components/color_input/color_input.vue' import RangeInput from 'src/components/range_input/range_input.vue' diff --git a/src/components/shadow_control/shadow_control.js b/src/components/shadow_control/shadow_control.js index a1d1012b..f8e12dbf 100644 --- a/src/components/shadow_control/shadow_control.js +++ b/src/components/shadow_control/shadow_control.js @@ -1,7 +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 { getCssShadow } from '../../services/style_setter/style_setter.js' +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' import { diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index 1fb65e1c..1bc92584 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -6,12 +6,22 @@ import { getCssRules } from '../theme_data/css_utils.js' import { defaultState } from '../../modules/config.js' export const applyTheme = (input) => { - const t0 = performance.now() - const { rules, theme } = generatePreset(input) - console.log(rules, theme) + const { version, theme: inputTheme } = input + let extraRules + let fonts + if (version === 2) { + const t0 = performance.now() + const { rules, theme } = generatePreset(inputTheme) + fonts = rules.fonts + const t1 = performance.now() + console.log('Themes 2 initialization took ' + (t1 - t0) + 'ms') + extraRules = convertTheme2To3(theme) + } else { + console.log(input) + extraRules = convertTheme2To3(input) + } + const t1 = performance.now() - console.log('Themes 2 initialization took ' + (t1 - t0) + 'ms') - const extraRules = convertTheme2To3(theme) const themes3 = init(extraRules) const t2 = performance.now() console.log('Themes 3 initialization took ' + (t2 - t1) + 'ms') @@ -24,7 +34,7 @@ export const applyTheme = (input) => { const styleSheet = styleEl.sheet styleSheet.toString() - styleSheet.insertRule(`:root { ${rules.fonts} }`, 'index-max') + styleSheet.insertRule(`:root { ${fonts} }`, 'index-max') getCssRules(themes3.eager, themes3.staticVars).forEach(rule => { // Hack to support multiple selectors on same component if (rule.match(/::-webkit-scrollbar-button/)) { @@ -133,8 +143,8 @@ export const getPreset = (val) => { data.colors = { bg, fg, text, link, cRed, cBlue, cGreen, cOrange } } - return { theme: data, source: theme.source } + return { theme: data, source: theme.source, version: isV1 ? 1 : 2 } }) } -export const setPreset = (val) => getPreset(val).then(data => applyTheme(data.theme)) +export const setPreset = (val) => getPreset(val).then(data => applyTheme(data)) diff --git a/src/services/theme_data/css_utils.js b/src/services/theme_data/css_utils.js index 8395f6a7..412accf9 100644 --- a/src/services/theme_data/css_utils.js +++ b/src/services/theme_data/css_utils.js @@ -2,6 +2,26 @@ import { convert } from 'chromatism' import { rgba2css } from '../color_convert/color_convert.js' +export const parseCssShadow = (text) => { + const dimensions = /(\d[a-z]*\s?){2,4}/.exec(text)?.[0] + const inset = /inset/.exec(text)?.[0] + const color = text.replace(dimensions, '').replace(inset, '') + + const [x, y, blur = 0, spread = 0] = dimensions.split(/ /).filter(x => x).map(x => x.trim()) + const isInset = inset?.trim() === 'inset' + console.log(color.trim()) + const colorString = color.split(/ /).filter(x => x).map(x => x.trim())[0] + + return { + x, + y, + blur, + spread, + inset: isInset, + color: colorString + } +} + export const getCssColorString = (color, alpha) => rgba2css({ ...convert(color).rgb, a: alpha }) export const getCssShadow = (input, usesDropShadow) => { diff --git a/src/services/theme_data/theme2_to_theme3.js b/src/services/theme_data/theme2_to_theme3.js index 743bc386..b367af36 100644 --- a/src/services/theme_data/theme2_to_theme3.js +++ b/src/services/theme_data/theme2_to_theme3.js @@ -100,6 +100,8 @@ export const temporary = new Set([ export const temporaryColors = {} export const convertTheme2To3 = (data) => { + data.colors.accent = data.colors.accent || data.colors.link + data.colors.link = data.colors.link || data.colors.accent const generateRoot = () => { const directives = {} basePaletteKeys.forEach(key => { directives['--' + key] = 'color | ' + data.colors[key] }) @@ -111,7 +113,8 @@ export const convertTheme2To3 = (data) => { const convertRadii = () => { const newRules = [] - radiiKeys.forEach(key => { + Object.keys(data.radii).forEach(key => { + if (!radiiKeys.has(key) || data.radii[key] === undefined) return null const originalRadius = data.radii[key] const rule = {} @@ -150,13 +153,17 @@ export const convertTheme2To3 = (data) => { roundness: originalRadius } newRules.push(rule) + if (rule.component === 'Button') { + newRules.push({ ...rule, component: 'ScrollbarElement' }) + } }) return newRules } const convertShadows = () => { const newRules = [] - shadowsKeys.forEach(key => { + Object.keys(data.shadows).forEach(key => { + if (!shadowsKeys.has(key)) return const originalShadow = data.shadows[key] const rule = {} @@ -205,6 +212,10 @@ export const convertTheme2To3 = (data) => { if (key === 'buttonPressed') { newRules.push({ ...rule, state: ['toggled'] }) } + + if (rule.component === 'Button') { + newRules.push({ ...rule, component: 'ScrollbarElement' }) + } }) return newRules } @@ -234,10 +245,13 @@ export const convertTheme2To3 = (data) => { rule.component = 'ChatMessage' } else if (prefix === 'poll') { rule.component = 'PollGraph' + } else if (prefix === 'btn') { + rule.component = 'Button' } else { rule.component = prefix[0].toUpperCase() + prefix.slice(1).toLowerCase() } return keys.map((key) => { + if (!data.colors[key]) return null const leftoverKey = key.replace(prefix, '') const parts = (leftoverKey || 'Bg').match(/[A-Z][a-z]*/g) const last = parts.slice(-1)[0] @@ -335,12 +349,17 @@ export const convertTheme2To3 = (data) => { newRule.variant = variantArray[0].toLowerCase() } } - console.log(key, newRule) - return newRule + + if (newRule.component === 'Button') { + console.log([newRule, { ...newRule, component: 'ScrollbarElement' }]) + return [newRule, { ...newRule, component: 'ScrollbarElement' }] + } else { + return [newRule] + } }) }) - const flatExtRules = extendedRules.filter(x => x).reduce((acc, x) => [...acc, ...x], []).filter(x => x) + const flatExtRules = extendedRules.filter(x => x).reduce((acc, x) => [...acc, ...x], []).filter(x => x).reduce((acc, x) => [...acc, ...x], []) return [generateRoot(), ...convertShadows(), ...convertRadii(), ...flatExtRules] } diff --git a/src/services/theme_data/theme3_slot_functions.js b/src/services/theme_data/theme3_slot_functions.js index 2324e121..2715c827 100644 --- a/src/services/theme_data/theme3_slot_functions.js +++ b/src/services/theme_data/theme3_slot_functions.js @@ -1,7 +1,7 @@ import { convert, brightness } from 'chromatism' import { alphaBlend, relativeLuminance } from '../color_convert/color_convert.js' -export const process = (text, functions, findColor, dynamicVars, staticVars) => { +export const process = (text, functions, { findColor, findShadow }, { dynamicVars, staticVars }) => { const { funcName, argsString } = /\$(?\w+)\((?[#a-zA-Z0-9-,.'"\s]*)\)/.exec(text).groups const args = argsString.split(/,/g).map(a => a.trim()) @@ -9,27 +9,27 @@ export const process = (text, functions, findColor, dynamicVars, staticVars) => if (args.length < func.argsNeeded) { throw new Error(`$${funcName} requires at least ${func.argsNeeded} arguments, but ${args.length} were provided`) } - return func.exec(args, findColor, dynamicVars, staticVars) + return func.exec(args, { findColor, findShadow }, { dynamicVars, staticVars }) } export const colorFunctions = { alpha: { argsNeeded: 2, - exec: (args, findColor, dynamicVars, staticVars) => { + exec: (args, { findColor }, { dynamicVars, staticVars }) => { const [color, amountArg] = args - const colorArg = convert(findColor(color, dynamicVars, staticVars)).rgb + const colorArg = convert(findColor(color, { dynamicVars, staticVars })).rgb const amount = Number(amountArg) return { ...colorArg, a: amount } } }, blend: { argsNeeded: 3, - exec: (args, findColor, dynamicVars, staticVars) => { + exec: (args, { findColor }, { dynamicVars, staticVars }) => { const [backgroundArg, amountArg, foregroundArg] = args - const background = convert(findColor(backgroundArg, dynamicVars, staticVars)).rgb - const foreground = convert(findColor(foregroundArg, dynamicVars, staticVars)).rgb + const background = convert(findColor(backgroundArg, { dynamicVars, staticVars })).rgb + const foreground = convert(findColor(foregroundArg, { dynamicVars, staticVars })).rgb const amount = Number(amountArg) return alphaBlend(background, amount, foreground) @@ -37,10 +37,10 @@ export const colorFunctions = { }, mod: { argsNeeded: 2, - exec: (args, findColor, dynamicVars, staticVars) => { + exec: (args, { findColor }, { dynamicVars, staticVars }) => { const [colorArg, amountArg] = args - const color = convert(findColor(colorArg, dynamicVars, staticVars)).rgb + const color = convert(findColor(colorArg, { dynamicVars, staticVars })).rgb const amount = Number(amountArg) const effectiveBackground = dynamicVars.lowerLevelBackground @@ -54,7 +54,7 @@ export const colorFunctions = { export const shadowFunctions = { borderSide: { argsNeeded: 3, - exec: (args, findColor, dynamicVars, staticVars) => { + exec: (args, { findColor }) => { const [color, side, alpha = '1', widthArg = '1', inset = 'inset'] = args const width = Number(widthArg) @@ -86,7 +86,7 @@ export const shadowFunctions = { break } }) - return targetShadow + return [targetShadow] } } } diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js index 8196415b..91bda11e 100644 --- a/src/services/theme_data/theme_data_3.service.js +++ b/src/services/theme_data/theme_data_3.service.js @@ -1,4 +1,5 @@ import { convert, brightness } from 'chromatism' +import { flattenDeep } from 'lodash' import { alphaBlend, getTextColor, @@ -20,6 +21,7 @@ import { normalizeCombination, findRules } from './iss_utils.js' +import { parseCssShadow } from './css_utils.js' const DEBUG = false @@ -36,7 +38,32 @@ const components = { ChatMessage: null } -const findColor = (color, dynamicVars, staticVars) => { +const findShadow = (shadows, { dynamicVars, staticVars }) => { + return (shadows || []).map(shadow => { + let targetShadow + if (typeof shadow === 'string') { + if (shadow.startsWith('$')) { + targetShadow = process(shadow, shadowFunctions, { findColor, findShadow }, { dynamicVars, staticVars }) + } else if (shadow.startsWith('--')) { + const [variable] = shadow.split(/,/g).map(str => str.trim()) // discarding modifier since it's not supported + const variableSlot = variable.substring(2) + return findShadow(staticVars[variableSlot], { dynamicVars, staticVars }) + } else { + targetShadow = parseCssShadow(shadow) + } + } else { + targetShadow = shadow + } + + const shadowArray = Array.isArray(targetShadow) ? targetShadow : [targetShadow] + return shadowArray.map(s => ({ + ...s, + color: findColor(s.color, { dynamicVars, staticVars }) + })) + }) +} + +const findColor = (color, { dynamicVars, staticVars }) => { if (typeof color !== 'string' || (!color.startsWith('--') && !color.startsWith('$'))) return color let targetColor = null if (color.startsWith('--')) { @@ -76,7 +103,7 @@ const findColor = (color, dynamicVars, staticVars) => { if (color.startsWith('$')) { try { - targetColor = process(color, colorFunctions, findColor, dynamicVars, staticVars) + targetColor = process(color, colorFunctions, { findColor }, { dynamicVars, staticVars }) } catch (e) { console.error('Failure executing color function', e) targetColor = '#FF00FF' @@ -89,7 +116,7 @@ const findColor = (color, dynamicVars, staticVars) => { const getTextColorAlpha = (directives, intendedTextColor, dynamicVars, staticVars) => { const opacity = directives.textOpacity const backgroundColor = convert(dynamicVars.lowerLevelBackground).rgb - const textColor = convert(findColor(intendedTextColor, dynamicVars, staticVars)).rgb + const textColor = convert(findColor(intendedTextColor, { dynamicVars, staticVars })).rgb if (opacity === null || opacity === undefined || opacity >= 1) { return convert(textColor).hex } @@ -288,7 +315,7 @@ export const init = (extraRuleset) => { dynamicVars.inheritedBackground = lowerLevelBackground dynamicVars.stacked = convert(stacked[lowerLevelSelector]).rgb - const intendedTextColor = convert(findColor(inheritedTextColor, dynamicVars, staticVars)).rgb + const intendedTextColor = convert(findColor(inheritedTextColor, { dynamicVars, staticVars })).rgb const textColor = newTextRule.directives.textAuto === 'no-auto' ? intendedTextColor : getTextColor( @@ -355,7 +382,7 @@ export const init = (extraRuleset) => { dynamicVars.inheritedBackground = inheritedBackground - const rgb = convert(findColor(computedDirectives.background, dynamicVars, staticVars)).rgb + const rgb = convert(findColor(computedDirectives.background, { dynamicVars, staticVars })).rgb if (!stacked[selector]) { let blend @@ -373,21 +400,7 @@ export const init = (extraRuleset) => { } if (computedDirectives.shadow) { - dynamicVars.shadow = (computedDirectives.shadow || []).map(shadow => { - let targetShadow - if (typeof shadow === 'string') { - if (shadow.startsWith('$')) { - targetShadow = process(shadow, shadowFunctions, findColor, dynamicVars, staticVars) - } - } else { - targetShadow = shadow - } - - return { - ...targetShadow, - color: findColor(targetShadow.color, dynamicVars, staticVars) - } - }) + dynamicVars.shadow = flattenDeep(findShadow(flattenDeep(computedDirectives.shadow), { dynamicVars, staticVars })) } if (!stacked[selector]) { @@ -403,14 +416,23 @@ export const init = (extraRuleset) => { const dynamicSlots = Object.entries(computedDirectives).filter(([k, v]) => k.startsWith('--')) dynamicSlots.forEach(([k, v]) => { - const [type, value] = v.split('|').map(x => x.trim()) // woah, Extreme! + const [type, ...value] = v.split('|').map(x => x.trim()) // woah, Extreme! switch (type) { case 'color': { - const color = findColor(value, dynamicVars, staticVars) + const color = findColor(value[0], { dynamicVars, staticVars }) dynamicVars[k] = color if (component.name === 'Root') { staticVars[k.substring(2)] = color } + break + } + case 'shadow': { + const shadow = value + dynamicVars[k] = shadow + if (component.name === 'Root') { + staticVars[k.substring(2)] = shadow + } + break } } }) -- cgit v1.2.3-70-g09d2 From 879f520b75bcb379790317627bc2a8d2b739a2fb Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 22 Feb 2024 00:02:24 +0200 Subject: tabs support + cleanup --- src/boot/after_store.js | 1 - src/components/alert.style.js | 3 +- src/components/button_unstyled.style.js | 2 -- src/components/panel.style.js | 3 +- src/components/tab_switcher/tab.style.js | 52 +++++++++++++++++++++++++++ src/components/tab_switcher/tab_switcher.jsx | 2 +- src/components/tab_switcher/tab_switcher.scss | 14 +++++--- src/services/theme_data/css_utils.js | 1 - src/services/theme_data/theme2_to_theme3.js | 10 ++++-- 9 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 src/components/tab_switcher/tab.style.js (limited to 'src/services/theme_data/css_utils.js') diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 49a8130c..84fea954 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -359,7 +359,6 @@ const afterStoreSetup = async ({ store, i18n }) => { const { theme } = store.state.instance const customThemePresent = customThemeSource || customTheme - console.log({ ...customThemeSource }, { ...customTheme }) if (customThemePresent) { if (customThemeSource && customThemeSource.themeEngineVersion === CURRENT_VERSION) { applyTheme(customThemeSource) diff --git a/src/components/alert.style.js b/src/components/alert.style.js index 5881e833..bb97bd64 100644 --- a/src/components/alert.style.js +++ b/src/components/alert.style.js @@ -5,7 +5,8 @@ export default { 'Text', 'Icon', 'Link', - 'Border' + 'Border', + 'ButtonUnstyled' ], variants: { normal: '.neutral', diff --git a/src/components/button_unstyled.style.js b/src/components/button_unstyled.style.js index 60dd0d47..a2d854aa 100644 --- a/src/components/button_unstyled.style.js +++ b/src/components/button_unstyled.style.js @@ -3,8 +3,6 @@ export default { selector: '.button-unstyled', states: { disabled: ':disabled', - toggled: '.toggled', - pressed: ':active', hover: ':hover:not(:disabled)', focused: ':focus-within' }, diff --git a/src/components/panel.style.js b/src/components/panel.style.js index 95a10366..504ecbcb 100644 --- a/src/components/panel.style.js +++ b/src/components/panel.style.js @@ -16,7 +16,8 @@ export default { 'Alert', 'UserCard', 'Chat', - 'Attachment' + 'Attachment', + 'Tab' ], defaultRules: [ { diff --git a/src/components/tab_switcher/tab.style.js b/src/components/tab_switcher/tab.style.js new file mode 100644 index 00000000..563da87c --- /dev/null +++ b/src/components/tab_switcher/tab.style.js @@ -0,0 +1,52 @@ +export default { + name: 'Tab', // Name of the component + selector: '.tab', // CSS selector/prefix + states: { + active: '.active', + hover: ':hover:not(:disabled)', + disabled: '.disabled' + }, + validInnerComponents: [ + 'Text', + 'Icon' + ], + defaultRules: [ + { + directives: { + background: '--fg', + shadow: ['--defaultButtonShadow', '--defaultButtonBevel'], + roundness: 3 + } + }, + { + state: ['hover'], + directives: { + shadow: ['--defaultButtonHoverGlow', '--defaultButtonBevel'] + } + }, + { + state: ['disabled'], + directives: { + background: '$blend(--inheritedBackground, 0.25, --parent)', + shadow: ['--defaultButtonBevel'] + } + }, + { + state: ['active'], + directives: { + opacity: 0 + } + }, + { + component: 'Text', + parent: { + component: 'Tab', + state: ['disabled'] + }, + directives: { + textOpacity: 0.25, + textOpacityMode: 'blend' + } + } + ] +} diff --git a/src/components/tab_switcher/tab_switcher.jsx b/src/components/tab_switcher/tab_switcher.jsx index b444da43..027a380a 100644 --- a/src/components/tab_switcher/tab_switcher.jsx +++ b/src/components/tab_switcher/tab_switcher.jsx @@ -97,7 +97,7 @@ export default { .map((slot, index) => { const props = slot.props if (!props) return - const classesTab = ['tab', 'button-default'] + const classesTab = ['tab'] const classesWrapper = ['tab-wrapper'] if (this.activeIndex === index) { classesTab.push('active') diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss index 705925c8..a90a13ed 100644 --- a/src/components/tab_switcher/tab_switcher.scss +++ b/src/components/tab_switcher/tab_switcher.scss @@ -25,8 +25,7 @@ content: ""; flex: 1 1 auto; border-bottom: 1px solid; - border-bottom-color: $fallback--border; - border-bottom-color: var(--border, $fallback--border); + border-bottom-color: var(--border); } .tab-wrapper { @@ -37,8 +36,7 @@ right: 0; bottom: 0; border-bottom: 1px solid; - border-bottom-color: $fallback--border; - border-bottom-color: var(--border, $fallback--border); + border-bottom-color: var(--border); } } @@ -173,6 +171,14 @@ } .tab { + user-select: none; + color: var(--text); + border: none; + cursor: pointer; + box-shadow: var(--shadow); + font-size: 1em; + font-family: var(--interfaceFont, sans-serif); + border-radius: var(--roundness); position: relative; white-space: nowrap; padding: 6px 1em; diff --git a/src/services/theme_data/css_utils.js b/src/services/theme_data/css_utils.js index 412accf9..3bbee6af 100644 --- a/src/services/theme_data/css_utils.js +++ b/src/services/theme_data/css_utils.js @@ -9,7 +9,6 @@ export const parseCssShadow = (text) => { const [x, y, blur = 0, spread = 0] = dimensions.split(/ /).filter(x => x).map(x => x.trim()) const isInset = inset?.trim() === 'inset' - console.log(color.trim()) const colorString = color.split(/ /).filter(x => x).map(x => x.trim())[0] return { diff --git a/src/services/theme_data/theme2_to_theme3.js b/src/services/theme_data/theme2_to_theme3.js index b367af36..ef9506a6 100644 --- a/src/services/theme_data/theme2_to_theme3.js +++ b/src/services/theme_data/theme2_to_theme3.js @@ -55,7 +55,7 @@ export const extendedBasePrefixes = [ 'panel', 'topBar', - // 'tab', // TODO: not implemented yet + 'tab', 'btn', 'input', 'selectedMenu', @@ -122,6 +122,9 @@ export const convertTheme2To3 = (data) => { case 'btn': rule.component = 'Button' break + case 'tab': + rule.component = 'Tab' + break case 'input': rule.component = 'Input' break @@ -155,6 +158,7 @@ export const convertTheme2To3 = (data) => { newRules.push(rule) if (rule.component === 'Button') { newRules.push({ ...rule, component: 'ScrollbarElement' }) + newRules.push({ ...rule, component: 'Tab' }) } }) return newRules @@ -215,6 +219,7 @@ export const convertTheme2To3 = (data) => { if (rule.component === 'Button') { newRules.push({ ...rule, component: 'ScrollbarElement' }) + newRules.push({ ...rule, component: 'Tab' }) } }) return newRules @@ -351,8 +356,7 @@ export const convertTheme2To3 = (data) => { } if (newRule.component === 'Button') { - console.log([newRule, { ...newRule, component: 'ScrollbarElement' }]) - return [newRule, { ...newRule, component: 'ScrollbarElement' }] + return [newRule, { ...newRule, component: 'Tab' }, { ...newRule, component: 'ScrollbarElement' }] } else { return [newRule] } -- cgit v1.2.3-70-g09d2 From 09e0e53ad6bb2afd53baf5281290dcee4c20327a Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 22 Feb 2024 14:36:56 +0200 Subject: opacity stuff, better debug mode --- src/services/style_setter/style_setter.js | 2 +- src/services/theme_data/css_utils.js | 13 +++- src/services/theme_data/theme2_to_theme3.js | 88 ++++++++++++++++++++++++- src/services/theme_data/theme_data_3.service.js | 31 ++------- 4 files changed, 104 insertions(+), 30 deletions(-) (limited to 'src/services/theme_data/css_utils.js') diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index 57e4a7b8..ed6c8505 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -22,7 +22,7 @@ export const applyTheme = (input) => { } const t1 = performance.now() - const themes3 = init(extraRules) + const themes3 = init(extraRules, '#FFFFFF') const t2 = performance.now() console.log('Themes 3 initialization took ' + (t2 - t1) + 'ms') const head = document.head diff --git a/src/services/theme_data/css_utils.js b/src/services/theme_data/css_utils.js index 3bbee6af..b98a78ed 100644 --- a/src/services/theme_data/css_utils.js +++ b/src/services/theme_data/css_utils.js @@ -2,6 +2,11 @@ import { convert } from 'chromatism' import { rgba2css } from '../color_convert/color_convert.js' +// This changes what backgrounds are used to "stacked" solid colors so you can see +// what theme engine "thinks" is actual background color is for purposes of text color +// generation and for when --stacked variable is used +const DEBUG = false + export const parseCssShadow = (text) => { const dimensions = /(\d[a-z]*\s?){2,4}/.exec(text)?.[0] const inset = /inset/.exec(text)?.[0] @@ -21,7 +26,7 @@ export const parseCssShadow = (text) => { } } -export const getCssColorString = (color, alpha) => rgba2css({ ...convert(color).rgb, a: alpha }) +export const getCssColorString = (color, alpha = 1) => rgba2css({ ...convert(color).rgb, a: alpha }) export const getCssShadow = (input, usesDropShadow) => { if (input.length === 0) { @@ -90,6 +95,12 @@ export const getCssRules = (rules) => rules.map(rule => { ].join(';\n ') } case 'background': { + if (DEBUG) { + return ` + --background: ${getCssColorString(rule.dynamicVars.stacked)}; + background-color: ${getCssColorString(rule.dynamicVars.stacked)}; + ` + } if (v === 'transparent') { return [ rule.directives.backgroundNoCssColor !== 'yes' ? ('background-color: ' + v) : '', diff --git a/src/services/theme_data/theme2_to_theme3.js b/src/services/theme_data/theme2_to_theme3.js index aa29d359..32797c42 100644 --- a/src/services/theme_data/theme2_to_theme3.js +++ b/src/services/theme_data/theme2_to_theme3.js @@ -14,6 +14,20 @@ export const basePaletteKeys = new Set([ 'cOrange' ]) +export const opacityKeys = new Set([ + 'alert', + 'alertPopup', + 'bg', + 'border', + 'btn', + 'faint', + 'input', + 'panel', + 'popover', + 'profileTint', + 'underlay' +]) + export const shadowsKeys = new Set([ 'panel', 'topBar', @@ -111,6 +125,78 @@ export const convertTheme2To3 = (data) => { } } + const convertOpacity = () => { + const newRules = [] + Object.keys(data.opacity).forEach(key => { + if (!opacityKeys.has(key) || data.opacity[key] === undefined) return null + const originalOpacity = data.opacity[key] + const rule = {} + + switch (key) { + case 'alert': + rule.component = 'Alert' + break + case 'alertPopup': + rule.component = 'Alert' + rule.parent = { component: 'Popover' } + break + case 'bg': + rule.component = 'Panel' + break + case 'border': + rule.component = 'Border' + break + case 'btn': + rule.component = 'Button' + break + case 'faint': + rule.component = 'Text' + rule.state = ['faint'] + break + case 'input': + rule.component = 'Input' + break + case 'panel': + rule.component = 'PanelHeader' + break + case 'popover': + rule.component = 'Popover' + break + case 'profileTint': + return null + case 'underlay': + rule.component = 'Underlay' + break + } + + switch (key) { + case 'alert': + case 'alertPopup': + case 'bg': + case 'btn': + case 'input': + case 'panel': + case 'popover': + case 'underlay': + rule.directives = { opacity: originalOpacity } + break + case 'faint': + case 'border': + rule.directives = { textOpacity: originalOpacity } + break + } + + newRules.push(rule) + + if (rule.component === 'Button') { + newRules.push({ ...rule, component: 'ScrollbarElement' }) + newRules.push({ ...rule, component: 'Tab' }) + } + }) + console.log(newRules) + return newRules + } + const convertRadii = () => { const newRules = [] Object.keys(data.radii).forEach(key => { @@ -372,5 +458,5 @@ export const convertTheme2To3 = (data) => { const flatExtRules = extendedRules.filter(x => x).reduce((acc, x) => [...acc, ...x], []).filter(x => x).reduce((acc, x) => [...acc, ...x], []) - return [generateRoot(), ...convertShadows(), ...convertRadii(), ...flatExtRules] + return [generateRoot(), ...convertShadows(), ...convertRadii(), ...convertOpacity(), ...flatExtRules] } diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js index 91bda11e..0133dfe4 100644 --- a/src/services/theme_data/theme_data_3.service.js +++ b/src/services/theme_data/theme_data_3.service.js @@ -23,8 +23,6 @@ import { } from './iss_utils.js' import { parseCssShadow } from './css_utils.js' -const DEBUG = false - // Ensuring the order of components const components = { Root: null, @@ -146,7 +144,7 @@ componentsContext.keys().forEach(key => { const ruleToSelector = genericRuleToSelector(components) -export const init = (extraRuleset) => { +export const init = (extraRuleset, ultimateBackgroundColor) => { const staticVars = {} const stacked = {} const computed = {} @@ -338,32 +336,11 @@ export const init = (extraRuleset) => { earlyLowerLevelRule.virtualDirectivesRaw = virtualDirectivesRaw computed[lowerLevelSelector].virtualDirectives = virtualDirectives computed[lowerLevelSelector].virtualDirectivesRaw = virtualDirectivesRaw - - // Debug: lets you see what it think background color should be - if (!DEBUG) return - - const directives = { - textColor, - background: convert(computed[lowerLevelSelector].background).hex, - ...inheritedTextOpacity - } - - addRule({ - dynamicVars, - selector: cssSelector, - virtual: true, - component: component.name, - parent, - ...combination, - directives, - virtualDirectives, - virtualDirectivesRaw - }) } else { computed[selector] = computed[selector] || {} // TODO: DEFAULT TEXT COLOR - const lowerLevelStackedBackground = stacked[lowerLevelSelector] || convert('#FF00FF').rgb + const lowerLevelStackedBackground = stacked[lowerLevelSelector] || convert(ultimateBackgroundColor).rgb if (computedDirectives.background) { let inheritRule = null @@ -386,7 +363,7 @@ export const init = (extraRuleset) => { if (!stacked[selector]) { let blend - const alpha = computedDirectives.opacity + const alpha = computedDirectives.opacity ?? 1 if (alpha >= 1) { blend = rgb } else if (alpha <= 0) { @@ -410,7 +387,7 @@ export const init = (extraRuleset) => { computed[selector].background = { ...lowerLevelStackedBackground, a: 0 } } - dynamicVars.stacked = lowerLevelStackedBackground + dynamicVars.stacked = stacked[selector] dynamicVars.background = computed[selector].background const dynamicSlots = Object.entries(computedDirectives).filter(([k, v]) => k.startsWith('--')) -- cgit v1.2.3-70-g09d2 From 779b3dc1228030740ccfbd5192bcd368b526ce56 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 22 Feb 2024 15:15:08 +0200 Subject: blur support, fix toggled buttons not working right --- src/components/panel.style.js | 1 + src/components/popover.style.js | 1 + src/services/theme_data/css_utils.js | 19 +++++++++++++++---- src/services/theme_data/theme2_to_theme3.js | 5 ++--- 4 files changed, 19 insertions(+), 7 deletions(-) (limited to 'src/services/theme_data/css_utils.js') diff --git a/src/components/panel.style.js b/src/components/panel.style.js index 504ecbcb..d9b27667 100644 --- a/src/components/panel.style.js +++ b/src/components/panel.style.js @@ -24,6 +24,7 @@ export default { directives: { background: '--bg', roundness: 3, + blur: '5px', shadow: [{ x: 1, y: 1, diff --git a/src/components/popover.style.js b/src/components/popover.style.js index 1b51c9b3..0197271b 100644 --- a/src/components/popover.style.js +++ b/src/components/popover.style.js @@ -21,6 +21,7 @@ export default { { directives: { background: '--bg', + blur: '10px', shadow: [{ x: 2, y: 2, diff --git a/src/services/theme_data/css_utils.js b/src/services/theme_data/css_utils.js index b98a78ed..b83b90bf 100644 --- a/src/services/theme_data/css_utils.js +++ b/src/services/theme_data/css_utils.js @@ -108,10 +108,21 @@ export const getCssRules = (rules) => rules.map(rule => { ].filter(x => x).join(';\n') } const color = getCssColorString(rule.dynamicVars.background, rule.directives.opacity) - return [ - rule.directives.backgroundNoCssColor !== 'yes' ? ('background-color: ' + color) : '', - ' --background: ' + color - ].filter(x => x).join(';\n') + const cssDirectives = ['--background: ' + color] + if (rule.directives.backgroundNoCssColor !== 'yes') { + cssDirectives.push('background-color: ' + color) + } + return cssDirectives.filter(x => x).join(';\n') + } + case 'blur': { + const cssDirectives = [] + if (rule.directives.opacity < 1) { + cssDirectives.push(`--backdrop-filter: blur(${v}) `) + if (rule.directives.backgroundNoCssColor !== 'yes') { + cssDirectives.push(`backdrop-filter: blur(${v}) `) + } + } + return cssDirectives.join(';\n') } case 'textColor': { if (rule.directives.textNoCssColor === 'yes') { return '' } diff --git a/src/services/theme_data/theme2_to_theme3.js b/src/services/theme_data/theme2_to_theme3.js index 32797c42..7adbbd42 100644 --- a/src/services/theme_data/theme2_to_theme3.js +++ b/src/services/theme_data/theme2_to_theme3.js @@ -193,7 +193,6 @@ export const convertTheme2To3 = (data) => { newRules.push({ ...rule, component: 'Tab' }) } }) - console.log(newRules) return newRules } @@ -424,12 +423,12 @@ export const convertTheme2To3 = (data) => { case 'alert': { const hasPanel = variantArray.find(x => x === 'Panel') if (hasPanel) { - rule.parent = { component: 'PanelHeader' } + newRule.parent = { component: 'PanelHeader' } variantArray = variantArray.filter(x => x !== 'Panel') } const hasTop = variantArray.find(x => x === 'Top') // TopBar if (hasTop) { - rule.parent = { component: 'TopBar' } + newRule.parent = { component: 'TopBar' } variantArray = variantArray.filter(x => x !== 'Top' && x !== 'Bar') } break -- cgit v1.2.3-70-g09d2 From 7d2faccd4f62e8ff6c2f6cc9b8b11d890a6ab974 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 22 Feb 2024 18:04:28 +0200 Subject: fonts support, cleanup --- src/App.scss | 36 ++---- src/components/input.style.js | 1 + src/components/rich_content/rich_content.scss | 8 +- src/components/rich_content/rich_content.style.js | 2 + src/components/root.style.js | 7 ++ src/components/select/select.vue | 8 +- .../tabs/security_tab/mfa_backup_codes.vue | 5 +- src/components/status_body/status_body.scss | 5 +- src/components/tab_switcher/tab_switcher.scss | 2 +- src/services/style_setter/style_setter.js | 15 +-- src/services/theme_data/css_utils.js | 125 +++++++++++---------- src/services/theme_data/theme2_to_theme3.js | 43 ++++++- src/services/theme_data/theme_data_3.service.js | 11 +- 13 files changed, 154 insertions(+), 114 deletions(-) (limited to 'src/services/theme_data/css_utils.js') diff --git a/src/App.scss b/src/App.scss index dd790c6a..41e445d2 100644 --- a/src/App.scss +++ b/src/App.scss @@ -22,7 +22,7 @@ html { body { font-family: sans-serif; - font-family: var(--interfaceFont, sans-serif); + font-family: var(--font); margin: 0; color: var(--text); -webkit-font-smoothing: antialiased; @@ -130,12 +130,7 @@ i[class*="icon-"], nav { z-index: var(--ZI_navbar); - background-color: $fallback--fg; - background-color: var(--topBar, $fallback--fg); - color: $fallback--faint; - color: var(--faint, $fallback--faint); - box-shadow: 0 0 4px rgb(0 0 0 / 60%); - box-shadow: var(--topBarShadow); + box-shadow: var(--shadow); box-sizing: border-box; height: var(--navbar-height); position: fixed; @@ -359,7 +354,7 @@ nav { box-shadow: var(--shadow); font-size: 1em; font-family: sans-serif; - font-family: var(--interfaceFont, sans-serif); + font-family: var(--font); &::-moz-focus-inner { border: none; @@ -409,11 +404,8 @@ nav { color: inherit; &.-link { - color: var(--link); - } - - &.-fullwidth { - width: 100%; + /* stylelint-disable-next-line declaration-no-important */ + color: var(--link) !important; } } @@ -437,8 +429,7 @@ textarea { border: none; border-radius: var(--roundness); box-shadow: var(--shadow); - font-family: sans-serif; - font-family: var(--inputFont, sans-serif); + font-family: var(--font); font-size: 1em; margin: 0; box-sizing: border-box; @@ -466,9 +457,8 @@ textarea { display: none; &:checked + label::before { - box-shadow: 0 0 2px black inset, 0 0 0 4px $fallback--fg inset; - box-shadow: var(--inputShadow), 0 0 0 4px var(--fg, $fallback--fg) inset; - background-color: var(--accent, $fallback--link); + box-shadow: var(--shadow); + background-color: var(--background); } &:disabled { @@ -523,11 +513,8 @@ textarea { width: 1.1em; height: 1.1em; border-radius: var(--roundness); - box-shadow: 0 0 2px black inset; - box-shadow: var(--inputShadow); + box-shadow: var(--shadow); margin-right: 0.5em; - background-color: $fallback--fg; - background-color: var(--input, $fallback--fg); vertical-align: top; text-align: center; line-height: 1.1; @@ -551,7 +538,7 @@ textarea { option { color: var(--text); - background-color: var(--bg, $fallback--bg); + background-color: var(--background); } .hide-number-spinner { @@ -667,8 +654,7 @@ option { .visibility-notice { padding: 0.5em; - border: 1px solid $fallback--faint; - border: 1px solid var(--faint, $fallback--faint); + border: 1px solid var(--textFaint); border-radius: var(--roundness); } diff --git a/src/components/input.style.js b/src/components/input.style.js index 70c775ad..139a0034 100644 --- a/src/components/input.style.js +++ b/src/components/input.style.js @@ -37,6 +37,7 @@ export default { }, { directives: { + '--font': 'generic | inherit', background: '--fg, -5', roundness: 3, shadow: [{ diff --git a/src/components/rich_content/rich_content.scss b/src/components/rich_content/rich_content.scss index 3bb5b16b..73eb07e9 100644 --- a/src/components/rich_content/rich_content.scss +++ b/src/components/rich_content/rich_content.scss @@ -1,10 +1,10 @@ -@import "../../variables"; - .RichContent { + font-family: var(--font); + blockquote { margin: 0.2em 0 0.2em 0.2em; font-style: italic; - border-left: 0.2em solid var(--faint, $fallback--faint); + border-left: 0.2em solid var(--textFaint); padding-left: 1em; } @@ -17,7 +17,7 @@ kbd, var, pre { - font-family: var(--postCodeFont, monospace); + font-family: var(--monoFont); } p { diff --git a/src/components/rich_content/rich_content.style.js b/src/components/rich_content/rich_content.style.js index 7acc9d4f..c8314000 100644 --- a/src/components/rich_content/rich_content.style.js +++ b/src/components/rich_content/rich_content.style.js @@ -9,6 +9,8 @@ export default { defaultRules: [ { directives: { + '--font': 'generic | inherit', + '--monoFont': 'generic | monospace', textNoCssColor: 'yes' } } diff --git a/src/components/root.style.js b/src/components/root.style.js index 8ddb8038..053d984b 100644 --- a/src/components/root.style.js +++ b/src/components/root.style.js @@ -9,5 +9,12 @@ export default { 'Scrollbar', 'ScrollbarElement', 'MobileDrawer' + ], + defaultRules: [ + { + directives: { + '--font': 'generic | sans-serif' + } + } ] } diff --git a/src/components/select/select.vue b/src/components/select/select.vue index 1797afc8..30fd0bb0 100644 --- a/src/components/select/select.vue +++ b/src/components/select/select.vue @@ -32,12 +32,10 @@ label.Select { appearance: none; background: transparent; border: none; - color: $fallback--text; - color: var(--inputText, --text, $fallback--text); + color: var(--text); margin: 0; padding: 0 2em 0 0.2em; - font-family: sans-serif; - font-family: var(--inputFont, sans-serif); + font-family: var(--font); font-size: 1em; width: 100%; z-index: 1; @@ -53,7 +51,7 @@ label.Select { height: 100%; width: 0.875em; color: $fallback--text; - color: var(--inputText, $fallback--text); + font-family: var(--font); line-height: 2; z-index: 0; pointer-events: none; diff --git a/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue b/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue index 923161b2..002f1bb2 100644 --- a/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue +++ b/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue @@ -25,12 +25,11 @@ .mfa-backup-codes { .warning { - color: $fallback--cOrange; - color: var(--cOrange, $fallback--cOrange); + color: var(--cOrange); } .backup-codes { - font-family: var(--postCodeFont, monospace); + font-family: var(--monoFont); } } diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss index 930ed803..0a467b4f 100644 --- a/src/components/status_body/status_body.scss +++ b/src/components/status_body/status_body.scss @@ -1,5 +1,3 @@ -@import "../../variables"; - .StatusBody { display: flex; flex-direction: column; @@ -14,7 +12,6 @@ & .text, & .summary { - font-family: var(--postFont, sans-serif); white-space: pre-wrap; overflow-wrap: break-word; word-wrap: break-word; @@ -41,7 +38,7 @@ margin-bottom: 0.5em; border-style: solid; border-width: 0 0 1px; - border-color: var(--border, $fallback--border); + border-color: var(--border); flex-grow: 0; &.-tall { diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss index a90a13ed..489407cb 100644 --- a/src/components/tab_switcher/tab_switcher.scss +++ b/src/components/tab_switcher/tab_switcher.scss @@ -177,7 +177,7 @@ cursor: pointer; box-shadow: var(--shadow); font-size: 1em; - font-family: var(--interfaceFont, sans-serif); + font-family: var(--font); border-radius: var(--roundness); position: relative; white-space: nowrap; diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index ed6c8505..1cda7213 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -6,25 +6,22 @@ import { getCssRules } from '../theme_data/css_utils.js' import { defaultState } from '../../modules/config.js' export const applyTheme = (input) => { - console.log({ ...input }) let extraRules - let fonts if (input.themeType !== 1) { const t0 = performance.now() - const { rules, theme } = generatePreset(input) - fonts = rules.fonts + const { theme } = generatePreset(input) const t1 = performance.now() - console.log('Themes 2 initialization took ' + (t1 - t0) + 'ms') + console.debug('Themes 2 initialization took ' + (t1 - t0) + 'ms') extraRules = convertTheme2To3(theme) } else { - console.log(input) + console.debug(input) extraRules = convertTheme2To3(input) } const t1 = performance.now() const themes3 = init(extraRules, '#FFFFFF') const t2 = performance.now() - console.log('Themes 3 initialization took ' + (t2 - t1) + 'ms') + console.debug('Themes 3 (eager) initialization took ' + (t2 - t1) + 'ms') const head = document.head const body = document.body body.classList.add('hidden') @@ -33,8 +30,6 @@ export const applyTheme = (input) => { head.appendChild(styleEl) const styleSheet = styleEl.sheet - styleSheet.toString() - styleSheet.insertRule(`:root { ${fonts} }`, 'index-max') getCssRules(themes3.eager, themes3.staticVars).forEach(rule => { // Hack to support multiple selectors on same component if (rule.match(/::-webkit-scrollbar-button/)) { @@ -58,7 +53,7 @@ export const applyTheme = (input) => { styleSheet.insertRule(rule, 'index-max') }) const t3 = performance.now() - console.log('Themes 3 finalization took ' + (t3 - t2) + 'ms') + console.debug('Themes 3 finalization (lazy) took ' + (t3 - t2) + 'ms') }) } diff --git a/src/services/theme_data/css_utils.js b/src/services/theme_data/css_utils.js index b83b90bf..f04fed42 100644 --- a/src/services/theme_data/css_utils.js +++ b/src/services/theme_data/css_utils.js @@ -1,6 +1,6 @@ import { convert } from 'chromatism' -import { rgba2css } from '../color_convert/color_convert.js' +import { hex2rgb, rgba2css } from '../color_convert/color_convert.js' // This changes what backgrounds are used to "stacked" solid colors so you can see // what theme engine "thinks" is actual background color is for purposes of text color @@ -78,72 +78,79 @@ export const getCssRules = (rules) => rules.map(rule => { return ' ' + k + ': ' + v }).join(';\n') - let directives - if (rule.component !== 'Root') { - directives = Object.entries(rule.directives).map(([k, v]) => { - switch (k) { - case 'roundness': { - return ' ' + [ - '--roundness: ' + v + 'px' - ].join(';\n ') + const directives = Object.entries(rule.directives).map(([k, v]) => { + switch (k) { + case 'roundness': { + return ' ' + [ + '--roundness: ' + v + 'px' + ].join(';\n ') + } + case 'shadow': { + return ' ' + [ + '--shadow: ' + getCssShadow(rule.dynamicVars.shadow), + '--shadowFilter: ' + getCssShadowFilter(rule.dynamicVars.shadow), + '--shadowInset: ' + getCssShadow(rule.dynamicVars.shadow, true) + ].join(';\n ') + } + case 'background': { + if (DEBUG) { + return ` + --background: ${getCssColorString(rule.dynamicVars.stacked)}; + background-color: ${getCssColorString(rule.dynamicVars.stacked)}; + ` } - case 'shadow': { - return ' ' + [ - '--shadow: ' + getCssShadow(rule.dynamicVars.shadow), - '--shadowFilter: ' + getCssShadowFilter(rule.dynamicVars.shadow), - '--shadowInset: ' + getCssShadow(rule.dynamicVars.shadow, true) - ].join(';\n ') + if (v === 'transparent') { + if (rule.component === 'Root') return [] + return [ + rule.directives.backgroundNoCssColor !== 'yes' ? ('background-color: ' + v) : '', + ' --background: ' + v + ].filter(x => x).join(';\n') } - case 'background': { - if (DEBUG) { - return ` - --background: ${getCssColorString(rule.dynamicVars.stacked)}; - background-color: ${getCssColorString(rule.dynamicVars.stacked)}; - ` - } - if (v === 'transparent') { - return [ - rule.directives.backgroundNoCssColor !== 'yes' ? ('background-color: ' + v) : '', - ' --background: ' + v - ].filter(x => x).join(';\n') - } - const color = getCssColorString(rule.dynamicVars.background, rule.directives.opacity) - const cssDirectives = ['--background: ' + color] + const color = getCssColorString(rule.dynamicVars.background, rule.directives.opacity) + const cssDirectives = ['--background: ' + color] + if (rule.directives.backgroundNoCssColor !== 'yes') { + cssDirectives.push('background-color: ' + color) + } + return cssDirectives.filter(x => x).join(';\n') + } + case 'blur': { + const cssDirectives = [] + if (rule.directives.opacity < 1) { + cssDirectives.push(`--backdrop-filter: blur(${v}) `) if (rule.directives.backgroundNoCssColor !== 'yes') { - cssDirectives.push('background-color: ' + color) + cssDirectives.push(`backdrop-filter: blur(${v}) `) } - return cssDirectives.filter(x => x).join(';\n') } - case 'blur': { - const cssDirectives = [] - if (rule.directives.opacity < 1) { - cssDirectives.push(`--backdrop-filter: blur(${v}) `) - if (rule.directives.backgroundNoCssColor !== 'yes') { - cssDirectives.push(`backdrop-filter: blur(${v}) `) + return cssDirectives.join(';\n') + } + case 'font': { + return 'font-family: ' + v + } + case 'textColor': { + if (rule.directives.textNoCssColor === 'yes') { return '' } + return 'color: ' + v + } + default: + if (k.startsWith('--')) { + const [type, value] = v.split('|').map(x => x.trim()) // woah, Extreme! + switch (type) { + case 'color': { + const color = rule.dynamicVars[k] + if (typeof color === 'string') { + return k + ': ' + rgba2css(hex2rgb(color)) + } else { + return k + ': ' + rgba2css(color) + } } + case 'generic': + return k + ': ' + value + default: + return '' } - return cssDirectives.join(';\n') } - case 'textColor': { - if (rule.directives.textNoCssColor === 'yes') { return '' } - return 'color: ' + v - } - default: - if (k.startsWith('--')) { - const [type] = v.split('|').map(x => x.trim()) // woah, Extreme! - switch (type) { - case 'color': - return k + ': ' + rgba2css(rule.dynamicVars[k]) - default: - return '' - } - } - return '' - } - }).filter(x => x).map(x => ' ' + x).join(';\n') - } else { - directives = {} - } + return '' + } + }).filter(x => x).map(x => ' ' + x).join(';\n') return [ header, diff --git a/src/services/theme_data/theme2_to_theme3.js b/src/services/theme_data/theme2_to_theme3.js index 7adbbd42..11f517c6 100644 --- a/src/services/theme_data/theme2_to_theme3.js +++ b/src/services/theme_data/theme2_to_theme3.js @@ -14,6 +14,13 @@ export const basePaletteKeys = new Set([ 'cOrange' ]) +export const fontsKeys = new Set([ + 'interface', + 'input', + 'post', + 'postCode' +]) + export const opacityKeys = new Set([ 'alert', 'alertPopup', @@ -249,6 +256,40 @@ export const convertTheme2To3 = (data) => { return newRules } + const convertFonts = () => { + const newRules = [] + Object.keys(data.fonts).forEach(key => { + if (!fontsKeys.has(key)) return + const originalFont = data.fonts[key].family + const rule = {} + + switch (key) { + case 'interface': + case 'postCode': + rule.component = 'Root' + break + case 'input': + rule.component = 'Input' + break + case 'post': + rule.component = 'RichContent' + break + } + switch (key) { + case 'interface': + case 'input': + case 'post': + rule.directives = { '--font': 'generic | ' + originalFont } + break + case 'postCode': + rule.directives = { '--monoFont': 'generic | ' + originalFont } + newRules.push({ ...rule, component: 'RichContent' }) + break + } + newRules.push(rule) + }) + return newRules + } const convertShadows = () => { const newRules = [] Object.keys(data.shadows).forEach(key => { @@ -457,5 +498,5 @@ export const convertTheme2To3 = (data) => { const flatExtRules = extendedRules.filter(x => x).reduce((acc, x) => [...acc, ...x], []).filter(x => x).reduce((acc, x) => [...acc, ...x], []) - return [generateRoot(), ...convertShadows(), ...convertRadii(), ...convertOpacity(), ...flatExtRules] + return [generateRoot(), ...convertShadows(), ...convertRadii(), ...convertOpacity(), ...convertFonts(), ...flatExtRules] } diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js index 0133dfe4..13caef9e 100644 --- a/src/services/theme_data/theme_data_3.service.js +++ b/src/services/theme_data/theme_data_3.service.js @@ -411,6 +411,13 @@ export const init = (extraRuleset, ultimateBackgroundColor) => { } break } + case 'generic': { + dynamicVars[k] = value + if (component.name === 'Root') { + staticVars[k.substring(2)] = value + } + break + } } }) @@ -454,9 +461,9 @@ export const init = (extraRuleset, ultimateBackgroundColor) => { } processInnerComponent(components.Root, eagerRules) - console.log('TOTAL COMBOS: ' + counter) + console.debug('Eager combinations processed:' + counter) const lazyExec = Promise.all(promises).then(() => { - console.log('TOTAL COMBOS: ' + counter) + console.debug('Total combinations processed: ' + counter) }).then(() => lazyRules) return { -- cgit v1.2.3-70-g09d2 From c83ddb0b2b824fb3c0e3bb596552e98c162c78d3 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Tue, 27 Feb 2024 17:03:39 +0200 Subject: better v1 detection, better menu-item consistency --- src/components/menu_item.style.js | 35 +++++++++++++++++++--- src/components/navigation/navigation_entry.vue | 14 ++++++++- .../settings_modal/tabs/theme_tab/theme_tab.js | 2 ++ src/services/style_setter/style_setter.js | 8 ++--- src/services/theme_data/css_utils.js | 2 +- src/services/theme_data/theme_data_3.service.js | 8 +++-- 6 files changed, 57 insertions(+), 12 deletions(-) (limited to 'src/services/theme_data/css_utils.js') diff --git a/src/components/menu_item.style.js b/src/components/menu_item.style.js index 3c70bd9f..3812f894 100644 --- a/src/components/menu_item.style.js +++ b/src/components/menu_item.style.js @@ -30,17 +30,44 @@ export default { { state: ['active'], directives: { - background: '$mod(--bg, 5)', + background: '$mod(--bg, 10)', + opacity: 1 + } + }, + { + state: ['active', 'hover'], + directives: { + background: '$mod(--bg, 15)', opacity: 1 } }, { component: 'Text', - variant: 'normal', parent: { component: 'MenuItem', - state: ['normal', 'hover'], - variant: 'normal' + state: ['hover'] + }, + directives: { + textColor: '--link', + textAuto: 'no-preserve' + } + }, + { + component: 'Text', + parent: { + component: 'MenuItem', + state: ['active'] + }, + directives: { + textColor: '--link', + textAuto: 'no-preserve' + } + }, + { + component: 'Icon', + parent: { + component: 'MenuItem', + state: ['active'] }, directives: { textColor: '--link', diff --git a/src/components/navigation/navigation_entry.vue b/src/components/navigation/navigation_entry.vue index 1189f76d..ac4a0c47 100644 --- a/src/components/navigation/navigation_entry.vue +++ b/src/components/navigation/navigation_entry.vue @@ -10,7 +10,7 @@ > @@ -84,11 +84,23 @@ } .main-link { + background: none; + border: none; + outline: none; + display: inline; + text-align: initial; + font-size: 100%; + font-family: inherit; + line-height: unset; + cursor: pointer; + box-sizing: content-box; + color: var(--text); flex: 1; padding: 0 1em; } .menu-icon { + color: var(--icon); margin-right: 0.8em; } diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js index dd525920..11c90b03 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -514,6 +514,7 @@ export default { this.$store.dispatch('setOption', { name: 'customTheme', value: { + themeFileVersion: this.selectedVersion, themeEngineVersion: CURRENT_VERSION, ...this.previewTheme } @@ -521,6 +522,7 @@ export default { this.$store.dispatch('setOption', { name: 'customThemeSource', value: { + themeFileVersion: this.selectedVersion, themeEngineVersion: CURRENT_VERSION, shadows: this.shadowsLocal, fonts: this.fontsLocal, diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index 52cf06ed..74d745f0 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -8,11 +8,11 @@ import { chunk } from 'lodash' export const applyTheme = async (input) => { let extraRules - if (input.themeType !== 1) { + if (input.themeFileVersion === 1) { + extraRules = convertTheme2To3(input) + } else { const { theme } = generatePreset(input) extraRules = convertTheme2To3(theme) - } else { - extraRules = convertTheme2To3(input) } const themes3 = init(extraRules, '#FFFFFF') @@ -125,7 +125,7 @@ export const getPreset = (val) => { .then((themes) => themes[val] ? themes[val] : themes['pleroma-dark']) .then((theme) => { const isV1 = Array.isArray(theme) - const data = isV1 ? { themeType: 1 } : theme.theme + const data = isV1 ? {} : theme.theme if (isV1) { const bg = hex2rgb(theme[1]) diff --git a/src/services/theme_data/css_utils.js b/src/services/theme_data/css_utils.js index f04fed42..321bc3e5 100644 --- a/src/services/theme_data/css_utils.js +++ b/src/services/theme_data/css_utils.js @@ -155,7 +155,7 @@ export const getCssRules = (rules) => rules.map(rule => { return [ header, directives + ';', - (!rule.virtual && rule.directives.textNoCssColor !== 'yes') ? ' color: var(--text);' : '', + (rule.component === 'Text' && rule.directives.textNoCssColor !== 'yes') ? ' color: var(--text);' : '', '', virtualDirectives, footer diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js index b3c4abf1..5fd16f19 100644 --- a/src/services/theme_data/theme_data_3.service.js +++ b/src/services/theme_data/theme_data_3.service.js @@ -275,8 +275,12 @@ export const init = (extraRuleset, ultimateBackgroundColor) => { selector: cssSelector.split(/ /g).slice(0, -1).join(' '), ...combination, directives: {}, - virtualDirectives, - virtualDirectivesRaw + virtualDirectives: { + [virtualName]: getTextColorAlpha(newTextRule.directives, textColor, dynamicVars) + }, + virtualDirectivesRaw: { + [virtualName]: textColor + } } } else { computed[selector] = computed[selector] || {} -- cgit v1.2.3-70-g09d2 From e2af986323d82ebd15d7a303ed40cc033d933479 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Tue, 27 Feb 2024 22:02:25 +0200 Subject: fix global notices --- src/components/alert.style.js | 3 +- .../global_notice_list/global_notice_list.vue | 42 +--------------------- src/components/root.style.js | 1 + src/components/underlay.style.js | 3 +- src/services/theme_data/css_utils.js | 2 +- 5 files changed, 6 insertions(+), 45 deletions(-) (limited to 'src/services/theme_data/css_utils.js') diff --git a/src/components/alert.style.js b/src/components/alert.style.js index bb97bd64..19bd4bbb 100644 --- a/src/components/alert.style.js +++ b/src/components/alert.style.js @@ -18,7 +18,8 @@ export default { { directives: { background: '--text', - opacity: 0.5 + opacity: 0.5, + blur: '9px' } }, { diff --git a/src/components/global_notice_list/global_notice_list.vue b/src/components/global_notice_list/global_notice_list.vue index 9e9ec7aa..71e1bf30 100644 --- a/src/components/global_notice_list/global_notice_list.vue +++ b/src/components/global_notice_list/global_notice_list.vue @@ -4,7 +4,7 @@ v-for="(notice, index) in notices" :key="index" class="alert global-notice" - :class="{ ['global-' + notice.level]: true }" + :class="{ [notice.level]: true }" >
{{ $t(notice.messageKey, notice.messageArgs) }} @@ -52,48 +52,8 @@ } } - .global-error { - background-color: var(--alertPopupError, $fallback--cRed); - color: var(--alertPopupErrorText, $fallback--text); - - .svg-inline--fa { - color: var(--alertPopupErrorText, $fallback--text); - } - } - - .global-warning { - background-color: var(--alertPopupWarning, $fallback--cOrange); - color: var(--alertPopupWarningText, $fallback--text); - - .svg-inline--fa { - color: var(--alertPopupWarningText, $fallback--text); - } - } - - .global-success { - background-color: var(--alertPopupSuccess, $fallback--cGreen); - color: var(--alertPopupSuccessText, $fallback--text); - - .svg-inline--fa { - color: var(--alertPopupSuccessText, $fallback--text); - } - } - - .global-info { - background-color: var(--alertPopupNeutral, $fallback--fg); - color: var(--alertPopupNeutralText, $fallback--text); - - .svg-inline--fa { - color: var(--alertPopupNeutralText, $fallback--text); - } - } - .close-notice { padding-right: 0.2em; - - .svg-inline--fa:hover { - opacity: 0.6; - } } } diff --git a/src/components/root.style.js b/src/components/root.style.js index 97289236..e4d33051 100644 --- a/src/components/root.style.js +++ b/src/components/root.style.js @@ -9,6 +9,7 @@ export default { 'Scrollbar', 'ScrollbarElement', 'MobileDrawer', + 'Alert', 'Button' // mobile post button ], defaultRules: [ diff --git a/src/components/underlay.style.js b/src/components/underlay.style.js index 3ed871cc..3e0e1bf1 100644 --- a/src/components/underlay.style.js +++ b/src/components/underlay.style.js @@ -6,8 +6,7 @@ export default { // we are searching for underlay specifically or for whatever is laid on top of it. outOfTreeSelector: '.underlay', validInnerComponents: [ - 'Panel', - 'Alert' + 'Panel' ], defaultRules: [ { diff --git a/src/services/theme_data/css_utils.js b/src/services/theme_data/css_utils.js index 321bc3e5..6f1fd0c2 100644 --- a/src/services/theme_data/css_utils.js +++ b/src/services/theme_data/css_utils.js @@ -155,7 +155,7 @@ export const getCssRules = (rules) => rules.map(rule => { return [ header, directives + ';', - (rule.component === 'Text' && rule.directives.textNoCssColor !== 'yes') ? ' color: var(--text);' : '', + (rule.component === 'Text' && rule.state.indexOf('faint') < 0 && rule.directives.textNoCssColor !== 'yes') ? ' color: var(--text);' : '', '', virtualDirectives, footer -- cgit v1.2.3-70-g09d2 From cf1345caca2fc905b0f692f6149e0006610614e4 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 28 Feb 2024 15:04:01 +0200 Subject: more scrollbars work --- src/App.scss | 16 ++++++++-------- src/services/theme_data/css_utils.js | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/services/theme_data/css_utils.js') diff --git a/src/App.scss b/src/App.scss index 36415ddc..8c60a05d 100644 --- a/src/App.scss +++ b/src/App.scss @@ -86,15 +86,15 @@ body { &:increment { background-image: - linear-gradient(45deg, var(--text) 50%, transparent calc(50% + 1px)), - linear-gradient(-45deg, transparent 50%, var(--text) calc(50% + 1px)); + linear-gradient(45deg, var(--text) 50%, transparent 51%), + linear-gradient(-45deg, transparent 50%, var(--text) 51%); background-position: top var(--___bgPadding) left 50%, right 50% bottom var(--___bgPadding); } &:decrement { background-image: linear-gradient(45deg, transparent 50%, var(--text) calc(50% + 1px)), - linear-gradient(-45deg, var(--text) 50%, transparent calc(50% + 1px)); + linear-gradient(-45deg, var(--text) 50%, transparent 51%); background-position: bottom var(--___bgPadding) right 50%, left 50% top var(--___bgPadding); } } @@ -104,15 +104,15 @@ body { &:increment { background-image: - linear-gradient(-45deg, transparent 50%, var(--text) calc(50% + 1px)), - linear-gradient(45deg, transparent 50%, var(--text) calc(50% + 1px)); + linear-gradient(-45deg, transparent 50%, var(--text) 51%), + linear-gradient(45deg, transparent 50%, var(--text) 51%); background-position: right var(--___bgPadding) top 50%, left var(--___bgPadding) top 50%; } &:decrement { background-image: - linear-gradient(-45deg, var(--text) 50%, transparent calc(50% + 1px)), - linear-gradient(45deg, var(--text) 50%, transparent calc(50% + 1px)); + linear-gradient(-45deg, var(--text) 50%, transparent 51%), + linear-gradient(45deg, var(--text) 50%, transparent 51%); background-position: left var(--___bgPadding) top 50%, right var(--___bgPadding) top 50%; } } @@ -121,7 +121,7 @@ body { } // Body should have background to scrollbar otherwise it will use white (body color?) html { - scrollbar-color: var(--selectedMenu) var(--wallpaper); + scrollbar-color: var(--fg) var(--wallpaper); background: var(--wallpaper); } } diff --git a/src/services/theme_data/css_utils.js b/src/services/theme_data/css_utils.js index 6f1fd0c2..a89eac3b 100644 --- a/src/services/theme_data/css_utils.js +++ b/src/services/theme_data/css_utils.js @@ -69,7 +69,7 @@ export const getCssShadowFilter = (input) => { export const getCssRules = (rules) => rules.map(rule => { let selector = rule.selector if (!selector) { - selector = 'body' + selector = 'html' } const header = selector + ' {' const footer = '}' -- cgit v1.2.3-70-g09d2