Skip to content

Commit 154a681

Browse files
committed
feat(button): add circular shape as round
1 parent 7821b78 commit 154a681

File tree

6 files changed

+252
-53
lines changed

6 files changed

+252
-53
lines changed

core/src/components/button/button.ios.scss

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,6 @@
114114
font-size: #{$button-ios-small-font-size};
115115
}
116116

117-
:host(.button-has-icon-only) {
118-
--padding-top: 0;
119-
--padding-bottom: 0;
120-
}
121-
122117

123118
// iOS Round Button
124119
// --------------------------------------------------
@@ -131,14 +126,44 @@
131126
--padding-bottom: #{$button-ios-round-padding-bottom};
132127
}
133128

134-
135129
// iOS Strong Button
136130
// --------------------------------------------------
137131

138132
:host(.button-strong) {
139133
font-weight: #{$button-ios-strong-font-weight};
140134
}
141135

136+
// iOS Icon Only Button
137+
//
138+
// These styles must be after the .button-round styles
139+
// in order to take priority. The styles are not applied
140+
// only when the .button-round class exists because the
141+
// size changes will also improve the look of the Rectangular
142+
// and Soft buttons containing only an icon.
143+
// --------------------------------------------------
144+
145+
::slotted(ion-icon[slot="icon-only"]) {
146+
font-size: 1.1em;
147+
}
148+
149+
:host(.button-has-icon-only) {
150+
--padding-top: 0;
151+
--padding-bottom: var(--padding-top);
152+
--padding-end: 15px;
153+
--padding-start: var(--padding-end);
154+
}
155+
156+
:host(.button-small.button-has-icon-only) {
157+
--padding-end: 6px;
158+
}
159+
160+
:host(.button-small) ::slotted(ion-icon[slot="icon-only"]) {
161+
font-size: 1.2em;
162+
}
163+
164+
:host(.button-large.button-has-icon-only) {
165+
--padding-end: 19px;
166+
}
142167

143168
// iOS Button Focused
144169
// --------------------------------------------------

core/src/components/button/button.md.scss

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,23 +113,42 @@
113113
font-size: #{$button-md-small-font-size};
114114
}
115115

116-
:host(.button-has-icon-only) {
117-
--padding-top: 0;
118-
--padding-bottom: 0;
119-
}
120-
121-
122116
// MD strong Button
123117
// --------------------------------------------------
124118

125119
:host(.button-strong) {
126120
font-weight: #{$button-md-strong-font-weight};
127121
}
128122

123+
// MD Icon Only Button
124+
//
125+
// These styles must be after the .button-round styles
126+
// in order to take priority. The styles are not applied
127+
// only when the .button-round class exists because the
128+
// size changes will also improve the look of the Rectangular
129+
// and Soft buttons containing only an icon.
130+
// --------------------------------------------------
131+
129132
::slotted(ion-icon[slot="icon-only"]) {
130133
@include padding(0);
134+
135+
font-size: 1.4em;
131136
}
132137

138+
:host(.button-has-icon-only) {
139+
--padding-top: 0;
140+
--padding-bottom: var(--padding-top);
141+
--padding-end: 8px;
142+
--padding-start: var(--padding-end);
143+
}
144+
145+
:host(.button-small.button-has-icon-only) {
146+
--padding-end: 4px;
147+
}
148+
149+
:host(.button-large.button-has-icon-only) {
150+
--padding-end: 14px;
151+
}
133152

134153
// Material Design Button: Hover
135154
// --------------------------------------------------

core/src/components/button/button.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { ComponentInterface, EventEmitter } from '@stencil/core';
2-
import { Component, Element, Event, Host, Prop, Watch, h } from '@stencil/core';
2+
import { Component, Element, Event, Host, Prop, Watch, State, h } from '@stencil/core';
33
import type { AnchorInterface, ButtonInterface } from '@utils/element-interface';
44
import type { Attributes } from '@utils/helpers';
55
import { inheritAriaAttributes, hasShadowDom } from '@utils/helpers';
@@ -38,6 +38,12 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
3838

3939
@Element() el!: HTMLElement;
4040

41+
/**
42+
* Tracks whether the button is a full
43+
* circle shape.
44+
*/
45+
@State() isCircle: boolean = false;
46+
4147
/**
4248
* The color to use from your application's color palette.
4349
* Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
@@ -295,6 +301,10 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
295301
this.ionBlur.emit();
296302
};
297303

304+
private slotChanged = () => {
305+
this.isCircle = this.hasIconOnly;
306+
};
307+
298308
render() {
299309
const mode = getIonMode(this);
300310
const {
@@ -374,7 +384,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
374384
{...inheritedAttributes}
375385
>
376386
<span class="button-inner">
377-
<slot name="icon-only"></slot>
387+
<slot name="icon-only" onSlotchange={this.slotChanged}></slot>
378388
<slot name="start"></slot>
379389
<slot></slot>
380390
<slot name="end"></slot>

core/src/components/button/button.vars.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ $button-round-padding-bottom: $button-round-padding-top !default;
1616
$button-round-padding-start: $button-round-padding-end !default;
1717

1818
/// @prop - Border radius of the round button
19-
$button-round-border-radius: 64px !default;
19+
$button-round-border-radius: 999px !default;

core/src/components/button/test/round/button.e2e.ts

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,64 @@ import { configs, test } from '@utils/test/playwright';
66
*/
77
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
88
test.describe(title('button: round'), () => {
9-
test('should not have visual regressions', async ({ page }) => {
10-
await page.goto(`/src/components/button/test/round`, config);
9+
test.describe('default', () => {
10+
test('should not have visual regressions', async ({ page }) => {
11+
await page.goto(`/src/components/button/test/round`, config);
1112

12-
await page.setIonViewport();
13+
await page.setIonViewport();
1314

14-
await expect(page).toHaveScreenshot(screenshot(`button-round`));
15+
const container = page.locator('#default');
16+
17+
await expect(container).toHaveScreenshot(screenshot(`button-round`));
18+
});
19+
});
20+
21+
test.describe('outline', () => {
22+
test('should not have visual regressions', async ({ page }) => {
23+
await page.goto(`/src/components/button/test/round`, config);
24+
25+
await page.setIonViewport();
26+
27+
const container = page.locator('#outline');
28+
29+
await expect(container).toHaveScreenshot(screenshot(`button-outline-round`));
30+
});
31+
});
32+
33+
test.describe('clear', () => {
34+
test('should not have visual regressions', async ({ page }) => {
35+
await page.goto(`/src/components/button/test/round`, config);
36+
37+
await page.setIonViewport();
38+
39+
const container = page.locator('#clear');
40+
41+
await expect(container).toHaveScreenshot(screenshot(`button-clear-round`));
42+
});
43+
});
44+
45+
test.describe('color', () => {
46+
test('should not have visual regressions', async ({ page }) => {
47+
await page.goto(`/src/components/button/test/round`, config);
48+
49+
await page.setIonViewport();
50+
51+
const container = page.locator('#color');
52+
53+
await expect(container).toHaveScreenshot(screenshot(`button-color-round`));
54+
});
55+
});
56+
57+
test.describe('expand', () => {
58+
test('should not have visual regressions', async ({ page }) => {
59+
await page.goto(`/src/components/button/test/round`, config);
60+
61+
await page.setIonViewport();
62+
63+
const container = page.locator('#expand');
64+
65+
await expect(container).toHaveScreenshot(screenshot(`button-expand-round`));
66+
});
1567
});
1668
});
1769
});

0 commit comments

Comments
 (0)