@helloimjolopez-pathway/pathway-tokens 11.0.0 → 11.1.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/components/scrollbar/scrollbar.jsx +23 -2
- package/components/sidenav/sidenav.jsx +43 -6
- package/dist/README.md +2 -2
- package/dist/contract.json +4 -4
- package/dist/layout-contextual.css +4 -1
- package/dist/tokens.js +33 -0
- package/dist/tokens.json +16 -0
- package/package.json +4 -3
|
@@ -43,8 +43,19 @@ export const SCROLL = {
|
|
|
43
43
|
// an overlay scrollbar is a redundant affordance (the content scrolls with or
|
|
44
44
|
// without it, and the OS bar remains). So contrast is bought back with SIZE
|
|
45
45
|
// and PRESENCE rather than with darkness: see thumbWidth and the grab strip.
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
// Scrim/Faint and Scrim/Light resolve to Cool Neutral 800, so the thumb was
|
|
47
|
+
// drawing a COOL grey over warm surfaces and reading as a cold bar against
|
|
48
|
+
// them. Reported 2026-10-02. The comment below has always said "light warm
|
|
49
|
+
// overlay" — the value simply did not match it.
|
|
50
|
+
//
|
|
51
|
+
// Scrim is also the wrong family: it is the modal backdrop, where a cool
|
|
52
|
+
// near-black is right. The thumb is an overlay on a surface, and under the
|
|
53
|
+
// alpha rule surfaces and fills are WARM. So the thumb now resolves through
|
|
54
|
+
// its own themed custom properties, set in the injected sheet below off the
|
|
55
|
+
// warm neutral alpha primitives. No new design token: a component-local
|
|
56
|
+
// property, the same mechanism the Widget uses for its column spans.
|
|
57
|
+
thumbRest: "var(--pw-scrollbar-thumb-rest)", // warm neutral 16%
|
|
58
|
+
thumbHover: "var(--pw-scrollbar-thumb-hover)", // warm neutral 24%
|
|
48
59
|
thumbBlur: "blur(8px) saturate(180%)",
|
|
49
60
|
// Hairline glass edge: semantic white at 35% via color-mix.
|
|
50
61
|
thumbEdge: "inset 0 0 0 0.5px color-mix(in srgb, var(--semantic-color-fill-static-neutral-faint) 35%, transparent)",
|
|
@@ -72,6 +83,16 @@ if (typeof document !== "undefined" && !document.getElementById("pds-scrollable-
|
|
|
72
83
|
const s = document.createElement("style");
|
|
73
84
|
s.id = "pds-scrollable-base";
|
|
74
85
|
s.textContent =
|
|
86
|
+
// Warm neutral, and it has to INVERT: 500 is the dark warm grey for a light
|
|
87
|
+
// surface, 100 the light warm grey for a dark one. An inline style cannot
|
|
88
|
+
// branch on [data-theme], which is why these live here rather than in the
|
|
89
|
+
// SCROLL map above.
|
|
90
|
+
":root,[data-theme=\"light\"]{" +
|
|
91
|
+
"--pw-scrollbar-thumb-rest:var(--primitive-color-warm-neutral-500-16);" +
|
|
92
|
+
"--pw-scrollbar-thumb-hover:var(--primitive-color-warm-neutral-500-24)}" +
|
|
93
|
+
"[data-theme=\"midnight\"],[data-theme=\"dark\"]{" +
|
|
94
|
+
"--pw-scrollbar-thumb-rest:var(--primitive-color-warm-neutral-100-16);" +
|
|
95
|
+
"--pw-scrollbar-thumb-hover:var(--primitive-color-warm-neutral-100-24)}" +
|
|
75
96
|
".pds-scrollable__view{scrollbar-width:none;-ms-overflow-style:none}" +
|
|
76
97
|
".pds-scrollable__view::-webkit-scrollbar{width:0;height:0;display:none}" +
|
|
77
98
|
"@media (hover: none){.pds-scrollable__grab{pointer-events:none!important}}";
|
|
@@ -139,6 +139,10 @@ export const L = {
|
|
|
139
139
|
iconWrap: 24, // no token in Figma — leading icon wrapper
|
|
140
140
|
iconInner: 16, // Material Symbols Rounded frame size, per design-system-spec §7.2
|
|
141
141
|
rowPadH: u("padding-tight"),
|
|
142
|
+
// Collapsed rail: container.rowStart's padding-right in Figma. It is what
|
|
143
|
+
// keeps the centred icon a hair left of the square's true centre, the same as
|
|
144
|
+
// the design.
|
|
145
|
+
railIconInset: u("padding-xxtight"),
|
|
142
146
|
textPad: u("padding-xtight"),
|
|
143
147
|
childIndent: 24, // no token in Figma — level-1 left indent
|
|
144
148
|
stripeW: 4, // no token in Figma — indicator stripe width
|
|
@@ -234,6 +238,13 @@ export function SideNavItem({
|
|
|
234
238
|
width: isSidebarCollapsed ? L.itemH : "100%",
|
|
235
239
|
marginLeft: isSidebarCollapsed ? "auto" : undefined,
|
|
236
240
|
marginRight: isSidebarCollapsed ? "auto" : undefined,
|
|
241
|
+
// Figma's container.rowStart is 40 wide inside the 44 square with
|
|
242
|
+
// padding-right 6 and primary=CENTER, so the icon centres in the 34
|
|
243
|
+
// that is left after the 4px indicator column. See the icon wrap below.
|
|
244
|
+
paddingRight: isSidebarCollapsed ? L.railIconInset : undefined,
|
|
245
|
+
// border-box or the 6px padding is ADDED to the 44, which made the rail
|
|
246
|
+
// item 50 wide and no longer a square.
|
|
247
|
+
boxSizing: "border-box",
|
|
237
248
|
borderRadius: T.radius, backgroundColor: fillBg,
|
|
238
249
|
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
239
250
|
overflow: "hidden", transition: "background-color var(--motion-duration-3) var(--motion-easing-standard)", userSelect: "none" }}>
|
|
@@ -244,13 +255,29 @@ export function SideNavItem({
|
|
|
244
255
|
{!isChild && item.icon && (
|
|
245
256
|
<div style={{ width: L.iconWrap, height: L.iconWrap, display: "flex",
|
|
246
257
|
alignItems: "center", justifyContent: "center", flexShrink: 0,
|
|
247
|
-
|
|
258
|
+
// COLLAPSED CENTRES, EXPANDED INDENTS. The fixed 12px left margin
|
|
259
|
+
// applied in both states, so on the rail the 24px icon sat at
|
|
260
|
+
// x 16..40 of the 44 square: 6px right of centre, in every state.
|
|
261
|
+
// Reported 2026-10-02. Auto margins hand the free space back to
|
|
262
|
+
// both sides, which with the 6px right padding above reproduces
|
|
263
|
+
// Figma's x=9 exactly.
|
|
264
|
+
marginLeft: isSidebarCollapsed ? "auto" : L.rowPadH,
|
|
265
|
+
marginRight: isSidebarCollapsed ? "auto" : undefined,
|
|
266
|
+
color: iconColor }}>
|
|
248
267
|
{typeof item.icon === "function"
|
|
249
268
|
? item.icon({ size: L.iconInner, color: iconColor })
|
|
250
269
|
: typeof item.icon === "string"
|
|
251
270
|
? <span className="material-symbols-rounded" aria-hidden="true"
|
|
252
271
|
style={{ fontSize: L.iconInner, lineHeight: 1, color: iconColor,
|
|
253
|
-
|
|
272
|
+
// display:block so the glyph is laid out as a box rather than
|
|
273
|
+
// on a text baseline — an inline glyph in a flex-centred
|
|
274
|
+
// parent is centred by its line box, not by its own art, so
|
|
275
|
+
// it rode high inside the 24px wrap.
|
|
276
|
+
display: "block",
|
|
277
|
+
// opsz MUST match fontSize. It said 20 against a 16px size,
|
|
278
|
+
// so the glyph was drawn on a 20px grid and scaled down into
|
|
279
|
+
// a 16px box, which shifts the art off centre.
|
|
280
|
+
fontVariationSettings: `'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' ${L.iconInner}` }}>
|
|
254
281
|
{item.icon}
|
|
255
282
|
</span>
|
|
256
283
|
: React.cloneElement(item.icon, { style: { color: iconColor } })}
|
|
@@ -258,9 +285,19 @@ export function SideNavItem({
|
|
|
258
285
|
)}
|
|
259
286
|
|
|
260
287
|
{/* Label */}
|
|
261
|
-
<div style={{
|
|
262
|
-
|
|
263
|
-
|
|
288
|
+
<div style={{
|
|
289
|
+
// Collapsed, the label must take NO part in the flex distribution.
|
|
290
|
+
// With flex:1 it still claimed the free space even though max-width
|
|
291
|
+
// clamped it to zero, so the icon's auto margins had nothing left to
|
|
292
|
+
// centre with and the icon stayed hard left.
|
|
293
|
+
flex: isSidebarCollapsed ? "0 0 0px" : 1,
|
|
294
|
+
minWidth: 0,
|
|
295
|
+
// Collapsed, the padding has to go too. max-width clamps the CONTENT
|
|
296
|
+
// box, so the label still occupied 8px of padding on the rail and ate
|
|
297
|
+
// most of the free space the icon's auto margins needed: the icon
|
|
298
|
+
// landed at x=5 instead of Figma's x=9.
|
|
299
|
+
paddingLeft: isSidebarCollapsed ? 0 : (isChild ? 32 : L.textPad),
|
|
300
|
+
paddingRight: isSidebarCollapsed ? 0 : ((!isChild && hasChildren) ? 0 : L.rowPadH),
|
|
264
301
|
maxWidth: isSidebarCollapsed ? 0 : 200,
|
|
265
302
|
opacity: isSidebarCollapsed ? 0 : 1,
|
|
266
303
|
overflow: "hidden",
|
|
@@ -276,7 +313,7 @@ export function SideNavItem({
|
|
|
276
313
|
|
|
277
314
|
{/* Chevron — groupers only */}
|
|
278
315
|
{!isChild && hasChildren && (
|
|
279
|
-
<div style={{ width: 40, height: L.iconWrap, display: "flex",
|
|
316
|
+
<div style={{ width: isSidebarCollapsed ? 0 : 40, height: L.iconWrap, display: "flex",
|
|
280
317
|
alignItems: "center", justifyContent: "center", flexShrink: 0,
|
|
281
318
|
maxWidth: isSidebarCollapsed ? 0 : 40,
|
|
282
319
|
opacity: isSidebarCollapsed ? 0 : 1,
|
package/dist/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**The colour contract is 210 names.** Your full working vocabulary is
|
|
4
4
|
**360**. If you add up every declaration in this folder you get
|
|
5
|
-
|
|
5
|
+
1155. That number is not the contract, and the table below says why.
|
|
6
6
|
|
|
7
7
|
## Link these, in this order
|
|
8
8
|
|
|
@@ -30,7 +30,7 @@ error**.
|
|
|
30
30
|
| `themes/midnight.css` | 210 | yes | yes | Colour contract, Midnight Mode. Same names as light. |
|
|
31
31
|
| `type.css` | 39 | yes | yes | Type scale. Compose from these. |
|
|
32
32
|
| `layout.css` | 76 | yes | yes | Spacing, radii, border widths. |
|
|
33
|
-
| `layout-contextual.css` |
|
|
33
|
+
| `layout-contextual.css` | 37 | **no** | **no** | Per-component metrics. This repo's components use these. |
|
|
34
34
|
| `motion.css` | 21 | yes | yes | Durations and easings. |
|
|
35
35
|
| `layout-responsive.css` | 9 | yes | yes | Sheet and TopNav padding. The only layout tokens with media queries. |
|
|
36
36
|
| `breakpoints.css` | 5 | yes | yes | Breakpoint values. |
|
package/dist/contract.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "The names a consumer may use. Generated from the emitted CSS by scripts/build-contract.js, do not hand-edit. Lint against `contract` if you want the boundary enforced; nothing here blocks a primitive.",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.1.0",
|
|
4
4
|
"generated": "2026-10-02",
|
|
5
5
|
"counts": {
|
|
6
6
|
"contract": 360,
|
|
7
|
-
"infrastructure":
|
|
8
|
-
"declarationsAcrossAllFiles":
|
|
7
|
+
"infrastructure": 585,
|
|
8
|
+
"declarationsAcrossAllFiles": 1155
|
|
9
9
|
},
|
|
10
10
|
"loadOrder": [
|
|
11
11
|
"primitives.css",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"layout-contextual.css": {
|
|
52
52
|
"contract": false,
|
|
53
53
|
"mustLoad": false,
|
|
54
|
-
"count":
|
|
54
|
+
"count": 37,
|
|
55
55
|
"role": "Per-component metrics. This repo's components use these."
|
|
56
56
|
},
|
|
57
57
|
"motion.css": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
prefer layout.css, which is the general spacing contract. These exist so a
|
|
10
10
|
component's geometry can be tuned without moving the whole scale.
|
|
11
11
|
|
|
12
|
-
Declares
|
|
12
|
+
Declares 37 custom properties.
|
|
13
13
|
Generated — do not edit. Run `npm run build-tokens`.
|
|
14
14
|
==========================================================================
|
|
15
15
|
*/
|
|
@@ -48,4 +48,7 @@
|
|
|
48
48
|
--contextual-layout-units-sidenav-width-collapsed: 84px;
|
|
49
49
|
--contextual-layout-units-sidenav-width-expanded: 256px;
|
|
50
50
|
--contextual-layout-units-topnav-height: 60px;
|
|
51
|
+
--contextual-layout-units-widget-minwidth-detail: 515px;
|
|
52
|
+
--contextual-layout-units-widget-minwidth-explore: 1050px;
|
|
53
|
+
--contextual-layout-units-widget-minwidth-glance: 275px;
|
|
51
54
|
}
|
package/dist/tokens.js
CHANGED
|
@@ -413,6 +413,39 @@ const tokens = {
|
|
|
413
413
|
"height"
|
|
414
414
|
]
|
|
415
415
|
},
|
|
416
|
+
"contextual-layout-units-widget-minwidth-glance": {
|
|
417
|
+
"value": 275,
|
|
418
|
+
"type": "number",
|
|
419
|
+
"path": [
|
|
420
|
+
"contextual-layout-units",
|
|
421
|
+
"amplify",
|
|
422
|
+
"widget",
|
|
423
|
+
"minwidth",
|
|
424
|
+
"glance"
|
|
425
|
+
]
|
|
426
|
+
},
|
|
427
|
+
"contextual-layout-units-widget-minwidth-detail": {
|
|
428
|
+
"value": 515,
|
|
429
|
+
"type": "number",
|
|
430
|
+
"path": [
|
|
431
|
+
"contextual-layout-units",
|
|
432
|
+
"amplify",
|
|
433
|
+
"widget",
|
|
434
|
+
"minwidth",
|
|
435
|
+
"detail"
|
|
436
|
+
]
|
|
437
|
+
},
|
|
438
|
+
"contextual-layout-units-widget-minwidth-explore": {
|
|
439
|
+
"value": 1050,
|
|
440
|
+
"type": "number",
|
|
441
|
+
"path": [
|
|
442
|
+
"contextual-layout-units",
|
|
443
|
+
"amplify",
|
|
444
|
+
"widget",
|
|
445
|
+
"minwidth",
|
|
446
|
+
"explore"
|
|
447
|
+
]
|
|
448
|
+
},
|
|
416
449
|
"elevation-light-lift": {
|
|
417
450
|
"value": "0 10px 28px -6px rgba(24,27,43,0.08)",
|
|
418
451
|
"type": "string",
|
package/dist/tokens.json
CHANGED
|
@@ -202,6 +202,22 @@
|
|
|
202
202
|
"$type": "number",
|
|
203
203
|
"$value": "{primitive-unit.unit.60}"
|
|
204
204
|
}
|
|
205
|
+
},
|
|
206
|
+
"widget": {
|
|
207
|
+
"minwidth": {
|
|
208
|
+
"glance": {
|
|
209
|
+
"$type": "number",
|
|
210
|
+
"$value": 275
|
|
211
|
+
},
|
|
212
|
+
"detail": {
|
|
213
|
+
"$type": "number",
|
|
214
|
+
"$value": 515
|
|
215
|
+
},
|
|
216
|
+
"explore": {
|
|
217
|
+
"$type": "number",
|
|
218
|
+
"$value": 1050
|
|
219
|
+
}
|
|
220
|
+
}
|
|
205
221
|
}
|
|
206
222
|
},
|
|
207
223
|
"newco": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helloimjolopez-pathway/pathway-tokens",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.1.0",
|
|
4
4
|
"description": "Pathway Design System tokens — CSS custom properties, JS export, and DTCG JSON",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"fix-tokens-preview": "node scripts/fix-tokens.js --dry-run",
|
|
64
64
|
"build-tokens": "node scripts/sync-motion-tokens.js && node style-dictionary.config.js && node scripts/stamp-headers.js",
|
|
65
65
|
"build-dist": "node scripts/sync-motion-tokens.js && node style-dictionary.config.js && node scripts/stamp-headers.js && node scripts/check-demo-tokens.js && node scripts/check-token-refs.js && node scripts/check-token-names.js && node scripts/check-token-object-refs.js && node scripts/fix-stale-doc-hex.js --check && node scripts/check-state-distinctness.js && node scripts/check-ladder-order.js && node scripts/check-variant-distinctness.js && node scripts/check-fill-foreground-pairs.js && node scripts/check-story-yield.js && node scripts/check-motion-coverage.js && node scripts/build-dist.js && node scripts/build-index.js && node scripts/build-contract.js && npm run build-elements && npm run sync-demo-module-icon",
|
|
66
|
-
"storybook": "node style-dictionary.config.js && storybook dev -p 6006",
|
|
66
|
+
"storybook": "node style-dictionary.config.js && PATHWAY_BRAND_AXIS=1 storybook dev -p 6006",
|
|
67
67
|
"build-storybook": "storybook build",
|
|
68
68
|
"check-demo-tokens": "node scripts/check-demo-tokens.js",
|
|
69
69
|
"assemble-export": "node scripts/assemble-figma-export.js",
|
|
@@ -84,7 +84,8 @@
|
|
|
84
84
|
"check-doc-hex": "node scripts/fix-stale-doc-hex.js --check",
|
|
85
85
|
"check-token-object-refs": "node scripts/check-token-object-refs.js",
|
|
86
86
|
"check-motion-coverage": "node scripts/check-motion-coverage.js",
|
|
87
|
-
"sync-demo-module-icon": "node scripts/sync-demo-module-icon.js"
|
|
87
|
+
"sync-demo-module-icon": "node scripts/sync-demo-module-icon.js",
|
|
88
|
+
"build-storybook:brands": "PATHWAY_BRAND_AXIS=1 storybook build"
|
|
88
89
|
},
|
|
89
90
|
"devDependencies": {
|
|
90
91
|
"@babel/preset-env": "^7.29.2",
|