@sorb/seed 0.3.0 → 0.4.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 +2 -2
- package/src/emit/sorbMantine.js +116 -0
- package/src/emit/sorbMantine.test.js +68 -0
- package/src/emit/sorbMatSys.js +159 -0
- package/src/emit/sorbMatSys.test.js +75 -0
- package/src/emit/sorbMui.js +165 -0
- package/src/emit/sorbMui.test.js +102 -0
- package/src/emit/sorbPrimevue.js +240 -0
- package/src/emit/sorbPrimevue.test.js +130 -0
- package/src/emit/sorbShadcn.js +186 -0
- package/src/emit/sorbShadcn.test.js +102 -0
- package/src/index.js +21 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Tests for the Sorb shadcn/ui theme format (`sorb/shadcn-theme`).
|
|
2
|
+
// Run: node --test
|
|
3
|
+
import { test } from 'node:test'
|
|
4
|
+
import assert from 'node:assert/strict'
|
|
5
|
+
import { SORB_SHADCN, sorbShadcn, shadcnRootLines, shadcnThemeInlineLines } from './sorbShadcn.js'
|
|
6
|
+
|
|
7
|
+
// A fabricated dictionary carrying the JJ role tokens the format resolves
|
|
8
|
+
// against (identity roleMap case — the JJ reference kit already uses
|
|
9
|
+
// canonical role ids from `@sorb/core`'s DEFAULT_ROLE_IDS).
|
|
10
|
+
const JJ_ROLE_TOKEN_IDS = [
|
|
11
|
+
'color.surface', 'color.surface-raised', 'color.surface-sunken',
|
|
12
|
+
'color.ink', 'color.ink-muted',
|
|
13
|
+
'color.brand', 'color.brand-contrast',
|
|
14
|
+
'color.accent', 'color.accent-contrast',
|
|
15
|
+
'color.danger', 'color.border', 'color.focus-ring',
|
|
16
|
+
'color.white',
|
|
17
|
+
'radius.control',
|
|
18
|
+
]
|
|
19
|
+
const dictionary = { allTokens: JJ_ROLE_TOKEN_IDS.map((id) => ({ path: id.split('.') })) }
|
|
20
|
+
|
|
21
|
+
test('format id is sorb/shadcn-theme', () => {
|
|
22
|
+
assert.equal(SORB_SHADCN, 'sorb/shadcn-theme')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test('root map: identity roleMap resolves every shadcn var to its canonical role\'s var()', () => {
|
|
26
|
+
const css = sorbShadcn({ dictionary })
|
|
27
|
+
assert.match(css, /--background: var\(--color-surface\);/)
|
|
28
|
+
assert.match(css, /--foreground: var\(--color-ink\);/)
|
|
29
|
+
assert.match(css, /--primary: var\(--color-brand\);/)
|
|
30
|
+
assert.match(css, /--primary-foreground: var\(--color-brand-contrast\);/)
|
|
31
|
+
assert.match(css, /--destructive: var\(--color-danger\);/)
|
|
32
|
+
assert.match(css, /--border: var\(--color-border\);/)
|
|
33
|
+
assert.match(css, /--input: var\(--color-border\);/)
|
|
34
|
+
assert.match(css, /--ring: var\(--color-focus-ring\);/)
|
|
35
|
+
assert.match(css, /--radius: var\(--radius-control\);/)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('root map: destructive-foreground falls back to the color.white primitive (role-contract gap)', () => {
|
|
39
|
+
const css = sorbShadcn({ dictionary })
|
|
40
|
+
assert.match(css, /--destructive-foreground: var\(--color-white\);/)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('root map: options.roleMap overrides a canonical role id to a non-JJ kit token', () => {
|
|
44
|
+
const css = sorbShadcn({
|
|
45
|
+
dictionary: { allTokens: [{ path: ['brand', 'primary'] }, ...dictionary.allTokens] },
|
|
46
|
+
options: { roleMap: { 'color.brand': 'brand.primary' } },
|
|
47
|
+
})
|
|
48
|
+
assert.match(css, /--primary: var\(--brand-primary\);/)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
test('options.destructiveForeground / options.radiusRole override the non-role defaults', () => {
|
|
52
|
+
const css = sorbShadcn({
|
|
53
|
+
dictionary: { allTokens: [{ path: ['ink', 'onDanger'] }, { path: ['radius', 'lg'] }, ...dictionary.allTokens] },
|
|
54
|
+
options: { destructiveForeground: 'ink.onDanger', radiusRole: 'radius.lg' },
|
|
55
|
+
})
|
|
56
|
+
assert.match(css, /--destructive-foreground: var\(--ink-onDanger\);/)
|
|
57
|
+
assert.match(css, /--radius: var\(--radius-lg\);/)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
test('emits an @theme inline block with the calc() radius scale, chained onto shadcn vars (not raw tokens)', () => {
|
|
61
|
+
const css = sorbShadcn({ dictionary })
|
|
62
|
+
assert.match(css, /@theme inline \{/)
|
|
63
|
+
assert.match(css, /--color-background: var\(--background\);/)
|
|
64
|
+
assert.match(css, /--color-primary-foreground: var\(--primary-foreground\);/)
|
|
65
|
+
assert.match(css, /--radius-sm: calc\(var\(--radius\) - 4px\);/)
|
|
66
|
+
assert.match(css, /--radius-md: calc\(var\(--radius\) - 2px\);/)
|
|
67
|
+
assert.match(css, /--radius-lg: var\(--radius\);/)
|
|
68
|
+
assert.match(css, /--radius-xl: calc\(var\(--radius\) \+ 4px\);/)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test('every emitted value is a var()/calc(var()) reference — never a baked literal (live-preview invariant)', () => {
|
|
72
|
+
const css = sorbShadcn({ dictionary })
|
|
73
|
+
const declLines = css.split('\n').filter((l) => /^\s*--[a-z-]+:/.test(l))
|
|
74
|
+
assert.ok(declLines.length > 0)
|
|
75
|
+
for (const line of declLines) {
|
|
76
|
+
assert.match(line, /:\s*(var\(--[a-zA-Z0-9-]+\)|calc\(var\(--[a-zA-Z0-9-]+\)[^)]*\))\s*;\s*$/, `unexpected literal: ${line}`)
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
test('warns (does not throw) when a resolved token id is not in the dictionary', () => {
|
|
81
|
+
const warnings = []
|
|
82
|
+
const origWarn = console.warn
|
|
83
|
+
console.warn = (msg) => warnings.push(msg)
|
|
84
|
+
try {
|
|
85
|
+
const css = sorbShadcn({ dictionary: { allTokens: [{ path: ['color', 'surface'] }] } })
|
|
86
|
+
assert.match(css, /--background: var\(--color-surface\);/) // still emits
|
|
87
|
+
} finally {
|
|
88
|
+
console.warn = origWarn
|
|
89
|
+
}
|
|
90
|
+
assert.ok(warnings.length > 0)
|
|
91
|
+
assert.match(warnings[0], /unresolved token id/)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
test('shadcnRootLines / shadcnThemeInlineLines are pure and independently testable', () => {
|
|
95
|
+
const rootLines = shadcnRootLines({})
|
|
96
|
+
assert.equal(rootLines.length, SHADCN_ROOT_LINE_COUNT)
|
|
97
|
+
const themeLines = shadcnThemeInlineLines()
|
|
98
|
+
assert.equal(themeLines.filter((l) => l.includes('--radius-')).length, 4)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
// 18 color-role pairs + destructive-foreground + radius
|
|
102
|
+
const SHADCN_ROOT_LINE_COUNT = 20
|
package/src/index.js
CHANGED
|
@@ -32,3 +32,24 @@ export {
|
|
|
32
32
|
tailwindV3Slot,
|
|
33
33
|
sorbTailwindV3,
|
|
34
34
|
} from './emit/sorbFormat.js'
|
|
35
|
+
|
|
36
|
+
// Mantine v7 CSS-var override format (framework-targets-productization T2) —
|
|
37
|
+
// promoted from `sorb-demo-mantine/sd/mantine-format.js`.
|
|
38
|
+
export { SORB_MANTINE_VARS, MANTINE_VAR_MAP, sorbMantineVars } from './emit/sorbMantine.js'
|
|
39
|
+
|
|
40
|
+
// shadcn/ui theme format (framework-targets-productization T1) — promoted
|
|
41
|
+
// from `sorb-demo-tailwind`'s hand-authored `shadcn-map.css`+`shadcn-theme.css`.
|
|
42
|
+
export { SORB_SHADCN, sorbShadcn, shadcnRootLines, shadcnThemeInlineLines } from './emit/sorbShadcn.js'
|
|
43
|
+
|
|
44
|
+
// MUI v6 CSS-var override format (framework-targets-productization T3) —
|
|
45
|
+
// promoted from `sorb-demo-mui/sd.config.js:18-86`.
|
|
46
|
+
export { SORB_MUI_VARS, MUI_VAR_MAP, sorbMuiVars } from './emit/sorbMui.js'
|
|
47
|
+
|
|
48
|
+
// Angular Material 20 M3 system-variable override format
|
|
49
|
+
// (framework-targets-productization T5) — promoted from
|
|
50
|
+
// `sorb-demo-angular/sd.config.js:96-113`.
|
|
51
|
+
export { SORB_MAT_SYS_VARS, MAT_SYS_MAP, sorbMatSysVars } from './emit/sorbMatSys.js'
|
|
52
|
+
|
|
53
|
+
// PrimeVue v4 preset format (framework-targets-productization T4) — the first
|
|
54
|
+
// JS-emitting target format; generated from `sorb-demo-primevue/src/jjPreset.js`.
|
|
55
|
+
export { SORB_PRIMEVUE_PRESET, PRIMEVUE_ROLE_TREE, sorbPrimevuePreset } from './emit/sorbPrimevue.js'
|