@rdlabo/ionic-theme-ios26 1.0.5 → 1.1.0

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 (65) hide show
  1. package/README.md +35 -1
  2. package/dist/css/components/ion-action-sheet.css +1 -1
  3. package/dist/css/components/ion-alert.css +1 -1
  4. package/dist/css/components/ion-button.css +1 -1
  5. package/dist/css/components/ion-datetime.css +1 -1
  6. package/dist/css/components/ion-fab.css +1 -1
  7. package/dist/css/components/ion-loading.css +1 -1
  8. package/dist/css/components/ion-modal.css +1 -1
  9. package/dist/css/components/ion-popover.css +1 -1
  10. package/dist/css/components/ion-range.css +1 -1
  11. package/dist/css/components/ion-searchbar.css +1 -1
  12. package/dist/css/components/ion-segment.css +1 -1
  13. package/dist/css/components/ion-tabs.css +1 -1
  14. package/dist/css/components/ion-toast.css +1 -1
  15. package/dist/css/components/ion-toggle.css +1 -1
  16. package/dist/css/components/ion-toolbar.css +1 -1
  17. package/dist/css/ionic-theme-ios26-dark-always.css +1 -1
  18. package/dist/css/ionic-theme-ios26-dark-class.css +1 -1
  19. package/dist/css/ionic-theme-ios26-dark-system.css +1 -1
  20. package/dist/css/ionic-theme-ios26.css +1 -1
  21. package/dist/index.d.ts +4 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +4 -2
  24. package/dist/popover/animations/ios.enter.d.ts +4 -0
  25. package/dist/popover/animations/ios.enter.d.ts.map +1 -0
  26. package/dist/popover/animations/ios.enter.js +111 -0
  27. package/dist/popover/animations/ios.leave.d.ts +3 -0
  28. package/dist/popover/animations/ios.leave.d.ts.map +1 -0
  29. package/dist/popover/animations/ios.leave.js +60 -0
  30. package/dist/popover/popover-interface.d.ts +38 -0
  31. package/dist/popover/popover-interface.d.ts.map +1 -0
  32. package/dist/popover/popover-interface.js +1 -0
  33. package/dist/popover/utils.d.ts +48 -0
  34. package/dist/popover/utils.d.ts.map +1 -0
  35. package/dist/popover/utils.js +479 -0
  36. package/dist/sheets-of-glass/animations.d.ts +8 -0
  37. package/dist/sheets-of-glass/animations.d.ts.map +1 -0
  38. package/dist/sheets-of-glass/animations.js +97 -0
  39. package/dist/sheets-of-glass/index.d.ts +3 -0
  40. package/dist/sheets-of-glass/index.d.ts.map +1 -0
  41. package/dist/sheets-of-glass/index.js +160 -0
  42. package/dist/sheets-of-glass/interfaces.d.ts +16 -0
  43. package/dist/sheets-of-glass/interfaces.d.ts.map +1 -0
  44. package/dist/sheets-of-glass/interfaces.js +1 -0
  45. package/dist/utils.d.ts +5 -1
  46. package/dist/utils.d.ts.map +1 -1
  47. package/dist/utils.js +26 -11
  48. package/package.json +1 -1
  49. package/src/index.ts +5 -3
  50. package/src/popover/animations/ios.enter.ts +176 -0
  51. package/src/popover/animations/ios.leave.ts +76 -0
  52. package/src/popover/popover-interface.ts +44 -0
  53. package/src/popover/utils.ts +912 -0
  54. package/src/{gestures → sheets-of-glass}/animations.ts +1 -1
  55. package/src/{gestures → sheets-of-glass}/index.ts +1 -1
  56. package/src/styles/components/ion-alert.scss +1 -0
  57. package/src/styles/components/ion-button.scss +29 -8
  58. package/src/styles/components/ion-popover.scss +6 -0
  59. package/src/styles/components/ion-range.scss +2 -1
  60. package/src/styles/components/ion-segment.scss +22 -7
  61. package/src/styles/components/ion-tabs.scss +9 -2
  62. package/src/styles/components/ion-toggle.scss +8 -4
  63. package/src/styles/utils/api.scss +12 -0
  64. package/src/{gestures/utils.ts → utils.ts} +18 -1
  65. /package/src/{gestures → sheets-of-glass}/interfaces.ts +0 -0
@@ -1,7 +1,7 @@
1
1
  import { Animation, AnimationKeyFrames } from '@ionic/core/dist/types/utils/animation/animation-interface';
2
2
  import { AnimationPosition, EffectScales } from './interfaces';
3
3
  import { createAnimation, GestureDetail } from '@ionic/core';
4
- import { getStep } from './utils';
4
+ import { getStep } from '../utils';
5
5
 
