@rdlabo/ionic-theme-ios26 0.0.2 → 0.0.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 (123) hide show
  1. package/.cursor/rules/css-compilation.mdc +34 -0
  2. package/.cursor/rules/demo-application.mdc +39 -0
  3. package/.cursor/rules/development-workflow.mdc +41 -0
  4. package/.cursor/rules/project-role.mdc +21 -0
  5. package/.github/FUNDING.yml +15 -0
  6. package/.husky/pre-commit +1 -0
  7. package/.lintstagedrc.yml +6 -0
  8. package/.prettierignore +3 -0
  9. package/FEEDBACK.md +25 -0
  10. package/README.md +58 -87
  11. package/USING_ION_ITEM_GROUP.md +58 -0
  12. package/build-sass.js +25 -0
  13. package/demo/ .cursor/rules/angular-20.mdc +136 -0
  14. package/demo/.browserslistrc +15 -0
  15. package/demo/.editorconfig +16 -0
  16. package/demo/.vscode/extensions.json +5 -0
  17. package/demo/.vscode/settings.json +3 -0
  18. package/demo/angular.json +141 -0
  19. package/demo/capacitor.config.ts +9 -0
  20. package/demo/eslint.config.js +47 -0
  21. package/demo/ionic.config.json +7 -0
  22. package/demo/karma.conf.js +44 -0
  23. package/demo/package-lock.json +20001 -0
  24. package/demo/package.json +60 -0
  25. package/demo/src/app/album/album-page.component.html +24 -0
  26. package/demo/src/app/album/album-page.component.scss +31 -0
  27. package/demo/src/app/album/album-page.component.spec.ts +21 -0
  28. package/demo/src/app/album/album-page.component.ts +24 -0
  29. package/demo/src/app/app.component.html +3 -0
  30. package/demo/src/app/app.component.ts +16 -0
  31. package/demo/src/app/app.config.ts +17 -0
  32. package/demo/src/app/app.routes.ts +8 -0
  33. package/demo/src/app/health/health-page.component.html +17 -0
  34. package/demo/src/app/health/health-page.component.scss +0 -0
  35. package/demo/src/app/health/health-page.component.spec.ts +21 -0
  36. package/demo/src/app/health/health-page.component.ts +14 -0
  37. package/demo/src/app/index/index-page.component.html +41 -0
  38. package/demo/src/app/index/index-page.component.scss +0 -0
  39. package/demo/src/app/index/index-page.component.spec.ts +21 -0
  40. package/demo/src/app/index/index-page.component.ts +102 -0
  41. package/demo/src/app/index/index.routes.ts +25 -0
  42. package/demo/src/app/index/pages/action-sheet/action-sheet.page.html +33 -0
  43. package/demo/src/app/index/pages/action-sheet/action-sheet.page.scss +0 -0
  44. package/demo/src/app/index/pages/action-sheet/action-sheet.page.spec.ts +17 -0
  45. package/demo/src/app/index/pages/action-sheet/action-sheet.page.ts +75 -0
  46. package/demo/src/app/index/pages/action-sheet/action-sheet.util.ts +28 -0
  47. package/demo/src/app/index/pages/alert/alert.page.html +33 -0
  48. package/demo/src/app/index/pages/alert/alert.page.scss +0 -0
  49. package/demo/src/app/index/pages/alert/alert.page.spec.ts +17 -0
  50. package/demo/src/app/index/pages/alert/alert.page.ts +75 -0
  51. package/demo/src/app/index/pages/alert/alert.util.ts +21 -0
  52. package/demo/src/app/index/pages/button/button.page.html +90 -0
  53. package/demo/src/app/index/pages/button/button.page.scss +0 -0
  54. package/demo/src/app/index/pages/button/button.page.spec.ts +17 -0
  55. package/demo/src/app/index/pages/button/button.page.ts +53 -0
  56. package/demo/src/app/index/pages/checkbox/checkbox.page.html +66 -0
  57. package/demo/src/app/index/pages/checkbox/checkbox.page.scss +0 -0
  58. package/demo/src/app/index/pages/checkbox/checkbox.page.spec.ts +17 -0
  59. package/demo/src/app/index/pages/checkbox/checkbox.page.ts +47 -0
  60. package/demo/src/app/settings/settings-page.component.html +120 -0
  61. package/demo/src/app/settings/settings-page.component.scss +33 -0
  62. package/demo/src/app/settings/settings-page.component.spec.ts +21 -0
  63. package/demo/src/app/settings/settings-page.component.ts +55 -0
  64. package/demo/src/app/tabs/tabs.page.html +23 -0
  65. package/demo/src/app/tabs/tabs.page.scss +9 -0
  66. package/demo/src/app/tabs/tabs.page.spec.ts +26 -0
  67. package/demo/src/app/tabs/tabs.page.ts +28 -0
  68. package/demo/src/app/tabs/tabs.routes.ts +41 -0
  69. package/demo/src/assets/.gitkeep +0 -0
  70. package/demo/src/favicon.ico +0 -0
  71. package/demo/src/global.scss +47 -0
  72. package/demo/src/index.html +24 -0
  73. package/demo/src/main.ts +5 -0
  74. package/demo/src/theme/theme-ios26.scss +25 -0
  75. package/demo/src/theme/variables.scss +2 -0
  76. package/demo/tsconfig.app.json +14 -0
  77. package/demo/tsconfig.json +30 -0
  78. package/demo/tsconfig.spec.json +17 -0
  79. package/package.json +38 -11
  80. package/prettier.config.js +18 -0
  81. package/screenshots/ios26.png +0 -0
  82. package/screenshots/why-ion-list-inset.png +0 -0
  83. package/src/components/ion-action-sheet.scss +42 -0
  84. package/src/components/ion-alert.scss +31 -0
  85. package/src/components/ion-button.scss +111 -0
  86. package/src/components/ion-card.scss +3 -0
  87. package/src/components/ion-fab.scss +16 -0
  88. package/src/components/ion-list.scss +33 -0
  89. package/src/components/ion-modal.scss +6 -0
  90. package/src/components/ion-popover.scss +21 -0
  91. package/src/components/ion-searchbar.scss +37 -0
  92. package/src/components/ion-segment.scss +10 -0
  93. package/src/components/ion-tabs.scss +47 -0
  94. package/src/components/ion-toast.scss +3 -0
  95. package/src/components/ion-toggle.scss +47 -0
  96. package/src/components-dark/ion-button.scss +28 -0
  97. package/src/components-dark/theme-dark.scss +14 -0
  98. package/src/ionic-theme-dark-class.scss +6 -0
  99. package/src/ionic-theme-dark-system.scss +8 -0
  100. package/src/ionic-theme-ios26.scss +32 -0
  101. package/src/md-ion-list-inset.scss +19 -0
  102. package/src/utils/api.scss +20 -0
  103. package/src/utils/default-variables.scss +10 -0
  104. package/src/utils/theme-list-inset.scss +92 -0
  105. package/src/utils/translucent.scss +70 -0
  106. package/tsconfig.json +5 -0
  107. package/css/ion-list-inset.css +0 -247
  108. package/css/ion-list-inset.css.map +0 -1
  109. package/css/ionic-theme-ios26.css +0 -349
  110. package/css/ionic-theme-ios26.css.map +0 -1
  111. package/fesm2022/rdlabo-ionic-theme-ios26.mjs +0 -4
  112. package/fesm2022/rdlabo-ionic-theme-ios26.mjs.map +0 -1
  113. package/index.d.ts +0 -3
  114. package/src/assets/ion-list-inset.scss +0 -198
  115. package/src/assets/ios-design/ion-button.scss +0 -68
  116. package/src/assets/ios-design/ion-popover.scss +0 -23
  117. package/src/assets/ios-design/ion-searchbar.scss +0 -44
  118. package/src/assets/ios-design/ion-segment.scss +0 -12
  119. package/src/assets/ios-design/ion-tabs.scss +0 -60
  120. package/src/assets/ios-design/ion-toggle.scss +0 -8
  121. package/src/assets/ios-design/ios-design-dark.scss +0 -28
  122. package/src/assets/ios-design.scss +0 -110
  123. package/src/assets/ios-variables.scss +0 -38
