@sorb/core 0.2.0 → 0.3.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/package.json +1 -1
- package/src/index.js +88 -1
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -197,6 +197,76 @@ export const TIER_RANK = Object.freeze({ component: 0, semantic: 1, primitive: 2
|
|
|
197
197
|
* `prefers-color-scheme: dark` setting.
|
|
198
198
|
*/
|
|
199
199
|
|
|
200
|
+
/**
|
|
201
|
+
* SEMANTIC-ROLE CONTRACT (framework-targets-productization, T0).
|
|
202
|
+
*
|
|
203
|
+
* The canonical set of role ids a token kit MUST expose for the framework
|
|
204
|
+
* TargetAdapter emit formats (`sorb/mantine-vars`, `sorb/mui-vars`,
|
|
205
|
+
* `sorb/mat-sys-vars`, `sorb/shadcn-theme`, `sorb/primevue-preset`) to emit
|
|
206
|
+
* correctly. Each format maps its framework's own vars (`--mantine-*`, `--mui-*`,
|
|
207
|
+
* `--mat-sys-*`, shadcn vars, PrimeVue preset roots) ONTO these role ids.
|
|
208
|
+
*
|
|
209
|
+
* These are DTCG dot-path ids (→ CSS var `--<kebab>` → preview-payload key
|
|
210
|
+
* `<kebab>`). The Janes Jeans kit (`@metatoy/janes-jeans`) is the reference
|
|
211
|
+
* implementation. A kit using different names supplies `options.roleMap`
|
|
212
|
+
* (role-id → its-own-token-id) to a format rather than forking it.
|
|
213
|
+
*
|
|
214
|
+
* SEMVER: adding a role id here is a MINOR bump; renaming or removing one is a
|
|
215
|
+
* MAJOR bump for @sorb/core AND @sorb/seed — every format consumer depends on
|
|
216
|
+
* this set. Scope = the UNION of the target maps' role columns, not a kit's full
|
|
217
|
+
* token tree; anything beyond this list is kit-private.
|
|
218
|
+
*
|
|
219
|
+
* @typedef {Object} SemanticRoles
|
|
220
|
+
* @property {string[]} color surface/ink/brand/accent/danger/success/border/focus roles.
|
|
221
|
+
* @property {string[]} radius control/card/pill.
|
|
222
|
+
* @property {string[]} shadow raised/overlay.
|
|
223
|
+
* @property {string[]} typography display/heading/body/caption × fontSize/Weight/lineHeight.
|
|
224
|
+
*/
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* The canonical role-id list (T0 reference = the JJ kit's semantic tier).
|
|
228
|
+
* @type {Readonly<{color: string[], radius: string[], shadow: string[], typography: string[]}>}
|
|
229
|
+
*/
|
|
230
|
+
export const DEFAULT_ROLE_IDS = Object.freeze({
|
|
231
|
+
color: Object.freeze([
|
|
232
|
+
'color.surface', 'color.surface-raised', 'color.surface-sunken',
|
|
233
|
+
'color.ink', 'color.ink-muted', 'color.ink-on-brand',
|
|
234
|
+
'color.brand', 'color.brand-hover', 'color.brand-contrast',
|
|
235
|
+
'color.accent', 'color.accent-hover', 'color.accent-contrast',
|
|
236
|
+
'color.danger', 'color.danger-hover', 'color.success', 'color.success-hover',
|
|
237
|
+
'color.focus-ring', 'color.border', 'color.border-subtle', 'color.border-strong',
|
|
238
|
+
]),
|
|
239
|
+
radius: Object.freeze(['radius.control', 'radius.card', 'radius.pill']),
|
|
240
|
+
shadow: Object.freeze(['shadow.raised', 'shadow.overlay']),
|
|
241
|
+
typography: Object.freeze([
|
|
242
|
+
'typography.display.fontSize', 'typography.display.fontWeight', 'typography.display.lineHeight',
|
|
243
|
+
'typography.heading.fontSize', 'typography.heading.fontWeight', 'typography.heading.lineHeight',
|
|
244
|
+
'typography.body.fontSize', 'typography.body.fontWeight', 'typography.body.lineHeight',
|
|
245
|
+
'typography.caption.fontSize', 'typography.caption.fontWeight', 'typography.caption.lineHeight',
|
|
246
|
+
]),
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Flat list of every canonical role id (all tiers), for iteration/validation.
|
|
251
|
+
* @type {readonly string[]}
|
|
252
|
+
*/
|
|
253
|
+
export const ALL_ROLE_IDS = Object.freeze([
|
|
254
|
+
...DEFAULT_ROLE_IDS.color, ...DEFAULT_ROLE_IDS.radius,
|
|
255
|
+
...DEFAULT_ROLE_IDS.shadow, ...DEFAULT_ROLE_IDS.typography,
|
|
256
|
+
])
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Resolve a role id to the kit's actual token id via an optional override map.
|
|
260
|
+
* A format calls `resolveRole('color.brand', options.roleMap)` → the kit's token
|
|
261
|
+
* id (identity when the kit uses canonical ids, i.e. the JJ reference).
|
|
262
|
+
* @param {string} roleId A canonical role id from {@link ALL_ROLE_IDS}.
|
|
263
|
+
* @param {Record<string,string>} [roleMap] role-id → kit-token-id overrides.
|
|
264
|
+
* @returns {string} the kit token id to reference (`var(--<kebab>)`).
|
|
265
|
+
*/
|
|
266
|
+
export function resolveRole(roleId, roleMap) {
|
|
267
|
+
return (roleMap && roleMap[roleId]) || roleId
|
|
268
|
+
}
|
|
269
|
+
|
|
200
270
|
/** Default SOURCE connector id (registered by sorb-seed). @type {string} */
|
|
201
271
|
export const DEFAULT_SOURCE_ID = 'storybook-dom'
|
|
202
272
|
|
|
@@ -243,11 +313,28 @@ export function registerCodeSource(conn) {
|
|
|
243
313
|
}
|
|
244
314
|
|
|
245
315
|
/**
|
|
246
|
-
* Register a TARGET adapter by its `id`.
|
|
316
|
+
* Register a TARGET adapter by its `id`. Minimal shape validation (T0b) — with
|
|
317
|
+
* seven+ adapters registering into one Map, a typo'd `id` or missing
|
|
318
|
+
* `emitFormat` would fail silently at query time; catch it at register time.
|
|
319
|
+
* Throws on a malformed adapter; `console.warn`s (does not throw) on a
|
|
320
|
+
* duplicate-id overwrite so a legitimate re-register in tests/HMR still works.
|
|
247
321
|
* @param {TargetAdapter} adapter
|
|
248
322
|
* @returns {TargetAdapter} the registered adapter.
|
|
249
323
|
*/
|
|
250
324
|
export function registerTarget(adapter) {
|
|
325
|
+
if (!adapter || typeof adapter.id !== 'string' || !adapter.id) {
|
|
326
|
+
throw new Error('registerTarget: adapter.id must be a non-empty string')
|
|
327
|
+
}
|
|
328
|
+
if (typeof adapter.emitFormat !== 'string' || !adapter.emitFormat) {
|
|
329
|
+
throw new Error(`registerTarget(${JSON.stringify(adapter.id)}): emitFormat must be a non-empty string`)
|
|
330
|
+
}
|
|
331
|
+
if (!Array.isArray(adapter.expectPrefixes)) {
|
|
332
|
+
throw new Error(`registerTarget(${JSON.stringify(adapter.id)}): expectPrefixes must be an array`)
|
|
333
|
+
}
|
|
334
|
+
if (connectors.target.has(adapter.id)) {
|
|
335
|
+
// eslint-disable-next-line no-console
|
|
336
|
+
console.warn(`registerTarget: overwriting existing target adapter ${JSON.stringify(adapter.id)}`)
|
|
337
|
+
}
|
|
251
338
|
connectors.target.set(adapter.id, adapter)
|
|
252
339
|
return adapter
|
|
253
340
|
}
|