diff --git a/.changeset/large-grasshoppers-work.md b/.changeset/large-grasshoppers-work.md
new file mode 100644
index 000000000000..38180fdb6701
--- /dev/null
+++ b/.changeset/large-grasshoppers-work.md
@@ -0,0 +1,5 @@
+---
+"@primer/react": minor
+---
+
+Remove the CSS modules feature flag from Checkbox
diff --git a/.changeset/large-rats-film.md b/.changeset/large-rats-film.md
new file mode 100644
index 000000000000..65778f70ed56
--- /dev/null
+++ b/.changeset/large-rats-film.md
@@ -0,0 +1,5 @@
+---
+"@primer/react": patch
+---
+
+docs: fix *.docs.json story ids
diff --git a/.changeset/slow-spoons-peel.md b/.changeset/slow-spoons-peel.md
new file mode 100644
index 000000000000..83dcb2f59434
--- /dev/null
+++ b/.changeset/slow-spoons-peel.md
@@ -0,0 +1,5 @@
+---
+"@primer/react": minor
+---
+
+Update `Token`, `IssueLabelToken`, `AvatarToken` components to use CSS Modules
diff --git a/.changeset/soft-bananas-behave.md b/.changeset/soft-bananas-behave.md
new file mode 100644
index 000000000000..1df88830ada7
--- /dev/null
+++ b/.changeset/soft-bananas-behave.md
@@ -0,0 +1,5 @@
+---
+"@primer/react": minor
+---
+
+Update FormControl sub-components to use new styled components format for migration
diff --git a/.changeset/stupid-elephants-work.md b/.changeset/stupid-elephants-work.md
new file mode 100644
index 000000000000..38180fdb6701
--- /dev/null
+++ b/.changeset/stupid-elephants-work.md
@@ -0,0 +1,5 @@
+---
+"@primer/react": minor
+---
+
+Remove the CSS modules feature flag from Checkbox
diff --git a/.github/workflows/consumer_test.yml b/.github/workflows/consumer_test.yml
deleted file mode 100644
index f9bccebd6ceb..000000000000
--- a/.github/workflows/consumer_test.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-name: Consumer test
-on:
- push: {branches: main}
- pull_request:
- workflow_dispatch:
-
-jobs:
- consumer-test:
- name: Consumer test
- runs-on: ubuntu-latest
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
- - name: Set up Node.js
- uses: actions/setup-node@v4
- with:
- node-version: 22
- cache: npm
- - run: npm i -g npm@^10.5.1
- - name: Remove "prepare" script
- run: npm pkg delete scripts.prepare
- - name: Install dependencies
- run: npm ci
- - name: Build @primer/react
- run: npm run build -w rollup-plugin-import-css -w @primer/react
- # Output the artifact as a tarball in `consumer-test`. Write the
- # information for this package in `consumer-test/pack.json` so we can read
- # from it later to install the package
- - name: Create a tarball for the package
- run: npm pack --pack-destination ../../examples/consumer-test --json > ../../examples/consumer-test/pack.json
- working-directory: packages/react
- - name: Clean package directory
- run: npm run clean:all
- - name: Test
- id: test
- working-directory: examples/consumer-test
- run: |
- # Read the filename for the tarball from `pack.json`
- npm install $(jq -r '.[0].filename' pack.json)
- npm install
- npm run check
- - name: Add annotation
- if: failure() && steps.test.conclusion == 'failure'
- run: |
- echo "::error file=tsconfig.build.json::Test package could not build. See https://github.com/primer/react/blob/main/examples/consumer-test"
diff --git a/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-colorblind-linux.png b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-colorblind-linux.png
new file mode 100644
index 000000000000..37c22f9b6eb1
Binary files /dev/null and b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-dimmed-linux.png b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-dimmed-linux.png
new file mode 100644
index 000000000000..00f46281bf45
Binary files /dev/null and b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-dimmed-linux.png differ
diff --git a/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-high-contrast-linux.png b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-high-contrast-linux.png
new file mode 100644
index 000000000000..e7e1e1dc3c26
Binary files /dev/null and b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-linux.png b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-linux.png
new file mode 100644
index 000000000000..37c22f9b6eb1
Binary files /dev/null and b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-linux.png differ
diff --git a/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-tritanopia-linux.png b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-tritanopia-linux.png
new file mode 100644
index 000000000000..37c22f9b6eb1
Binary files /dev/null and b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-dark-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-light-colorblind-linux.png b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-light-colorblind-linux.png
new file mode 100644
index 000000000000..c72be7970982
Binary files /dev/null and b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-light-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-light-high-contrast-linux.png b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-light-high-contrast-linux.png
new file mode 100644
index 000000000000..616a524b0a23
Binary files /dev/null and b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-light-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-light-linux.png b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-light-linux.png
new file mode 100644
index 000000000000..c72be7970982
Binary files /dev/null and b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-light-linux.png differ
diff --git a/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-light-tritanopia-linux.png b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-light-tritanopia-linux.png
new file mode 100644
index 000000000000..c72be7970982
Binary files /dev/null and b/.playwright/snapshots/components/BaseStyles.test.ts-snapshots/BaseStyles-Dev-Default-light-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-colorblind-linux.png
new file mode 100644
index 000000000000..380729cf4173
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-dimmed-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-dimmed-linux.png
new file mode 100644
index 000000000000..6ba0952ef13a
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-dimmed-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-high-contrast-linux.png
new file mode 100644
index 000000000000..572b14f775c9
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-linux.png
new file mode 100644
index 000000000000..380729cf4173
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-tritanopia-linux.png
new file mode 100644
index 000000000000..380729cf4173
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-dark-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-light-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-light-colorblind-linux.png
new file mode 100644
index 000000000000..1ed79aaea664
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-light-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-light-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-light-high-contrast-linux.png
new file mode 100644
index 000000000000..1d4331b7752c
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-light-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-light-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-light-linux.png
new file mode 100644
index 000000000000..1ed79aaea664
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-light-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-light-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-light-tritanopia-linux.png
new file mode 100644
index 000000000000..1ed79aaea664
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Default-light-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-colorblind-linux.png
new file mode 100644
index 000000000000..380729cf4173
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-dimmed-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-dimmed-linux.png
new file mode 100644
index 000000000000..6ba0952ef13a
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-dimmed-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-high-contrast-linux.png
new file mode 100644
index 000000000000..572b14f775c9
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-linux.png
new file mode 100644
index 000000000000..380729cf4173
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-tritanopia-linux.png
new file mode 100644
index 000000000000..380729cf4173
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-dark-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-light-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-light-colorblind-linux.png
new file mode 100644
index 000000000000..1ed79aaea664
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-light-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-light-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-light-high-contrast-linux.png
new file mode 100644
index 000000000000..1d4331b7752c
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-light-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-light-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-light-linux.png
new file mode 100644
index 000000000000..1ed79aaea664
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-light-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-light-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-light-tritanopia-linux.png
new file mode 100644
index 000000000000..1ed79aaea664
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Dev-Default-light-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-colorblind-linux.png
new file mode 100644
index 000000000000..775708b3e595
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-dimmed-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-dimmed-linux.png
new file mode 100644
index 000000000000..691ab37f700a
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-dimmed-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-high-contrast-linux.png
new file mode 100644
index 000000000000..5a59ac5cfc09
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-linux.png
new file mode 100644
index 000000000000..775708b3e595
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-tritanopia-linux.png
new file mode 100644
index 000000000000..775708b3e595
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-dark-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-light-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-light-colorblind-linux.png
new file mode 100644
index 000000000000..7ef2b17da041
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-light-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-light-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-light-high-contrast-linux.png
new file mode 100644
index 000000000000..826116ad1257
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-light-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-light-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-light-linux.png
new file mode 100644
index 000000000000..7ef2b17da041
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-light-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-light-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-light-tritanopia-linux.png
new file mode 100644
index 000000000000..7ef2b17da041
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Labelled-By-External-Element-light-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-colorblind-linux.png
new file mode 100644
index 000000000000..a95a54727762
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-dimmed-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-dimmed-linux.png
new file mode 100644
index 000000000000..07303911f0b0
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-dimmed-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-high-contrast-linux.png
new file mode 100644
index 000000000000..4755127c8585
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-linux.png
new file mode 100644
index 000000000000..a95a54727762
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-tritanopia-linux.png
new file mode 100644
index 000000000000..a95a54727762
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-dark-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-light-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-light-colorblind-linux.png
new file mode 100644
index 000000000000..1e9614f028d0
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-light-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-light-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-light-high-contrast-linux.png
new file mode 100644
index 000000000000..a6b1cc225b80
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-light-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-light-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-light-linux.png
new file mode 100644
index 000000000000..1e9614f028d0
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-light-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-light-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-light-tritanopia-linux.png
new file mode 100644
index 000000000000..1e9614f028d0
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-Selected-Tab-light-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-colorblind-linux.png
new file mode 100644
index 000000000000..e4bbf59873fe
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-dimmed-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-dimmed-linux.png
new file mode 100644
index 000000000000..bccafd46ed99
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-dimmed-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-high-contrast-linux.png
new file mode 100644
index 000000000000..0a0048d51a81
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-linux.png
new file mode 100644
index 000000000000..b76e862b7117
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-tritanopia-linux.png
new file mode 100644
index 000000000000..e4bbf59873fe
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-dark-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-light-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-light-colorblind-linux.png
new file mode 100644
index 000000000000..39fd21dbdede
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-light-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-light-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-light-high-contrast-linux.png
new file mode 100644
index 000000000000..391e41a82a70
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-light-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-light-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-light-linux.png
new file mode 100644
index 000000000000..39fd21dbdede
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-light-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-light-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-light-tritanopia-linux.png
new file mode 100644
index 000000000000..39fd21dbdede
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-In-Loading-State-light-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-colorblind-linux.png
new file mode 100644
index 000000000000..06312377557d
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-dimmed-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-dimmed-linux.png
new file mode 100644
index 000000000000..8b34b8686c28
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-dimmed-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-high-contrast-linux.png
new file mode 100644
index 000000000000..0b566ed6a862
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-linux.png
new file mode 100644
index 000000000000..06312377557d
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-tritanopia-linux.png
new file mode 100644
index 000000000000..06312377557d
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-dark-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-light-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-light-colorblind-linux.png
new file mode 100644
index 000000000000..2dc42e41db51
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-light-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-light-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-light-high-contrast-linux.png
new file mode 100644
index 000000000000..259cc07ed6f7
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-light-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-light-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-light-linux.png
new file mode 100644
index 000000000000..2dc42e41db51
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-light-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-light-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-light-tritanopia-linux.png
new file mode 100644
index 000000000000..2dc42e41db51
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Counters-light-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-colorblind-linux.png
new file mode 100644
index 000000000000..fef8afe02dbc
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-dimmed-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-dimmed-linux.png
new file mode 100644
index 000000000000..e3b49a50fd89
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-dimmed-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-high-contrast-linux.png
new file mode 100644
index 000000000000..e5776e970605
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-linux.png
new file mode 100644
index 000000000000..fef8afe02dbc
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-tritanopia-linux.png
new file mode 100644
index 000000000000..fef8afe02dbc
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-dark-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-light-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-light-colorblind-linux.png
new file mode 100644
index 000000000000..1258c1ed1874
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-light-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-light-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-light-high-contrast-linux.png
new file mode 100644
index 000000000000..30403a93e92b
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-light-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-light-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-light-linux.png
new file mode 100644
index 000000000000..1258c1ed1874
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-light-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-light-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-light-tritanopia-linux.png
new file mode 100644
index 000000000000..1258c1ed1874
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-Hidden-On-Narrow-Screen-light-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-colorblind-linux.png
new file mode 100644
index 000000000000..79b4f821f967
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-dimmed-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-dimmed-linux.png
new file mode 100644
index 000000000000..2af230e86b4a
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-dimmed-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-high-contrast-linux.png
new file mode 100644
index 000000000000..b3ac40e62b7e
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-linux.png
new file mode 100644
index 000000000000..79b4f821f967
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-tritanopia-linux.png
new file mode 100644
index 000000000000..79b4f821f967
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-dark-tritanopia-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-light-colorblind-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-light-colorblind-linux.png
new file mode 100644
index 000000000000..d05768fe7ca4
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-light-colorblind-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-light-high-contrast-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-light-high-contrast-linux.png
new file mode 100644
index 000000000000..39292cd50857
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-light-high-contrast-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-light-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-light-linux.png
new file mode 100644
index 000000000000..d05768fe7ca4
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-light-linux.png differ
diff --git a/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-light-tritanopia-linux.png b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-light-tritanopia-linux.png
new file mode 100644
index 000000000000..d05768fe7ca4
Binary files /dev/null and b/.playwright/snapshots/components/UnderlinePanels.test.ts-snapshots/UnderlinePanels-With-Icons-light-tritanopia-linux.png differ
diff --git a/e2e/components/BaseStyles.test.ts b/e2e/components/BaseStyles.test.ts
new file mode 100644
index 000000000000..22735f58ea5f
--- /dev/null
+++ b/e2e/components/BaseStyles.test.ts
@@ -0,0 +1,44 @@
+import {test, expect} from '@playwright/test'
+import {visit} from '../test-helpers/storybook'
+import {themes} from '../test-helpers/themes'
+
+const stories = [
+ {
+ id: 'behaviors-basestyles-dev--default',
+ title: 'Dev Default',
+ },
+] as const
+
+test.describe('BaseStyles', () => {
+ for (const story of stories) {
+ test.describe(story.title, () => {
+ for (const theme of themes) {
+ test.describe(theme, () => {
+ test('default @vrt', async ({page}) => {
+ await visit(page, {
+ id: story.id,
+ globals: {
+ colorScheme: theme,
+ },
+ })
+
+ // Default state
+ expect(await page.screenshot({animations: 'disabled'})).toMatchSnapshot(
+ `BaseStyles.${story.title}.${theme}.png`,
+ )
+ })
+
+ test('axe @aat', async ({page}) => {
+ await visit(page, {
+ id: story.id,
+ globals: {
+ colorScheme: theme,
+ },
+ })
+ await expect(page).toHaveNoViolations()
+ })
+ })
+ }
+ })
+ }
+})
diff --git a/e2e/components/UnderlinePanels.test.ts b/e2e/components/UnderlinePanels.test.ts
index 3166549175f5..fd9b5ec97647 100644
--- a/e2e/components/UnderlinePanels.test.ts
+++ b/e2e/components/UnderlinePanels.test.ts
@@ -2,244 +2,74 @@ import {test, expect} from '@playwright/test'
import {visit} from '../test-helpers/storybook'
import {themes} from '../test-helpers/themes'
-test.describe('UnderlinePanels', () => {
- test.describe('Default', () => {
- for (const theme of themes) {
- test.describe(theme, () => {
- test('default @vrt', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels--default',
- globals: {
- colorScheme: theme,
- },
- })
-
- // Default state
- expect(await page.screenshot()).toMatchSnapshot(`UnderlineNav.Default.${theme}.png`)
- })
-
- test('axe @aat', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels--default',
- globals: {
- colorScheme: theme,
- },
- })
- await expect(page).toHaveNoViolations({
- rules: {
- 'color-contrast': {
- enabled: theme !== 'dark_dimmed',
- },
- },
- })
- })
- })
- }
- })
-
- test.describe('Labelled By External Element', () => {
- for (const theme of themes) {
- test.describe(theme, () => {
- test('default @vrt', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels-features--labelled-by-external-element',
- globals: {
- colorScheme: theme,
- },
- })
-
- // Default state
- expect(await page.screenshot()).toMatchSnapshot(`UnderlineNav.Labelled By External Element.${theme}.png`)
- })
-
- test('axe @aat', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels-features--labelled-by-external-element',
- globals: {
- colorScheme: theme,
- },
- })
- await expect(page).toHaveNoViolations({
- rules: {
- 'color-contrast': {
- enabled: theme !== 'dark_dimmed',
- },
- },
- })
- })
- })
- }
- })
-
- test.describe('Selected Tab', () => {
- for (const theme of themes) {
- test.describe(theme, () => {
- test('default @vrt', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels-features--selected-tab',
- globals: {
- colorScheme: theme,
- },
- })
-
- // Default state
- expect(await page.screenshot()).toMatchSnapshot(`UnderlineNav.Selected Tab.${theme}.png`)
- })
+const stories: Array<{title: string; id: string}> = [
+ {
+ title: 'Default',
+ id: 'experimental-components-underlinepanels--default',
+ },
+ {
+ title: 'Dev Default',
+ id: 'experimental-components-underlinepanels-dev--default',
+ },
+ {
+ title: 'Labelled By External Element',
+ id: 'experimental-components-underlinepanels-features--labelled-by-external-element',
+ },
+ {
+ title: 'Selected Tab',
+ id: 'experimental-components-underlinepanels-features--selected-tab',
+ },
+ {
+ title: 'With Counters',
+ id: 'experimental-components-underlinepanels-features--with-counters',
+ },
+ {
+ title: 'With Counters In Loading State',
+ id: 'experimental-components-underlinepanels-features--with-counters-in-loading-state',
+ },
+ {
+ title: 'With Icons',
+ id: 'experimental-components-underlinepanels-features--with-icons',
+ },
+ {
+ title: 'With Icons Hidden On Narrow Screen',
+ id: 'experimental-components-underlinepanels-features--with-icons-hidden-on-narrow-screen',
+ },
+]
- test('axe @aat', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels-features--selected-tab',
- globals: {
- colorScheme: theme,
- },
- })
- await expect(page).toHaveNoViolations({
- rules: {
- 'color-contrast': {
- enabled: theme !== 'dark_dimmed',
- },
- },
- })
- })
- })
- }
- })
-
- test.describe('With Counters', () => {
- for (const theme of themes) {
- test.describe(theme, () => {
- test('default @vrt', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels-features--with-counters',
- globals: {
- colorScheme: theme,
- },
- })
-
- // Default state
- expect(await page.screenshot()).toMatchSnapshot(`UnderlineNav.With Counters.${theme}.png`)
- })
-
- test('axe @aat', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels-features--with-counters',
- globals: {
- colorScheme: theme,
- },
- })
- await expect(page).toHaveNoViolations({
- rules: {
- 'color-contrast': {
- enabled: theme !== 'dark_dimmed',
+test.describe('UnderlinePanels', () => {
+ for (const story of stories) {
+ test.describe(story.title, () => {
+ for (const theme of themes) {
+ test.describe(theme, () => {
+ test('@vrt', async ({page}) => {
+ await visit(page, {
+ id: story.id,
+ globals: {
+ colorScheme: theme,
},
- },
- })
- })
- })
- }
- })
+ })
- test.describe('With Counters In Loading State', () => {
- for (const theme of themes) {
- test.describe(theme, () => {
- test('default @vrt', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels-features--with-counters-in-loading-state',
- globals: {
- colorScheme: theme,
- },
+ expect(await page.screenshot()).toMatchSnapshot(`UnderlinePanels.${story.title}.${theme}.png`)
})
- // Default state
- expect(await page.screenshot()).toMatchSnapshot(`UnderlineNav.With Counters In Loading State.${theme}.png`)
- })
-
- test('axe @aat', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels-features--with-counters-in-loading-state',
- globals: {
- colorScheme: theme,
- },
- })
- await expect(page).toHaveNoViolations({
- rules: {
- 'color-contrast': {
- enabled: theme !== 'dark_dimmed',
+ test('@aat', async ({page}) => {
+ await visit(page, {
+ id: story.id,
+ globals: {
+ colorScheme: theme,
},
- },
- })
- })
- })
- }
- })
-
- test.describe('With Icons', () => {
- for (const theme of themes) {
- test.describe(theme, () => {
- test('default @vrt', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels-features--with-icons',
- globals: {
- colorScheme: theme,
- },
- })
-
- // Default state
- expect(await page.screenshot()).toMatchSnapshot(`UnderlineNav.With Icons.${theme}.png`)
- })
-
- test('axe @aat', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels-features--with-icons',
- globals: {
- colorScheme: theme,
- },
- })
- await expect(page).toHaveNoViolations({
- rules: {
- 'color-contrast': {
- enabled: theme !== 'dark_dimmed',
- },
- },
- })
- })
- })
- }
- })
-
- test.describe('With Icons Hidden On Narrow Screen', () => {
- for (const theme of themes) {
- test.describe(theme, () => {
- test('default @vrt', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels-features--with-icons-hidden-on-narrow-screen',
- globals: {
- colorScheme: theme,
- },
- })
-
- // Default state
- expect(await page.screenshot()).toMatchSnapshot(
- `UnderlineNav.With Icons Hidden On Narrow Screen.${theme}.png`,
- )
- })
-
- test('axe @aat', async ({page}) => {
- await visit(page, {
- id: 'experimental-components-underlinepanels-features--with-icons-hidden-on-narrow-screen',
- globals: {
- colorScheme: theme,
- },
- })
- await expect(page).toHaveNoViolations({
- rules: {
- 'color-contrast': {
- enabled: theme !== 'dark_dimmed',
+ })
+ await expect(page).toHaveNoViolations({
+ rules: {
+ 'color-contrast': {
+ enabled: theme !== 'dark_dimmed',
+ },
},
- },
+ })
})
})
- })
- }
- })
+ }
+ })
+ }
})
diff --git a/examples/app-router/package.json b/examples/app-router/package.json
index 67edd7a1270a..2546bf848867 100644
--- a/examples/app-router/package.json
+++ b/examples/app-router/package.json
@@ -15,7 +15,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"styled-components": "5.x",
- "typescript": "^5.6.3"
+ "typescript": "^5.7.2"
},
"devDependencies": {
"@next/eslint-plugin-next": "14.1.0",
diff --git a/examples/codesandbox/package.json b/examples/codesandbox/package.json
index dc895e279b3e..fb8e7d13ec6a 100644
--- a/examples/codesandbox/package.json
+++ b/examples/codesandbox/package.json
@@ -25,7 +25,7 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.7",
"styled-components": "5.x",
- "typescript": "^5.6.3",
+ "typescript": "^5.7.2",
"vite": "^5.2.14"
}
}
diff --git a/examples/consumer-test/App.tsx b/examples/consumer-test/App.tsx
deleted file mode 100644
index 0d947c6888d9..000000000000
--- a/examples/consumer-test/App.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import React from 'react'
-import {Box} from '@primer/react'
-
-export default function App() {
- return
-}
diff --git a/examples/consumer-test/README.md b/examples/consumer-test/README.md
deleted file mode 100644
index 6e7ac65e3ba7..000000000000
--- a/examples/consumer-test/README.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Primer React Consumer Test
-
-This directory is used to run a simple test that asserts that a consumer of
-Primer React can build their own project with strict TypeScript options enabled,
-including `"skipLibCheck": false`.
-
-During Primer React's build process, we run the TypeScript compiler and output
-`.d.ts` declaration files for consumers of Primer React that are using
-TypeScript. If the build script runs with a TypeScript configuration that has
-any files in its `types` or `typeRoots` that import any of our development
-dependencies, it's possible for our build output to be polluted by interface
-augmentations in those dependencies, or in transitive dependencies.
-
-The best way to avoid this is to ensure that any files that import development
-dependencies are excluded in our `tsconfig.build.json` file we use to build
-Primer React.
-
-If a mistake is made and a file is omitted, we will catch those when we attempt
-to build this consumer library, which has `"skipLibCheck": false` in its
-TypeScript configuration.
-
-For historical context, see these issues:
-
-- [v27.0.0 breaks TypeScript typings](https://github.com/primer/react/issues/1163)
-- [Storybook dependency changes types in build output](https://github.com/primer/react/issues/1849)
diff --git a/examples/consumer-test/package.json b/examples/consumer-test/package.json
deleted file mode 100644
index aad3a55c548d..000000000000
--- a/examples/consumer-test/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name": "example-consumer-test",
- "version": "0.0.0",
- "private": true,
- "scripts": {
- "check": "tsc --noEmit"
- },
- "dependencies": {
- "@types/react": "^18.3.11",
- "@types/react-dom": "^18.2.19",
- "@types/styled-components": "^5.1.11",
- "@primer/react": "37.6.0",
- "react": "^18.0.0",
- "react-dom": "^18.0.0",
- "styled-components": "^5.3.11",
- "typescript": "~4.7.2"
- }
-}
diff --git a/examples/consumer-test/tsconfig.json b/examples/consumer-test/tsconfig.json
deleted file mode 100644
index 1a898abb1a08..000000000000
--- a/examples/consumer-test/tsconfig.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "compilerOptions": {
- "skipLibCheck": false, // IMPORTANT: Validates our type outputs
- "target": "esnext",
- "module": "commonjs",
- "allowJs": true,
- "checkJs": false,
- "jsx": "preserve",
- "declaration": true,
- "noEmit": true,
- "strict": true,
- "moduleResolution": "node",
- "esModuleInterop": true,
- "forceConsistentCasingInFileNames": true
- },
- "include": ["./*.tsx"]
-}
diff --git a/examples/theming/package.json b/examples/theming/package.json
index 7c5f08213347..8c89876ea7a7 100644
--- a/examples/theming/package.json
+++ b/examples/theming/package.json
@@ -17,7 +17,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"styled-components": "5.x",
- "typescript": "^5.6.3"
+ "typescript": "^5.7.2"
},
"devDependencies": {
"@next/eslint-plugin-next": "14.1.0",
diff --git a/package-lock.json b/package-lock.json
index 8394b00ba12d..1eb9a8e7d56a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -48,7 +48,7 @@
"rimraf": "5.0.5",
"size-limit": "11.1.5",
"stylelint": "16.9.0",
- "typescript": "5.6.3"
+ "typescript": "^5.7.2"
},
"engines": {
"node": ">=12",
@@ -62,12 +62,12 @@
"name": "example-app-router",
"version": "0.0.0",
"dependencies": {
- "@primer/react": "37.5.0",
+ "@primer/react": "37.6.0",
"next": "^14.2.10",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"styled-components": "5.x",
- "typescript": "^5.6.3"
+ "typescript": "^5.7.2"
},
"devDependencies": {
"@next/eslint-plugin-next": "14.1.0",
@@ -81,7 +81,7 @@
"react-dom": "^18.3.1"
},
"devDependencies": {
- "@primer/react": "37.5.0",
+ "@primer/react": "37.6.0",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.11.0",
@@ -91,15 +91,16 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.7",
"styled-components": "5.x",
- "typescript": "^5.6.3",
+ "typescript": "^5.7.2",
"vite": "^5.2.14"
}
},
"examples/consumer-test": {
"name": "example-consumer-test",
"version": "0.0.0",
+ "extraneous": true,
"dependencies": {
- "@primer/react": "37.5.0",
+ "@primer/react": "37.6.0",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.2.19",
"@types/styled-components": "^5.1.11",
@@ -109,29 +110,18 @@
"typescript": "~4.7.2"
}
},
- "examples/consumer-test/node_modules/typescript": {
- "version": "4.7.4",
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=4.2.0"
- }
- },
"examples/theming": {
"name": "example-theming",
"version": "0.0.0",
"dependencies": {
"@primer/octicons-react": "^19.9.0",
- "@primer/react": "37.5.0",
+ "@primer/react": "37.6.0",
"clsx": "^1.2.1",
"next": "^14.2.10",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"styled-components": "5.x",
- "typescript": "^5.6.3"
+ "typescript": "^5.7.2"
},
"devDependencies": {
"@next/eslint-plugin-next": "14.1.0",
@@ -8425,6 +8415,7 @@
},
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.5",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/react": "*",
@@ -8657,6 +8648,7 @@
},
"node_modules/@types/react-dom": {
"version": "18.3.0",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/react": "*"
@@ -8713,6 +8705,7 @@
},
"node_modules/@types/styled-components": {
"version": "5.1.34",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/hoist-non-react-statics": "*",
@@ -14609,10 +14602,6 @@
"resolved": "examples/app-router",
"link": true
},
- "node_modules/example-consumer-test": {
- "resolved": "examples/consumer-test",
- "link": true
- },
"node_modules/example-theming": {
"resolved": "examples/theming",
"link": true
@@ -28714,9 +28703,9 @@
"license": "MIT"
},
"node_modules/typescript": {
- "version": "5.6.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
- "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
+ "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@@ -30301,7 +30290,7 @@
"postcss": "^8.4.41",
"postcss-custom-properties-fallback": "^1.0.2",
"postcss-mixins": "^11.0.1",
- "typescript": "^5.6.3"
+ "typescript": "^5.7.2"
},
"peerDependencies": {
"postcss": "^8.4.41"
@@ -30443,7 +30432,7 @@
},
"packages/react": {
"name": "@primer/react",
- "version": "37.5.0",
+ "version": "37.6.0",
"license": "MIT",
"dependencies": {
"@github/relative-time-element": "^4.4.3",
@@ -30569,7 +30558,7 @@
"terser": "5.36.0",
"ts-toolbelt": "9.6.0",
"tsx": "4.7.0",
- "typescript": "^5.6.3",
+ "typescript": "^5.7.2",
"typescript-plugin-css-modules": "5.1.0",
"unist-util-find": "3.0.0",
"unist-util-find-before": "4.0.0",
@@ -30895,7 +30884,8 @@
"postcss-modules": "^6.0.0",
"rimraf": "^5.0.7",
"rollup-plugin-esbuild": "^6.1.1",
- "rollup-plugin-typescript2": "^0.36.0"
+ "rollup-plugin-typescript2": "^0.36.0",
+ "typescript": "^5.7.2"
},
"peerDependencies": {
"postcss": "^8.4.38",
diff --git a/package.json b/package.json
index cf3ab916a778..e5e34f232e60 100644
--- a/package.json
+++ b/package.json
@@ -76,7 +76,7 @@
"rimraf": "5.0.5",
"size-limit": "11.1.5",
"stylelint": "16.9.0",
- "typescript": "5.6.3"
+ "typescript": "^5.7.2"
},
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "^4.9.6"
@@ -93,5 +93,6 @@
"webpack": false,
"running": false
}
- ]
+ ],
+ "packageManager": "npm@10.9.1+sha512.c89530d37c4baa38afd43e76a077a84b9aa63840b986426584fd5c5a54ab0a0b21bb1595c851042b733784b0b43706d36a494b4d8ae1a086a762cb8d3f95942a"
}
diff --git a/packages/postcss-preset-primer/package.json b/packages/postcss-preset-primer/package.json
index 3ba7cfd1ec12..305a93706cbb 100644
--- a/packages/postcss-preset-primer/package.json
+++ b/packages/postcss-preset-primer/package.json
@@ -29,6 +29,6 @@
"postcss": "^8.4.41",
"postcss-custom-properties-fallback": "^1.0.2",
"postcss-mixins": "^11.0.1",
- "typescript": "^5.6.3"
+ "typescript": "^5.7.2"
}
}
diff --git a/packages/react/package.json b/packages/react/package.json
index 10f99488535f..d6b18e57148b 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -201,7 +201,7 @@
"terser": "5.36.0",
"ts-toolbelt": "9.6.0",
"tsx": "4.7.0",
- "typescript": "^5.6.3",
+ "typescript": "^5.7.2",
"typescript-plugin-css-modules": "5.1.0",
"unist-util-find": "3.0.0",
"unist-util-find-before": "4.0.0",
diff --git a/packages/react/script/components-json/build.ts b/packages/react/script/components-json/build.ts
index c698b1a0a0a0..33c7a82f7bf4 100644
--- a/packages/react/script/components-json/build.ts
+++ b/packages/react/script/components-json/build.ts
@@ -22,6 +22,7 @@ type Component = {
| '@primer/react/experimental'
| '@primer/react/drafts'
stories: Array<{id: string; code?: string}>
+ source?: string
}
const ajv = new Ajv()
@@ -114,7 +115,10 @@ const components = docsFiles.map(docsFilepath => {
}
// TODO: Provide default type and description for sx and ref props
- return docs
+ return {
+ source: `https://github.com/primer/react/tree/main/packages/react/${docsFilepath.substring(0, docsFilepath.lastIndexOf('/'))}`,
+ ...docs,
+ }
})
const data = {schemaVersion: 2, components: keyBy(components, 'id')}
diff --git a/packages/react/script/components-json/component.schema.json b/packages/react/script/components-json/component.schema.json
index 4bc4f0037bc7..7fe4969c0432 100644
--- a/packages/react/script/components-json/component.schema.json
+++ b/packages/react/script/components-json/component.schema.json
@@ -77,6 +77,10 @@
"type": "string",
"description": "The path to import the component from. i.e. '@primer/react/experimental'"
},
+ "source": {
+ "type": "string",
+ "description": "Link to the component source on GitHub"
+ },
"stories": {
"type": "array",
diff --git a/packages/react/src/ActionBar/ActionBar.docs.json b/packages/react/src/ActionBar/ActionBar.docs.json
index 8d1ce1dba9b2..878a96eafe2e 100644
--- a/packages/react/src/ActionBar/ActionBar.docs.json
+++ b/packages/react/src/ActionBar/ActionBar.docs.json
@@ -5,7 +5,7 @@
"a11yReviewed": true,
"stories": [
{
- "id": "components-actionbar--default"
+ "id": "experimental-components-actionbar--default"
}
],
"importPath": "@primer/react",
diff --git a/packages/react/src/Banner/Banner.docs.json b/packages/react/src/Banner/Banner.docs.json
index 5e2c8980b3b0..9a22b629a396 100644
--- a/packages/react/src/Banner/Banner.docs.json
+++ b/packages/react/src/Banner/Banner.docs.json
@@ -6,46 +6,46 @@
"importPath": "@primer/react/experimental",
"stories": [
{
- "id": "components-banner--default"
+ "id": "experimental-components-banner--default"
},
{
- "id": "components-banner-features--critical"
+ "id": "experimental-components-banner-features--critical"
},
{
- "id": "components-banner-features--info"
+ "id": "experimental-components-banner-features--info"
},
{
- "id": "components-banner-features--success"
+ "id": "experimental-components-banner-features--success"
},
{
- "id": "components-banner-features--upsell"
+ "id": "experimental-components-banner-features--upsell"
},
{
- "id": "components-banner-features--warning"
+ "id": "experimental-components-banner-features--warning"
},
{
- "id": "components-banner-features--dismiss"
+ "id": "experimental-components-banner-features--dismiss"
},
{
- "id": "components-banner-features--dismiss-with-actions"
+ "id": "experimental-components-banner-features--dismiss-with-actions"
},
{
- "id": "components-banner-features--with-hidden-title"
+ "id": "experimental-components-banner-features--with-hidden-title"
},
{
- "id": "components-banner-features--with-hidden-title-and-actions"
+ "id": "experimental-components-banner-features--with-hidden-title-and-actions"
},
{
- "id": "components-banner-features--dismissible-with-hidden-title-and-actions"
+ "id": "experimental-components-banner-features--dismissible-with-hidden-title-and-actions"
},
{
- "id": "components-banner-features--dismissible-with-hidden-title-and-secondary-action"
+ "id": "experimental-components-banner-features--dismissible-with-hidden-title-and-secondary-action"
},
{
- "id": "components-banner-features--with-actions"
+ "id": "experimental-components-banner-features--with-actions"
},
{
- "id": "components-banner-features--custom-icon"
+ "id": "experimental-components-banner-features--custom-icon"
}
],
"props": [
diff --git a/packages/react/src/BaseStyles.dev.stories.tsx b/packages/react/src/BaseStyles.dev.stories.tsx
new file mode 100644
index 000000000000..d313f0890099
--- /dev/null
+++ b/packages/react/src/BaseStyles.dev.stories.tsx
@@ -0,0 +1,11 @@
+import {BaseStyles} from '.'
+import type {Meta} from '@storybook/react'
+import React from 'react'
+import type {ComponentProps} from './utils/types'
+
+export default {
+ title: 'Behaviors/BaseStyles/Dev',
+ component: BaseStyles,
+} as Meta>
+
+export const Default = () => Hello
diff --git a/packages/react/src/Blankslate/Blankslate.docs.json b/packages/react/src/Blankslate/Blankslate.docs.json
index a2cf0807b057..234cfa9cb89f 100644
--- a/packages/react/src/Blankslate/Blankslate.docs.json
+++ b/packages/react/src/Blankslate/Blankslate.docs.json
@@ -5,25 +5,25 @@
"a11yReviewed": false,
"stories": [
{
- "id": "drafts-components-blankslate--default"
+ "id": "experimental-components-blankslate--default"
},
{
- "id": "drafts-components-blankslate-features--with-visual"
+ "id": "experimental-components-blankslate-features--with-visual"
},
{
- "id": "drafts-components-blankslate-features--with-primary-action"
+ "id": "experimental-components-blankslate-features--with-primary-action"
},
{
- "id": "drafts-components-blankslate-features--with-secondary-action"
+ "id": "experimental-components-blankslate-features--with-secondary-action"
},
{
- "id": "drafts-components-blankslate-features--with-border"
+ "id": "experimental-components-blankslate-features--with-border"
},
{
- "id": "drafts-components-blankslate-features--narrow"
+ "id": "experimental-components-blankslate-features--narrow"
},
{
- "id": "drafts-components-blankslate-features--spacious"
+ "id": "experimental-components-blankslate-features--spacious"
}
],
"importPath": "@primer/react/experimental",
diff --git a/packages/react/src/Checkbox/Checkbox.test.tsx b/packages/react/src/Checkbox/Checkbox.test.tsx
index bf115bfd6ec5..05dbad283174 100644
--- a/packages/react/src/Checkbox/Checkbox.test.tsx
+++ b/packages/react/src/Checkbox/Checkbox.test.tsx
@@ -9,7 +9,7 @@ describe('Checkbox', () => {
beforeEach(() => {
jest.resetAllMocks()
})
- behavesAsComponent({Component: Checkbox})
+ behavesAsComponent({Component: Checkbox, options: {skipAs: true}})
checkExports('Checkbox', {
default: Checkbox,
diff --git a/packages/react/src/Checkbox/Checkbox.tsx b/packages/react/src/Checkbox/Checkbox.tsx
index 42fac1068807..5b60739d4d02 100644
--- a/packages/react/src/Checkbox/Checkbox.tsx
+++ b/packages/react/src/Checkbox/Checkbox.tsx
@@ -1,17 +1,12 @@
import {clsx} from 'clsx'
-import styled from 'styled-components'
import {useProvidedRefOrCreate} from '../hooks'
import React, {useContext, useEffect, type ChangeEventHandler, type InputHTMLAttributes, type ReactElement} from 'react'
-import sx, {type SxProp} from '../sx'
+import {type SxProp} from '../sx'
import useLayoutEffect from '../utils/useIsomorphicLayoutEffect'
import type {FormValidationStatus} from '../utils/types/FormValidationStatus'
import {CheckboxGroupContext} from '../CheckboxGroup/CheckboxGroupContext'
-import getGlobalFocusStyles from '../internal/utils/getGlobalFocusStyles'
-import {get} from '../constants'
-import {sharedCheckboxAndRadioStyles} from '../internal/utils/sharedCheckboxAndRadioStyles'
import classes from './Checkbox.module.css'
import sharedClasses from './shared.module.css'
-import {useFeatureFlag} from '../FeatureFlags'
import Box from '../Box'
export type CheckboxProps = {
@@ -43,106 +38,6 @@ export type CheckboxProps = {
} & Exclude, 'value'> &
SxProp
-const StyledCheckbox = styled.input`
- ${sharedCheckboxAndRadioStyles};
- border-radius: ${get('radii.1')};
- transition:
- background-color,
- border-color 80ms cubic-bezier(0.33, 1, 0.68, 1); /* checked -> unchecked - add 120ms delay to fully see animation-out */
-
- &::before {
- width: var(--base-size-16, 16px);
- height: var(--base-size-16, 16px);
- visibility: hidden;
- content: '';
- background-color: ${get('colors.fg.onEmphasis')};
- transition: visibility 0s linear 230ms;
- clip-path: inset(var(--base-size-16, 16px) 0 0 0);
- mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iOSIgdmlld0JveD0iMCAwIDEyIDkiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTEuNzgwMyAwLjIxOTYyNUMxMS45MjEgMC4zNjA0MjcgMTIgMC41NTEzMDUgMTIgMC43NTAzMTNDMTIgMC45NDkzMjEgMTEuOTIxIDEuMTQwMTkgMTEuNzgwMyAxLjI4MUw0LjUxODYgOC41NDA0MkM0LjM3Nzc1IDguNjgxIDQuMTg2ODIgOC43NiAzLjk4Nzc0IDguNzZDMy43ODg2NyA4Ljc2IDMuNTk3NzMgOC42ODEgMy40NTY4OSA4LjU0MDQyTDAuMjAxNjIyIDUuMjg2MkMwLjA2ODkyNzcgNS4xNDM4MyAtMC4wMDMzMDkwNSA0Ljk1NTU1IDAuMDAwMTE2NDkzIDQuNzYwOThDMC4wMDM1NTIwNSA0LjU2NjQzIDAuMDgyMzg5NCA0LjM4MDgxIDAuMjIwMDMyIDQuMjQzMjFDMC4zNTc2NjUgNC4xMDU2MiAwLjU0MzM1NSA0LjAyNjgxIDAuNzM3OTcgNC4wMjMzOEMwLjkzMjU4NCA0LjAxOTk0IDEuMTIwOTMgNC4wOTIxNyAxLjI2MzM0IDQuMjI0ODJMMy45ODc3NCA2Ljk0ODM1TDEwLjcxODYgMC4yMTk2MjVDMTAuODU5NSAwLjA3ODk5MjMgMTEuMDUwNCAwIDExLjI0OTUgMEMxMS40NDg1IDAgMTEuNjM5NSAwLjA3ODk5MjMgMTEuNzgwMyAwLjIxOTYyNVoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=');
- mask-size: 75%;
- mask-repeat: no-repeat;
- mask-position: center;
-
- animation: checkmarkOut 80ms cubic-bezier(0.65, 0, 0.35, 1) forwards;
- }
-
- &:checked,
- &:indeterminate {
- background: var(--control-checked-bgColor-rest, ${get('colors.accent.fg')});
- border-color: var(
- --control-checked-bgColor-rest,
- ${get('colors.accent.fg')}
- ); /* using bgColor here to avoid a border change in dark high contrast */
-
- &::before {
- animation: checkmarkIn 80ms cubic-bezier(0.65, 0, 0.35, 1) forwards 80ms;
- }
- }
-
- &:disabled {
- cursor: not-allowed;
- }
-
- &:checked {
- transition:
- background-color,
- border-color 80ms cubic-bezier(0.32, 0, 0.67, 0) 0ms;
-
- &::before {
- visibility: visible;
- transition: visibility 0s linear 0s;
- }
-
- &:disabled {
- background-color: var(--control-checked-bgColor-disabled, ${get('colors.fg.muted')});
- border-color: var(--control-checked-borderColor-disabled, ${get('colors.fg.muted')});
- opacity: 1;
-
- &::before {
- background-color: var(--control-checked-fgColor-disabled, ${get('colors.fg.onEmphasis')});
- }
- }
-
- /* Windows High Contrast mode */
- @media (forced-colors: active) {
- background-color: canvastext;
- border-color: canvastext;
- }
- }
-
- &:indeterminate {
- background: var(--control-checked-bgColor-rest, ${get('colors.accent.fg')});
- &::before {
- mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMiIgdmlld0JveD0iMCAwIDEwIDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMCAxQzAgMC40NDc3MTUgMC40NDc3MTUgMCAxIDBIOUM5LjU1MjI5IDAgMTAgMC40NDc3MTUgMTAgMUMxMCAxLjU1MjI4IDkuNTUyMjkgMiA5IDJIMUMwLjQ0NzcxNSAyIDAgMS41NTIyOCAwIDFaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K');
- visibility: visible;
- }
- }
-
- ${getGlobalFocusStyles()};
-
- ${sx};
-
- @keyframes checkmarkIn {
- from {
- clip-path: inset(var(--base-size-16, 16px) 0 0 0);
- }
-
- to {
- clip-path: inset(0 0 0 0);
- }
- }
-
- @keyframes checkmarkOut {
- from {
- clip-path: inset(0 0 0 0);
- }
-
- to {
- clip-path: inset(var(--base-size-16, 16px) 0 0 0);
- }
- }
-`
-
/**
* An accessible, native checkbox component
*/
@@ -163,7 +58,6 @@ const Checkbox = React.forwardRef(
},
ref,
): ReactElement => {
- const enabled = useFeatureFlag('primer_react_css_modules_ga')
const checkboxRef = useProvidedRefOrCreate(ref as React.RefObject)
const checkboxGroupContext = useContext(CheckboxGroupContext)
const handleOnChange: ChangeEventHandler = e => {
@@ -204,21 +98,17 @@ const Checkbox = React.forwardRef(
}
})
- if (enabled) {
- if (sxProp) {
- return (
-
- )
- }
- return
+ if (sxProp) {
+ return (
+
+ )
}
-
- return
+ return
},
)
diff --git a/packages/react/src/CounterLabel/CounterLabel.tsx b/packages/react/src/CounterLabel/CounterLabel.tsx
index 707007cc9dfc..08105b8701db 100644
--- a/packages/react/src/CounterLabel/CounterLabel.tsx
+++ b/packages/react/src/CounterLabel/CounterLabel.tsx
@@ -1,13 +1,9 @@
import {clsx} from 'clsx'
import type {HTMLAttributes} from 'react'
import React, {forwardRef} from 'react'
-import styled from 'styled-components'
-import {get} from '../constants'
-import sx from '../sx'
import type {SxProp} from '../sx'
import {VisuallyHidden} from '../VisuallyHidden'
import {defaultSxProp} from '../utils/defaultSxProp'
-import {useFeatureFlag} from '../FeatureFlags'
import Box from '../Box'
import classes from './CounterLabel.module.css'
@@ -20,7 +16,6 @@ export type CounterLabelProps = React.PropsWithChildren<
const CounterLabel = forwardRef(
({scheme = 'secondary', sx = defaultSxProp, className, children, ...rest}, forwardedRef) => {
- const enabled = useFeatureFlag('primer_react_css_modules_ga')
const label = ({children})
const counterProps = {
ref: forwardedRef,
@@ -29,67 +24,27 @@ const CounterLabel = forwardRef(
...rest,
}
- if (enabled) {
- if (sx !== defaultSxProp) {
- return (
- <>
-
- {children}
-
- {label}
- >
- )
- }
+ if (sx !== defaultSxProp) {
return (
<>
-
+
{children}
-
+
{label}
>
)
}
-
return (
<>
-
+
{children}
-
+
{label}
>
)
},
)
-const StyledCounterLabel = styled.span`
- display: inline-block;
- padding: var(--base-size-2, 0.125rem) var(--base-size-6, 0.375rem);
- font-size: 12px;
- font-weight: var(--base-text-weight-semibold, bold);
- line-height: 1;
- border-radius: 20px;
- border: var(--borderWidth-thin, max(1px, 0.0625rem)) solid var(--counter-borderColor, var(--color-counter-border));
-
- &:where([data-scheme='primary']) {
- background-color: ${get('colors.neutral.emphasis')};
- color: ${get('colors.fg.onEmphasis')};
- }
-
- &:where([data-scheme='secondary']) {
- background-color: ${get('colors.neutral.muted')};
- color: ${get('colors.fg.default')};
- }
-
- &:where(:empty) {
- display: none;
- }
-
- /* Place the sx prop styles after previously inserted styles so that it will win out in specificity */
- & {
- ${sx}
- }
-`
-
CounterLabel.displayName = 'CounterLabel'
export default CounterLabel
diff --git a/packages/react/src/CounterLabel/__snapshots__/CounterLabel.test.tsx.snap b/packages/react/src/CounterLabel/__snapshots__/CounterLabel.test.tsx.snap
index 1d08b1f9ece0..77ff00aad26c 100644
--- a/packages/react/src/CounterLabel/__snapshots__/CounterLabel.test.tsx.snap
+++ b/packages/react/src/CounterLabel/__snapshots__/CounterLabel.test.tsx.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CounterLabel renders with secondary scheme when no "scheme" prop is provided 1`] = `
-.c1:not(:focus):not(:active):not(:focus-within) {
+.c0:not(:focus):not(:active):not(:focus-within) {
-webkit-clip-path: inset(50%);
clip-path: inset(50%);
height: 1px;
@@ -11,30 +11,16 @@ exports[`CounterLabel renders with secondary scheme when no "scheme" prop is pro
width: 1px;
}
-.c0 {
- display: inline-block;
- padding: var(--base-size-2,0.125rem) var(--base-size-6,0.375rem);
- font-size: 12px;
- font-weight: var(--base-text-weight-semibold,bold);
- line-height: 1;
- border-radius: 20px;
- border: var(--borderWidth-thin,max(1px,0.0625rem)) solid var(--counter-borderColor,var(--color-counter-border));
-}
-
-.c0:where(:empty) {
- display: none;
-}
-
1234
(
1234
@@ -44,7 +30,7 @@ exports[`CounterLabel renders with secondary scheme when no "scheme" prop is pro
`;
exports[`CounterLabel respects the primary "scheme" prop 1`] = `
-.c1:not(:focus):not(:active):not(:focus-within) {
+.c0:not(:focus):not(:active):not(:focus-within) {
-webkit-clip-path: inset(50%);
clip-path: inset(50%);
height: 1px;
@@ -54,30 +40,16 @@ exports[`CounterLabel respects the primary "scheme" prop 1`] = `
width: 1px;
}
-.c0 {
- display: inline-block;
- padding: var(--base-size-2,0.125rem) var(--base-size-6,0.375rem);
- font-size: 12px;
- font-weight: var(--base-text-weight-semibold,bold);
- line-height: 1;
- border-radius: 20px;
- border: var(--borderWidth-thin,max(1px,0.0625rem)) solid var(--counter-borderColor,var(--color-counter-border));
-}
-
-.c0:where(:empty) {
- display: none;
-}
-
1234
(
1234
diff --git a/packages/react/src/DataTable/DataTable.docs.json b/packages/react/src/DataTable/DataTable.docs.json
index 773441478d23..88d0373ae346 100644
--- a/packages/react/src/DataTable/DataTable.docs.json
+++ b/packages/react/src/DataTable/DataTable.docs.json
@@ -5,43 +5,43 @@
"a11yReviewed": true,
"stories": [
{
- "id": "drafts-components-datatable--default"
+ "id": "experimental-components-datatable--default"
},
{
- "id": "drafts-components-datatable-features--with-title"
+ "id": "experimental-components-datatable-features--with-title"
},
{
- "id": "drafts-components-datatable-features--with-title-and-subtitle"
+ "id": "experimental-components-datatable-features--with-title-and-subtitle"
},
{
- "id": "drafts-components-datatable-features--with-sorting"
+ "id": "experimental-components-datatable-features--with-sorting"
},
{
- "id": "drafts-components-datatable-features--with-actions"
+ "id": "experimental-components-datatable-features--with-actions"
},
{
- "id": "drafts-components-datatable-features--with-action"
+ "id": "experimental-components-datatable-features--with-action"
},
{
- "id": "drafts-components-datatable-features--with-row-action"
+ "id": "experimental-components-datatable-features--with-row-action"
},
{
- "id": "drafts-components-datatable-features--with-row-actions"
+ "id": "experimental-components-datatable-features--with-row-actions"
},
{
- "id": "drafts-components-datatable-features--with-row-action-menu"
+ "id": "experimental-components-datatable-features--with-row-action-menu"
},
{
- "id": "drafts-components-datatable-features--with-custom-heading"
+ "id": "experimental-components-datatable-features--with-custom-heading"
},
{
- "id": "drafts-components-datatable-features--with-no-content"
+ "id": "experimental-components-datatable-features--with-no-content"
},
{
- "id": "drafts-components-datatable-features--with-loading"
+ "id": "experimental-components-datatable-features--with-loading"
},
{
- "id": "drafts-components-datatable-features--with-pagination"
+ "id": "experimental-components-datatable-features--with-pagination"
}
],
"importPath": "@primer/react/experimental",
diff --git a/packages/react/src/Dialog/Dialog.docs.json b/packages/react/src/Dialog/Dialog.docs.json
index 195991edd363..fe93cc281b1a 100644
--- a/packages/react/src/Dialog/Dialog.docs.json
+++ b/packages/react/src/Dialog/Dialog.docs.json
@@ -6,34 +6,34 @@
"a11yReviewed": false,
"stories": [
{
- "id": "drafts-components-dialog--default"
+ "id": "components-dialog--default"
},
{
- "id": "drafts-components-dialog-features--with-custom-renderers"
+ "id": "components-dialog-features--with-custom-renderers"
},
{
- "id": "drafts-components-dialog-features--stress-test"
+ "id": "components-dialog-features--stress-test"
},
{
- "id": "drafts-components-dialog-features--repro-multistep-dialog-with-conditional-footer"
+ "id": "components-dialog-features--repro-multistep-dialog-with-conditional-footer"
},
{
- "id": "drafts-components-dialog-features--bottom-sheet-narrow"
+ "id": "components-dialog-features--bottom-sheet-narrow"
},
{
- "id": "drafts-components-dialog-features--full-screen-narrow"
+ "id": "components-dialog-features--full-screen-narrow"
},
{
- "id": "drafts-components-dialog-features--side-sheet"
+ "id": "components-dialog-features--side-sheet"
},
{
- "id": "drafts-components-dialog-features--return-focus-ref"
+ "id": "components-dialog-features--return-focus-ref"
},
{
- "id": "drafts-components-dialog-features--new-issues"
+ "id": "components-dialog-features--new-issues"
},
{
- "id": "drafts-components-dialog-features--retains-focus-trap-with-dynamic-content"
+ "id": "components-dialog-features--retains-focus-trap-with-dynamic-content"
}
],
"importPath": "@primer/react/experimental",
diff --git a/packages/react/src/FormControl/FormControl.tsx b/packages/react/src/FormControl/FormControl.tsx
index a629806a353e..69d4b9bf8717 100644
--- a/packages/react/src/FormControl/FormControl.tsx
+++ b/packages/react/src/FormControl/FormControl.tsx
@@ -14,9 +14,9 @@ import {get} from '../constants'
import {useSlots} from '../hooks/useSlots'
import type {SxProp} from '../sx'
import {useId} from '../hooks/useId'
-import FormControlCaption from './_FormControlCaption'
-import FormControlLabel from './_FormControlLabel'
-import FormControlLeadingVisual from './_FormControlLeadingVisual'
+import {FormControlCaption} from './FormControlCaption'
+import FormControlLabel from './FormControlLabel'
+import FormControlLeadingVisual from './FormControlLeadingVisual'
import FormControlValidation from './_FormControlValidation'
import {FormControlContextProvider} from './_FormControlContext'
import {warning} from '../utils/warning'
diff --git a/packages/react/src/FormControl/FormControlCaption.tsx b/packages/react/src/FormControl/FormControlCaption.tsx
new file mode 100644
index 000000000000..dc05e1a3bad1
--- /dev/null
+++ b/packages/react/src/FormControl/FormControlCaption.tsx
@@ -0,0 +1,36 @@
+import React from 'react'
+import type {SxProp} from '../sx'
+import {useFormControlContext} from './_FormControlContext'
+import Text from '../Text'
+import styled from 'styled-components'
+import {get} from '../constants'
+import sx from '../sx'
+
+const StyledCaption = styled(Text)`
+ color: var(--fgColor-muted);
+ display: block;
+ font-size: ${get('fontSizes.0')};
+
+ &:where([data-control-disabled]) {
+ color: var(--control-fgColor-disabled);
+ }
+
+ ${sx}
+`
+
+type FormControlCaptionProps = React.PropsWithChildren<
+ {
+ id?: string
+ } & SxProp
+>
+
+function FormControlCaption({id, children, sx}: FormControlCaptionProps) {
+ const {captionId, disabled} = useFormControlContext()
+ return (
+
+ {children}
+
+ )
+}
+
+export {FormControlCaption}
diff --git a/packages/react/src/FormControl/_FormControlLabel.tsx b/packages/react/src/FormControl/FormControlLabel.tsx
similarity index 95%
rename from packages/react/src/FormControl/_FormControlLabel.tsx
rename to packages/react/src/FormControl/FormControlLabel.tsx
index 4d62b19e1149..485894c18d48 100644
--- a/packages/react/src/FormControl/_FormControlLabel.tsx
+++ b/packages/react/src/FormControl/FormControlLabel.tsx
@@ -1,7 +1,7 @@
import React from 'react'
-import InputLabel from '../internal/components/InputLabel'
import type {SxProp} from '../sx'
import {useFormControlContext} from './_FormControlContext'
+import {InputLabel} from '../internal/components/InputLabel'
export type Props = {
/**
@@ -49,6 +49,7 @@ const FormControlLabel: React.FC<
sx,
...props,
}
+
return {children}
}
diff --git a/packages/react/src/FormControl/FormControlLeadingVisual.tsx b/packages/react/src/FormControl/FormControlLeadingVisual.tsx
new file mode 100644
index 000000000000..27c18d69acac
--- /dev/null
+++ b/packages/react/src/FormControl/FormControlLeadingVisual.tsx
@@ -0,0 +1,44 @@
+import React from 'react'
+import {get} from '../constants'
+import type {SxProp} from '../sx'
+import {useFormControlContext} from './_FormControlContext'
+import styled from 'styled-components'
+import sx from '../sx'
+
+const FormControlLeadingVisual: React.FC> = ({children, sx}) => {
+ const {disabled, captionId} = useFormControlContext()
+ return (
+
+ {children}
+
+ )
+}
+
+const StyledLeadingVisual = styled.div`
+ --leadingVisual-size: ${get('fontSizes.2')};
+
+ color: var(--fgColor-default);
+ margin-inline-start: ${get('space.2')};
+
+ &:where([data-control-disabled]) {
+ color: var(--fgColor-muted);
+ }
+
+ & > * {
+ min-width: var(--leadingVisual-size);
+ min-height: var(--leadingVisual-size);
+ fill: currentColor;
+ }
+
+ &:where([data-has-caption]) {
+ --leadingVisual-size: ${get('fontSizes.4')};
+ }
+
+ ${sx}
+`
+
+export default FormControlLeadingVisual
diff --git a/packages/react/src/FormControl/_FormControlCaption.tsx b/packages/react/src/FormControl/_FormControlCaption.tsx
deleted file mode 100644
index 4a3be2bdedbc..000000000000
--- a/packages/react/src/FormControl/_FormControlCaption.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from 'react'
-import InputCaption from '../internal/components/InputCaption'
-import type {SxProp} from '../sx'
-import {useFormControlContext} from './_FormControlContext'
-
-const FormControlCaption: React.FC> = ({children, sx, id}) => {
- const {captionId, disabled} = useFormControlContext()
- return (
-
- {children}
-
- )
-}
-
-export default FormControlCaption
diff --git a/packages/react/src/FormControl/_FormControlLeadingVisual.tsx b/packages/react/src/FormControl/_FormControlLeadingVisual.tsx
deleted file mode 100644
index 80551681704a..000000000000
--- a/packages/react/src/FormControl/_FormControlLeadingVisual.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import React from 'react'
-import Box from '../Box'
-import {get} from '../constants'
-import type {SxProp} from '../sx'
-import {useFormControlContext} from './_FormControlContext'
-
-const FormControlLeadingVisual: React.FC> = ({children, sx}) => {
- const {disabled, captionId} = useFormControlContext()
- return (
- *': {
- minWidth: captionId ? get('fontSizes.4') : get('fontSizes.2'),
- minHeight: captionId ? get('fontSizes.4') : get('fontSizes.2'),
- fill: 'currentColor',
- },
- ...sx,
- }}
- ml={2}
- >
- {children}
-
- )
-}
-
-export default FormControlLeadingVisual
diff --git a/packages/react/src/Overlay/Overlay.docs.json b/packages/react/src/Overlay/Overlay.docs.json
index 2ad110618160..6091b66b5c7a 100644
--- a/packages/react/src/Overlay/Overlay.docs.json
+++ b/packages/react/src/Overlay/Overlay.docs.json
@@ -4,6 +4,7 @@
"status": "alpha",
"a11yReviewed": false,
"stories": [
+ {"id": "private-components-overlay--default"},
{"id": "private-components-overlay-features--dialog-overlay"},
{"id": "private-components-overlay-features--positioned-overlays"}
],
diff --git a/packages/react/src/PageHeader/PageHeader.docs.json b/packages/react/src/PageHeader/PageHeader.docs.json
index 97a43da92b06..5a599706f2b8 100644
--- a/packages/react/src/PageHeader/PageHeader.docs.json
+++ b/packages/react/src/PageHeader/PageHeader.docs.json
@@ -5,43 +5,43 @@
"a11yReviewed": true,
"stories": [
{
- "id": "drafts-components-pageheader--default"
+ "id": "components-pageheader--default"
},
{
- "id": "drafts-components-pageheader-features--has-title-only"
+ "id": "components-pageheader-features--has-title-only"
},
{
- "id": "drafts-components-pageheader-features--has-large-title"
+ "id": "components-pageheader-features--has-large-title"
},
{
- "id": "drafts-components-pageheader-features--with-leading-and-trailing-visuals"
+ "id": "components-pageheader-features--with-leading-and-trailing-visuals"
},
{
- "id": "drafts-components-pageheader-features--with-leading-visual-hidden-on-regular-viewport"
+ "id": "components-pageheader-features--with-leading-visual-hidden-on-regular-viewport"
},
{
- "id": "drafts-components-pageheader-features--with-actions"
+ "id": "components-pageheader-features--with-actions"
},
{
- "id": "drafts-components-pageheader-features--with-description-slot"
+ "id": "components-pageheader-features--with-description-slot"
},
{
- "id": "drafts-components-pageheader-features--with-navigation-slot"
+ "id": "components-pageheader-features--with-navigation-slot"
},
{
- "id": "drafts-components-pageheader-features--with-custom-navigation"
+ "id": "components-pageheader-features--with-custom-navigation"
},
{
- "id": "drafts-components-pageheader-features--with-leading-and-trailing-actions"
+ "id": "components-pageheader-features--with-leading-and-trailing-actions"
},
{
- "id": "drafts-components-pageheader-features--with-parent-link-and-actions-of-context-area"
+ "id": "components-pageheader-features--with-parent-link-and-actions-of-context-area"
},
{
- "id": "drafts-components-pageheader-features--with-context-bar-and-actions-of-context-area"
+ "id": "components-pageheader-features--with-context-bar-and-actions-of-context-area"
},
{
- "id": "drafts-components-pageheader-features--with-actions-that-have-responsive-content"
+ "id": "components-pageheader-features--with-actions-that-have-responsive-content"
}
],
"importPath": "@primer/react",
diff --git a/packages/react/src/TabNav/TabNav.docs.json b/packages/react/src/TabNav/TabNav.docs.json
index c08c3beb19fb..640e328cca27 100644
--- a/packages/react/src/TabNav/TabNav.docs.json
+++ b/packages/react/src/TabNav/TabNav.docs.json
@@ -5,10 +5,10 @@
"a11yReviewed": false,
"stories": [
{
- "id": "components-tabnav--default"
+ "id": "deprecated-components-tabnav--default"
},
{
- "id": "components-tabnav-features--selected"
+ "id": "deprecated-components-tabnav-features--selected"
}
],
"importPath": "@primer/react/deprecated",
diff --git a/packages/react/src/Token/AvatarToken.module.css b/packages/react/src/Token/AvatarToken.module.css
new file mode 100644
index 000000000000..02850e1d52eb
--- /dev/null
+++ b/packages/react/src/Token/AvatarToken.module.css
@@ -0,0 +1,36 @@
+:root {
+ --spacing: calc(var(--base-size-4) * 2);
+}
+
+.AvatarContainer {
+ display: block;
+}
+
+.Avatar {
+ width: 100%;
+ height: 100%;
+}
+
+.Token {
+ padding-left: var(--base-size-4) !important;
+}
+
+.AvatarContainer:where([data-size='small']) {
+ width: calc(16px - var(--spacing));
+ height: calc(16px - var(--spacing));
+}
+
+.AvatarContainer:where([data-size='medium']) {
+ width: calc(20px - var(--spacing));
+ height: calc(20px - var(--spacing));
+}
+
+.AvatarContainer:where([data-size='large']) {
+ width: calc(24px - var(--spacing));
+ height: calc(24px - var(--spacing));
+}
+
+.AvatarContainer:where([data-size='xlarge']) {
+ width: calc(32px - var(--spacing));
+ height: calc(32px - var(--spacing));
+}
diff --git a/packages/react/src/Token/AvatarToken.tsx b/packages/react/src/Token/AvatarToken.tsx
index b03a1059356d..c6b70005639d 100644
--- a/packages/react/src/Token/AvatarToken.tsx
+++ b/packages/react/src/Token/AvatarToken.tsx
@@ -6,23 +6,51 @@ import {defaultTokenSize, tokenSizes} from './TokenBase'
import Token from './Token'
import Avatar from '../Avatar'
import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic'
+import {toggleStyledComponent} from '../internal/utils/toggleStyledComponent'
+import {useFeatureFlag} from '../FeatureFlags'
+import classes from './AvatarToken.module.css'
+import {clsx} from 'clsx'
// TODO: update props to only accept 'large' and 'xlarge' on the next breaking change
export interface AvatarTokenProps extends TokenBaseProps {
avatarSrc: string
}
-const AvatarContainer = styled.span<{avatarSize: TokenSizeKeys}>`
- // 'space.1' is used because to match space from the left of the token to the left of the avatar
- // '* 2' is done to account for the top and bottom
- --spacing: calc(${get('space.1')} * 2);
+const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_team'
- display: block;
- height: ${props => `calc(${tokenSizes[props.avatarSize]} - var(--spacing))`};
- width: ${props => `calc(${tokenSizes[props.avatarSize]} - var(--spacing))`};
-`
+const AvatarContainer = toggleStyledComponent(
+ CSS_MODULES_FEATURE_FLAG,
+ 'span',
+ styled.span<{avatarSize: TokenSizeKeys}>`
+ // 'space.1' is used because to match space from the left of the token to the left of the avatar
+ // '* 2' is done to account for the top and bottom
+ --spacing: calc(${get('space.1')} * 2);
+
+ display: block;
+ height: ${props => `calc(${tokenSizes[props.avatarSize]} - var(--spacing))`};
+ width: ${props => `calc(${tokenSizes[props.avatarSize]} - var(--spacing))`};
+ `,
+)
+
+const AvatarToken = forwardRef(({avatarSrc, id, size = defaultTokenSize, className, ...rest}, forwardedRef) => {
+ const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG)
+ if (enabled) {
+ return (
+ (
+
+
+
+ )}
+ size={size}
+ id={id?.toString()}
+ className={clsx(classes.Token, className)}
+ {...rest}
+ ref={forwardedRef}
+ />
+ )
+ }
-const AvatarToken = forwardRef(({avatarSrc, id, size = defaultTokenSize, ...rest}, forwardedRef) => {
return (
(
diff --git a/packages/react/src/Token/IssueLabelToken.module.css b/packages/react/src/Token/IssueLabelToken.module.css
new file mode 100644
index 000000000000..5543c1074805
--- /dev/null
+++ b/packages/react/src/Token/IssueLabelToken.module.css
@@ -0,0 +1,8 @@
+.IssueLabel:where([data-has-remove-button='true']) {
+ padding-right: 0;
+}
+
+.RemoveButton:where([data-has-multiple-action-targets='true']) {
+ position: relative;
+ z-index: 1;
+}
diff --git a/packages/react/src/Token/IssueLabelToken.tsx b/packages/react/src/Token/IssueLabelToken.tsx
index 54b0b89ba53d..a8b1f409d673 100644
--- a/packages/react/src/Token/IssueLabelToken.tsx
+++ b/packages/react/src/Token/IssueLabelToken.tsx
@@ -8,6 +8,9 @@ import {parseToHsla, parseToRgba} from 'color2k'
import {useTheme} from '../ThemeProvider'
import TokenTextContainer from './_TokenTextContainer'
import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic'
+import classes from './IssueLabelToken.module.css'
+import {useFeatureFlag} from '../FeatureFlags'
+import {clsx} from 'clsx'
export interface IssueLabelTokenProps extends TokenBaseProps {
/**
@@ -16,6 +19,7 @@ export interface IssueLabelTokenProps extends TokenBaseProps {
fillColor?: string
}
+const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_team'
const tokenBorderWidthPx = 1
const lightModeStyles = {
@@ -43,6 +47,8 @@ const darkModeStyles = {
}
const IssueLabelToken = forwardRef((props, forwardedRef) => {
+ const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG)
+
const {
as,
fillColor = '#999',
@@ -54,6 +60,7 @@ const IssueLabelToken = forwardRef((props, forwardedRef) => {
hideRemoveButton,
href,
onClick,
+ className,
...rest
} = props
const interactiveTokenProps = {
@@ -61,6 +68,7 @@ const IssueLabelToken = forwardRef((props, forwardedRef) => {
href,
onClick,
}
+
const {resolvedColorScheme} = useTheme()
const hasMultipleActionTargets = isTokenInteractive(props) && Boolean(onRemove) && !hideRemoveButton
const onRemoveClick: MouseEventHandler = e => {
@@ -133,6 +141,37 @@ const IssueLabelToken = forwardRef((props, forwardedRef) => {
}
}, [fillColor, resolvedColorScheme, hideRemoveButton, onRemove, isSelected, props])
+ if (enabled) {
+ return (
+
+ {text}
+ {!hideRemoveButton && onRemove ? (
+
+ ) : null}
+
+ )
+ }
+
return (
>> = ({children, size}) => (
@@ -35,6 +40,8 @@ const LeadingVisualContainer: React.FC {
+ const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG)
+
const {
as,
onRemove,
@@ -46,6 +53,8 @@ const Token = forwardRef((props, forwardedRef) => {
href,
onClick,
sx: sxProp = defaultSxProp,
+ className,
+ style,
...rest
} = props
const hasMultipleActionTargets = isTokenInteractive(props) && Boolean(onRemove) && !hideRemoveButton
@@ -58,7 +67,8 @@ const Token = forwardRef((props, forwardedRef) => {
href,
onClick,
}
- const sx = merge(
+
+ const mergedSx = merge(
{
backgroundColor: 'neutral.subtle',
borderColor: props.isSelected ? 'fg.default' : 'border.subtle',
@@ -80,16 +90,56 @@ const Token = forwardRef((props, forwardedRef) => {
sxProp,
)
+ if (enabled) {
+ return (
+
+ {LeadingVisual ? (
+
+
+
+ ) : null}
+
+ {text}
+ {onRemove && (press backspace or delete to remove)}
+
+
+ {!hideRemoveButton && onRemove ? (
+
+ ) : null}
+
+ )
+ }
+
return (
{LeadingVisual ? (
diff --git a/packages/react/src/Token/TokenBase.module.css b/packages/react/src/Token/TokenBase.module.css
new file mode 100644
index 000000000000..d8da36547705
--- /dev/null
+++ b/packages/react/src/Token/TokenBase.module.css
@@ -0,0 +1,60 @@
+.TokenBase {
+ position: relative;
+ display: inline-flex;
+ font-family: inherit;
+ font-weight: var(--base-text-weight-semibold);
+ text-decoration: none;
+ white-space: nowrap;
+ border-radius: var(--borderRadius-full);
+ align-items: center;
+}
+
+.TokenBase:where([data-cursor-is-interactive='true']) {
+ cursor: pointer;
+}
+
+.TokenBase:where([data-cursor-is-interactive='false']) {
+ cursor: auto;
+}
+
+.TokenBase:where([data-size='small']) {
+ width: auto;
+ height: 16px;
+ padding-right: var(--base-size-4);
+ padding-left: var(--base-size-4);
+ font-size: var(--text-body-size-small);
+ /* stylelint-disable-next-line primer/typography */
+ line-height: 16px;
+}
+
+.TokenBase:where([data-size='medium']) {
+ width: auto;
+ height: 20px;
+ padding-right: var(--base-size-8);
+ padding-left: var(--base-size-8);
+ font-size: var(--text-body-size-small);
+ /* stylelint-disable-next-line primer/typography */
+ line-height: 20px;
+}
+
+.TokenBase[data-size='large'] {
+ width: auto;
+ height: 24px;
+ padding-right: var(--base-size-8);
+ padding-left: var(--base-size-8);
+ font-size: var(--text-body-size-small);
+ /* stylelint-disable-next-line primer/typography */
+ line-height: 24px;
+}
+
+.TokenBase[data-size='xlarge'] {
+ width: auto;
+ height: 32px;
+ padding-top: 0;
+ padding-right: var(--base-size-16);
+ padding-bottom: 0;
+ padding-left: var(--base-size-16);
+ font-size: var(--text-body-size-medium);
+ /* stylelint-disable-next-line primer/typography */
+ line-height: 32px;
+}
diff --git a/packages/react/src/Token/TokenBase.tsx b/packages/react/src/Token/TokenBase.tsx
index 43b314367e8d..89b3b28219a4 100644
--- a/packages/react/src/Token/TokenBase.tsx
+++ b/packages/react/src/Token/TokenBase.tsx
@@ -2,10 +2,14 @@ import type {ComponentProps, KeyboardEvent} from 'react'
import React from 'react'
import styled from 'styled-components'
import {variant} from 'styled-system'
+import {clsx} from 'clsx'
import {get} from '../constants'
import type {SxProp} from '../sx'
import sx from '../sx'
import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic'
+import {useFeatureFlag} from '../FeatureFlags'
+import classes from './TokenBase.module.css'
+import {toggleStyledComponent} from '../internal/utils/toggleStyledComponent'
export type TokenSizeKeys = 'small' | 'medium' | 'large' | 'xlarge'
@@ -112,26 +116,54 @@ const variants = variant<
},
})
-const StyledTokenBase = styled.span<
- {
- size?: TokenSizeKeys
- } & SxProp
->`
- align-items: center;
- border-radius: 999px;
- cursor: ${props => (isTokenInteractive(props) ? 'pointer' : 'auto')};
- display: inline-flex;
- font-weight: ${get('fontWeights.bold')};
- font-family: inherit;
- text-decoration: none;
- position: relative;
- white-space: nowrap;
- ${variants}
- ${sx}
-`
+const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_team'
+
+const StyledTokenBase = toggleStyledComponent(
+ CSS_MODULES_FEATURE_FLAG,
+ 'span',
+ styled.span<
+ {
+ size?: TokenSizeKeys
+ } & SxProp
+ >`
+ align-items: center;
+ border-radius: 999px;
+ cursor: ${props => (isTokenInteractive(props) ? 'pointer' : 'auto')};
+ display: inline-flex;
+ font-weight: ${get('fontWeights.bold')};
+ font-family: inherit;
+ text-decoration: none;
+ position: relative;
+ white-space: nowrap;
+ ${variants}
+ ${sx}
+ `,
+)
const TokenBase = React.forwardRef(
- ({onRemove, onKeyDown, id, size = defaultTokenSize, ...rest}, forwardedRef) => {
+ ({onRemove, onKeyDown, id, className, size = defaultTokenSize, ...rest}, forwardedRef) => {
+ const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG)
+
+ if (enabled) {
+ return (
+ ) => {
+ onKeyDown && onKeyDown(event)
+
+ if ((event.key === 'Backspace' || event.key === 'Delete') && onRemove) {
+ onRemove()
+ }
+ }}
+ className={clsx(classes.TokenBase, className)}
+ data-cursor-is-interactive={isTokenInteractive(rest)}
+ data-size={size}
+ id={id?.toString()}
+ {...rest}
+ ref={forwardedRef}
+ />
+ )
+ }
+
return (
) => {
@@ -144,7 +176,6 @@ const TokenBase = React.forwardRef
)
diff --git a/packages/react/src/__tests__/BaseStyles.test.tsx b/packages/react/src/__tests__/BaseStyles.test.tsx
new file mode 100644
index 000000000000..e76089554631
--- /dev/null
+++ b/packages/react/src/__tests__/BaseStyles.test.tsx
@@ -0,0 +1,33 @@
+import {render} from '@testing-library/react'
+import MatchMediaMock from 'jest-matchmedia-mock'
+import 'jest-styled-components'
+import React from 'react'
+import {BaseStyles} from '..'
+
+let matchMedia: MatchMediaMock
+
+describe('BaseStyles', () => {
+ beforeAll(() => {
+ matchMedia = new MatchMediaMock()
+ })
+
+ afterEach(() => {
+ matchMedia.clear()
+ })
+
+ it('has default styles', () => {
+ const {container} = render()
+ expect(container).toMatchSnapshot()
+ })
+
+ it('respects styling props', () => {
+ const styles = {
+ color: '#f00',
+ fontFamily: 'Arial',
+ lineHeight: '3.5',
+ }
+
+ const {container} = render()
+ expect(container.children[0]).toHaveStyle({color: '#f00', 'font-family': 'Arial', 'line-height': '3.5'})
+ })
+})
diff --git a/packages/react/src/__tests__/__snapshots__/BaseStyles.test.tsx.snap b/packages/react/src/__tests__/__snapshots__/BaseStyles.test.tsx.snap
new file mode 100644
index 000000000000..18c719e6bffe
--- /dev/null
+++ b/packages/react/src/__tests__/__snapshots__/BaseStyles.test.tsx.snap
@@ -0,0 +1,19 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`BaseStyles has default styles 1`] = `
+.c0 {
+ font-family: normal;
+ line-height: default;
+ color: fg.default;
+}
+
+
+`;
diff --git a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx
index 6cffe9375e39..b407db2cf19b 100644
--- a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx
+++ b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx
@@ -20,7 +20,7 @@ import {useSlots} from '../../hooks/useSlots'
import {useProvidedRefOrCreate, useId, useAnchoredPosition} from '../../hooks'
import type {OverlayProps} from '../../Overlay/Overlay'
import {StyledOverlay, heightMap} from '../../Overlay/Overlay'
-import InputLabel from '../../internal/components/InputLabel'
+import {InputLabel} from '../../internal/components/InputLabel'
import {invariant} from '../../utils/invariant'
import {AriaStatus} from '../../live-region'
import {useResponsiveValue} from '../../hooks/useResponsiveValue'
diff --git a/packages/react/src/experimental/Skeleton/SkeletonAvatar.docs.json b/packages/react/src/experimental/Skeleton/SkeletonAvatar.docs.json
index e96a36bb9367..769e560f30ad 100644
--- a/packages/react/src/experimental/Skeleton/SkeletonAvatar.docs.json
+++ b/packages/react/src/experimental/Skeleton/SkeletonAvatar.docs.json
@@ -5,22 +5,22 @@
"a11yReviewed": false,
"stories": [
{
- "id": "drafts-components-skeletonavatar--default"
+ "id": "experimental-components-skeleton-skeletonavatar--default"
},
{
- "id": "drafts-components-skeletonavatar-features--square"
+ "id": "experimental-components-skeleton-skeletonavatar-features--square"
},
{
- "id": "drafts-components-skeletonavatar-features--size"
+ "id": "experimental-components-skeleton-skeletonavatar-features--size"
},
{
- "id": "drafts-components-skeletonavatar-features--size-responsive"
+ "id": "experimental-components-skeleton-skeletonavatar-features--size-responsive"
},
{
- "id": "drafts-components-skeletonavatar-features--in-a-stack"
+ "id": "experimental-components-skeleton-skeletonavatar-features--in-a-stack"
},
{
- "id": "drafts-components-skeletonavatar-features--in-an-avatar-pair"
+ "id": "experimental-components-skeleton-skeletonavatar-features--in-an-avatar-pair"
}
],
"importPath": "@primer/react/experimental",
diff --git a/packages/react/src/experimental/Skeleton/SkeletonBox.docs.json b/packages/react/src/experimental/Skeleton/SkeletonBox.docs.json
index 297d00582b6d..292c07072b58 100644
--- a/packages/react/src/experimental/Skeleton/SkeletonBox.docs.json
+++ b/packages/react/src/experimental/Skeleton/SkeletonBox.docs.json
@@ -5,13 +5,13 @@
"a11yReviewed": false,
"stories": [
{
- "id": "drafts-components-skeletonbox--default"
+ "id": "experimental-components-skeleton-skeletonbox--default"
},
{
- "id": "drafts-components-skeletonbox-features--custom-height"
+ "id": "experimental-components-skeleton-skeletonbox-features--custom-height"
},
{
- "id": "drafts-components-skeletonbox-features--custom-width"
+ "id": "experimental-components-skeleton-skeletonbox-features--custom-width"
}
],
"importPath": "@primer/react/experimental",
diff --git a/packages/react/src/experimental/Skeleton/SkeletonText.docs.json b/packages/react/src/experimental/Skeleton/SkeletonText.docs.json
index 1031e6e4a83c..ed691e649b07 100644
--- a/packages/react/src/experimental/Skeleton/SkeletonText.docs.json
+++ b/packages/react/src/experimental/Skeleton/SkeletonText.docs.json
@@ -5,37 +5,37 @@
"a11yReviewed": false,
"stories": [
{
- "id": "drafts-components-skeletontext--default"
+ "id": "experimental-components-skeleton-skeletontext--default"
},
{
- "id": "drafts-components-skeletontext-features--with-max-width"
+ "id": "experimental-components-skeleton-skeletontext-features--with-max-width"
},
{
- "id": "drafts-components-skeletontext-features--with-multiple-lines"
+ "id": "experimental-components-skeleton-skeletontext-features--with-multiple-lines"
},
{
- "id": "drafts-components-skeletontext-features--display"
+ "id": "experimental-components-skeleton-skeletontext-features--display"
},
{
- "id": "drafts-components-skeletontext-features--subtitle"
+ "id": "experimental-components-skeleton-skeletontext-features--subtitle"
},
{
- "id": "drafts-components-skeletontext-features--title-large"
+ "id": "experimental-components-skeleton-skeletontext-features--title-large"
},
{
- "id": "drafts-components-skeletontext-features--title-medium"
+ "id": "experimental-components-skeleton-skeletontext-features--title-medium"
},
{
- "id": "drafts-components-skeletontext-features--title-small"
+ "id": "experimental-components-skeleton-skeletontext-features--title-small"
},
{
- "id": "drafts-components-skeletontext-features--body-large"
+ "id": "experimental-components-skeleton-skeletontext-features--body-large"
},
{
- "id": "drafts-components-skeletontext-features--body-medium"
+ "id": "experimental-components-skeleton-skeletontext-features--body-medium"
},
{
- "id": "drafts-components-skeletontext-features--body-small"
+ "id": "experimental-components-skeleton-skeletontext-features--body-small"
}
],
"importPath": "@primer/react/experimental",
diff --git a/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.dev.stories.tsx b/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.dev.stories.tsx
new file mode 100644
index 000000000000..6ffd6f3a423b
--- /dev/null
+++ b/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.dev.stories.tsx
@@ -0,0 +1,20 @@
+import React from 'react'
+import type {Meta} from '@storybook/react'
+import UnderlinePanels from './UnderlinePanels'
+import type {ComponentProps} from '../../utils/types'
+
+export default {
+ title: 'Experimental/Components/UnderlinePanels/Dev',
+ component: UnderlinePanels,
+} as Meta>
+
+export const Default = () => (
+
+ Tab 1
+ Tab 2
+ Tab 3
+ Panel 1
+ Panel 2
+ Panel 3
+
+)
diff --git a/packages/react/src/internal/components/InputCaption.tsx b/packages/react/src/internal/components/InputCaption.tsx
deleted file mode 100644
index 03fbb184be9a..000000000000
--- a/packages/react/src/internal/components/InputCaption.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from 'react'
-import Text from '../../Text'
-import type {SxProp} from '../../sx'
-
-type Props = {
- /**
- * The unique identifier used to associate the caption with an input
- */
- id: string
- /**
- * Whether the input associated with this caption is disabled
- */
- disabled?: boolean
-} & SxProp
-
-const InputCaption: React.FC> = ({children, disabled, id, sx}) => (
-
- {children}
-
-)
-
-export default InputCaption
diff --git a/packages/react/src/internal/components/InputLabel.tsx b/packages/react/src/internal/components/InputLabel.tsx
index b4d2fa43aed3..9126d1920863 100644
--- a/packages/react/src/internal/components/InputLabel.tsx
+++ b/packages/react/src/internal/components/InputLabel.tsx
@@ -1,7 +1,7 @@
import React from 'react'
-import Box from '../../Box'
-import type {SxProp} from '../../sx'
-import VisuallyHidden from '../../_VisuallyHidden'
+import styled from 'styled-components'
+import {get} from '../../constants'
+import sx, {type SxProp} from '../../sx'
type BaseProps = SxProp & {
disabled?: boolean
@@ -23,9 +23,9 @@ export type LegendOrSpanProps = BaseProps & {
htmlFor?: undefined
}
-type Props = LabelProps | LegendOrSpanProps
+type Props = React.PropsWithChildren
-const InputLabel: React.FC> = ({
+function InputLabel({
children,
disabled,
htmlFor,
@@ -38,37 +38,62 @@ const InputLabel: React.FC> = ({
as = 'label',
className,
...props
-}) => {
+}: Props) {
return (
-
{required || requiredText ? (
-
- {children}
+
+ {children}
{requiredText ?? '*'}
-
+
) : (
children
)}
-
+
)
}
-export default InputLabel
+const StyledRequiredText = styled.span`
+ display: flex;
+ column-gap: ${get('space.1')};
+`
+
+const StyledLabel = styled.label`
+ align-self: flex-start;
+ display: block;
+ color: var(--fgColor-default);
+ cursor: pointer;
+ font-weight: 600;
+ font-size: ${get('fontSizes.1')};
+
+ &:where([data-control-disabled]) {
+ color: var(--fgColor-muted);
+ cursor: not-allowed;
+ }
+
+ &:where([data-visually-hidden]) {
+ border: 0;
+ clip: rect(0 0 0 0);
+ clip-path: inset(50%);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ white-space: nowrap;
+ width: 1px;
+ }
+
+ ${sx}
+`
+
+export {InputLabel}
diff --git a/packages/react/src/internal/components/InputValidation.tsx b/packages/react/src/internal/components/InputValidation.tsx
index cfa2c8537b56..d23fe867cb5c 100644
--- a/packages/react/src/internal/components/InputValidation.tsx
+++ b/packages/react/src/internal/components/InputValidation.tsx
@@ -1,10 +1,12 @@
import type {IconProps} from '@primer/octicons-react'
import {AlertFillIcon, CheckCircleFillIcon} from '@primer/octicons-react'
import React from 'react'
-import Box from '../../Box'
import Text from '../../Text'
import type {SxProp} from '../../sx'
import type {FormValidationStatus} from '../../utils/types/FormValidationStatus'
+import styled from 'styled-components'
+import {get} from '../../constants'
+import sx from '../../sx'
type Props = {
id: string
@@ -19,14 +21,8 @@ const validationIconMap: Record<
error: AlertFillIcon,
}
-const validationColorMap: Record, string> = {
- success: 'success.fg',
- error: 'danger.fg',
-}
-
const InputValidation: React.FC> = ({children, id, validationStatus, sx}) => {
const IconComponent = validationStatus ? validationIconMap[validationStatus] : undefined
- const fgColor = validationStatus ? validationColorMap[validationStatus] : undefined
// TODO: use `text-caption-lineHeight` token as a custom property when it's available
// then, we can move this all to CSS and use `calc` to get our height values
@@ -35,30 +31,57 @@ const InputValidation: React.FC> = ({children, id
const iconBoxMinHeight = iconSize * captionLineHeight
return (
-
- {IconComponent && (
-
+
+ {IconComponent ? (
+
-
- )}
-
+
+ ) : null}
+
{children}
-
-
+
+
)
}
+const StyledInputValidation = styled(Text)`
+ color: var(--inputValidation-fgColor);
+ display: flex;
+ font-size: ${get('fontSizes.0')};
+ font-weight: 600;
+
+ & :where(a) {
+ color: currentColor;
+ text-dectoration: underline;
+ }
+
+ &:where([data-validation-status='success']) {
+ --inputValidation-fgColor: ${get('colors.success.fg')};
+ }
+
+ &:where([data-validation-status='error']) {
+ --inputValidation-fgColor: ${get('colors.danger.fg')};
+ }
+
+ ${sx}
+`
+
+const StyledValidationIcon = styled.span`
+ align-items: center;
+ display: flex;
+ margin-inline-end: ${get('space.1')};
+ min-height: var(--inputValidation-iconSize);
+`
+
+const StyledValidationText = styled.span`
+ line-height: var(--inputValidation-lineHeight);
+`
+
export default InputValidation
diff --git a/packages/rollup-plugin-import-css/package.json b/packages/rollup-plugin-import-css/package.json
index 7e8fc7ec7930..ca98879e86b3 100644
--- a/packages/rollup-plugin-import-css/package.json
+++ b/packages/rollup-plugin-import-css/package.json
@@ -25,7 +25,8 @@
"postcss-modules": "^6.0.0",
"rimraf": "^5.0.7",
"rollup-plugin-esbuild": "^6.1.1",
- "rollup-plugin-typescript2": "^0.36.0"
+ "rollup-plugin-typescript2": "^0.36.0",
+ "typescript": "^5.7.2"
},
"sideEffects": false
}