@electrovir/color 0.0.0 → 1.1.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.
@@ -0,0 +1,101 @@
1
+ /* node:coverage disable */
2
+ import { 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, unsafeCSS } from 'element-vir';
6
+ import { viraFontCssVars, ViraInput } from 'vira';
7
+ import { colorFormats, } from '../color-class/color-formats.js';
8
+ import { Color } from '../color-class/color.js';
9
+ /**
10
+ * A slider for a specific color coordinate in a specific color space in a specific color.
11
+ *
12
+ * @category Elements
13
+ */
14
+ export const VirColorSlider = defineElement()({
15
+ tagName: 'vir-color-slider',
16
+ cssVars: {
17
+ 'vir-color-slider-gradient': 'black',
18
+ },
19
+ styles: ({ cssVars }) => css `
20
+ :host {
21
+ display: flex;
22
+ align-items: center;
23
+ font-family: ${viraFontCssVars['vira-monospace'].value};
24
+ gap: 2px;
25
+ }
26
+
27
+ input[type='range'] {
28
+ flex-grow: 1;
29
+ appearance: none;
30
+ background: ${cssVars['vir-color-slider-gradient'].value};
31
+ height: 9px;
32
+ border-radius: 4px;
33
+ cursor: pointer;
34
+ }
35
+
36
+ ${ViraInput} {
37
+ width: 76px;
38
+ }
39
+
40
+ .coordinate {
41
+ font-size: 18px;
42
+ margin-top: -4px;
43
+ }
44
+ `,
45
+ events: {
46
+ valueChange: defineElementEvent(),
47
+ },
48
+ render({ inputs, events, dispatch, cssVars }) {
49
+ const formatDefinition = colorFormats[inputs.colorFormatName];
50
+ const coordinateDefinition = formatDefinition.coords[inputs.colorCoordinateName];
51
+ if (!coordinateDefinition) {
52
+ throw new Error(`Invalid color coordinate '${inputs.colorCoordinateName}' for color format '${inputs.colorFormatName}'`);
53
+ }
54
+ const totalStops = 10;
55
+ const colorStops = createArray(totalStops, (index) => {
56
+ const value = coordinateDefinition.min +
57
+ (coordinateDefinition.max - coordinateDefinition.min) * (index / totalStops);
58
+ const stopColor = new Color({
59
+ [inputs.colorFormatName]: {
60
+ ...inputs.color[inputs.colorFormatName],
61
+ [inputs.colorCoordinateName]: value,
62
+ },
63
+ });
64
+ return stopColor.toCss()[inputs.colorFormatName];
65
+ });
66
+ const gradient = css `linear-gradient(to right, ${unsafeCSS(colorStops.join(','))})`;
67
+ const coordinateValue = assertWrap.isNumber(inputs.color[inputs.colorFormatName][inputs.colorCoordinateName]);
68
+ return html `
69
+ <span class="coordinate">${inputs.colorCoordinateName.toUpperCase()}</span>
70
+ <input
71
+ type="range"
72
+ style=${css `
73
+ ${cssVars['vir-color-slider-gradient'].name}: ${gradient};
74
+ `}
75
+ min=${coordinateDefinition.min}
76
+ max=${coordinateDefinition.max}
77
+ .value=${String(coordinateValue)}
78
+ step=${Math.pow(10, coordinateDefinition.digits ? -coordinateDefinition.digits : 0)}
79
+ ${listen('input', (event) => {
80
+ const element = extractEventTarget(event, HTMLInputElement);
81
+ const newValue = Number(element.value);
82
+ if (isNaN(newValue)) {
83
+ return;
84
+ }
85
+ dispatch(new events.valueChange(newValue));
86
+ })}
87
+ />
88
+ <${ViraInput.assign({
89
+ value: String(coordinateValue),
90
+ })}
91
+ ${listen(ViraInput.events.valueChange, (event) => {
92
+ const newValue = Number(event.detail);
93
+ if (isNaN(newValue)) {
94
+ return;
95
+ }
96
+ dispatch(new events.valueChange(newValue));
97
+ })}
98
+ ></${ViraInput}>
99
+ `;
100
+ },
101
+ });
@@ -0,0 +1,10 @@
1
+ import { type CalculatedContrast, type FontWeight } from '../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 []>;
@@ -0,0 +1,96 @@
1
+ /* node:coverage disable */
2
+ import { classMap, css, defineElement, html, unsafeCSS } from 'element-vir';
3
+ import { contrastLevelLabel, ContrastLevelName, contrastLevels, } from '../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
+ });
package/dist/index.d.ts CHANGED
@@ -1,3 +1,9 @@
1
- export * from './color-formats.js';
2
- export * from './color-name-length.js';
3
- export * from './color.js';
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';
5
+ export * from './elements/vir-all-color-space-sliders.element.js';
6
+ export * from './elements/vir-color-format-sliders.element.js';
7
+ export * from './elements/vir-color-pair.element.js';
8
+ export * from './elements/vir-color-slider.element.js';
9
+ export * from './elements/vir-contrast-indicator.element.js';
package/dist/index.js CHANGED
@@ -1,3 +1,9 @@
1
- export * from './color-formats.js';
2
- export * from './color-name-length.js';
3
- export * from './color.js';
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';
5
+ export * from './elements/vir-all-color-space-sliders.element.js';
6
+ export * from './elements/vir-color-format-sliders.element.js';
7
+ export * from './elements/vir-color-pair.element.js';
8
+ export * from './elements/vir-color-slider.element.js';
9
+ export * from './elements/vir-contrast-indicator.element.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electrovir/color",
3
- "version": "0.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "A wrapper for culori with an extremely simple API.",
5
5
  "keywords": [
6
6
  "color",
@@ -40,7 +40,7 @@
40
40
  "publish": "virmator publish npm run test:all",
41
41
  "start": "virmator frontend",
42
42
  "test": "virmator test web",
43
- "test:all": "npm run compile && concurrently --colors --kill-others-on-fail -c auto --names tests,spelling,format,docs,deps,lint,build \"npm run test:coverage\" \"npm run test:spelling\" \"npm run test:format\" \"npm run test:docs\" \"npm run test:deps\" \"npm run test:lint\" \"npm run build\"",
43
+ "test:all": "npm run compile && runstorm --names tests,spelling,format,docs,deps,lint,build \"npm run test:coverage\" \"npm run test:spelling\" \"npm run test:format\" \"npm run test:docs\" \"npm run test:deps\" \"npm run test:lint\" \"npm run build\"",
44
44
  "test:coverage": "npm run test coverage",
45
45
  "test:deps": "virmator deps check",
46
46
  "test:docs": "virmator docs check",
@@ -50,55 +50,66 @@
50
50
  "test:update": "npm test update"
51
51
  },
