@rdlabo/ionic-theme-ios26 0.1.1 → 0.1.3

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 (211) hide show
  1. package/dist/css/components/ion-action-sheet.css +1 -0
  2. package/dist/css/components/ion-alert.css +1 -0
  3. package/dist/css/components/ion-breadcrumbs.css +1 -0
  4. package/dist/css/components/ion-button.css +1 -0
  5. package/dist/css/components/ion-card.css +1 -0
  6. package/dist/css/components/ion-chip.css +1 -0
  7. package/dist/css/components/ion-content.css +1 -0
  8. package/dist/css/components/ion-datetime.css +1 -0
  9. package/dist/css/components/ion-fab.css +1 -0
  10. package/dist/css/components/ion-list.css +1 -0
  11. package/dist/css/components/ion-loading.css +1 -0
  12. package/dist/css/components/ion-modal.css +1 -0
  13. package/dist/css/components/ion-picker.css +1 -0
  14. package/dist/css/components/ion-popover.css +1 -0
  15. package/dist/css/components/ion-range.css +1 -0
  16. package/dist/css/components/ion-searchbar.css +1 -0
  17. package/dist/css/components/ion-segment.css +1 -0
  18. package/dist/css/components/ion-tabs.css +1 -0
  19. package/dist/css/components/ion-toast.css +1 -0
  20. package/dist/css/components/ion-toggle.css +1 -0
  21. package/dist/css/components/ion-toolbar.css +1 -0
  22. package/dist/css/default-variables.css +1 -0
  23. package/dist/css/ionic-theme-ios26-dark-always.css +1 -0
  24. package/dist/css/ionic-theme-ios26-dark-class.css +1 -0
  25. package/dist/css/ionic-theme-ios26-dark-system.css +1 -0
  26. package/dist/css/ionic-theme-ios26.css +1 -0
  27. package/dist/css/md-ion-list-inset.css +1 -0
  28. package/dist/css/utils/api.css +1 -0
  29. package/dist/css/utils/dark/ion-button.css +1 -0
  30. package/dist/css/utils/theme-dark.css +1 -0
  31. package/dist/css/utils/theme-list-inset.css +1 -0
  32. package/dist/css/utils/translucent.css +1 -0
  33. package/package.json +8 -13
  34. package/.cursor/rules/css-compilation.mdc +0 -34
  35. package/.cursor/rules/demo-application.mdc +0 -39
  36. package/.cursor/rules/development-workflow.mdc +0 -41
  37. package/.cursor/rules/project-role.mdc +0 -21
  38. package/.github/FUNDING.yml +0 -15
  39. package/.github/workflows/lint.yml +0 -40
  40. package/.husky/pre-commit +0 -1
  41. package/.lintstagedrc.yml +0 -6
  42. package/.prettierignore +0 -3
  43. package/FEEDBACK.md +0 -118
  44. package/FEEDBACK2.md +0 -45
  45. package/USING_ION_ITEM_GROUP.md +0 -56
  46. package/demo/ .cursor/rules/angular-20.mdc +0 -136
  47. package/demo/.browserslistrc +0 -15
  48. package/demo/.editorconfig +0 -16
  49. package/demo/.vscode/extensions.json +0 -5
  50. package/demo/.vscode/settings.json +0 -3
  51. package/demo/angular.json +0 -141
  52. package/demo/capacitor.config.ts +0 -9
  53. package/demo/eslint.config.js +0 -49
  54. package/demo/ionic.config.json +0 -7
  55. package/demo/karma.conf.js +0 -44
  56. package/demo/package-lock.json +0 -20001
  57. package/demo/package.json +0 -60
  58. package/demo/src/app/album/album-page.component.html +0 -24
  59. package/demo/src/app/album/album-page.component.scss +0 -17
  60. package/demo/src/app/album/album-page.component.spec.ts +0 -21
  61. package/demo/src/app/album/album-page.component.ts +0 -24
  62. package/demo/src/app/app.component.html +0 -3
  63. package/demo/src/app/app.component.ts +0 -16
  64. package/demo/src/app/app.config.ts +0 -17
  65. package/demo/src/app/app.routes.ts +0 -8
  66. package/demo/src/app/health/health-page.component.html +0 -17
  67. package/demo/src/app/health/health-page.component.scss +0 -0
  68. package/demo/src/app/health/health-page.component.spec.ts +0 -21
  69. package/demo/src/app/health/health-page.component.ts +0 -14
  70. package/demo/src/app/index/index-page.component.html +0 -51
  71. package/demo/src/app/index/index-page.component.scss +0 -0
  72. package/demo/src/app/index/index-page.component.spec.ts +0 -21
  73. package/demo/src/app/index/index-page.component.ts +0 -94
  74. package/demo/src/app/index/index.routes.ts +0 -109
  75. package/demo/src/app/index/pages/accordion/accordion.page.html +0 -45
  76. package/demo/src/app/index/pages/accordion/accordion.page.scss +0 -0
  77. package/demo/src/app/index/pages/accordion/accordion.page.spec.ts +0 -21
  78. package/demo/src/app/index/pages/accordion/accordion.page.ts +0 -47
  79. package/demo/src/app/index/pages/action-sheet/action-sheet.page.html +0 -33
  80. package/demo/src/app/index/pages/action-sheet/action-sheet.page.scss +0 -0
  81. package/demo/src/app/index/pages/action-sheet/action-sheet.page.spec.ts +0 -21
  82. package/demo/src/app/index/pages/action-sheet/action-sheet.page.ts +0 -73
  83. package/demo/src/app/index/pages/action-sheet/action-sheet.util.ts +0 -28
  84. package/demo/src/app/index/pages/alert/alert.page.html +0 -33
  85. package/demo/src/app/index/pages/alert/alert.page.scss +0 -0
  86. package/demo/src/app/index/pages/alert/alert.page.spec.ts +0 -21
  87. package/demo/src/app/index/pages/alert/alert.page.ts +0 -73
  88. package/demo/src/app/index/pages/alert/alert.util.ts +0 -21
  89. package/demo/src/app/index/pages/breadcrumbs/breadcrumbs.page.html +0 -41
  90. package/demo/src/app/index/pages/breadcrumbs/breadcrumbs.page.scss +0 -0
  91. package/demo/src/app/index/pages/breadcrumbs/breadcrumbs.page.spec.ts +0 -21
  92. package/demo/src/app/index/pages/breadcrumbs/breadcrumbs.page.ts +0 -47
  93. package/demo/src/app/index/pages/button/button.page.html +0 -112
  94. package/demo/src/app/index/pages/button/button.page.scss +0 -3
  95. package/demo/src/app/index/pages/button/button.page.spec.ts +0 -21
  96. package/demo/src/app/index/pages/button/button.page.ts +0 -51
  97. package/demo/src/app/index/pages/card/card.page.html +0 -171
  98. package/demo/src/app/index/pages/card/card.page.scss +0 -0
  99. package/demo/src/app/index/pages/card/card.page.spec.ts +0 -21
  100. package/demo/src/app/index/pages/card/card.page.ts +0 -57
  101. package/demo/src/app/index/pages/checkbox/checkbox.page.html +0 -66
  102. package/demo/src/app/index/pages/checkbox/checkbox.page.scss +0 -0
  103. package/demo/src/app/index/pages/checkbox/checkbox.page.spec.ts +0 -21
  104. package/demo/src/app/index/pages/checkbox/checkbox.page.ts +0 -45
  105. package/demo/src/app/index/pages/chip/chip.page.html +0 -72
  106. package/demo/src/app/index/pages/chip/chip.page.scss +0 -0
  107. package/demo/src/app/index/pages/chip/chip.page.spec.ts +0 -21
  108. package/demo/src/app/index/pages/chip/chip.page.ts +0 -47
  109. package/demo/src/app/index/pages/date-and-time-pickers/date-and-time-pickers.page.html +0 -48
  110. package/demo/src/app/index/pages/date-and-time-pickers/date-and-time-pickers.page.scss +0 -0
  111. package/demo/src/app/index/pages/date-and-time-pickers/date-and-time-pickers.page.spec.ts +0 -21
  112. package/demo/src/app/index/pages/date-and-time-pickers/date-and-time-pickers.page.ts +0 -55
  113. package/demo/src/app/index/pages/floating-action-button/floating-action-button.page.html +0 -106
  114. package/demo/src/app/index/pages/floating-action-button/floating-action-button.page.scss +0 -0
  115. package/demo/src/app/index/pages/floating-action-button/floating-action-button.page.spec.ts +0 -21
  116. package/demo/src/app/index/pages/floating-action-button/floating-action-button.page.ts +0 -49
  117. package/demo/src/app/index/pages/inputs/inputs.page.html +0 -65
  118. package/demo/src/app/index/pages/inputs/inputs.page.scss +0 -0
  119. package/demo/src/app/index/pages/inputs/inputs.page.spec.ts +0 -21
  120. package/demo/src/app/index/pages/inputs/inputs.page.ts +0 -49
  121. package/demo/src/app/index/pages/item-list/item-list.page.html +0 -52
  122. package/demo/src/app/index/pages/item-list/item-list.page.scss +0 -0
  123. package/demo/src/app/index/pages/item-list/item-list.page.spec.ts +0 -21
  124. package/demo/src/app/index/pages/item-list/item-list.page.ts +0 -47
  125. package/demo/src/app/index/pages/menu/menu.page.html +0 -13
  126. package/demo/src/app/index/pages/menu/menu.page.scss +0 -0
  127. package/demo/src/app/index/pages/menu/menu.page.spec.ts +0 -21
  128. package/demo/src/app/index/pages/menu/menu.page.ts +0 -17
  129. package/demo/src/app/index/pages/modal/modal.page.html +0 -37
  130. package/demo/src/app/index/pages/modal/modal.page.scss +0 -0
  131. package/demo/src/app/index/pages/modal/modal.page.spec.ts +0 -21
  132. package/demo/src/app/index/pages/modal/modal.page.ts +0 -77
  133. package/demo/src/app/index/pages/popover/popover.page.html +0 -34
  134. package/demo/src/app/index/pages/popover/popover.page.scss +0 -0
  135. package/demo/src/app/index/pages/popover/popover.page.spec.ts +0 -21
  136. package/demo/src/app/index/pages/popover/popover.page.ts +0 -47
  137. package/demo/src/app/index/pages/progress-indicators/progress-indicators.page.html +0 -28
  138. package/demo/src/app/index/pages/progress-indicators/progress-indicators.page.scss +0 -0
  139. package/demo/src/app/index/pages/progress-indicators/progress-indicators.page.spec.ts +0 -21
  140. package/demo/src/app/index/pages/progress-indicators/progress-indicators.page.ts +0 -47
  141. package/demo/src/app/index/pages/radio/radio.page.html +0 -39
  142. package/demo/src/app/index/pages/radio/radio.page.scss +0 -0
  143. package/demo/src/app/index/pages/radio/radio.page.spec.ts +0 -21
  144. package/demo/src/app/index/pages/radio/radio.page.ts +0 -47
  145. package/demo/src/app/index/pages/range/range.page.html +0 -58
  146. package/demo/src/app/index/pages/range/range.page.scss +0 -0
  147. package/demo/src/app/index/pages/range/range.page.spec.ts +0 -21
  148. package/demo/src/app/index/pages/range/range.page.ts +0 -49
  149. package/demo/src/app/index/pages/reorder/reorder.page.html +0 -52
  150. package/demo/src/app/index/pages/reorder/reorder.page.scss +0 -0
  151. package/demo/src/app/index/pages/reorder/reorder.page.spec.ts +0 -21
  152. package/demo/src/app/index/pages/reorder/reorder.page.ts +0 -47
  153. package/demo/src/app/index/pages/searchbar/searchbar.page.html +0 -33
  154. package/demo/src/app/index/pages/searchbar/searchbar.page.scss +0 -0
  155. package/demo/src/app/index/pages/searchbar/searchbar.page.spec.ts +0 -21
  156. package/demo/src/app/index/pages/searchbar/searchbar.page.ts +0 -45
  157. package/demo/src/app/index/pages/segment/segment.page.html +0 -107
  158. package/demo/src/app/index/pages/segment/segment.page.scss +0 -1
  159. package/demo/src/app/index/pages/segment/segment.page.spec.ts +0 -21
  160. package/demo/src/app/index/pages/segment/segment.page.ts +0 -51
  161. package/demo/src/app/index/pages/select/select.page.html +0 -74
  162. package/demo/src/app/index/pages/select/select.page.scss +0 -0
  163. package/demo/src/app/index/pages/select/select.page.spec.ts +0 -21
  164. package/demo/src/app/index/pages/select/select.page.ts +0 -50
  165. package/demo/src/app/index/pages/tabs/tabs.page.html +0 -78
  166. package/demo/src/app/index/pages/tabs/tabs.page.scss +0 -6
  167. package/demo/src/app/index/pages/tabs/tabs.page.spec.ts +0 -21
  168. package/demo/src/app/index/pages/tabs/tabs.page.ts +0 -47
  169. package/demo/src/app/index/pages/toast/toast.page.html +0 -32
  170. package/demo/src/app/index/pages/toast/toast.page.scss +0 -0
  171. package/demo/src/app/index/pages/toast/toast.page.spec.ts +0 -21
  172. package/demo/src/app/index/pages/toast/toast.page.ts +0 -66
  173. package/demo/src/app/index/pages/toggle/toggle.page.html +0 -45
  174. package/demo/src/app/index/pages/toggle/toggle.page.scss +0 -0
  175. package/demo/src/app/index/pages/toggle/toggle.page.spec.ts +0 -21
  176. package/demo/src/app/index/pages/toggle/toggle.page.ts +0 -49
  177. package/demo/src/app/index/pages/toolbar/toolbar.page.html +0 -121
  178. package/demo/src/app/index/pages/toolbar/toolbar.page.scss +0 -0
  179. package/demo/src/app/index/pages/toolbar/toolbar.page.spec.ts +0 -21
  180. package/demo/src/app/index/pages/toolbar/toolbar.page.ts +0 -55
  181. package/demo/src/app/settings/settings-page.component.html +0 -117
  182. package/demo/src/app/settings/settings-page.component.scss +0 -33
  183. package/demo/src/app/settings/settings-page.component.spec.ts +0 -21
  184. package/demo/src/app/settings/settings-page.component.ts +0 -55
  185. package/demo/src/app/tabs/tabs.page.html +0 -23
  186. package/demo/src/app/tabs/tabs.page.scss +0 -0
  187. package/demo/src/app/tabs/tabs.page.spec.ts +0 -26
  188. package/demo/src/app/tabs/tabs.page.ts +0 -28
  189. package/demo/src/app/tabs/tabs.routes.ts +0 -40
  190. package/demo/src/assets/.gitkeep +0 -0
  191. package/demo/src/favicon.ico +0 -0
  192. package/demo/src/global.scss +0 -65
  193. package/demo/src/index.html +0 -24
  194. package/demo/src/main.ts +0 -5
  195. package/demo/src/test.ts +0 -7
  196. package/demo/src/theme/variables.scss +0 -20
  197. package/demo/tsconfig.app.json +0 -14
  198. package/demo/tsconfig.json +0 -30
  199. package/demo/tsconfig.spec.json +0 -17
  200. package/demo/util/mocks/angular/angular-delegate.ts +0 -18
  201. package/demo/util/mocks/angular/ion-router-outlet.ts +0 -39
  202. package/demo/util/mocks/angular/modal-controller.ts +0 -7
  203. package/demo/util/mocks/angular/nav-controller.ts +0 -22
  204. package/demo/util/mocks/angular/popover-controller.ts +0 -7
  205. package/demo/util/mocks/util/base.mock.ts +0 -13
  206. package/demo/util/mocks/util/overlay.ts +0 -13
  207. package/demo/util/test.config.ts +0 -54
  208. package/prettier.config.js +0 -18
  209. package/screenshots/ios26.png +0 -0
  210. package/screenshots/why-ion-list-inset.png +0 -0
  211. package/tsconfig.json +0 -5
