Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
a0a0fd6
beta: vanilaa 19'
dreamwasp Mar 16, 2026
39d5707
format
dreamwasp Mar 16, 2026
3f68790
.spec
dreamwasp Mar 17, 2026
2a98de1
Merge branch 'main' into cass-gm-plain-19
dreamwasp Mar 17, 2026
2fa55ca
test
dreamwasp Mar 17, 2026
e29e664
Merge branch 'cass-gm-plain-19' of github.com:Codecademy/gamut into c…
dreamwasp Mar 17, 2026
b79068d
Merge branch 'main' into cass-gm-plain-19
dreamwasp Mar 17, 2026
91f5f46
ref check
dreamwasp Mar 18, 2026
fc66bcc
type widening + formatting
dreamwasp Mar 18, 2026
3bb18db
revert type widening
dreamwasp Mar 18, 2026
fe532d0
18/19
dreamwasp Mar 19, 2026
16e2769
terst build
dreamwasp Mar 19, 2026
bd2e499
update react-hook-form
dreamwasp Mar 19, 2026
077f07b
put connected form back
dreamwasp Mar 19, 2026
469095e
try re-creating ref type in cast;
dreamwasp Mar 19, 2026
2df70b1
ts upgrade test
dreamwasp Mar 24, 2026
3adb8cb
test typescript
dreamwasp Mar 25, 2026
5d52f0d
lint + format
dreamwasp Mar 25, 2026
aa6bb4b
update to main
dreamwasp Apr 2, 2026
7117ecc
test in ci
dreamwasp Apr 2, 2026
d78affa
start fixing test failures
dreamwasp Apr 3, 2026
ad2809d
add release plan
dreamwasp Apr 3, 2026
5134194
Merge origin/cass-gm-plain-19 into cass-gm-plain-1819
dreamwasp Apr 3, 2026
e6fd469
chore: align babel-plugin-macros and component-test-setup for syncpack
dreamwasp Apr 3, 2026
d8b11d8
dedupe yrn
dreamwasp Apr 3, 2026
b6d3eeb
lint fix
dreamwasp Apr 3, 2026
e103d5d
release plan update
dreamwasp Apr 3, 2026
8cfdf84
Merge branch 'main' into cass-gmt-1473-beta
dreamwasp Apr 15, 2026
71b5d00
update plan
dreamwasp Apr 15, 2026
a0a3ad0
merge dev
dreamwasp Apr 29, 2026
91d194b
update
dreamwasp May 1, 2026
60ded6f
fix failing tests from merge
dreamwasp May 1, 2026
1e9898d
fix popover refs + Dialog/Modal
dreamwasp May 1, 2026
2bdb59b
chore: add beta dist-tag publish workflow
dreamwasp May 4, 2026
c6fc630
change git-head rf
dreamwasp May 4, 2026
27bbf5b
test beta
dreamwasp May 4, 2026
c8563bf
feat(SelectDropdown):isCreatable
dreamwasp Jun 5, 2026
8d86bc8
tweaks
dreamwasp Jun 11, 2026
cabad9d
refactor prop table
dreamwasp Jun 12, 2026
2ab39ce
write SelectDropdown skill
dreamwasp Jun 12, 2026
cd2dc5a
Merge branch 'main' into cass-gmt-292
dreamwasp Jun 12, 2026
878a06f
tweak props + co-pilot
dreamwasp Jun 12, 2026
d99285b
Merge branch 'main' into cass-gmt-292
dreamwasp Jun 16, 2026
f2e6db1
as
dreamwasp Jun 16, 2026
7064061
tweak
dreamwasp Jun 16, 2026
a4b27b8
SelectDropdown skill
dreamwasp Jun 16, 2026
6942cc9
test beta w/ select
dreamwasp Jun 16, 2026
8ae76f3
still just a test
dreamwasp Jun 16, 2026
5261dd9
need an alpha
dreamwasp Jun 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ module.exports = {

ignorePatterns: ['packages/code-connect/**/*'],

settings: {
'import/parsers': {
[require.resolve('@typescript-eslint/parser')]: [
'.ts',
'.cts',
'.mts',
'.tsx',
'.js',
'.jsx',
'.mjs',
'.cjs',
],
},
},

rules: {
'gamut/prefer-themed': 'error',
'gamut/no-css-standalone': 'error',
Expand Down Expand Up @@ -38,6 +53,13 @@ module.exports = {
// being applied to subsequent plugin imports/extensions. Wild.
files: ['*.tsx', '*.ts'],
rules: {
'@typescript-eslint/no-empty-object-type': [
'error',
{
allowInterfaces: 'with-single-extends',
allowObjectTypes: 'always',
},
],
'no-void': ['error', { allowAsStatement: true }],
// These rules could be useful, but we haven't gotten around to enabling them here
// See WEB-2 for general tracking.
Expand Down
127 changes: 127 additions & 0 deletions .github/actions/prerelease-publish/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
name: PR prerelease npm publish
description: Checkout, setup, build publish targets, gamut-release, and sticky PR comment

inputs:
node-auth-token:
description: NPM token value (pass secrets.NODE_AUTH_TOKEN)
required: true
gh-token:
description: GitHub token for release tooling (pass secrets.ACTIONS_GITHUB_TOKEN)
required: true
ignore-commit-message:
description: Commit message prefix to skip (chore release commits)
required: true
manifest-path:
description: JSON manifest path written by gamut-release
required: true
comment-path:
description: Markdown file path for the PR comment body
required: true
comment-title:
description: Title line after the emoji (e.g. Published Alpha Packages)
required: true
sticky-header:
description: Sticky comment header key
required: true
publish-run:
description: Bash to set PREID and run gamut-release:pre-release
required: true

runs:
using: composite
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
filter: tree:0
ref: ${{ github.event.pull_request.head.ref }}

- name: Setup and Build
id: setup
uses: ./.github/actions/yarn

- name: Set git user
uses: ./.github/actions/set-git-user

- name: Set npm token
uses: ./.github/actions/set-npm-token
with:
token-secret: ${{ inputs.node-auth-token }}

- name: Ensure workflow is associated with a pull request
uses: ./.github/actions/validate-pr-context

- name: Skip build from automated commit
uses: ./.github/actions/skip-automated-commits
with:
ignore-commit-message: ${{ inputs.ignore-commit-message }}

- run: npx nx run-many --target=publish-build --parallel=3
shell: bash

- name: Publish prerelease packages
id: publish-prerelease
shell: bash
env:
GH_TOKEN: ${{ inputs.gh-token }}
NODE_AUTH_TOKEN: ${{ inputs.node-auth-token }}
run: |
${{ inputs.publish-run }}
- name: Build prerelease packages comment
id: build-comment
continue-on-error: true
uses: actions/github-script@v7
env:
MANIFEST_PATH: ${{ inputs.manifest-path }}
OUTPUT_PATH: ${{ inputs.comment-path }}
COMMENT_TITLE: ${{ inputs.comment-title }}
with:
script: |
const fs = require('fs');
const core = require('@actions/core');
const manifestPath = process.env.MANIFEST_PATH;
const outputPath = process.env.OUTPUT_PATH;
const commentTitle = process.env.COMMENT_TITLE;
if (!fs.existsSync(manifestPath)) {
fs.writeFileSync(outputPath, '');
core.setOutput('has_comment', 'false');
return;
}
const entries = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
if (!Array.isArray(entries) || entries.length === 0) {
fs.writeFileSync(outputPath, '');
core.setOutput('has_comment', 'false');
return;
}
const tableLines = [
'| Package | Version | npm | Diff |',
'| --- | --- | --- | --- |',
...entries.map((entry) => {
const pkgUrl = `https://www.npmjs.com/package/${entry.name}`;
const versionUrl = `${pkgUrl}/v/${entry.version}`;
const baseVersion = entry.previousVersion || null;
const diffUrl = baseVersion
? `https://npmdiff.dev/${encodeURIComponent(
entry.name
)}/${baseVersion}/${entry.version}/`
: null;
const npmLink = `[npm](${versionUrl})`;
const diffLink = diffUrl ? `[diff](${diffUrl})` : 'N/A';
return `| \`${entry.name}\` | \`${entry.version}\` | ${npmLink} | ${diffLink} |`;
}),
];
const comment = `📬 ${commentTitle}\n\n${tableLines.join('\n')}\n`;
fs.writeFileSync(outputPath, comment);
core.setOutput('has_comment', 'true');
- name: Comment with published packages
uses: ./.github/actions/sticky-comment
if: ${{ !cancelled() && steps.build-comment.outputs.has_comment == 'true' }}
with:
github-token: ${{ inputs.gh-token }}
header: ${{ inputs.sticky-header }}
message-path: ${{ inputs.comment-path }}
100 changes: 17 additions & 83 deletions .github/workflows/publish-alpha.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,94 +17,28 @@ permissions:
issues: write
actions: write

concurrency:
group: npm-prerelease-${{ github.event.pull_request.number }}
cancel-in-progress: false

jobs:
publish-alpha:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'beta') }}
runs-on: ubuntu-22.04
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.ref }}

