@electrovir/color 1.7.12 → 2.0.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.
Files changed (29) hide show
  1. package/dist/demo/all-book-pages.js +1 -10
  2. package/dist/demo/top-level-pages.d.ts +0 -1
  3. package/dist/demo/top-level-pages.js +0 -4
  4. package/dist/demo/vir-demo.element.js +2 -2
  5. package/dist/index.d.ts +0 -10
  6. package/dist/index.js +0 -10
  7. package/package.json +16 -18
  8. package/dist/data/local-storage.client.d.ts +0 -4
  9. package/dist/data/local-storage.client.js +0 -6
  10. package/dist/elements/vir-all-color-space-sliders.element.d.ts +0 -11
  11. package/dist/elements/vir-all-color-space-sliders.element.js +0 -53
  12. package/dist/elements/vir-all-spaces-color-picker.element.d.ts +0 -15
  13. package/dist/elements/vir-all-spaces-color-picker.element.js +0 -69
  14. package/dist/elements/vir-color-details.element.d.ts +0 -14
  15. package/dist/elements/vir-color-details.element.js +0 -151
  16. package/dist/elements/vir-color-format-sliders.element.d.ts +0 -14
  17. package/dist/elements/vir-color-format-sliders.element.js +0 -58
  18. package/dist/elements/vir-color-pair-contrast-summary.element.d.ts +0 -9
  19. package/dist/elements/vir-color-pair-contrast-summary.element.js +0 -307
  20. package/dist/elements/vir-color-pair.element.d.ts +0 -17
  21. package/dist/elements/vir-color-pair.element.js +0 -201
  22. package/dist/elements/vir-color-picker.element.d.ts +0 -20
  23. package/dist/elements/vir-color-picker.element.js +0 -272
  24. package/dist/elements/vir-color-slider.element.d.ts +0 -14
  25. package/dist/elements/vir-color-slider.element.js +0 -120
  26. package/dist/elements/vir-color-swatch.element.d.ts +0 -20
  27. package/dist/elements/vir-color-swatch.element.js +0 -48
  28. package/dist/elements/vir-contrast-indicator.element.d.ts +0 -10
  29. package/dist/elements/vir-contrast-indicator.element.js +0 -96
