Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
145b9d9
feat: Style Macro DevTool
snowystinger May 27, 2025
7d8b453
add parcel patch
snowystinger May 27, 2025
3266c18
small fixes
snowystinger May 27, 2025
8e4f8ee
fix mergeStyles
snowystinger May 27, 2025
b956f9c
Merge branch 'main' into style-macro-devtool
snowystinger Jun 3, 2025
af59e2e
Add README so people know how to develop this extension
snowystinger Jun 3, 2025
85e70d2
add todos, fix tests, fix lint
snowystinger Jun 3, 2025
3adab93
fix dev logic
snowystinger Jun 3, 2025
690037a
add todo
snowystinger Jun 3, 2025
5a89555
use static method to inject script
snowystinger Jun 4, 2025
a68dbfd
fix the patch
snowystinger Jun 5, 2025
2bf9d6a
I don't think there is a bug here, different states get different mac…
snowystinger Jun 5, 2025
237392f
remove console logs
snowystinger Jun 5, 2025
2706cd1
add extension icon
snowystinger Jun 5, 2025
a95b4f6
use document idle instead of start to help with tab reload
snowystinger Jun 16, 2025
15ab735
Merge branch 'main' into style-macro-devtool
snowystinger Jun 16, 2025
6fe2d0b
fix package.json
snowystinger Jun 16, 2025
70f3ef5
Merge branch 'main' into style-macro-devtool
snowystinger Jul 11, 2025
3258ea0
Merge branch 'main' into style-macro-devtool
snowystinger Oct 22, 2025
cafae4e
have dev tool handle all book keeping and poll to avoid memory leak
snowystinger Oct 23, 2025
05bc7cf
Add architecture diagrams and explanations
snowystinger Oct 23, 2025
22c9464
Add patch back in
snowystinger Oct 24, 2025
3cbc47f
fix install
snowystinger Oct 24, 2025
ef751da
remove console.log
snowystinger Oct 24, 2025
16dbc84
fix patch and ts error
snowystinger Oct 24, 2025
3e92ced
fix lint
snowystinger Oct 24, 2025
3c1ce45
fix RSC
snowystinger Oct 24, 2025
5e1e2f0
fix rsc more
snowystinger Oct 24, 2025
f5cb5a8
Merge branch 'main' into style-macro-devtool
snowystinger Oct 29, 2025
4d9ce27
Update static macros to store their data directly in a css class
snowystinger Oct 29, 2025
3ec550d
fix tests
snowystinger Oct 29, 2025
148ba97
fix lint
snowystinger Oct 29, 2025
0efc6b7
fix handling between multiple tabs
snowystinger Oct 29, 2025
e5ab27b
fix polling cleanup to work with new classnames
snowystinger Oct 29, 2025
ab75a0e
revert button change
snowystinger Oct 29, 2025
105aa4a
remove static macros extension information in production
snowystinger Oct 29, 2025
4bc53f8
add info to the architecture
snowystinger Oct 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .yarn/patches/@parcel-transformer-js-npm-2.16.0-ae71b060cb.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
diff --git a/lib/JSTransformer.js b/lib/JSTransformer.js
index c2a45a9665b4b88836d720669b997872082bb143..f46b0edf814e398ed2a2584efeb040c4b77d58db 100644
--- a/lib/JSTransformer.js
+++ b/lib/JSTransformer.js
@@ -447,14 +447,8 @@ var _default = exports.default = new (_plugin().Transformer)({
},
loc: {
filePath: asset.filePath,
- start: {
- line: loc.start_line + Number(asset.meta.startLine ?? 1) - 1,
- column: loc.start_col
- },
- end: {
- line: loc.end_line + Number(asset.meta.startLine ?? 1) - 1,
- column: loc.end_col
- }
+ line: loc.line,
+ col: loc.col
},
invalidateOnFileChange(filePath) {
asset.invalidateOnFileChange(filePath);
10 changes: 9 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -500,4 +500,12 @@ export default [{
rules: {
"react/react-in-jsx-scope": OFF,
},
}];
}, {
files: ["packages/dev/style-macro-chrome-plugin/**"],
languageOptions: {
globals: {
...globals.webextensions,
...globals.browser
}
}
}];
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@
"remark-parse": "patch:remark-parse@npm%3A10.0.1#~/.yarn/patches/remark-parse-npm-10.0.1-e654d7df78.patch",
"lightningcss": "1.30.1",
"react-server-dom-parcel": "canary",
"react-test-renderer": "19.1.0"
"react-test-renderer": "19.1.0",
"@parcel/transformer-js@npm:2.16.0": "patch:@parcel/transformer-js@npm%3A2.16.0#~/.yarn/patches/@parcel-transformer-js-npm-2.16.0-ae71b060cb.patch"
},
"@parcel/transformer-css": {
"cssModules": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,24 @@
import {mergeStyles} from '../runtime';
import {style} from '../spectrum-theme';

function stripMacro(css) {
return css.replaceAll(/ -macro-static-[0-9a-zA-Z]+/gi, '').replaceAll(/ -macro-dynamic-[0-9a-zA-Z]+/gi, '');
}

describe('mergeStyles', () => {
it('should merge styles', () => {
let a = style({backgroundColor: 'red-1000', color: 'pink-100'});
let b = style({fontSize: 'body-xs', backgroundColor: 'gray-50'});
let expected = style({backgroundColor: 'gray-50', color: 'pink-100', fontSize: 'body-xs'});
let merged = mergeStyles(a, b);
expect(merged).toBe(expected);
expect(stripMacro(merged)).toBe(stripMacro(expected.toString()));
});

it('should merge with arbitrary values', () => {
let a = style({backgroundColor: 'red-1000', color: '[hotpink]'});
let b = style({fontSize: '[15px]', backgroundColor: 'gray-50'});
let expected = style({backgroundColor: 'gray-50', color: '[hotpink]', fontSize: '[15px]'});
let merged = mergeStyles(a, b);
expect(merged).toBe(expected);
expect(stripMacro(merged)).toBe(stripMacro(expected.toString()));
});
});
74 changes: 47 additions & 27 deletions packages/@react-spectrum/s2/style/__tests__/style-macro.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,13 @@ describe('style-macro', () => {
}
}

.-macro-static-EVNQL {
--macro-data: {"style":{"marginTop":{":first-child":{"default":4,"lg":8}}},"loc":"undefined:undefined:undefined"};
}

"
`);
expect(js).toMatchInlineSnapshot('" Jbs12 Jbpv12"');
expect(js).toMatchInlineSnapshot('" Jbs12 Jbpv12 -macro-static-EVNQL"');
});

it('should support self references', () => {
Expand Down Expand Up @@ -114,10 +118,14 @@ describe('style-macro', () => {
}
}

.-macro-static-qHi23 {
--macro-data: {"style":{"borderWidth":2,"paddingX":"edge-to-text","width":"calc(200px - self(borderStartWidth) - self(paddingStart))"},"loc":"undefined:undefined:undefined"};
}

"
`);