- name: Setup and Build
id: setup
uses: ./.github/actions/yarn

- name: Set git user
uses: ./.github/actions/set-git-user

- name: Set npm token
uses: ./.github/actions/set-npm-token
with:
token-secret: ${{ secrets.NODE_AUTH_TOKEN }}

- name: Ensure workflow is associated with a pull request
uses: ./.github/actions/validate-pr-context

- name: Skip build from automated commit
uses: ./.github/actions/skip-automated-commits
- uses: ./.github/actions/prerelease-publish
with:
node-auth-token: ${{ secrets.NODE_AUTH_TOKEN }}
gh-token: ${{ secrets.ACTIONS_GITHUB_TOKEN }}
ignore-commit-message: ${{ env.IGNORE_COMMIT_MESSAGE }}

- run: npx nx run-many --target=publish-build --parallel=3

- name: Publish alpha packages
id: publish-alpha
run: |
SHORT_SHA=${GITHUB_SHA:0:6}
PREID="alpha.${SHORT_SHA}"
npx nx run gamut-release:alpha --preid="${PREID}" --manifest
env:
GH_TOKEN: ${{ secrets.ACTIONS_GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}

- name: List alpha packages versions
id: published
continue-on-error: true
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const manifestPath = 'alpha-publish-manifest.json';
const outputPath = 'alpha-publish-comment.md';
if (!fs.existsSync(manifestPath)) {
fs.writeFileSync(outputPath, '');
return;
}

const entries = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
if (!Array.isArray(entries) || entries.length === 0) {
fs.writeFileSync(outputPath, '');
return;
}

const tableLines = [
'| Package | Version | npm | Diff |',
'| --- | --- | --- | --- |',
...entries.map((entry) => {
const pkgUrl = `https://www.npmjs.com/package/${entry.name}`;
const versionUrl = `${pkgUrl}/v/${entry.version}`;
const baseVersion = entry.previousVersion || null;
const diffUrl = baseVersion
? `https://npmdiff.dev/${encodeURIComponent(
entry.name
)}/${baseVersion}/${entry.version}/`
: null;
const npmLink = `[npm](${versionUrl})`;
const diffLink = diffUrl ? `[diff](${diffUrl})` : 'N/A';

return `| \`${entry.name}\` | \`${entry.version}\` | ${npmLink} | ${diffLink} |`;
}),
];
const comment = `📬 Published Alpha Packages:\n\n${tableLines.join(
'\n'
)}\n`;
fs.writeFileSync(outputPath, comment);

- name: Comment with published alpha packages
uses: ./.github/actions/sticky-comment
if: ${{ !cancelled() && hashFiles('alpha-publish-comment.md') != '' }}
with:
github-token: ${{ secrets.ACTIONS_GITHUB_TOKEN }}
header: Alpha Packages
message-path: alpha-publish-comment.md
manifest-path: alpha-publish-manifest.json
comment-path: alpha-publish-comment.md
comment-title: Published Alpha Packages
sticky-header: Alpha Packages
publish-run: |
SHORT_SHA=${GITHUB_SHA:0:6}
PREID="alpha.${SHORT_SHA}"
npx nx run gamut-release:pre-release --preid="${PREID}" --manifest
43 changes: 43 additions & 0 deletions .github/workflows/publish-beta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Publish Beta

on:
pull_request:
types: [labeled]

env:
NODE_VERSION: '22.13.1'
NODE_OPTIONS: '--max_old_space_size=8196'
NX_CLOUD: false
IGNORE_COMMIT_MESSAGE: 'chore(release): publish'

permissions:
id-token: write
contents: read
pull-requests: write
issues: write
actions: write

concurrency:
group: npm-prerelease-${{ github.event.pull_request.number }}
cancel-in-progress: false

jobs:
publish-beta:
if: github.event.label.name == 'beta' && github.event.pull_request.head.ref == 'cass-gmt-1607-publish'
runs-on: ubuntu-22.04
timeout-minutes: 30
steps:
- uses: actions/checkout@v4

- uses: ./.github/actions/prerelease-publish
with:
node-auth-token: ${{ secrets.NODE_AUTH_TOKEN }}
gh-token: ${{ secrets.ACTIONS_GITHUB_TOKEN }}
ignore-commit-message: ${{ env.IGNORE_COMMIT_MESSAGE }}
manifest-path: beta-publish-manifest.json
comment-path: beta-publish-comment.md
comment-title: 'Published Beta Packages (install with `@beta`):'
sticky-header: Beta Packages
publish-run: |
PREID="beta.pr${{ github.event.pull_request.number }}.${{ github.run_id }}"
npx nx run gamut-release:pre-release --preid="${PREID}" --publish-tag=beta --manifest=beta-publish-manifest.json
12 changes: 12 additions & 0 deletions .nx/version-plans/version-plan-1775236316343.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
eslint-plugin-gamut: major
gamut-illustrations: major
gamut-patterns: major
gamut-styles: major
gamut-icons: major
gamut-tests: major
variance: major
gamut: major
---

React 18+19 compatibility: workspace on React 19; peers support React 18.3 and 19. Includes eslint-plugin-gamut and core Gamut packages (major bumps per plan).
5 changes: 5 additions & 0 deletions .nx/version-plans/version-plan-1781295720164.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
gamut: minor
---

feat(SelectDropdown): add isCreateable prop + remove SearchIcon
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,21 @@ Add new Button variant and fix spacing issues
- It will create git tags and GitHub releases
1. You can find the new version number on npmjs.com/package/<package-name>, or find it in that package's `package.json` on the `main` branch

### Publishing an alpha version of a module
### Publishing an pre-release version of a module

Every PR that changes files in a package publishes alpha releases that you can use to test your changes across applications.
You can consume prerelease packages from npm before your PR merges. Two flows are available; **alpha** and **beta** are mutually exclusive on a PR.

**Alpha (default):** On each push to the PR branch, CI publishes alpha releases (per-commit prerelease versions on npm). This does **not** run while the PR has the **`beta`** label.

**Beta:** Add the **`beta`** label to the PR (create the label in the repo if it does not exist). That triggers a one-time publish to npm under the **`beta`** dist-tag (install with e.g. `yarn add @codecademy/gamut@beta`). Pushing new commits does **not** republish beta automatically; remove the **`beta`** label and add it again after your changes to trigger another publish.

> NOTE: in case an alpha build is not published upon opening of the PR or Draft PR, re-run the `build-test` check and that will re-run the alpha build publishing flows

1. Create a PR or Draft PR.
- This will kickoff a Github Action workflow which will publish an alpha build. (This will appear in Github as the "Deploy")
1. After the alpha build is published, the `codecademydev` bot should comment on your PR with the names of the published alpha packages. <br/>
- Without the **`beta`** label, each push kicks off the workflow that publishes an alpha build. (This will appear in Github as the "Deploy")
1. After packages are published, the `codecademydev` bot should comment on your PR with the names of the published packages (separate comments for alpha vs beta). <br/>
<img width="290" height="auto" src="https://user-images.githubusercontent.com/4298857/114948632-3fa88a80-9e04-11eb-89ef-d016a1c9c572.png">
1. Install this version of the package in your application you wish to test your changes on.
1. Install that version in the application where you want to test your changes (alpha by exact version from the table, or beta via `@beta` when using the beta flow).

### Working with pre-published changes

Expand Down
3 changes: 2 additions & 1 deletion jest.config.base.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Config } from 'jest';
import path from 'node:path';

import type { Config } from 'jest';

const COVERAGE_PATH_IGNORE_PATTERNS = [
'<rootDir>/node_modules/',
'<rootDir>/dist/',
Expand Down
Loading
Loading