@rokkit/core 1.3.0 → 1.3.2
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/index.d.ts +1 -1
- package/dist/theme.d.ts +28 -0
- package/package.json +2 -2
- package/src/index.js +1 -1
- package/src/theme.ts +22 -5
- package/src/utils.js +6 -3
package/dist/index.d.ts
CHANGED
|
@@ -5,11 +5,11 @@ export * from "./utils.js";
|
|
|
5
5
|
export * from "./nested.js";
|
|
6
6
|
export * from "./string.js";
|
|
7
7
|
export * from "./theme.js";
|
|
8
|
-
export { ColorSpace } from "./color-space.js";
|
|
9
8
|
export { FieldMapper } from "./field-mapper.js";
|
|
10
9
|
export { createEmitter } from "./events.js";
|
|
11
10
|
export { getLineTypes } from "./connector.js";
|
|
12
11
|
export { generateTicks } from "./ticks.js";
|
|
13
12
|
export { getNestedFields } from "./mapping.js";
|
|
13
|
+
export { ColorSpace, relativeLuminance } from "./color-space.js";
|
|
14
14
|
export { getItemAtIndex, getIndexForItem } from "./mapped-items.js";
|
|
15
15
|
export { weekdays, getCalendarDays } from "./calendar.js";
|
package/dist/theme.d.ts
CHANGED
|
@@ -46,6 +46,34 @@ export declare function themeRules(mapping: {
|
|
|
46
46
|
* @returns {Array} Array of shortcut definitions
|
|
47
47
|
*/
|
|
48
48
|
export declare function contrastShortcuts(name: any, onColor?: string): (RegExp | (([, end]: [any, any]) => string))[][];
|
|
49
|
+
/**
|
|
50
|
+
* Near-black / near-white on-color endpoints. Not pure #000/#fff — a hair of
|
|
51
|
+
* lift reads softer on a saturated fill while still clearing AA (near-black is
|
|
52
|
+
* dark enough that even a mid-bright vermillion 500 reaches ~5:1).
|
|
53
|
+
*
|
|
54
|
+
* Exported so consumers (e.g. the demo skin engine) reuse the EXACT library
|
|
55
|
+
* derivation rather than re-deriving on-colors and drifting from `Theme`.
|
|
56
|
+
*/
|
|
57
|
+
export declare const ON_COLOR_DARK = "#161616";
|
|
58
|
+
export declare const ON_COLOR_LIGHT = "#fafafa";
|
|
59
|
+
/**
|
|
60
|
+
* Fill luminance where ON_COLOR_DARK and ON_COLOR_LIGHT give equal WCAG contrast:
|
|
61
|
+
* solve (Yf+0.05)² = (Y_dark+0.05)(Y_light+0.05) with Y_dark≈0.0074, Y_light≈0.956
|
|
62
|
+
* → Yf ≈ 0.190. Fills at/above this take dark text; below take light text. (Truly
|
|
63
|
+
* mid-luminance fills near this point clear neither pair at AA — that's the
|
|
64
|
+
* palette author's choice to make, per "pick a 500 where black or white works".)
|
|
65
|
+
*/
|
|
66
|
+
export declare const ON_COLOR_Y_CROSSOVER = 0.19;
|
|
67
|
+
/**
|
|
68
|
+
* Pick the readable on-color hex for a fill of relative luminance `y`.
|
|
69
|
+
* Bright fills (y at/above the crossover) take near-black text; dark fills take
|
|
70
|
+
* near-white. A null `y` means the fill couldn't be measured → near-white
|
|
71
|
+
* (matches the historical default).
|
|
72
|
+
*
|
|
73
|
+
* @param {number | null} y - relative luminance (0–1) of the fill, or null
|
|
74
|
+
* @returns {string} on-color hex
|
|
75
|
+
*/
|
|
76
|
+
export declare function pickOnColor(y: number | null): string;
|
|
49
77
|
/**
|
|
50
78
|
* Theme class for managing color palettes, mappings, and semantic shortcuts.
|
|
51
79
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rokkit/core",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Contains core utility functions and classes that can be used in various components.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -46,6 +46,6 @@
|
|
|
46
46
|
"ramda": "^0.32.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@rokkit/icons": "1.3.
|
|
49
|
+
"@rokkit/icons": "1.3.2"
|
|
50
50
|
}
|
|
51
51
|
}
|
package/src/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export * from './nested.js'
|
|
|
11
11
|
export * from './string.js'
|
|
12
12
|
// skipcq: JS-E1004 - Needed for exposing all functions
|
|
13
13
|
export * from './theme.js'
|
|
14
|
-
export { ColorSpace } from './color-space.js'
|
|
14
|
+
export { ColorSpace, relativeLuminance } from './color-space.js'
|
|
15
15
|
export { FieldMapper } from './field-mapper.js'
|
|
16
16
|
export { getItemAtIndex, getIndexForItem } from './mapped-items.js'
|
|
17
17
|
export { createEmitter } from './events.js'
|
package/src/theme.ts
CHANGED
|
@@ -95,9 +95,12 @@ export function contrastShortcuts(name, onColor = '#fafafa') {
|
|
|
95
95
|
* Near-black / near-white on-color endpoints. Not pure #000/#fff — a hair of
|
|
96
96
|
* lift reads softer on a saturated fill while still clearing AA (near-black is
|
|
97
97
|
* dark enough that even a mid-bright vermillion 500 reaches ~5:1).
|
|
98
|
+
*
|
|
99
|
+
* Exported so consumers (e.g. the demo skin engine) reuse the EXACT library
|
|
100
|
+
* derivation rather than re-deriving on-colors and drifting from `Theme`.
|
|
98
101
|
*/
|
|
99
|
-
const ON_COLOR_DARK = '#161616'
|
|
100
|
-
const ON_COLOR_LIGHT = '#fafafa'
|
|
102
|
+
export const ON_COLOR_DARK = '#161616'
|
|
103
|
+
export const ON_COLOR_LIGHT = '#fafafa'
|
|
101
104
|
/**
|
|
102
105
|
* Fill luminance where ON_COLOR_DARK and ON_COLOR_LIGHT give equal WCAG contrast:
|
|
103
106
|
* solve (Yf+0.05)² = (Y_dark+0.05)(Y_light+0.05) with Y_dark≈0.0074, Y_light≈0.956
|
|
@@ -105,7 +108,21 @@ const ON_COLOR_LIGHT = '#fafafa'
|
|
|
105
108
|
* mid-luminance fills near this point clear neither pair at AA — that's the
|
|
106
109
|
* palette author's choice to make, per "pick a 500 where black or white works".)
|
|
107
110
|
*/
|
|
108
|
-
const ON_COLOR_Y_CROSSOVER = 0.19
|
|
111
|
+
export const ON_COLOR_Y_CROSSOVER = 0.19
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Pick the readable on-color hex for a fill of relative luminance `y`.
|
|
115
|
+
* Bright fills (y at/above the crossover) take near-black text; dark fills take
|
|
116
|
+
* near-white. A null `y` means the fill couldn't be measured → near-white
|
|
117
|
+
* (matches the historical default).
|
|
118
|
+
*
|
|
119
|
+
* @param {number | null} y - relative luminance (0–1) of the fill, or null
|
|
120
|
+
* @returns {string} on-color hex
|
|
121
|
+
*/
|
|
122
|
+
export function pickOnColor(y: number | null): string {
|
|
123
|
+
if (y === null) return ON_COLOR_LIGHT
|
|
124
|
+
return y >= ON_COLOR_Y_CROSSOVER ? ON_COLOR_DARK : ON_COLOR_LIGHT
|
|
125
|
+
}
|
|
109
126
|
|
|
110
127
|
/**
|
|
111
128
|
* Fallback chain for nullable color mappings.
|
|
@@ -270,6 +287,7 @@ export class Theme {
|
|
|
270
287
|
if (name === 'on-primary') {
|
|
271
288
|
return this.#adapter.wrap(this.#onColorHex('primary', colors))
|
|
272
289
|
}
|
|
290
|
+
/* v8 ignore next -- on-primary is the only 'derived' token, so this default is unreachable */
|
|
273
291
|
return undefined
|
|
274
292
|
}
|
|
275
293
|
|
|
@@ -283,8 +301,7 @@ export class Theme {
|
|
|
283
301
|
const palette = colors[this.#mapping[role]]
|
|
284
302
|
const fill = palette?.['500']
|
|
285
303
|
const y = fill !== undefined ? relativeLuminance(fill, this.#adapter.name) : null
|
|
286
|
-
|
|
287
|
-
return y >= ON_COLOR_Y_CROSSOVER ? ON_COLOR_DARK : ON_COLOR_LIGHT
|
|
304
|
+
return pickOnColor(y)
|
|
288
305
|
}
|
|
289
306
|
|
|
290
307
|
#surfaceInkAlias(role: 'surface' | 'ink'): Record<string, string> {
|
package/src/utils.js
CHANGED
|
@@ -172,12 +172,13 @@ export function getSnippet(obj, key, defaultSnippet = null) {
|
|
|
172
172
|
/**
|
|
173
173
|
* Resolve which snippet to render for a proxy item.
|
|
174
174
|
*
|
|
175
|
-
*
|
|
175
|
+
* Reads the proxy's `snippet` field (via proxy.get('snippet'), honoring fields.snippet)
|
|
176
|
+
* for a per-item named override first (e.g. item.snippet = 'highlighted').
|
|
176
177
|
* Falls back to the component-level fallback snippet name (e.g. 'itemContent' / 'groupContent').
|
|
177
178
|
* Returns null if neither is found.
|
|
178
179
|
*
|
|
179
180
|
* @param {Record<string, unknown>} snippets - snippets passed to the component
|
|
180
|
-
* @param {{
|
|
181
|
+
* @param {{ get: (key: string) => unknown }} proxy - a ProxyItem; its snippet field is read via proxy.get('snippet')
|
|
181
182
|
* @param {string} [fallback] - fallback snippet name; defaults to ITEM_SNIPPET ('itemContent')
|
|
182
183
|
* @returns {Function | null}
|
|
183
184
|
*/
|
|
@@ -190,7 +191,9 @@ function asSnippet(value) {
|
|
|
190
191
|
}
|
|
191
192
|
|
|
192
193
|
export function resolveSnippet(snippets, proxy, fallback = ITEM_SNIPPET) {
|
|
193
|
-
|
|
194
|
+
// `snippet` is a field-mapped prop like icon/href — read it via the proxy's
|
|
195
|
+
// field accessor (honors fields.snippet), not as a direct property.
|
|
196
|
+
const name = proxy?.get('snippet')
|
|
194
197
|
return asSnippet(name && snippets[name]) || asSnippet(snippets[fallback])
|
|
195
198
|
}
|
|
196
199
|
|