52
52
  "dependencies": {
53
- "@augment-vir/assert": "^31.23.3",
54
- "@augment-vir/common": "^31.23.3",
55
- "color-name": "^2.0.0",
56
- "culori": "^4.0.1",
57
- "type-fest": "^4.41.0"
53
+ "@augment-vir/assert": "^31.57.3",
54
+ "@augment-vir/common": "^31.57.3",
55
+ "@augment-vir/web": "^31.57.3",
56
+ "apca-w3": "^0.1.9",
57
+ "color-name": "^2.1.0",
58
+ "culori": "^4.0.2",
59
+ "type-fest": "^5.3.1"
58
60
  },
59
61
  "devDependencies": {
60
- "@augment-vir/test": "^31.23.3",
61
- "@eslint/eslintrc": "^3.3.1",
62
- "@eslint/js": "^9.28.0",
63
- "@stylistic/eslint-plugin": "^4.4.1",
62
+ "@augment-vir/test": "^31.57.3",
63
+ "@eslint/eslintrc": "^3.3.3",
64
+ "@eslint/js": "^9.39.2",
65
+ "@stylistic/eslint-plugin": "^5.6.1",
64
66
  "@stylistic/eslint-plugin-ts": "^4.4.1",
65
67
  "@types/color-name": "^2.0.0",
66
- "@types/culori": "^4.0.0",
67
- "@typescript-eslint/eslint-plugin": "^8.33.1",
68
+ "@types/culori": "^4.0.1",
69
+ "@typescript-eslint/eslint-plugin": "^8.51.0",
68
70
  "@web/dev-server-esbuild": "^1.0.4",
69
71
  "@web/test-runner": "^0.20.2",
70
72
  "@web/test-runner-commands": "^0.9.0",
71
- "@web/test-runner-playwright": "^0.11.0",
73
+ "@web/test-runner-playwright": "^0.11.1",
72
74
  "@web/test-runner-visual-regression": "^0.10.0",
73
- "cspell": "^9.0.2",
74
- "dependency-cruiser": "^16.10.2",
75
- "element-vir": "^26.0.0",
76
- "esbuild": "^0.25.5",
77
- "eslint": "^9.28.0",
78
- "eslint-config-prettier": "^10.1.5",
79
- "eslint-plugin-jsdoc": "^50.7.1",
75
+ "cspell": "^9.4.0",
76
+ "dependency-cruiser": "^17.3.5",
77
+ "element-vir": "^26.14.0",
78
+ "esbuild": "^0.27.2",
79
+ "eslint": "^9.39.2",
80
+ "eslint-config-prettier": "^10.1.8",
81
+ "eslint-plugin-jsdoc": "^61.5.0",
80
82
  "eslint-plugin-monorepo-cop": "^1.0.2",
81
- "eslint-plugin-playwright": "^2.2.0",
82
- "eslint-plugin-prettier": "^5.4.1",
83
+ "eslint-plugin-playwright": "^2.4.0",
84
+ "eslint-plugin-prettier": "^5.5.4",
83
85
  "eslint-plugin-require-extensions": "^0.1.3",
84
- "eslint-plugin-sonarjs": "^3.0.2",
85
- "eslint-plugin-unicorn": "^59.0.1",
86
- "execute-in-browser": "^1.0.7",
86
+ "eslint-plugin-sonarjs": "^3.0.5",
87
+ "eslint-plugin-unicorn": "^62.0.0",
88
+ "execute-in-browser": "^1.0.9",
87
89
  "istanbul-smart-text-reporter": "^1.1.5",
90
+ "lit-css-vars": "^3.0.11",
88
91
  "markdown-code-example-inserter": "^3.0.3",
89
- "prettier": "^3.3.3",
92
+ "npm-check-updates": "^19.2.0",
93
+ "prettier": "~3.3.3",
90
94
  "prettier-plugin-interpolated-html-tags": "^2.0.1",
91
- "prettier-plugin-jsdoc": "^1.3.2",
92
- "prettier-plugin-multiline-arrays": "^4.0.3",
93
- "prettier-plugin-organize-imports": "^4.1.0",
94
- "prettier-plugin-packagejson": "^2.5.15",
95
+ "prettier-plugin-jsdoc": "^1.8.0",
96
+ "prettier-plugin-multiline-arrays": "^4.1.3",
97
+ "prettier-plugin-organize-imports": "^4.3.0",
98
+ "prettier-plugin-packagejson": "^2.5.20",
95
99
  "prettier-plugin-sort-json": "^4.1.1",
96
- "prettier-plugin-toml": "^2.0.5",
97
- "typedoc": "^0.28.5",
98
- "typescript": "^5.8.3",
99
- "typescript-eslint": "^8.33.1",
100
- "virmator": "^13.15.4",
101
- "vite": "^6.3.5"
100
+ "prettier-plugin-toml": "^2.0.6",
101
+ "runstorm": "^1.0.0",
102
+ "typedoc": "^0.28.15",
103
+ "typescript": "^5.9.3",
104
+ "typescript-eslint": "^8.51.0",
105
+ "vira": "^28.16.0",
106
+ "virmator": "^14.4.0",
107
+ "vite": "^7.3.0"
108
+ },
109
+ "peerDependencies": {
110
+ "element-vir": ">=26",
111
+ "lit-css-vars": ">=3",
112
+ "vira": ">=28"
102
113
  },
103
114
  "engines": {
104
115
  "node": ">=22"