@electrovir/color 1.5.3 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{color-class → data/color-class}/color-formats.d.ts +79 -3
- package/dist/{color-class → data/color-class}/color-formats.js +89 -3
- package/dist/{color-class → data/color-class}/color.d.ts +19 -6
- package/dist/{color-class → data/color-class}/color.js +31 -11
- package/dist/data/local-storage.client.d.ts +4 -0
- package/dist/data/local-storage.client.js +6 -0
- package/dist/demo/all-book-pages.js +4 -2
- package/dist/demo/vir-demo.element.js +12 -2
- package/dist/elements/vir-all-color-space-sliders.element.d.ts +1 -1
- package/dist/elements/vir-all-color-space-sliders.element.js +2 -1
- package/dist/elements/vir-all-spaces-color-picker.element.d.ts +1 -1
- package/dist/elements/vir-all-spaces-color-picker.element.js +2 -2
- package/dist/elements/vir-color-details.element.js +1 -1
- package/dist/elements/vir-color-format-sliders.element.d.ts +3 -2
- package/dist/elements/vir-color-format-sliders.element.js +8 -4
- package/dist/elements/vir-color-pair-contrast-summary.element.js +2 -2
- package/dist/elements/vir-color-pair.element.d.ts +1 -1
- package/dist/elements/vir-color-pair.element.js +3 -3
- package/dist/elements/vir-color-picker.element.d.ts +12 -6
- package/dist/elements/vir-color-picker.element.js +178 -47
- package/dist/elements/vir-color-slider.element.d.ts +2 -2
- package/dist/elements/vir-color-slider.element.js +13 -5
- package/dist/elements/vir-color-swatch.element.d.ts +1 -1
- package/dist/elements/vir-contrast-indicator.element.d.ts +1 -1
- package/dist/elements/vir-contrast-indicator.element.js +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/package.json +15 -13
- /package/dist/{color-class → data/color-class}/color-name-length.d.ts +0 -0
- /package/dist/{color-class → data/color-class}/color-name-length.js +0 -0
- /package/dist/{contrast → data/contrast}/contrast.d.ts +0 -0
- /package/dist/{contrast → data/contrast}/contrast.js +0 -0
|
@@ -26,8 +26,53 @@ export type ColorCoordinateDefinition = {
|
|
|
26
26
|
* @default 1
|
|
27
27
|
*/
|
|
28
28
|
factor?: number | undefined;
|
|
29
|
-
suffix?: string;
|
|
29
|
+
suffix?: string | undefined;
|
|
30
|
+
radix?: number | undefined;
|
|
31
|
+
radixPad?: number | undefined;
|
|
30
32
|
}>;
|
|
33
|
+
/**
|
|
34
|
+
* Color formats supported by culori conversions.
|
|
35
|
+
*
|
|
36
|
+
* @category Internal
|
|
37
|
+
*/
|
|
38
|
+
export declare enum CuloriConversionFormat {
|
|
39
|
+
a98 = "a98",
|
|
40
|
+
cubehelix = "cubehelix",
|
|
41
|
+
dlab = "dlab",
|
|
42
|
+
dlch = "dlch",
|
|
43
|
+
hsi = "hsi",
|
|
44
|
+
hsl = "hsl",
|
|
45
|
+
hsv = "hsv",
|
|
46
|
+
hwb = "hwb",
|
|
47
|
+
itp = "itp",
|
|
48
|
+
jab = "jab",
|
|
49
|
+
jch = "jch",
|
|
50
|
+
lab = "lab",
|
|
51
|
+
lab65 = "lab65",
|
|
52
|
+
lch = "lch",
|
|
53
|
+
lch65 = "lch65",
|
|
54
|
+
lchuv = "lchuv",
|
|
55
|
+
lrgb = "lrgb",
|
|
56
|
+
luv = "luv",
|
|
57
|
+
okhsl = "okhsl",
|
|
58
|
+
okhsv = "okhsv",
|
|
59
|
+
oklab = "oklab",
|
|
60
|
+
oklch = "oklch",
|
|
61
|
+
p3 = "p3",
|
|
62
|
+
prophoto = "prophoto",
|
|
63
|
+
rec2020 = "rec2020",
|
|
64
|
+
rgb = "rgb",
|
|
65
|
+
xyb = "xyb",
|
|
66
|
+
xyz50 = "xyz50",
|
|
67
|
+
xyz65 = "xyz65",
|
|
68
|
+
yiq = "yiq"
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The subset of {@link ColorFormatName} that supports color conversion (via culori).
|
|
72
|
+
*
|
|
73
|
+
* @category Internal
|
|
74
|
+
*/
|
|
75
|
+
export type SupportedConversionFormat = Extract<ColorFormatName, `${CuloriConversionFormat}`>;
|
|
31
76
|
/**
|
|
32
77
|
* All raw supported color formats.
|
|
33
78
|
*
|
|
@@ -54,6 +99,34 @@ export declare const rawColorFormats: {
|
|
|
54
99
|
};
|
|
55
100
|
readonly colorSpace: "rgb";
|
|
56
101
|
};
|
|
102
|
+
readonly hex: {
|
|
103
|
+
readonly coords: {
|
|
104
|
+
readonly r: {
|
|
105
|
+
readonly min: 0;
|
|
106
|
+
readonly max: 255;
|
|
107
|
+
readonly factor: 255;
|
|
108
|
+
readonly radix: 16;
|
|
109
|
+
readonly radixPad: 2;
|
|
110
|
+
};
|
|
111
|
+
readonly g: {
|
|
112
|
+
readonly min: 0;
|
|
113
|
+
readonly max: 255;
|
|
114
|
+
readonly factor: 255;
|
|
115
|
+
readonly radix: 16;
|
|
116
|
+
readonly radixPad: 2;
|
|
117
|
+
};
|
|
118
|
+
readonly b: {
|
|
119
|
+
readonly min: 0;
|
|
120
|
+
readonly max: 255;
|
|
121
|
+
readonly factor: 255;
|
|
122
|
+
readonly radix: 16;
|
|
123
|
+
readonly radixPad: 2;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
readonly conversionFormat: CuloriConversionFormat.rgb;
|
|
127
|
+
readonly rawSyntax: "hexString";
|
|
128
|
+
readonly colorSpace: "rgb";
|
|
129
|
+
};
|
|
57
130
|
readonly hsl: {
|
|
58
131
|
readonly coords: {
|
|
59
132
|
readonly h: {
|
|
@@ -187,15 +260,16 @@ export declare const ColorFormatName: { [Key in ColorFormatName]: Key; };
|
|
|
187
260
|
* @enum
|
|
188
261
|
*/
|
|
189
262
|
export declare const ColorSyntaxName: {
|
|
190
|
-
readonly hex: "hex";
|
|
191
263
|
readonly name: "name";
|
|
192
|
-
readonly
|
|
264
|
+
readonly hexString: "hexString";
|
|
193
265
|
readonly hsl: "hsl";
|
|
194
266
|
readonly hwb: "hwb";
|
|
195
267
|
readonly lab: "lab";
|
|
196
268
|
readonly lch: "lch";
|
|
197
269
|
readonly oklab: "oklab";
|
|
198
270
|
readonly oklch: "oklch";
|
|
271
|
+
readonly rgb: "rgb";
|
|
272
|
+
readonly hex: "hex";
|
|
199
273
|
};
|
|
200
274
|
export type ColorSyntaxName = Values<typeof ColorSyntaxName>;
|
|
201
275
|
/**
|
|
@@ -281,4 +355,6 @@ export type ColorFormatDefinition<ColorSpace extends ColorSpaceName = any, Color
|
|
|
281
355
|
/** This name for this color to be used in `Colorjs.to()`. Defaults to the color format key. */
|
|
282
356
|
colorSpace: ColorSpace;
|
|
283
357
|
colorFormat: ColorFormat;
|
|
358
|
+
conversionFormat: SupportedConversionFormat;
|
|
359
|
+
rawSyntax: ColorSyntaxName;
|
|
284
360
|
};
|
|
@@ -1,4 +1,43 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { assert, assertWrap, check } from '@augment-vir/assert';
|
|
2
|
+
import { arrayToObject, getObjectTypedEntries, getObjectTypedValues, getOrSet, mapObjectValues, stringify, } from '@augment-vir/common';
|
|
3
|
+
/**
|
|
4
|
+
* Color formats supported by culori conversions.
|
|
5
|
+
*
|
|
6
|
+
* @category Internal
|
|
7
|
+
*/
|
|
8
|
+
export var CuloriConversionFormat;
|
|
9
|
+
(function (CuloriConversionFormat) {
|
|
10
|
+
CuloriConversionFormat["a98"] = "a98";
|
|
11
|
+
CuloriConversionFormat["cubehelix"] = "cubehelix";
|
|
12
|
+
CuloriConversionFormat["dlab"] = "dlab";
|
|
13
|
+
CuloriConversionFormat["dlch"] = "dlch";
|
|
14
|
+
CuloriConversionFormat["hsi"] = "hsi";
|
|
15
|
+
CuloriConversionFormat["hsl"] = "hsl";
|
|
16
|
+
CuloriConversionFormat["hsv"] = "hsv";
|
|
17
|
+
CuloriConversionFormat["hwb"] = "hwb";
|
|
18
|
+
CuloriConversionFormat["itp"] = "itp";
|
|
19
|
+
CuloriConversionFormat["jab"] = "jab";
|
|
20
|
+
CuloriConversionFormat["jch"] = "jch";
|
|
21
|
+
CuloriConversionFormat["lab"] = "lab";
|
|
22
|
+
CuloriConversionFormat["lab65"] = "lab65";
|
|
23
|
+
CuloriConversionFormat["lch"] = "lch";
|
|
24
|
+
CuloriConversionFormat["lch65"] = "lch65";
|
|
25
|
+
CuloriConversionFormat["lchuv"] = "lchuv";
|
|
26
|
+
CuloriConversionFormat["lrgb"] = "lrgb";
|
|
27
|
+
CuloriConversionFormat["luv"] = "luv";
|
|
28
|
+
CuloriConversionFormat["okhsl"] = "okhsl";
|
|
29
|
+
CuloriConversionFormat["okhsv"] = "okhsv";
|
|
30
|
+
CuloriConversionFormat["oklab"] = "oklab";
|
|
31
|
+
CuloriConversionFormat["oklch"] = "oklch";
|
|
32
|
+
CuloriConversionFormat["p3"] = "p3";
|
|
33
|
+
CuloriConversionFormat["prophoto"] = "prophoto";
|
|
34
|
+
CuloriConversionFormat["rec2020"] = "rec2020";
|
|
35
|
+
CuloriConversionFormat["rgb"] = "rgb";
|
|
36
|
+
CuloriConversionFormat["xyb"] = "xyb";
|
|
37
|
+
CuloriConversionFormat["xyz50"] = "xyz50";
|
|
38
|
+
CuloriConversionFormat["xyz65"] = "xyz65";
|
|
39
|
+
CuloriConversionFormat["yiq"] = "yiq";
|
|
40
|
+
})(CuloriConversionFormat || (CuloriConversionFormat = {}));
|
|
2
41
|
/**
|
|
3
42
|
* All raw supported color formats.
|
|
4
43
|
*
|
|
@@ -25,6 +64,34 @@ export const rawColorFormats = {
|
|
|
25
64
|
},
|
|
26
65
|
colorSpace: 'rgb',
|
|
27
66
|
},
|
|
67
|
+
hex: {
|
|
68
|
+
coords: {
|
|
69
|
+
r: {
|
|
70
|
+
min: 0,
|
|
71
|
+
max: 255,
|
|
72
|
+
factor: 255,
|
|
73
|
+
radix: 16,
|
|
74
|
+
radixPad: 2,
|
|
75
|
+
},
|
|
76
|
+
g: {
|
|
77
|
+
min: 0,
|
|
78
|
+
max: 255,
|
|
79
|
+
factor: 255,
|
|
80
|
+
radix: 16,
|
|
81
|
+
radixPad: 2,
|
|
82
|
+
},
|
|
83
|
+
b: {
|
|
84
|
+
min: 0,
|
|
85
|
+
max: 255,
|
|
86
|
+
factor: 255,
|
|
87
|
+
radix: 16,
|
|
88
|
+
radixPad: 2,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
conversionFormat: CuloriConversionFormat.rgb,
|
|
92
|
+
rawSyntax: 'hexString',
|
|
93
|
+
colorSpace: 'rgb',
|
|
94
|
+
},
|
|
28
95
|
hsl: {
|
|
29
96
|
coords: {
|
|
30
97
|
h: {
|
|
@@ -159,8 +226,8 @@ export const ColorFormatName = mapObjectValues(rawColorFormats, (colorName) => c
|
|
|
159
226
|
*/
|
|
160
227
|
export const ColorSyntaxName = {
|
|
161
228
|
...ColorFormatName,
|
|
162
|
-
hex: 'hex',
|
|
163
229
|
name: 'name',
|
|
230
|
+
hexString: 'hexString',
|
|
164
231
|
};
|
|
165
232
|
/**
|
|
166
233
|
* All supported color formats.
|
|
@@ -168,10 +235,29 @@ export const ColorSyntaxName = {
|
|
|
168
235
|
* @category Color Format
|
|
169
236
|
*/
|
|
170
237
|
export const colorFormats = mapObjectValues(rawColorFormats, (colorFormatName, colorFormatValue) => {
|
|
238
|
+
/* node:coverage disable */
|
|
239
|
+
const conversionFormat = check.isEnumValue(colorFormatName, CuloriConversionFormat) &&
|
|
240
|
+
check.isEnumValue(colorFormatName, ColorFormatName)
|
|
241
|
+
? colorFormatName
|
|
242
|
+
: // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
243
|
+
'conversionFormat' in colorFormatValue && colorFormatValue.conversionFormat
|
|
244
|
+
? check.isEnumValue(colorFormatValue.conversionFormat, CuloriConversionFormat) &&
|
|
245
|
+
check.isEnumValue(colorFormatValue.conversionFormat, ColorFormatName)
|
|
246
|
+
? colorFormatValue.conversionFormat
|
|
247
|
+
: undefined
|
|
248
|
+
: undefined;
|
|
249
|
+
assert.isTruthy(conversionFormat, `Invalid conversion format for color format '${colorFormatName}' ${stringify(colorFormatValue)}.`);
|
|
171
250
|
return {
|
|
172
251
|
...colorFormatValue,
|
|
173
252
|
colorFormat: colorFormatName,
|
|
253
|
+
conversionFormat,
|
|
254
|
+
rawSyntax: assertWrap.isEnumValue(
|
|
255
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
256
|
+
'rawSyntax' in colorFormatValue && colorFormatValue.rawSyntax
|
|
257
|
+
? colorFormatValue.rawSyntax
|
|
258
|
+
: colorFormatName, ColorSyntaxName),
|
|
174
259
|
};
|
|
260
|
+
/* node:coverage enable */
|
|
175
261
|
});
|
|
176
262
|
/**
|
|
177
263
|
* All supported color space names.
|
|
@@ -226,7 +312,7 @@ export function getColorSyntaxFromCssString(cssString) {
|
|
|
226
312
|
return ColorSyntaxName.lch;
|
|
227
313
|
}
|
|
228
314
|
else if (cssString.startsWith('#')) {
|
|
229
|
-
return ColorSyntaxName.
|
|
315
|
+
return ColorSyntaxName.hexString;
|
|
230
316
|
}
|
|
231
317
|
else {
|
|
232
318
|
return ColorSyntaxName.name;
|
|
@@ -9,7 +9,7 @@ import { ColorFormatName, ColorSyntaxName, type ColorCoordsByFormat, type ColorV
|
|
|
9
9
|
export type ColorUpdate = RequireExactlyOne<{
|
|
10
10
|
[FormatName in ColorFormatName]: PartialWithUndefined<Record<ColorCoordsByFormat[FormatName], number>>;
|
|
11
11
|
} & {
|
|
12
|
-
[ColorSyntaxName.
|
|
12
|
+
[ColorSyntaxName.hexString]: HexColor;
|
|
13
13
|
[ColorSyntaxName.name]: string;
|
|
14
14
|
}>;
|
|
15
15
|
/**
|
|
@@ -19,7 +19,7 @@ export type ColorUpdate = RequireExactlyOne<{
|
|
|
19
19
|
* @category Internal
|
|
20
20
|
*/
|
|
21
21
|
export type AllColorsValues = ColorValue & {
|
|
22
|
-
|
|
22
|
+
hexString: HexColor;
|
|
23
23
|
[ColorSyntaxName.name]: string;
|
|
24
24
|
names: string[];
|
|
25
25
|
};
|
|
@@ -47,13 +47,15 @@ export declare class Color {
|
|
|
47
47
|
constructor(
|
|
48
48
|
/** Any valid CSS color string or an object of color coordinate values. */
|
|
49
49
|
initValue: string | Readonly<ColorUpdate>);
|
|
50
|
+
/** Checks if the input string can be converted into a color. */
|
|
51
|
+
static isValidColorString(this: void, value: string): boolean;
|
|
50
52
|
/** Checks, with a type guard, that a given input is a Color class instance. */
|
|
51
|
-
static isColor<T>(value: T): value is Extract<T, Readonly<Color>>;
|
|
53
|
+
static isColor<T>(this: void, value: T): value is Extract<T, Readonly<Color>>;
|
|
52
54
|
/**
|
|
53
55
|
* Create a new {@link Color} instance by parsing the output of another instance's
|
|
54
56
|
* {@link Color.serialize} method.
|
|
55
57
|
*/
|
|
56
|
-
static deserialize(input: string): Color;
|
|
58
|
+
static deserialize(this: void, input: string): Color;
|
|
57
59
|
/**
|
|
58
60
|
* Converts the color class to a CSS string format in the color space and format that it was
|
|
59
61
|
* originally set with.
|
|
@@ -65,7 +67,12 @@ export declare class Color {
|
|
|
65
67
|
protected readonly _allColors: {
|
|
66
68
|
names: string[];
|
|
67
69
|
name: string;
|
|
68
|
-
|
|
70
|
+
hexString: HexColor;
|
|
71
|
+
hex: {
|
|
72
|
+
r: number;
|
|
73
|
+
g: number;
|
|
74
|
+
b: number;
|
|
75
|
+
};
|
|
69
76
|
rgb: {
|
|
70
77
|
r: number;
|
|
71
78
|
g: number;
|
|
@@ -153,7 +160,13 @@ export declare class Color {
|
|
|
153
160
|
*/
|
|
154
161
|
get name(): string;
|
|
155
162
|
/** The current color expressed as an RGB hex string. */
|
|
156
|
-
get
|
|
163
|
+
get hexString(): `#${string}`;
|
|
164
|
+
/** The current color expressed as an RGB hex coordinates. */
|
|
165
|
+
get hex(): {
|
|
166
|
+
r: number;
|
|
167
|
+
g: number;
|
|
168
|
+
b: number;
|
|
169
|
+
};
|
|
157
170
|
/** The current color expressed as its RGB coordinate values. */
|
|
158
171
|
get rgb(): {
|
|
159
172
|
r: number;
|
|
@@ -21,6 +21,16 @@ export class Color {
|
|
|
21
21
|
initValue) {
|
|
22
22
|
this.set(initValue);
|
|
23
23
|
}
|
|
24
|
+
/** Checks if the input string can be converted into a color. */
|
|
25
|
+
static isValidColorString(value) {
|
|
26
|
+
try {
|
|
27
|
+
new Color(value);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
24
34
|
/** Checks, with a type guard, that a given input is a Color class instance. */
|
|
25
35
|
static isColor(value) {
|
|
26
36
|
return value instanceof Color;
|
|
@@ -56,7 +66,12 @@ export class Color {
|
|
|
56
66
|
_allColors = {
|
|
57
67
|
names: ['black'],
|
|
58
68
|
[ColorSyntaxName.name]: 'black',
|
|
59
|
-
|
|
69
|
+
hexString: '#000000',
|
|
70
|
+
[ColorSyntaxName.hex]: {
|
|
71
|
+
r: 0,
|
|
72
|
+
g: 0,
|
|
73
|
+
b: 0,
|
|
74
|
+
},
|
|
60
75
|
[ColorSyntaxName.rgb]: {
|
|
61
76
|
r: 0,
|
|
62
77
|
g: 0,
|
|
@@ -121,8 +136,8 @@ export class Color {
|
|
|
121
136
|
return this.setByString(newValue);
|
|
122
137
|
}
|
|
123
138
|
assert.isLengthExactly(Object.keys(newValue), 1, `Cannot set multiple color formats at once: got '${joinWithFinalConjunction(Object.keys(newValue))}'`);
|
|
124
|
-
if (newValue.
|
|
125
|
-
this.setByString(newValue.
|
|
139
|
+
if (newValue.hexString || newValue.name) {
|
|
140
|
+
this.setByString(newValue.hexString || newValue.name);
|
|
126
141
|
}
|
|
127
142
|
else {
|
|
128
143
|
const [colorFormatName, colorValues,] = assertWrap.isDefined(getObjectTypedEntries(newValue)[0]);
|
|
@@ -137,7 +152,7 @@ export class Color {
|
|
|
137
152
|
: this[colorFormatName][coordName];
|
|
138
153
|
return assertWrap.isDefined(rawCoordValue);
|
|
139
154
|
}));
|
|
140
|
-
this.setByString(`${
|
|
155
|
+
this.setByString(`${colorFormatDefinition.conversionFormat}(${orderedColorCoords.join(' ')})`);
|
|
141
156
|
}
|
|
142
157
|
}
|
|
143
158
|
/**
|
|
@@ -147,12 +162,13 @@ export class Color {
|
|
|
147
162
|
pullFromInternalColor() {
|
|
148
163
|
getEnumValues(ColorFormatName).forEach((colorFormatName) => {
|
|
149
164
|
const colorFormatDefinition = colorFormats[colorFormatName];
|
|
165
|
+
const mappedColorFormatName = colorFormatDefinition.conversionFormat;
|
|
150
166
|
const originalColorDefinition = check.isKeyOf(this.#internalColor.mode, colorFormats)
|
|
151
167
|
? colorFormats[this.#internalColor.mode]
|
|
152
168
|
: undefined;
|
|
153
169
|
const converted = clampGamut(colorFormatDefinition.colorSpace === originalColorDefinition?.colorSpace
|
|
154
|
-
?
|
|
155
|
-
: 'rgb')(converter(
|
|
170
|
+
? mappedColorFormatName
|
|
171
|
+
: 'rgb')(converter(mappedColorFormatName)(this.#internalColor));
|
|
156
172
|
/* node:coverage ignore next 5: technically this shouldn't happen, idk how to manually trigger it. */
|
|
157
173
|
if (!converted) {
|
|
158
174
|
assert.never(`Failed to convert color '${JSON.stringify(this.#internalColor)}' to '${colorFormatName}'.`);
|
|
@@ -167,7 +183,7 @@ export class Color {
|
|
|
167
183
|
}
|
|
168
184
|
});
|
|
169
185
|
});
|
|
170
|
-
this._allColors
|
|
186
|
+
this._allColors.hexString = formatHex(this.#internalColor);
|
|
171
187
|
this._allColors.names = findMatchingColorNames(this.rgb);
|
|
172
188
|
this._allColors[ColorSyntaxName.name] = this._allColors.names[0] || '';
|
|
173
189
|
}
|
|
@@ -197,10 +213,10 @@ export class Color {
|
|
|
197
213
|
return coordValues.map((coordValue) => String(coordValue).padStart(6, ' ')).join(' ');
|
|
198
214
|
});
|
|
199
215
|
return {
|
|
200
|
-
[ColorSyntaxName.hex]: this.hex,
|
|
201
216
|
...colorFormatStrings,
|
|
202
217
|
names: this.names.join(', ').padEnd(maxColorNameLength, ' '),
|
|
203
|
-
name: (this.names[0] || '').padEnd(maxColorNameLength, ' '),
|
|
218
|
+
[ColorSyntaxName.name]: (this.names[0] || '').padEnd(maxColorNameLength, ' '),
|
|
219
|
+
[ColorSyntaxName.hexString]: this[ColorSyntaxName.hexString],
|
|
204
220
|
};
|
|
205
221
|
}
|
|
206
222
|
/**
|
|
@@ -215,9 +231,9 @@ export class Color {
|
|
|
215
231
|
return `${colorFormatName}(${coordValues.join(' ')})`;
|
|
216
232
|
});
|
|
217
233
|
return {
|
|
218
|
-
[ColorSyntaxName.hex]: this.hex,
|
|
219
234
|
...colorFormatStrings,
|
|
220
|
-
|
|
235
|
+
[ColorSyntaxName.hexString]: this[ColorSyntaxName.hexString],
|
|
236
|
+
[ColorSyntaxName.name]: this.names[0] || '',
|
|
221
237
|
};
|
|
222
238
|
}
|
|
223
239
|
/**
|
|
@@ -235,6 +251,10 @@ export class Color {
|
|
|
235
251
|
return this._allColors.names[0] || '';
|
|
236
252
|
}
|
|
237
253
|
/** The current color expressed as an RGB hex string. */
|
|
254
|
+
get hexString() {
|
|
255
|
+
return this._allColors[ColorSyntaxName.hexString];
|
|
256
|
+
}
|
|
257
|
+
/** The current color expressed as an RGB hex coordinates. */
|
|
238
258
|
get hex() {
|
|
239
259
|
return copyThroughJson(this._allColors[ColorSyntaxName.hex]);
|
|
240
260
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { LocalStorageClient } from '@electrovir/local-storage-client';
|
|
2
|
+
export declare const colorLocalStorageClient: LocalStorageClient<{
|
|
3
|
+
lastFormat: import("object-shape-tester").Shape<import("@sinclair/typebox").TUnion<(import("@sinclair/typebox").TLiteral<"hsl"> | import("@sinclair/typebox").TLiteral<"hwb"> | import("@sinclair/typebox").TLiteral<"lab"> | import("@sinclair/typebox").TLiteral<"lch"> | import("@sinclair/typebox").TLiteral<"oklab"> | import("@sinclair/typebox").TLiteral<"oklch"> | import("@sinclair/typebox").TLiteral<"rgb"> | import("@sinclair/typebox").TLiteral<"hex">)[]>>;
|
|
4
|
+
}>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { LocalStorageClient } from '@electrovir/local-storage-client';
|
|
2
|
+
import { enumShape } from 'object-shape-tester';
|
|
3
|
+
import { ColorFormatName } from './color-class/color-formats.js';
|
|
4
|
+
export const colorLocalStorageClient = new LocalStorageClient({
|
|
5
|
+
lastFormat: enumShape(ColorFormatName),
|
|
6
|
+
});
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { virColorPickerBookPage } from '
|
|
1
|
+
import { virAllColorSpaceSlidersBookPage } from '../elements/vir-all-color-space-sliders.element.book.js';
|
|
2
|
+
import { virColorPickerBookPage } from '../elements/vir-color-picker.element.book.js';
|
|
3
|
+
import { colorExamplesPage } from './color-examples.book.js';
|
|
3
4
|
import { elementsBookPage, examplesBookPage } from './top-level-pages.js';
|
|
4
5
|
export const allBookPages = [
|
|
5
6
|
elementsBookPage,
|
|
6
7
|
examplesBookPage,
|
|
7
8
|
colorExamplesPage,
|
|
9
|
+
virAllColorSpaceSlidersBookPage,
|
|
8
10
|
virColorPickerBookPage,
|
|
9
11
|
];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* node:coverage disable */
|
|
2
|
-
import { ElementBookApp } from 'element-book';
|
|
2
|
+
import { ElementBookApp, ElementBookSlotName } from 'element-book';
|
|
3
3
|
import { css, defineElement, html } from 'element-vir';
|
|
4
|
+
import { noNativeSpacing } from 'vira';
|
|
4
5
|
import { allBookPages } from './all-book-pages.js';
|
|
5
6
|
export const VirDemo = defineElement()({
|
|
6
7
|
tagName: 'vir-demo',
|
|
@@ -18,6 +19,13 @@ export const VirDemo = defineElement()({
|
|
|
18
19
|
max-width: 100%;
|
|
19
20
|
box-sizing: border-box;
|
|
20
21
|
}
|
|
22
|
+
|
|
23
|
+
h1 {
|
|
24
|
+
${noNativeSpacing};
|
|
25
|
+
font-size: 16px;
|
|
26
|
+
margin-bottom: 16px;
|
|
27
|
+
text-align: center;
|
|
28
|
+
}
|
|
21
29
|
`,
|
|
22
30
|
render() {
|
|
23
31
|
return html `
|
|
@@ -27,7 +35,9 @@ export const VirDemo = defineElement()({
|
|
|
27
35
|
useInternalRouter: true,
|
|
28
36
|
basePath: 'color',
|
|
29
37
|
},
|
|
30
|
-
})}
|
|
38
|
+
})}>
|
|
39
|
+
<h1 slot=${ElementBookSlotName.NavHeader}>@electrovir/color</h1>
|
|
40
|
+
</${ElementBookApp}>
|
|
31
41
|
`;
|
|
32
42
|
},
|
|
33
43
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* node:coverage disable */
|
|
2
2
|
import { getObjectTypedKeys, getObjectTypedValues } from '@augment-vir/common';
|
|
3
3
|
import { css, defineElement, defineElementEvent, html, listen } from 'element-vir';
|
|
4
|
-
import { colorFormatsBySpace } from '../color-class/color-formats.js';
|
|
4
|
+
import { colorFormatsBySpace } from '../data/color-class/color-formats.js';
|
|
5
5
|
import { VirColorFormatSliders } from './vir-color-format-sliders.element.js';
|
|
6
6
|
/**
|
|
7
7
|
* Color sliders for all color spaces.
|
|
@@ -34,6 +34,7 @@ export const VirAllColorSpaceSliders = defineElement()({
|
|
|
34
34
|
<${VirColorFormatSliders.assign({
|
|
35
35
|
color: inputs.color,
|
|
36
36
|
colorFormatName,
|
|
37
|
+
showFormatName: true,
|
|
37
38
|
})}
|
|
38
39
|
${listen(VirColorFormatSliders.events.colorChange, (event) => {
|
|
39
40
|
dispatch(new events.colorChange(event.detail));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ColorSyntaxName } from '../color-class/color-formats.js';
|
|
1
|
+
import { type ColorSyntaxName } from '../data/color-class/color-formats.js';
|
|
2
2
|
/**
|
|
3
3
|
* A color picker element that shows sliders for all supported color spaces at once, as well as all
|
|
4
4
|
* the values for all supported color spaces in a table.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* node:coverage disable */
|
|
2
2
|
import { css, defineElement, defineElementEvent, html, listen } from 'element-vir';
|
|
3
|
-
import { getColorSyntaxFromCssString } from '../color-class/color-formats.js';
|
|
4
|
-
import { Color } from '../color-class/color.js';
|
|
3
|
+
import { getColorSyntaxFromCssString, } from '../data/color-class/color-formats.js';
|
|
4
|
+
import { Color } from '../data/color-class/color.js';
|
|
5
5
|
import { VirAllColorSpaceSliders } from './vir-all-color-space-sliders.element.js';
|
|
6
6
|
import { VirColorDetails } from './vir-color-details.element.js';
|
|
7
7
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { getObjectTypedEntries, omitObjectKeys } from '@augment-vir/common';
|
|
3
3
|
import { css, defineElement, defineElementEvent, html, listen } from 'element-vir';
|
|
4
4
|
import { defineTable, noNativeSpacing, viraFontCssVars, ViraInput } from 'vira';
|
|
5
|
-
import { Color } from '../color-class/color.js';
|
|
5
|
+
import { Color } from '../data/color-class/color.js';
|
|
6
6
|
import { VirColorSwatch } from './vir-color-swatch.element.js';
|
|
7
7
|
/**
|
|
8
8
|
* A color swatch alongside the color in all of its different supported formats.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type ColorFormatName } from '../color-class/color-formats.js';
|
|
2
|
-
import { type Color } from '../color-class/color.js';
|
|
1
|
+
import { type ColorFormatName } from '../data/color-class/color-formats.js';
|
|
2
|
+
import { type Color } from '../data/color-class/color.js';
|
|
3
3
|
/**
|
|
4
4
|
* Color sliders for all coordinates within a specific color format.
|
|
5
5
|
*
|
|
@@ -8,6 +8,7 @@ import { type Color } from '../color-class/color.js';
|
|
|
8
8
|
export declare const VirColorFormatSliders: import("element-vir").DeclarativeElementDefinition<"vir-color-format-sliders", {
|
|
9
9
|
color: Readonly<Color>;
|
|
10
10
|
colorFormatName: ColorFormatName;
|
|
11
|
+
showFormatName: boolean;
|
|
11
12
|
}, {}, {
|
|
12
13
|
colorChange: import("element-vir").DefineEvent<string>;
|
|
13
14
|
}, "vir-color-format-sliders-", "vir-color-format-sliders-", readonly [], readonly []>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* node:coverage disable */
|
|
2
2
|
import { getObjectTypedKeys } from '@augment-vir/common';
|
|
3
|
-
import { css, defineElement, defineElementEvent, html, listen } from 'element-vir';
|
|
3
|
+
import { css, defineElement, defineElementEvent, html, listen, nothing } from 'element-vir';
|
|
4
4
|
import { noNativeSpacing } from 'vira';
|
|
5
|
-
import { colorFormats, } from '../color-class/color-formats.js';
|
|
5
|
+
import { colorFormats, } from '../data/color-class/color-formats.js';
|
|
6
6
|
import { VirColorSlider } from './vir-color-slider.element.js';
|
|
7
7
|
/**
|
|
8
8
|
* Color sliders for all coordinates within a specific color format.
|
|
@@ -40,14 +40,18 @@ export const VirColorFormatSliders = defineElement()({
|
|
|
40
40
|
[colorCoordinate]: event.detail,
|
|
41
41
|
},
|
|
42
42
|
});
|
|
43
|
-
const newValue = newColor.toCss()[
|
|
43
|
+
const newValue = newColor.toCss()[colorFormat.conversionFormat];
|
|
44
44
|
dispatch(new events.colorChange(newValue));
|
|
45
45
|
})}
|
|
46
46
|
></${VirColorSlider}>
|
|
47
47
|
`;
|
|
48
48
|
});
|
|
49
49
|
return html `
|
|
50
|
-
|
|
50
|
+
${inputs.showFormatName
|
|
51
|
+
? html `
|
|
52
|
+
<h3>${inputs.colorFormatName}</h3>
|
|
53
|
+
`
|
|
54
|
+
: nothing}
|
|
51
55
|
${coordinateTemplates}
|
|
52
56
|
`;
|
|
53
57
|
},
|
|
@@ -3,8 +3,8 @@ import { assertWrap } from '@augment-vir/assert';
|
|
|
3
3
|
import { getObjectTypedEntries, round } from '@augment-vir/common';
|
|
4
4
|
import { classMap, css, defineElement, html, unsafeCSS } from 'element-vir';
|
|
5
5
|
import { defineTable, noNativeSpacing, ViraBoldText, viraFontCssVars } from 'vira';
|
|
6
|
-
import { Color } from '../color-class/color.js';
|
|
7
|
-
import { calculateContrast, calculateFontSizes, contrastLevelLabel, contrastLevels, fontWeightByName, } from '../contrast/contrast.js';
|
|
6
|
+
import { Color } from '../data/color-class/color.js';
|
|
7
|
+
import { calculateContrast, calculateFontSizes, contrastLevelLabel, contrastLevels, fontWeightByName, } from '../data/contrast/contrast.js';
|
|
8
8
|
import { VirColorSwatch } from './vir-color-swatch.element.js';
|
|
9
9
|
import { VirContrastIndicator } from './vir-contrast-indicator.element.js';
|
|
10
10
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* node:coverage disable */
|
|
2
2
|
import { assertWrap, check } from '@augment-vir/assert';
|
|
3
3
|
import { css, defineElement, html, listen, nothing, onDomCreated, unsafeCSS } from 'element-vir';
|
|
4
|
-
import { noNativeFormStyles, noNativeSpacing } from 'vira';
|
|
5
|
-
import { calculateContrast } from '../contrast/contrast.js';
|
|
4
|
+
import { noNativeFormStyles, noNativeSpacing, viraFontCssVars } from 'vira';
|
|
5
|
+
import { calculateContrast } from '../data/contrast/contrast.js';
|
|
6
6
|
import { VirContrastIndicator } from './vir-contrast-indicator.element.js';
|
|
7
7
|
/**
|
|
8
8
|
* Showcase a foreground/backend color pair.
|
|
@@ -85,7 +85,7 @@ export const VirColorPair = defineElement()({
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
.css-var-names {
|
|
88
|
-
font-family: monospace;
|
|
88
|
+
font-family: ${viraFontCssVars['vira-monospace'].value};
|
|
89
89
|
display: flex;
|
|
90
90
|
max-width: 100%;
|
|
91
91
|
flex-direction: column;
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { Color } from '../color-class/color.js';
|
|
1
|
+
import { type PartialWithUndefined } from '@augment-vir/common';
|
|
2
|
+
import { Color } from '../data/color-class/color.js';
|
|
3
3
|
/**
|
|
4
4
|
* A color picker element with a swatch that opens a popup with color format sliders.
|
|
5
5
|
*
|
|
6
|
+
* Set the width and height of the swatch using the provided CSS variables.
|
|
7
|
+
*
|
|
6
8
|
* @category Elements
|
|
7
9
|
*/
|
|
8
|
-
export declare const VirColorPicker: import("element-vir").DeclarativeElementDefinition<"vir-color-picker", {
|
|
10
|
+
export declare const VirColorPicker: import("element-vir").DeclarativeElementDefinition<"vir-color-picker", Readonly<{
|
|
9
11
|
color: string | Readonly<Color> | undefined;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
+
} & PartialWithUndefined<{
|
|
13
|
+
alwaysShowPicker: boolean;
|
|
14
|
+
showHexValue: boolean;
|
|
15
|
+
}>>, {
|
|
16
|
+
selectedFormatName: "hsl" | "hwb" | "lab" | "lch" | "oklab" | "oklch" | "rgb" | "hex";
|
|
17
|
+
rawInput: undefined | string;
|
|
12
18
|
}, {
|
|
13
19
|
colorChange: import("element-vir").DefineEvent<string>;
|
|
14
|
-
}, "vir-color-picker-", "vir-color-picker-width" | "vir-color-picker-height", readonly [], readonly []>;
|
|
20
|
+
}, "vir-color-picker-always-show", "vir-color-picker-swatch-width" | "vir-color-picker-swatch-height", readonly [], readonly []>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* node:coverage disable */
|
|
2
2
|
import { checkWrap } from '@augment-vir/assert';
|
|
3
3
|
import { getObjectTypedValues } from '@augment-vir/common';
|
|
4
|
-
import { css, defineElement, defineElementEvent, html, listen,
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
4
|
+
import { css, defineElement, defineElementEvent, html, listen, nothing } from 'element-vir';
|
|
5
|
+
import { Copy24Icon, noNativeFormStyles, viraFontCssVars, viraFormCssVars, ViraIcon, ViraInput, ViraPopUpTrigger, ViraSelect, viraShadows, } from 'vira';
|
|
6
|
+
import { ColorFormatName, colorFormats } from '../data/color-class/color-formats.js';
|
|
7
|
+
import { Color } from '../data/color-class/color.js';
|
|
8
|
+
import { colorLocalStorageClient } from '../data/local-storage.client.js';
|
|
9
9
|
import { VirColorFormatSliders } from './vir-color-format-sliders.element.js';
|
|
10
10
|
import { VirColorSwatch } from './vir-color-swatch.element.js';
|
|
11
11
|
const colorFormatOptions = getObjectTypedValues(ColorFormatName).map((formatName) => ({
|
|
@@ -15,17 +15,40 @@ const colorFormatOptions = getObjectTypedValues(ColorFormatName).map((formatName
|
|
|
15
15
|
/**
|
|
16
16
|
* A color picker element with a swatch that opens a popup with color format sliders.
|
|
17
17
|
*
|
|
18
|
+
* Set the width and height of the swatch using the provided CSS variables.
|
|
19
|
+
*
|
|
18
20
|
* @category Elements
|
|
19
21
|
*/
|
|
20
22
|
export const VirColorPicker = defineElement()({
|
|
21
23
|
tagName: 'vir-color-picker',
|
|
22
24
|
cssVars: {
|
|
23
|
-
'vir-color-picker-width': '100px',
|
|
24
|
-
'vir-color-picker-height': '100px',
|
|
25
|
+
'vir-color-picker-swatch-width': '100px',
|
|
26
|
+
'vir-color-picker-swatch-height': '100px',
|
|
25
27
|
},
|
|
26
|
-
|
|
28
|
+
state() {
|
|
29
|
+
return {
|
|
30
|
+
selectedFormatName: colorLocalStorageClient.get.lastFormat() || ColorFormatName.rgb,
|
|
31
|
+
rawInput: undefined,
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
hostClasses: {
|
|
35
|
+
'vir-color-picker-always-show': ({ inputs }) => !!inputs.alwaysShowPicker,
|
|
36
|
+
},
|
|
37
|
+
styles: ({ cssVars, hostClasses }) => css `
|
|
27
38
|
:host {
|
|
28
|
-
display: inline-
|
|
39
|
+
display: inline-flex;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
${hostClasses['vir-color-picker-always-show'].selector} {
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
align-items: center;
|
|
45
|
+
gap: 4px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
button {
|
|
49
|
+
${noNativeFormStyles}
|
|
50
|
+
cursor: pointer;
|
|
51
|
+
display: flex;
|
|
29
52
|
}
|
|
30
53
|
|
|
31
54
|
${ViraPopUpTrigger} {
|
|
@@ -34,82 +57,190 @@ export const VirColorPicker = defineElement()({
|
|
|
34
57
|
box-sizing: border-box;
|
|
35
58
|
}
|
|
36
59
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
60
|
+
.swatch-wrapper {
|
|
61
|
+
display: flex;
|
|
62
|
+
flex-direction: column;
|
|
63
|
+
gap: 4px;
|
|
64
|
+
align-items: center;
|
|
65
|
+
|
|
66
|
+
& ${VirColorSwatch} {
|
|
67
|
+
width: ${cssVars['vir-color-picker-swatch-width'].value};
|
|
68
|
+
height: ${cssVars['vir-color-picker-swatch-height'].value};
|
|
69
|
+
box-sizing: border-box;
|
|
70
|
+
}
|
|
42
71
|
}
|
|
43
72
|
|
|
44
|
-
.
|
|
73
|
+
.code-button {
|
|
74
|
+
font-family: ${viraFontCssVars['vira-monospace'].value};
|
|
75
|
+
font-size: 12px;
|
|
76
|
+
color: #666;
|
|
77
|
+
display: flex;
|
|
78
|
+
justify-content: center;
|
|
79
|
+
gap: 2px;
|
|
80
|
+
align-items: center;
|
|
81
|
+
|
|
82
|
+
& ${ViraIcon} {
|
|
83
|
+
width: 18px;
|
|
84
|
+
aspect-ratio: 1;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&:hover {
|
|
88
|
+
color: #000;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
&:active {
|
|
92
|
+
color: dodgerblue;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.picker {
|
|
45
97
|
display: flex;
|
|
46
98
|
flex-direction: column;
|
|
47
|
-
gap:
|
|
99
|
+
gap: 4px;
|
|
48
100
|
padding: 16px;
|
|
49
101
|
background: white;
|
|
50
102
|
border: 1px solid #ccc;
|
|
51
103
|
border-radius: 8px;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.pop-up .picker {
|
|
52
107
|
${viraShadows.menuShadow}
|
|
53
108
|
}
|
|
109
|
+
|
|
110
|
+
.raw-input-wrapper {
|
|
111
|
+
display: flex;
|
|
112
|
+
align-items: center;
|
|
113
|
+
justify-content: center;
|
|
114
|
+
gap: 8px;
|
|
115
|
+
font-size: 12px;
|
|
116
|
+
${viraFormCssVars['vira-form-border-color'].name}: #ddd;
|
|
117
|
+
color: #666;
|
|
118
|
+
|
|
119
|
+
& ${ViraInput} {
|
|
120
|
+
flex-grow: 1;
|
|
121
|
+
width: unset;
|
|
122
|
+
color: inherit;
|
|
123
|
+
height: 20px;
|
|
124
|
+
border: none;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
54
127
|
`,
|
|
55
128
|
events: {
|
|
56
129
|
colorChange: defineElementEvent(),
|
|
57
130
|
},
|
|
58
|
-
state
|
|
59
|
-
return {
|
|
60
|
-
selectedFormatName: ColorFormatName.rgb,
|
|
61
|
-
};
|
|
62
|
-
},
|
|
63
|
-
render({ inputs, dispatch, events, state, updateState, host, cssVars }) {
|
|
131
|
+
render({ inputs, dispatch, events, state, updateState }) {
|
|
64
132
|
const color = Color.isColor(inputs.color)
|
|
65
133
|
? inputs.color
|
|
66
134
|
: new Color(inputs.color || 'black');
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
135
|
+
const formatDefinition = colorFormats[state.selectedFormatName];
|
|
136
|
+
const rawInput = state.rawInput ?? color.toCss()[formatDefinition.rawSyntax];
|
|
137
|
+
const rawInputTemplate = html `
|
|
138
|
+
<div class="raw-input-wrapper">
|
|
139
|
+
<${ViraInput.assign({
|
|
140
|
+
value: rawInput,
|
|
70
141
|
})}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
forCssVar: cssVars['vir-color-picker-width'],
|
|
75
|
-
toValue: `${size.contentRect.width}px`,
|
|
76
|
-
});
|
|
77
|
-
setCssVarValue({
|
|
78
|
-
onElement: host,
|
|
79
|
-
forCssVar: cssVars['vir-color-picker-height'],
|
|
80
|
-
toValue: `${size.contentRect.height}px`,
|
|
142
|
+
${listen(ViraInput.events.valueChange, (event) => {
|
|
143
|
+
updateState({
|
|
144
|
+
rawInput: event.detail,
|
|
81
145
|
});
|
|
146
|
+
if (Color.isValidColorString(rawInput)) {
|
|
147
|
+
dispatch(new events.colorChange(rawInput));
|
|
148
|
+
}
|
|
149
|
+
})}
|
|
150
|
+
></${ViraInput}>
|
|
151
|
+
<button
|
|
152
|
+
class="code-button"
|
|
153
|
+
${listen('click', async () => {
|
|
154
|
+
await globalThis.navigator.clipboard.writeText(rawInput);
|
|
155
|
+
})}
|
|
156
|
+
>
|
|
157
|
+
<${ViraIcon.assign({
|
|
158
|
+
icon: Copy24Icon,
|
|
159
|
+
fitContainer: true,
|
|
160
|
+
})}></${ViraIcon}>
|
|
161
|
+
</button>
|
|
162
|
+
</div>
|
|
163
|
+
`;
|
|
164
|
+
const hexValueTemplate = html `
|
|
165
|
+
<button
|
|
166
|
+
class="code-button"
|
|
167
|
+
${listen('click', async () => {
|
|
168
|
+
await globalThis.navigator.clipboard.writeText(color.hexString);
|
|
82
169
|
})}
|
|
83
170
|
>
|
|
171
|
+
<span>${color.hexString}</span>
|
|
172
|
+
<${ViraIcon.assign({
|
|
173
|
+
icon: Copy24Icon,
|
|
174
|
+
fitContainer: true,
|
|
175
|
+
})}></${ViraIcon}>
|
|
176
|
+
</button>
|
|
177
|
+
`;
|
|
178
|
+
const swatchTemplate = html `
|
|
179
|
+
<div class="swatch-wrapper">
|
|
84
180
|
<${VirColorSwatch.assign({
|
|
85
181
|
backgroundColor: color,
|
|
86
|
-
})}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
182
|
+
})}></${VirColorSwatch}>
|
|
183
|
+
${inputs.showHexValue ? hexValueTemplate : nothing}
|
|
184
|
+
</div>
|
|
185
|
+
`;
|
|
186
|
+
const pickerTemplate = html `
|
|
187
|
+
<div class="picker">
|
|
188
|
+
<${ViraSelect.assign({
|
|
91
189
|
options: colorFormatOptions,
|
|
92
190
|
value: state.selectedFormatName,
|
|
93
191
|
})}
|
|
94
|
-
|
|
192
|
+
${listen(ViraSelect.events.valueChange, (event) => {
|
|
95
193
|
const selectedFormat = checkWrap.isEnumValue(event.detail, ColorFormatName);
|
|
96
194
|
if (selectedFormat) {
|
|
97
195
|
updateState({
|
|
98
196
|
selectedFormatName: selectedFormat,
|
|
99
197
|
});
|
|
198
|
+
colorLocalStorageClient.set.lastFormat(selectedFormat);
|
|
100
199
|
}
|
|
101
200
|
})}
|
|
102
|
-
|
|
103
|
-
|
|
201
|
+
></${ViraSelect}>
|
|
202
|
+
${rawInputTemplate}
|
|
203
|
+
<${VirColorFormatSliders.assign({
|
|
104
204
|
color,
|
|
105
205
|
colorFormatName: state.selectedFormatName,
|
|
206
|
+
showFormatName: false,
|
|
106
207
|
})}
|
|
107
|
-
|
|
208
|
+
${listen(VirColorFormatSliders.events.colorChange, (event) => {
|
|
108
209
|
dispatch(new events.colorChange(event.detail));
|
|
109
210
|
})}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
</${ViraPopUpTrigger}>
|
|
211
|
+
></${VirColorFormatSliders}>
|
|
212
|
+
</div>
|
|
113
213
|
`;
|
|
214
|
+
if (inputs.alwaysShowPicker) {
|
|
215
|
+
return html `
|
|
216
|
+
${swatchTemplate} ${pickerTemplate}
|
|
217
|
+
`;
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
return html `
|
|
221
|
+
<${ViraPopUpTrigger.assign({
|
|
222
|
+
keepOpenAfterInteraction: true,
|
|
223
|
+
})}>
|
|
224
|
+
<button class="trigger" slot=${ViraPopUpTrigger.slotNames.trigger}>
|
|
225
|
+
${swatchTemplate}
|
|
226
|
+
</button>
|
|
227
|
+
<div class="pop-up" slot=${ViraPopUpTrigger.slotNames.popUp}>
|
|
228
|
+
${pickerTemplate}
|
|
229
|
+
</div>
|
|
230
|
+
</${ViraPopUpTrigger}>
|
|
231
|
+
`;
|
|
232
|
+
}
|
|
114
233
|
},
|
|
115
234
|
});
|
|
235
|
+
CSS.registerProperty({
|
|
236
|
+
name: String(VirColorPicker.cssVars['vir-color-picker-swatch-width'].name),
|
|
237
|
+
syntax: '<length>',
|
|
238
|
+
inherits: true,
|
|
239
|
+
initialValue: VirColorPicker.cssVars['vir-color-picker-swatch-width'].default,
|
|
240
|
+
});
|
|
241
|
+
CSS.registerProperty({
|
|
242
|
+
name: String(VirColorPicker.cssVars['vir-color-picker-swatch-height'].name),
|
|
243
|
+
syntax: '<length>',
|
|
244
|
+
inherits: true,
|
|
245
|
+
initialValue: VirColorPicker.cssVars['vir-color-picker-swatch-height'].default,
|
|
246
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type ColorCoordinateName, type ColorFormatName } from '../color-class/color-formats.js';
|
|
2
|
-
import { Color } from '../color-class/color.js';
|
|
1
|
+
import { type ColorCoordinateName, type ColorFormatName } from '../data/color-class/color-formats.js';
|
|
2
|
+
import { Color } from '../data/color-class/color.js';
|
|
3
3
|
/**
|
|
4
4
|
* A slider for a specific color coordinate in a specific color space in a specific color.
|
|
5
5
|
*
|
|
@@ -4,8 +4,8 @@ import { createArray } from '@augment-vir/common';
|
|
|
4
4
|
import { extractEventTarget } from '@augment-vir/web';
|
|
5
5
|
import { css, defineElement, defineElementEvent, html, listen, unsafeCSS } from 'element-vir';
|
|
6
6
|
import { viraFontCssVars, ViraInput } from 'vira';
|
|
7
|
-
import { colorFormats, } from '../color-class/color-formats.js';
|
|
8
|
-
import { Color } from '../color-class/color.js';
|
|
7
|
+
import { colorFormats, } from '../data/color-class/color-formats.js';
|
|
8
|
+
import { Color } from '../data/color-class/color.js';
|
|
9
9
|
/**
|
|
10
10
|
* A slider for a specific color coordinate in a specific color space in a specific color.
|
|
11
11
|
*
|
|
@@ -61,10 +61,16 @@ export const VirColorSlider = defineElement()({
|
|
|
61
61
|
[inputs.colorCoordinateName]: value,
|
|
62
62
|
},
|
|
63
63
|
});
|
|
64
|
-
return stopColor.toCss()[
|
|
64
|
+
return stopColor.toCss()[formatDefinition.conversionFormat];
|
|
65
65
|
});
|
|
66
66
|
const gradient = css `linear-gradient(to right, ${unsafeCSS(colorStops.join(','))})`;
|
|
67
67
|
const coordinateValue = assertWrap.isNumber(inputs.color[inputs.colorFormatName][inputs.colorCoordinateName]);
|
|
68
|
+
const displayValue = coordinateDefinition.radix
|
|
69
|
+
? Math.round(coordinateValue)
|
|
70
|
+
.toString(coordinateDefinition.radix)
|
|
71
|
+
.toUpperCase()
|
|
72
|
+
.padStart(coordinateDefinition.radixPad || 0, '0')
|
|
73
|
+
: String(coordinateValue);
|
|
68
74
|
return html `
|
|
69
75
|
<span class="coordinate">${inputs.colorCoordinateName.toUpperCase()}</span>
|
|
70
76
|
<input
|
|
@@ -86,10 +92,12 @@ export const VirColorSlider = defineElement()({
|
|
|
86
92
|
})}
|
|
87
93
|
/>
|
|
88
94
|
<${ViraInput.assign({
|
|
89
|
-
value:
|
|
95
|
+
value: displayValue,
|
|
90
96
|
})}
|
|
91
97
|
${listen(ViraInput.events.valueChange, (event) => {
|
|
92
|
-
const newValue =
|
|
98
|
+
const newValue = coordinateDefinition.radix
|
|
99
|
+
? parseInt(event.detail, coordinateDefinition.radix)
|
|
100
|
+
: Number(event.detail);
|
|
93
101
|
if (isNaN(newValue)) {
|
|
94
102
|
return;
|
|
95
103
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Color } from '../color-class/color.js';
|
|
1
|
+
import { type Color } from '../data/color-class/color.js';
|
|
2
2
|
/**
|
|
3
3
|
* Show a background and/or foreground color. Note that if a foreground color is provided that it is
|
|
4
4
|
* not actually applied to anything, you must provide a child element for it to be applied to.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* node:coverage disable */
|
|
2
2
|
import { classMap, css, defineElement, html, unsafeCSS } from 'element-vir';
|
|
3
|
-
import { contrastLevelLabel, ContrastLevelName, contrastLevels, } from '../contrast/contrast.js';
|
|
3
|
+
import { contrastLevelLabel, ContrastLevelName, contrastLevels, } from '../data/contrast/contrast.js';
|
|
4
4
|
/**
|
|
5
5
|
* Show contrast details for a calculated contrast.
|
|
6
6
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from './color-class/color-formats.js';
|
|
2
|
-
export * from './color-class/color-name-length.js';
|
|
3
|
-
export * from './color-class/color.js';
|
|
4
|
-
export * from './contrast/contrast.js';
|
|
1
|
+
export * from './data/color-class/color-formats.js';
|
|
2
|
+
export * from './data/color-class/color-name-length.js';
|
|
3
|
+
export * from './data/color-class/color.js';
|
|
4
|
+
export * from './data/contrast/contrast.js';
|
|
5
5
|
export * from './elements/vir-all-color-space-sliders.element.js';
|
|
6
6
|
export * from './elements/vir-all-spaces-color-picker.element.js';
|
|
7
7
|
export * from './elements/vir-color-details.element.js';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from './color-class/color-formats.js';
|
|
2
|
-
export * from './color-class/color-name-length.js';
|
|
3
|
-
export * from './color-class/color.js';
|
|
4
|
-
export * from './contrast/contrast.js';
|
|
1
|
+
export * from './data/color-class/color-formats.js';
|
|
2
|
+
export * from './data/color-class/color-name-length.js';
|
|
3
|
+
export * from './data/color-class/color.js';
|
|
4
|
+
export * from './data/contrast/contrast.js';
|
|
5
5
|
export * from './elements/vir-all-color-space-sliders.element.js';
|
|
6
6
|
export * from './elements/vir-all-spaces-color-picker.element.js';
|
|
7
7
|
export * from './elements/vir-color-details.element.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@electrovir/color",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "A wrapper for culori with an extremely simple API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"color",
|
|
@@ -50,31 +50,33 @@
|
|
|
50
50
|
"test:update": "npm test update"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@augment-vir/assert": "^31.57.
|
|
54
|
-
"@augment-vir/common": "^31.57.
|
|
55
|
-
"@augment-vir/web": "^31.57.
|
|
53
|
+
"@augment-vir/assert": "^31.57.5",
|
|
54
|
+
"@augment-vir/common": "^31.57.5",
|
|
55
|
+
"@augment-vir/web": "^31.57.5",
|
|
56
|
+
"@electrovir/local-storage-client": "^0.0.1",
|
|
56
57
|
"apca-w3": "^0.1.9",
|
|
57
58
|
"color-name": "^2.1.0",
|
|
58
59
|
"culori": "^4.0.2",
|
|
60
|
+
"object-shape-tester": "^6.11.0",
|
|
59
61
|
"type-fest": "^5.3.1"
|
|
60
62
|
},
|
|
61
63
|
"devDependencies": {
|
|
62
|
-
"@augment-vir/test": "^31.57.
|
|
64
|
+
"@augment-vir/test": "^31.57.5",
|
|
63
65
|
"@eslint/eslintrc": "^3.3.3",
|
|
64
66
|
"@eslint/js": "^9.39.2",
|
|
65
67
|
"@stylistic/eslint-plugin": "^5.6.1",
|
|
66
68
|
"@stylistic/eslint-plugin-ts": "^4.4.1",
|
|
67
69
|
"@types/color-name": "^2.0.0",
|
|
68
70
|
"@types/culori": "^4.0.1",
|
|
69
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
71
|
+
"@typescript-eslint/eslint-plugin": "^8.52.0",
|
|
70
72
|
"@web/dev-server-esbuild": "^1.0.4",
|
|
71
73
|
"@web/test-runner": "^0.20.2",
|
|
72
74
|
"@web/test-runner-commands": "^0.9.0",
|
|
73
75
|
"@web/test-runner-playwright": "^0.11.1",
|
|
74
76
|
"@web/test-runner-visual-regression": "^0.10.0",
|
|
75
77
|
"cspell": "^9.4.0",
|
|
76
|
-
"dependency-cruiser": "^17.3.
|
|
77
|
-
"element-book": "^26.14.
|
|
78
|
+
"dependency-cruiser": "^17.3.6",
|
|
79
|
+
"element-book": "^26.14.2",
|
|
78
80
|
"element-vir": "^26.14.0",
|
|
79
81
|
"esbuild": "^0.27.2",
|
|
80
82
|
"eslint": "^9.39.2",
|
|
@@ -90,7 +92,7 @@
|
|
|
90
92
|
"istanbul-smart-text-reporter": "^1.1.5",
|
|
91
93
|
"lit-css-vars": "^3.0.11",
|
|
92
94
|
"markdown-code-example-inserter": "^3.0.3",
|
|
93
|
-
"npm-check-updates": "^19.
|
|
95
|
+
"npm-check-updates": "^19.3.1",
|
|
94
96
|
"prettier": "~3.3.3",
|
|
95
97
|
"prettier-plugin-interpolated-html-tags": "^2.0.1",
|
|
96
98
|
"prettier-plugin-jsdoc": "^1.8.0",
|
|
@@ -102,10 +104,10 @@
|
|
|
102
104
|
"runstorm": "^1.0.0",
|
|
103
105
|
"typedoc": "^0.28.15",
|
|
104
106
|
"typescript": "^5.9.3",
|
|
105
|
-
"typescript-eslint": "^8.
|
|
106
|
-
"vira": "^28.
|
|
107
|
-
"virmator": "^14.4.
|
|
108
|
-
"vite": "^7.3.
|
|
107
|
+
"typescript-eslint": "^8.52.0",
|
|
108
|
+
"vira": "^28.19.0",
|
|
109
|
+
"virmator": "^14.4.2",
|
|
110
|
+
"vite": "^7.3.1"
|
|
109
111
|
},
|
|
110
112
|
"peerDependencies": {
|
|
111
113
|
"element-vir": ">=26",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|