@@ -1,40 +0,0 @@
1
- name: Lint
2
- on:
3
- push:
4
- branches:
5
- - '**'
6
- pull_request:
7
- types: [opened]
8
- jobs:
9
- prettier:
10
- runs-on: ubuntu-latest
11
- steps:
12
- - uses: actions/checkout@v4
13
- - uses: actions/setup-node@v4
14
- with:
15
- node-version: 22
16
- - uses: actions/cache@v4
17
- with:
18
- path: node_modules
19
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
20
- restore-keys: |
21
- ${{ runner.os }}-node-
22
- - run: npm install
23
- - run: npm run lint
24
- lint:
25
- runs-on: ubuntu-latest
26
- steps:
27
- - uses: actions/checkout@v4
28
- - uses: actions/setup-node@v4
29
- with:
30
- node-version: 22
31
- - uses: actions/cache@v4
32
- with:
33
- path: node_modules
34
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
35
- restore-keys: |
36
- ${{ runner.os }}-node-
37
- - run: npm install
38
- working-directory: './demo'
39
- - run: npm run lint
40
- working-directory: './demo'
package/.husky/pre-commit DELETED
@@ -1 +0,0 @@
1
- npx lint-staged
package/.lintstagedrc.yml DELETED
@@ -1,6 +0,0 @@
1
- "*.ts":
2
- - prettier --parser typescript --write
3
- "*.html":
4
- - prettier --parser angular --write
5
- "*.scss":
6
- - prettier --parser scss --write
package/.prettierignore DELETED
@@ -1,3 +0,0 @@
1
- node_modules
2
- dist
3
- www
package/FEEDBACK.md DELETED
@@ -1,118 +0,0 @@
1
- # Feature Requests for Ionic Framework
2
-
3
- ## docs(): Naming conventions for Ionic theme classes
4
-
5
- After the Ionic Modular release, I expect many themes to be distributed through community activities. Therefore, I would like to establish naming conventions for theme application classes. I would appreciate the Ionic team's opinion on this matter.
6
-
7
- - Classes for manually applying themes
8
- - .theme-[theme-name] (ex: .theme-ios26)
9
- - .theme-[theme-name]-enabled (ex: .theme-ios26-enabled)
10
- - .[theme-name]-enabled (ex: .ios26-enabled)
11
- - .ion-[theme-name]-enabled (ex: .ion-ios26-enabled)
12
- - Classes for manually removing themes
13
- - .theme-no-[theme-name] (ex: .theme-no-ios26)
14
- - .theme-[theme-name]-disabled (ex: .theme-ios26-disabled)
15
- - .[theme-name]-disabled (ex: .ios26-disabled)
16
- - .ion-[theme-name]-disabled (ex: .ion-ios26-disabled)
17
-
18
-
19
- ## feat(): ion-config new property for `collapse`
20
-
21
- Currently, `collapse` behavior is automatically enabled in iOS mode, but this should be configurable through `ion-config` for better control.
22
-
23
- ex:
24
- ```typescript
25
- export interface IonicConfig {
26
- ...,
27
- collapseLargeTitle: {
28
- ios: boolean;
29
- md: boolean;
30
- ionic: boolean;
31
- },
32
- collapseBackButtonAnimation: {
33
- ios: boolean;
34
- md: boolean;
35
- ionic: boolean;
36
- },
37
- }
38
- ```
39
-
40
- ### should disable ion-back-button Animation
41
-
42
- When using `collapse` on the previous screen and specifying `ion-buttons ion-back-button` on the next screen, iOS 18 and earlier animation processing occurs. Since this is unnecessary for iOS 26+, a property to disable this would be beneficial.
43
-
44
- https://github.com/ionic-team/ionic-framework/blob/3b80473f2fd5ad4da5a9f5d66f783a69909c8965/core/src/utils/transition/ios.transition.ts#L333C31-L337
45
- - enteringBackButtonTextAnimation
46
- - enteringBackButtonIconAnimation
47
- - enteringBackButtonAnimation
48
-
49
- Currently, I work around this by not placing `ion-back-button` inside `ion-buttons` due to the selector relationship `ion-buttons > ion-back-button`.
50
-
51
-
52
- ## feat(): ion-content[fullscreen=true] will have .content-fullscreen class
53
-
54
- For implementing iOS 26's blurred safe area effects, a class indicating whether `ion-content` has fullscreen configuration is needed.
55
- I would like to use selectors like the following:
56
-
57
- ```css
58
- .ion-page:has(ion-header.header-translucent) ion-content.content-fullscreen {
59
- }
60
-
61
- .ion-page:has(ion-header.footer-translucent) ion-content.content-fullscreen {
62
- }
63
- ```
64
-
65
- Currently, I assume fullscreen is specified when using `translucent` elements, but this is not guaranteed.
66
-
67
-
68
- ## feat(): add .range-knob-min and .range-knob-max directly to ion-range
69
-
70
- Currently, `.range-knob-min` and `.range-knob-max` are applied to DOM elements inside ShadowDOM, but since these represent the state of `ion-range` itself, they should be applied directly to the component.
71
- This would provide more flexibility for knob styling.
72
-
73
- Current:
74
- ```html
75
- <ion-range>
76
- #shadow-root
77
- ...
78
- <div class="range-knob-handle ... range-knob-min">...</div>
79
- </ion-range>
80
- ```
81
-
82
- After:
83
- ```html
84
- <ion-range class="range-knob-min">
85
- #shadow-root
86
- ...
87
- <div class="range-knob-handle ... range-knob-min">...</div>
88
- </ion-range>
89
- ```
90
-
91
-
92
- ## feat(): add native shadow-part for design
93
-
94
- ### native-inner(or item-inner) part to ion-item
95
- The styling for `ion-item[lines=inset]` is applied to `.item-inner`, which cannot be styled directly. This limitation means that for iOS 26 styling, I can only modify the border-bottom style through `::part(native)` with padding-right, preventing me from utilizing the full right side of `ion-item`. Adding `::part(native-inner)` would increase styling flexibility.
96
-
97
- ```diff
98
- <ion-item>
99
- <button type="button" class="item-native" part="native">
100
- - <div class="item-inner">
101
- + <div class="item-inner" part="native-inner">
102
- ...
103
- </div>
104
- </button>
105
- </ion-item>
106
- ```
107
-
108
- ### native part to ion-toast
109
- The default styling for `ion-toast` is applied to `div.toast-wrapper`, and CSS Custom Properties overrides work similarly. However, there's no way to directly override `div.toast-wrapper`. Currently, I disable this styling using CSS Custom Properties and then apply new styles to `::part(container)`. This is not ideal for styling, so adding `::part(native)` to allow direct override of `div.toast-wrapper` would be preferable.
110
-
111
- ```diff
112
- <ion-toast>
113
- - <div class="toast-wrapper">...</div>
114
- + <div class="toast-wrapper" part="native">...</div>
115
- </ion-toast>
116
- ```
117
-
118
-
package/FEEDBACK2.md DELETED
@@ -1,45 +0,0 @@
1
- # Feature Requests for Ionic Framework
2
- ## feat(): native container add at ion-segment
3
-
4
- 現在、`ion-segment` はShadowDOMであるにもかかわらず、container DOMをもっていない。このため、 `ion-segment` にスタイルをあてるためには、`ion-segment` 自身にあてるしか方法がない。このため、子孫要素である `ion-segment-button` のタップエフェクトを、 `ion-segment` の外に表示することができない。
5
-
6
- Current:
7
-
8
- ```html
9
- <ion-segment>
10
- ::shadow-root
11
- // Put child element
12
- <ion-segment-button></ion-segment-button>
13
- <ion-segment-button></ion-segment-button>
14
- </ion-segment>
15
- ```
16
-
17
- After:
18
-
19
- ```html
20
- <ion-segment>
21
- ::shadow-root
22
- <div class="segment-container" part="container">
23
- // Put child element
24
- <ion-segment-button></ion-segment-button>
25
- <ion-segment-button></ion-segment-button>
26
- </div>
27
- </ion-segment>
28
- ```
29
-
30
- このことで、以下のようにスタイリングしたい。
31
-
32
- ```scss
33
- ion-segment {
34
- &::part(container) {
35
- overflow: visible;
36
- margin: 12px; // Enable Effect Area
37
- background: var(255, 255, 255, 0.7);
38
- }
39
- ion-segment-button {
40
- &.segment-button-checked {
41
- transform: scale(1.1); // Enable overflow effect
42
- }
43
- }
44
- }
45
- ```
@@ -1,56 +0,0 @@
1
- # Using `ion-item-group` with iOS26 Theme
2
-
3
- This theme aims to bring Ionic Framework applications as close as possible to iOS 26 design. In most cases, you can use your existing Ionic code as-is, but **only under specific conditions**, you need to add `ion-item-group`.
4
-
5
- ## When is `ion-item-group` required?
6
-
7
- It is only required when **both** of the following conditions are met:
8
-
9
- - You have enabled the `inset` property on `ion-list`
10
-
11
- Only when these conditions apply, you need to wrap your list items with `ion-item-group`.
12
-
13
- ## Implementation Example
14
-
15
- ```diff
16
- <ion-list inset=true>
17
- <ion-list-header><ion-label>Label</ion-label></ion-list-header>
18
- + <ion-item-group>
19
- <ion-item>...</ion-item>
20
- <ion-item>...</ion-item>
21
- + </ion-item-group>
22
- </ion-list>
23
- ```
24
-
25
- ## Why is this change necessary?
26
-
27
- ### Background: Challenges in iOS Design Reproduction
28
-
29
- By default in Ionic Framework, `ion-list` has a background color, and `ion-list-header` is treated as part of the list. However, with this structure, it's impossible to accurately reproduce **iOS's native design patterns**.
30
-
31
- ![](screenshots/why-ion-list-inset.png)
32
-
33
- ### Solution: Background Color Separation
34
-
35
- To faithfully reproduce iOS design, this theme makes the following changes:
36
-
37
- - Set `ion-list` background color to transparent
38
- - Delegate background color to `ion-item-group`
39
-
40
- This change allows `ion-list-header` to be treated as an independent element, achieving the native iOS appearance.
41
-
42
- ## Using the Same Design with Material Design
43
-
44
- If you want to use the same design pattern with Material Design theme, import the following CSS:
45
-
46
- ```css
47
- @import '@rdlabo/ionic-theme-ios26/css/md-ion-list-inset.css';
48
- ```
49
-
50
- This will apply the same `ion-item-group` pattern to the Material Design theme as well.
51
-
52
- ## Summary
53
-
54
- - **Most cases**: You can use your existing Ionic code as-is
55
- - **Specific conditions only**: `ion-item-group` is only required when setting using `inset` on `ion-list`
56
- - **Purpose**: To accurately reproduce iOS 26's native design patterns
@@ -1,136 +0,0 @@
1
- ---
2
- description: This rule provides comprehensive best practices and coding standards for Angular development, focusing on modern TypeScript, standalone components, signals, and performance optimizations.
3
- globs: ["**/*.{ts,html,scss,css}"]
4
- ---
5
-
6
- # Angular Best Practices
7
-
8
- This project adheres to modern Angular best practices, emphasizing maintainability, performance, accessibility, and scalability.
9
-
10
- ## TypeScript Best Practices
11
-
12
- * **Strict Type Checking:** Always enable and adhere to strict type checking. This helps catch errors early and improves code quality.
13
- * **Prefer Type Inference:** Allow TypeScript to infer types when they are obvious from the context. This reduces verbosity while maintaining type safety.
14
- * **Bad:**
15
- ```typescript
16
- let name: string = 'Angular';
17
- ```
18
- * **Good:**
19
- ```typescript
20
- let name = 'Angular';
21
- ```
22
- * **Avoid `any`:** Do not use the `any` type unless absolutely necessary as it bypasses type checking. Prefer `unknown` when a type is uncertain and you need to handle it safely.
23
-
24
- ## Angular Best Practices
25
-
26
- * **Standalone Components:** Always use standalone components, directives, and pipes. Avoid using `NgModules` for new features or refactoring existing ones.
27
- * **Implicit Standalone:** When creating standalone components, you do not need to explicitly set `standalone: true` inside the `@Component`, `@Directive` and `@Pipe` decorators, as it is implied by default.
28
- * **Bad:**
29
- ```typescript
30
- @Component({
31
- standalone: true,
32
- // ...
33
- })
34
- export class MyComponent {}
35
- ```
36
- * **Good:**
37
- ```typescript
38
- @Component({
39
- // `standalone: true` is implied
40
- // ...
41
- })
42
- export class MyComponent {}
43
- ```
44
- * **Signals for State Management:** Utilize Angular Signals for reactive state management within components and services.
45
- * **Lazy Loading:** Implement lazy loading for feature routes to improve initial load times of your application.
46
- * **NgOptimizedImage:** Use `NgOptimizedImage` for all static images to automatically optimize image loading and performance.
47
- * **Host bindings:** Do NOT use the `@HostBinding` and `@HostListener` decorators. Put host bindings inside the `host` object of the `@Component` or `@Directive` decorator instead.
48
-
49
- ## Components
50
-
51
- * **Single Responsibility:** Keep components small, focused, and responsible for a single piece of functionality.
52
- * **`input()` and `output()` Functions:** Prefer `input()` and `output()` functions over the `@Input()` and `@Output()` decorators for defining component inputs and outputs.
53
- * **Old Decorator Syntax:**
54
- ```typescript
55
- @Input() userId!: string;
56
- @Output() userSelected = new EventEmitter<string>();
57
- ```
58
- * **New Function Syntax:**
59
- ```typescript
60
- import { input, output } from '@angular/core';
61
-
62
- // ...
63
- userId = input<string>('');
64
- userSelected = output<string>();
65
- ```
66
- * **`computed()` for Derived State:** Use the `computed()` function from `@angular/core` for derived state based on signals.
67
- * **`ChangeDetectionStrategy.OnPush`:** Always set `changeDetection: ChangeDetectionStrategy.OnPush` in the `@Component` decorator for performance benefits by reducing unnecessary change detection cycles.
68
- * **Inline Templates:** Prefer inline templates (template: `...`) for small components to keep related code together. For larger templates, use external HTML files.
69
- * **Reactive Forms:** Prefer Reactive forms over Template-driven forms for complex forms, validation, and dynamic controls due to their explicit, immutable, and synchronous nature.
70
- * **No `ngClass` / `NgClass`:** Do not use the `ngClass` directive. Instead, use native `class` bindings for conditional styling.
71
- * **Bad:**
72
- ```html
73
- <section [ngClass]="{'active': isActive}"></section>
74
- ```
75
- * **Good:**
76
- ```html
77
- <section [class.active]="isActive"></section>
78
- <section [class]="{'active': isActive}"></section>
79
- <section [class]="myClasses"></section>
80
- ```
81
- * **No `ngStyle` / `NgStyle`:** Do not use the `ngStyle` directive. Instead, use native `style` bindings for conditional inline styles.
82
- * **Bad:**
83
- ```html
84
- <section [ngStyle]="{'font-size': fontSize + 'px'}"></section>
85
- ```
86
- * **Good:**
87
- ```html
88
- <section [style.font-size.px]="fontSize"></section>
89
- <section [style]="myStyles"></section>
90
- ```
91
-
92
- ## State Management
93
-
94
- * **Signals for Local State:** Use signals for managing local component state.
95
- * **`computed()` for Derived State:** Leverage `computed()` for any state that can be derived from other signals.
96
- * **Pure and Predictable Transformations:** Ensure state transformations are pure functions (no side effects) and predictable.
97
- * **Signal value updates:** Do NOT use `mutate` on signals, use `update` or `set` instead.
98
-
99
- ## Templates
100
-
101
- * **Simple Templates:** Keep templates as simple as possible, avoiding complex logic directly in the template. Delegate complex logic to the component's TypeScript code.
102
- * **Native Control Flow:** Use the new built-in control flow syntax (`@if`, `@for`, `@switch`) instead of the older structural directives (`*ngIf`, `*ngFor`, `*ngSwitch`).
103
- * **Old Syntax:**
104
- ```html
105
- <section *ngIf="isVisible">Content</section>
106
- <section *ngFor="let item of items">{{ item }}</section>
107
- ```
108
- * **New Syntax:**
109
- ```html
110
- @if (isVisible) {
111
- <section>Content</section>
112
- }
113
- @for (item of items; track item.id) {
114
- <section>{{ item }}</section>
115
- }
116
- ```
117
- * **Async Pipe:** Use the `async` pipe to handle observables in templates. This automatically subscribes and unsubscribes, preventing memory leaks.
118
-
119
- ## Services
120
-
121
- * **Single Responsibility:** Design services around a single, well-defined responsibility.
122
- * **`providedIn: 'root'`:** Use the `providedIn: 'root'` option when declaring injectable services to ensure they are singletons and tree-shakable.
123
- * **`inject()` Function:** Prefer the `inject()` function over constructor injection when injecting dependencies, especially within `provide` functions, `computed` properties, or outside of constructor context.
124
- * **Old Constructor Injection:**
125
- ```typescript
126
- constructor(private myService: MyService) {}
127
- ```
128
- * **New `inject()` Function:**
129
- ```typescript
130
- import { inject } from '@angular/core';
131
-
132
- export class MyComponent {
133
- private myService = inject(MyService);
134
- // ...
135
- }
136
- ```
@@ -1,15 +0,0 @@
1
- # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2
- # For additional information regarding the format and rule options, please see:
3
- # https://github.com/browserslist/browserslist#queries
4
-
5
- # For the full list of supported browsers by the Angular framework, please see:
6
- # https://angular.dev/reference/versions#browser-support
7
-
8
- # You can see what browsers were selected by your queries by running:
9
- # npx browserslist
10
-
11
- Chrome >=107
12
- Firefox >=106
13
- Edge >=107
14
- Safari >=16.1
15
- iOS >=16.1
@@ -1,16 +0,0 @@
1
- # Editor configuration, see https://editorconfig.org
2
- root = true
3
-
4
- [*]
5
- charset = utf-8
6
- indent_style = space
7
- indent_size = 2
8
- insert_final_newline = true
9
- trim_trailing_whitespace = true
10
-
11
- [*.ts]
12
- quote_type = single
13
-
14
- [*.md]
15
- max_line_length = off
16
- trim_trailing_whitespace = false
@@ -1,5 +0,0 @@
1
- {
2
- "recommendations": [
3
- "Webnative.webnative"
4
- ]
5
- }
@@ -1,3 +0,0 @@
1
- {
2
- "typescript.preferences.autoImportFileExcludePatterns": ["@ionic/angular/common", "@ionic/angular"]
3
- }
package/demo/angular.json DELETED
@@ -1,141 +0,0 @@
1
- {
2
- "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3
- "version": 1,
4
- "newProjectRoot": "projects",
5
- "projects": {
6
- "app": {
7
- "projectType": "application",
8
- "schematics": {
9
- "@ionic/angular-toolkit:page": {
10
- "styleext": "scss",
11
- "standalone": true
12
- }
13
- },
14
- "root": "",
15
- "sourceRoot": "src",
16
- "prefix": "app",
17
- "architect": {
18
- "build": {
19
- "builder": "@angular-devkit/build-angular:application",
20
- "options": {
21
- "outputPath": {
22
- "base": "www",
23
- "browser": ""
24
- },
25
- "index": "src/index.html",
26
- "tsConfig": "tsconfig.app.json",
27
- "inlineStyleLanguage": "scss",
28
- "assets": [
29
- {
30
- "glob": "**/*",
31
- "input": "src/assets",
32
- "output": "assets"
33
- }
34
- ],
35
- "styles": ["src/global.scss", "src/theme/variables.scss"],
36
- "scripts": [],
37
- "browser": "src/main.ts"
38
- },
39
- "configurations": {
40
- "production": {
41
- "budgets": [
42
- {
43
- "type": "initial",
44
- "maximumWarning": "2mb",
45
- "maximumError": "5mb"
46
- },
47
- {
48
- "type": "anyComponentStyle",
49
- "maximumWarning": "2kb",
50
- "maximumError": "4kb"
51
- }
52
- ],
53
- "outputHashing": "all"
54
- },
55
- "development": {
56
- "optimization": false,
57
- "extractLicenses": false,
58
- "sourceMap": true,
59
- "namedChunks": true
60
- },
61
- "ci": {
62
- "progress": false
63
- }
64
- },
65
- "defaultConfiguration": "production"
66
- },
67
- "serve": {
68
- "builder": "@angular-devkit/build-angular:dev-server",
69
- "configurations": {
70
- "production": {
71
- "buildTarget": "app:build:production"
72
- },
73
- "development": {
74
- "buildTarget": "app:build:development"
75
- },
76
- "ci": {
77
- "progress": false
78
- }
79
- },
80
- "defaultConfiguration": "development"
81
- },
82
- "extract-i18n": {
83
- "builder": "@angular-devkit/build-angular:extract-i18n",
84
- "options": {
85
- "buildTarget": "app:build"
86
- }
87
- },
88
- "test": {
89
- "builder": "@angular-devkit/build-angular:karma",
90
- "options": {
91
- "main": "src/test.ts",
92
- "tsConfig": "tsconfig.spec.json",
93
- "karmaConfig": "karma.conf.js",
94
- "inlineStyleLanguage": "scss",
95
- "assets": [
96
- {
97
- "glob": "**/*",
98
- "input": "src/assets",
99
- "output": "assets"
100
- }
101
- ],
102
- "styles": ["src/global.scss", "src/theme/variables.scss"],
103
- "scripts": []
104
- },
105
- "configurations": {
106
- "ci": {
107
- "progress": false,
108
- "watch": false
109
- }
110
- }
111
- },
112
- "lint": {
113
- "builder": "@angular-eslint/builder:lint",
114
- "options": {
115
- "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
116
- }
117
- }
118
- }
119
- }
120
- },
121
- "cli": {
122
- "schematicCollections": [
123
- "@ionic/angular-toolkit"
124
- ],
125
- "analytics": "cbe1df8d-204f-4a38-b88d-9f3a65fd6af4"
126
- },
127
- "schematics": {
128
- "@ionic/angular-toolkit:component": {
129
- "styleext": "scss"
130
- },
131
- "@ionic/angular-toolkit:page": {
132
- "styleext": "scss"
133
- },
134
- "@angular-eslint/schematics:application": {
135
- "setParserOptionsProject": true
136
- },
137
- "@angular-eslint/schematics:library": {
138
- "setParserOptionsProject": true
139
- }
140
- }
141
- }
@@ -1,9 +0,0 @@
1
- import type { CapacitorConfig } from '@capacitor/cli';
2
-
3
- const config: CapacitorConfig = {
4
- appId: 'io.ionic.starter',
5
- appName: 'demo',
6
- webDir: 'www',
7
- };
8
-
9
- export default config;
@@ -1,49 +0,0 @@
1
- // @ts-check
2
- const eslint = require("@eslint/js");
3
- const tseslint = require("typescript-eslint");
4
- const angular = require("angular-eslint");
5
- const rdlabo = require('@rdlabo/eslint-plugin-rules');
6
-
7
- module.exports = tseslint.config(
8
- {
9
- files: ["**/*.ts"],
10
- plugins: {
11
- '@rdlabo/rules': rdlabo,
12
- },
13
- extends: [
14
- eslint.configs.recommended,
15
- ...tseslint.configs.recommended,
16
- ...tseslint.configs.stylistic,
17
- ...angular.configs.tsRecommended,
18
- ],
19
- processor: angular.processInlineTemplates,
20
- rules: {
21
- "@typescript-eslint/no-explicit-any": "off",
22
- "@typescript-eslint/no-unused-vars": "off",
23
- "@angular-eslint/directive-selector": "off",
24
- "@angular-eslint/component-selector": "off",
25
- "@angular-eslint/no-empty-lifecycle-method": "off",
26
- "@typescript-eslint/no-empty-function": "off",
27
- '@rdlabo/rules/deny-constructor-di': 'error',
28
- '@rdlabo/rules/deny-import-from-ionic-module': 'error',
29
- '@rdlabo/rules/implements-ionic-lifecycle': 'error',
30
- '@rdlabo/rules/deny-soft-private-modifier': 'error',
31
- '@rdlabo/rules/signal-use-as-signal': 'error',
32
- '@rdlabo/rules/signal-use-as-signal-template': 'error',
33
- '@rdlabo/rules/component-property-use-readonly': 'error',
34
- },
35
- },
36
- {
37
- files: ["**/*.html"],
38
- plugins: {
39
- '@rdlabo/rules': rdlabo,
40
- },
41
- extends: [
42
- ...angular.configs.templateRecommended,
43
- ...angular.configs.templateAccessibility,
44
- ],
45
- rules: {
46
- '@rdlabo/rules/ionic-attr-type-check': 'error',
47
- },
48
- }
49
- );
@@ -1,7 +0,0 @@
1
- {
2
- "name": "demo",
3
- "integrations": {
4
- "capacitor": {}
5
- },
6
- "type": "angular-standalone"
7
- }