@@ -1,272 +0,0 @@
1
- /* node:coverage disable */
2
- import { checkWrap } from '@augment-vir/assert';
3
- import { getObjectTypedValues } from '@augment-vir/common';
4
- import { css, defineElement, defineElementEvent, html, listen, nothing } from 'element-vir';
5
- import { CssVarSyntaxName } from 'lit-css-vars';
6
- import { ViraPopUpTrigger } from 'vira/dist/elements/pop-up/vira-pop-up-trigger.element.js';
7
- import { ViraIcon } from 'vira/dist/elements/vira-icon.element.js';
8
- import { ViraInput } from 'vira/dist/elements/vira-input.element.js';
9
- import { ViraSelect } from 'vira/dist/elements/vira-select.element.js';
10
- import { Copy24Icon } from 'vira/dist/icons/icon-svgs/24/copy-24.icon.js';
11
- import { viraFontCssVars } from 'vira/dist/styles/font.js';
12
- import { viraFormCssVars } from 'vira/dist/styles/form-styles.js';
13
- import { noNativeFormStyles } from 'vira/dist/styles/native-styles.js';
14
- import { viraShadows } from 'vira/dist/styles/shadows.js';
15
- import { ColorFormatName, colorFormats } from '../data/color-class/color-formats.js';
16
- import { Color } from '../data/color-class/color.js';
17
- import { colorLocalStorageClient } from '../data/local-storage.client.js';
18
- import { VirColorFormatSliders } from './vir-color-format-sliders.element.js';
19
- import { VirColorSwatch } from './vir-color-swatch.element.js';
20
- const colorFormatOptions = getObjectTypedValues(ColorFormatName).map((formatName) => {
21
- return {
22
- value: formatName,
23
- label: formatName.toUpperCase(),
24
- };
25
- });
26
- /**
27
- * A color picker element with a swatch that opens a popup with color format sliders.
28
- *
29
- * Set the width and height of the swatch using the provided CSS variables.
30
- *
31
- * @category Elements
32
- */
33
- export const VirColorPicker = defineElement()({
34
- tagName: 'vir-color-picker',
35
- cssVars: {
36
- 'vir-color-picker-swatch-width': {
37
- default: '100px',
38
- syntax: CssVarSyntaxName.Length,
39
- },
40
- 'vir-color-picker-swatch-height': {
41
- default: '100px',
42
- syntax: CssVarSyntaxName.Length,
43
- },
44
- },
45
- state() {
46
- return {
47
- selectedFormatName: colorLocalStorageClient.get.lastFormat() || ColorFormatName.rgb,
48
- rawInput: undefined,
49
- };
50
- },
51
- hostClasses: {
52
- 'vir-color-picker-always-show': ({ inputs }) => !!inputs.alwaysShowPicker,
53
- },
54
- styles: ({ cssVars, hostClasses }) => {
55
- return css `
56
- :host {
57
- display: inline-flex;
58
- }
59
-
60
- ${hostClasses['vir-color-picker-always-show'].selector} {
61
- flex-direction: column;
62
- align-items: center;
63
- gap: 4px;
64
- }
65
-
66
- button {
67
- ${noNativeFormStyles}
68
- cursor: pointer;
69
- display: flex;
70
- }
71
-
72
- ${ViraPopUpTrigger} {
73
- width: 100%;
74
- height: 100%;
75
- box-sizing: border-box;
76
- }
77
-
78
- .swatch-wrapper {
79
- display: flex;
80
- flex-direction: column;
81
- gap: 4px;
82
- align-items: center;
83
-
84
- & ${VirColorSwatch} {
85
- width: ${cssVars['vir-color-picker-swatch-width'].value};
86
- height: ${cssVars['vir-color-picker-swatch-height'].value};
87
- box-sizing: border-box;
88
- }
89
- }
90
-
91
- .code-button {
92
- font-family: ${viraFontCssVars['vira-monospace'].value};
93
- font-size: 12px;
94
- color: #666;
95
- display: flex;
96
- justify-content: center;
97
- gap: 2px;
98
- align-items: center;
99
-
100
- & ${ViraIcon} {
101
- width: 18px;
102
- aspect-ratio: 1;
103
- }
104
-
105
- &:hover {
106
- color: #000;
107
- }
108
-
109
- &:active {
110
- color: dodgerblue;
111
- }
112
- }
113
-
114
- .picker {
115
- display: flex;
116
- flex-direction: column;
117
- gap: 4px;
118
- padding: 16px;
119
- background: white;
120
- border: 1px solid #ccc;
121
- border-radius: 8px;
122
- }
123
-
124
- .pop-up .picker {
125
- ${viraShadows.menuShadow}
126
- }
127
-
128
- .raw-input-wrapper {
129
- text-align: left;
130
- display: flex;
131
- align-items: center;
132
- justify-content: center;
133
- gap: 8px;
134
- font-size: 12px;
135
- ${viraFormCssVars['vira-form-border-color'].name}: #ddd;
136
- color: #666;
137
-
138
- & ${ViraInput} {
139
- flex-grow: 1;
140
- width: unset;
141
- color: inherit;
142
- height: 20px;
143
- border: none;
144
- }
145
- }
146
- `;
147
- },
148
- events: {
149
- colorChange: defineElementEvent(),
150
- },
151
- render({ inputs, dispatch, events, state, updateState }) {
152
- const color = Color.isColor(inputs.color)
153
- ? inputs.color
154
- : new Color(inputs.color || 'black');
155
- const formatDefinition = colorFormats[state.selectedFormatName];
156
- const rawInput = state.rawInput ?? color.toCss()[formatDefinition.rawSyntax];
157
- const rawInputTemplate = html `
158
- <div class="raw-input-wrapper">
159
- <${ViraInput.assign({
160
- value: rawInput,
161
- })}
162
- ${listen(ViraInput.events.valueChange, (event) => {
163
- const rawInput = event.detail;
164
- updateState({
165
- rawInput,
166
- });
167
- if (Color.isValidColorString(rawInput)) {
168
- dispatch(new events.colorChange(rawInput));
169
- }
170
- })}
171
- ></${ViraInput}>
172
- <button
173
- class="code-button"
174
- ${listen('click', async () => {
175
- await globalThis.navigator.clipboard.writeText(rawInput);
176
- })}
177
- >
178
- <${ViraIcon.assign({
179
- icon: Copy24Icon,
180
- fitContainer: true,
181
- })}></${ViraIcon}>
182
- </button>
183
- </div>
184
- `;
185
- const hexValueTemplate = html `
186
- <button
187
- class="code-button"
188
- ${listen('click', async () => {
189
- await globalThis.navigator.clipboard.writeText(color.hexString);
190
- })}
191
- >
192
- <span>${color.hexString}</span>
193
- <${ViraIcon.assign({
194
- icon: Copy24Icon,
195
- fitContainer: true,
196
- })}></${ViraIcon}>
197
- </button>
198
- `;
199
- const swatchTemplate = html `
200
- <div class="swatch-wrapper">
201
- <${VirColorSwatch.assign({
202
- backgroundColor: color,
203
- })}></${VirColorSwatch}>
204
- ${inputs.showHexValue ? hexValueTemplate : nothing}
205
- </div>
206
- `;
207
- const pickerTemplate = html `
208
- <div class="picker">
209
- <${ViraSelect.assign({
210
- options: colorFormatOptions,
211
- value: state.selectedFormatName,
212
- })}
213
- ${listen(ViraSelect.events.valueChange, (event) => {
214
- const selectedFormat = checkWrap.isEnumValue(event.detail, ColorFormatName);
215
- if (selectedFormat) {
216
- updateState({
217
- selectedFormatName: selectedFormat,
218
- });
219
- colorLocalStorageClient.set.lastFormat(selectedFormat);
220
- }
221
- })}
222
- ></${ViraSelect}>
223
- ${rawInputTemplate}
224
- <${VirColorFormatSliders.assign({
225
- color,
226
- colorFormatName: state.selectedFormatName,
227
- showFormatName: false,
228
- })}
229
- ${listen(VirColorFormatSliders.events.colorChange, (event) => {
230
- dispatch(new events.colorChange(event.detail));
231
- updateState({
232
- rawInput: undefined,
233
- });
234
- })}
235
- ></${VirColorFormatSliders}>
236
- </div>
237
- `;
238
- if (inputs.alwaysShowPicker) {
239
- return html `
240
- ${swatchTemplate} ${pickerTemplate}
241
- `;
242
- }
243
- else {
244
- return html `
245
- <${ViraPopUpTrigger.assign({
246
- keepOpenAfterInteraction: true,
247
- })}>
248
- <button
249
- class="trigger"
250
- slot=${ViraPopUpTrigger.slotNames['vira-pop-up-trigger-trigger']}
251
- ${listen('mousedown', () => {
252
- const storedFormat = colorLocalStorageClient.get.lastFormat();
253
- if (storedFormat) {
254
- updateState({
255
- selectedFormatName: storedFormat,
256
- });
257
- }
258
- })}
259
- >
260
- ${swatchTemplate}
261
- </button>
262
- <div
263
- class="pop-up"
264
- slot=${ViraPopUpTrigger.slotNames['vira-pop-up-trigger-pop-up']}
265
- >
266
- ${pickerTemplate}
267
- </div>
268
- </${ViraPopUpTrigger}>
269
- `;
270
- }
271
- },
272
- });
@@ -1,14 +0,0 @@
1
- import { type ColorCoordinateName, type ColorFormatName } from '../data/color-class/color-formats.js';
2
- import { Color } from '../data/color-class/color.js';
3
- /**
4
- * A slider for a specific color coordinate in a specific color space in a specific color.
5
- *
6
- * @category Elements
7
- */
8
- export declare const VirColorSlider: import("element-vir").DeclarativeElementDefinition<"vir-color-slider", {
9
- color: Readonly<Color>;
10
- colorFormatName: ColorFormatName;
11
- colorCoordinateName: ColorCoordinateName;
12
- }, {}, {
13
- valueChange: import("element-vir").DefineEvent<number>;
14
- }, "vir-color-slider-", "vir-color-slider-gradient", readonly [], readonly []>;
@@ -1,120 +0,0 @@
1
- /* node:coverage disable */
2
- import { assert, assertWrap } from '@augment-vir/assert';
3
- import { createArray } from '@augment-vir/common';
4
- import { extractEventTarget } from '@augment-vir/web';
5
- import { css, defineElement, defineElementEvent, html, listen, onDomRendered, unsafeCSS, } from 'element-vir';
6
- import { ViraInput } from 'vira/dist/elements/vira-input.element.js';
7
- import { viraFontCssVars } from 'vira/dist/styles/font.js';
8
- import { colorFormats, } from '../data/color-class/color-formats.js';
9
- import { Color } from '../data/color-class/color.js';
10
- /**
11
- * A slider for a specific color coordinate in a specific color space in a specific color.
12
- *
13
- * @category Elements
14
- */
15
- export const VirColorSlider = defineElement()({
16
- tagName: 'vir-color-slider',
17
- cssVars: {
18
- 'vir-color-slider-gradient': 'black',
19
- },
20
- styles: ({ cssVars }) => {
21
- return css `
22
- :host {
23
- display: flex;
24
- align-items: center;
25
- font-family: ${viraFontCssVars['vira-monospace'].value};
26
- gap: 2px;
27
- }
28
-
29
- input[type='range'] {
30
- flex-grow: 1;
31
- appearance: none;
32
- background: ${cssVars['vir-color-slider-gradient'].value};
33
- height: 9px;
34
- border-radius: 4px;
35
- cursor: pointer;
36
- }
37
-
38
- ${ViraInput} {
39
- width: 76px;
40
- }
41
-
42
- .coordinate {
43
- font-size: 18px;
44
- margin-top: -4px;
45
- }
46
- `;
47
- },
48
- events: {
49
- valueChange: defineElementEvent(),
50
- },
51
- render({ inputs, events, dispatch, cssVars }) {
52
- const formatDefinition = colorFormats[inputs.colorFormatName];
53
- const coordinateDefinition = formatDefinition.coords[inputs.colorCoordinateName];
54
- if (!coordinateDefinition) {
55
- throw new Error(`Invalid color coordinate '${inputs.colorCoordinateName}' for color format '${inputs.colorFormatName}'`);
56
- }
57
- const totalStops = 10;
58
- const colorStops = createArray(totalStops, (index) => {
59
- const value = coordinateDefinition.min +
60
- (coordinateDefinition.max - coordinateDefinition.min) * (index / totalStops);
61
- const stopColor = new Color({
62
- [inputs.colorFormatName]: {
63
- ...inputs.color[inputs.colorFormatName],
64
- [inputs.colorCoordinateName]: value,
65
- },
66
- });
67
- return stopColor.toCss()[formatDefinition.conversionFormat];
68
- });
69
- const gradient = css `linear-gradient(to right, ${unsafeCSS(colorStops.join(','))})`;
70
- const coordinateValue = assertWrap.isNumber(inputs.color[inputs.colorFormatName][inputs.colorCoordinateName]);
71
- const displayValue = coordinateDefinition.radix
72
- ? Math.round(coordinateValue)
73
- .toString(coordinateDefinition.radix)
74
- .toUpperCase()
75
- .padStart(coordinateDefinition.radixPad || 0, '0')
76
- : String(coordinateValue);
77
- return html `
78
- <span class="coordinate">${inputs.colorCoordinateName.toUpperCase()}</span>
79
- <input
80
- type="range"
81
- style=${css `
82
- ${cssVars['vir-color-slider-gradient'].name}: ${gradient};
83
- `}
84
- step=${Math.pow(10, coordinateDefinition.digits ? -coordinateDefinition.digits : 0)}
85
- ${onDomRendered((element) => {
86
- /**
87
- * We must set these imperatively to force the input element to match the
88
- * inputs, otherwise when swapping color formats these color sliders don't
89
- * update correctly.
90
- */
91
- assert.instanceOf(element, HTMLInputElement);
92
- element.min = String(coordinateDefinition.min);
93
- element.max = String(coordinateDefinition.max);
94
- element.value = String(coordinateValue);
95
- })}
96
- ${listen('input', (event) => {
97
- const element = extractEventTarget(event, HTMLInputElement);
98
- const newValue = Number(element.value);
99
- if (isNaN(newValue)) {
100
- return;
101
- }
102
- dispatch(new events.valueChange(newValue));
103
- })}
104
- />
105
- <${ViraInput.assign({
106
- value: displayValue,
107
- })}
108
- ${listen(ViraInput.events.valueChange, (event) => {
109
- const newValue = coordinateDefinition.radix
110
- ? parseInt(event.detail, coordinateDefinition.radix)
111
- : Number(event.detail);
112
- if (isNaN(newValue)) {
113
- return;
114
- }
115
- dispatch(new events.valueChange(newValue));
116
- })}
117
- ></${ViraInput}>
118
- `;
119
- },
120
- });
@@ -1,20 +0,0 @@
1
- import { type Color } from '../data/color-class/color.js';
2
- /**
3
- * Show a background and/or foreground color. Note that if a foreground color is provided that it is
4
- * not actually applied to anything, you must provide a child element for it to be applied to.
5
- *
6
- * @category Elements
7
- */
8
- export declare const VirColorSwatch: import("element-vir").DeclarativeElementDefinition<"vir-color-swatch", ((Required<Pick<{
9
- foregroundColor: string | Readonly<Color>;
10
- backgroundColor: string | Readonly<Color>;
11
- }, "foregroundColor">> & Partial<Pick<{
12
- foregroundColor: string | Readonly<Color>;
13
- backgroundColor: string | Readonly<Color>;
14
- }, "backgroundColor">>) | (Required<Pick<{
15
- foregroundColor: string | Readonly<Color>;
16
- backgroundColor: string | Readonly<Color>;
17
- }, "backgroundColor">> & Partial<Pick<{
18
- foregroundColor: string | Readonly<Color>;
19
- backgroundColor: string | Readonly<Color>;
20
- }, "foregroundColor">>)) & {}, {}, {}, "vir-color-swatch-", "vir-color-swatch-", readonly [], readonly []>;
@@ -1,48 +0,0 @@
1
- /* node:coverage disable */
2
- import { css, defineElement, html, unsafeCSS } from 'element-vir';
3
- /**
4
- * Show a background and/or foreground color. Note that if a foreground color is provided that it is
5
- * not actually applied to anything, you must provide a child element for it to be applied to.
6
- *
7
- * @category Elements
8
- */
9
- export const VirColorSwatch = defineElement()({
10
- tagName: 'vir-color-swatch',
11
- styles: css `
12
- :host {
13
- display: flex;
14
- height: 400px;
15
- width: 400px;
16
- border: 1px solid black;
17
- max-height: 100%;
18
- max-width: 100%;
19
- container-type: size;
20
- overflow: hidden;
21
- }
22
-
23
- div {
24
- flex-grow: 1;
25
- height: 100%;
26
- max-height: 100%;
27
- width: 100%;
28
- max-width: 100%;
29
- display: flex;
30
- justify-content: center;
31
- align-items: center;
32
- }
33
- `,
34
- render({ inputs }) {
35
- const backgroundColor = inputs.backgroundColor || inputs.foregroundColor;
36
- const foregroundColor = inputs.foregroundColor || 'transparent';
37
- return html `
38
- <div
39
- style=${css `
40
- background-color: ${unsafeCSS(backgroundColor)};
41
- color: ${unsafeCSS(foregroundColor)};
42
- `}
43
- >
44
- <slot></slot>
45
- </div>
46
- `;
47
- },
48
- });
@@ -1,10 +0,0 @@
1
- import { type CalculatedContrast, type FontWeight } from '../data/contrast/contrast.js';
2
- /**
3
- * Show contrast details for a calculated contrast.
4
- *
5
- * @category Elements
6
- */
7
- export declare const VirContrastIndicator: import("element-vir").DeclarativeElementDefinition<"vir-contrast-indicator", {
8
- contrast: Readonly<CalculatedContrast>;
9
- fontWeight: FontWeight;
10
- }, {}, {}, "vir-contrast-indicator-", "vir-contrast-indicator-", readonly [], readonly []>;
@@ -1,96 +0,0 @@
1
- /* node:coverage disable */
2
- import { classMap, css, defineElement, html, unsafeCSS } from 'element-vir';
3
- import { contrastLevelLabel, ContrastLevelName, contrastLevels, } from '../data/contrast/contrast.js';
4
- /**
5
- * Show contrast details for a calculated contrast.
6
- *
7
- * @category Elements
8
- */
9
- export const VirContrastIndicator = defineElement()({
10
- tagName: 'vir-contrast-indicator',
11
- styles: css `
12
- :host {
13
- display: inline-flex;
14
- max-width: 100%;
15
- font-size: 12px;
16
- }
17
-
18
- .wrapper {
19
- text-align: center;
20
- flex-grow: 1;
21
- display: flex;
22
- flex-direction: column;
23
- max-width: 100%;
24
- color: #aaa;
25
- }
26
-
27
- .${unsafeCSS(ContrastLevelName.Invisible)} {
28
- color: red;
29
- }
30
- .${unsafeCSS(ContrastLevelName.Decoration)} {
31
- color: #ff6600;
32
- }
33
- .${unsafeCSS(ContrastLevelName.Placeholder)} {
34
- color: #a5a520;
35
- }
36
-
37
- .gauge {
38
- align-self: center;
39
- background-color: currentColor;
40
- display: flex;
41
- padding: 1px;
42
- gap: 1px;
43
- margin-bottom: 2px;
44
- /* Sure sure if I actually want to keep this. */
45
- display: none;
46
- }
47
-
48
- .gauge-level {
49
- width: 10px;
50
- height: 2px;
51
-
52
- &.active {
53
- background-color: white;
54
- }
55
- }
56
-
57
- .gauge-text + .gauge-text {
58
- border-left: 1px solid #ccc;
59
- padding-left: 1ex;
60
- }
61
- `,
62
- render({ inputs }) {
63
- const gaugeLevels = contrastLevels
64
- .toReversed()
65
- .slice(1)
66
- .map((level) => {
67
- return html `
68
- <div
69
- class="gauge-level ${classMap({
70
- active: level.min <= Math.abs(inputs.contrast.contrast),
71
- })}"
72
- ></div>
73
- `;
74
- });
75
- const title = [
76
- inputs.contrast.contrastLevel.description,
77
- '\nFont weights to font sizes:',
78
- JSON.stringify(inputs.contrast.fontSizes, null, 4),
79
- ].join('\n');
80
- const fontSize = inputs.contrast.fontSizes[inputs.fontWeight] > 150
81
- ? '-'
82
- : `${inputs.contrast.fontSizes[inputs.fontWeight]}px`;
83
- return html `
84
- <div title=${title} class="wrapper ${inputs.contrast.contrastLevel.name}">
85
- <div class="gauge">${gaugeLevels}</div>
86
- <span>
87
- <span class="gauge-text">${Math.round(inputs.contrast.contrast)} Lc</span>
88
- <span class="gauge-text">
89
- ${contrastLevelLabel[inputs.contrast.contrastLevel.name]}
90
- </span>
91
- <span class="gauge-text">${fontSize}</span>
92
- </span>
93
- </div>
94
- `;
95
- },
96
- });