@primitiv-ui/tokens 0.1.29 → 0.1.30

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/README.md CHANGED
@@ -58,7 +58,7 @@ and `dist/index.html` (UI). Stays running and rebuilds on change.
58
58
  ### 4. Load the plugin into Figma desktop (one-time per machine)
59
59
 
60
60
  In Figma desktop: **Plugins → Development → Import plugin from
61
- manifest…** and select
61
+ manifest...** and select
62
62
  `apps/primitiv-sync-figma-plugin/manifest.json`. After this Figma
63
63
  remembers it under **Plugins → Development → Primitiv Sync**.
64
64
 
@@ -110,7 +110,7 @@ backup "real".
110
110
  ## Conventions
111
111
 
112
112
  - Slash-separated Figma variable names (`font-family/heading`) become
113
- nested DTCG groups (`{ "font-family": { "heading": {…} } }`).
113
+ nested DTCG groups (`{ "font-family": { "heading": {...} } }`).
114
114
  - Each token has `$type` and `$value`. Aliases (next cycle) will use
115
115
  DTCG's `{group.sub.name}` reference string.
116
116
  - Colours emit as hex: `#rrggbb` opaque, `#rrggbbaa` translucent.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primitiv-ui/tokens",
3
- "version": "0.1.29",
3
+ "version": "0.1.30",
4
4
  "description": "The DTCG-conformant design-token layer for the Primitiv ecosystem, plus helpers that transform Figma variable exports into DTCG JSON.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -0,0 +1,10 @@
1
+ {
2
+ "breakpoint": {
3
+ "xs": { "$type": "number", "$value": 360 },
4
+ "sm": { "$type": "number", "$value": 640 },
5
+ "md": { "$type": "number", "$value": 768 },
6
+ "lg": { "$type": "number", "$value": 1024 },
7
+ "xl": { "$type": "number", "$value": 1280 },
8
+ "2xl": { "$type": "number", "$value": 1536 }
9
+ }
10
+ }
@@ -0,0 +1,64 @@
1
+ import context from './context.json'
2
+ import primitives from './primitives.json'
3
+
4
+ /*
5
+ * `code.*` is the mono typographic family — the one every colour value, hex,
6
+ * ratio and percentage in Harmoni is set in.
7
+ *
8
+ * Why this needs a test: the family was authored size-first, so it shipped with
9
+ * `font-size` and `line-height` and nothing else. That is invisible in the JSON
10
+ * (a group with two members looks intentional) but it is not a usable family —
11
+ * a Figma text style binds four members, so `code.*` could not be expressed as
12
+ * a text style at all, and `font-family.mono` sat in the primitives with
13
+ * nothing consuming it. This asserts the family is complete *and* that it is
14
+ * the mono one, which is the whole reason it exists apart from `body`.
15
+ */
16
+
17
+ type Mode = 'dense' | 'compact' | 'comfortable' | 'spacious'
18
+ type DtcgNode = { $type?: string; $value?: unknown; [key: string]: unknown }
19
+
20
+ const MODES: Mode[] = ['dense', 'compact', 'comfortable', 'spacious']
21
+ const SIZES = ['xs', 'sm', 'md', 'lg', 'xl'] as const
22
+
23
+ /** The members a Figma text style binds, plus the weight the CSS layer needs. */
24
+ const MEMBERS = {
25
+ 'font-family': 'string',
26
+ 'font-weight': 'number',
27
+ 'font-size': 'number',
28
+ 'line-height': 'number',
29
+ 'font-style': 'string',
30
+ } as const
31
+
32
+ function codeSize(mode: Mode, size: string): DtcgNode {
33
+ const code = (context as Record<Mode, DtcgNode>)[mode].code as DtcgNode
34
+ return code[size] as DtcgNode
35
+ }
36
+
37
+ /** Resolve a DTCG alias (`{font-family.mono}`) against the primitive tree. */
38
+ function resolvePrimitive(ref: string): unknown {
39
+ const path = ref.slice(1, -1).split('.')
40
+ let node: DtcgNode = primitives as DtcgNode
41
+ for (const key of path) node = node[key] as DtcgNode
42
+ return node.$value
43
+ }
44
+
45
+ describe('code typography', () => {
46
+ for (const mode of MODES) {
47
+ for (const size of SIZES) {
48
+ it(`${mode} / code / ${size} is a complete typographic family`, () => {
49
+ const entry = codeSize(mode, size)
50
+ for (const [member, type] of Object.entries(MEMBERS)) {
51
+ const node = entry[member] as DtcgNode | undefined
52
+ expect(node, `${mode}.code.${size}.${member} is missing`).toBeDefined()
53
+ expect(node?.$type).toBe(type)
54
+ }
55
+ })
56
+
57
+ it(`${mode} / code / ${size} is set in the mono face`, () => {
58
+ const family = codeSize(mode, size)['font-family'] as DtcgNode | undefined
59
+ expect(family?.$value).toBe('{font-family.mono}')
60
+ expect(resolvePrimitive(family?.$value as string)).toBe('JetBrains Mono')
61
+ })
62
+ }
63
+ }
64
+ })