Better Disabled buttons support. Mammal theme fixes. Implemented proper

context-aware `mod` argument - now checks lightness of "variant" color. needs
retesting tho
This commit is contained in:
Henry Jameson 2020-02-07 01:25:26 +02:00
parent e46bb94226
commit 611da13a4b
7 changed files with 89 additions and 34 deletions

View file

@ -179,7 +179,7 @@ input, textarea, .select, .input {
right: 5px; right: 5px;
height: 100%; height: 100%;
color: $fallback--text; color: $fallback--text;
color: var(--text, $fallback--text); color: var(--inputText, $fallback--text);
line-height: 28px; line-height: 28px;
z-index: 0; z-index: 0;
pointer-events: none; pointer-events: none;
@ -254,7 +254,7 @@ input, textarea, .select, .input {
display: none; display: none;
&:checked + label::before { &:checked + label::before {
color: $fallback--text; color: $fallback--text;
color: var(--text, $fallback--text); color: var(--inputText, $fallback--text);
} }
&:disabled { &:disabled {
&, &,

View file

@ -87,13 +87,13 @@ export default {
&:checked + .checkbox-indicator::before { &:checked + .checkbox-indicator::before {
color: $fallback--text; color: $fallback--text;
color: var(--text, $fallback--text); color: var(--inputText, $fallback--text);
} }
&:indeterminate + .checkbox-indicator::before { &:indeterminate + .checkbox-indicator::before {
content: ''; content: '';
color: $fallback--text; color: $fallback--text;
color: var(--text, $fallback--text); color: var(--inputText, $fallback--text);
} }
} }

View file

@ -430,6 +430,20 @@
:label="$t('settings.text')" :label="$t('settings.text')"
/> />
<ContrastRatio :contrast="previewContrast.btnText" /> <ContrastRatio :contrast="previewContrast.btnText" />
<ColorInput
v-model="btnPanelTextColorLocal"
name="btnPanelTextColor"
:fallback="previewTheme.colors.btnPanelText"
:label="$t('settings.style.advanced_colors.panel_header')"
/>
<ContrastRatio :contrast="previewContrast.btnPanelText" />
<ColorInput
v-model="btnTopBarTextColorLocal"
name="btnTopBarTextColor"
:fallback="previewTheme.colors.btnTopBarText"
:label="$t('settings.style.advanced_colors.top_bar')"
/>
<ContrastRatio :contrast="previewContrast.btnTopBarText" />
<h4>{{ $t('settings.style.advanced_colors.pressed') }}</h4> <h4>{{ $t('settings.style.advanced_colors.pressed') }}</h4>
<ColorInput <ColorInput
v-model="btnPressedColorLocal" v-model="btnPressedColorLocal"
@ -444,6 +458,20 @@
:label="$t('settings.text')" :label="$t('settings.text')"
/> />
<ContrastRatio :contrast="previewContrast.btnPressedText" /> <ContrastRatio :contrast="previewContrast.btnPressedText" />
<ColorInput
v-model="btnPressedPanelTextColorLocal"
name="btnPressedPanelTextColor"
:fallback="previewTheme.colors.btnPressedPanelText"
:label="$t('settings.style.advanced_colors.panel_header')"
/>
<ContrastRatio :contrast="previewContrast.btnPressedPanelText" />
<ColorInput
v-model="btnPressedTopBarTextColorLocal"
name="btnPressedTopBarTextColor"
:fallback="previewTheme.colors.btnPressedTopBarText"
:label="$t('settings.style.advanced_colors.top_bar')"
/>
<ContrastRatio :contrast="previewContrast.btnPressedTopBarText" />
<h4>{{ $t('settings.style.advanced_colors.disabled') }}</h4> <h4>{{ $t('settings.style.advanced_colors.disabled') }}</h4>
<ColorInput <ColorInput
v-model="btnDisabledColorLocal" v-model="btnDisabledColorLocal"
@ -458,6 +486,20 @@
:label="$t('settings.text')" :label="$t('settings.text')"
/> />
<ContrastRatio :contrast="previewContrast.btnDisabledText" /> <ContrastRatio :contrast="previewContrast.btnDisabledText" />
<ColorInput
v-model="btnDisabledPanelTextColorLocal"
name="btnDisabledPanelTextColor"
:fallback="previewTheme.colors.btnDisabledPanelText"
:label="$t('settings.style.advanced_colors.panel_header')"
/>
<ContrastRatio :contrast="previewContrast.btnDisabledPanelText" />
<ColorInput
v-model="btnDisabledTopBarTextColorLocal"
name="btnDisabledTopBarTextColor"
:fallback="previewTheme.colors.btnDisabledTopBarText"
:label="$t('settings.style.advanced_colors.top_bar')"
/>
<ContrastRatio :contrast="previewContrast.btnDisabledTopBarText" />
<h4>{{ $t('settings.style.advanced_colors.toggled') }}</h4> <h4>{{ $t('settings.style.advanced_colors.toggled') }}</h4>
<ColorInput <ColorInput
v-model="btnToggledColorLocal" v-model="btnToggledColorLocal"
@ -471,6 +513,21 @@
:fallback="previewTheme.colors.btnToggledText" :fallback="previewTheme.colors.btnToggledText"
:label="$t('settings.text')" :label="$t('settings.text')"
/> />
<ContrastRatio :contrast="previewContrast.btnToggledText" />
<ColorInput
v-model="btnToggledPanelTextColorLocal"
name="btnToggledPanelTextColor"
:fallback="previewTheme.colors.btnToggledPanelText"
:label="$t('settings.style.advanced_colors.panel_header')"
/>
<ContrastRatio :contrast="previewContrast.btnToggledPanelText" />
<ColorInput
v-model="btnToggledTopBarTextColorLocal"
name="btnToggledTopBarTextColor"
:fallback="previewTheme.colors.btnToggledTopBarText"
:label="$t('settings.style.advanced_colors.top_bar')"
/>
<ContrastRatio :contrast="previewContrast.btnToggledTopBarText" />
</div> </div>
<div class="color-item"> <div class="color-item">
<h4>{{ $t('settings.style.advanced_colors.tabs') }}</h4> <h4>{{ $t('settings.style.advanced_colors.tabs') }}</h4>

View file

@ -472,6 +472,7 @@
"selectedPost": "Selected post", "selectedPost": "Selected post",
"selectedMenu": "Selected menu item", "selectedMenu": "Selected menu item",
"disabled": "Disabled", "disabled": "Disabled",
"toggled": "Toggled",
"tabs": "Tabs" "tabs": "Tabs"
}, },
"radii": { "radii": {

View file

@ -114,10 +114,7 @@ export const generateColors = (themeData) => {
? colors2to3(themeData.colors || themeData) ? colors2to3(themeData.colors || themeData)
: themeData.colors || themeData : themeData.colors || themeData
const isLightOnDark = convert(sourceColors.bg).hsl.l < convert(sourceColors.text).hsl.l const { colors, opacity } = getColors(sourceColors, themeData.opacity || {})
const mod = isLightOnDark ? 1 : -1
const { colors, opacity } = getColors(sourceColors, themeData.opacity || {}, mod)
const htmlColors = Object.entries(colors) const htmlColors = Object.entries(colors)
.reduce((acc, [k, v]) => { .reduce((acc, [k, v]) => {
@ -381,25 +378,17 @@ export const getThemes = () => {
} }
export const colors2to3 = (colors) => { export const colors2to3 = (colors) => {
return Object.entries(colors).reduce((acc, [slotName, color]) => { return Object.entries(colors).reduce((acc, [slotName, color]) => {
const btnStates = ['', 'Pressed', 'Disabled', 'Toggled']
const btnPositions = ['', 'Panel', 'TopBar'] const btnPositions = ['', 'Panel', 'TopBar']
switch (slotName) { switch (slotName) {
case 'lightBg': case 'lightBg':
return { ...acc, highlight: color } return { ...acc, highlight: color }
case 'btn':
return {
...acc,
...btnStates.reduce((stateAcc, state) => ({ ...stateAcc, ['btn' + state]: color }), {})
}
case 'btnText': case 'btnText':
return { return {
...acc, ...acc,
...btnPositions ...btnPositions
.map(position => btnStates.map(state => state + position))
.flat()
.reduce( .reduce(
(statePositionAcc, statePosition) => (statePositionAcc, position) =>
({ ...statePositionAcc, ['btn' + statePosition + 'Text']: color }) ({ ...statePositionAcc, ['btn' + position + 'Text']: color })
, {} , {}
) )
} }

View file

@ -85,6 +85,8 @@ export const SLOT_INHERITANCE = {
}, },
text: { text: {
depends: [], depends: [],
layer: 'bg',
opacity: null,
priority: 1 priority: 1
}, },
underlay: { underlay: {
@ -422,6 +424,7 @@ export const SLOT_INHERITANCE = {
// Buttons // Buttons
btn: { btn: {
depends: ['fg'], depends: ['fg'],
variant: 'btn',
opacity: 'btn' opacity: 'btn'
}, },
btnText: { btnText: {
@ -430,20 +433,23 @@ export const SLOT_INHERITANCE = {
textColor: true textColor: true
}, },
btnPanelText: { btnPanelText: {
depends: ['panelText'], depends: ['btnText'],
layer: 'btnPanel', layer: 'btnPanel',
variant: 'btn', variant: 'btn',
textColor: true textColor: true
}, },
btnTopBarText: { btnTopBarText: {
depends: ['topBarText'], depends: ['btnText'],
layer: 'btnTopBar', layer: 'btnTopBar',
variant: 'btn', variant: 'btn',
textColor: true textColor: true
}, },
// Buttons: pressed // Buttons: pressed
btnPressed: '--btn', btnPressed: {
depends: ['btn'],
layer: 'btn'
},
btnPressedText: { btnPressedText: {
depends: ['btnText'], depends: ['btnText'],
layer: 'btn', layer: 'btn',
@ -451,7 +457,8 @@ export const SLOT_INHERITANCE = {
textColor: true textColor: true
}, },
btnPressedPanel: { btnPressedPanel: {
depends: ['btnPressed'] depends: ['btnPressed'],
layer: 'btn'
}, },
btnPressedPanelText: { btnPressedPanelText: {
depends: ['btnPanelText'], depends: ['btnPanelText'],
@ -469,6 +476,7 @@ export const SLOT_INHERITANCE = {
// Buttons: toggled // Buttons: toggled
btnToggled: { btnToggled: {
depends: ['btn'], depends: ['btn'],
layer: 'btn',
color: (mod, btn) => brightness(mod * 20, btn).rgb color: (mod, btn) => brightness(mod * 20, btn).rgb
}, },
btnToggledText: { btnToggledText: {
@ -496,25 +504,22 @@ export const SLOT_INHERITANCE = {
color: (mod, btn, bg) => alphaBlend(btn, 0.5, bg) color: (mod, btn, bg) => alphaBlend(btn, 0.5, bg)
}, },
btnDisabledText: { btnDisabledText: {
depends: ['btnText'], depends: ['btnText', 'btnDisabled'],
layer: 'btn', layer: 'btn',
variant: 'btnDisabled', variant: 'btnDisabled',
textColor: true, color: (mod, text, btn) => alphaBlend(text, 0.5, btn)
color: (mod, text) => brightness(mod * -60, text).rgb
}, },
btnDisabledPanelText: { btnDisabledPanelText: {
depends: ['btnPanelText'], depends: ['btnPanelText', 'btnDisabled'],
layer: 'btnPanel', layer: 'btnPanel',
variant: 'btnDisabled', variant: 'btnDisabled',
textColor: true, color: (mod, text, btn) => alphaBlend(text, 0.5, btn)
color: (mod, text) => brightness(mod * -60, text).rgb
}, },
btnDisabledTopBarText: { btnDisabledTopBarText: {
depends: ['btnTopBarText'], depends: ['btnTopBarText', 'btnDisabled'],
layer: 'btnTopBar', layer: 'btnTopBar',
variant: 'btnDisabled', variant: 'btnDisabled',
textColor: true, color: (mod, text, btn) => alphaBlend(text, 0.5, btn)
color: (mod, text) => brightness(mod * -60, text).rgb
}, },
// Input fields // Input fields

View file

@ -255,14 +255,17 @@ export const computeDynamicColor = (sourceColor, getColor, mod) => {
} }
/** /**
* THE function you want to use. Takes provided colors and opacities, mod * THE function you want to use. Takes provided colors and opacities
* value and uses inheritance data to figure out color needed for the slot. * value and uses inheritance data to figure out color needed for the slot.
*/ */
export const getColors = (sourceColors, sourceOpacity, mod) => SLOT_ORDERED.reduce(({ colors, opacity }, key) => { export const getColors = (sourceColors, sourceOpacity) => SLOT_ORDERED.reduce(({ colors, opacity }, key) => {
const value = SLOT_INHERITANCE[key] const value = SLOT_INHERITANCE[key]
const isObject = typeof value === 'object' const isObject = typeof value === 'object'
const isString = typeof value === 'string' const isString = typeof value === 'string'
const sourceColor = sourceColors[key] const sourceColor = sourceColors[key]
const variant = value.variant || value.layer || 'bg'
const isLightOnDark = relativeLuminance(colors[variant] || sourceColors[variant]) < 0.5
const mod = isLightOnDark ? 1 : -1
let outputColor = null let outputColor = null
if (sourceColor) { if (sourceColor) {
// Color is defined in source color // Color is defined in source color
@ -318,7 +321,7 @@ export const getColors = (sourceColors, sourceOpacity, mod) => SLOT_ORDERED.redu
opacity opacity
) )
) )
const isLightOnDark = relativeLuminance(bg) > 127 const isLightOnDark = relativeLuminance(bg) > 0.5
const mod = isLightOnDark ? 1 : -1 const mod = isLightOnDark ? 1 : -1
if (value.textColor === 'bw') { if (value.textColor === 'bw') {