@@ -0,0 +1,34 @@
1
+ ---
2
+ description: SCSS to CSS compilation process and build workflow
3
+ globs: *.scss,*.css,package.json
4
+ ---
5
+
6
+ # CSS Compilation Process
7
+
8
+ ## ビルドプロセス
9
+
10
+ ### ソースファイル
11
+ - **入力**: `src/` ディレクトリ内のSCSSファイル
12
+ - **メインファイル**: [src/ionic-theme-ios26.scss](mdc:src/ionic-theme-ios26.scss)
13
+
14
+ ### 出力ファイル
15
+ - **出力**: `dist/css/` ディレクトリ内のCSSファイル
16
+ - **生成ファイル**:
17
+ - [dist/css/ionic-theme-ios26.min.css](mdc:dist/css/ionic-theme-ios26.min.css): メインCSSファイル(圧縮版)
18
+ - [dist/css/ionic-theme-ios26.min.css.map](mdc:dist/css/ionic-theme-ios26.min.css.map): ソースマップ
19
+ - [dist/css/md-ion-list-inset.min.css](mdc:dist/css/md-ion-list-inset.min.css): インセットリスト専用CSS(圧縮版)
20
+ - [dist/css/md-ion-list-inset.min.css.map](mdc:dist/css/md-ion-list-inset.min.css.map): ソースマップ
21
+
22
+ ## コンパイル時の注意事項
23
+
24
+ 1. **依存関係**: [package.json](mdc:package.json)でビルドツールの依存関係を確認
25
+ 2. **ソースマップ**: 開発時のデバッグ用にソースマップファイルも生成
26
+ 3. **最適化**: 本番用にはCSSの最適化(minify)を検討
27
+ 4. **テスト**: コンパイル後は`demo/`アプリケーションで動作確認
28
+
29
+ ## ファイル構造の一貫性
30
+
31
+ - SCSSファイルは`src/`に配置
32
+ - コンパイル後のCSSファイルは`dist/css/`に配置
33
+ - デモアプリケーションは`demo/`に配置
34
+ - スクリーンショットなどのリソースは`screenshots/`に配置
@@ -0,0 +1,39 @@
1
+ ---
2
+ description: Angular demo application structure and usage
3
+ globs: demo/**/*
4
+ ---
5
+
6
+ # Demo Application (Angular)
7
+
8
+ ## デモアプリケーションの目的
9
+
10
+ `demo/` ディレクトリには、Ionic iOS26テーマの動作確認用のAngularアプリケーションが含まれています。
11
+
12
+ ## 主要なコンポーネント
13
+
14
+ ### ページコンポーネント
15
+ - [album-page.component](mdc:demo/src/app/album/): アルバムページ(リスト表示の確認)
16
+ - [health-page.component](mdc:demo/src/app/health/): ヘルスページ(ヘルス関連UIの確認)
17
+ - [settings-page.component](mdc:demo/src/app/settings/): 設定ページ(設定UIの確認)
18
+ - [simple-page.component](mdc:demo/src/app/simple/): シンプルページ(基本的なコンポーネントの確認)
19
+
20
+ ### ナビゲーション
21
+ - [tabs.page](mdc:demo/src/app/tabs/): タブベースのナビゲーション
22
+
23
+ ## テーマファイル
24
+
25
+ - [demo/src/theme/theme-ios26.scss](mdc:demo/src/theme/theme-ios26.scss): デモアプリ用のテーマ設定
26
+ - [demo/src/global.scss](mdc:demo/src/global.scss): グローバルスタイル
27
+
28
+ ## 使用方法
29
+
30
+ 1. **開発サーバー起動**: `cd demo && npm start` または `ionic serve`
31
+ 2. **テーマ確認**: 各ページでiOS26テーマの適用状況を確認
32
+ 3. **スタイル調整**: `src/` のSCSSファイルを編集後、デモアプリで確認
33
+
34
+ ## 設定ファイル
35
+
36
+ - [demo/angular.json](mdc:demo/angular.json): Angular CLI設定
37
+ - [demo/package.json](mdc:demo/package.json): デモアプリの依存関係
38
+ - [demo/ionic.config.json](mdc:demo/ionic.config.json): Ionic設定
39
+ - [demo/capacitor.config.ts](mdc:demo/capacitor.config.ts): Capacitor設定
@@ -0,0 +1,41 @@
1
+ ---
2
+ description: Development workflow and directory structure guidelines
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # Development Workflow
7
+
8
+ ## ディレクトリ構造の詳細
9
+
10
+ ### src/ ディレクトリ
11
+ - **src/components/**: 個別のIonicコンポーネント用のSCSSファイル
12
+ - [ion-button.scss](mdc:src/components/ion-button.scss): ボタンスタイル
13
+ - [ion-list.scss](mdc:src/components/ion-list.scss): リストスタイル
14
+ - [ion-popover.scss](mdc:src/components/ion-popover.scss): ポップオーバースタイル
15
+ - [ion-searchbar.scss](mdc:src/components/ion-searchbar.scss): 検索バースタイル
16
+ - [ion-tabs.scss](mdc:src/components/ion-tabs.scss): タブスタイル
17
+ - [ion-toggle.scss](mdc:src/components/ion-toggle.scss): トグルスタイル
18
+
19
+ - **src/utils/**: ユーティリティファイル
20
+ - [api.scss](mdc:src/utils/api.scss): API関連ユーティリティ
21
+ - [theme-dark.scss](mdc:src/utils/theme-dark.scss): ダークテーマ用ユーティリティ
22
+ - [theme-list-inset.scss](mdc:src/utils/theme-list-inset.scss): インセットリスト用ユーティリティ
23
+ - [translucent.scss](mdc:src/utils/translucent.scss): 半透明効果用ユーティリティ
24
+
25
+ - **src/**: ルートレベルのファイル
26
+ - [default-variables.scss](mdc:src/default-variables.scss): デフォルト変数定義
27
+ - [md-ion-list-inset.scss](mdc:src/md-ion-list-inset.scss): Material Design用インセットリスト
28
+
29
+ - **src/ionic-theme-ios26.scss**: メインのSCSSファイル(全てのコンポーネントを統合)
30
+
31
+ ### demo/ ディレクトリ
32
+ - Angular 20ベースのデモアプリケーション
33
+ - 各ページコンポーネントでテーマの動作確認
34
+ - [demo/src/theme/theme-ios26.scss](mdc:demo/src/theme/theme-ios26.scss): デモアプリ用テーマファイル
35
+
36
+ ## 開発時の注意事項
37
+
38
+ 1. **SCSSファイルの編集**: `src/` ディレクトリ内のSCSSファイルを編集
39
+ 2. **コンパイル**: 変更後は適切なビルドコマンドでCSSファイルを生成
40
+ 3. **確認**: `demo/` アプリケーションでスタイルの動作確認
41
+ 4. **ドキュメント**: READMEは英語で記述(OSS配布のため)
@@ -0,0 +1,21 @@
1
+ ---
2
+ description: Ionic iOS26 Theme Library Project Overview
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # Ionic iOS26 Theme Library Project
7
+
8
+ このプロジェクトは、Ionic FrameworkをiOS26のルックアンドフィールにするためのCSSライブラリです。OSSで配布するため、READMEの記述は基本的に英語になります。
9
+
10
+ ## プロジェクト構造
11
+
12
+ - **src/**: コンパイル前のSCSSファイルが配置されます
13
+ - **css/**: コンパイル後のCSSファイルが配置されます
14
+ - **demo/**: 開発と確認に用いるAngularプロジェクトです
15
+
16
+ ## 主要なファイル
17
+
18
+ - [package.json](mdc:package.json): プロジェクトの依存関係とビルドスクリプト
19
+ - [src/ionic-theme-ios26.scss](mdc:src/ionic-theme-ios26.scss): メインのSCSSファイル
20
+ - [demo/](mdc:demo/): Angularデモアプリケーション
21
+ - [README.md](mdc:README.md): プロジェクトの説明(英語)
@@ -0,0 +1,15 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: rdlabo
4
+ patreon: # Replace with a single Patreon username
5
+ open_collective: # Replace with a single Open Collective username
6
+ ko_fi: # Replace with a single Ko-fi username
7
+ tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
+ liberapay: # Replace with a single Liberapay username
10
+ issuehunt: # Replace with a single IssueHunt username
11
+ lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12
+ polar: # Replace with a single Polar username
13
+ buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14
+ thanks_dev: # Replace with a single thanks.dev username
15
+ custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
@@ -0,0 +1 @@
1
+ npx lint-staged
@@ -0,0 +1,6 @@
1
+ "*.ts":
2
+ - prettier --parser typescript --write
3
+ "*.html":
4
+ - prettier --parser angular --write
5
+ "*.scss":
6
+ - prettier --parser scss --write
@@ -0,0 +1,3 @@
1
+ node_modules
2
+ dist
3
+ www
package/FEEDBACK.md ADDED
@@ -0,0 +1,25 @@
1
+ ## feat(): ion-config new property for disable ion-back-button Animation
2
+
3
+ 遷移前画面で `collapse` を使っており、遷移後画面で `ion-buttons ion-back-button` を指定している場合、iOS18以前のアニメーション処理が行われます。これは、iOS26以降では不要なので、無効化できるプロパティが必要です。
4
+
5
+ https://github.com/ionic-team/ionic-framework/blob/3b80473f2fd5ad4da5a9f5d66f783a69909c8965/core/src/utils/transition/ios.transition.ts#L333C31-L337
6
+ - enteringBackButtonTextAnimation
7
+ - enteringBackButtonIconAnimation
8
+ - enteringBackButtonAnimation
9
+
10
+ 現在、 `ion-buttons > ion-back-button` をセレクタする関係上、 `ion-back-button` を `ion-buttons` の中にいれない対応をとっています。。
11
+
12
+ # feat(): ion-content[fullscreen=true] will have .content-fullscreen class
13
+
14
+ iOS26の上下セーフエリアのぼかしを入れるため、ion-contentがfullscreen設定されているかのclassが必要です。
15
+ 以下のようなセレクターの指定を行いたいです。
16
+
17
+ ```css
18
+ .ion-page:has(ion-header.header-translucent) ion-content.content-fullscreen {
19
+ }
20
+
21
+ .ion-page:has(ion-header.footer-translucent) ion-content.content-fullscreen {
22
+ }
23
+ ```
24
+
25
+ 現在、 `translucent` な要素を使っている場合はfullscreenを指定している前提で実装していますが、これは確実ではありません。
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  A CSS theme library that applies iOS26 design system to Ionic applications.
4
4
 
5
+ ![](screenshots/ios26.png)
6
+
5
7
  DEMO is here: https://ionic-theme-ios26.netlify.app/
6
8
 
7
9
  ## Overview
@@ -10,130 +12,99 @@ This library provides CSS files to apply the iOS26 design system used in real pr
10
12
 
11
13
  > **⚠️ Under Development**: This library is currently in the development and consideration phase as an OSS project, based on files copied from real projects. We are working on API stability and documentation improvement before full-scale use.
12
14
 
15
+ ## 💖 Support This Project
16
+
17
+ Enjoying this project? Your support helps keep it alive and growing!
18
+ Sponsoring means you directly contribute to new features, improvements, and maintenance.
19
+
20
+ [Become a Sponsor →](https://github.com/sponsors/rdlabo)
13
21
 
14
22
  ## Setup
15
23
 
16
24
  > **⚠️ Warning**: This library is under development. API changes and breaking changes may occur before full-scale use.
17
25
 
18
- ### 1. Installation
19
-
20
26
  ```bash
21
27
  npm install @rdlabo/ionic-theme-ios26
22
28
  ```
23
29
 
24
- ### 2. CSS File Import (Required)
25
-
26
- Import the theme in your project's main CSS file (e.g., `src/styles.scss`) and set the `--max-safe-area` variable:
30
+ And import the theme in your project's main CSS file (e.g., `src/styles.scss`) and set the `--ios26-floating-safe-area-bottom` variable:
27
31
 
28
32
  ```scss
29
- @import '@rdlabo/ionic-theme-ios26/css/ionic-theme-ios26.css';
30
- @import '@rdlabo/ionic-theme-ios26/css/ion-list-inset.css';
33
+ @import '@rdlabo/ionic-theme-ios26/dist/css/ionic-theme-ios26.min.css';
31
34
 
32
- /* Required: Safe area configuration */
33
35
  :root {
34
- --max-safe-area: calc(max(10px, var(--ion-safe-area-bottom, 0px)) + var(--admob-safe-area, 0px));
36
+ /*
37
+ * This is default value. If you should change value, update this variable.
38
+ * ex) Using admob banner ad.
39
+ * --ios26-floating-safe-area-bottom: calc(max(10px, var(--ion-safe-area-bottom, 0px)) + var(--admob-safe-area, 0px));
40
+ */
41
+ --ios26-floating-safe-area-bottom: max(10px, var(--ion-safe-area-bottom, 0px));
35
42
  }
