@radicool/throughline 0.22.0 → 0.24.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.
Files changed (52) hide show
  1. package/README.md +5 -5
  2. package/adapters/codex/prompts/component-builder.md +12 -4
  3. package/adapters/cursor/.cursor/rules/component-builder.mdc +12 -4
  4. package/adapters/generic/skills/component-builder/SKILL.md +12 -4
  5. package/package.json +1 -1
  6. package/references/figma-checks.md +813 -0
  7. package/references/figma-component-standards.md +16 -38
  8. package/references/figma-scripting.md +6 -6
  9. package/references/proof-bundle.md +1 -0
  10. package/references/state-baseline.md +5 -3
  11. package/scripts/README.md +5 -2
  12. package/scripts/build-figma-checks.mjs +111 -0
  13. package/scripts/build-state-baseline.mjs +5 -3
  14. package/scripts/install.mjs +9 -4
  15. package/scripts/lib/component-states.mjs +4 -1
  16. package/scripts/lib/contrast.mjs +5 -2
  17. package/scripts/lib/figma-checks-read.figma.js +174 -0
  18. package/scripts/lib/figma-checks.mjs +385 -0
  19. package/scripts/lib/fixtures/figma-checks/avatar-not-in-table.json +44 -0
  20. package/scripts/lib/fixtures/figma-checks/button-ios-swift-skipped.json +86 -0
  21. package/scripts/lib/fixtures/figma-checks/button-missing-default.json +72 -0
  22. package/scripts/lib/fixtures/figma-checks/button-mui-ring.json +93 -0
  23. package/scripts/lib/fixtures/figma-checks/button-no-focus-variant.json +72 -0
  24. package/scripts/lib/fixtures/figma-checks/button-plain-frames.json +93 -0
  25. package/scripts/lib/fixtures/figma-checks/button-ring-child-not-absolute.json +95 -0
  26. package/scripts/lib/fixtures/figma-checks/button-ring-hidden.json +93 -0
  27. package/scripts/lib/fixtures/figma-checks/button-ring-unbound-colour.json +99 -0
  28. package/scripts/lib/fixtures/figma-checks/button-shadcn-filled.json +93 -0
  29. package/scripts/lib/fixtures/figma-checks/button-sparse.json +135 -0
  30. package/scripts/lib/fixtures/figma-checks/button-spread-zero.json +93 -0
  31. package/scripts/lib/fixtures/figma-checks/button-transparent-ring-child.json +95 -0
  32. package/scripts/lib/fixtures/figma-checks/button-vanilla-inside.json +88 -0
  33. package/scripts/lib/fixtures/figma-checks/button-vanilla-outside.json +88 -0
  34. package/scripts/lib/fixtures/figma-checks/button-wrong-combination.json +93 -0
  35. package/scripts/lib/fixtures/figma-checks/checkbox-checked-axis.real.json +246 -0
  36. package/scripts/lib/fixtures/figma-checks/checkbox-checked-synonym.json +88 -0
  37. package/scripts/lib/fixtures/figma-checks/checkbox-missing-selected.json +80 -0
  38. package/scripts/lib/fixtures/figma-checks/indicator-failed.json +106 -0
  39. package/scripts/lib/fixtures/figma-checks/input-control-layer-missing.json +67 -0
  40. package/scripts/lib/fixtures/figma-checks/input-control-layer-ring-on-wrapper.json +80 -0
  41. package/scripts/lib/fixtures/figma-checks/input-control-layer.json +80 -0
  42. package/scripts/lib/fixtures/figma-checks/input-mui-weight-unbound.json +67 -0
  43. package/scripts/lib/fixtures/figma-checks/input-mui.json +67 -0
  44. package/scripts/lib/fixtures/figma-checks/ring-single-mode.json +112 -0
  45. package/scripts/lib/fixtures/figma-checks/ring-translucent.json +111 -0
  46. package/scripts/lib/fixtures/figma-checks/sample-button.real.json +1498 -0
  47. package/scripts/lib/fixtures/figma-checks/sample-ring-on-muted-raw.json +113 -0
  48. package/scripts/lib/fixtures/figma-checks/sample-ring-passes.json +169 -0
  49. package/scripts/lib/fixtures/figma-checks/surface-missing.json +108 -0
  50. package/scripts/lib/fixtures/figma-checks/surface-single-mode.json +112 -0
  51. package/scripts/lib/fixtures/figma-checks/surface-translucent.json +112 -0
  52. package/scripts/lib/fixtures/figma-checks/zygarden-ring-light-fails.json +113 -0