expect(js).toMatchInlineSnapshot('" _kc12 hc12 mCPFGYc12 lc12 SMBFGYc12 Rv12 ZjUQgKd12 -m_-mc12 -S_-Sv12"');
expect(js).toMatchInlineSnapshot('" _kc12 hc12 mCPFGYc12 lc12 SMBFGYc12 Rv12 ZjUQgKd12 -m_-mc12 -S_-Sv12 -macro-static-qHi23"');
});

it('should support allowed overrides', () => {
Expand All @@ -134,9 +142,9 @@ describe('style-macro', () => {
color: 'green-400'
});

expect(js()).toMatchInlineSnapshot('" gw12 pg12"');
expect(overrides).toMatchInlineSnapshot('" g8tmWqb12 pHJ3AUd12"');
expect(js({}, overrides)).toMatchInlineSnapshot('" g8tmWqb12 pg12"');
expect(js()).toMatchInlineSnapshot('" gw12 pg12 -macro-dynamic-1xxglvk"');
expect(overrides).toMatchInlineSnapshot('" g8tmWqb12 pHJ3AUd12 -macro-static-Su6dhb"');
expect(js({}, overrides)).toMatchInlineSnapshot('" g8tmWqb12 pg12 -macro-dynamic-jk90zw"');
});

it('should support allowed overrides for properties that expand into multiple', () => {
Expand All @@ -151,9 +159,9 @@ describe('style-macro', () => {
translateX: 40
});

expect(js()).toMatchInlineSnapshot('" -_7PloMd-B12 __Ya12"');
expect(overrides).toMatchInlineSnapshot('" -_7PloMd-D12 __Ya12"');
expect(js({}, overrides)).toMatchInlineSnapshot('" -_7PloMd-D12 __Ya12"');
expect(js()).toMatchInlineSnapshot('" -_7PloMd-B12 __Ya12 -macro-dynamic-1nf427l"');
expect(overrides).toMatchInlineSnapshot('" -_7PloMd-D12 __Ya12 -macro-static-ZCkud"');
expect(js({}, overrides)).toMatchInlineSnapshot('" -_7PloMd-D12 __Ya12 -macro-dynamic-1pnuhyr"');
});