36
43
  ```
37
44
 
38
- > **Important**: The theme will not work correctly without the `--max-safe-area` setting. This configuration is mandatory.
39
-
40
- ### 3. Framework-specific Configuration Examples
45
+ ## Important Notes
41
46
 
42
- #### For Angular Projects
47
+ ### Support Dark Mode
43
48
 
44
- Add CSS file to `angular.json`:
49
+ We support Ionic Dark Mode. More information is here: https://ionicframework.com/docs/theming/dark-mode
45
50
 
46
- ```json
47
- {
48
- "styles": [
49
- "node_modules/@rdlabo/ionic-theme-ios26/css/ionic-theme-ios26.css",
50
- "node_modules/@rdlabo/ionic-theme-ios26/css/ion-list-inset.css"
51
- ]
52
- }
53
- ```
51
+ | Mode | Code |
52
+ |-----------|------------------------------------------------------------------------------|
53
+ | Always | Overwrite library colors on the :root selector. |
54
+ | System | @import '@rdlabo/ionic-theme-ios26/dist/css/ionic-theme-dark-system.min.css' |
55
+ | CSS Class | @import '@rdlabo/ionic-theme-ios26/dist/css/ionic-theme-dark-class.min.css' |
54
56
 
55
- **Required**: Set `--max-safe-area` in `src/styles.scss`:
57
+ ### `ion-back-button` `ion-buttons` に入れないで使う必要があります
56
58
 
57
- ```scss
58
- :root {
59
- --max-safe-area: calc(max(10px, var(--ion-safe-area-bottom, 0px)) + var(--admob-safe-area, 0px));
60
- }
61
- ```
59
+ 以下の条件を満たす時、Ionic Frameworkは `ion-back-button` をプログラムで生成して、アニメーションで表示します。
62
60
 
63
- #### For React Projects
61
+ - 遷移前のページに `ion-header[collapse='condense']` を使用している
62
+ - 遷移後のページに、 `ion-buttons ion-back-button` がある
64
63
 
65
- Import CSS file in `index.js` or `App.js`:
64
+ これはiOS26のUIではなく、このプログラムを避けるために以下の実装を行う必要があります。
66
65
 
67
- ```javascript
68
- import '@rdlabo/ionic-theme-ios26/css/ionic-theme-ios26.css';
69
- import '@rdlabo/ionic-theme-ios26/css/ion-list-inset.css';
66
+ ```diff
67
+ <ion-header>
68
+ - <ion-buttons slot="start">
69
+ - <ion-back-button></ion-back-button>
70
+ - </ion-buttons>
71
+ + <ion-back-button slot=start></ion-back-button>
72
+ </ion-header>
70
73
  ```
