Skip to content

chore: Add icon size and stroke width props#4514

Open
at-susie wants to merge 24 commits into
mainfrom
feat/custom-icon-size
Open

chore: Add icon size and stroke width props#4514
at-susie wants to merge 24 commits into
mainfrom
feat/custom-icon-size

Conversation

@at-susie
Copy link
Copy Markdown
Member

@at-susie at-susie commented May 13, 2026

Description

This PR adds:

1. New sizes and strokeWidths props on IconProvider:

Extend the existing IconProvider component with two new props — sizes and strokeWidths — that allow overriding icon dimensions and stroke widths at any level of the component tree.
In a nutshell, this proposal enables icon size and stroke-width customization by overriding the inline size and stroke-width of both the icon SVG and its wrapper element via the existing IconProvider.

Because the icon-provider already establishes a predictable scoping mechanism, icon sizes can be flexibly adjusted at different levels of the UI while maintaining consistent behavior.
This approach:

  • Leverages the existing provider/context pattern used for icon customization
  • Supports scoped overrides (global → local)
  • Provides independent control over both size and stroke-width per variant

2. A new x-small icon size variant (12px) for the icon component:

While it’s not currently used by any existing components, it supports future use cases we’ve already identified, such as icons inside badge components and icons used in button groups within prompt inputs.

How has this been tested?

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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

❌ Patch coverage is 88.23529% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.41%. Comparing base (7c2631d) to head (fe62fc1).

Files with missing lines Patch % Lines
src/icon-provider/internal.tsx 81.57% 7 Missing ⚠️
src/icon/internal.tsx 96.42% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4514      +/-   ##
==========================================
- Coverage   97.42%   97.41%   -0.02%     
==========================================
  Files         939      939              
  Lines       29645    29708      +63     
  Branches    10772    10800      +28     
==========================================
+ Hits        28883    28939      +56     
- Misses        715      722       +7     
  Partials       47       47              

☔ View full report in Codecov by Sentry.
📢 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.

- Add x-small and large icon size variants to complement existing sizes
- Create IconSizes component showcasing all icon size options (x-small, small, normal, medium, big, large)
- Update icon-scale-props page to display icon sizes in typography headings with size labels
- Refactor icon size display from static list to dynamic mapped component
- Add delivery method form field example to ButtonsInputsDropdowns section
- Remove section separator comments for cleaner code organization
- Update icon provider and icon interfaces to support new size variants
- Update icon mixins and styling for new size tokens
- Add x-small and large size tokens to style dictionary borders and sizes
- Update token name utilities and metadata for new size variants
- Update all related snapshot tests to reflect new icon size options
@at-susie at-susie force-pushed the feat/custom-icon-size branch from 2f5eb33 to 1d370b1 Compare May 18, 2026 09:38
at-susie added 2 commits May 18, 2026 14:05
- Add `sizes` prop to IconProvider to customize icon dimensions per size variant
- Add `strokeWidths` prop to IconProvider to customize stroke widths per size variant
- Support scoped overrides at any level of the component tree
- Update IconProvider internal implementation to apply size and stroke-width overrides
- Update Icon internal implementation to respect provider overrides
- Add comprehensive API proposal documentation with usage examples and design rationale
- Update icon provider dev page to demonstrate new scale props functionality
- Update icon-related dev pages (custom SVG, icons list, text align) to reflect changes
- Update snapshot tests to reflect new IconProvider interface and behavior
at-susie added 2 commits May 18, 2026 16:21
- Replace numeric IDs ('1', '2', '3', etc.) with semantic prefixed IDs ('action-1', 'action-2', 'action-3', etc.)
- Update all nested child node IDs to follow the new naming convention
- Update expandedItems state initialization to use new semantic IDs
- Improve ID clarity and maintainability in icon-scale-props demo page

function TableAndCards() {
const [selectedTableItems, setSelectedTableItems] = useState([tableItems[2]]);
const { items, collectionProps } = useCollection(tableItems, { sorting: {} });
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.

nit: Do we really need sorting and selection in this demo page?

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.

Good point — switched to generateItems + columnsConfig from the shared table configs, which removes the custom selection/sorting setup.

enableTokenGroups={true}
expandToViewport={true}
filteringAriaLabel="Find distributions"
i18nStrings={{
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.

We can use I18nProvider instead. The simplest option is to use the SimplePage template as such:

<SimplePage title="Icon scale overview" i18n={{}} screenshotArea={{}}>
  ...
</SimplePage>

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.

the same applies to other i18nStrings on this page

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.

Thanks for the suggestion. Removed the verbose i18nStrings from PropertyFilter and SplitPanel for now. Will look into adopting SimplePage / I18nProvider as a follow-up.

Comment thread pages/icon-provider/icon-scale-props.page.tsx
Comment thread pages/icon-provider/icon-scale-props.page.tsx
children?: ConnectorLinesItem[];
}

const connectorLinesItems: ConnectorLinesItem[] = [
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.

nit: why do we call these connectorLinesItems and not treeItems, and why is a custom type needed for these?

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.

Good catch — renamed to treeItems and TreeItem. The custom interface was unnecessary since the shape is the same as what TreeView expects.

})}
getItemId={item => item.id}
getItemChildren={item => item.children}
onItemToggle={({ detail }) =>
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.

nit: for the purposes of this demo I think we can remove the interactivity from the tree-view, wdyt?

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.

Done — removed the useState and onItemToggle handler, expandedItems is now a plain constant.

// Split panel state
const [splitPanelOpen, setSplitPanelOpen] = useState(true);

const sizeXSmallValue = parseFloat(iconSizeXSmall);
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.

nit: this value is used in a single place - you can call parseFloat before passing it to the provider in order to avoid creation of a new var here

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.

Done — removed all the intermediate *Value variables and inlined parseFloat() directly in the IconProvider props.

Comment thread src/icon/mixins.scss Outdated

&.size-#{$name} {
inline-size: $size;
/* stylelint-disable-next-line custom-property-pattern */
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.

This rule exists in order to avoid using un-hashed css props that consumers can start relying on in their code. See approach used for style API (/internal/generated/custom-css-properties) - can use use it here, too?

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.

Good call. Added iconSizeOverride, iconStrokeWidthOverride, and iconStrokeScale to
custom-css-properties.js, regenerated the map, and updated mixins.scss to use the hashed variables via @use '../internal/generated/custom-css-properties' as custom-props. Also updated internal.tsx and the tests to use the map. No more stylelint-disable comments needed.

Comment thread src/icon/mixins.scss Outdated
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.

2 participants