Skip to content

Commit eed7167

Browse files
feat(grid, row, col): add recipe and tokens (#31189)
Issue number: resolves internal Co-authored-by: Brandy Smith <brandyscarney@users.noreply.github.com>
1 parent ce80f6d commit eed7167

142 files changed

Lines changed: 2189 additions & 497 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

BREAKING.md

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ This is a comprehensive list of the breaking changes introduced in the major ver
1919
- [Button](#version-9x-button)
2020
- [Card](#version-9x-card)
2121
- [Chip](#version-9x-chip)
22+
- [Col](#version-9x-col)
2223
- [Content](#version-9x-content)
2324
- [Datetime](#version-9x-datetime)
2425
- [Grid](#version-9x-grid)
@@ -27,6 +28,7 @@ This is a comprehensive list of the breaking changes introduced in the major ver
2728
- [Item Divider](#version-9x-item-divider)
2829
- [Menu Toggle](#version-9x-menu-toggle)
2930
- [Radio Group](#version-9x-radio-group)
31+
- [Row](#version-9x-row)
3032
- [Spinner](#version-9x-spinner)
3133
- [Text](#version-9x-text)
3234
- [Textarea](#version-9x-textarea)
@@ -87,6 +89,25 @@ This is a comprehensive list of the breaking changes introduced in the major ver
8789
- Specific theme classes (e.g., `ion-chip.md`) are no longer supported. Style modifications based on the active theme must be implemented using theme tokens rather than direct class targeting.
8890
- The `border-radius` of the `ios` and `md` chip now defaults to `10px` and `8px`, respectively, instead of `16px` in accordance with the iOS and Material Design 3 guidelines. To revert to the previous appearance, set the `shape` to `"round"`, or override the `IonChip.shape.round.border.radius` to specify a different value for global styles and `--ion-chip-shape-round-border-radius` for component-specific styles.
8991

92+
<h4 id="version-9x-col">Col</h4>
93+
94+
The following breaking changes apply to `ion-col`:
95+
96+
1. `--ion-grid-column-padding-*` CSS variables have been replaced with per-side, per-breakpoint tokens in the `col` namespace. <sup>[1](#version-9x-col-padding-variables)</sup>
97+
2. Theme classes (`ion-col.md`, `ion-col.ios`) are no longer supported. <sup>[2](#version-9x-col-theme-classes)</sup>
98+
99+
<h5 id="version-9x-col-padding-variables">Padding variables</h5>
100+
101+
Column padding was a single value per breakpoint and is now set per-side, and the variables have moved from the `grid` namespace to the `col` namespace. Use the new token structure for global styles, or the corresponding CSS variable for component-specific overrides:
102+
103+
| Old (8.x) | New token (global) | New CSS variable (component-specific) |
104+
|---|---|---|
105+
| `--ion-grid-column-padding-{bp}` | `IonCol.breakpoint.{bp}.padding.{top\|end\|bottom\|start}` | `--ion-col-breakpoint-{bp}-padding-{top\|end\|bottom\|start}` |
106+
107+
<h5 id="version-9x-col-theme-classes">Theme classes</h5>
108+
109+
Remove any instances that target the theme classes: `ion-col.md`, `ion-col.ios`.
110+
90111
<h4 id="version-9x-content">Content</h4>
91112

92113
The following breaking changes apply to `ion-content`:
@@ -141,9 +162,32 @@ Remove any instances that target the theme classes: `ion-content.md`, `ion-conte
141162

142163
<h4 id="version-9x-grid">Grid</h4>
143164

144-
- The properties `pull` and `push` have been deprecated and no longer work. A similar look can be achieved with the newly added property `order`.
165+
The following breaking changes apply to `ion-grid`:
166+
167+
1. `--ion-grid-padding-*` CSS variables have been replaced with per-side, per-breakpoint tokens. <sup>[1](#version-9x-grid-padding-variables)</sup>
168+
2. `--ion-grid-width-*` CSS variables for the fixed grid have been replaced with per-breakpoint tokens. <sup>[2](#version-9x-grid-fixed-width-variables)</sup>
169+
3. The `push` and `pull` properties have been deprecated. <sup>[3](#version-9x-grid-deprecated-push-and-pull-properties)</sup>
170+
4. Theme classes (`ion-grid.md`, `ion-grid.ios`) are no longer supported. <sup>[4](#version-9x-grid-theme-classes)</sup>
171+
172+
<h5 id="version-9x-grid-padding-variables">Padding variables</h5>
145173

146-
<h5>Example 1: Swap two columns</h5>
174+
Grid padding was a single value per breakpoint and is now set per-side. Use the new token structure for global styles, or the corresponding CSS variable for component-specific overrides:
175+
176+
| Old (8.x) | New token (global) | New CSS variable (component-specific) |
177+
|---|---|---|
178+
| `--ion-grid-padding-{bp}` | `IonGrid.breakpoint.{bp}.padding.{top\|end\|bottom\|start}` | `--ion-grid-breakpoint-{bp}-padding-{top\|end\|bottom\|start}` |
179+
180+
<h5 id="version-9x-grid-fixed-width-variables">Fixed width variables</h5>
181+
182+
| Old (8.x) | New token (global) | New CSS variable (component-specific) |
183+
|---|---|---|
184+
| `--ion-grid-width-{bp}` | `IonGrid.breakpoint.{bp}.width` | `--ion-grid-breakpoint-{bp}-width` |
185+
186+
<h5 id="version-9x-grid-deprecated-push-and-pull-properties">Deprecated <code>push</code> and <code>pull</code> properties</h5>
187+
188+
The `push` and `pull` properties have been disabled. They now log a deprecation warning and no longer affect layout. Use the `order` property to achieve a similar result.
189+
190+
**Example 1: Swap two columns**
147191

148192
**Version up to 8.x**
149193

@@ -169,7 +213,7 @@ Remove any instances that target the theme classes: `ion-content.md`, `ion-conte
169213
</ion-grid>
170214
```
171215

172-
<h5>Example 2: Reorder columns with specific sizes</h5>
216+
**Example 2: Reorder columns with specific sizes**
173217

174218
To reorder two columns where column 1 has `size="9" push="3"` and column 2 has `size="3" pull="9"`:
175219

@@ -195,7 +239,7 @@ To reorder two columns where column 1 has `size="9" push="3"` and column 2 has `
195239
</ion-grid>
196240
```
197241

198-
<h5>Example 3: Push</h5>
242+
**Example 3: Push**
199243

200244
```html
201245
<ion-grid>
@@ -225,7 +269,7 @@ To reorder two columns where column 1 has `size="9" push="3"` and column 2 has `
225269
</ion-grid>
226270
```
227271

228-
<h5>Example 4: Push and Pull</h5>
272+
**Example 4: Push and Pull**
229273

230274
```html
231275
<ion-grid>
@@ -255,6 +299,10 @@ To reorder two columns where column 1 has `size="9" push="3"` and column 2 has `
255299
</ion-grid>
256300
```
257301

302+
<h5 id="version-9x-grid-theme-classes">Theme classes</h5>
303+
304+
Remove any instances that target the theme classes: `ion-grid.md`, `ion-grid.ios`.
305+
258306
<h4 id="version-9x-image">Image</h4>
259307

260308
The following breaking changes apply to `ion-img`:
@@ -304,6 +352,16 @@ If you were targeting the internals of `ion-radio-group` in your CSS, you will n
304352

305353
Additionally, the `radio-group-wrapper` div element has been removed, causing slotted elements to be direct children of the `ion-radio-group`.
306354

355+
<h4 id="version-9x-row">Row</h4>
356+
357+
The following breaking changes apply to `ion-row`:
358+
359+
1. Theme classes (`ion-row.md`, `ion-row.ios`) are no longer supported. <sup>[1](#version-9x-row-theme-classes)</sup>
360+
361+
<h5 id="version-9x-row-theme-classes">Theme classes</h5>
362+
363+
Remove any instances that target the theme classes: `ion-row.md`, `ion-row.ios`.
364+
307365
<h4 id="version-9x-spinner">Spinner</h4>
308366

309367
- 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.

core/api.txt

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -781,15 +781,26 @@ ion-col,prop,sizeMd,string | undefined,undefined,false,false
781781
ion-col,prop,sizeSm,string | undefined,undefined,false,false
782782
ion-col,prop,sizeXl,string | undefined,undefined,false,false
783783
ion-col,prop,sizeXs,string | undefined,undefined,false,false
784-
ion-col,prop,theme,"ios" | "md" | "ionic",undefined,false,false
785-
ion-col,css-prop,--col-unit-size
786-
ion-col,css-prop,--ion-grid-column-padding
787-
ion-col,css-prop,--ion-grid-column-padding-lg
788-
ion-col,css-prop,--ion-grid-column-padding-md
789-
ion-col,css-prop,--ion-grid-column-padding-sm
790-
ion-col,css-prop,--ion-grid-column-padding-xl
791-
ion-col,css-prop,--ion-grid-column-padding-xs
792-
ion-col,css-prop,--ion-grid-columns
784+
ion-col,css-prop,--ion-col-breakpoint-lg-padding-bottom
785+
ion-col,css-prop,--ion-col-breakpoint-lg-padding-end
786+
ion-col,css-prop,--ion-col-breakpoint-lg-padding-start
787+
ion-col,css-prop,--ion-col-breakpoint-lg-padding-top
788+
ion-col,css-prop,--ion-col-breakpoint-md-padding-bottom
789+
ion-col,css-prop,--ion-col-breakpoint-md-padding-end
790+
ion-col,css-prop,--ion-col-breakpoint-md-padding-start
791+
ion-col,css-prop,--ion-col-breakpoint-md-padding-top
792+
ion-col,css-prop,--ion-col-breakpoint-sm-padding-bottom
793+
ion-col,css-prop,--ion-col-breakpoint-sm-padding-end
794+
ion-col,css-prop,--ion-col-breakpoint-sm-padding-start
795+
ion-col,css-prop,--ion-col-breakpoint-sm-padding-top
796+
ion-col,css-prop,--ion-col-breakpoint-xl-padding-bottom
797+
ion-col,css-prop,--ion-col-breakpoint-xl-padding-end
798+
ion-col,css-prop,--ion-col-breakpoint-xl-padding-start
799+
ion-col,css-prop,--ion-col-breakpoint-xl-padding-top
800+
ion-col,css-prop,--ion-col-breakpoint-xs-padding-bottom
801+
ion-col,css-prop,--ion-col-breakpoint-xs-padding-end
802+
ion-col,css-prop,--ion-col-breakpoint-xs-padding-start
803+
ion-col,css-prop,--ion-col-breakpoint-xs-padding-top
793804

794805
ion-content,shadow
795806
ion-content,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
@@ -1043,19 +1054,32 @@ ion-gallery,prop,theme,"ios" | "md" | "ionic",undefined,false,false
10431054
ion-grid,shadow
10441055
ion-grid,prop,fixed,boolean,false,false,false
10451056
ion-grid,prop,mode,"ios" | "md",undefined,false,false
1046-
ion-grid,prop,theme,"ios" | "md" | "ionic",undefined,false,false
1047-
ion-grid,css-prop,--ion-grid-padding
1048-
ion-grid,css-prop,--ion-grid-padding-lg
1049-
ion-grid,css-prop,--ion-grid-padding-md
1050-
ion-grid,css-prop,--ion-grid-padding-sm
1051-
ion-grid,css-prop,--ion-grid-padding-xl
1052-
ion-grid,css-prop,--ion-grid-padding-xs
1053-
ion-grid,css-prop,--ion-grid-width
1054-
ion-grid,css-prop,--ion-grid-width-lg
1055-
ion-grid,css-prop,--ion-grid-width-md
1056-
ion-grid,css-prop,--ion-grid-width-sm
1057-
ion-grid,css-prop,--ion-grid-width-xl
1058-
ion-grid,css-prop,--ion-grid-width-xs
1057+
ion-grid,css-prop,--ion-grid-breakpoint-lg-padding-bottom
1058+
ion-grid,css-prop,--ion-grid-breakpoint-lg-padding-end
1059+
ion-grid,css-prop,--ion-grid-breakpoint-lg-padding-start
1060+
ion-grid,css-prop,--ion-grid-breakpoint-lg-padding-top
1061+
ion-grid,css-prop,--ion-grid-breakpoint-lg-width
1062+
ion-grid,css-prop,--ion-grid-breakpoint-md-padding-bottom
1063+
ion-grid,css-prop,--ion-grid-breakpoint-md-padding-end
1064+
ion-grid,css-prop,--ion-grid-breakpoint-md-padding-start
1065+
ion-grid,css-prop,--ion-grid-breakpoint-md-padding-top
1066+
ion-grid,css-prop,--ion-grid-breakpoint-md-width
1067+
ion-grid,css-prop,--ion-grid-breakpoint-sm-padding-bottom
1068+
ion-grid,css-prop,--ion-grid-breakpoint-sm-padding-end
1069+
ion-grid,css-prop,--ion-grid-breakpoint-sm-padding-start
1070+
ion-grid,css-prop,--ion-grid-breakpoint-sm-padding-top
1071+
ion-grid,css-prop,--ion-grid-breakpoint-sm-width
1072+
ion-grid,css-prop,--ion-grid-breakpoint-xl-padding-bottom
1073+
ion-grid,css-prop,--ion-grid-breakpoint-xl-padding-end
1074+
ion-grid,css-prop,--ion-grid-breakpoint-xl-padding-start
1075+
ion-grid,css-prop,--ion-grid-breakpoint-xl-padding-top
1076+
ion-grid,css-prop,--ion-grid-breakpoint-xl-width
1077+
ion-grid,css-prop,--ion-grid-breakpoint-xs-padding-bottom
1078+
ion-grid,css-prop,--ion-grid-breakpoint-xs-padding-end
1079+
ion-grid,css-prop,--ion-grid-breakpoint-xs-padding-start
1080+
ion-grid,css-prop,--ion-grid-breakpoint-xs-padding-top
1081+
ion-grid,css-prop,--ion-grid-breakpoint-xs-width
1082+
ion-grid,css-prop,--ion-grid-columns
10591083

10601084
ion-header,none
10611085
ion-header,prop,collapse,"condense" | "fade" | undefined,undefined,false,false
@@ -2255,8 +2279,7 @@ ion-router-outlet,prop,theme,"ios" | "md" | "ionic",undefined,false,false
22552279

22562280
ion-row,shadow
22572281
ion-row,prop,mode,"ios" | "md",undefined,false,false
2258-
ion-row,prop,theme,"ios" | "md" | "ionic",undefined,false,false
2259-
ion-row,css-prop,--ion-grid-gap
2282+
ion-row,css-prop,--ion-row-gap
22602283

22612284
ion-searchbar,scoped
22622285
ion-searchbar,prop,animated,boolean,false,false,false

core/src/components.d.ts

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,10 +1043,6 @@ export namespace Components {
10431043
* The size of the column for xs screens, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
10441044
*/
10451045
"sizeXs"?: string;
1046-
/**
1047-
* The theme determines the visual appearance of the component.
1048-
*/
1049-
"theme"?: "ios" | "md" | "ionic";
10501046
}
10511047
interface IonContent {
10521048
/**
@@ -1512,10 +1508,6 @@ export namespace Components {
15121508
* The mode determines the platform behaviors of the component.
15131509
*/
15141510
"mode"?: "ios" | "md";
1515-
/**
1516-
* The theme determines the visual appearance of the component.
1517-
*/
1518-
"theme"?: "ios" | "md" | "ionic";
15191511
}
15201512
interface IonHeader {
15211513
/**
@@ -3463,7 +3455,7 @@ export namespace Components {
34633455
* The mode determines the platform behaviors of the component.
34643456
* @default getIonMode(this)
34653457
*/
3466-
"mode": "ios" | "md";
3458+
"mode": "md" | "ios";
34673459
"setRouteId": (id: string, params: ComponentProps | undefined, direction: RouterDirection, animation?: AnimationBuilder) => Promise<RouteWrite>;
34683460
"swipeHandler"?: SwipeGestureHandler;
34693461
/**
@@ -3476,10 +3468,6 @@ export namespace Components {
34763468
* The mode determines the platform behaviors of the component.
34773469
*/
34783470
"mode"?: "ios" | "md";
3479-
/**
3480-
* The theme determines the visual appearance of the component.
3481-
*/
3482-
"theme"?: "ios" | "md" | "ionic";
34833471
}
34843472
interface IonSearchbar {
34853473
/**
@@ -7062,10 +7050,6 @@ declare namespace LocalJSX {
70627050
* The size of the column for xs screens, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
70637051
*/
70647052
"sizeXs"?: string;
7065-
/**
7066-
* The theme determines the visual appearance of the component.
7067-
*/
7068-
"theme"?: "ios" | "md" | "ionic";
70697053
}
70707054
interface IonContent {
70717055
/**
@@ -7520,10 +7504,6 @@ declare namespace LocalJSX {
75207504
* The mode determines the platform behaviors of the component.
75217505
*/
75227506
"mode"?: "ios" | "md";
7523-
/**
7524-
* The theme determines the visual appearance of the component.
7525-
*/
7526-
"theme"?: "ios" | "md" | "ionic";
75277507
}
75287508
interface IonHeader {
75297509
/**
@@ -9511,7 +9491,7 @@ declare namespace LocalJSX {
95119491
* The mode determines the platform behaviors of the component.
95129492
* @default getIonMode(this)
95139493
*/
9514-
"mode"?: "ios" | "md";
9494+
"mode"?: "md" | "ios";
95159495
"onIonNavDidChange"?: (event: IonRouterOutletCustomEvent<void>) => void;
95169496
"onIonNavWillChange"?: (event: IonRouterOutletCustomEvent<void>) => void;
95179497
"onIonNavWillLoad"?: (event: IonRouterOutletCustomEvent<void>) => void;
@@ -9526,10 +9506,6 @@ declare namespace LocalJSX {
95269506
* The mode determines the platform behaviors of the component.
95279507
*/
95289508
"mode"?: "ios" | "md";
9529-
/**
9530-
* The theme determines the visual appearance of the component.
9531-
*/
9532-
"theme"?: "ios" | "md" | "ionic";
95339509
}
95349510
interface IonSearchbar {
95359511
/**
@@ -11229,7 +11205,7 @@ declare namespace LocalJSX {
1122911205
"target": string | undefined;
1123011206
}
1123111207
interface IonRouterOutletAttributes {
11232-
"mode": "ios" | "md";
11208+
"mode": "md" | "ios";
1123311209
"animated": boolean;
1123411210
}
1123511211
interface IonSearchbarAttributes {
Loading
Loading
Loading

core/src/components/action-sheet/test/translucent/index.html

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@
1414
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
1515

1616
<style>
17-
f {
18-
display: block;
19-
width: 100%;
17+
.color-grid {
18+
display: grid;
19+
grid-template-columns: repeat(3, 1fr);
20+
}
21+
22+
.color-block {
2023
height: 150px;
24+
25+
border: 5px solid transparent;
26+
background-clip: padding-box;
2127
}
2228

2329
.red {
@@ -77,19 +83,17 @@
7783
<button class="expand" id="scrollWithoutCancel" onclick="presentScrollNoCancel()">Scroll Without Cancel</button>
7884
<button class="expand" id="cancelOnly" onclick="presentCancelOnly()">Cancel Only</button>
7985

80-
<ion-grid>
81-
<ion-row>
82-
<ion-col size="4"><f class="red"></f></ion-col>
83-
<ion-col size="4"><f class="green"></f></ion-col>
84-
<ion-col size="4"><f class="blue"></f></ion-col>
85-
<ion-col size="4"><f class="yellow"></f></ion-col>
86-
<ion-col size="4"><f class="pink"></f></ion-col>
87-
<ion-col size="4"><f class="purple"></f></ion-col>
88-
<ion-col size="4"><f class="black"></f></ion-col>
89-
<ion-col size="4"><f class="fuchsia"></f></ion-col>
90-
<ion-col size="4"><f class="orange"></f></ion-col>
91-
</ion-row>
92-
</ion-grid>
86+
<div class="color-grid">
87+
<div class="color-block red"></div>
88+
<div class="color-block green"></div>
89+
<div class="color-block blue"></div>
90+
<div class="color-block yellow"></div>
91+
<div class="color-block pink"></div>
92+
<div class="color-block purple"></div>
93+
<div class="color-block black"></div>
94+
<div class="color-block fuchsia"></div>
95+
<div class="color-block orange"></div>
96+
</div>
9397
</ion-content>
9498
<ion-action-sheet-controller></ion-action-sheet-controller>
9599
</ion-app>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type { IonPadding } from '../../themes/themes.interfaces';
2+
import { ION_GRID_BREAKPOINTS } from '../grid/grid.interface';
3+
4+
export type IonColRecipe = {
5+
breakpoint?: {
6+
[K in IonColBreakpoint]?: {
7+
padding?: IonPadding;
8+
};
9+
};
10+
};
11+
12+
// TODO(FW-7285): Replace with global breakpoints
13+
export const ION_COL_BREAKPOINTS = ION_GRID_BREAKPOINTS;
14+
export type IonColBreakpoint = (typeof ION_COL_BREAKPOINTS)[number];
15+
16+
export type IonColProperty = 'size' | 'order' | 'offset';
17+
18+
export type IonColStyle = {
19+
'--internal-col-margin'?: string;
20+
'--internal-col-span'?: string;
21+
order?: string;
22+
};

0 commit comments

Comments
 (0)