it('should support allowed overrides for shorthands', () => {
Expand All @@ -168,9 +176,9 @@ describe('style-macro', () => {
padding: 40
});

expect(js()).toMatchInlineSnapshot('" Tk12 Qk12 Sk12 Rk12"');
expect(overrides).toMatchInlineSnapshot('" Tm12 Qm12 Sm12 Rm12"');
expect(js({}, overrides)).toMatchInlineSnapshot('" Tm12 Qm12 Sm12 Rm12"');
expect(js()).toMatchInlineSnapshot('" Tk12 Qk12 Sk12 Rk12 -macro-dynamic-1w5dwn"');
expect(overrides).toMatchInlineSnapshot('" Tm12 Qm12 Sm12 Rm12 -macro-static-FQziuc"');
expect(js({}, overrides)).toMatchInlineSnapshot('" Tm12 Qm12 Sm12 Rm12 -macro-dynamic-p1i90v"');
});

it("should support allowed overrides for values that aren't defined", () => {
Expand All @@ -185,9 +193,9 @@ describe('style-macro', () => {
minWidth: 32
});

expect(js()).toMatchInlineSnapshot('" gE12"');
expect(overrides).toMatchInlineSnapshot('" Nk12"');
expect(js({}, overrides)).toMatchInlineSnapshot('" Nk12 gE12"');
expect(js()).toMatchInlineSnapshot('" gE12 -macro-dynamic-nl2mms"');
expect(overrides).toMatchInlineSnapshot('" Nk12 -macro-static-pDx0l"');
expect(js({}, overrides)).toMatchInlineSnapshot('" Nk12 gE12 -macro-dynamic-11y5vdc"');
});

