Skip to content

chore: Style api mixins - #5165

Merged
pan-kot merged 8 commits into
mainfrom
chore-style-api-mixins
Oct 21, 2026
Merged

pan-kot merged 8 commits into
mainfrom
chore-style-api-mixins

Conversation

@pan-kot

@pan-kot pan-kot commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Description

Implements styling tech design changes as per RsrNx38C0132, and follows API structure defined in P3d34KdbCd6o.

Key changes:

  • All existing internal styling v2 implementations are migrated to a combination of style tokens and properties (before it was all tokens)
  • Sass mixins are generated per every non-empty styling component/slot
  • Focus ring gutters are removed for now
  • Several styling props for checkbox, radio-button, toggle, dropdown are renamed
  • Test pages are updated to feature the use of new mixins

How has this been tested?

  • Styling API changes are captured with the existing snapshot tests
  • Visual regressions are manually verified using the existing test pages - these will be covered with automated tests before release
  • Generated mixins will be covered with a snapshot test before release
Review checklist

The following items are to be evaluated by the author(s) and the reviewer(s).

Correctness

  • Changes include appropriate documentation updates.
  • Changes are backward-compatible if not indicated, see CONTRIBUTING.md.
  • Changes do not include unsupported browser features, see CONTRIBUTING.md.
  • Changes were manually tested for accessibility, see accessibility guidelines.

Security

Testing

  • Changes are covered with new/existing unit tests?
  • Changes are covered with new/existing integration tests?

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

const path = require('path');
const fs = require('fs');
const { extractStyleApiDocs } = require('@cloudscape-design/component-toolkit/internal/style-api/docs');
const { generateSlotMixins } = require('@cloudscape-design/component-toolkit/internal/style-api/generate-slot-mixins');

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

type="success"
dismissible={true}
action={<Button {...{ styleClassNames: { button: styles['alert-genai-action'] } }}>Generate again</Button>}
action={<Button {...{ styleClassNames: { root: styles['alert-genai-action'] } }}>Generate again</Button>}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This change is per API proposal review by the team: the separate button/anchor slots of the button are replaced with a single root slot.

