logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
commit: 98f972e557047a626880692189fdae68269a732e
parent 9ec61d0f0a26369196d9e9b4ac62f4a5b3c38ce1
Author: Henry Jameson <me@hjkos.com>
Date:   Sun, 11 Feb 2024 23:11:28 +0200

menu-item improvements

Diffstat:

Msrc/App.scss84+++++--------------------------------------------------------------------------
Asrc/components/border.style.js13+++++++++++++
Msrc/components/button.style.js27++++++++++++++++-----------
Dsrc/components/dropdown_menu.style.js19-------------------
Asrc/components/menu_item.style.js45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/modals.style.js8++++++++
Msrc/components/nav_panel/nav_panel.vue6+++---
Msrc/components/navigation/navigation_entry.vue36------------------------------------
Msrc/components/panel.style.js13+++++++++++--
Msrc/components/panel_header.style.js3++-
Msrc/components/popover.style.js16++++++++++++++--
Msrc/components/root.style.js4++--
Msrc/components/underlay.style.js5++++-
Msrc/panel.scss49+++----------------------------------------------
Msrc/services/theme_data/theme_data_3.service.js118++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Mtop_bar.style.js14++++++++++++++
16 files changed, 209 insertions(+), 251 deletions(-)

diff --git a/src/App.scss b/src/App.scss @@ -129,15 +129,6 @@ i[class*="icon-"], color: var(--icon); } -.button-unstyled:hover, -a:hover { - > i[class*="icon-"], - > .svg-inline--fa, - > .iconLetter { - color: var(--text); - } -} - nav { z-index: var(--ZI_navbar); background-color: $fallback--fg; @@ -192,8 +183,7 @@ nav { grid-column: 1 / span 3; grid-row: 1 / 1; pointer-events: none; - background-color: rgb(0 0 0 / 15%); - background-color: var(--underlay, rgb(0 0 0 / 15%)); + background-color: var(--underlay); z-index: -1000; } @@ -363,10 +353,7 @@ nav { .button-default { user-select: none; - color: $fallback--text; - color: var(--btnText, $fallback--text); - background-color: $fallback--fg; - background-color: var(--btn, $fallback--fg); + color: var(--text); border: none; border-radius: $fallback--btnRadius; border-radius: var(--btnRadius, $fallback--btnRadius); @@ -376,70 +363,12 @@ nav { font-family: sans-serif; font-family: var(--interfaceFont, sans-serif); - &.-sublime { - background: transparent; - } - - i[class*="icon-"], - .svg-inline--fa { - color: var(--icon); - } - &::-moz-focus-inner { border: none; } - &:active { - color: $fallback--text; - color: var(--btnPressedText, $fallback--text); - background-color: $fallback--fg; - background-color: var(--btnPressed, $fallback--fg); - - svg, - i { - color: $fallback--text; - color: var(--btnPressedText, $fallback--text); - } - } - &:disabled { cursor: not-allowed; - color: $fallback--text; - color: var(--btnDisabledText, $fallback--text); - background-color: $fallback--fg; - background-color: var(--btnDisabled, $fallback--fg); - - svg, - i { - color: $fallback--text; - color: var(--btnDisabledText, $fallback--text); - } - } - - &.toggled { - color: $fallback--text; - color: var(--btnToggledText, $fallback--text); - background-color: $fallback--fg; - background-color: var(--btnToggled, $fallback--fg); - box-shadow: - 0 0 4px 0 rgb(255 255 255 / 30%), - 0 1px 0 0 rgb(0 0 0 / 20%) inset, - 0 -1px 0 0 rgb(255 255 255 / 20%) inset; - box-shadow: var(--buttonPressedShadow); - - svg, - i { - color: $fallback--text; - color: var(--btnToggledText, $fallback--text); - } - } - - &.danger { - // TODO: add better color variable - color: $fallback--text; - color: var(--alertErrorPanelText, $fallback--text); - background-color: $fallback--alertError; - background-color: var(--alertError, $fallback--alertError); } } @@ -458,8 +387,7 @@ nav { color: inherit; &.-link { - color: $fallback--link; - color: var(--link, $fallback--link); + color: var(--link); } &.-fullwidth { @@ -510,7 +438,6 @@ textarea { &[disabled="disabled"], &.disabled { cursor: not-allowed; - opacity: 0.5; } &[type="range"] { @@ -610,9 +537,7 @@ textarea { } option { - color: $fallback--text; - color: var(--text, $fallback--text); - background-color: $fallback--bg; + color: var(--text); background-color: var(--bg, $fallback--bg); } @@ -746,6 +671,7 @@ option { .faint { --text: var(--textFaint); --textGreentext: var(--textGreentextFaint); + --textCyantext: var(--textCyantextFaint); --link: var(--linkFaint); color: var(--text); diff --git a/src/components/border.style.js b/src/components/border.style.js @@ -0,0 +1,13 @@ +export default { + name: 'Border', + selector: '/*border*/', + virtual: true, + defaultRules: [ + { + directives: { + textColor: '$mod(--parent, 10)', + textAuto: 'no-auto' + } + } + ] +} diff --git a/src/components/button.style.js b/src/components/button.style.js @@ -23,28 +23,37 @@ const hoverGlow = { export default { name: 'Button', // Name of the component selector: '.button', // CSS selector/prefix - // States, system witll calculate ALL possible combinations of those and append a "normal" to them + standalone "normal" state + // outOfTreeSelector: '' // out-of-tree selector is used when other components are laid over it but it's not part of the tree, see Underlay component + // States, system witll calculate ALL possible combinations of those and prepend "normal" to them + standalone "normal" state states: { - // normal: state is implicitly added + // States are a bit expensive - the amount of combinations generated is about (1/6)n^3+n, so adding more state increased number of combination by an order of magnitude! + // All states inherit from "normal" state, there is no other inheirtance, i.e. hover+disabled only inherits from "normal", not from hover nor disabled. + // However, cascading still works, so resulting state will be result of merging of all relevant states/variants + // normal: '' // normal state is implicitly added, it is always included disabled: ':disabled', toggled: '.toggled', pressed: ':active', hover: ':hover', focused: ':focus-within' }, - // Variants are mutually exclusive, which saves on computation time + // Variants are mutually exclusive, each component implicitly has "normal" variant, and all other variants inherit from it. variants: { - normal: '-default', // you can override normal variant - danger: '.danger', - unstyled: '-unstyled' + // Variants save on computation time since adding new variant just adds one more "set". + normal: '-default', // you can override normal variant, it will be appenended to the main class + danger: '-default.danger' + // Overall the compuation difficulty is N*((1/6)M^3+M) where M is number of distinct states and N is number of variants. + // This (currently) is further multipled by number of places where component can exist. }, + // This lists all other components that can possibly exist within one. Recursion is currently not supported (and probably won't be supported ever). validInnerComponents: [ 'Text', 'Icon' ], + // Default rules, used as "default theme", essentially. defaultRules: [ { - component: 'Button', + // 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: [{ @@ -58,7 +67,6 @@ export default { } }, { - component: 'Button', variant: 'unstyled', directives: { background: '--fg', @@ -66,14 +74,12 @@ export default { } }, { - component: 'Button', state: ['hover'], directives: { shadow: [hoverGlow, ...buttonInsetFakeBorders] } }, { - component: 'Button', state: ['hover', 'pressed'], directives: { background: '--accent,-24.2', @@ -81,7 +87,6 @@ export default { } }, { - component: 'Button', state: ['disabled'], directives: { background: '$blend(--background, 0.25, --parent)', diff --git a/src/components/dropdown_menu.style.js b/src/components/dropdown_menu.style.js @@ -1,19 +0,0 @@ -export default { - name: 'DropdownMenu', - selector: '.dropdown', - validInnerComponents: [ - 'Text', - 'Icon', - 'Input' - ], - states: { - hover: ':hover' - }, - defaultRules: [ - { - directives: { - background: '--fg' - } - } - ] -} diff --git a/src/components/menu_item.style.js b/src/components/menu_item.style.js @@ -0,0 +1,45 @@ +export default { + name: 'MenuItem', + selector: '.menu-item', + validInnerComponents: [ + 'Text', + 'Icon', + 'Input', + 'Border' + ], + states: { + hover: ':hover', + active: 'active' + }, + defaultRules: [ + { + directives: { + background: '--fg' + } + }, + { + component: 'Text', + variant: 'normal', + parent: { + component: 'MenuItem', + state: ['normal', 'hover'], + variant: 'normal' + }, + directives: { + textColor: '--link', + textAuto: 'no-preserve' + } + }, + { + component: 'Icon', + parent: { + component: 'MenuItem', + state: ['hover'] + }, + directives: { + textColor: '--link', + textAuto: 'no-preserve' + } + } + ] +} diff --git a/src/components/modals.style.js b/src/components/modals.style.js @@ -0,0 +1,8 @@ +export default { + name: 'Modals', + selector: '.modal-view', + validInnerComponents: [ + 'Panel' + ], + defaultRules: [] +} diff --git a/src/components/nav_panel/nav_panel.vue b/src/components/nav_panel/nav_panel.vue @@ -107,7 +107,7 @@ .NavPanel { .panel { overflow: hidden; - box-shadow: var(--panelShadow); + box-shadow: var(--shadow); } ul { @@ -124,14 +124,14 @@ } > li { - &:first-child .menu-item { + &:first-child.menu-item { border-top-right-radius: $fallback--panelRadius; border-top-right-radius: var(--panelRadius, $fallback--panelRadius); border-top-left-radius: $fallback--panelRadius; border-top-left-radius: var(--panelRadius, $fallback--panelRadius); } - &:last-child .menu-item { + &:last-child.menu-item { border-bottom-right-radius: $fallback--panelRadius; border-bottom-right-radius: var(--panelRadius, $fallback--panelRadius); border-bottom-left-radius: $fallback--panelRadius; diff --git a/src/components/navigation/navigation_entry.vue b/src/components/navigation/navigation_entry.vue @@ -1,7 +1,6 @@ <template> <OptionalRouterLink v-slot="{ isActive, href, navigate } = {}" - ass="ass" :to="routeTo" > <li @@ -96,40 +95,5 @@ margin-right: -0.8em; } } - - &:hover { - background-color: $fallback--lightBg; - background-color: var(--selectedMenu, $fallback--lightBg); - color: $fallback--link; - color: var(--selectedMenuText, $fallback--link); - - --faint: var(--selectedMenuFaintText, $fallback--faint); - --faintLink: var(--selectedMenuFaintLink, $fallback--faint); - --lightText: var(--selectedMenuLightText, $fallback--lightText); - - .menu-icon { - --icon: var(--text, $fallback--icon); - } - } - - &.-active { - font-weight: bolder; - background-color: $fallback--lightBg; - background-color: var(--selectedMenu, $fallback--lightBg); - color: $fallback--text; - color: var(--selectedMenuText, $fallback--text); - - --faint: var(--selectedMenuFaintText, $fallback--faint); - --faintLink: var(--selectedMenuFaintLink, $fallback--faint); - --lightText: var(--selectedMenuLightText, $fallback--lightText); - - .menu-icon { - --icon: var(--text, $fallback--icon); - } - - &:hover { - text-decoration: underline; - } - } } </style> diff --git a/src/components/panel.style.js b/src/components/panel.style.js @@ -7,12 +7,21 @@ export default { 'Icon', 'Button', 'Input', - 'PanelHeader' + 'PanelHeader', + 'MenuItem' ], defaultRules: [ { directives: { - background: '--bg' + background: '--bg', + shadow: [{ + x: 1, + y: 1, + blur: 4, + spread: 0, + color: '#000000', + alpha: 0.6 + }] } } ] diff --git a/src/components/panel_header.style.js b/src/components/panel_header.style.js @@ -11,7 +11,8 @@ export default { { component: 'PanelHeader', directives: { - background: '--fg' + background: '--fg', + shadow: [] } } ] diff --git a/src/components/popover.style.js b/src/components/popover.style.js @@ -1,6 +1,10 @@ export default { name: 'Popover', selector: '.popover', + variants: { + tooltip: '.tooltip', + modal: '.modal' + }, validInnerComponents: [ 'Text', 'Link', @@ -8,12 +12,20 @@ export default { 'Button', 'Input', 'PanelHeader', - 'DropdownMenu' + 'MenuItem' ], defaultRules: [ { directives: { - background: '--fg' + background: '--bg', + shadow: [{ + x: 2, + y: 2, + blur: 3, + spread: 0, + color: '#000000', + alpha: 0.5 + }] } } ] diff --git a/src/components/root.style.js b/src/components/root.style.js @@ -3,8 +3,8 @@ export default { selector: ':root', validInnerComponents: [ 'Underlay', - 'TopBar', - 'Popover' + 'Modals', + 'TopBar' ], defaultRules: [ { diff --git a/src/components/underlay.style.js b/src/components/underlay.style.js @@ -1,6 +1,9 @@ export default { name: 'Underlay', - selector: 'body', // Should be '#content' but for now this is better for testing until I have proper popovers and such... + selector: '#content', + // Out of tree selector: Most components are laid over underlay, but underlay itself is not part of the DOM tree, + // i.e. it's a separate absolutely-positioned component, so we need to treat it differently depending on whether + // we are searching for underlay specifically or for whatever is laid on top of it. outOfTreeSelector: '.underlay', validInnerComponents: [ 'Panel' diff --git a/src/panel.scss b/src/panel.scss @@ -3,8 +3,6 @@ position: relative; display: flex; flex-direction: column; - background-color: $fallback--bg; - background-color: var(--bg, $fallback--bg); .panel-heading { background-color: inherit; @@ -24,8 +22,7 @@ left: 0; right: 0; z-index: 5; - box-shadow: 1px 1px 4px rgb(0 0 0 / 60%); - box-shadow: var(--panelShadow); + box-shadow: var(--shadow); pointer-events: none; } } @@ -133,58 +130,18 @@ border-radius: var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius) 0 0; border-width: 0 0 1px; align-items: start; - // panel theme - color: var(--panelText); &::after { background-color: var(--background); z-index: -2; border-radius: $fallback--panelRadius $fallback--panelRadius 0 0; border-radius: var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius) 0 0; - box-shadow: var(--panelHeaderShadow); - } - - .button-unstyled:hover, - a:hover { - i[class*="icon-"], - .svg-inline--fa, - .iconLetter { - color: var(--panelText); - } - } - - .faint { - background-color: transparent; - color: $fallback--faint; - color: var(--panelFaint, $fallback--faint); + box-shadow: var(--shadow); } &:not(.-flexible-height) { > .button-default { flex-shrink: 0; - - &, - i[class*="icon-"] { - color: $fallback--text; - color: var(--btnPanelText, $fallback--text); - } - - &:active { - background-color: $fallback--fg; - background-color: var(--btnPressedPanel, $fallback--fg); - color: $fallback--text; - color: var(--btnPressedPanelText, $fallback--text); - } - - &:disabled { - color: $fallback--text; - color: var(--btnDisabledPanelText, $fallback--text); - } - - &.toggled { - color: $fallback--text; - color: var(--btnToggledPanelText, $fallback--text); - } } } @@ -227,6 +184,6 @@ align-items: center; border-width: 1px 0 0; border-style: solid; - border-color: var(--border, $fallback--border); + border-color: var(--border); } /* stylelint-enable no-descending-specificity */ diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js @@ -11,7 +11,8 @@ import Root from 'src/components/root.style.js' import TopBar from 'src/components/top_bar.style.js' import Underlay from 'src/components/underlay.style.js' import Popover from 'src/components/popover.style.js' -import DropdownMenu from 'src/components/dropdown_menu.style.js' +import Modals from 'src/components/modals.style.js' +import MenuItem from 'src/components/menu_item.style.js' import Panel from 'src/components/panel.style.js' import PanelHeader from 'src/components/panel_header.style.js' import Button from 'src/components/button.style.js' @@ -19,34 +20,11 @@ import Input from 'src/components/input.style.js' import Text from 'src/components/text.style.js' import Link from 'src/components/link.style.js' import Icon from 'src/components/icon.style.js' +import Border from 'src/components/border.style.js' const DEBUG = false export const DEFAULT_SHADOWS = { - panel: [{ - x: 1, - y: 1, - blur: 4, - spread: 0, - color: '#000000', - alpha: 0.6 - }], - topBar: [{ - x: 0, - y: 0, - blur: 4, - spread: 0, - color: '#000000', - alpha: 0.6 - }], - popup: [{ - x: 2, - y: 2, - blur: 3, - spread: 0, - color: '#000000', - alpha: 0.5 - }], avatar: [{ x: 0, y: 1, @@ -54,9 +32,7 @@ export const DEFAULT_SHADOWS = { spread: 0, color: '#000000', alpha: 0.7 - }], - avatarStatus: [], - panelHeader: [] + }] } const components = { @@ -64,9 +40,11 @@ const components = { Text, Link, Icon, + Border, Underlay, + Modals, Popover, - DropdownMenu, + MenuItem, Panel, PanelHeader, TopBar, @@ -196,16 +174,41 @@ export const init = (extraRuleset, palette) => { const rules = [] - const ruleset = [ - ...Object.values(components).map(c => c.defaultRules.map(r => ({ component: c.name, ...r })) || []).reduce((acc, arr) => [...acc, ...arr], []), - ...extraRuleset - ].map(rule => { + const normalizeCombination = rule => { rule.variant = rule.variant ?? 'normal' rule.state = [...new Set(['normal', ...(rule.state || [])])] + } + + const rulesetUnsorted = [ + ...Object.values(components) + .map(c => (c.defaultRules || []).map(r => ({ component: c.name, ...r }))) + .reduce((acc, arr) => [...acc, ...arr], []), + ...extraRuleset + ].map(rule => { + normalizeCombination(rule) + let currentParent = rule.parent + while (currentParent) { + normalizeCombination(currentParent) + currentParent = currentParent.parent + } return rule }) + const ruleset = rulesetUnsorted + .map((data, index) => ({ data, index })) + .sort(({ data: a, index: ai }, { data: b, index: bi }) => { + const parentsA = unroll(a).length + const parentsB = unroll(b).length + + if (parentsA === parentsB || (parentsB !== 0 && parentsA !== 0)) return ai - bi + if (parentsA === 0 && parentsB !== 0) return -1 + if (parentsB === 0 && parentsA !== 0) return 1 + return 0 // failsafe, shouldn't happen? + }) + .map(({ data }) => data) + + console.log(ruleset) const virtualComponents = new Set(Object.values(components).filter(c => c.virtual).map(c => c.name)) const addRule = (rule) => { @@ -260,6 +263,18 @@ export const init = (extraRuleset, palette) => { targetColor = alphaBlend(backgroundArg, amount, foregroundArg) break } + case 'mod': { + if (args.length !== 2) { + throw new Error(`$mod requires 2 arguments, ${args.length} were provided`) + } + const color = convert(findColor(args[0], dynamicVars)).rgb + const amount = Number(args[1]) + const effectiveBackground = dynamicVars.lowerLevelBackground + const isLightOnDark = relativeLuminance(convert(effectiveBackground).rgb) < 0.5 + const mod = isLightOnDark ? 1 : -1 + targetColor = brightness(amount * mod, color).rgb + break + } } } catch (e) { console.error('Failure executing color function', e) @@ -332,12 +347,12 @@ export const init = (extraRuleset, palette) => { } const processInnerComponent = (component, parent) => { - const parentList = parent ? unroll(parent).reverse().map(c => c.component) : [] - if (!component.virtual) { - const path = [...parentList, component.name].join(' > ') - console.log('Component ' + path + ' process starting') - } - const t0 = performance.now() + // const parentList = parent ? unroll(parent).reverse().map(c => c.component) : [] + // if (!component.virtual) { + // const path = [...parentList, component.name].join(' > ') + // console.log('Component ' + path + ' process starting') + // } + // const t0 = performance.now() const { validInnerComponents = [], states: originalStates = {}, @@ -359,7 +374,7 @@ export const init = (extraRuleset, palette) => { }).reduce((acc, x) => [...acc, ...x], []) stateVariantCombination.forEach(combination => { - const tt0 = performance.now() + // const tt0 = performance.now() const soloSelector = ruleToSelector({ component: component.name, ...combination }, true) const selector = ruleToSelector({ component: component.name, ...combination, parent }, true) @@ -422,6 +437,11 @@ export const init = (extraRuleset, palette) => { } } + if (component.name === 'Text' && combination.variant === 'normal' && computedRule.parent.component === 'MenuItem' && computedRule.parent.state.indexOf('hover') >= 0) { + console.log(existingRules) + console.log(computedRule, newTextRule) + } + dynamicVars.inheritedBackground = lowerLevelBackground // TODO properly provide "parent" text color? @@ -518,17 +538,17 @@ export const init = (extraRuleset, palette) => { } innerComponents.forEach(innerComponent => processInnerComponent(innerComponent, { parent, component: name, ...combination })) - const tt1 = performance.now() - if (!component.virtual) { - console.log('State-variant ' + combination.variant + ' : ' + combination.state.join('+') + ' procession time: ' + (tt1 - tt0) + 'ms') - } + // const tt1 = performance.now() + // if (!component.virtual) { + // console.log('State-variant ' + combination.variant + ' : ' + combination.state.join('+') + ' procession time: ' + (tt1 - tt0) + 'ms') + // } }) - const t1 = performance.now() - if (!component.virtual) { - const path = [...parentList, component.name].join(' > ') - console.log('Component ' + path + ' procession time: ' + (t1 - t0) + 'ms') - } + // const t1 = performance.now() + // if (!component.virtual) { + // const path = [...parentList, component.name].join(' > ') + // console.log('Component ' + path + ' procession time: ' + (t1 - t0) + 'ms') + // } } processInnerComponent(components.Root) diff --git a/top_bar.style.js b/top_bar.style.js @@ -5,5 +5,19 @@ export default { 'Link', 'Text', 'Icon' + ], + defaultRules: [ + { + directives: { + shadow: [{ + x: 0, + y: 0, + blur: 4, + spread: 0, + color: '#000000', + alpha: 0.6 + }] + } + } ] }