@ionic/core 8.2.3-dev.11724345963.10ca6051 → 8.2.3-dev.11724680612.1b9ef92a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/components/ion-input-password-toggle.js +11 -7
  2. package/components/ion-input.js +14 -5
  3. package/components/ion-textarea.js +15 -5
  4. package/components/ion-toggle.js +14 -11
  5. package/css/core.css +1 -1
  6. package/css/core.css.map +1 -1
  7. package/css/ionic/bundle.ionic.css +1 -1
  8. package/css/ionic/bundle.ionic.css.map +1 -1
  9. package/css/ionic/core.ionic.css +1 -1
  10. package/css/ionic/core.ionic.css.map +1 -1
  11. package/css/ionic/global.bundle.ionic.css.map +1 -1
  12. package/css/ionic/typography.ionic.css.map +1 -1
  13. package/css/ionic.bundle.css +1 -1
  14. package/css/ionic.bundle.css.map +1 -1
  15. package/dist/cjs/ion-input-password-toggle.cjs.entry.js +11 -7
  16. package/dist/cjs/ion-input.cjs.entry.js +14 -5
  17. package/dist/cjs/ion-textarea.cjs.entry.js +15 -5
  18. package/dist/cjs/ion-toggle.cjs.entry.js +14 -11
  19. package/dist/collection/components/input/input.js +14 -5
  20. package/dist/collection/components/input-password-toggle/input-password-toggle.common.css +61 -0
  21. package/dist/collection/components/input-password-toggle/input-password-toggle.ionic.css +137 -0
  22. package/dist/collection/components/input-password-toggle/input-password-toggle.js +9 -7
  23. package/dist/collection/components/input-password-toggle/test/basic/input-password-toggle.e2e.js +1 -1
  24. package/dist/collection/components/textarea/test/shape/textarea.e2e.js +79 -0
  25. package/dist/collection/components/textarea/textarea.ionic.css +12 -1
  26. package/dist/collection/components/textarea/textarea.js +17 -7
  27. package/dist/collection/components/toggle/test/color/toggle.e2e.js +1 -1
  28. package/dist/collection/components/toggle/test/enable-on-off-labels/toggle.e2e.js +1 -1
  29. package/dist/collection/components/toggle/test/item/toggle.e2e.js +4 -2
  30. package/dist/collection/components/toggle/test/label/toggle.e2e.js +29 -0
  31. package/dist/collection/components/toggle/test/sizes/toggle.e2e.js +1 -1
  32. package/dist/collection/components/toggle/test/states/toggle.e2e.js +29 -1
  33. package/dist/collection/components/toggle/toggle.ionic.css +391 -0
  34. package/dist/collection/components/toggle/toggle.ios.css +163 -138
  35. package/dist/collection/components/toggle/toggle.js +12 -9
  36. package/dist/collection/components/toggle/toggle.md.css +163 -138
  37. package/dist/docs.json +13 -5
  38. package/dist/esm/ion-input-password-toggle.entry.js +11 -7
  39. package/dist/esm/ion-input.entry.js +14 -5
  40. package/dist/esm/ion-textarea.entry.js +15 -5
  41. package/dist/esm/ion-toggle.entry.js +14 -11
  42. package/dist/esm-es5/ion-input-password-toggle.entry.js +1 -1
  43. package/dist/esm-es5/ion-input.entry.js +1 -1
  44. package/dist/esm-es5/ion-textarea.entry.js +1 -1
  45. package/dist/esm-es5/ion-toggle.entry.js +1 -1
  46. package/dist/html.html-data.json +7 -1
  47. package/dist/ionic/ionic.esm.js +1 -1
  48. package/dist/ionic/p-13c363e4.entry.js +4 -0
  49. package/dist/ionic/p-22711da4.system.entry.js +4 -0
  50. package/dist/ionic/p-33dd8047.system.entry.js +4 -0
  51. package/dist/ionic/p-3d9c39bc.entry.js +4 -0
  52. package/dist/ionic/p-7b590e46.system.js +1 -1
  53. package/dist/ionic/p-aad91b75.system.entry.js +4 -0
  54. package/dist/ionic/{p-201d8768.system.entry.js → p-c2c3807b.system.entry.js} +1 -1
  55. package/dist/ionic/p-c8453a83.entry.js +4 -0
  56. package/dist/ionic/p-de8e8567.entry.js +4 -0
  57. package/dist/types/components/input/input.d.ts +1 -0
  58. package/dist/types/components/textarea/textarea.d.ts +7 -2
  59. package/dist/types/components.d.ts +4 -4
  60. package/hydrate/index.js +54 -28
  61. package/package.json +1 -1
  62. package/dist/collection/components/input-password-toggle/input-password-toggle.css +0 -0
  63. package/dist/ionic/p-1ee206ac.entry.js +0 -4
  64. package/dist/ionic/p-3a2eb448.system.entry.js +0 -4
  65. package/dist/ionic/p-6691825a.system.entry.js +0 -4
  66. package/dist/ionic/p-7a1b640f.entry.js +0 -4
  67. package/dist/ionic/p-8102551e.system.entry.js +0 -4
  68. package/dist/ionic/p-924deb6b.entry.js +0 -4
  69. package/dist/ionic/p-a6bb62ea.entry.js +0 -4
@@ -275,6 +275,15 @@ export class Textarea {
275
275
  get hasLabel() {
276
276
  return this.label !== undefined || this.labelSlot !== null;
277
277
  }
278
+ getShape() {
279
+ const theme = getIonTheme(this);
280
+ const { shape } = this;
281
+ // TODO(ROU-11050): Update theme check when shapes are defined for all themes.
282
+ if (theme === 'ionic' && shape === undefined) {
283
+ return 'round';
284
+ }
285
+ return shape;
286
+ }
278
287
  /**
279
288
  * Renders the border container when fill="outline".
280
289
  */
@@ -336,8 +345,9 @@ export class Textarea {
336
345
  return (h("div", { class: "textarea-bottom" }, this.renderHintText(), this.renderCounter()));
337
346
  }
338
347
  render() {
339
- const { inputId, disabled, fill, shape, size, labelPlacement, el, hasFocus } = this;
348
+ const { inputId, disabled, fill, size, labelPlacement, el, hasFocus } = this;
340
349
  const theme = getIonTheme(this);
350
+ const shape = this.getShape();
341
351
  const value = this.getValue();
342
352
  const inItem = hostContext('ion-item', this.el);
343
353
  const shouldRenderHighlight = theme === 'md' && fill !== 'outline' && !inItem;
@@ -361,7 +371,7 @@ export class Textarea {
361
371
  * TODO(FW-5592): Remove hasStartEndSlots condition
362
372
  */
363
373
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
364
- return (h(Host, { key: '0f80c3af71da1262718eabb385478447a4d04bce', class: createColorClasses(this.color, {
374
+ return (h(Host, { key: '25f8192436c242c227cdcec236dc376a6ad4331d', class: createColorClasses(this.color, {
365
375
  [theme]: true,
366
376
  'has-value': hasValue,
367
377
  'has-focus': hasFocus,
@@ -371,7 +381,7 @@ export class Textarea {
371
381
  [`textarea-size-${size}`]: true,
372
382
  [`textarea-label-placement-${labelPlacement}`]: true,
373
383
  'textarea-disabled': disabled,
374
- }) }, h("label", { key: 'd20e202c8dbbf26e4a734b856294256bdf18ef94', class: "textarea-wrapper", htmlFor: inputId }, this.renderLabelContainer(), h("div", { key: 'c54e1d41af4a4c9e5c954a829061fb9ecd2eab15', class: "textarea-wrapper-inner" },
384
+ }) }, h("label", { key: 'cd1a80101c9cc5c1123005e9e3bfe1ff06e9a5d8', class: "textarea-wrapper", htmlFor: inputId }, this.renderLabelContainer(), h("div", { key: '68dffe868cdf170f0eab38e912a97c2374c82aaa', class: "textarea-wrapper-inner" },
375
385
  /**
376
386
  * For the ionic theme, we render the outline container here
377
387
  * instead of higher up, so it can be positioned relative to
@@ -381,7 +391,7 @@ export class Textarea {
381
391
  * <label> element, ensuring that clicking the label text
382
392
  * focuses the textarea.
383
393
  */
384
- theme === 'ionic' && fill === 'outline' && h("div", { key: '148f16138dcbfd8a724d248b4e1f73220b017fd4', class: "textarea-outline" }), h("div", { key: 'b5550e1ad2af3af871b6e9d05c040a5ee009f1da', class: "start-slot-wrapper" }, h("slot", { key: 'ce6d54e769b9de5afb43f432c1194a1a80d8124d', name: "start" })), h("div", { key: '80de31c0139de21273ecc381c9d99bbfebed188a', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, h("textarea", Object.assign({ key: '4a3174126f2979ce3fa873c42c313ff83a5f71de', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown }, this.inheritedAttributes), value)), h("div", { key: '5d6e196c46f9af1360b89a3d355ecf434df47657', class: "end-slot-wrapper" }, h("slot", { key: '4109293cca9ccca19a81428ea5149107ebb00359', name: "end" }))), shouldRenderHighlight && h("div", { key: '18063161e67aa882dc2262626fd435352192d6c3', class: "textarea-highlight" })), this.renderBottomContent()));
394
+ theme === 'ionic' && fill === 'outline' && h("div", { key: 'eafeed172c5deafd3e28e8dbc8339b9ab3d06298', class: "textarea-outline" }), h("div", { key: 'dae967e2619efd99e40db41dfde375d162a772a4', class: "start-slot-wrapper" }, h("slot", { key: '4d5d48dcd842bec3effbab43fdcbbca137f01237', name: "start" })), h("div", { key: 'd3b11f95a4b76dd13363ed67279bd09be8776b71', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, h("textarea", Object.assign({ key: 'e86bd3b607b29b67ebcdbfa0b2e73417df786e1d', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown }, this.inheritedAttributes), value)), h("div", { key: 'ac0788d419f7b74d6a4f35cbd8e7ae78412380a6', class: "end-slot-wrapper" }, h("slot", { key: 'b409e7f30418b2e70f4dcb43f184be9032591089', name: "end" }))), shouldRenderHighlight && h("div", { key: '35f5928604c3a35962d08e99d4eeeedebb53a470', class: "textarea-highlight" })), this.renderBottomContent()));
385
395
  }
386
396
  static get is() { return "ion-textarea"; }
387
397
  static get encapsulation() { return "scoped"; }
@@ -880,15 +890,15 @@ export class Textarea {
880
890
  "type": "string",
881
891
  "mutable": false,
882
892
  "complexType": {
883
- "original": "'round'",
884
- "resolved": "\"round\" | undefined",
893
+ "original": "'soft' | 'round' | 'rectangular'",
894
+ "resolved": "\"rectangular\" | \"round\" | \"soft\" | undefined",
885
895
  "references": {}
886
896
  },
887
897
  "required": false,
888
898
  "optional": true,
889
899
  "docs": {
890
900
  "tags": [],
891
- "text": "The shape of the textarea. If \"round\" it will have an increased border radius."
901
+ "text": "Set to `\"soft\"` for a textarea with slightly rounded corners,\n`\"round\"` for a textarea with fully rounded corners, or `\"rectangular\"`\nfor a textarea without rounded corners.\n\nDefaults to `\"round\"` for the `ionic` theme, undefined for all other themes."
892
902
  },
893
903
  "attribute": "shape",
894
904
  "reflect": false
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { expect } from "@playwright/test";
5
5
  import { configs, test } from "../../../../utils/test/playwright/index";
6
- configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
6
+ configs({ directions: ['ltr'], modes: ['ios', 'md', 'ionic-md'] }).forEach(({ title, screenshot, config }) => {
7
7
  test.describe(title('toggle: color'), () => {
8
8
  test('should apply color when checked', async ({ page }) => {
9
9
  await page.setContent(`
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { expect } from "@playwright/test";
5
5
  import { configs, test } from "../../../../utils/test/playwright/index";
6
- configs({ palettes: ['light', 'dark'] }).forEach(({ title, screenshot, config }) => {
6
+ configs({ palettes: ['light', 'dark'], modes: ['ios', 'md', 'ionic-md'] }).forEach(({ title, screenshot, config }) => {
7
7
  test.describe(title('toggle: enable-on-off-labels'), () => {
8
8
  test('should not have visual regressions', async ({ page }) => {
9
9
  await page.setContent(`
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { expect } from "@playwright/test";
5
5
  import { configs, test } from "../../../../utils/test/playwright/index";
6
- configs().forEach(({ title, screenshot, config }) => {
6
+ configs({ modes: ['ios', 'md', 'ionic-md'] }).forEach(({ title, screenshot, config }) => {
7
7
  test.describe(title('toggle: item'), () => {
8
8
  test('should render correctly in list', async ({ page }) => {
9
9
  await page.setContent(`
@@ -29,7 +29,7 @@ configs().forEach(({ title, screenshot, config }) => {
29
29
  });
30
30
  });
31
31
  });
32
- configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
32
+ configs({ directions: ['ltr'], modes: ['ios', 'md', 'ionic-md'] }).forEach(({ title, screenshot, config }) => {
33
33
  test.describe(title('toggle: item color contrast'), () => {
34
34
  test('label should have correct contrast when used in an item', async ({ page }) => {
35
35
  await page.setContent(`
@@ -73,6 +73,8 @@ configs({ directions: ['ltr'], modes: ['md'] }).forEach(({ title, screenshot, co
73
73
  await expect(list).toHaveScreenshot(screenshot(`toggle-stacked-label-in-item`));
74
74
  });
75
75
  });
76
+ });
77
+ configs({ directions: ['ltr'], modes: ['ios', 'md', 'ionic-md'] }).forEach(({ title, config }) => {
76
78
  test.describe(title('toggle: ionChange'), () => {
77
79
  test('clicking padded space within item should click the toggle', async ({ page }) => {
78
80
  await page.setContent(`
@@ -118,3 +118,32 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config, screen
118
118
  });
119
119
  });
120
120
  });
121
+ configs({ modes: ['ionic-md'] }).forEach(({ title, screenshot, config }) => {
122
+ test.describe(title('toggle: start placement'), () => {
123
+ test('should render the label in the start position', async ({ page }) => {
124
+ await page.setContent(`
125
+ <ion-toggle label-placement="start">Label</ion-toggle>
126
+ `, config);
127
+ const toggle = page.locator('ion-toggle');
128
+ await expect(toggle).toHaveScreenshot(screenshot(`toggle-label-start`));
129
+ });
130
+ });
131
+ test.describe(title('toggle: end placement'), () => {
132
+ test('should render the label in the end position', async ({ page }) => {
133
+ await page.setContent(`
134
+ <ion-toggle label-placement="end">Label</ion-toggle>
135
+ `, config);
136
+ const toggle = page.locator('ion-toggle');
137
+ await expect(toggle).toHaveScreenshot(screenshot(`toggle-label-end`));
138
+ });
139
+ });
140
+ test.describe(title('toggle: start long label'), () => {
141
+ test('long label should truncate', async ({ page }) => {
142
+ await page.setContent(`
143
+ <ion-toggle label-placement="start">Enable Notifications Enable Notifications Enable Notifications Enable Notifications Enable Notifications Enable Notifications Enable Notifications</ion-toggle>
144
+ `, config);
145
+ const toggle = page.locator('ion-toggle');
146
+ await expect(toggle).toHaveScreenshot(screenshot(`toggle-label-start-long-label`));
147
+ });
148
+ });
149
+ });
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { expect } from "@playwright/test";
5
5
  import { configs, test } from "../../../../utils/test/playwright/index";
6
- configs().forEach(({ title, screenshot, config }) => {
6
+ configs({ modes: ['ios', 'md', 'ionic-md'] }).forEach(({ title, screenshot, config }) => {
7
7
  test.describe(title('toggle: sizes'), () => {
8
8
  test('should not have visual regressions', async ({ page }) => {
9
9
  await page.goto(`/src/components/toggle/test/sizes`, config);
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { expect } from "@playwright/test";
5
5
  import { configs, test } from "../../../../utils/test/playwright/index";
6
- configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
6
+ configs({ directions: ['ltr'], modes: ['ios', 'md', 'ionic-md'] }).forEach(({ title, screenshot, config }) => {
7
7
  test.describe(title('toggle: states'), () => {
8
8
  test('should render disabled toggle correctly', async ({ page }) => {
9
9
  await page.setContent(`
@@ -28,3 +28,31 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
28
28
  });
29
29
  });
30
30
  });
31
+ /**
32
+ * Focused and Pressed states are only available in the Ionic theme
33
+ */
34
+ configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ title, screenshot, config }) => {
35
+ test.describe(title('toggle: states'), () => {
36
+ test('should render focused toggle correctly', async ({ page }) => {
37
+ await page.setContent(`
38
+ <ion-toggle class="ion-focused">Label</ion-toggle>
39
+ `, config);
40
+ const toggle = page.locator('ion-toggle');
41
+ await expect(toggle).toHaveScreenshot(screenshot(`toggle-focused`));
42
+ });
43
+ test('should render pressed unchecked toggle correctly', async ({ page }) => {
44
+ await page.setContent(`
45
+ <ion-toggle class="ion-activated">Label</ion-toggle>
46
+ `, config);
47
+ const toggle = page.locator('ion-toggle');
48
+ await expect(toggle).toHaveScreenshot(screenshot(`toggle-unchecked-pressed`));
49
+ });
50
+ test('should render pressed checked toggle correctly', async ({ page }) => {
51
+ await page.setContent(`
52
+ <ion-toggle class="ion-activated" checked>Label</ion-toggle>
53
+ `, config);
54
+ const toggle = page.locator('ion-toggle');
55
+ await expect(toggle).toHaveScreenshot(screenshot(`toggle-checked-pressed`));
56
+ });
57
+ });
58
+ });
@@ -0,0 +1,391 @@
1
+ /**
2
+ * Convert a pixels given value into rem
3
+ *
4
+ * @param pixels - Value in pixels to be converted (i.e. px)
5
+ * @param context (optional) - Baseline value
6
+ */
7
+ /**
8
+ * This is an auto-generated file, please do not change it directly.
9
+ * Ionic Design System
10
+ */
11
+ /**
12
+ * A heuristic that applies CSS to tablet
13
+ * viewports.
14
+ *
15
+ * Usage:
16
+ * @include tablet-viewport() {
17
+ * :host {
18
+ * background-color: green;
19
+ * }
20
+ * }
21
+ */
22
+ /**
23
+ * A heuristic that applies CSS to mobile
24
+ * viewports (i.e. phones, not tablets).
25
+ *
26
+ * Usage:
27
+ * @include mobile-viewport() {
28
+ * :host {
29
+ * background-color: blue;
30
+ * }
31
+ * }
32
+ */
33
+ /**
34
+ * Convert a font size to a dynamic font size.
35
+ * Fonts that participate in Dynamic Type should use
36
+ * dynamic font sizes.
37
+ * @param size - The initial font size including the unit (i.e. px or pt)
38
+ * @param unit (optional) - The unit to convert to. Use this if you want to
39
+ * convert to a unit other than $baselineUnit.
40
+ */
41
+ /**
42
+ * Convert a font size to a dynamic font size but impose
43
+ * a maximum font size.
44
+ * @param size - The initial font size including the unit (i.e. px or pt)
45
+ * @param maxScale - The maximum scale of the font (i.e. 2.5 for a maximum 250% scale).
46
+ * @param unit (optional) - The unit to convert the initial font size to. Use this if you want to
47
+ * convert to a unit other than $baselineUnit.
48
+ */
49
+ /**
50
+ * Convert a font size to a dynamic font size but impose
51
+ * a minimum font size.
52
+ * @param size - The initial font size including the unit (i.e. px or pt)
53
+ * @param minScale - The minimum scale of the font (i.e. 0.8 for a minimum 80% scale).
54
+ * @param unit (optional) - The unit to convert the initial font size to. Use this if you want to
55
+ * convert to a unit other than $baselineUnit.
56
+ */
57
+ /**
58
+ * Convert a font size to a dynamic font size but impose
59
+ * maximum and minimum font sizes.
60
+ * @param size - The initial font size including the unit (i.e. px or pt)
61
+ * @param minScale - The minimum scale of the font (i.e. 0.8 for a minimum 80% scale).
62
+ * @param maxScale - The maximum scale of the font (i.e. 2.5 for a maximum 250% scale).
63
+ * @param unit (optional) - The unit to convert the initial font size to. Use this if you want to
64
+ * convert to a unit other than $baselineUnit.
65
+ */
66
+ /**
67
+ * A heuristic that applies CSS to tablet
68
+ * viewports.
69
+ *
70
+ * Usage:
71
+ * @include tablet-viewport() {
72
+ * :host {
73
+ * background-color: green;
74
+ * }
75
+ * }
76
+ */
77
+ /**
78
+ * A heuristic that applies CSS to mobile
79
+ * viewports (i.e. phones, not tablets).
80
+ *
81
+ * Usage:
82
+ * @include mobile-viewport() {
83
+ * :host {
84
+ * background-color: blue;
85
+ * }
86
+ * }
87
+ */
88
+ :host {
89
+ /**
90
+ * @prop --track-background: Background of the toggle track
91
+ * @prop --track-background-checked: Background of the toggle track when checked
92
+ * @prop --border-radius: Border radius of the toggle track
93
+ *
94
+ * @prop --handle-background: Background of the toggle handle
95
+ * @prop --handle-background-checked: Background of the toggle handle when checked
96
+ *
97
+ * @prop --handle-border-radius: Border radius of the toggle handle
98
+ * @prop --handle-box-shadow: Box shadow of the toggle handle
99
+ * @prop --handle-height: Height of the toggle handle
100
+ * @prop --handle-max-height: Maximum height of the toggle handle
101
+ * @prop --handle-width: Width of the toggle handle
102
+ * @prop --handle-spacing: Horizontal spacing around the toggle handle
103
+ * @prop --handle-transition: Transition of the toggle handle
104
+ */
105
+ /* stylelint-disable-next-line declaration-no-important */
106
+ box-sizing: content-box !important;
107
+ display: inline-block;
108
+ position: relative;
109
+ max-width: 100%;
110
+ outline: none;
111
+ cursor: pointer;
112
+ user-select: none;
113
+ }
114
+
115
+ :host(.in-item) {
116
+ flex: 1 1 0;
117
+ width: 100%;
118
+ height: 100%;
119
+ }
120
+
121
+ /**
122
+ * Toggle can be slotted
123
+ * in components such as item and
124
+ * toolbar which is why we do not
125
+ * limit the below behavior to just ion-item.
126
+ */
127
+ :host([slot=start]),
128
+ :host([slot=end]) {
129
+ flex: initial;
130
+ width: auto;
131
+ }
132
+
133
+ :host(.ion-focused) input {
134
+ border: 2px solid #5e9ed6;
135
+ }
136
+
137
+ :host(.toggle-disabled) {
138
+ pointer-events: none;
139
+ }
140
+
141
+ input {
142
+ position: absolute;
143
+ top: 0;
144
+ right: 0;
145
+ bottom: 0;
146
+ left: 0;
147
+ width: 100%;
148
+ height: 100%;
149
+ margin: 0;
150
+ padding: 0;
151
+ border: 0;
152
+ outline: 0;
153
+ opacity: 0;
154
+ overflow: hidden;
155
+ clip: rect(0 0 0 0);
156
+ -webkit-appearance: none;
157
+ -moz-appearance: none;
158
+ }
159
+
160
+ .toggle-wrapper {
161
+ display: flex;
162
+ position: relative;
163
+ flex-grow: 1;
164
+ height: inherit;
165
+ transition: background-color 15ms linear;
166
+ cursor: inherit;
167
+ }
168
+
169
+ /**
170
+ * If no label text is placed into the slot
171
+ * then the element should be hidden otherwise
172
+ * there will be additional margins added.
173
+ */
174
+ .label-text-wrapper-hidden {
175
+ display: none;
176
+ }
177
+
178
+ .native-wrapper {
179
+ display: flex;
180
+ align-items: center;
181
+ }
182
+
183
+ /**
184
+ * Label is on the left of the input in LTR and
185
+ * on the right in RTL.
186
+ */
187
+ :host(.toggle-label-placement-start) .toggle-wrapper {
188
+ flex-direction: row;
189
+ }
190
+
191
+ /**
192
+ * Label is on the right of the input in LTR and
193
+ * on the left in RTL.
194
+ */
195
+ :host(.toggle-label-placement-end) .toggle-wrapper {
196
+ flex-direction: row-reverse;
197
+ }
198
+
199
+ .toggle-icon-wrapper {
200
+ display: flex;
201
+ position: relative;
202
+ align-items: center;
203
+ width: 100%;
204
+ height: 100%;
205
+ transition: var(--handle-transition);
206
+ will-change: transform;
207
+ }
208
+
209
+ .toggle-icon {
210
+ border-radius: var(--border-radius);
211
+ display: block;
212
+ position: relative;
213
+ width: 100%;
214
+ height: 100%;
215
+ background: var(--track-background);
216
+ overflow: inherit;
217
+ }
218
+
219
+ :host(.toggle-checked) .toggle-icon {
220
+ background: var(--track-background-checked);
221
+ }
222
+
223
+ .toggle-inner {
224
+ border-radius: var(--handle-border-radius);
225
+ position: absolute;
226
+ left: var(--handle-spacing);
227
+ width: var(--handle-width);
228
+ height: var(--handle-height);
229
+ max-height: var(--handle-max-height);
230
+ transition: var(--handle-transition);
231
+ background: var(--handle-background);
232
+ box-shadow: var(--handle-box-shadow);
233
+ contain: strict;
234
+ }
235
+
236
+ /**
237
+ * We do not use the @ltr and @rtl mixins
238
+ * here because ion-toggle uses the Shadow DOM
239
+ * and WebKit does not support :host-context.
240
+ */
241
+ :host(.toggle-ltr) .toggle-inner {
242
+ left: var(--handle-spacing);
243
+ }
244
+
245
+ :host(.toggle-rtl) .toggle-inner {
246
+ right: var(--handle-spacing);
247
+ }
248
+
249
+ :host(.toggle-ltr.toggle-checked) .toggle-icon-wrapper {
250
+ transform: translate3d(calc(100% - var(--handle-width)), 0, 0);
251
+ }
252
+
253
+ :host(.toggle-rtl.toggle-checked) .toggle-icon-wrapper {
254
+ transform: translate3d(calc(-100% + var(--handle-width)), 0, 0);
255
+ }
256
+
257
+ :host(.toggle-checked) .toggle-inner {
258
+ background: var(--handle-background-checked);
259
+ }
260
+
261
+ :host(.toggle-ltr.toggle-checked) .toggle-inner {
262
+ transform: translate3d(calc(var(--handle-spacing) * -2), 0, 0);
263
+ }
264
+
265
+ :host(.toggle-rtl.toggle-checked) .toggle-inner {
266
+ transform: translate3d(calc(var(--handle-spacing) * 2), 0, 0);
267
+ }
268
+
269
+ :host {
270
+ --track-background: var(--ionic-color-neutral-800, #626262);
271
+ --track-background-checked: var(--ion-color-primary, #105cef);
272
+ --border-radius: var(--ionic-border-radius-full, 999px);
273
+ --focus-ring-color: var(--ionic-state-focus-1, #9ec4fd);
274
+ --focus-ring-width: var(--ionic-border-size-050, 2px);
275
+ --handle-background: var(--ionic-color-base-white, #ffffff);
276
+ --handle-background-checked: var(--ionic-color-base-white, #ffffff);
277
+ --handle-border-radius: var(--ionic-border-radius-full, 999px);
278
+ --handle-height: var(--ionic-scale-500, 20px);
279
+ --handle-max-height: var(--ionic-scale-500, 20px);
280
+ --handle-width: var(--ionic-scale-500, 20px);
281
+ --handle-spacing: var(--ionic-space-050, 2px);
282
+ --handle-transition: transform 300ms, width 120ms ease-in-out 80ms, left 110ms ease-in-out 80ms,
283
+ right 110ms ease-in-out 80ms;
284
+ font-size: var(--ionic-font-size-350, 0.875rem);
285
+ font-weight: var(--ionic-font-weight-regular, 400);
286
+ letter-spacing: var(--ionic-letter-spacing-0, 0);
287
+ line-height: var(--ionic-line-height-600, 24px);
288
+ text-decoration: none;
289
+ text-transform: none;
290
+ width: 100%;
291
+ z-index: 2;
292
+ }
293
+
294
+ .toggle-wrapper {
295
+ align-items: center;
296
+ min-height: var(--ionic-scale-1200, 48px);
297
+ }
298
+
299
+ .native-wrapper .toggle-icon {
300
+ width: var(--ionic-scale-1100, 44px);
301
+ height: var(--ionic-scale-600, 24px);
302
+ /**
303
+ * The handle box shadow should not
304
+ * overflow outside of the track container.
305
+ */
306
+ overflow: hidden;
307
+ }
308
+
309
+ :host(.ion-color.toggle-checked) .toggle-icon {
310
+ background: var(--ion-color-base);
311
+ }
312
+
313
+ :host(.ion-focused) .toggle-icon {
314
+ outline: var(--focus-ring-width) var(--ionic-border-style-solid, solid) var(--focus-ring-color);
315
+ outline-offset: var(--focus-ring-width);
316
+ }
317
+
318
+ :host(.ion-activated) .toggle-icon::after {
319
+ right: 0;
320
+ left: 0;
321
+ top: 0;
322
+ bottom: 0;
323
+ position: absolute;
324
+ background-color: var(--ionic-state-pressed, rgba(36, 36, 36, 0.08));
325
+ content: "";
326
+ }
327
+
328
+ :host(.toggle-disabled) .toggle-icon::after {
329
+ right: 0;
330
+ left: 0;
331
+ top: 0;
332
+ bottom: 0;
333
+ position: absolute;
334
+ background-color: var(--ionic-state-disabled, rgba(255, 255, 255, 0.6));
335
+ content: "";
336
+ pointer-events: none;
337
+ }
338
+
339
+ .toggle-inner {
340
+ will-change: background-color, transform;
341
+ display: flex;
342
+ align-items: center;
343
+ justify-content: center;
344
+ color: var(--ionic-color-neutral-1200, #242424);
345
+ }
346
+
347
+ .toggle-inner .toggle-switch-icon {
348
+ width: var(--ionic-scale-400, 16px);
349
+ height: var(--ionic-scale-400, 16px);
350
+ }
351
+
352
+ /**
353
+ * Label is on the left of the input in LTR and
354
+ * on the right in RTL.
355
+ */
356
+ :host .toggle-wrapper {
357
+ justify-content: space-between;
358
+ }
359
+
360
+ :host .label-text-wrapper {
361
+ /**
362
+ * The margin between the label and
363
+ * the input should be on the end
364
+ * when the label sits at the start.
365
+ */
366
+ -webkit-margin-start: 0;
367
+ margin-inline-start: 0;
368
+ -webkit-margin-end: var(--ionic-space-400, 16px);
369
+ margin-inline-end: var(--ionic-space-400, 16px);
370
+ color: var(--ionic-color-neutral-1200, #242424);
371
+ }
372
+
373
+ /**
374
+ * Label is on the right of the input in LTR and
375
+ * on the left in RTL.
376
+ */
377
+ :host(.toggle-label-placement-end) .toggle-wrapper {
378
+ justify-content: start;
379
+ }
380
+
381
+ /**
382
+ * The margin between the label and
383
+ * the input should be on the start
384
+ * when the label sits at the end.
385
+ */
386
+ :host(.toggle-label-placement-end) .label-text-wrapper {
387
+ -webkit-margin-start: var(--ionic-space-400, 16px);
388
+ margin-inline-start: var(--ionic-space-400, 16px);
389
+ -webkit-margin-end: 0;
390
+ margin-inline-end: 0;
391
+ }