Skip to content
Closed
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
1 change: 1 addition & 0 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ ion-button,prop,expand,"block" | "full" | undefined,undefined,false,true
ion-button,prop,fill,"clear" | "default" | "outline" | "solid" | undefined,undefined,false,true
ion-button,prop,form,HTMLFormElement | string | undefined,undefined,false,false
ion-button,prop,href,string | undefined,undefined,false,false
ion-button,prop,hue,"bold" | "subtle" | undefined,'bold',false,false
ion-button,prop,mode,"ios" | "md",undefined,false,false
ion-button,prop,rel,string | undefined,undefined,false,false
ion-button,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
Expand Down
8 changes: 8 additions & 0 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,10 @@ export namespace Components {
* Contains a URL or a URL fragment that the hyperlink points to. If this property is set, an anchor tag will be rendered.
*/
"href": string | undefined;
/**
* Set to `"bold"` for a button with vibrant, bold colors or to `"subtle"` for a button with muted, subtle colors.
*/
"hue"?: 'bold' | 'subtle';
/**
* The mode determines the platform behaviors of the component.
*/
Expand Down Expand Up @@ -6019,6 +6023,10 @@ declare namespace LocalJSX {
* Contains a URL or a URL fragment that the hyperlink points to. If this property is set, an anchor tag will be rendered.
*/
"href"?: string | undefined;
/**
* Set to `"bold"` for a button with vibrant, bold colors or to `"subtle"` for a button with muted, subtle colors.
*/
"hue"?: 'bold' | 'subtle';
/**
* The mode determines the platform behaviors of the component.
*/
Expand Down
19 changes: 19 additions & 0 deletions core/src/components/button/button.ionic.scss
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@
--ripple-color: var(--background-activated);
}

:host(.button-solid.button-subtle) {
--background: #{globals.ion-color(primary, base, $subtle: true)};
--background-activated: #{globals.ion-color(primary, shade, $subtle: true)};
--color: #{globals.ion-color(primary, contrast, $subtle: true)};
}

// Outline Button
// --------------------------------------------------

Expand Down Expand Up @@ -81,6 +87,19 @@
// Ripple Effect
// -------------------------------------------------------------------------------

:host(.button-solid.button-subtle.ion-color) .button-native {
background: globals.current-color(base, $subtle: true);
color: globals.current-color(contrast, $subtle: true);
}

:host(.button-solid.button-subtle.ion-color.ion-activated) .button-native::after {
background: globals.current-color(shade, $subtle: true);
}

:host(.button-solid.button-subtle.ion-color.ion-focused) .button-native::after {
background: globals.current-color(tint, $subtle: true);
}

:host(.button-solid.ion-color) ion-ripple-effect {
color: globals.current-color(shade);
}
Expand Down
23 changes: 21 additions & 2 deletions core/src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
*/
@Prop({ reflect: true }) expand?: 'full' | 'block';

/**
* Set to `"bold"` for a button with vibrant, bold colors or to `"subtle"` for
* a button with muted, subtle colors.
*/
@Prop() hue?: 'bold' | 'subtle' = 'bold';

/**
* Set to `"clear"` for a transparent button that resembles a flat button, to `"outline"`
* for a transparent button with a border, or to `"solid"` for a button with a filled background.
Expand Down Expand Up @@ -349,8 +355,20 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
};

render() {
const { buttonType, type, disabled, rel, target, href, color, expand, hasIconOnly, strong, inheritedAttributes } =
this;
const {
buttonType,
type,
disabled,
rel,
target,
href,
color,
expand,
hue,
hasIconOnly,
strong,
inheritedAttributes,
} = this;

const theme = getIonTheme(this);
const mode = getIonMode(this);
Expand Down Expand Up @@ -394,6 +412,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
[theme]: true,
[buttonType]: true,
[`${buttonType}-${expand}`]: expand !== undefined,
[`${buttonType}-${hue}`]: hue !== undefined,
[`${buttonType}-${size}`]: size !== undefined,
[`${buttonType}-${shape}`]: true,
[`${buttonType}-${fill}`]: true,
Expand Down
241 changes: 140 additions & 101 deletions core/src/components/button/test/basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>

<style>
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
}

ion-button {
margin: 8px 4px;
}
</style>
</head>

<body>
Expand All @@ -23,108 +34,136 @@
</ion-header>

<ion-content class="ion-padding ion-text-center" id="content" no-bounce>
<p>
<ion-button id="default">Default</ion-button>
<ion-button class="ion-focused">Default.focused</ion-button>
<ion-button class="ion-activated">Default.activated</ion-button>
</p>

<p>
<ion-button color="primary">Primary</ion-button>
<ion-button class="ion-focused" color="primary">Primary.focused</ion-button>
<ion-button class="ion-activated" color="primary">Primary.activated</ion-button>
</p>

<p>
<ion-button color="secondary">Secondary</ion-button>
<ion-button class="ion-focused" color="secondary">Secondary.focused</ion-button>
<ion-button class="ion-activated" color="secondary">Secondary.activated</ion-button>
</p>

<p>
<ion-button color="tertiary">Tertiary</ion-button>
<ion-button class="ion-focused" color="tertiary">Tertiary.focused</ion-button>
<ion-button class="ion-activated" color="tertiary">Tertiary.activated</ion-button>
</p>

<p>
<ion-button color="success">Success</ion-button>
<ion-button class="ion-focused" color="success">Success.focused</ion-button>
<ion-button class="ion-activated" color="success">Success.activated</ion-button>
</p>

<p>
<ion-button color="warning">Warning</ion-button>
<ion-button class="ion-focused" color="warning">Warning.focused</ion-button>
<ion-button class="ion-activated" color="warning">Warning.activated</ion-button>
</p>

<p>
<ion-button color="danger">Danger</ion-button>
<ion-button class="ion-focused" color="danger">Danger.focused</ion-button>
<ion-button class="ion-activated" color="danger">Danger.activated</ion-button>
</p>

<p>
<ion-button color="light">Light</ion-button>
<ion-button class="ion-focused" color="light">Light.focused</ion-button>
<ion-button class="ion-activated" color="light">Light.activated</ion-button>
</p>

<p>
<ion-button color="medium">Medium</ion-button>
<ion-button class="ion-focused" color="medium">Medium.focused</ion-button>
<ion-button class="ion-activated" color="medium">Medium.activated</ion-button>
</p>

<p>
<ion-button color="dark">Dark</ion-button>
<ion-button class="ion-focused" color="dark">Dark.focused</ion-button>
<ion-button class="ion-activated" color="dark">Dark.activated</ion-button>
</p>

<p>
<ion-button style="--opacity: 0.2">Opacity: 0.2</ion-button>
</p>

<p>
<ion-button expand="block" id="disabledButton" disabled>Button Disabled</ion-button>
<ion-button expand="block" color="secondary" disabled>Secondary Disabled</ion-button>
<ion-button expand="block" color="tertiary" style="--opacity: 1" disabled>Disabled opacity: 1</ion-button>
</p>

<p>
<ion-button expand="block" onclick="toggleDisabled()">Toggle Disabled</ion-button>
</p>

<p>
<ion-button id="dynamicColor1" onclick="changeColor(event)">Change Color</ion-button>
<ion-button id="dynamicColor2" onclick="changeColor(event)" fill="outline">Change Color</ion-button>
</p>
<div class="container">
<div class="item">
<h2>Bold (default) Buttons</h2>

<p>
<ion-button id="default">Default</ion-button>
<ion-button class="ion-focused">Default.focused</ion-button>
<ion-button class="ion-activated">Default.activated</ion-button>
</p>

<p>
<ion-button color="primary">Primary</ion-button>
<ion-button class="ion-focused" color="primary">Primary.focused</ion-button>
<ion-button class="ion-activated" color="primary">Primary.activated</ion-button>
</p>

<p>
<ion-button color="secondary">Secondary</ion-button>
<ion-button class="ion-focused" color="secondary">Secondary.focused</ion-button>
<ion-button class="ion-activated" color="secondary">Secondary.activated</ion-button>
</p>

<p>
<ion-button color="tertiary">Tertiary</ion-button>
<ion-button class="ion-focused" color="tertiary">Tertiary.focused</ion-button>
<ion-button class="ion-activated" color="tertiary">Tertiary.activated</ion-button>
</p>

<p>
<ion-button color="success">Success</ion-button>
<ion-button class="ion-focused" color="success">Success.focused</ion-button>
<ion-button class="ion-activated" color="success">Success.activated</ion-button>
</p>

<p>
<ion-button color="warning">Warning</ion-button>
<ion-button class="ion-focused" color="warning">Warning.focused</ion-button>
<ion-button class="ion-activated" color="warning">Warning.activated</ion-button>
</p>

<p>
<ion-button color="danger">Danger</ion-button>
<ion-button class="ion-focused" color="danger">Danger.focused</ion-button>
<ion-button class="ion-activated" color="danger">Danger.activated</ion-button>
</p>

<p>
<ion-button color="light">Light</ion-button>
<ion-button class="ion-focused" color="light">Light.focused</ion-button>
<ion-button class="ion-activated" color="light">Light.activated</ion-button>
</p>

<p>
<ion-button color="medium">Medium</ion-button>
<ion-button class="ion-focused" color="medium">Medium.focused</ion-button>
<ion-button class="ion-activated" color="medium">Medium.activated</ion-button>
</p>

<p>
<ion-button color="dark">Dark</ion-button>
<ion-button class="ion-focused" color="dark">Dark.focused</ion-button>
<ion-button class="ion-activated" color="dark">Dark.activated</ion-button>
</p>
</div>

<div class="item">
<h2>Subtle Buttons</h2>

<p>
<ion-button hue="subtle" id="default">Default</ion-button>
<ion-button hue="subtle" class="ion-focused">Default.focused</ion-button>
<ion-button hue="subtle" class="ion-activated">Default.activated</ion-button>
</p>

<p>
<ion-button hue="subtle" color="primary">Primary</ion-button>
<ion-button hue="subtle" color="primary" class="ion-focused">Primary.focused</ion-button>
<ion-button hue="subtle" color="primary" class="ion-activated">Primary.activated</ion-button>
</p>

<p>
<ion-button hue="subtle" color="secondary">Secondary</ion-button>
<ion-button hue="subtle" class="ion-focused" color="secondary">Secondary.focused</ion-button>
<ion-button hue="subtle" class="ion-activated" color="secondary">Secondary.activated</ion-button>
</p>

<p>
<ion-button hue="subtle" color="tertiary">Tertiary</ion-button>
<ion-button hue="subtle" class="ion-focused" color="tertiary">Tertiary.focused</ion-button>
<ion-button hue="subtle" class="ion-activated" color="tertiary">Tertiary.activated</ion-button>
</p>

<p>
<ion-button hue="subtle" color="success">Success</ion-button>
<ion-button hue="subtle" color="success" class="ion-focused">Success.focused</ion-button>
<ion-button hue="subtle" color="success" class="ion-activated">Success.activated</ion-button>
</p>

<p>
<ion-button hue="subtle" color="warning">Warning</ion-button>
<ion-button hue="subtle" color="warning" class="ion-focused">Warning.focused</ion-button>
<ion-button hue="subtle" color="warning" class="ion-activated">Warning.activated</ion-button>
</p>

<p>
<ion-button hue="subtle" color="danger">Danger</ion-button>
<ion-button hue="subtle" color="danger" class="ion-focused">Danger.focused</ion-button>
<ion-button hue="subtle" color="danger" class="ion-activated">Danger.activated</ion-button>
</p>

<p>
<ion-button hue="subtle" color="light">Light</ion-button>
<ion-button hue="subtle" color="light" class="ion-focused">Light.focused</ion-button>
<ion-button hue="subtle" color="light" class="ion-activated">Light.activated</ion-button>
</p>

<p>
<ion-button hue="subtle" color="medium">Medium</ion-button>
<ion-button hue="subtle" color="medium" class="ion-focused">Medium.focused</ion-button>
<ion-button hue="subtle" color="medium" class="ion-activated">Medium.activated</ion-button>
</p>

<p>
<ion-button hue="subtle" color="dark">Dark</ion-button>
<ion-button hue="subtle" color="dark" class="ion-focused">Dark.focused</ion-button>
<ion-button hue="subtle" color="dark" class="ion-activated">Dark.activated</ion-button>
</p>
</div>
</div>
</ion-content>
</ion-app>

<script>
testingColors = ['primary', 'secondary', 'danger', 'dark'];
testingColorIndex = {
dynamicColor1: 0,
dynamicColor2: 0,
};

function changeColor(ev) {
el = ev.currentTarget;

testingColorIndex[el.id] =
testingColorIndex[el.id] >= testingColors.length - 1 ? 0 : testingColorIndex[el.id] + 1;
newColor = testingColors[testingColorIndex[el.id]];

el.color = newColor;
}

function toggleDisabled() {
var buttonEl = document.getElementById('disabledButton');
buttonEl.disabled = !buttonEl.disabled;
}
</script>
</body>
</html>
4 changes: 2 additions & 2 deletions packages/angular/src/directives/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,14 +345,14 @@ export declare interface IonBreadcrumbs extends Components.IonBreadcrumbs {


@ProxyCmp({
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type']
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'hue', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type']
})
@Component({
selector: 'ion-button',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'],
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'hue', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'],
})
export class IonButton {
protected el: HTMLIonButtonElement;
Expand Down
4 changes: 2 additions & 2 deletions packages/angular/standalone/src/directives/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,14 +440,14 @@ export declare interface IonBreadcrumbs extends Components.IonBreadcrumbs {

@ProxyCmp({
defineCustomElementFn: defineIonButton,
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type']
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'hue', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type']
})
@Component({
selector: 'ion-button',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'],
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'hue', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'],
standalone: true
})
export class IonButton {
Expand Down
Loading
Loading