{
type: 'pair',
label: 'Circle button',
label: 'Pill button',

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We remove --awsui-style-focus-ring-gutter-block and --awsui-style-focus-ring-gutter-inline to reduce the scope of new styling as these are not required for parity with v1. Because of this, the circle button example is no longer achievable because the default button focus outline gutters are not equal for between inline/block.

disabled && styles['checkbox-control-disabled'],
readOnly && styles['checkbox-control-readonly']
),
label: clsx(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

label and description slots are removed as unnecessary: these can be styled on the consumer side instead because the respective props support any React nodes.

--awsui-style-border-color: #{palette.$control-border-checked};
--awsui-style-color: #{palette.$control-fg};
@include checkbox.control(
$fill-color: palette.$control-bg,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Checkbox styles props names are updated:

  • background-color -> fill-color (to not be confused with CSS background; fill-color can take a single color value - gradients or images are not supported);
  • color -> indicator-color (to not be confused with CSS color which applies to fonts; this is called "indicator" and not "check" or "mark" for consistency with radio-button and toggle);
  • border-color -> border-color (unchanged - despite potential confusion with CSS native border-color, the risk of a misuse is low; unlike CSS border-color - this can only take a single value).

--awsui-style-border-color: #{palette.$border-accent};
--awsui-style-border-width: 2px;
--awsui-style-border-radius: 0px;
@include dropdown.dropdown(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The border-color and border-width props were replaced with outline-color and outline-width to be deliberately distinct from the border. That is because in the dropdown we render borders on a pseudo-element (::after), and these apply differently from normal borders. It is possible to support both border and outline properties at the same time, but there is no confirmed need yet - so only outline is supported for now.

"properties": [
"color",
"background",
"border",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Properties "border", "border-radius", and "padding" are automatically expanded in the generated mixins. For example, the "padding" is expanded into ["padding", "padding-block", "padding-inline"]. Properties always expand consistently, therefore there is no need to include this redundant info in the style docs metadata.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it could actually be useful to include the "redundant" info - if the underlying implementation changes in some way then we would get a clear warning about that. These snapshots are essentially testing our public API, so we should have them as close to that API surface area as possible

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I agree - I will create a follow-up pr to include this info. The docs are produced by the component-toolkit utils, so a separate PR is required in either case.

border-start-end-radius: $border-radius;
border-end-start-radius: $border-radius;
border-end-end-radius: $border-radius;
border-start-start-radius: inherit;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This change is needed so that a border-radius set on the dropdown container also takes effect on the border outline: these radii must always be in sync.

@@ -51,9 +51,9 @@ $_focus-ring-carriers: toolkit.resolve($focus-ring, carrier);
}
}

@mixin docs($name, $map) {
@mixin docs($name, $tokens: null, $properties: null, $descriptions: null) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This integrates with updated style docs utils from the component-toolkit, allowing to specify not just tokens but also properties per slot, and annotate the slot, tokens, and properties with descriptions.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Missing package exports prevent consumers using export-aware resolvers from importing the generated Sass modules.

1 open issue
What changed in this PR

Migrates internal Style API v2 styling to a mix of tokens and CSS properties, with generated Sass mixins for component slots.

Changes:

  • Generates slot mixins during builds and watch updates.
  • Updates component styling definitions and removes checkbox/toggle text slots.
  • Migrates demos to mixins and refreshes documentation snapshots.
File Description
src/​toggle/​styles.scss Renames control tokens; removes text slots.
src/​toggle/​internal.tsx Removes text-slot class forwarding.
src/​toggle/​__tests__/​style-api.test.tsx Updates control-slot tests.
src/​radio-button/​styles.scss Renames control tokens.
src/​link/​styles.scss Declares supported CSS properties.
src/​internal/​styles/​style-api.scss Extends documentation helper; removes gutter tokens.
src/​internal/​styles/​links.scss Removes token-based link overrides.
src/​internal/​styles/​forms/​mixins.scss Inherits dropdown outline radii.
src/​internal/​components/​radio-button/​styles.scss Uses renamed radio tokens.
src/​internal/​components/​checkbox-icon/​styles.scss Uses renamed checkbox tokens.
src/​internal/​components/​abstract-switch/​styles.scss Removes text-slot tokens.
src/​internal/​components/​abstract-switch/​index.tsx Removes text-slot class props.
src/​dropdown/​styles.scss Adds outline tokens and CSS properties.
src/​checkbox/​styles.scss Renames control tokens; removes text slots.
src/​checkbox/​internal.tsx Removes text-slot class forwarding.
src/​checkbox/​__tests__/​style-api.test.tsx Updates control-slot tests.
src/​button/​styles.scss Moves surface styling to CSS properties.
src/​badge/​styles.scss Replaces tokens with CSS properties.
src/​alert/​styles.scss Updates root and icon styling definitions.
src/​__tests__/​snapshot-tests/​__snapshots__/​style-docs.test.ts.snap Refreshes styling definitions.
pages/​toggle/​style-api-v2.scss Uses toggle mixins.
pages/​toggle/​style-api-v2.page.tsx Removes text-styling examples.
pages/​radio-button/​style-api-v2.scss Uses radio mixins.
pages/​link/​style-api-v2.scss Uses link mixins; adds font styling.
pages/​link/​style-api-v2.page.tsx Adds custom-font example.
pages/​dropdown/​style-api-v2.scss Uses dropdown mixins and custom shadow.
pages/​dropdown/​style-api-v2.page.tsx Updates shadow example label.
pages/​checkbox/​style-api-v2.scss Uses checkbox mixins.
pages/​checkbox/​style-api-v2.page.tsx Updates state classes; removes text styling.
pages/​button/​style-api-v2.scss Uses button mixins and pill styling.
pages/​button/​style-api-v2.page.tsx Renames circle example to pill.
pages/​badge/​style-api-v2.scss Uses badge mixins and custom typography.
pages/​badge/​style-api-v2.page.tsx Adds typography example.
pages/​alert/​style-api-v2.scss Uses alert and button mixins.
pages/​alert/​style-api-v2.page.tsx Corrects action button slot name.
gulpfile.js Runs mixin generation during build/watch.
build-tools/​tasks/​style-mixins.js Generates component Sass modules.
build-tools/​tasks/​index.js Registers mixin generation task.

Review effort: Balanced

Comment thread build-tools/tasks/style-mixins.js
@pan-kot
pan-kot requested a balanced review from Copilot October 21, 2026 07:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Generated mixin coverage is deferred, and cross-component cascade and focus changes need final human validation.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@pan-kot
pan-kot marked this pull request as ready for review October 21, 2026 07:30
@pan-kot
pan-kot requested a review from a team as a code owner October 21, 2026 07:30
@codecov

codecov Bot commented Oct 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.73%. Comparing base (347d271) to head (9369652).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5165      +/-   ##
==========================================
- Coverage   97.73%   97.73%   -0.01%     
==========================================
  Files         996      996              
  Lines       32152    32178      +26     
  Branches    11860    11873      +13     
==========================================
+ Hits        31424    31449      +25     
+ Misses        722      684      -38     
- Partials        6       45      +39     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pan-kot
pan-kot added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit b655074 Oct 21, 2026
68 checks passed
@pan-kot
pan-kot deleted the chore-style-api-mixins branch October 21, 2026 12:53

This branch was successfully deployed

3 active deployments
dev-pages-react18 — 93696527 Deployed Oct 21, 2026 by pan-kot via deploy (React 18) / deploy #2894
dev-pages-react16 — 93696527 Deployed Oct 21, 2026 by pan-kot via deploy (React 16) / deploy #2894
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants