@rdlabo/ionic-theme-ios27 0.1.0 → 0.2.1-beta.pr185.sha0793981f6cf4

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 (148) hide show
  1. package/README.md +34 -8
  2. package/dist/css/components/ion-button.css +1 -1
  3. package/dist/css/components/ion-fab.css +1 -1
  4. package/dist/css/components/ion-list.css +1 -1
  5. package/dist/css/components/ion-menu.css +1 -1
  6. package/dist/css/components/ion-searchbar.css +1 -1
  7. package/dist/css/components/ion-tabs.css +1 -1
  8. package/dist/css/components/ion-toolbar.css +1 -1
  9. package/dist/css/ionic-theme-ios27.css +1 -1
  10. package/dist/css/md-ion-list-inset.css +1 -1
  11. package/dist/css/utils/translucent.css +1 -1
  12. package/dist/index.d.ts +1 -2
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -2
  15. package/dist/native/components/searchable-tabs.d.ts +2 -0
  16. package/dist/native/components/searchable-tabs.d.ts.map +1 -1
  17. package/dist/native/components/searchable-tabs.js +131 -21
  18. package/dist/native/definitions.d.ts +19 -0
  19. package/dist/native/definitions.d.ts.map +1 -1
  20. package/dist/native/index.d.ts +4 -3
  21. package/dist/native/index.d.ts.map +1 -1
  22. package/dist/native/index.js +22 -9
  23. package/dist/native/lifecycle.d.ts +4 -0
  24. package/dist/native/lifecycle.d.ts.map +1 -0
  25. package/dist/native/lifecycle.js +34 -0
  26. package/dist/native/runtime.d.ts +2 -2
  27. package/dist/native/runtime.d.ts.map +1 -1
  28. package/dist/native/runtime.js +57 -11
  29. package/dist/tab-bar-searchable/animations/enter.d.ts +1 -1
  30. package/dist/tab-bar-searchable/animations/enter.d.ts.map +1 -1
  31. package/dist/tab-bar-searchable/animations/enter.js +1 -1
  32. package/dist/tab-bar-searchable/animations/leave.d.ts +1 -1
  33. package/dist/tab-bar-searchable/animations/leave.d.ts.map +1 -1
  34. package/dist/tab-bar-searchable/animations/leave.js +1 -1
  35. package/dist/tab-bar-searchable/index.d.ts +2 -2
  36. package/dist/tab-bar-searchable/index.d.ts.map +1 -1
  37. package/dist/tab-bar-searchable/index.js +2 -3
  38. package/dist/transition/ios.transition.d.ts +6 -1
  39. package/dist/transition/ios.transition.d.ts.map +1 -1
  40. package/dist/transition/ios.transition.js +10 -385
  41. package/docs/features.md +3 -1
  42. package/docs/ios-adaptive.md +20 -21
  43. package/docs/native-ui-shell.md +117 -3
  44. package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellSearchController.swift +243 -64
  45. package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellTabBar.swift +77 -6
  46. package/ios/Sources/IonicNativeUIShellPlugin/IonicNativeUIShellPlugin.swift +106 -11
  47. package/ios/Tests/IonicNativeUIShellPluginTests/ShellSnapshotTests.swift +258 -2
  48. package/node_modules/@rdlabo/ionic-theme-utils/LICENSE +21 -0
  49. package/node_modules/@rdlabo/ionic-theme-utils/README.md +28 -0
  50. package/node_modules/@rdlabo/ionic-theme-utils/dist/dom.d.ts +3 -0
  51. package/node_modules/@rdlabo/ionic-theme-utils/dist/dom.d.ts.map +1 -0
  52. package/node_modules/@rdlabo/ionic-theme-utils/dist/dom.js +13 -0
  53. package/node_modules/@rdlabo/ionic-theme-utils/dist/dom.js.map +1 -0
  54. package/node_modules/@rdlabo/ionic-theme-utils/dist/focus-controller.d.ts +6 -0
  55. package/node_modules/@rdlabo/ionic-theme-utils/dist/focus-controller.d.ts.map +1 -0
  56. package/node_modules/@rdlabo/ionic-theme-utils/dist/focus-controller.js +37 -0
  57. package/node_modules/@rdlabo/ionic-theme-utils/dist/focus-controller.js.map +1 -0
  58. package/node_modules/@rdlabo/ionic-theme-utils/dist/index.d.ts +13 -0
  59. package/node_modules/@rdlabo/ionic-theme-utils/dist/index.d.ts.map +1 -0
  60. package/node_modules/@rdlabo/ionic-theme-utils/dist/index.js +11 -0
  61. package/node_modules/@rdlabo/ionic-theme-utils/dist/index.js.map +1 -0
  62. package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/animations/ios.enter.d.ts +0 -1
  63. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.enter.d.ts.map +1 -0
  64. package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/animations/ios.enter.js +8 -5
  65. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.enter.js.map +1 -0
  66. package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/animations/ios.leave.d.ts.map +1 -1
  67. package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/animations/ios.leave.js +11 -5
  68. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.leave.js.map +1 -0
  69. package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/callout-surface.js +1 -0
  70. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/callout-surface.js.map +1 -0
  71. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/popover-interface.js +2 -0
  72. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/popover-interface.js.map +1 -0
  73. package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/utils.d.ts +1 -0
  74. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/utils.d.ts.map +1 -0
  75. package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/utils.js +3 -2
  76. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/utils.js.map +1 -0
  77. package/node_modules/@rdlabo/ionic-theme-utils/dist/sheets-of-glass.d.ts +16 -0
  78. package/node_modules/@rdlabo/ionic-theme-utils/dist/sheets-of-glass.d.ts.map +1 -0
  79. package/node_modules/@rdlabo/ionic-theme-utils/dist/sheets-of-glass.js +2 -0
  80. package/node_modules/@rdlabo/ionic-theme-utils/dist/sheets-of-glass.js.map +1 -0
  81. package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/tab-bar-searchable/interfaces.js +1 -0
  82. package/node_modules/@rdlabo/ionic-theme-utils/dist/tab-bar-searchable/interfaces.js.map +1 -0
  83. package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/tab-bar-searchable/utils.js +1 -0
  84. package/node_modules/@rdlabo/ionic-theme-utils/dist/tab-bar-searchable/utils.js.map +1 -0
  85. package/node_modules/@rdlabo/ionic-theme-utils/dist/theme.d.ts +15 -0
  86. package/node_modules/@rdlabo/ionic-theme-utils/dist/theme.d.ts.map +1 -0
  87. package/node_modules/@rdlabo/ionic-theme-utils/dist/theme.js +49 -0
  88. package/node_modules/@rdlabo/ionic-theme-utils/dist/theme.js.map +1 -0
  89. package/node_modules/@rdlabo/ionic-theme-utils/dist/transition/ios.transition.d.ts +18 -0
  90. package/node_modules/@rdlabo/ionic-theme-utils/dist/transition/ios.transition.d.ts.map +1 -0
  91. package/node_modules/@rdlabo/ionic-theme-utils/dist/transition/ios.transition.js +412 -0
  92. package/node_modules/@rdlabo/ionic-theme-utils/dist/transition/ios.transition.js.map +1 -0
  93. package/node_modules/@rdlabo/ionic-theme-utils/package.json +64 -0
  94. package/node_modules/@rdlabo/ionic-theme-utils/src/dom.spec.ts +19 -0
  95. package/node_modules/@rdlabo/ionic-theme-utils/src/dom.ts +16 -0
  96. package/node_modules/@rdlabo/ionic-theme-utils/src/focus-controller.ts +38 -0
  97. package/node_modules/@rdlabo/ionic-theme-utils/src/index.ts +59 -0
  98. package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/popover/animations/ios.enter.ts +7 -5
  99. package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/popover/animations/ios.leave.ts +14 -5
  100. package/node_modules/@rdlabo/ionic-theme-utils/src/popover/utils.spec.ts +58 -0
  101. package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/popover/utils.ts +4 -2
  102. package/node_modules/@rdlabo/ionic-theme-utils/src/sheets-of-glass.ts +17 -0
  103. package/node_modules/@rdlabo/ionic-theme-utils/src/styles/index.scss +1 -0
  104. package/node_modules/@rdlabo/ionic-theme-utils/src/styles/md-ion-list-inset.scss +20 -0
  105. package/node_modules/@rdlabo/ionic-theme-utils/src/styles/structured-list.scss +310 -0
  106. package/node_modules/@rdlabo/ionic-theme-utils/src/tab-bar-searchable/utils.spec.ts +56 -0
  107. package/node_modules/@rdlabo/ionic-theme-utils/src/theme.ts +51 -0
  108. package/node_modules/@rdlabo/ionic-theme-utils/src/transition/ios.transition.spec.ts +52 -0
  109. package/node_modules/@rdlabo/ionic-theme-utils/src/transition/ios.transition.ts +542 -0
  110. package/package.json +13 -5
  111. package/src/index.ts +4 -2
  112. package/src/native/components/searchable-tabs.ts +142 -22
  113. package/src/native/definitions.ts +34 -0
  114. package/src/native/index.ts +38 -11
  115. package/src/native/lifecycle.ts +38 -0
  116. package/src/native/runtime.ts +60 -10
  117. package/src/styles/components/ion-button.scss +21 -10
  118. package/src/styles/components/ion-fab.scss +10 -4
  119. package/src/styles/components/ion-list.scss +12 -3
  120. package/src/styles/components/ion-menu.scss +17 -10
  121. package/src/styles/components/ion-searchbar.scss +1 -1
  122. package/src/styles/components/ion-tabs.scss +14 -10
  123. package/src/styles/components/ion-toolbar.scss +9 -10
  124. package/src/styles/md-ion-list-inset.scss +2 -2
  125. package/src/styles/utils/dark/ion-list.scss +1 -1
  126. package/src/styles/utils/translucent.scss +44 -0
  127. package/src/tab-bar-searchable/animations/enter.ts +1 -2
  128. package/src/tab-bar-searchable/animations/leave.ts +1 -2
  129. package/src/tab-bar-searchable/index.ts +12 -4
  130. package/src/transition/ios.transition.ts +14 -473
  131. package/dist/css/utils/structured-list.css +0 -1
  132. package/dist/popover/animations/ios.enter.d.ts.map +0 -1
  133. package/dist/popover/popover-interface.js +0 -1
  134. package/dist/popover/utils.d.ts.map +0 -1
  135. package/src/styles/utils/structured-list.scss +0 -223
  136. /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/animations/ios.leave.d.ts +0 -0
  137. /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/callout-surface.d.ts +0 -0
  138. /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/callout-surface.d.ts.map +0 -0
  139. /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/popover-interface.d.ts +0 -0
  140. /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/popover-interface.d.ts.map +0 -0
  141. /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/tab-bar-searchable/interfaces.d.ts +0 -0
  142. /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/tab-bar-searchable/interfaces.d.ts.map +0 -0
  143. /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/tab-bar-searchable/utils.d.ts +0 -0
  144. /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/tab-bar-searchable/utils.d.ts.map +0 -0
  145. /package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/popover/callout-surface.ts +0 -0
  146. /package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/popover/popover-interface.ts +0 -0
  147. /package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/tab-bar-searchable/interfaces.ts +0 -0
  148. /package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/tab-bar-searchable/utils.ts +0 -0
