more optimizations, execution is now split into eager (for main UI) and
lazy (for modals, popovers etc) parts
This commit is contained in:
parent
34e4dd0a79
commit
96e3a1593a
42
src/components/alert.style.js
Normal file
42
src/components/alert.style.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
export default {
|
||||||
|
name: 'Alert',
|
||||||
|
selector: '.alert',
|
||||||
|
validInnerComponents: [
|
||||||
|
'Text',
|
||||||
|
'Icon',
|
||||||
|
'Link',
|
||||||
|
'Border'
|
||||||
|
],
|
||||||
|
variants: {
|
||||||
|
normal: '.neutral',
|
||||||
|
error: '.error',
|
||||||
|
warning: '.warning',
|
||||||
|
success: '.success'
|
||||||
|
},
|
||||||
|
defaultRules: [
|
||||||
|
{
|
||||||
|
directives: {
|
||||||
|
background: '--text',
|
||||||
|
opacity: 0.8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: 'error',
|
||||||
|
directives: {
|
||||||
|
background: '--cRed'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: 'warning',
|
||||||
|
directives: {
|
||||||
|
background: '--cOrange'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: 'success',
|
||||||
|
directives: {
|
||||||
|
background: '--cGreen'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
25
src/components/badge.style.js
Normal file
25
src/components/badge.style.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
export default {
|
||||||
|
name: 'Badge',
|
||||||
|
selector: '.badge',
|
||||||
|
validInnerComponents: [
|
||||||
|
'Text',
|
||||||
|
'Icon'
|
||||||
|
],
|
||||||
|
variants: {
|
||||||
|
normal: '.neutral',
|
||||||
|
notification: '.notification'
|
||||||
|
},
|
||||||
|
defaultRules: [
|
||||||
|
{
|
||||||
|
directives: {
|
||||||
|
background: '--cGreen'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: 'notification',
|
||||||
|
directives: {
|
||||||
|
background: '--cRed'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -38,11 +38,11 @@ export default {
|
|||||||
// All states inherit from "normal" state, there is no other inheirtance, i.e. hover+disabled only inherits from "normal", not from hover nor disabled.
|
// 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
|
// 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
|
// normal: '' // normal state is implicitly added, it is always included
|
||||||
disabled: ':disabled',
|
|
||||||
toggled: '.toggled',
|
toggled: '.toggled',
|
||||||
pressed: ':active',
|
pressed: ':active',
|
||||||
hover: ':hover',
|
hover: ':hover',
|
||||||
focused: ':focus-within'
|
focused: ':focus-within',
|
||||||
|
disabled: ':disabled'
|
||||||
},
|
},
|
||||||
// Variants are mutually exclusive, each component implicitly has "normal" variant, and all other variants inherit from it.
|
// Variants are mutually exclusive, each component implicitly has "normal" variant, and all other variants inherit from it.
|
||||||
variants: {
|
variants: {
|
||||||
@ -107,13 +107,6 @@ export default {
|
|||||||
shadow: [...buttonInsetFakeBorders]
|
shadow: [...buttonInsetFakeBorders]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
state: ['disabled', 'hover'],
|
|
||||||
directives: {
|
|
||||||
background: '$blend(--background, 0.25, --parent)',
|
|
||||||
shadow: [...buttonInsetFakeBorders]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
component: 'Text',
|
component: 'Text',
|
||||||
parent: {
|
parent: {
|
||||||
@ -124,17 +117,6 @@ export default {
|
|||||||
textOpacity: 0.25,
|
textOpacity: 0.25,
|
||||||
textOpacityMode: 'blend'
|
textOpacityMode: 'blend'
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'Text',
|
|
||||||
parent: {
|
|
||||||
component: 'Button',
|
|
||||||
state: ['disabled', 'hover']
|
|
||||||
},
|
|
||||||
directives: {
|
|
||||||
textOpacity: 0.25,
|
|
||||||
textOpacityMode: 'blend'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,8 @@ export default {
|
|||||||
},
|
},
|
||||||
validInnerComponents: [
|
validInnerComponents: [
|
||||||
'Text',
|
'Text',
|
||||||
'Icon'
|
'Icon',
|
||||||
|
'Badge'
|
||||||
],
|
],
|
||||||
defaultRules: [
|
defaultRules: [
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,8 @@ export default {
|
|||||||
'Text',
|
'Text',
|
||||||
'Icon',
|
'Icon',
|
||||||
'Input',
|
'Input',
|
||||||
'Border'
|
'Border',
|
||||||
|
'ButtonUnstyled'
|
||||||
],
|
],
|
||||||
states: {
|
states: {
|
||||||
hover: ':hover',
|
hover: ':hover',
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'Modals',
|
name: 'Modals',
|
||||||
selector: '.modal-view',
|
selector: '.modal-view',
|
||||||
|
lazy: true,
|
||||||
validInnerComponents: [
|
validInnerComponents: [
|
||||||
'Panel'
|
'Panel'
|
||||||
],
|
],
|
||||||
|
@ -11,7 +11,8 @@ export default {
|
|||||||
'PanelHeader',
|
'PanelHeader',
|
||||||
'MenuItem',
|
'MenuItem',
|
||||||
'Post',
|
'Post',
|
||||||
'Notification'
|
'Notification',
|
||||||
|
'Alert'
|
||||||
],
|
],
|
||||||
defaultRules: [
|
defaultRules: [
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,9 @@ export default {
|
|||||||
'Link',
|
'Link',
|
||||||
'Icon',
|
'Icon',
|
||||||
'Button',
|
'Button',
|
||||||
'ButtonUnstyled'
|
'ButtonUnstyled',
|
||||||
|
'Badge',
|
||||||
|
'Alert'
|
||||||
],
|
],
|
||||||
defaultRules: [
|
defaultRules: [
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'Popover',
|
name: 'Popover',
|
||||||
selector: '.popover',
|
selector: '.popover',
|
||||||
|
lazy: true,
|
||||||
variants: {
|
variants: {
|
||||||
tooltip: '.tooltip',
|
|
||||||
modal: '.modal'
|
modal: '.modal'
|
||||||
},
|
},
|
||||||
validInnerComponents: [
|
validInnerComponents: [
|
||||||
|
@ -7,7 +7,8 @@ export default {
|
|||||||
'Icon',
|
'Icon',
|
||||||
'Button',
|
'Button',
|
||||||
'ButtonUnstyled',
|
'ButtonUnstyled',
|
||||||
'Input'
|
'Input',
|
||||||
|
'Badge'
|
||||||
],
|
],
|
||||||
defaultRules: [
|
defaultRules: [
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,8 @@ export default {
|
|||||||
// we are searching for underlay specifically or for whatever is laid on top of it.
|
// we are searching for underlay specifically or for whatever is laid on top of it.
|
||||||
outOfTreeSelector: '.underlay',
|
outOfTreeSelector: '.underlay',
|
||||||
validInnerComponents: [
|
validInnerComponents: [
|
||||||
'Panel'
|
'Panel',
|
||||||
|
'Alert'
|
||||||
],
|
],
|
||||||
defaultRules: [
|
defaultRules: [
|
||||||
{
|
{
|
||||||
|
@ -28,11 +28,17 @@ export const applyTheme = (input) => {
|
|||||||
// styleSheet.insertRule(`:root { ${rules.colors} }`, 'index-max')
|
// styleSheet.insertRule(`:root { ${rules.colors} }`, 'index-max')
|
||||||
// styleSheet.insertRule(`:root { ${rules.shadows} }`, 'index-max')
|
// styleSheet.insertRule(`:root { ${rules.shadows} }`, 'index-max')
|
||||||
styleSheet.insertRule(`:root { ${rules.fonts} }`, 'index-max')
|
styleSheet.insertRule(`:root { ${rules.fonts} }`, 'index-max')
|
||||||
themes3.css.forEach(rule => {
|
themes3.css(themes3.eager).forEach(rule => {
|
||||||
console.log(rule)
|
|
||||||
styleSheet.insertRule(rule, 'index-max')
|
styleSheet.insertRule(rule, 'index-max')
|
||||||
})
|
})
|
||||||
body.classList.remove('hidden')
|
body.classList.remove('hidden')
|
||||||
|
themes3.lazy.then(lazyRules => {
|
||||||
|
themes3.css(lazyRules).forEach(rule => {
|
||||||
|
styleSheet.insertRule(rule, 'index-max')
|
||||||
|
})
|
||||||
|
const t3 = performance.now()
|
||||||
|
console.log('Themes 3 finalization took ' + (t3 - t2) + 'ms')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const configColumns = ({ sidebarColumnWidth, contentColumnWidth, notifsColumnWidth, emojiReactionsScale }) =>
|
const configColumns = ({ sidebarColumnWidth, contentColumnWidth, notifsColumnWidth, emojiReactionsScale }) =>
|
||||||
|
@ -27,6 +27,8 @@ import Post from 'src/components/post.style.js'
|
|||||||
import Notification from 'src/components/notification.style.js'
|
import Notification from 'src/components/notification.style.js'
|
||||||
import RichContent from 'src/components/rich_content.style.js'
|
import RichContent from 'src/components/rich_content.style.js'
|
||||||
import Avatar from 'src/components/avatar.style.js'
|
import Avatar from 'src/components/avatar.style.js'
|
||||||
|
import Badge from 'src/components/badge.style.js'
|
||||||
|
import Alert from 'src/components/alert.style.js'
|
||||||
|
|
||||||
const DEBUG = false
|
const DEBUG = false
|
||||||
|
|
||||||
@ -50,7 +52,9 @@ const components = {
|
|||||||
Post,
|
Post,
|
||||||
Notification,
|
Notification,
|
||||||
RichContent,
|
RichContent,
|
||||||
Avatar
|
Avatar,
|
||||||
|
Alert,
|
||||||
|
Badge
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Unrolls" a tree structure of item: { parent: { ...item2, parent: { ...item3, parent: {...} } }}
|
// "Unrolls" a tree structure of item: { parent: { ...item2, parent: { ...item3, parent: {...} } }}
|
||||||
@ -59,9 +63,8 @@ const unroll = (item) => {
|
|||||||
const out = []
|
const out = []
|
||||||
let currentParent = item
|
let currentParent = item
|
||||||
while (currentParent) {
|
while (currentParent) {
|
||||||
const { parent: newParent, ...rest } = currentParent
|
out.push(currentParent)
|
||||||
out.push(rest)
|
currentParent = currentParent.parent
|
||||||
currentParent = newParent
|
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@ -173,7 +176,8 @@ export const init = (extraRuleset, palette) => {
|
|||||||
const stacked = {}
|
const stacked = {}
|
||||||
const computed = {}
|
const computed = {}
|
||||||
|
|
||||||
const rules = []
|
const eagerRules = []
|
||||||
|
const lazyRules = []
|
||||||
|
|
||||||
const normalizeCombination = rule => {
|
const normalizeCombination = rule => {
|
||||||
rule.variant = rule.variant ?? 'normal'
|
rule.variant = rule.variant ?? 'normal'
|
||||||
@ -211,10 +215,6 @@ export const init = (extraRuleset, palette) => {
|
|||||||
|
|
||||||
const virtualComponents = new Set(Object.values(components).filter(c => c.virtual).map(c => c.name))
|
const virtualComponents = new Set(Object.values(components).filter(c => c.virtual).map(c => c.name))
|
||||||
|
|
||||||
const addRule = (rule) => {
|
|
||||||
rules.push(rule)
|
|
||||||
}
|
|
||||||
|
|
||||||
const findColor = (color, dynamicVars) => {
|
const findColor = (color, dynamicVars) => {
|
||||||
if (typeof color !== 'string' || (!color.startsWith('--') && !color.startsWith('$'))) return color
|
if (typeof color !== 'string' || (!color.startsWith('--') && !color.startsWith('$'))) return color
|
||||||
let targetColor = null
|
let targetColor = null
|
||||||
@ -346,7 +346,14 @@ export const init = (extraRuleset, palette) => {
|
|||||||
.join(' ')
|
.join(' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
const processInnerComponent = (component, parent) => {
|
let counter = 0
|
||||||
|
const promises = []
|
||||||
|
const processInnerComponent = (component, rules, parent) => {
|
||||||
|
const addRule = (rule) => {
|
||||||
|
rules.push(rule)
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentSelector = ruleToSelector(parent, true)
|
||||||
// const parentList = parent ? unroll(parent).reverse().map(c => c.component) : []
|
// const parentList = parent ? unroll(parent).reverse().map(c => c.component) : []
|
||||||
// if (!component.virtual) {
|
// if (!component.virtual) {
|
||||||
// const path = [...parentList, component.name].join(' > ')
|
// const path = [...parentList, component.name].join(' > ')
|
||||||
@ -367,18 +374,36 @@ export const init = (extraRuleset, palette) => {
|
|||||||
|
|
||||||
// Optimization: we only really need combinations without "normal" because all states implicitly have it
|
// Optimization: we only really need combinations without "normal" because all states implicitly have it
|
||||||
const permutationStateKeys = Object.keys(states).filter(s => s !== 'normal')
|
const permutationStateKeys = Object.keys(states).filter(s => s !== 'normal')
|
||||||
const stateCombinations = [['normal'], ...getAllPossibleCombinations(permutationStateKeys).map(combination => ['normal', ...combination])]
|
const stateCombinations = [
|
||||||
|
['normal'],
|
||||||
|
...getAllPossibleCombinations(permutationStateKeys)
|
||||||
|
.map(combination => ['normal', ...combination])
|
||||||
|
.filter(combo => {
|
||||||
|
// Optimization: filter out some hard-coded combinations that don't make sense
|
||||||
|
if (combo.indexOf('disabled') >= 0) {
|
||||||
|
return !(
|
||||||
|
combo.indexOf('hover') >= 0 ||
|
||||||
|
combo.indexOf('focused') >= 0 ||
|
||||||
|
combo.indexOf('pressed') >= 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
const stateVariantCombination = Object.keys(variants).map(variant => {
|
const stateVariantCombination = Object.keys(variants).map(variant => {
|
||||||
return stateCombinations.map(state => ({ variant, state }))
|
return stateCombinations.map(state => ({ variant, state }))
|
||||||
}).reduce((acc, x) => [...acc, ...x], [])
|
}).reduce((acc, x) => [...acc, ...x], [])
|
||||||
|
|
||||||
stateVariantCombination.forEach(combination => {
|
stateVariantCombination.forEach(combination => {
|
||||||
|
counter++
|
||||||
// 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)
|
|
||||||
|
|
||||||
const lowerLevelSelector = selector.split(/ /g).slice(0, -1).join(' ')
|
combination.component = component.name
|
||||||
|
const soloSelector = ruleToSelector(combination, true)
|
||||||
|
const selector = [parentSelector, soloSelector].filter(x => x).join(' ')
|
||||||
|
|
||||||
|
const lowerLevelSelector = parentSelector
|
||||||
const lowerLevelBackground = computed[lowerLevelSelector]?.background
|
const lowerLevelBackground = computed[lowerLevelSelector]?.background
|
||||||
const lowerLevelVirtualDirectives = computed[lowerLevelSelector]?.virtualDirectives
|
const lowerLevelVirtualDirectives = computed[lowerLevelSelector]?.virtualDirectives
|
||||||
const lowerLevelVirtualDirectivesRaw = computed[lowerLevelSelector]?.virtualDirectivesRaw
|
const lowerLevelVirtualDirectivesRaw = computed[lowerLevelSelector]?.virtualDirectivesRaw
|
||||||
@ -489,10 +514,7 @@ export const init = (extraRuleset, palette) => {
|
|||||||
// TODO: DEFAULT TEXT COLOR
|
// TODO: DEFAULT TEXT COLOR
|
||||||
const lowerLevelComputedBackground = computed[lowerLevelSelector]?.background || convert('#FFFFFF').rgb
|
const lowerLevelComputedBackground = computed[lowerLevelSelector]?.background || convert('#FFFFFF').rgb
|
||||||
|
|
||||||
if (
|
if (computedDirectives.shadow != null || computedDirectives.roundness != null) {
|
||||||
computedDirectives.shadow != null ||
|
|
||||||
computedDirectives.roundness != null
|
|
||||||
) {
|
|
||||||
addRuleNeeded = true
|
addRuleNeeded = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,7 +571,22 @@ export const init = (extraRuleset, palette) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
innerComponents.forEach(innerComponent => processInnerComponent(innerComponent, { parent, component: name, ...combination }))
|
innerComponents.forEach(innerComponent => {
|
||||||
|
if (innerComponent.lazy) {
|
||||||
|
promises.push(new Promise((resolve, reject) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
try {
|
||||||
|
processInnerComponent(innerComponent, lazyRules, { parent, component: name, ...combination })
|
||||||
|
resolve()
|
||||||
|
} catch (e) {
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
}, 0)
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
processInnerComponent(innerComponent, rules, { parent, component: name, ...combination })
|
||||||
|
}
|
||||||
|
})
|
||||||
// const tt1 = performance.now()
|
// const tt1 = performance.now()
|
||||||
// if (!component.virtual) {
|
// if (!component.virtual) {
|
||||||
// console.log('State-variant ' + combination.variant + ' : ' + combination.state.join('+') + ' procession time: ' + (tt1 - tt0) + 'ms')
|
// console.log('State-variant ' + combination.variant + ' : ' + combination.state.join('+') + ' procession time: ' + (tt1 - tt0) + 'ms')
|
||||||
@ -563,11 +600,16 @@ export const init = (extraRuleset, palette) => {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
processInnerComponent(components.Root)
|
processInnerComponent(components.Root, eagerRules)
|
||||||
|
console.log('TOTAL COMBOS: ' + counter)
|
||||||
|
const lazyExec = Promise.all(promises).then(() => {
|
||||||
|
console.log('TOTAL COMBOS: ' + counter)
|
||||||
|
}).then(() => lazyRules)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
raw: rules,
|
lazy: lazyExec,
|
||||||
css: rules.map(rule => {
|
eager: eagerRules,
|
||||||
|
css: rules => rules.map(rule => {
|
||||||
let selector = rule.selector
|
let selector = rule.selector
|
||||||
if (!selector) {
|
if (!selector) {
|
||||||
selector = 'body'
|
selector = 'body'
|
||||||
|
Loading…
Reference in New Issue
Block a user