Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 6 additions & 5 deletions BREAKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,12 @@ The following breaking changes apply to `ion-button`:
5. Icon-only buttons are now squares as tall as a text button of the same size. In `md`, this makes them a few pixels smaller at the small and default sizes and larger at the large size. To change their size, set the size's `min.height` as described above.
6. The `md` button follows Material Design 2 for its spacing, outline, elevation and disabled state. <sup>[6](#version-10x-button-md-material-design-2)</sup>
7. The `ios` button follows iOS 17 for its font, icons and disabled state. <sup>[7](#version-10x-button-ios-17)</sup>
8. CSS variables have been replaced. <sup>[8](#version-10x-button-replaced-css-variables)</sup>
9. `--padding-*` CSS variables are no longer part of the documented public API (but remain functional). <sup>[9](#version-10x-button-padding-variables)</sup>
10. The fill, size, shape and expand classes have been renamed. <sup>[10](#version-10x-button-renamed-classes)</sup>
11. The `default` size has been deprecated. <sup>[11](#version-10x-button-deprecated-default-size)</sup>
12. Theme classes (`ion-button.md`, `ion-button.ios`) are no longer supported. <sup>[12](#version-10x-button-theme-classes)</sup>
8. A badge without a `vertical` position now has a gap between it and the label, and no longer makes the button taller than its `min.height`. To remove the gap, set `IonButton.size.<size>.badge.margin.start` for global styles or `--ion-button-size-<size>-badge-margin-start` for component-specific styles to `0`.
9. CSS variables have been replaced. <sup>[9](#version-10x-button-replaced-css-variables)</sup>
10. `--padding-*` CSS variables are no longer part of the documented public API (but remain functional). <sup>[10](#version-10x-button-padding-variables)</sup>
11. The fill, size, shape and expand classes have been renamed. <sup>[11](#version-10x-button-renamed-classes)</sup>
12. The `default` size has been deprecated. <sup>[12](#version-10x-button-deprecated-default-size)</sup>
13. Theme classes (`ion-button.md`, `ion-button.ios`) are no longer supported. <sup>[13](#version-10x-button-theme-classes)</sup>

<h5 id="version-10x-button-md-material-design-2">Material Design 2 in <code>md</code></h5>

Expand Down
12 changes: 12 additions & 0 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,10 @@ ion-button,css-prop,--ion-button-shape-crisp-border-radius
ion-button,css-prop,--ion-button-shape-rectangular-border-radius
ion-button,css-prop,--ion-button-shape-round-border-radius
ion-button,css-prop,--ion-button-shape-soft-border-radius
ion-button,css-prop,--ion-button-size-large-badge-margin-bottom
ion-button,css-prop,--ion-button-size-large-badge-margin-end
ion-button,css-prop,--ion-button-size-large-badge-margin-start
ion-button,css-prop,--ion-button-size-large-badge-margin-top
ion-button,css-prop,--ion-button-size-large-font-size
ion-button,css-prop,--ion-button-size-large-icon-font-size
ion-button,css-prop,--ion-button-size-large-icon-leading-margin-bottom
Expand Down Expand Up @@ -620,6 +624,10 @@ ion-button,css-prop,--ion-button-size-large-spinner-trailing-margin-bottom
ion-button,css-prop,--ion-button-size-large-spinner-trailing-margin-end
ion-button,css-prop,--ion-button-size-large-spinner-trailing-margin-start
ion-button,css-prop,--ion-button-size-large-spinner-trailing-margin-top
ion-button,css-prop,--ion-button-size-medium-badge-margin-bottom
ion-button,css-prop,--ion-button-size-medium-badge-margin-end
ion-button,css-prop,--ion-button-size-medium-badge-margin-start
ion-button,css-prop,--ion-button-size-medium-badge-margin-top
ion-button,css-prop,--ion-button-size-medium-font-size
ion-button,css-prop,--ion-button-size-medium-icon-font-size
ion-button,css-prop,--ion-button-size-medium-icon-leading-margin-bottom
Expand Down Expand Up @@ -660,6 +668,10 @@ ion-button,css-prop,--ion-button-size-medium-spinner-trailing-margin-bottom
ion-button,css-prop,--ion-button-size-medium-spinner-trailing-margin-end
ion-button,css-prop,--ion-button-size-medium-spinner-trailing-margin-start
ion-button,css-prop,--ion-button-size-medium-spinner-trailing-margin-top
ion-button,css-prop,--ion-button-size-small-badge-margin-bottom
ion-button,css-prop,--ion-button-size-small-badge-margin-end
ion-button,css-prop,--ion-button-size-small-badge-margin-start
ion-button,css-prop,--ion-button-size-small-badge-margin-top
ion-button,css-prop,--ion-button-size-small-font-size
ion-button,css-prop,--ion-button-size-small-icon-font-size
ion-button,css-prop,--ion-button-size-small-icon-leading-margin-bottom
Expand Down
12 changes: 12 additions & 0 deletions core/src/components/button/_button.docs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@
* @prop --ion-button-size-small-spinner-trailing-margin-end: Right margin if direction is left-to-right, and left margin if direction is right-to-left of a spinner in the `end` slot of the `small` button size
* @prop --ion-button-size-small-spinner-trailing-margin-bottom: Bottom margin of a spinner in the `end` slot of the `small` button size
* @prop --ion-button-size-small-spinner-trailing-margin-start: Left margin if direction is left-to-right, and right margin if direction is right-to-left of a spinner in the `end` slot of the `small` button size
* @prop --ion-button-size-small-badge-margin-top: Top margin of a badge without a `vertical` position in a text button of the `small` size
* @prop --ion-button-size-small-badge-margin-end: Right margin if direction is left-to-right, and left margin if direction is right-to-left of a badge without a `vertical` position in a text button of the `small` size
* @prop --ion-button-size-small-badge-margin-bottom: Bottom margin of a badge without a `vertical` position in a text button of the `small` size
* @prop --ion-button-size-small-badge-margin-start: Left margin if direction is left-to-right, and right margin if direction is right-to-left of a badge without a `vertical` position in a text button of the `small` size
* @prop --ion-button-size-medium-min-width: Minimum width of the `medium` button size
* @prop --ion-button-size-medium-min-height: Minimum height of the `medium` button size, and the width and height of an icon-only button of that size
* @prop --ion-button-size-medium-font-size: Font size of the `medium` button size
Expand Down Expand Up @@ -93,6 +97,10 @@
* @prop --ion-button-size-medium-spinner-trailing-margin-end: Right margin if direction is left-to-right, and left margin if direction is right-to-left of a spinner in the `end` slot of the `medium` button size
* @prop --ion-button-size-medium-spinner-trailing-margin-bottom: Bottom margin of a spinner in the `end` slot of the `medium` button size
* @prop --ion-button-size-medium-spinner-trailing-margin-start: Left margin if direction is left-to-right, and right margin if direction is right-to-left of a spinner in the `end` slot of the `medium` button size
* @prop --ion-button-size-medium-badge-margin-top: Top margin of a badge without a `vertical` position in a text button of the `medium` size
* @prop --ion-button-size-medium-badge-margin-end: Right margin if direction is left-to-right, and left margin if direction is right-to-left of a badge without a `vertical` position in a text button of the `medium` size
* @prop --ion-button-size-medium-badge-margin-bottom: Bottom margin of a badge without a `vertical` position in a text button of the `medium` size
* @prop --ion-button-size-medium-badge-margin-start: Left margin if direction is left-to-right, and right margin if direction is right-to-left of a badge without a `vertical` position in a text button of the `medium` size
* @prop --ion-button-size-large-min-width: Minimum width of the `large` button size
* @prop --ion-button-size-large-min-height: Minimum height of the `large` button size, and the width and height of an icon-only button of that size
* @prop --ion-button-size-large-font-size: Font size of the `large` button size
Expand Down Expand Up @@ -133,6 +141,10 @@
* @prop --ion-button-size-large-spinner-trailing-margin-end: Right margin if direction is left-to-right, and left margin if direction is right-to-left of a spinner in the `end` slot of the `large` button size
* @prop --ion-button-size-large-spinner-trailing-margin-bottom: Bottom margin of a spinner in the `end` slot of the `large` button size
* @prop --ion-button-size-large-spinner-trailing-margin-start: Left margin if direction is left-to-right, and right margin if direction is right-to-left of a spinner in the `end` slot of the `large` button size
* @prop --ion-button-size-large-badge-margin-top: Top margin of a badge without a `vertical` position in a text button of the `large` size
* @prop --ion-button-size-large-badge-margin-end: Right margin if direction is left-to-right, and left margin if direction is right-to-left of a badge without a `vertical` position in a text button of the `large` size
* @prop --ion-button-size-large-badge-margin-bottom: Bottom margin of a badge without a `vertical` position in a text button of the `large` size
* @prop --ion-button-size-large-badge-margin-start: Left margin if direction is left-to-right, and right margin if direction is right-to-left of a badge without a `vertical` position in a text button of the `large` size
* @prop --ion-button-shape-crisp-border-radius: Border radius of the `crisp` button shape
* @prop --ion-button-shape-soft-border-radius: Border radius of the `soft` button shape
* @prop --ion-button-shape-round-border-radius: Border radius of the `round` button shape
Expand Down
5 changes: 5 additions & 0 deletions core/src/components/button/button.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@ type IonButtonSizeDefinition = {
icon?: IonButtonIconDefinition;
iconOnly?: IonButtonIconOnlyDefinition;
spinner?: IonButtonSpinnerDefinition;

/** A badge without a `vertical` position, which sits after the label of a text button */
badge?: {
margin?: IonMargin;
};
};

type IonButtonShapeDefinition = {
Expand Down
14 changes: 14 additions & 0 deletions core/src/components/button/button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -486,5 +486,19 @@ $spinner-sizes: xsmall, small, medium, large, xlarge;
// --------------------------------------------------

:host(.button-has-badge) .button-native {
// Keeps a badge taller than the label from making the button taller than its min height
@include mixins.padding(var(--padding-top, 0), null, var(--padding-bottom, 0), null);

overflow: visible;
}

@each $size in $sizes {
:host(.button-size-#{$size}:not(.button-has-icon-only)) ::slotted(ion-badge:not([vertical])) {
@include mixins.margin(
var(--ion-button-size-#{$size}-badge-margin-top),
var(--ion-button-size-#{$size}-badge-margin-end),
var(--ion-button-size-#{$size}-badge-margin-bottom),
var(--ion-button-size-#{$size}-badge-margin-start)
);
}
}
45 changes: 45 additions & 0 deletions core/src/components/button/test/badge/button.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,50 @@ configs({ modes: ['md', 'ios', 'ionic-md'] }).forEach(({ config, screenshot, tit

await expect(container).toHaveScreenshot(screenshot(`button-badge`));
});

test('should space a badge without a position from the label', async ({ page }) => {
const rows = BUTTON_SIZES.map(
(buttonSize) => `<div class="row">${contents
.flatMap((html) =>
ION_BADGE_SIZES.map(
(badgeSize) => `<ion-button size="${buttonSize}" shape="round">
Button
<ion-badge hue="bold" shape="round" color="danger" size="${badgeSize}">${html}</ion-badge>
</ion-button>`
)
)
.join('\n')}
</div>`
).join('\n');

await page.setContent(
`
<style>
.row {
display: grid;
grid-template-columns: repeat(3, auto);
justify-items: start;
align-items: center;
padding-bottom: 10px;
row-gap: 5px;
column-gap: 30px;
}
</style>

<div class="badge-container">
${rows}
</div>
`,
config
);

const container = page.locator('.badge-container');

// Fits the viewport to the content so nothing renders outside it
const box = await container.boundingBox();
await page.setViewportSize({ width: Math.ceil(box!.width) + 200, height: Math.ceil(box!.height) + 32 });

await expect(container).toHaveScreenshot(screenshot(`button-badge-no-position`));
});
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions core/src/themes/ionic/default.tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,15 @@ export const defaultTheme: DefaultTheme = {
},
},
},

badge: {
margin: {
top: 'var(--ion-spacing-0)',
end: 'var(--ion-spacing-0)',
bottom: 'var(--ion-spacing-0)',
start: 'var(--ion-spacing-sm)',
},
},
},

medium: {
Expand Down Expand Up @@ -778,6 +787,15 @@ export const defaultTheme: DefaultTheme = {
},
},
},

badge: {
margin: {
top: 'var(--ion-spacing-0)',
end: 'var(--ion-spacing-0)',
bottom: 'var(--ion-spacing-0)',
start: 'var(--ion-spacing-250)',
},
},
},

large: {
Expand Down Expand Up @@ -887,6 +905,15 @@ export const defaultTheme: DefaultTheme = {
},
},
},

badge: {
margin: {
top: 'var(--ion-spacing-0)',
end: 'var(--ion-spacing-0)',
bottom: 'var(--ion-spacing-0)',
start: 'var(--ion-spacing-md)',
},
},
},
},

Expand Down
27 changes: 27 additions & 0 deletions core/src/themes/ios/default.tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,15 @@ export const defaultTheme: DefaultTheme = {
},
},
},

badge: {
margin: {
top: '0',
end: '0',
bottom: '0',
start: 'var(--ion-spacing-xxs)',
},
},
},

medium: {
Expand Down Expand Up @@ -725,6 +734,15 @@ export const defaultTheme: DefaultTheme = {
},
},
},

badge: {
margin: {
top: '0',
end: '0',
bottom: '0',
start: 'var(--ion-spacing-xxs)',
},
},
},

large: {
Expand Down Expand Up @@ -815,6 +833,15 @@ export const defaultTheme: DefaultTheme = {
},
},
},

badge: {
margin: {
top: '0',
end: '0',
bottom: '0',
start: 'var(--ion-spacing-xxs)',
},
},
},
},

Expand Down
27 changes: 27 additions & 0 deletions core/src/themes/md/default.tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,15 @@ export const defaultTheme: DefaultTheme = {
},
},
},

badge: {
margin: {
top: '0',
end: '0',
bottom: '0',
start: 'var(--ion-spacing-sm)',
},
},
},

medium: {
Expand Down Expand Up @@ -786,6 +795,15 @@ export const defaultTheme: DefaultTheme = {
},
},
},

badge: {
margin: {
top: '0',
end: '0',
bottom: '0',
start: 'var(--ion-spacing-sm)',
},
},
},

large: {
Expand Down Expand Up @@ -874,6 +892,15 @@ export const defaultTheme: DefaultTheme = {
},
},
},

badge: {
margin: {
top: '0',
end: '0',
bottom: '0',
start: 'var(--ion-spacing-md)',
},
},
},
},

Expand Down
Loading