it('should support runtime conditions', () => {
Expand Down Expand Up @@ -241,9 +249,9 @@ describe('style-macro', () => {
"
`);

expect(js({})).toMatchInlineSnapshot('" gH12 pt12"');
expect(js({isHovered: true})).toMatchInlineSnapshot('" gF12 po12"');
expect(js({isPressed: true})).toMatchInlineSnapshot('" gE12 pm12"');
expect(js({})).toMatchInlineSnapshot('" gH12 pt12 -macro-dynamic-179ovcu"');
expect(js({isHovered: true})).toMatchInlineSnapshot('" gF12 po12 -macro-dynamic-1i83kjb"');
expect(js({isPressed: true})).toMatchInlineSnapshot('" gE12 pm12 -macro-dynamic-1npaxjo"');
});

it('should support nested runtime conditions', () => {
Expand Down Expand Up @@ -284,10 +292,10 @@ describe('style-macro', () => {

"
`);
expect(js({})).toMatchInlineSnapshot('" gH12"');
expect(js({isHovered: true})).toMatchInlineSnapshot('" gF12"');
expect(js({isSelected: true})).toMatchInlineSnapshot('" g_h12"');
expect(js({isSelected: true, isHovered: true})).toMatchInlineSnapshot('" g312"');
expect(js({})).toMatchInlineSnapshot('" gH12 -macro-dynamic-nl2p5j"');
expect(js({isHovered: true})).toMatchInlineSnapshot('" gF12 -macro-dynamic-nl2nh1"');
expect(js({isSelected: true})).toMatchInlineSnapshot('" g_h12 -macro-dynamic-1w0viba"');
expect(js({isSelected: true, isHovered: true})).toMatchInlineSnapshot('" g312 -macro-dynamic-nl27ia"');
});

it('should support variant runtime conditions', () => {
Expand All @@ -301,9 +309,9 @@ describe('style-macro', () => {
}
});

expect(js({variant: 'accent'})).toMatchInlineSnapshot('" gY12"');
expect(js({variant: 'primary'})).toMatchInlineSnapshot('" gjQquMe12"');
expect(js({variant: 'secondary'})).toMatchInlineSnapshot('" gw12"');
expect(js({variant: 'accent'})).toMatchInlineSnapshot('" gY12 -macro-dynamic-nl33fs"');
expect(js({variant: 'primary'})).toMatchInlineSnapshot('" gjQquMe12 -macro-dynamic-enz676"');
expect(js({variant: 'secondary'})).toMatchInlineSnapshot('" gw12 -macro-dynamic-nl3sna"');
});

it('supports runtime conditions nested inside css conditions', () => {
Expand Down Expand Up @@ -337,16 +345,16 @@ describe('style-macro', () => {
"
`);

expect(js({})).toMatchInlineSnapshot('" plb12"');
expect(js({isSelected: true})).toMatchInlineSnapshot('" ple12"');
expect(js({})).toMatchInlineSnapshot('" plb12 -macro-dynamic-1w7i5ba"');
expect(js({isSelected: true})).toMatchInlineSnapshot('" ple12 -macro-dynamic-1w7i7u1"');
});

it('should expand shorthand properties to longhands', () => {
let {js, css} = testStyle({
padding: 24
});

expect(js).toMatchInlineSnapshot('" Th12 Qh12 Sh12 Rh12"');
expect(js).toMatchInlineSnapshot('" Th12 Qh12 Sh12 Rh12 -macro-static-V268ld"');
expect(css).toMatchInlineSnapshot(`
"@layer _.a;

Expand All @@ -371,6 +379,10 @@ describe('style-macro', () => {
}
}

.-macro-static-V268ld {
--macro-data: {"style":{"padding":24},"loc":"undefined:undefined:undefined"};
}

"
`);
});
Expand All @@ -389,6 +401,10 @@ describe('style-macro', () => {
}
}

.-macro-static-MvZuec {
--macro-data: {"style":{"backgroundColor":"blue-1000/50"},"loc":"undefined:undefined:undefined"};
}

"
`);
});
Expand All @@ -410,6 +426,10 @@ describe('style-macro', () => {
}
}

.-macro-static-2pvxid {
--macro-data: {"style":{"--foo":{"type":"backgroundColor","value":"gray-300"}},"loc":"undefined:undefined:undefined"};
}

"
`);
});
Expand Down
15 changes: 11 additions & 4 deletions packages/@react-spectrum/s2/style/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,23 @@ import {StyleString} from './types';
export function mergeStyles(...styles: (StyleString | null | undefined)[]): StyleString {
let definedStyles = styles.filter(Boolean) as StyleString[];
if (definedStyles.length === 1) {
return definedStyles[0];
let first = definedStyles[0];
if (typeof first !== 'string') {
// static macro has a toString method so that we generate the style macro map for the entry
// it's automatically called in other places, but for our merging, we have to call it ourselves
return (first as StyleString).toString() as StyleString;
}
return first;
}

let map = new Map();
let map = new Map<string, string>();
for (let style of definedStyles) {
for (let [k, v] of parse(style)) {
// must call toString here for the static macro
for (let [k, v] of parse(style.toString())) {
map.set(k, v);
}
}

let res = '';
for (let value of map.values()) {
res += value;
Expand Down
Loading