@rokkit/core 1.3.1 → 1.3.3

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 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.1",
3
+ "version": "1.3.3",
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.1"
49
+ "@rokkit/icons": "1.3.3"
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.
@@ -284,8 +301,7 @@ export class Theme {
284
301
  const palette = colors[this.#mapping[role]]
285
302
  const fill = palette?.['500']
286
303
  const y = fill !== undefined ? relativeLuminance(fill, this.#adapter.name) : null
287
- if (y === null) return ON_COLOR_LIGHT
288
- return y >= ON_COLOR_Y_CROSSOVER ? ON_COLOR_DARK : ON_COLOR_LIGHT
304
+ return pickOnColor(y)
289
305
  }
290
306
 
291
307
  #surfaceInkAlias(role: 'surface' | 'ink'): Record<string, string> {