@@ -0,0 +1,72 @@
1
+ {
2
+ "covers": "zero focus variants on an in-scope component is not a pass",
3
+ "expect": {
4
+ "name": "Button",
5
+ "matrix": {
6
+ "variant": [
7
+ "primary"
8
+ ],
9
+ "state": [
10
+ "default",
11
+ "hover",
12
+ "active",
13
+ "disabled"
14
+ ]
15
+ },
16
+ "uiFramework": "shadcn"
17
+ },
18
+ "snapshot": {
19
+ "type": "COMPONENT_SET",
20
+ "variantGroupProperties": {
21
+ "Variant": {
22
+ "values": [
23
+ "Primary"
24
+ ]
25
+ },
26
+ "State": {
27
+ "values": [
28
+ "Default",
29
+ "Hover",
30
+ "Active",
31
+ "Disabled"
32
+ ]
33
+ }
34
+ },
35
+ "children": [
36
+ {
37
+ "type": "COMPONENT",
38
+ "variantProperties": {
39
+ "Variant": "Primary",
40
+ "State": "Default"
41
+ }
42
+ },
43
+ {
44
+ "type": "COMPONENT",
45
+ "variantProperties": {
46
+ "Variant": "Primary",
47
+ "State": "Hover"
48
+ }
49
+ },
50
+ {
51
+ "type": "COMPONENT",
52
+ "variantProperties": {
53
+ "Variant": "Primary",
54
+ "State": "Active"
55
+ }
56
+ },
57
+ {
58
+ "type": "COMPONENT",
59
+ "variantProperties": {
60
+ "Variant": "Primary",
61
+ "State": "Disabled"
62
+ }
63
+ }
64
+ ]
65
+ },
66
+ "expected": {
67
+ "structural-read-back": "pass",
68
+ "state-baseline": "fail",
69
+ "focus-indicator": "fail",
70
+ "focus-contrast": "skip"
71
+ }
72
+ }
@@ -0,0 +1,93 @@
1
+ {
2
+ "covers": "plain FRAMEs instead of a COMPONENT_SET of COMPONENTs",
3
+ "expect": {
4
+ "name": "Button",
5
+ "matrix": {
6
+ "variant": [
7
+ "primary"
8
+ ],
9
+ "state": [
10
+ "default",
11
+ "hover",
12
+ "focus",
13
+ "active",
14
+ "disabled"
15
+ ]
16
+ },
17
+ "uiFramework": "shadcn"
18
+ },
19
+ "snapshot": {
20
+ "type": "FRAME",
21
+ "variantGroupProperties": {
22
+ "Variant": {
23
+ "values": [
24
+ "Primary"
25
+ ]
26
+ },
27
+ "State": {
28
+ "values": [
29
+ "Default",
30
+ "Hover",
31
+ "Focus",
32
+ "Active",
33
+ "Disabled"
34
+ ]
35
+ }
36
+ },
37
+ "children": [
38
+ {
39
+ "type": "FRAME",
40
+ "variantProperties": {
41
+ "Variant": "Primary",
42
+ "State": "Default"
43
+ }
44
+ },
45
+ {
46
+ "type": "FRAME",
47
+ "variantProperties": {
48
+ "Variant": "Primary",
49
+ "State": "Hover"
50
+ }
51
+ },
52
+ {
53
+ "type": "FRAME",
54
+ "variantProperties": {
55
+ "Variant": "Primary",
56
+ "State": "Focus"
57
+ },
58
+ "effects": [
59
+ {
60
+ "type": "DROP_SHADOW",
61
+ "visible": true,
62
+ "spread": 3,
63
+ "colorVariable": "Color/Border/Focus"
64
+ }
65
+ ],
66
+ "strokeAlign": "INSIDE",
67
+ "strokeVariables": [],
68
+ "strokeWeightBound": false,
69
+ "children": []
70
+ },
71
+ {
72
+ "type": "FRAME",
73
+ "variantProperties": {
74
+ "Variant": "Primary",
75
+ "State": "Active"
76
+ }
77
+ },
78
+ {
79
+ "type": "FRAME",
80
+ "variantProperties": {
81
+ "Variant": "Primary",
82
+ "State": "Disabled"
83
+ }
84
+ }
85
+ ]
86
+ },
87
+ "expected": {
88
+ "structural-read-back": "fail",
89
+ "state-baseline": "pass",
90
+ "focus-indicator": "fail",
91
+ "focus-contrast": "skip"
92
+ }
93
+ }
@@ -0,0 +1,95 @@
1
+ {
2
+ "covers": "ring child that is in flow, not ABSOLUTE",
3
+ "expect": {
4
+ "name": "Button",
5
+ "matrix": {
6
+ "variant": [
7
+ "primary"
8
+ ],
9
+ "state": [
10
+ "default",
11
+ "hover",
12
+ "focus",
13
+ "active",
14
+ "disabled"
15
+ ]
16
+ },
17
+ "uiFramework": "shadcn"
18
+ },
19
+ "snapshot": {
20
+ "type": "COMPONENT_SET",
21
+ "variantGroupProperties": {
22
+ "Variant": {
23
+ "values": [
24
+ "Primary"
25
+ ]
26
+ },
27
+ "State": {
28
+ "values": [
29
+ "Default",
30
+ "Hover",
31
+ "Focus",
32
+ "Active",
33
+ "Disabled"
34
+ ]
35
+ }
36
+ },
37
+ "children": [
38
+ {
39
+ "type": "COMPONENT",
40
+ "variantProperties": {
41
+ "Variant": "Primary",
42
+ "State": "Default"
43
+ }
44
+ },
45
+ {
46
+ "type": "COMPONENT",
47
+ "variantProperties": {
48
+ "Variant": "Primary",
49
+ "State": "Hover"
50
+ }
51
+ },
52
+ {
53
+ "type": "COMPONENT",
54
+ "variantProperties": {
55
+ "Variant": "Primary",
56
+ "State": "Focus"
57
+ },
58
+ "effects": [],
59
+ "strokeAlign": "INSIDE",
60
+ "strokeVariables": [],
61
+ "strokeWeightBound": false,
62
+ "children": [
63
+ {
64
+ "layoutPositioning": "AUTO",
65
+ "strokeAlign": "OUTSIDE",
66
+ "strokeVariables": [
67
+ "border/focus"
68
+ ],
69
+ "strokeWeightBound": true
70
+ }
71
+ ]
72
+ },
73
+ {
74
+ "type": "COMPONENT",
75
+ "variantProperties": {
76
+ "Variant": "Primary",
77
+ "State": "Active"
78
+ }
79
+ },
80
+ {
81
+ "type": "COMPONENT",
82
+ "variantProperties": {
83
+ "Variant": "Primary",
84
+ "State": "Disabled"
85
+ }
86
+ }
87
+ ]
88
+ },
89
+ "expected": {
90
+ "structural-read-back": "pass",
91
+ "state-baseline": "pass",
92
+ "focus-indicator": "fail",
93
+ "focus-contrast": "skip"
94
+ }
95
+ }
@@ -0,0 +1,93 @@
1
+ {
2
+ "covers": "shadow with visible: false",
3
+ "expect": {
4
+ "name": "Button",
5
+ "matrix": {
6
+ "variant": [
7
+ "primary"
8
+ ],
9
+ "state": [
10
+ "default",
11
+ "hover",
12
+ "focus",
13
+ "active",
14
+ "disabled"
15
+ ]
16
+ },
17
+ "uiFramework": "shadcn"
18
+ },
19
+ "snapshot": {
20
+ "type": "COMPONENT_SET",
21
+ "variantGroupProperties": {
22
+ "Variant": {
23
+ "values": [
24
+ "Primary"
25
+ ]
26
+ },
27
+ "State": {
28
+ "values": [
29
+ "Default",
30
+ "Hover",
31
+ "Focus",
32
+ "Active",
33
+ "Disabled"
34
+ ]
35
+ }
36
+ },
37
+ "children": [
38
+ {
39
+ "type": "COMPONENT",
40
+ "variantProperties": {
41
+ "Variant": "Primary",
42
+ "State": "Default"
43
+ }
44
+ },
45
+ {
46
+ "type": "COMPONENT",
47
+ "variantProperties": {
48
+ "Variant": "Primary",
49
+ "State": "Hover"
50
+ }
51
+ },
52
+ {
53
+ "type": "COMPONENT",
54
+ "variantProperties": {
55
+ "Variant": "Primary",
56
+ "State": "Focus"
57
+ },
58
+ "effects": [
59
+ {
60
+ "type": "DROP_SHADOW",
61
+ "visible": false,
62
+ "spread": 3,
63
+ "colorVariable": "Color/Border/Focus"
64
+ }
65
+ ],
66
+ "strokeAlign": "INSIDE",
67
+ "strokeVariables": [],
68
+ "strokeWeightBound": false,
69
+ "children": []
70
+ },
71
+ {
72
+ "type": "COMPONENT",
73
+ "variantProperties": {
74
+ "Variant": "Primary",
75
+ "State": "Active"
76
+ }
77
+ },
78
+ {
79
+ "type": "COMPONENT",
80
+ "variantProperties": {
81
+ "Variant": "Primary",
82
+ "State": "Disabled"
83
+ }
84
+ }
85
+ ]
86
+ },
87
+ "expected": {
88
+ "structural-read-back": "pass",
89
+ "state-baseline": "pass",
90
+ "focus-indicator": "fail",
91
+ "focus-contrast": "skip"
92
+ }
93
+ }
@@ -0,0 +1,99 @@
1
+ {
2
+ "covers": "shadow with a raw colour and a variable with no focus word",
3
+ "expect": {
4
+ "name": "Button",
5
+ "matrix": {
6
+ "variant": [
7
+ "primary"
8
+ ],
9
+ "state": [
10
+ "default",
11
+ "hover",
12
+ "focus",
13
+ "active",
14
+ "disabled"
15
+ ]
16
+ },
17
+ "uiFramework": "shadcn"
18
+ },
19
+ "snapshot": {
20
+ "type": "COMPONENT_SET",
21
+ "variantGroupProperties": {
22
+ "Variant": {
23
+ "values": [
24
+ "Primary"
25
+ ]
26
+ },
27
+ "State": {
28
+ "values": [
29
+ "Default",
30
+ "Hover",
31
+ "Focus",
32
+ "Active",
33
+ "Disabled"
34
+ ]
35
+ }
36
+ },
37
+ "children": [
38
+ {
39
+ "type": "COMPONENT",
40
+ "variantProperties": {
41
+ "Variant": "Primary",
42
+ "State": "Default"
43
+ }
44
+ },
45
+ {
46
+ "type": "COMPONENT",
47
+ "variantProperties": {
48
+ "Variant": "Primary",
49
+ "State": "Hover"
50
+ }
51
+ },
52
+ {
53
+ "type": "COMPONENT",
54
+ "variantProperties": {
55
+ "Variant": "Primary",
56
+ "State": "Focus"
57
+ },
58
+ "effects": [
59
+ {
60
+ "type": "DROP_SHADOW",
61
+ "visible": true,
62
+ "spread": 3,
63
+ "colorVariable": null
64
+ },
65
+ {
66
+ "type": "DROP_SHADOW",
67
+ "visible": true,
68
+ "spread": 3,
69
+ "colorVariable": "color/border/default"
70
+ }
71
+ ],
72
+ "strokeAlign": "INSIDE",
73
+ "strokeVariables": [],
74
+ "strokeWeightBound": false,
75
+ "children": []
76
+ },
77
+ {
78
+ "type": "COMPONENT",
79
+ "variantProperties": {
80
+ "Variant": "Primary",
81
+ "State": "Active"
82
+ }
83
+ },
84
+ {
85
+ "type": "COMPONENT",
86
+ "variantProperties": {
87
+ "Variant": "Primary",
88
+ "State": "Disabled"
89
+ }
90
+ }
91
+ ]
92
+ },
93
+ "expected": {
94
+ "structural-read-back": "pass",
95
+ "state-baseline": "pass",
96
+ "focus-indicator": "fail",
97
+ "focus-contrast": "skip"
98
+ }
99
+ }
@@ -0,0 +1,93 @@
1
+ {
2
+ "covers": "filled control: DROP_SHADOW ring, axis and value case differs from the matrix",
3
+ "expect": {
4
+ "name": "Button",
5
+ "matrix": {
6
+ "variant": [
7
+ "primary"
8
+ ],
9
+ "state": [
10
+ "default",
11
+ "hover",
12
+ "focus",
13
+ "active",
14
+ "disabled"
15
+ ]
16
+ },
17
+ "uiFramework": "shadcn"
18
+ },
19
+ "snapshot": {
20
+ "type": "COMPONENT_SET",
21
+ "variantGroupProperties": {
22
+ "Variant": {
23
+ "values": [
24
+ "Primary"
25
+ ]
26
+ },
27
+ "State": {
28
+ "values": [
29
+ "Default",
30
+ "Hover",
31
+ "Focus",
32
+ "Active",
33
+ "Disabled"
34
+ ]
35
+ }
36
+ },
37
+ "children": [
38
+ {
39
+ "type": "COMPONENT",
40
+ "variantProperties": {
41
+ "Variant": "Primary",
42
+ "State": "Default"
43
+ }
44
+ },
45
+ {
46
+ "type": "COMPONENT",
47
+ "variantProperties": {
48
+ "Variant": "Primary",
49
+ "State": "Hover"
50
+ }
51
+ },
52
+ {
53
+ "type": "COMPONENT",
54
+ "variantProperties": {
55
+ "Variant": "Primary",
56
+ "State": "Focus"
57
+ },
58
+ "effects": [
59
+ {
60
+ "type": "DROP_SHADOW",
61
+ "visible": true,
62
+ "spread": 3,
63
+ "colorVariable": "Color/Border/Focus"
64
+ }
65
+ ],
66
+ "strokeAlign": "INSIDE",
67
+ "strokeVariables": [],
68
+ "strokeWeightBound": false,
69
+ "children": []
70
+ },
71
+ {
72
+ "type": "COMPONENT",
73
+ "variantProperties": {
74
+ "Variant": "Primary",
75
+ "State": "Active"
76
+ }
77
+ },
78
+ {
79
+ "type": "COMPONENT",
80
+ "variantProperties": {
81
+ "Variant": "Primary",
82
+ "State": "Disabled"
83
+ }
84
+ }
85
+ ]
86
+ },
87
+ "expected": {
88
+ "structural-read-back": "pass",
89
+ "state-baseline": "pass",
90
+ "focus-indicator": "pass",
91
+ "focus-contrast": "skip"
92
+ }
93
+ }
@@ -0,0 +1,135 @@
1
+ {
2
+ "covers": "deliberately sparse set fails the full cross product",
3
+ "expect": {
4
+ "name": "Button",
5
+ "matrix": {
6
+ "variant": [
7
+ "primary",
8
+ "secondary"
9
+ ],
10
+ "state": [
11
+ "default",
12
+ "hover",
13
+ "focus",
14
+ "active",
15
+ "disabled"
16
+ ]
17
+ },
18
+ "uiFramework": "shadcn"
19
+ },
20
+ "snapshot": {
21
+ "type": "COMPONENT_SET",
22
+ "variantGroupProperties": {
23
+ "Variant": {
24
+ "values": [
25
+ "Primary",
26
+ "Secondary"
27
+ ]
28
+ },
29
+ "State": {
30
+ "values": [
31
+ "Default",
32
+ "Hover",
33
+ "Focus",
34
+ "Active",
35
+ "Disabled"
36
+ ]
37
+ }
38
+ },
39
+ "children": [
40
+ {
41
+ "type": "COMPONENT",
42
+ "variantProperties": {
43
+ "Variant": "Primary",
44
+ "State": "Default"
45
+ }
46
+ },
47
+ {
48
+ "type": "COMPONENT",
49
+ "variantProperties": {
50
+ "Variant": "Primary",
51
+ "State": "Hover"
52
+ }
53
+ },
54
+ {
55
+ "type": "COMPONENT",
56
+ "variantProperties": {
57
+ "Variant": "Primary",
58
+ "State": "Focus"
59
+ },
60
+ "effects": [
61
+ {
62
+ "type": "DROP_SHADOW",
63
+ "visible": true,
64
+ "spread": 3,
65
+ "colorVariable": "Color/Border/Focus"
66
+ }
67
+ ],
68
+ "strokeAlign": "INSIDE",
69
+ "strokeVariables": [],
70
+ "strokeWeightBound": false,
71
+ "children": []
72
+ },
73
+ {
74
+ "type": "COMPONENT",
75
+ "variantProperties": {
76
+ "Variant": "Primary",
77
+ "State": "Active"
78
+ }
79
+ },
80
+ {
81
+ "type": "COMPONENT",
82
+ "variantProperties": {
83
+ "Variant": "Primary",
84
+ "State": "Disabled"
85
+ }
86
+ },
87
+ {
88
+ "type": "COMPONENT",
89
+ "variantProperties": {
90
+ "Variant": "Secondary",
91
+ "State": "Default"
92
+ }
93
+ },
94
+ {
95
+ "type": "COMPONENT",
96
+ "variantProperties": {
97
+ "Variant": "Secondary",
98
+ "State": "Hover"
99
+ }
100
+ },
101
+ {
102
+ "type": "COMPONENT",
103
+ "variantProperties": {
104
+ "Variant": "Secondary",
105
+ "State": "Focus"
106
+ },
107
+ "effects": [
108
+ {
109
+ "type": "DROP_SHADOW",
110
+ "visible": true,
111
+ "spread": 3,
112
+ "colorVariable": "Color/Border/Focus"
113
+ }
114
+ ],
115
+ "strokeAlign": "INSIDE",
116
+ "strokeVariables": [],
117
+ "strokeWeightBound": false,
118
+ "children": []
119
+ },
120
+ {
121
+ "type": "COMPONENT",
122
+ "variantProperties": {
123
+ "Variant": "Secondary",
124
+ "State": "Disabled"
125
+ }
126
+ }
127
+ ]
128
+ },
129
+ "expected": {
130
+ "structural-read-back": "fail",
131
+ "state-baseline": "pass",
132
+ "focus-indicator": "pass",
133
+ "focus-contrast": "skip"
134
+ }
135
+ }