71
74
 
72
- **Required**: Set `--max-safe-area` in main CSS file:
73
-
74
- ```css
75
- :root {
76
- --max-safe-area: calc(max(10px, var(--ion-safe-area-bottom, 0px)) + var(--admob-safe-area, 0px));
77
- }
78
- ```
75
+ ### Using `ion-item-group`
79
76
 
80
- #### For Vue.js Projects
77
+ Under specific conditions, you need to use `ion-item-group`. For details, please refer to [USING_ION_ITEM_GROUP.md](./USING_ION_ITEM_GROUP.md).
81
78
 
82
- Import CSS file in `main.js`:
79
+ ### You can also use the liquid glass mixin
83
80
 
84
- ```javascript
85
- import '@rdlabo/ionic-theme-ios26/css/ionic-theme-ios26.css';
86
- import '@rdlabo/ionic-theme-ios26/css/ion-list-inset.css';
87
- ```
81
+ You can use the liquid glass mixin by importing SCSS files from the main package.
88
82
 
89
- **Required**: Set `--max-safe-area` in main CSS file:
83
+ ```scss
84
+ @use '@rdlabo/ionic-theme-ios26/src/utils/api';
90
85
 
91
- ```css
92
- :root {
93
- --max-safe-area: calc(max(10px, var(--ion-safe-area-bottom, 0px)) + var(--admob-safe-area, 0px));
86
+ ion-textarea label.textarea-wrapper {
87
+ @include api.glass-background;
94
88
  }
95
89
  ```
96
90
 
91
+ ## CSS Utility Classes
97
92
 
98
- ## Development Status
99
-
100
- This library is currently in the development and consideration phase. We are working on the following tasks:
101
-
102
- - [ ] API stabilization
103
- - [ ] Documentation improvement
104
- - [ ] Test coverage enhancement
105
- - [ ] Performance optimization
106
- - [ ] Community feedback collection
107
-
108
- ## Developer Information
109
-
110
- ### Build
111
-
112
- ```bash
113
- ng build ionic-theme-ios26
114
- ```
115
-
116
- ### Test
117
-
118
- ```bash
119
- ng test
120
- ```
121
-
122
- ## License
123
-
124
- MIT License
93
+ ### .ios26-liquid-glass
125
94
 
126
- ## Contributing
95
+ Apply this class to components where you want to use the iOS26 design that is not automatically applied. Supported selectors are as follows:
127
96
 
128
- This project is under development. We welcome feedback and suggestions:
97
+ - `ion-button`
98
+ - `ion-buttons.ios26-liquid-glass ion-button`
99
+ - `ion-button.ios26-liquid-glass`
129
100
 
130
- - Issue reporting
131
- - Feature requests
132
- - Documentation improvements
133
- - Code review participation
101
+ ### .ios26-no-liquid-glass
134
102
 
135
- ## Support
103
+ Many components automatically have the iOS26 design applied, but apply this class when you don't want it. Supported selectors are as follows:
136
104
 
137
- - **Under Development**: No formal support is provided
138
- - **Feedback**: Please report issues on GitHub Issues page
139
- - **Community**: Participate in developer community discussions
105
+ - `ion-button`
106
+ - `ion-header > ion-toolbar > ion-buttons.ios26-no-liquid-glass > ion-button`
107
+ - `ion-header > ion-toolbar > ion-buttons.ios26-no-liquid-glass > ion-back-button`
108
+ - `ion-header > ion-toolbar > ion-buttons > ion-button.ios26-no-liquid-glass`
109
+ - `ion-header > ion-toolbar > ion-buttons > ion-back-button.ios26-no-liquid-glass`
110
+ - `ion-popover.ios26-no-liquid-glass`
@@ -0,0 +1,58 @@
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-content color="light">
17
+ <ion-list inset=true>
18
+ <ion-list-header><ion-label>Label</ion-label></ion-list-header>
19
+ + <ion-item-group>
20
+ <ion-item>...</ion-item>
21
+ <ion-item>...</ion-item>
22
+ + </ion-item-group>
23
+ </ion-list>
24
+ </ion-content>
25
+ ```
26
+
27
+ ## Why is this change necessary?
28
+
29
+ ### Background: Challenges in iOS Design Reproduction
30
+
31
+ 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**.
32
+
33
+ ![](screenshots/why-ion-list-inset.png)
34
+
35
+ ### Solution: Background Color Separation
36
+
37
+ To faithfully reproduce iOS design, this theme makes the following changes:
38
+
39
+ - Set `ion-list` background color to transparent
40
+ - Delegate background color to `ion-item-group`
41
+
42
+ This change allows `ion-list-header` to be treated as an independent element, achieving the native iOS appearance.
43
+
44
+ ## Using the Same Design with Material Design
45
+
46
+ If you want to use the same design pattern with Material Design theme, import the following CSS:
47
+
48
+ ```css
49
+ @import '@rdlabo/ionic-theme-ios26/css/md-ion-list-inset.css';
50
+ ```
51
+
52
+ This will apply the same `ion-item-group` pattern to the Material Design theme as well.
53
+
54
+ ## Summary
55
+
56
+ - **Most cases**: You can use your existing Ionic code as-is
57
+ - **Specific conditions only**: `ion-item-group` is only required when setting using `inset` on `ion-list`
58
+ - **Purpose**: To accurately reproduce iOS 26's native design patterns
package/build-sass.js ADDED
@@ -0,0 +1,25 @@
1
+ const { execSync } = require('child_process');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ const srcDir = path.resolve(__dirname, 'src');
6
+ const outDir = path.resolve(__dirname, 'dist/css');
7
+
8
+ // 出力先ディレクトリがなければ作る
9
+ if (!fs.existsSync(outDir)) {
10
+ fs.mkdirSync(outDir, { recursive: true });
11
+ }
12
+
13
+ // src ディレクトリの .scss ファイルを取得
14
+ const scssFiles = fs.readdirSync(srcDir).filter(f => f.endsWith('.scss'));
15
+
16
+ scssFiles.forEach(file => {
17
+ const srcPath = path.join(srcDir, file);
18
+ const fileName = path.basename(file, '.scss');
19
+ const outPath = path.join(outDir, `${fileName}.min.css`);
20
+
21
+ console.log(`Building ${srcPath} → ${outPath}`);
22
+ execSync(`npx sass ${srcPath} ${outPath} --style=compressed`, { stdio: 'inherit' });
23
+ });
24
+
25
+ console.log('All SCSS files compiled successfully!');
@@ -0,0 +1,136 @@
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
+ ```
@@ -0,0 +1,15 @@
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
@@ -0,0 +1,16 @@
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
@@ -0,0 +1,5 @@
1
+ {
2
+ "recommendations": [
3
+ "Webnative.webnative"
4
+ ]
5
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "typescript.preferences.autoImportFileExcludePatterns": ["@ionic/angular/common", "@ionic/angular"]
3
+ }