Uh oh!
There was an error while loading. Please reload this page.
perf(ActionList): replace :has() selector with JS-computed attribute - #7714
Conversation
🦋 Changeset detectedLatest commit: abb7503 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
🤖 Lint issues have been automatically fixed and committed to this PR. |
There was a problem hiding this comment.
Pull request overview
This PR aims to improve ActionList rendering performance by removing an expensive container-level :has() selector and replacing it with a JS-computed data-mixed-descriptions attribute. However, the PR also introduces a new packages/primer-api workspace plus a new GitHub Actions workflow for a Slack/LLM “Primer Bot”, which significantly expands scope beyond the stated goal.
Changes:
- ActionList: replace container
:has()selector withdata-mixed-descriptionscomputed after render. - Add a new
@primer/apiworkspace (HTTP server + GitHub Action entrypoint) for answering Primer questions via LLM + primer.style docs. - Add a new
primer-bot.ymlworkflow to run the bot onrepository_dispatch/ manual dispatch.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/react/src/ActionList/List.tsx | Computes and sets data-mixed-descriptions on the list element post-render. |
| packages/react/src/ActionList/ActionList.module.css | Switches styling condition from :has() to [data-mixed-descriptions='true']. |
| packages/primer-api/tsconfig.json | Adds TS config for the new @primer/api workspace. |
| packages/primer-api/src/prompts.ts | Defines the LLM system prompt and user prompt builder. |
| packages/primer-api/src/llm.ts | Adds OpenAI/GitHub Models chat completion integration and context retrieval wiring. |
| packages/primer-api/src/knowledge.ts | Retrieves relevant component docs from primer.style and formats context for the prompt. |
| packages/primer-api/src/index.ts | Implements a small HTTP server with /ask and /health endpoints. |
| packages/primer-api/src/config.ts | Loads configuration from environment variables (tokens, model, port, etc.). |
| packages/primer-api/src/action.ts | GitHub Actions entrypoint to read dispatch payload and post an answer to Slack. |
| packages/primer-api/package.json | Declares the new workspace package, scripts, and dependencies. |
| packages/primer-api/README.md | Documents bot setup (Slack + repo dispatch + workflow) and local dev usage. |
| packages/primer-api/.env.example | Provides example env vars for local usage. |
| .github/workflows/primer-bot.yml | Adds workflow to run the Primer bot from dispatch events or manual input. |
| package-lock.json | Updates lockfile for new workspace/dependencies and version bumps. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
a721664 to
c383302Compare🤖 Lint issues have been automatically fixed and committed to this PR. |
faeb40f to
0919c3bCompare- Use useIsomorphicLayoutEffect for SSR compatibility - Only update data-mixed-descriptions when value changes - Remove attribute when not needed instead of setting 'false'
👋 Hi from github/github-ui! Your integration PR is ready: https://github.com/github/github-ui/pull/19042 |
Replace :has() selector with a JavaScript-computed attribute for performance improvements in ActionList.
Closeshttps://github.com/github/github-ui/issues/17359
This CSS selector on the ActionList container forces the browser to walk the entire subtree on every DOM mutation:
With 100 items (~1860 DOM elements), sequential DOM mutations with forced style recalc (the pattern during React reconciliation):
:has())(Chrome, 100 items, 6x CPU throttle. Safari is worse due to historically quadratic
:has()invalidation, causing the 10-20+ second freezes reported in github/github-ui#17223.)Replaced with a
data-mixed-descriptionsattribute computed viauseLayoutEffectin List.tsx. TwoquerySelectorcalls after render replace continuous full-subtree style invalidation from the CSS engine.Why DOM queries instead of React children/context:
useSlotsat render time, so the List can't know which Items have descriptions without duplicating slot detection or deeply inspecting opaque children trees (fragile with Groups, conditional rendering, wrapper components)Related: #7708 (stylelint guard for container-level
:has()selectors), github/github-ui#17223Changelog
New
N/A
Changed
:has([data-has-description])container selector withdata-mixed-descriptionsattribute computed in JSRemoved
N/A
Rollout strategy
Testing & Reviewing
font-weight: normalwhen the list has mixed items (some with descriptions, some without)Merge checklist