6
6
  export const getScaleAnimation = (effectElement: Element): Animation => {
7
7
  return createAnimation().addElement(effectElement.shadowRoot!.querySelector<HTMLElement>('[part="native"]')!).easing('ease-out');
@@ -2,7 +2,7 @@ import { AnimationPosition, EffectScales, registeredEffect } from './interfaces'
2
2
  import { createAnimation, createGesture, GestureDetail } from '@ionic/core';
3
3
  import type { Animation } from '@ionic/core/dist/types/utils/animation/animation-interface';
4
4
  import { Gesture } from '@ionic/core/dist/types/utils/gesture';
5
- import { changeSelectedElement, cloneElement, getStep } from './utils';
5
+ import { changeSelectedElement, cloneElement, getStep } from '../utils';
6
6
  import { createMoveAnimation, createPreMoveAnimation, getMoveAnimationKeyframe, getScaleAnimation } from './animations';
7
7
 
8
8
  const GESTURE_NAME = 'ios26-enable-gesture';
@@ -1,6 +1,7 @@
1
1
  @use '../utils/api';
2
2
 
3
3
  ion-alert.ios:not(.ios26-disabled) {
4
+ --min-width: 280px;
4
5
  --backdrop-opacity: 0.2;
5
6
 
6
7
  // --max-width: clamp(270px, 16.875rem, 324px);
@@ -28,23 +28,30 @@ $scaleup-large-icon-only: 1.22;
28
28
  z-index: 5;
29
29
  @include api.glass-background-button-activated;
30
30
 
31
- transform: scale($scaleup-default-icon-only);
31
+ // Hardware acceleration optimization for scale transforms
32
+ transform: scale($scaleup-default-icon-only) translateZ(0);
33
+ -webkit-transform: scale($scaleup-default-icon-only) translateZ(0);
32
34
  &:has(:not(.button-has-icon-only):not(.back-button-has-icon-only)),
33
35
  &:has(ion-button:nth-child(n + 2)) {
34
- transform: scale($scaleup-default);
36
+ transform: scale($scaleup-default) translateZ(0);
37
+ -webkit-transform: scale($scaleup-default) translateZ(0);
35
38
  }
36
39
  &:has(.button-small) {
37
- transform: scale($scaleup-small-icon-only);
40
+ transform: scale($scaleup-small-icon-only) translateZ(0);
41
+ -webkit-transform: scale($scaleup-small-icon-only) translateZ(0);
38
42
  &:has(:not(.button-has-icon-only):not(.back-button-has-icon-only)),
39
43
  &:has(ion-button:nth-child(n + 2)) {
40
- transform: scale($scaleup-small);
44
+ transform: scale($scaleup-small) translateZ(0);
45
+ -webkit-transform: scale($scaleup-small) translateZ(0);
41
46
  }
42
47
  }
43
48
  &:has(.button-large) {
44
- transform: scale($scaleup-large-icon-only);
49
+ transform: scale($scaleup-large-icon-only) translateZ(0);
50
+ -webkit-transform: scale($scaleup-large-icon-only) translateZ(0);
45
51
  &:has(:not(.button-has-icon-only):not(.back-button-has-icon-only)),
46
52
  &:has(ion-button:nth-child(n + 2)) {
47
- transform: scale($scaleup-large);
53
+ transform: scale($scaleup-large) translateZ(0);
54
+ -webkit-transform: scale($scaleup-large) translateZ(0);
48
55
  }
49
56
  }
50
57
  }
@@ -135,7 +142,17 @@ $scaleup-large-icon-only: 1.22;
135
142
  transition:
136
143
  transform var(--ios26-activated-transition-duration) ease-out,
137
144
  color 50ms ease;
138
- will-change: transform;
145
+
146
+ // will-change is optimized to only apply when needed for performance
147
+ &:not(.ios26-disabled):hover,
148
+ &:not(.ios26-disabled):active,
149
+ &:not(.ios26-disabled).ion-activated {
150
+ will-change: transform;
151
+ }
152
+
153
+ &:not(.ios26-disabled):not(:hover):not(:active):not(.ion-activated) {
154
+ will-change: auto;
155
+ }
139
156
 
140
157
  // button size default
141
158
  &:not(.button-small):not(.button-large) {
@@ -166,7 +183,8 @@ $scaleup-large-icon-only: 1.22;
166
183
  /*
167
184
  * fill=solid && type=submit button has edge brightness.
168
185
  */
169
- &.button-solid[type='submit'] {
186
+ &.button-solid[type='submit'],
187
+ &.button-solid.button-submit {
170
188
  /*
171
189
  * If not set ion-color-**, button color set primary.
172
190
  * https://github.com/ionic-team/ionic-framework/blob/main/core/src/components/button/button.scss#L78-L81
@@ -174,6 +192,9 @@ $scaleup-large-icon-only: 1.22;
174
192
  --color: var(--ion-color-primary-brightness, var(--ion-color-contrast));
175
193
  --color-activated: var(--ion-color-primary-brightness);
176
194
  --border-color: var(--ion-color-primary-brightness, transparent);
195
+ --background-activated: var(--ion-color-primary-shade, #004acd);
196
+ --background-focused: var(--ion-color-primary-shade, #004acd);
197
+ --background-hover: var(--ion-color-primary-tint, #1a65eb);
177
198
  --border-width: 0.5px;
178
199
  --border-style: solid;
179
200
 
@@ -18,6 +18,12 @@ ion-popover.ios:not(.ios26-disabled) {
18
18
  background: transparent;
19
19
  ion-item {
20
20
  --background: transparent;
21
+ &:last-of-type {
22
+ --border-width: 0px;
23
+ --show-full-highlight: 0;
24
+ --inner-border-width: 0px;
25
+ --show-inset-highlight: 0;
26
+ }
21
27
  }
22
28
  }
23
29
  }
@@ -22,7 +22,8 @@ ion-range.ios:not(.ios26-disabled) {
22
22
  transition: transform 300ms ease;
23
23
  }
24
24
  &.range-pressed::part(knob) {
25
- transform: scale(1.4, 1.6) translateX(calc(38px * -0.1));
25
+ transform: scale(1.4, 1.6) translateX(calc(38px * -0.1)) translateZ(0);
26
+ -webkit-transform: scale(1.4, 1.6) translateX(calc(38px * -0.1)) translateZ(0);
26
27
  @include api.glass-background(0.1, 0.5px, 120%);
27
28
  box-shadow:
28
29
  inset 0 8px 8px -8px var(--bar-background),
@@ -19,7 +19,16 @@ ion-segment.ios:not(.ios26-disabled) {
19
19
  }
20
20
 
21
21
  transition: transform var(--ios26-activated-transition-duration) ease-out;
22
- will-change: transform;
22
+
23
+ // will-change is optimized to only apply when needed for performance
24
+ &:has(ion-segment-button.ion-activated),
25
+ &:has(ion-segment-button.segment-activated) {
26
+ will-change: transform;
27
+ }
28
+
29
+ &:not(:has(ion-segment-button.ion-activated)):not(:has(ion-segment-button.segment-activated)) {
30
+ will-change: auto;
31
+ }
23
32
 
24
33
  &.in-toolbar-color:not(.in-segment-color) {
25
34
  ion-segment-button:not(.segment-button-checked)::part(native) {
@@ -28,17 +37,20 @@ ion-segment.ios:not(.ios26-disabled) {
28
37
  }
29
38
 
30
39
  &:not(.ios26-enable-gesture).segment-activated {
31
- transform: scale(1.1);
40
+ transform: scale(1.1) translateZ(0);
41
+ -webkit-transform: scale(1.1) translateZ(0);
32
42
  ion-segment-button {
33
43
  transition: transform 100ms ease-out;
34
44
  &.segment-button-checked::part(native) {
35
- transform: scale(1.08);
45
+ transform: scale(1.08) translateZ(0);
46
+ -webkit-transform: scale(1.08) translateZ(0);
36
47
  }
37
48
  &::part(indicator-background) {
38
49
  position: relative;
39
50
  z-index: 1;
40
51
  background: rgba(var(--ion-text-color-rgb, 0, 0, 0), 0);
41
- transform: scale(1.1);
52
+ transform: scale(1.1) translateZ(0);
53
+ -webkit-transform: scale(1.1) translateZ(0);
42
54
  transform-origin: center center;
43
55
  }
44
56
  }
@@ -46,16 +58,19 @@ ion-segment.ios:not(.ios26-disabled) {
46
58
 
47
59
  &.ios26-enable-gesture {
48
60
  &:has(ion-segment-button.ion-activated) {
49
- transform: scale(1.1);
61
+ transform: scale(1.1) translateZ(0);
62
+ -webkit-transform: scale(1.1) translateZ(0);
50
63
  ion-segment-button {
51
64
  transition: transform 100ms ease-out;
52
65
  &.segment-button-checked::part(native) {
53
- transform: scale(1.08);
66
+ transform: scale(1.08) translateZ(0);
67
+ -webkit-transform: scale(1.08) translateZ(0);
54
68
  }
55
69
  &::part(indicator-background) {
56
70
  position: relative;
57
71
  z-index: 1;
58
- transform: scale(1.1);
72
+ transform: scale(1.1) translateZ(0);
73
+ -webkit-transform: scale(1.1) translateZ(0);
59
74
  transform-origin: center center;
60
75
  }
61
76
  }
@@ -32,9 +32,16 @@ ion-tab-bar.ios:not(.ios26-disabled) {
32
32
  padding: 2px 2px;
33
33
 
34
34
  transition: transform var(--ios26-activated-transition-duration) ease-out;
35
- will-change: transform;
35
+
36
+ // will-change is optimized to only apply when needed for performance
36
37
  &:has(ion-tab-button.ion-activated) {
37
- transform: scale(1.038);
38
+ will-change: transform;
39
+ transform: scale(1.038) translateZ(0);
40
+ -webkit-transform: scale(1.038) translateZ(0);
41
+ }
42
+
43
+ &:not(:has(ion-tab-button.ion-activated)) {
44
+ will-change: auto;
38
45
  }
39
46
 
40
47
  &:has(ion-tab-button.ion-activated) {
@@ -7,10 +7,12 @@
7
7
  ion-item.ios:not(.ios26-disabled) ion-toggle.ios:not(.ios26-disabled) {
8
8
  &.toggle-checked.toggle-activated::part(track) {
9
9
  transform-origin: left;
10
- transform: scaleX(0.894);
10
+ transform: scaleX(0.894) translateZ(0);
11
+ -webkit-transform: scaleX(0.894) translateZ(0);
11
12
  }
12
13
  &.toggle-activated::part(handle) {
13
- transform: scale(1.4, 1.6) translateX(calc(38px * -0.15));
14
+ transform: scale(1.4, 1.6) translateX(calc(38px * -0.15)) translateZ(0);
15
+ -webkit-transform: scale(1.4, 1.6) translateX(calc(38px * -0.15)) translateZ(0);
14
16
  }
15
17
  }
16
18
 
@@ -27,10 +29,12 @@ ion-toggle.ios:not(.ios26-disabled) {
27
29
  transition: transform 280ms ease;
28
30
  }
29
31
  &.toggle-activated:not(.toggle-checked)::part(handle) {
30
- transform: translateX(-4px) scale(1.4, 1.6);
32
+ transform: translateX(-4px) scale(1.4, 1.6) translateZ(0);
33
+ -webkit-transform: translateX(-4px) scale(1.4, 1.6) translateZ(0);
31
34
  }
32
35
  &.toggle-activated::part(handle) {
33
- transform: scale(1.4, 1.6);
36
+ transform: scale(1.4, 1.6) translateZ(0);
37
+ -webkit-transform: scale(1.4, 1.6) translateZ(0);
34
38
  @include api.glass-background(0.1, 0.5px, 120%);
35
39
  transition:
36
40
  transform 280ms,
@@ -8,6 +8,12 @@
8
8
  border-right: 0.5px solid rgba(var(--ios26-glass-border-color-rgb), 0.8);
9
9
  border-bottom: 0.5px solid rgba(var(--ios26-glass-border-color-rgb), 1);
10
10
  border-left: 0.5px solid rgba(var(--ios26-glass-border-color-rgb), 0.6);
11
+
12
+ // Hardware acceleration optimization for glass effects
13
+ transform: translateZ(0);
14
+ -webkit-transform: translateZ(0);
15
+ -webkit-backface-visibility: hidden;
16
+ backface-visibility: hidden;
11
17
  }
12
18
 
13
19
  @mixin glass-background-button-activated {
@@ -24,6 +30,12 @@
24
30
  border-right: 0.8px solid rgba(var(--ios26-button-color-selected-rgb), 0.4);
25
31
  border-bottom: 0.8px solid rgba(var(--ios26-button-color-selected-rgb), 0.8);
26
32
  border-left: 0.8px solid rgba(var(--ios26-button-color-selected-rgb), 0.6);
33
+
34
+ // Hardware acceleration optimization for glass effects
35
+ transform: translateZ(0);
36
+ -webkit-transform: translateZ(0);
37
+ -webkit-backface-visibility: hidden;
38
+ backface-visibility: hidden;
27
39
  }
28
40
 
29
41
  @mixin glass-background-overlay {
@@ -1,4 +1,21 @@
1
- import { AnimationPosition } from './interfaces';
1
+ import { AnimationPosition } from './sheets-of-glass/interfaces';
2
+
3
+ declare const __zone_symbol__requestAnimationFrame: any;
4
+ declare const requestAnimationFrame: any;
5
+
6
+ export const getElementRoot = (el: HTMLElement, fallback: HTMLElement = el) => {
7
+ return el.shadowRoot || fallback;
8
+ };
9
+
10
+ export const raf = (h: FrameRequestCallback) => {
11
+ if (typeof __zone_symbol__requestAnimationFrame === 'function') {
12
+ return __zone_symbol__requestAnimationFrame(h);
13
+ }
14
+ if (typeof requestAnimationFrame === 'function') {
15
+ return requestAnimationFrame(h);
16
+ }
17
+ return setTimeout(h);
18
+ };
2
19
 
3
20
  export const cloneElement = (tagName: string): HTMLElement => {
4
21
  const getCachedEl = document.querySelector(`${tagName}.ion-cloned-element`);
File without changes