@@ -13,6 +13,9 @@ $scaleup-default-icon-only: api.$button-scaleup-default-icon-only;
13
13
  $scaleup-large: 1.12;
14
14
  $scaleup-large-icon-only: api.$button-scaleup-large-icon-only;
15
15
 
16
+ // Fit to the iOS 27 glass button's expansion: a small overshoot, settling at 380ms.
17
+ $press-transition: transform var(--ios-theme-button-press-duration, 380ms) cubic-bezier(0.37, 0.36, 0.03, 1.34);
18
+
16
19
  @mixin theme-buttons {
17
20
  @include api.glass-control-background;
18
21
  border-radius: 25px;
@@ -24,14 +27,17 @@ $scaleup-large-icon-only: api.$button-scaleup-large-icon-only;
24
27
  /**
25
28
  * compare .header-collapse-main ion-toolbar.in-toolbar ion-title, .header-collapse-main ion-toolbar.in-toolbar ion-buttons
26
29
  */
27
- transition: transform var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease-out;
30
+ transition: $press-transition;
28
31
 
29
32
  z-index: 0;
30
33
 
31
34
  &:has(.ion-activated) {
32
35
  z-index: 5;
33
36
  @include api.glass-background-button-activated;
37
+ }
34
38
 
39
+ // Follow the actual press so a short tap reverses before reaching full scale.
40
+ &:has(ion-button:active:not(.button-disabled), ion-menu-button:active:not([disabled])) {
35
41
  // Hardware acceleration optimization for scale transforms
36
42
  transform: scale($scaleup-default-icon-only) translateZ(0);
37
43
  -webkit-transform: scale($scaleup-default-icon-only) translateZ(0);
@@ -141,7 +147,7 @@ $scaleup-large-icon-only: api.$button-scaleup-large-icon-only;
141
147
  }
142
148
 
143
149
  transition:
144
- transform var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease-out,
150
+ $press-transition,
145
151
  color 50ms ease;
146
152
 
147
153
  &.in-toolbar:not(.ion-color):not(.in-toolbar-color) {
@@ -247,8 +253,10 @@ $scaleup-large-icon-only: api.$button-scaleup-large-icon-only;
247
253
  inset 0 -0.5px 0 rgba(255, 255, 255, 0.48),
248
254
  0 0.5px 1px rgba(0, 0, 0, 0.12);
249
255
  }
250
- &.ion-activated.button-has-icon-only,
251
- &.ion-activated.back-button-has-icon-only {
256
+ }
257
+ &:active:not(.button-disabled) {
258
+ &.button-has-icon-only,
259
+ &.back-button-has-icon-only {
252
260
  transform: scale($scaleup-default-icon-only);
253
261
  &.button-small {
254
262
  transform: scale($scaleup-small-icon-only);
@@ -332,8 +340,10 @@ $scaleup-large-icon-only: api.$button-scaleup-large-icon-only;
332
340
  &.ion-color {
333
341
  --color: rgba(var(--ion-color-base-rgb, var(--ion-text-color-rgb, 0, 0, 0)), 0.1);
334
342
  }
335
- &.ion-activated.button-has-icon-only,
336
- &.ion-activated.back-button-has-icon-only {
343
+ }
344
+ &:active:not(.button-disabled) {
345
+ &.button-has-icon-only,
346
+ &.back-button-has-icon-only {
337
347
  transform: scale($scaleup-default-icon-only);
338
348
  &.button-small {
339
349
  transform: scale($scaleup-small-icon-only);
@@ -401,17 +411,18 @@ ion-buttons.ios:not(.ios-theme-disabled, .ios26-disabled):not(
401
411
  ion-buttons.ios:not(.ios-theme-disabled, .ios26-disabled):not(
402
412
  :has(ion-back-button, ion-button:not(.button-clear), ion-menu-button.menu-button-hidden)
403
413
  ) {
404
- transition: transform var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease-out;
414
+ transition: $press-transition;
405
415
  }
406
416
 
407
417
  ion-buttons.ios:not(.ios-theme-disabled, .ios26-disabled):not(:has(ion-back-button, ion-button.button-clear)) {
408
418
  ion-button {
409
- margin: 0 6px;
419
+ margin-block: 0;
420
+ margin-inline: 6px;
410
421
  &:first-child {
411
- margin-left: 0;
422
+ margin-inline-start: 0;
412
423
  }
413
424
  &:last-child {
414
- margin-right: 0;
425
+ margin-inline-end: 0;
415
426
  }
416
427
  &:only-child {
417
428
  margin: 0;
@@ -6,7 +6,13 @@ $scaleup-default-icon-only: api.$button-scaleup-default-icon-only;
6
6
  $scaleup-large-icon-only: api.$button-scaleup-large-icon-only;
7
7
 
8
8
  ion-fab.ios:not(.ios-theme-disabled, .ios26-disabled) {
9
+ --ios-theme-safe-area-inline-start: var(--ion-safe-area-left, 0px);
10
+ --ios-theme-safe-area-inline-end: var(--ion-safe-area-right, 0px);
9
11
  --transform-value: 2.5px;
12
+ &:dir(rtl) {
13
+ --ios-theme-safe-area-inline-start: var(--ion-safe-area-right, 0px);
14
+ --ios-theme-safe-area-inline-end: var(--ion-safe-area-left, 0px);
15
+ }
10
16
  &:has(> ion-fab-button.fab-button-small) {
11
17
  --transform-value: 4px;
12
18
  }
@@ -85,20 +91,20 @@ ion-fab.ios:not(.ios-theme-disabled, .ios26-disabled) {
85
91
  }
86
92
 
87
93
  &.fab-horizontal-start {
88
- left: calc(16px + var(--ios-theme-menu-width, var(--ios26-menu-width, var(--ion-safe-area-left), 0px)));
94
+ inset-inline-start: calc(16px + var(--ios-theme-menu-width, var(--ios26-menu-width, var(--ios-theme-safe-area-inline-start))));
89
95
  }
90
96
 
91
97
  &.fab-horizontal-end {
92
- right: calc(16px + var(--ion-safe-area-right, 0px));
98
+ inset-inline-end: calc(16px + var(--ios-theme-safe-area-inline-end));
93
99
  }
94
100
 
95
101
  &:has(.fab-button-small) {
96
102
  &.fab-horizontal-start {
97
- left: calc(10px + var(--ios-theme-menu-width, var(--ios26-menu-width, var(--ion-safe-area-left), 0px)));
103
+ inset-inline-start: calc(10px + var(--ios-theme-menu-width, var(--ios26-menu-width, var(--ios-theme-safe-area-inline-start))));
98
104
  }
99
105
 
100
106
  &.fab-horizontal-end {
101
- right: calc(10px + var(--ion-safe-area-right, 0px));
107
+ inset-inline-end: calc(10px + var(--ios-theme-safe-area-inline-end));
102
108
  }
103
109
  }
104
110
  }
@@ -1,4 +1,4 @@
1
- @use '../utils/structured-list';
1
+ @use 'pkg:@rdlabo/ionic-theme-utils/styles/structured-list';
2
2
 
3
3
  ion-list.ios:not(.ios-theme-disabled, .ios26-disabled) {
4
4
  --ion-border-color: var(--ion-color-step-100, var(--ion-background-color-step-100, #e8e8e8));
@@ -11,7 +11,7 @@ ion-list.ios:not(.ios-theme-disabled, .ios26-disabled) {
11
11
  }
12
12
 
13
13
  ion-list.list-inset.ios:not(.ios-theme-disabled, .ios26-disabled) {
14
- @include structured-list.layout(20px, 28px);
14
+ @include structured-list.layout(20px, 28px, $variant: ios27);
15
15
 
16
16
  ion-radio-group,
17
17
  ion-reorder-group {
@@ -23,13 +23,22 @@ ion-list.list-inset.ios:not(.ios-theme-disabled, .ios26-disabled) {
23
23
  padding-inline-end: calc(var(--ion-safe-area-right, 0) + 20px);
24
24
  }
25
25
 
26
+ &:dir(rtl) ion-radio-group > .radio-group-top {
27
+ padding-inline-start: calc(var(--ion-safe-area-right, 0) + 20px);
28
+ padding-inline-end: calc(var(--ion-safe-area-left, 0) + 20px);
29
+ }
30
+
26
31
  > :is(#{structured-list.$groups}) {
27
32
  ion-item {
28
33
  // To draw lines inside
29
34
  --inner-padding-end: 0;
30
35
 
31
36
  &::part(native) {
32
- padding-right: calc(var(--ion-safe-area-right, 0px) + 18px);
37
+ padding-inline-end: calc(var(--ion-safe-area-right, 0px) + 18px);
38
+ }
39
+
40
+ &:dir(rtl)::part(native) {
41
+ padding-inline-end: calc(var(--ion-safe-area-left, 0px) + 18px);
33
42
  }
34
43
 
35
44
  --min-height: 52px;
@@ -6,13 +6,13 @@ ion-split-pane.ios:not(.ios-theme-disabled, .ios26-disabled).split-pane-visible:
6
6
  .split-pane-main {
7
7
  ion-tab-bar.ios:not(.ios-theme-disabled, .ios26-disabled) {
8
8
  width: calc(
9
- 100% - calc(18px + var(--ion-safe-area-left, 0px)) - calc(18px + var(--ion-safe-area-left, 0px)) - 60px -
9
+ 100% - calc(18px + var(--ion-safe-area-left, 0px)) - calc(18px + var(--ion-safe-area-right, 0px)) - 60px -
10
10
  12px - var(--ios-theme-menu-width, var(--ios26-menu-width))
11
11
  );
12
12
 
13
13
  &:has(:nth-child(5)) {
14
14
  width: calc(
15
- 100% - calc(18px + var(--ion-safe-area-left, 0px)) - calc(18px + var(--ion-safe-area-left, 0px)) - var(
15
+ 100% - calc(18px + var(--ion-safe-area-left, 0px)) - calc(18px + var(--ion-safe-area-right, 0px)) - var(
16
16
  --ios-theme-menu-width,
17
17
  var(--ios26-menu-width)
18
18
  )
@@ -31,7 +31,7 @@ ion-split-pane.ios:not(.ios-theme-disabled, .ios26-disabled).split-pane-visible:
31
31
  /*
32
32
  * 90px: https://github.com/ionic-team/ionic-framework/blob/main/core/src/components/title/title.ios.scss#L8
33
33
  */
34
- padding-left: calc(90px + var(--ios-theme-menu-width, var(--ios26-menu-width)));
34
+ padding-inline-start: calc(90px + var(--ios-theme-menu-width, var(--ios26-menu-width)));
35
35
  }
36
36
  }
37
37
  ion-content {
@@ -45,7 +45,10 @@ ion-split-pane.ios:not(.ios-theme-disabled, .ios26-disabled).split-pane-visible:
45
45
  }
46
46
  ion-tab-bar.ios:not(.ios-theme-disabled, .ios26-disabled) {
47
47
  &[slot='bottom'] {
48
- left: calc(16px + var(--ion-safe-area-left, 0px) + var(--ios-theme-menu-width, var(--ios26-menu-width)));
48
+ inset-inline-start: calc(16px + var(--ion-safe-area-left, 0px) + var(--ios-theme-menu-width, var(--ios26-menu-width)));
49
+ &:dir(rtl) {
50
+ inset-inline-start: calc(16px + var(--ion-safe-area-right, 0px) + var(--ios-theme-menu-width, var(--ios26-menu-width)));
51
+ }
49
52
  }
50
53
  }
51
54
  }
@@ -62,7 +65,7 @@ ion-split-pane.ios:not(.ios-theme-disabled, .ios26-disabled).split-pane-visible:
62
65
  /*
63
66
  * 90px: https://github.com/ionic-team/ionic-framework/blob/main/core/src/components/title/title.ios.scss#L8
64
67
  */
65
- padding-right: calc(90px + var(--ios-theme-menu-width, var(--ios26-menu-width)));
68
+ padding-inline-end: calc(90px + var(--ios-theme-menu-width, var(--ios26-menu-width)));
66
69
  }
67
70
  }
68
71
  ion-content {
@@ -88,10 +91,10 @@ ion-menu.ios:not(.ios-theme-disabled, .ios26-disabled) {
88
91
  z-index: 999;
89
92
 
90
93
  &.menu-side-start {
91
- left: 0;
94
+ inset-inline-start: 0;
92
95
  }
93
96
  &.menu-side-end {
94
- left: calc(100vw - var(--ios-theme-menu-width, var(--ios26-menu-width)));
97
+ inset-inline-end: 0;
95
98
  }
96
99
 
97
100
  &::part(backdrop) {
@@ -119,9 +122,13 @@ ion-menu.ios:not(.ios-theme-disabled, .ios26-disabled) {
119
122
  --ios-theme-content-box-shadow-rgb: var(--ios26-content-box-shadow-rgb);
120
123
 
121
124
  &::part(scroll) {
122
- margin: calc(var(--ios-theme-floating-safe-area-top, var(--ios26-floating-safe-area-top)) + 6px)
123
- calc(16px + var(--ion-safe-area-right, 0px)) var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom))
124
- calc(12px + var(--ion-safe-area-left, 0px));
125
+ margin-block: calc(var(--ios-theme-floating-safe-area-top, var(--ios26-floating-safe-area-top)) + 6px)
126
+ var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom));
127
+ margin-inline: calc(12px + var(--ion-safe-area-left, 0px)) calc(16px + var(--ion-safe-area-right, 0px));
128
+ }
129
+
130
+ &:dir(rtl)::part(scroll) {
131
+ margin-inline: calc(12px + var(--ion-safe-area-right, 0px)) calc(16px + var(--ion-safe-area-left, 0px));
125
132
  }
126
133
  }
127
134
  }
@@ -274,6 +274,6 @@ ion-searchbar.ios:not(.ios-theme-disabled, .ios26-disabled).searchbar-classic {
274
274
  width: 1.18rem;
275
275
  }
276
276
  button.searchbar-clear-button {
277
- right: 8px;
277
+ inset-inline-end: 8px;
278
278
  }
279
279
  }
@@ -1,6 +1,12 @@
1
1
  @use '../utils/api';
2
2
 
3
3
  ion-tab-bar.ios:not(.ios-theme-disabled, .ios26-disabled) {
4
+ --ios-theme-safe-area-inline-start: var(--ion-safe-area-left, 0px);
5
+ --ios-theme-safe-area-inline-end: var(--ion-safe-area-right, 0px);
6
+ &:dir(rtl) {
7
+ --ios-theme-safe-area-inline-start: var(--ion-safe-area-right, 0px);
8
+ --ios-theme-safe-area-inline-end: var(--ion-safe-area-left, 0px);
9
+ }
4
10
  // Ionic forces content-box on the host. Keep the Glass border in a
5
11
  // separate layer so its physical-pixel rounding cannot resize the bar.
6
12
  border: 0;
@@ -29,26 +35,24 @@ ion-tab-bar.ios:not(.ios-theme-disabled, .ios26-disabled) {
29
35
  &[slot='top'] {
30
36
  position: absolute;
31
37
  top: var(--ios-theme-floating-safe-area-top, var(--ios26-floating-safe-area-top));
32
- right: calc(16px + var(--ion-safe-area-right, 0px));
38
+ inset-inline-end: calc(16px + var(--ios-theme-safe-area-inline-end));
33
39
  }
34
40
 
35
41
  &[slot='bottom'] {
36
42
  position: absolute;
37
43
  bottom: var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom));
38
- left: calc(16px + var(--ion-safe-area-left, 0px));
44
+ inset-inline-start: calc(16px + var(--ios-theme-safe-area-inline-start));
39
45
  }
40
46
 
41
- &.tab-bar-position-start,
42
- &.tab-bar-position-end:dir(rtl) {
43
- left: calc(16px + var(--ion-safe-area-left, 0px));
44
- right: auto;
47
+ &.tab-bar-position-start {
48
+ inset-inline-start: calc(16px + var(--ios-theme-safe-area-inline-start));
49
+ inset-inline-end: auto;
45
50
  margin-inline: 0;
46
51
  }
47
52
 
48
- &.tab-bar-position-end,
49
- &.tab-bar-position-start:dir(rtl) {
50
- left: auto;
51
- right: calc(16px + var(--ion-safe-area-right, 0px));
53
+ &.tab-bar-position-end {
54
+ inset-inline-start: auto;
55
+ inset-inline-end: calc(16px + var(--ios-theme-safe-area-inline-end));
52
56
  margin-inline: 0;
53
57
  }
54
58
 
@@ -57,27 +57,29 @@ ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled).toolbar-searchbar {
57
57
  }
58
58
  &:has(ion-buttons[slot='start']) {
59
59
  ion-buttons[slot='start'] {
60
- margin-right: 6px;
60
+ margin-inline-end: 6px;
61
61
  }
62
62
  ion-searchbar.ios:not(.ios-theme-disabled, .ios26-disabled) {
63
63
  &:not(.searchbar-classic) {
64
64
  padding-inline: 6px 12px;
65
65
  }
66
66
  &.searchbar-classic .searchbar-input-container {
67
- margin: 0 12px 0 6px;
67
+ margin-block: 0;
68
+ margin-inline: 6px 12px;
68
69
  }
69
70
  }
70
71
  }
71
72
  &:has(ion-buttons[slot='end']) {
72
73
  ion-buttons[slot='end'] {
73
- margin-left: 6px;
74
+ margin-inline-start: 6px;
74
75
  }
75
76
  ion-searchbar.ios:not(.ios-theme-disabled, .ios26-disabled) {
76
77
  &:not(.searchbar-classic) {
77
78
  padding-inline: 12px 6px;
78
79
  }
79
80
  &.searchbar-classic .searchbar-input-container {
80
- margin: 0 6px 0 12px;
81
+ margin-block: 0;
82
+ margin-inline: 12px 6px;
81
83
  }
82
84
  }
83
85
  }
@@ -85,15 +87,12 @@ ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled).toolbar-searchbar {
85
87
 
86
88
  ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled) {
87
89
  ion-buttons {
88
- margin-left: 12px;
89
- margin-right: 12px;
90
+ margin-inline: 12px;
90
91
  }
91
92
  ion-back-button {
92
- margin-left: 12px;
93
- margin-right: 12px;
93
+ margin-inline: 12px;
94
94
  }
95
95
  ion-buttons > ion-back-button {
96
- margin-left: 0;
97
- margin-right: 0;
96
+ margin-inline: 0;
98
97
  }
99
98
  }
@@ -1,10 +1,10 @@
1
- @use 'utils/structured-list';
1
+ @use 'pkg:@rdlabo/ionic-theme-utils/styles/structured-list';
2
2
 
3
3
  ion-list.md {
4
4
  @include structured-list.support-text;
5
5
 
6
6
  &.list-inset {
7
- @include structured-list.layout(8px, 16px);
7
+ @include structured-list.layout(8px, 16px, $variant: ios27);
8
8
  :is(#{structured-list.$groups}) ion-item {
9
9
  & > ion-input[labelplacement='floating'] {
10
10
  transition: transform 200ms ease;
@@ -1,4 +1,4 @@
1
- @use '../structured-list';
1
+ @use 'pkg:@rdlabo/ionic-theme-utils/styles/structured-list';
2
2
 
3
3
  @mixin ion-list {
4
4
  ion-list.ios:not(.ios-theme-disabled, .ios26-disabled) {
@@ -20,6 +20,18 @@ ion-footer.ios:not(.ios-theme-disabled, .ios26-disabled).footer-translucent {
20
20
  }
21
21
  }
22
22
 
23
+ .ion-page:has(> ion-content.ios.content-fullscreen) > ion-header.ios:not(.ios-theme-disabled, .ios26-disabled):not(.header-translucent),
24
+ .ion-page:has(> ion-content.ios.content-fullscreen) > ion-footer.ios:not(.ios-theme-disabled, .ios26-disabled):not(.footer-translucent) {
25
+ ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled) {
26
+ --background: transparent;
27
+ --opacity: 1;
28
+
29
+ &::part(background) {
30
+ --opacity: 0;
31
+ }
32
+ }
33
+ }
34
+
23
35
  ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-translucent:not(.header-collapse-condense) {
24
36
  &:has(> ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled) > *)::before {
25
37
  height: 100%;
@@ -40,6 +52,27 @@ ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-translucent:not(
40
52
  }
41
53
  }
42
54
 
55
+ .ion-page:has(> ion-content.ios.content-fullscreen) > ion-footer.ios:not(.ios-theme-disabled, .ios26-disabled).footer-translucent {
56
+ &:has(> ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled) > *)::before {
57
+ bottom: 0;
58
+ height: 100%;
59
+ background: rgba(
60
+ var(--ion-color-base-rgb, var(--ios-theme-content-box-shadow-rgb, var(--ios26-content-box-shadow-rgb))),
61
+ calc(0.2 * var(--opacity-scale, 1))
62
+ );
63
+ backdrop-filter: blur(8px);
64
+ }
65
+
66
+ &:not(.ion-no-border) > ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled):has(> *):first-of-type {
67
+ --border-width: 0.5px 0 0;
68
+ --border-color: var(--ion-toolbar-border-color, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08));
69
+ &::part(background) {
70
+ --opacity: 1;
71
+ background: transparent;
72
+ }
73
+ }
74
+ }
75
+
43
76
  ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-collapse-main ion-toolbar.in-toolbar ion-title {
44
77
  transition:
45
78
  opacity 0.5s ease-in-out,
@@ -58,6 +91,8 @@ ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-collapse-condens
58
91
 
59
92
  ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-translucent::before,
60
93
  ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-translucent::after,
94
+ .ion-page:has(> ion-content.ios.content-fullscreen) > ion-footer.ios:not(.ios-theme-disabled, .ios26-disabled).footer-translucent::before,
95
+ .ion-page:has(> ion-content.ios.content-fullscreen) > ion-footer.ios:not(.ios-theme-disabled, .ios26-disabled).footer-translucent::after,
61
96
  ion-content.ios:not(.ios-theme-disabled, .ios26-disabled).content-fullscreen::part(background)::before {
62
97
  content: '';
63
98
  position: absolute;
@@ -84,6 +119,15 @@ ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-translucent::aft
84
119
  mask-composite: intersect;
85
120
  }
86
121
 
122
+ .ion-page:has(> ion-content.ios.content-fullscreen) > ion-footer.ios:not(.ios-theme-disabled, .ios26-disabled).footer-translucent::after {
123
+ z-index: 2;
124
+ bottom: 0;
125
+ height: 100%;
126
+ backdrop-filter: blur(2px);
127
+ mask-image: linear-gradient(rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 20%);
128
+ mask-composite: intersect;
129
+ }
130
+
87
131
  /**
88
132
  * ここから下は、ion-content::beforeが content:'' を持たない限り表示されない
89
133
  */
@@ -1,7 +1,6 @@
1
- import { ElementReferences, ElementSizes } from '../interfaces';
2
1
  import { Animation, createAnimation } from '@ionic/core';
2
+ import { ANIMATION_DELAY_CLOSE_BUTTONS, OPACITY_TRANSITION, type ElementReferences, type ElementSizes } from '@rdlabo/ionic-theme-utils';
3
3
  import { cloneElement } from '../../utils';
4
- import { ANIMATION_DELAY_CLOSE_BUTTONS, OPACITY_TRANSITION } from '../utils';
5
4
 
6
5
  export const createEffectAnimation = (references: ElementReferences, sizes: ElementSizes): Animation => {
7
6
  const effectElement = cloneElement('ion-icon');
@@ -1,7 +1,6 @@
1
- import { ElementReferences, ElementSizes } from '../interfaces';
2
1
  import { Animation, createAnimation } from '@ionic/core';
2
+ import { ANIMATION_DELAY_CLOSE_BUTTONS, OPACITY_TRANSITION, type ElementReferences, type ElementSizes } from '@rdlabo/ionic-theme-utils';
3
3
  import { cloneElement } from '../../utils';
4
- import { ANIMATION_DELAY_CLOSE_BUTTONS, OPACITY_TRANSITION } from '../utils';
5
4
 
6
5
  export const createReverseEffectAnimation = (
7
6
  references: ElementReferences,
@@ -1,5 +1,4 @@
1
1
  import { createAnimation } from '@ionic/core';
2
- import { isNativeUIShell, registerNativeSearch, requestNativeSearch, suspendNativeUIShell } from '../native-integration';
3
2
  import {
4
3
  ANIMATION_DELAY_BASE,
5
4
  ANIMATION_DURATION,
@@ -7,8 +6,11 @@ import {
7
6
  getElementReferences,
8
7
  getElementSizes,
9
8
  throwErrorByFailedClickElement,
10
- } from './utils';
11
- import { SearchableEventCache, TabBarSearchableFunction, TabBarSearchableType } from './interfaces';
9
+ type SearchableEventCache,
10
+ type TabBarSearchableFunction,
11
+ TabBarSearchableType,
12
+ } from '@rdlabo/ionic-theme-utils';
13
+ import { isNativeUIShell, registerNativeSearch, requestNativeSearch, suspendNativeUIShell } from '../native-integration';
12
14
  import {
13
15
  createCloseButtonsAnimation,
14
16
  createEffectAnimation,
@@ -24,7 +26,13 @@ import {
24
26
  createReverseTabBarAnimation,
25
27
  } from './animations/leave';
26
28
 
27
- export * from './interfaces';
29
+ export {
30
+ TabBarSearchableType,
31
+ type TabBarSearchableFunction,
32
+ type SearchableEventCache,
33
+ type ElementSizes,
34
+ type ElementReferences,
35
+ } from '@rdlabo/ionic-theme-utils';
28
36
 
29
37
  /**
30
38
  * <ion-fab vertical="bottom" horizontal="end" slot="fixed">