Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2068,6 +2068,7 @@ ion-toast,part,wrapper
ion-toggle,shadow
ion-toggle,prop,alignment,"center" | "start" | undefined,undefined,false,false
ion-toggle,prop,checked,boolean,false,false,false
ion-toggle,prop,checkedIcon,null | string | undefined,undefined,false,false
ion-toggle,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-toggle,prop,disabled,boolean,false,false,false
ion-toggle,prop,enableOnOffLabels,boolean | undefined,config.get('toggleOnOffLabels'),false,false
Expand All @@ -2078,6 +2079,7 @@ ion-toggle,prop,labelPlacement,"end" | "fixed" | "stacked" | "start",'start',fal
ion-toggle,prop,mode,"ios" | "md",undefined,false,false
ion-toggle,prop,name,string,this.inputId,false,false
ion-toggle,prop,required,boolean,false,false,false
ion-toggle,prop,uncheckedIcon,null | string | undefined,undefined,false,false
ion-toggle,prop,value,null | string | undefined,'on',false,false
ion-toggle,event,ionBlur,void,true
ion-toggle,event,ionChange,ToggleChangeEventDetail<any>,true
Expand Down
18 changes: 18 additions & 0 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3700,6 +3700,10 @@ export namespace Components {
* @default false
*/
"checked": boolean;
/**
* The built-in named SVG icon name or the exact `src` of an SVG file to use when the toggle is checked.
*/
"checkedIcon"?: string | null;
/**
* The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics).
*/
Expand Down Expand Up @@ -3745,6 +3749,10 @@ export namespace Components {
* @default false
*/
"required": boolean;
/**
* The built-in named SVG icon name or the exact `src` of an SVG file to use when the toggle is unchecked.
*/
"uncheckedIcon"?: string | null;
/**
* The value of the toggle does not mean if it's checked or not, use the `checked` property for that. The value of a toggle is analogous to the value of a `<input type="checkbox">`, it's only used when the toggle participates in a native `<form>`.
* @default 'on'
Expand Down Expand Up @@ -9094,6 +9102,10 @@ declare namespace LocalJSX {
* @default false
*/
"checked"?: boolean;
/**
* The built-in named SVG icon name or the exact `src` of an SVG file to use when the toggle is checked.
*/
"checkedIcon"?: string | null;
/**
* The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics).
*/
Expand Down Expand Up @@ -9151,6 +9163,10 @@ declare namespace LocalJSX {
* @default false
*/
"required"?: boolean;
/**
* The built-in named SVG icon name or the exact `src` of an SVG file to use when the toggle is unchecked.
*/
"uncheckedIcon"?: string | null;
/**
* The value of the toggle does not mean if it's checked or not, use the `checked` property for that. The value of a toggle is analogous to the value of a `<input type="checkbox">`, it's only used when the toggle participates in a native `<form>`.
* @default 'on'
Expand Down Expand Up @@ -9907,6 +9923,8 @@ declare namespace LocalJSX {
"helperText": string;
"value": string | null;
"enableOnOffLabels": boolean | undefined;
"checkedIcon": string | null;
"uncheckedIcon": string | null;
"labelPlacement": 'start' | 'end' | 'fixed' | 'stacked';
"justify": 'start' | 'end' | 'space-between';
"alignment": 'start' | 'center';
Expand Down
6 changes: 5 additions & 1 deletion core/src/components/toggle/test/states/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,18 @@
<div class="grid">
<div class="grid-item">
<h2>Unchecked</h2>
<ion-toggle>Enable Notifications</ion-toggle>
<ion-toggle >Enable Notifications</ion-toggle>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

extra space which would look bad?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

removed

</div>

<div class="grid-item">
<h2>Checked</h2>
<ion-toggle checked="true">Enable Notifications</ion-toggle>
</div>

<ion-toggle enable-on-off-labels="true" checked-icon="heart" unchecked-icon="close" checked="true">Icons Toggle</ion-toggle>



Copy link
Copy Markdown

Choose a reason for hiding this comment

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

extra newlines?

<div class="grid-item">
<h2>Disabled, Unchecked</h2>
<ion-toggle disabled="true">Enable Notifications</ion-toggle>
Expand Down
53 changes: 53 additions & 0 deletions core/src/components/toggle/test/toggle.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { newSpecPage } from '@stencil/core/testing';
import { checkmarkOutline, ellipseOutline, removeOutline } from 'ionicons/icons';

import { config } from '../../../global/config';
import { Toggle } from '../toggle';
Expand Down Expand Up @@ -41,6 +42,58 @@ describe('toggle', () => {
});
});

describe('checkedIcon and uncheckedIcon', () => {
it('should set custom checked icon on the instance, overriding config', async () => {
const t = await newToggle();
t.checkedIcon = 'custom-checked-icon-instance';
config.reset({
toggleCheckedIcon: 'custom-checked-icon-config',
});

expect((t as any).getSwitchLabelIcon('md', true)).toBe('custom-checked-icon-instance');
});

it('should set custom unchecked icon on the instance, overriding config', async () => {
const t = await newToggle();
t.uncheckedIcon = 'custom-unchecked-icon-instance';
config.reset({
toggleUncheckedIcon: 'custom-unchecked-icon-config',
});

expect((t as any).getSwitchLabelIcon('md', false)).toBe('custom-unchecked-icon-instance');
});

it('should set custom checked icon in the config', async () => {
const t = await newToggle();
config.reset({
toggleCheckedIcon: 'custom-checked-icon-config',
});

expect((t as any).getSwitchLabelIcon('md', true)).toBe('custom-checked-icon-config');
});

it('should set custom unchecked icon in the config', async () => {
const t = await newToggle();
config.reset({
toggleUncheckedIcon: 'custom-unchecked-icon-config',
});

expect((t as any).getSwitchLabelIcon('md', false)).toBe('custom-unchecked-icon-config');
});

it('should use default icons in md mode', async () => {
const t = await newToggle();
expect((t as any).getSwitchLabelIcon('md', true)).toBe(checkmarkOutline);
expect((t as any).getSwitchLabelIcon('md', false)).toBe(removeOutline);
});

it('should use default icons in ios mode', async () => {
const t = await newToggle();
expect((t as any).getSwitchLabelIcon('ios', true)).toBe(removeOutline);
expect((t as any).getSwitchLabelIcon('ios', false)).toBe(ellipseOutline);
});
});

describe('shadow parts', () => {
it('should have shadow parts', async () => {
const page = await newSpecPage({
Expand Down
14 changes: 10 additions & 4 deletions core/src/components/toggle/toggle.md.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
--handle-max-height: #{$toggle-md-handle-max-height};
--handle-spacing: 0;
--handle-transition: #{$toggle-md-transition};
--on-off-label-icon-size: 13px;


}

// Toggle Native Wrapper
Expand Down Expand Up @@ -61,10 +64,13 @@
}

.toggle-inner .toggle-switch-icon {
@include padding(1px);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think this should stay.


width: 100%;
height: 100%;
width: var(--on-off-label-icon-size);
height: var(--on-off-label-icon-size);
min-width: var(--on-off-label-icon-size);
min-height: var(--on-off-label-icon-size);
display: block;
opacity: 0.86;
transition: transform $toggle-md-transition-duration, opacity $toggle-md-transition-duration, color $toggle-md-transition-duration;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

was there a reason to include min-{width,height}, display, opacity and transition, though? It should've been already styled as icon support was already there.

}

// Material Design Toggle: Disabled
Expand Down
19 changes: 17 additions & 2 deletions core/src/components/toggle/toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,18 @@ export class Toggle implements ComponentInterface {
*/
@Prop() enableOnOffLabels: boolean | undefined = config.get('toggleOnOffLabels');

/**
* The built-in named SVG icon name or the exact `src` of an SVG file
* to use when the toggle is checked.
*/
@Prop() checkedIcon?: string | null;

/**
* The built-in named SVG icon name or the exact `src` of an SVG file
* to use when the toggle is unchecked.
*/
@Prop() uncheckedIcon?: string | null;

/**
* Where to place the label relative to the input.
* `"start"`: The label will appear to the left of the toggle in LTR and to the right in RTL.
Expand Down Expand Up @@ -348,10 +360,13 @@ export class Toggle implements ComponentInterface {
};

private getSwitchLabelIcon = (mode: Mode, checked: boolean) => {
const checkedIcon = this.checkedIcon ?? config.get('toggleCheckedIcon');
const uncheckedIcon = this.uncheckedIcon ?? config.get('toggleUncheckedIcon');

if (mode === 'md') {
return checked ? checkmarkOutline : removeOutline;
return checked ? checkedIcon ?? checkmarkOutline : uncheckedIcon ?? removeOutline;
}
return checked ? removeOutline : ellipseOutline;
return checked ? checkedIcon ?? removeOutline : uncheckedIcon ?? ellipseOutline;
};

private renderOnOffSwitchLabels(mode: Mode, checked: boolean) {
Expand Down
10 changes: 10 additions & 0 deletions core/src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ export interface IonicConfig {
*/
toggleOnOffLabels?: boolean;

/**
* Overrides the default checked icon in all `<ion-toggle>` components.
*/
toggleCheckedIcon?: string;

/**
* Overrides the default unchecked icon in all `<ion-toggle>` components.
*/
toggleUncheckedIcon?: string;

/**
* Overrides the default spinner for all `ion-loading` overlays, ie. the ones
* created with `ion-loading-controller`.
Expand Down
4 changes: 2 additions & 2 deletions packages/angular/src/directives/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2567,14 +2567,14 @@ Shorthand for ionToastDidDismiss.


@ProxyCmp({
inputs: ['alignment', 'checked', 'color', 'disabled', 'enableOnOffLabels', 'errorText', 'helperText', 'justify', 'labelPlacement', 'mode', 'name', 'required', 'value']
inputs: ['alignment', 'checked', 'checkedIcon', 'color', 'disabled', 'enableOnOffLabels', 'errorText', 'helperText', 'justify', 'labelPlacement', 'mode', 'name', 'required', 'uncheckedIcon', 'value']
})
@Component({
selector: 'ion-toggle',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['alignment', 'checked', 'color', 'disabled', 'enableOnOffLabels', 'errorText', 'helperText', 'justify', 'labelPlacement', 'mode', 'name', 'required', 'value'],
inputs: ['alignment', 'checked', 'checkedIcon', 'color', 'disabled', 'enableOnOffLabels', 'errorText', 'helperText', 'justify', 'labelPlacement', 'mode', 'name', 'required', 'uncheckedIcon', 'value'],
})
export class IonToggle {
protected el: HTMLIonToggleElement;
Expand Down
2 changes: 2 additions & 0 deletions packages/vue/src/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,8 @@ export const IonToggle: StencilVueComponent<JSX.IonToggle, JSX.IonToggle["checke
'helperText',
'value',
'enableOnOffLabels',
'checkedIcon',
'uncheckedIcon',
'labelPlacement',
'justify',
'alignment',
Expand Down