Skip to content

Conversation

@snowystinger
Copy link
Member

@snowystinger snowystinger commented May 27, 2025

Closes

Follow instructions in README to run the plugin. There is also a description of the extension architecture in there as it is non-trivial due to the various sandbox that chrome imposes in addition to the different ways that a macro could be updated ie. static, dynamic, conditional static.

Note, there is a parcel bug which will cause all tabs that have had the content script injected to reload on every change. I cannot resolve this right now. If you build instead so that the extension doesn't change, then it won't do this. It's only during HMR. This will also cause every tab to refresh if a tab that had loaded the extension is closed.
For this reason, it can be easier to build the extension instead of running it as if you're developing.

Some notes, this is currently meant to be used in addition to the regular panels and AtomicCSS to determine where styles are coming from. It is not designed to replace those extensions and inspectors.

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exists for this component).
  • Looked at the Accessibility Practices for this feature - Aria Practices

📝 Test Instructions:

I added a style macro in the commit e5ab27b which is static and is swapped with another static one on a span inside buttons. It reacts to the button being focused. You can see the extensions dev panel is updated when this swap occurs despite it being a static macro.

I removed that afterwards. So to test the updates on static macros, use that storybook build.

Otherwise, you can inspect elements and view the results in the dev tools panel.

🧢 Your Project:

@rspbot
Copy link

rspbot commented Jun 3, 2025

Build successful! 🎉

@snowystinger snowystinger marked this pull request as ready for review June 3, 2025 06:14
@rspbot
Copy link

rspbot commented Jun 3, 2025

Build successful! 🎉

@rspbot
Copy link

rspbot commented Jun 3, 2025

Build successful! 🎉

@rspbot
Copy link

rspbot commented Jun 4, 2025

Build successful! 🎉

@rspbot
Copy link

rspbot commented Jun 5, 2025

Build successful! 🎉

@snowystinger snowystinger changed the title [WIP] feat: Style macro devtool feat: Style macro devtool Jun 5, 2025
@rspbot
Copy link

rspbot commented Jun 5, 2025

Build successful! 🎉

@rspbot
Copy link

rspbot commented Jun 5, 2025

Build successful! 🎉

@rspbot
Copy link

rspbot commented Jun 5, 2025

Build successful! 🎉

@rspbot
Copy link

rspbot commented Jun 6, 2025

Build successful! 🎉

@rspbot
Copy link

rspbot commented Jun 6, 2025

Build successful! 🎉

@snowystinger snowystinger force-pushed the style-macro-devtool branch from 994911b to 2706cd1 Compare June 6, 2025 05:03
@rspbot
Copy link

rspbot commented Jun 6, 2025

Build successful! 🎉

@rspbot
Copy link

rspbot commented Oct 29, 2025

@rspbot
Copy link

rspbot commented Oct 29, 2025

@rspbot
Copy link

rspbot commented Oct 29, 2025

@rspbot
Copy link

rspbot commented Oct 29, 2025

# Conflicts:
#	package.json
#	packages/@react-spectrum/s2/style/__tests__/style-macro.test.js
#	packages/@react-spectrum/s2/style/style-macro.ts
#	packages/dev/parcel-config-storybook/package.json
#	packages/dev/s2-icon-builder/package.json
#	yarn.lock
@rspbot
Copy link

rspbot commented Dec 18, 2025

@rspbot
Copy link

rspbot commented Dec 18, 2025

differentiate between hash conflicts when same style is used in multiple files
LFDanLu
LFDanLu previously approved these changes Dec 18, 2025
@rspbot
Copy link

rspbot commented Jan 6, 2026

@rspbot
Copy link

rspbot commented Jan 6, 2026

@rspbot
Copy link

rspbot commented Jan 6, 2026

Copy link
Member

@reidbarber reidbarber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Tested in our storybook.

Copy link
Member

@yihuiliao yihuiliao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested on the s2 storybook, i like the logo haha

// the defaults from the style definition are omitted.
let allowedOverridesSet = new Set<string>();
let js = 'let rules = " ";\n';
let js = 'let rules = " ", currentRules = {};\n';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only needed in dev builds right?

this.pseudos = '';
this.property = property;
this.value = value;
if (isCompilingDependencies !== null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remind me what this is for? Why is it only when compiling dependencies?

copy(): Rule
}

let conditionStack: string[] = [];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps at some point we can refactor this to not rely on global state

}
if (conditionStack.length) {
// name += ` (${conditionStack.join(', ')})`;
res += ` currentRules[${JSON.stringify(name)}] = typeof currentRules[${JSON.stringify(name)}] === 'object' ? currentRules[${JSON.stringify(name)}] : {"default": currentRules[${JSON.stringify(name)}]}; currentRules[${JSON.stringify(name)}][${JSON.stringify(conditionStack.join(' && '))}] = ${JSON.stringify(this.themeValue)};`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kinda hard to read. A comment would help. Also maybe store JSON.stringify(name) in a variable and use that?

@@ -0,0 +1,384 @@
# style-macro-chrome-plugin

This is a chrome plugin to assist in debugging the styles applied by our Style Macro.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This is a chrome plugin to assist in debugging the styles applied by our Style Macro.
This is a chrome plugin to assist in debugging the styles applied by the React Spectrum Style Macro.

- DevTools reads directly from CSS via `getComputedStyle()`

**Dynamic Macros** (`-macro-dynamic-{hash}`):
- Used when style conditions can change (e.g., `style({ color: isActive ? 'red' : 'blue' })`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Used when style conditions can change (e.g., `style({ color: isActive ? 'red' : 'blue' })`)
- Used when style conditions can change (e.g., `style({color: {default: 'blue', isActive: 'red'}})`)

| `macro-response` | Content → Background → DevTools | Return requested macro data |
| `get-macro` | Background → Content | Internal forwarding of query-macros |
| `init` | DevTools → Background | Establish connection with tabId |
| `class-changed` | Page → Content → Background → DevTools | Notify that selected element's className changed |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might want to namespace these in case other scripts/extensions have the same names

chrome.runtime.onMessage.addListener((message, _sender, _sendResponse) => {
debugLog('Received message:', message);

if (message.action === 'get-macro') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to store the macro data directly in the dev tools instead of in the content script? i.e. have the content script send the macro data in the update-macros message instead of storing in window.__macros and then requesting it asynchronously via get-macro?

// Generate a unique ID if element doesn't have one
if (!element.hasAttribute('data-devtools-id')) {
element.setAttribute('data-devtools-id', 'dt-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use a property instead of an attribute so it is more hidden and less likely to get overwritten by something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants