mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
DEV: Introduce ColorPaletteEditor component
This commit is contained in:
@@ -0,0 +1,186 @@
|
|||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import { fn } from "@ember/helper";
|
||||||
|
import { on } from "@ember/modifier";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import concatClass from "discourse/helpers/concat-class";
|
||||||
|
import dIcon from "discourse/helpers/d-icon";
|
||||||
|
import { i18n } from "discourse-i18n";
|
||||||
|
|
||||||
|
const LIGHT = "light";
|
||||||
|
const DARK = "dark";
|
||||||
|
|
||||||
|
class Color {
|
||||||
|
@tracked lightValue;
|
||||||
|
@tracked darkValue;
|
||||||
|
|
||||||
|
constructor({ name, lightValue, darkValue }) {
|
||||||
|
this.name = name;
|
||||||
|
this.lightValue = lightValue;
|
||||||
|
this.darkValue = darkValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
get displayName() {
|
||||||
|
return this.name.replaceAll("_", " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
get description() {
|
||||||
|
return i18n(`admin.customize.colors.${this.name}.description`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const NavTab = <template>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
class={{concatClass "" (if @active "active")}}
|
||||||
|
tabindex="0"
|
||||||
|
{{on "click" @action}}
|
||||||
|
{{on "keydown" @action}}
|
||||||
|
...attributes
|
||||||
|
>
|
||||||
|
{{dIcon @icon}}
|
||||||
|
<span>{{@label}}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</template>;
|
||||||
|
|
||||||
|
const Picker = class extends Component {
|
||||||
|
@action
|
||||||
|
onInput(event) {
|
||||||
|
const color = event.target.value.replace("#", "");
|
||||||
|
if (this.args.showDark) {
|
||||||
|
this.args.color.darkValue = color;
|
||||||
|
} else {
|
||||||
|
this.args.color.lightValue = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
onChange(event) {
|
||||||
|
const color = event.target.value.replace("#", "");
|
||||||
|
if (this.args.showDark) {
|
||||||
|
this.args.onDarkChange(color);
|
||||||
|
this.args.color.darkValue = color;
|
||||||
|
} else {
|
||||||
|
this.args.color.lightValue = color;
|
||||||
|
this.args.onLightChange(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get displayedColor() {
|
||||||
|
if (this.args.showDark) {
|
||||||
|
return this.args.color.darkValue;
|
||||||
|
} else {
|
||||||
|
return this.args.color.lightValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get activeValue() {
|
||||||
|
let color;
|
||||||
|
if (this.args.showDark) {
|
||||||
|
color = this.args.color.darkValue;
|
||||||
|
} else {
|
||||||
|
color = this.args.color.lightValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (color) {
|
||||||
|
return `#${color}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input
|
||||||
|
class="color-palette-editor__input"
|
||||||
|
type="color"
|
||||||
|
value={{this.activeValue}}
|
||||||
|
{{on "input" this.onInput}}
|
||||||
|
{{on "change" this.onChange}}
|
||||||
|
/>
|
||||||
|
{{dIcon "hashtag"}}
|
||||||
|
<span
|
||||||
|
class="color-palette-editor__color-code"
|
||||||
|
>{{this.displayedColor}}</span>
|
||||||
|
</template>
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class ColorPaletteEditor extends Component {
|
||||||
|
@tracked selectedMode;
|
||||||
|
|
||||||
|
get currentMode() {
|
||||||
|
return this.selectedMode ?? this.args.initialMode ?? LIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
get lightModeActive() {
|
||||||
|
return this.currentMode === LIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
get darkModeActive() {
|
||||||
|
return this.currentMode === DARK;
|
||||||
|
}
|
||||||
|
|
||||||
|
get colors() {
|
||||||
|
return this.args.colors.map((color) => {
|
||||||
|
return new Color({
|
||||||
|
name: color.name,
|
||||||
|
lightValue: color.hex,
|
||||||
|
darkValue: color.dark_hex,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
changeMode(newMode, event) {
|
||||||
|
if (
|
||||||
|
event.type === "click" ||
|
||||||
|
(event.type === "keydown" && event.keyCode === 13)
|
||||||
|
) {
|
||||||
|
this.selectedMode = newMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="color-palette-editor">
|
||||||
|
<div class="nav-pills color-palette-editor__nav-pills">
|
||||||
|
<NavTab
|
||||||
|
@active={{this.lightModeActive}}
|
||||||
|
@action={{fn this.changeMode LIGHT}}
|
||||||
|
@icon="sun"
|
||||||
|
@label={{i18n "admin.customize.colors.editor.light"}}
|
||||||
|
class="light-tab"
|
||||||
|
/>
|
||||||
|
<NavTab
|
||||||
|
@active={{this.darkModeActive}}
|
||||||
|
@action={{fn this.changeMode DARK}}
|
||||||
|
@icon="moon"
|
||||||
|
@label={{i18n "admin.customize.colors.editor.dark"}}
|
||||||
|
class="dark-tab"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="color-palette-editor__colors-list">
|
||||||
|
{{#each this.colors as |color|}}
|
||||||
|
<div
|
||||||
|
data-color-name={{color.name}}
|
||||||
|
class="color-palette-editor__colors-item"
|
||||||
|
>
|
||||||
|
<div class="color-palette-editor__color-info">
|
||||||
|
<div class="color-palette-editor__color-description">
|
||||||
|
{{color.description}}
|
||||||
|
</div>
|
||||||
|
<div class="color-palette-editor__color-name">
|
||||||
|
{{color.displayName}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="color-palette-editor__picker">
|
||||||
|
<Picker
|
||||||
|
@color={{color}}
|
||||||
|
@showDark={{this.darkModeActive}}
|
||||||
|
@onLightChange={{fn @onLightColorChange color.name}}
|
||||||
|
@onDarkChange={{fn @onDarkColorChange color.name}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
}
|
||||||
@@ -0,0 +1,388 @@
|
|||||||
|
import { click, find, render, triggerEvent } from "@ember/test-helpers";
|
||||||
|
import { module, test } from "qunit";
|
||||||
|
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||||
|
import ColorPaletteEditor from "admin/components/color-palette-editor";
|
||||||
|
|
||||||
|
function editor() {
|
||||||
|
return {
|
||||||
|
isActiveModeLight() {
|
||||||
|
return this.lightModeNavPill().classList.contains("active");
|
||||||
|
},
|
||||||
|
|
||||||
|
isActiveModeDark() {
|
||||||
|
return this.darkModeNavPill().classList.contains("active");
|
||||||
|
},
|
||||||
|
|
||||||
|
lightModeNavPill() {
|
||||||
|
return this.navPills().querySelector(".light-tab");
|
||||||
|
},
|
||||||
|
|
||||||
|
darkModeNavPill() {
|
||||||
|
return this.navPills().querySelector(".dark-tab");
|
||||||
|
},
|
||||||
|
|
||||||
|
navPills() {
|
||||||
|
return find(".color-palette-editor__nav-pills");
|
||||||
|
},
|
||||||
|
|
||||||
|
async switchToLightTab() {
|
||||||
|
await click(this.lightModeNavPill());
|
||||||
|
},
|
||||||
|
|
||||||
|
async switchToDarkTab() {
|
||||||
|
await click(this.darkModeNavPill());
|
||||||
|
},
|
||||||
|
|
||||||
|
color(name) {
|
||||||
|
return {
|
||||||
|
container() {
|
||||||
|
return find(
|
||||||
|
`.color-palette-editor__colors-item[data-color-name="${name}"]`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
displayedValue() {
|
||||||
|
return this.container().querySelector(
|
||||||
|
".color-palette-editor__color-code"
|
||||||
|
).textContent;
|
||||||
|
},
|
||||||
|
|
||||||
|
displayName() {
|
||||||
|
return this.container()
|
||||||
|
.querySelector(".color-palette-editor__color-name")
|
||||||
|
.textContent.trim();
|
||||||
|
},
|
||||||
|
|
||||||
|
description() {
|
||||||
|
return this.container()
|
||||||
|
.querySelector(".color-palette-editor__color-description")
|
||||||
|
.textContent.trim();
|
||||||
|
},
|
||||||
|
|
||||||
|
input() {
|
||||||
|
return this.container().querySelector(".color-palette-editor__input");
|
||||||
|
},
|
||||||
|
|
||||||
|
async sendInputEvent(value) {
|
||||||
|
const input = this.input();
|
||||||
|
input.value = value;
|
||||||
|
await triggerEvent(input, "input");
|
||||||
|
},
|
||||||
|
|
||||||
|
async sendChangeEvent(value) {
|
||||||
|
const input = this.input();
|
||||||
|
input.value = value;
|
||||||
|
await triggerEvent(input, "change");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module("Integration | Component | ColorPaletteEditor", function (hooks) {
|
||||||
|
setupRenderingTest(hooks);
|
||||||
|
|
||||||
|
hooks.beforeEach(function () {
|
||||||
|
this.subject = editor();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("switching between light and dark modes", async function (assert) {
|
||||||
|
const colors = [
|
||||||
|
{
|
||||||
|
name: "primary",
|
||||||
|
hex: "aaaaaa",
|
||||||
|
dark_hex: "1e3c8a",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "header_background",
|
||||||
|
hex: "473921",
|
||||||
|
dark_hex: "f2cca9",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
await render(<template>
|
||||||
|
<ColorPaletteEditor @colors={{colors}} />
|
||||||
|
</template>);
|
||||||
|
|
||||||
|
assert.true(
|
||||||
|
this.subject.isActiveModeLight(),
|
||||||
|
"light mode tab is active by default"
|
||||||
|
);
|
||||||
|
assert.false(
|
||||||
|
this.subject.isActiveModeDark(),
|
||||||
|
"dark mode tab is not active by default"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").input().value,
|
||||||
|
"#aaaaaa",
|
||||||
|
"input for the primary color is showing the light color"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").displayedValue(),
|
||||||
|
"aaaaaa",
|
||||||
|
"displayed value for the primary color is showing the light color"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").input().value,
|
||||||
|
"#473921",
|
||||||
|
"input for the header_background color is showing the light color"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").displayedValue(),
|
||||||
|
"473921",
|
||||||
|
"displayed value for the header_background color is showing the light color"
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.subject.switchToDarkTab();
|
||||||
|
|
||||||
|
assert.false(
|
||||||
|
this.subject.isActiveModeLight(),
|
||||||
|
"light mode tab is now inactive"
|
||||||
|
);
|
||||||
|
assert.true(this.subject.isActiveModeDark(), "dark mode tab is now active");
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").input().value,
|
||||||
|
"#1e3c8a",
|
||||||
|
"input for the primary color is showing the dark color"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").displayedValue(),
|
||||||
|
"1e3c8a",
|
||||||
|
"displayed value for the primary color is showing the dark color"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").input().value,
|
||||||
|
"#f2cca9",
|
||||||
|
"input for the header_background color is showing the dark color"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").displayedValue(),
|
||||||
|
"f2cca9",
|
||||||
|
"displayed value for the header_background color is showing the dark color"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("replacing underscores in color name with spaces for display", async function (assert) {
|
||||||
|
const colors = [
|
||||||
|
{
|
||||||
|
name: "my_awesome_color",
|
||||||
|
hex: "aaaaaa",
|
||||||
|
dark_hex: "1e3c8a",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "header_background",
|
||||||
|
hex: "473921",
|
||||||
|
dark_hex: "f2cca9",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
await render(<template>
|
||||||
|
<ColorPaletteEditor @colors={{colors}} />
|
||||||
|
</template>);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("my_awesome_color").displayName(),
|
||||||
|
"my awesome color"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").displayName(),
|
||||||
|
"header background"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("modifying colors", async function (assert) {
|
||||||
|
const colors = [
|
||||||
|
{
|
||||||
|
name: "primary",
|
||||||
|
hex: "aaaaaa",
|
||||||
|
dark_hex: "1e3c8a",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "header_background",
|
||||||
|
hex: "473921",
|
||||||
|
dark_hex: "f2cca9",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const lightChanges = [];
|
||||||
|
const darkChanges = [];
|
||||||
|
|
||||||
|
const onLightColorChange = (name, value) => {
|
||||||
|
lightChanges.push([name, value]);
|
||||||
|
};
|
||||||
|
const onDarkColorChange = (name, value) => {
|
||||||
|
darkChanges.push([name, value]);
|
||||||
|
};
|
||||||
|
|
||||||
|
await render(<template>
|
||||||
|
<ColorPaletteEditor
|
||||||
|
@colors={{colors}}
|
||||||
|
@onLightColorChange={{onLightColorChange}}
|
||||||
|
@onDarkColorChange={{onDarkColorChange}}
|
||||||
|
/>
|
||||||
|
</template>);
|
||||||
|
|
||||||
|
await this.subject.color("primary").sendInputEvent("#abcdef");
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").input().value,
|
||||||
|
"#abcdef",
|
||||||
|
"the input element for the primary color changes its value for `input` events"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").displayedValue(),
|
||||||
|
"abcdef",
|
||||||
|
"displayed value for the primary color updates for `input` events"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
lightChanges.length,
|
||||||
|
0,
|
||||||
|
"light color change callbacks aren't triggered for `input` events"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
darkChanges.length,
|
||||||
|
0,
|
||||||
|
"dark color change callbacks aren't triggered for `input` events"
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.subject.color("primary").sendChangeEvent("#fedcba");
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").input().value,
|
||||||
|
"#fedcba",
|
||||||
|
"the input element for the primary color changes its value for `change` events"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").displayedValue(),
|
||||||
|
"fedcba",
|
||||||
|
"displayed value for the primary color updates for `change` events"
|
||||||
|
);
|
||||||
|
assert.deepEqual(
|
||||||
|
lightChanges,
|
||||||
|
[["primary", "fedcba"]],
|
||||||
|
"light color change callbacks are triggered for `change` eventswhen the light color changes"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
darkChanges.length,
|
||||||
|
0,
|
||||||
|
"dark color change callbacks aren't triggered for `change` events when the light color changes"
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.subject.switchToDarkTab();
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").input().value,
|
||||||
|
"#1e3c8a",
|
||||||
|
"the dark color isn't affected by the change to the light color"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").displayedValue(),
|
||||||
|
"1e3c8a",
|
||||||
|
"the dark color isn't affected by the change to the light color"
|
||||||
|
);
|
||||||
|
|
||||||
|
lightChanges.length = 0;
|
||||||
|
darkChanges.length = 0;
|
||||||
|
|
||||||
|
await this.subject.color("header_background").sendInputEvent("#776655");
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").input().value,
|
||||||
|
"#776655",
|
||||||
|
"the input element for the header_background color changes its value for `input` events"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").displayedValue(),
|
||||||
|
"776655",
|
||||||
|
"displayed value for the header_background color updates for `input` events"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
lightChanges.length,
|
||||||
|
0,
|
||||||
|
"light color change callbacks aren't triggered for `input` events"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
darkChanges.length,
|
||||||
|
0,
|
||||||
|
"dark color change callbacks aren't triggered for `input` events"
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.subject.color("header_background").sendChangeEvent("#99aaff");
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").input().value,
|
||||||
|
"#99aaff",
|
||||||
|
"the input element for the header_background color changes its value for `change` events"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").displayedValue(),
|
||||||
|
"99aaff",
|
||||||
|
"displayed value for the header_background color updates for `change` events"
|
||||||
|
);
|
||||||
|
assert.deepEqual(
|
||||||
|
darkChanges,
|
||||||
|
[["header_background", "99aaff"]],
|
||||||
|
"dark color change callbacks are triggered for `change` eventswhen the dark color changes"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
lightChanges.length,
|
||||||
|
0,
|
||||||
|
"light color change callbacks aren't triggered for `change` events when the dark color changes"
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.subject.switchToLightTab();
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").input().value,
|
||||||
|
"#fedcba",
|
||||||
|
"the light color for the primary color is remembered after switching tabs"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").displayedValue(),
|
||||||
|
"fedcba",
|
||||||
|
"the light color for the primary color is remembered after switching tabs"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").input().value,
|
||||||
|
"#473921",
|
||||||
|
"the light color for the header_background color remains unchanged"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").displayedValue(),
|
||||||
|
"473921",
|
||||||
|
"the light color for the header_background color remains unchanged"
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.subject.switchToDarkTab();
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").input().value,
|
||||||
|
"#1e3c8a",
|
||||||
|
"the dark color for the primary color remains unchanged"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("primary").displayedValue(),
|
||||||
|
"1e3c8a",
|
||||||
|
"the dark color for the primary color remains unchanged"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").input().value,
|
||||||
|
"#99aaff",
|
||||||
|
"the dark color for the header_background color is remembered after switching tabs"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
this.subject.color("header_background").displayedValue(),
|
||||||
|
"99aaff",
|
||||||
|
"the dark color for the header_background color is remembered after switching tabs"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1242,3 +1242,4 @@ a.inline-editable-field {
|
|||||||
@import "common/admin/schema_theme_setting_editor";
|
@import "common/admin/schema_theme_setting_editor";
|
||||||
@import "common/admin/customize_themes_show_schema";
|
@import "common/admin/customize_themes_show_schema";
|
||||||
@import "common/admin/admin_bulk_users_delete_modal";
|
@import "common/admin/admin_bulk_users_delete_modal";
|
||||||
|
@import "common/admin/color-palette-editor";
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
.color-palette-editor {
|
||||||
|
&__nav-pills {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
|
||||||
|
li {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
|
||||||
|
a {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__colors-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__colors-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__color-info {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__color-name {
|
||||||
|
color: var(--primary-medium);
|
||||||
|
font-size: var(--font-down-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__picker {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 5px 10px;
|
||||||
|
gap: 5px;
|
||||||
|
border: 1px solid var(--primary-low);
|
||||||
|
|
||||||
|
.d-icon-hashtag {
|
||||||
|
color: var(--primary-high);
|
||||||
|
font-size: var(--font-down-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__input {
|
||||||
|
width: 23px;
|
||||||
|
height: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__color-code {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: var(--font-up-1);
|
||||||
|
color: var(--primary-high);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -206,8 +206,7 @@ input {
|
|||||||
&[type="email"],
|
&[type="email"],
|
||||||
&[type="url"],
|
&[type="url"],
|
||||||
&[type="search"],
|
&[type="search"],
|
||||||
&[type="tel"],
|
&[type="tel"] {
|
||||||
&[type="color"] {
|
|
||||||
@include appearance-none;
|
@include appearance-none;
|
||||||
@include form-item-sizing;
|
@include form-item-sizing;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -223,6 +222,22 @@ input {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[type="color"] {
|
||||||
|
border: var(--d-input-border);
|
||||||
|
border-radius: var(--d-input-border-radius);
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&::-webkit-color-swatch-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-color-swatch {
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&[type="time"] {
|
&[type="time"] {
|
||||||
max-width: 140px;
|
max-width: 140px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,14 +22,4 @@
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
height: unset;
|
height: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset webkit/blink default style
|
|
||||||
input[type="color"]::-webkit-color-swatch-wrapper {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="color"]::-webkit-color-swatch {
|
|
||||||
border: none;
|
|
||||||
border-radius: 0; // Reset webkit specific style
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6346,6 +6346,9 @@ en:
|
|||||||
hover:
|
hover:
|
||||||
name: "hover"
|
name: "hover"
|
||||||
description: "The background-color of elements such as list-items when they are hovered on or have keyboard focus."
|
description: "The background-color of elements such as list-items when they are hovered on or have keyboard focus."
|
||||||
|
editor:
|
||||||
|
light: "Light"
|
||||||
|
dark: "Dark"
|
||||||
robots:
|
robots:
|
||||||
title: "Override your site's robots.txt file:"
|
title: "Override your site's robots.txt file:"
|
||||||
warning: "This will permanently override any related site settings."
|
warning: "This will permanently override any related site settings."
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ module SvgSprite
|
|||||||
grip-lines
|
grip-lines
|
||||||
hand-point-right
|
hand-point-right
|
||||||
handshake-angle
|
handshake-angle
|
||||||
|
hashtag
|
||||||
heart
|
heart
|
||||||
hourglass-start
|
hourglass-start
|
||||||
house
|
house
|
||||||
|
|||||||
Reference in New Issue
Block a user