Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0a3f41d
feat(spinner): add recipe and tokens
thetaPC Mar 17, 2026
5eee3a8
chore(spinner): run build
thetaPC Mar 17, 2026
75a325a
test(color): update test page and snapshots
thetaPC Mar 17, 2026
53d06e1
chore(spinner): delete old styles
thetaPC Mar 17, 2026
78cfbba
test(spinner): update resize
thetaPC Mar 17, 2026
edb0414
test(spinner): remove diff term
thetaPC Mar 17, 2026
2ffac3e
test(spinner): update spacing
thetaPC Mar 17, 2026
3d89f21
feat(spinner): add recipe and config types
thetaPC Mar 17, 2026
363cddf
feat(spinner): change class names
thetaPC Mar 17, 2026
7b13706
test(spinner): update class
thetaPC Mar 17, 2026
b2a301a
refactor(spinner): remove plural type
thetaPC Mar 18, 2026
5f0020c
test(spinner): update color snapshots
thetaPC Mar 19, 2026
1179d40
refactor(theme): alphabetize imports
thetaPC Mar 19, 2026
4f5ee31
docs(spinner, chip): update get value functions comments
thetaPC Mar 19, 2026
2cd0043
Merge branch 'FW-6860' of github.com:ionic-team/ionic-framework into …
thetaPC Mar 19, 2026
4c1c6d2
feat(spinner): change type names
thetaPC Mar 19, 2026
ee53528
refactor(spinner): change existing config type name
thetaPC Mar 19, 2026
8019941
docs(chip, spinner): update method descriptions
thetaPC Mar 20, 2026
0aef08c
feat(chip, spinner): remove old CSS variables
thetaPC Mar 23, 2026
cb80321
feat(spinner): rename internal interface
thetaPC Mar 23, 2026
5388749
docs(breaking): update to include spinner
thetaPC Mar 23, 2026
de06eb8
feat(spinner): update --color to be internal
thetaPC Mar 23, 2026
7e1f630
feat(button, spinner): update color when spinner is inside button
thetaPC Mar 23, 2026
3c5afb3
fix(spinner): add missing token
thetaPC Mar 23, 2026
8668db4
docs(chip, spinner): clarify how defaults work
thetaPC Mar 23, 2026
528cb40
refactor(spinner): update return type
thetaPC Mar 23, 2026
e00d1f0
revert(BREAKING): leave radio group as is
thetaPC Mar 23, 2026
062a7c7
docs(BREAKING): update chip to include ionic modular changes
thetaPC Mar 23, 2026
95b1b41
docs(chip, spinner): add CSS variables to comments
thetaPC Mar 23, 2026
a8892a9
docs(chip): update logic comment
thetaPC Mar 23, 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
25 changes: 18 additions & 7 deletions BREAKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ This is a comprehensive list of the breaking changes introduced in the major ver
- [Card](#version-9x-card)
- [Chip](#version-9x-chip)
- [Grid](#version-9x-grid)
- [Radio Group](#version-9x-radio-group)
Comment thread
brandyscarney marked this conversation as resolved.
Outdated
- [Spinner](#version-9x-spinner)

<h2 id="version-9x-components">Components</h2>

Expand All @@ -38,12 +40,6 @@ This is a comprehensive list of the breaking changes introduced in the major ver

- The properties `pull` and `push` have been deprecated and no longer work. A similar look can be achieved with the newly added property `order`.

<h4 id="version-9x-radio-group">Radio Group</h4>
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was moved to the correct location. It was originally added right in the middle of the grid changes.


- Converted `ion-radio-group` to use [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM).<br/>
If you were targeting the internals of `ion-radio-group` in your CSS, you will need to target the `supporting-text`, `helper-text` or `error-text` [Shadow Parts](https://ionicframework.com/docs/theming/css-shadow-parts) instead, or use the provided CSS Variables.<br/>
Additionally, the `radio-group-wrapper` div element has been removed, causing slotted elements to be direct children of the `ion-radio-group`.

<h5>Example 1: Swap two columns</h5>

**Version up to 8.x**
Expand Down Expand Up @@ -140,4 +136,19 @@ To reorder two columns where column 1 has `size="9" push="3"` and column 2 has `
</ion-col>
</ion-row>
</ion-grid>
```
```

<h4 id="version-9x-radio-group">Radio Group</h4>

- Converted `ion-radio-group` to use [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM).<br/>
If you were targeting the internals of `ion-radio-group` in your CSS, you will need to target the `supporting-text`, `helper-text` or `error-text` [Shadow Parts](https://ionicframework.com/docs/theming/css-shadow-parts) instead, or use the provided CSS Variables.<br/>
Additionally, the `radio-group-wrapper` div element has been removed, causing slotted elements to be direct children of the `ion-radio-group`.

<h4 id="version-9x-spinner">Spinner</h4>

- Component CSS variables have been removed. The component now utilizes the centralized Ionic Theming system. Global updates should be managed via the theme tokens file, while component-specific overrides are handled through localized CSS variables.
Comment thread
brandyscarney marked this conversation as resolved.
- `--color` is replaced by `IonSpinner.color` for global styles and
`--ion-spinner-color` for component-specific styles.
- CSS classes now include the property name to improve clarity.
- `.spinner-[spinner-name]` → `.spinner-name-[spinner-name]`
- Specific theme classes (e.g., `ion-spinner.md`) are no longer supported. Style modifications based on the active theme must be implemented using theme tokens rather than direct class targeting.
9 changes: 0 additions & 9 deletions core/api.txt
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 PR description says:

CSS Overrides: Ensure selectors align with the new slotted element logic and variable names (e.g., --ion-spinner-color).

--color should no longer be used. Setting the value, IonSpinner.color, within the tokens file should be used to change the color.

But we still have this variable, why?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Because we discussed that it would be revisited as we add more components. Should I just remove them?

Copy link
Copy Markdown
Member

@brandyscarney brandyscarney Mar 20, 2026

Choose a reason for hiding this comment

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

Oh I thought that was just about the focus variables. I don't see a reason they can't override the --color on components directly? Developers might want it to be different than the global theme.

Copy link
Copy Markdown
Contributor Author

@thetaPC thetaPC Mar 23, 2026

Choose a reason for hiding this comment

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

Then they can override them per component by using --ion-spinner-color instead of --color. I ended up removing the old CSS variables since having both might be confusing of when to use them, the same for chip: 0aef08c and 7e1f630

Original file line number Diff line number Diff line change
Expand Up @@ -602,11 +602,6 @@ ion-chip,prop,mode,"ios" | "md",undefined,false,false
ion-chip,prop,outline,boolean,false,false,false
ion-chip,prop,shape,"rectangular" | "round" | "soft" | undefined,undefined,false,false
ion-chip,prop,size,"large" | "small" | undefined,undefined,false,false
ion-chip,css-prop,--border-radius
ion-chip,css-prop,--color
ion-chip,css-prop,--focus-ring-color
ion-chip,css-prop,--focus-ring-style
ion-chip,css-prop,--focus-ring-width

ion-col,shadow
ion-col,prop,mode,"ios" | "md",undefined,false,false
Expand Down Expand Up @@ -2309,10 +2304,6 @@ ion-spinner,prop,mode,"ios" | "md",undefined,false,false
ion-spinner,prop,name,"bubbles" | "circles" | "circular" | "crescent" | "dots" | "lines" | "lines-sharp" | "lines-sharp-small" | "lines-small" | undefined,undefined,false,false
ion-spinner,prop,paused,boolean,false,false,false
ion-spinner,prop,size,"large" | "medium" | "small" | "xlarge" | "xsmall" | undefined,undefined,false,false
ion-spinner,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-spinner,css-prop,--color,ionic
ion-spinner,css-prop,--color,ios
ion-spinner,css-prop,--color,md

ion-split-pane,shadow
ion-split-pane,prop,contentId,string | undefined,undefined,false,true
Expand Down
18 changes: 6 additions & 12 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { SegmentViewScrollEvent } from "./components/segment-view/segment-view-i
import { SelectChangeEventDetail, SelectCompareFn, SelectInterface } from "./components/select/select-interface";
import { SelectModalOption } from "./components/select-modal/select-modal-interface";
import { SelectPopoverOption } from "./components/select-popover/select-popover-interface";
import { SpinnerSize } from "./components/spinner/spinner.interfaces";
import { TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout } from "./components/tab-bar/tab-bar-interface";
import { TextareaChangeEventDetail, TextareaInputEventDetail } from "./components/textarea/textarea-interface";
import { ToastButton, ToastDismissOptions, ToastLayout, ToastPosition, ToastPresentOptions, ToastSwipeGestureDirection } from "./components/toast/toast-interface";
Expand Down Expand Up @@ -77,6 +78,7 @@ export { SegmentViewScrollEvent } from "./components/segment-view/segment-view-i
export { SelectChangeEventDetail, SelectCompareFn, SelectInterface } from "./components/select/select-interface";
export { SelectModalOption } from "./components/select-modal/select-modal-interface";
export { SelectPopoverOption } from "./components/select-popover/select-popover-interface";
export { SpinnerSize } from "./components/spinner/spinner.interfaces";
export { TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout } from "./components/tab-bar/tab-bar-interface";
export { TextareaChangeEventDetail, TextareaInputEventDetail } from "./components/textarea/textarea-interface";
export { ToastButton, ToastDismissOptions, ToastLayout, ToastPosition, ToastPresentOptions, ToastSwipeGestureDirection } from "./components/toast/toast-interface";
Expand Down Expand Up @@ -3881,13 +3883,9 @@ export namespace Components {
*/
"paused": boolean;
/**
* Set to `"xsmall"` for the smallest size. Set to `"small"` for a smaller size. Set to `"medium"` for a medium size. Set to `"large"` for a large size. Set to `"xlarge"` for the largest size. Defaults to `"xsmall"` for the `ionic` theme, undefined for all other themes.
* Set to `"xsmall"` for the smallest size. Set to `"small"` for a smaller size. Set to `"medium"` for a medium size. Set to `"large"` for a large size. Set to `"xlarge"` for the largest size. Defaults to `"medium"`.
*/
"size"?: 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge';
/**
* The theme determines the visual appearance of the component.
*/
"theme"?: "ios" | "md" | "ionic";
"size"?: SpinnerSize;
}
interface IonSplitPane {
/**
Expand Down Expand Up @@ -9911,13 +9909,9 @@ declare namespace LocalJSX {
*/
"paused"?: boolean;
/**
* Set to `"xsmall"` for the smallest size. Set to `"small"` for a smaller size. Set to `"medium"` for a medium size. Set to `"large"` for a large size. Set to `"xlarge"` for the largest size. Defaults to `"xsmall"` for the `ionic` theme, undefined for all other themes.
* Set to `"xsmall"` for the smallest size. Set to `"small"` for a smaller size. Set to `"medium"` for a medium size. Set to `"large"` for a large size. Set to `"xlarge"` for the largest size. Defaults to `"medium"`.
*/
"size"?: 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge';
/**
* The theme determines the visual appearance of the component.
*/
"theme"?: "ios" | "md" | "ionic";
"size"?: SpinnerSize;
}
interface IonSplitPane {
/**
Expand Down
26 changes: 8 additions & 18 deletions core/src/components/chip/chip.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,7 @@
// --------------------------------------------------

:host {
/**
* @prop --border-radius: Border radius of the chip
* @prop --color: Color of the chip
* @prop --focus-ring-color: Color of the focus ring
* @prop --focus-ring-style: Style of the focus ring
* @prop --focus-ring-width: Width of the focus ring
*/
Comment on lines -8 to -14
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.

How do we plan to document the new CSS variables? Are we going to add them here or somewhere else?

Copy link
Copy Markdown
Contributor Author

@thetaPC thetaPC Mar 23, 2026

Choose a reason for hiding this comment

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

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.

Is this auto-generated? If not we should really find a way to do so lol.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No, it was painstakingly annoying 😭 I'll make a ticket for us to look into a way to generate these.

--focus-ring-color: var(--ion-chip-state-focus-ring-color);
--focus-ring-style: var(--ion-chip-state-focus-ring-style);
--focus-ring-width: var(--ion-chip-state-focus-ring-width);

@include mixins.font-smoothing();
@include mixins.border-radius(var(--border-radius));
@include mixins.margin(
var(--ion-chip-margin-top),
var(--ion-chip-margin-end),
Expand All @@ -37,8 +25,6 @@
align-items: center;
justify-content: center;

color: var(--color);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was never being applied. The color is done through the hue classes.


font-weight: var(--ion-chip-font-weight);

letter-spacing: var(--ion-chip-letter-spacing);
Expand Down Expand Up @@ -72,15 +58,15 @@
// ---------------------------------------------

:host(.chip-shape-soft) {
--border-radius: var(--ion-chip-shape-soft-border-radius);
@include mixins.border-radius(var(--ion-chip-shape-soft-border-radius));
}

:host(.chip-shape-round) {
--border-radius: var(--ion-chip-shape-round-border-radius);
@include mixins.border-radius(var(--ion-chip-shape-round-border-radius));
}

:host(.chip-shape-rectangular) {
--border-radius: var(--ion-chip-shape-rectangular-border-radius);
@include mixins.border-radius(var(--ion-chip-shape-rectangular-border-radius));
}

// Chip: Bold Solid
Expand Down Expand Up @@ -358,7 +344,11 @@

// Focus
:host(.ion-focused) {
@include mixins.focused-state(var(--focus-ring-width), var(--focus-ring-style), var(--focus-ring-color));
@include mixins.focused-state(
var(--ion-chip-state-focus-ring-width),
var(--ion-chip-state-focus-ring-style),
var(--ion-chip-state-focus-ring-color)
);
}

// Chip Slotted Elements
Expand Down
12 changes: 8 additions & 4 deletions core/src/components/chip/chip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ export class Chip implements ComponentInterface {
}

/**
* Set the fill based on the custom theme config
* Gets the chip fill. Uses the `fill` property if set, otherwise
* checks the theme config and falls back to 'solid' if neither is provided.
*/
get fillValue(): string {
const fillConfig = config.getObjectValue('IonChip.fill', 'solid') as string;
Expand All @@ -91,7 +92,8 @@ export class Chip implements ComponentInterface {
}

/**
* Set the hue based on the custom theme config
* Gets the chip hue. Uses the `hue` property if set, otherwise
* checks the theme config and falls back to 'subtle' if neither is provided.
*/
get hueValue(): string {
const hueConfig = config.getObjectValue('IonChip.hue', 'subtle') as string;
Expand All @@ -101,7 +103,8 @@ export class Chip implements ComponentInterface {
}

/**
* Set the shape based on the custom theme config
* Gets the chip shape. Uses the `shape` property if set, otherwise
* checks the theme config and falls back to 'round' if neither is provided.
*/
get shapeValue(): string {
const shapeConfig = config.getObjectValue('IonChip.shape', 'round') as string;
Expand All @@ -111,7 +114,8 @@ export class Chip implements ComponentInterface {
}

/**
* Set the size based on the custom theme config
* Gets the chip size. Uses the `size` property if set, otherwise
* checks the theme config and falls back to 'large' if neither is provided.
*/
get sizeValue(): string {
const sizeConfig = config.getObjectValue('IonChip.size', 'large') as string;
Expand Down
4 changes: 2 additions & 2 deletions core/src/components/spinner/spinner-configs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SpinnerConfigs } from './spinner-interface';
import type { SpinnerDefinitions } from './spinner.interfaces';

const spinners = {
bubbles: {
Expand Down Expand Up @@ -150,5 +150,5 @@ const spinners = {
},
};

export const SPINNERS: SpinnerConfigs = spinners;
export const SPINNERS: SpinnerDefinitions = spinners;
export type SpinnerTypes = keyof typeof spinners;
22 changes: 0 additions & 22 deletions core/src/components/spinner/spinner-interface.ts
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was renamed, not sure why it's not showing as such.

This file was deleted.

78 changes: 78 additions & 0 deletions core/src/components/spinner/spinner.interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
export interface SpinnerDefinitions {
[spinnerName: string]: SpinnerDefinition;
}

export interface SpinnerDefinition {
dur: number;
circles?: number;
lines?: number;
elmDuration?: boolean;
fn: (dur: number, index: number, total: number) => SpinnerData;
}

interface SpinnerData {
Comment thread
brandyscarney marked this conversation as resolved.
r?: number;
y1?: number;
y2?: number;
cx?: number;
cy?: number;
style: { [key: string]: string | undefined };
viewBox?: string;
transform?: string;
}

export type IonSpinnerRecipe = {
color?: string;

lines?: {
stroke?: {
width?: string;
};

small?: {
stroke?: {
width?: string;
};
};

sharp?: {
stroke?: {
width?: string;
};

small?: {
stroke?: {
width?: string;
};
};
};
};

circular?: {
stroke?: {
width?: string;
};
};

crescent?: {
stroke?: {
width?: string;
};
};

// Sizes
size?: {
[K in SpinnerSize]?: IonSpinnerSizeDefinition;
};
};

type IonSpinnerSizeDefinition = {
width?: string;
height?: string;
};

export type IonSpinnerConfig = {
size?: SpinnerSize;
};

export type SpinnerSize = 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge';
62 changes: 0 additions & 62 deletions core/src/components/spinner/spinner.ionic.scss

This file was deleted.

Loading
Loading