@pplancq/react-template 2.8.16 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/_README.md +57 -52
  3. package/mise.toml +2 -2
  4. package/package.json +28 -27
  5. package/scripts/removeDemo.cjs +105 -66
  6. package/src/README.md +81 -0
  7. package/src/app/App.tsx +18 -0
  8. package/src/{bootstrap.tsx → app/AppHTMLElement.tsx} +2 -2
  9. package/src/app/README.md +69 -0
  10. package/src/{__tests__/bootstraps.test.tsx → app/__tests__/AppHTMLElement.test.tsx} +5 -5
  11. package/src/app/config/serviceContainer.ts +6 -0
  12. package/src/app/providers/Providers/Providers.tsx +18 -0
  13. package/src/{providers → app/providers}/QueryClientProvider/QueryClientProvider.tsx +3 -3
  14. package/src/app/providers/ServiceProvider/ServiceContext.ts +8 -0
  15. package/src/app/providers/ServiceProvider/ServiceProvider.tsx +14 -0
  16. package/src/app/routing/Router.tsx +14 -0
  17. package/src/app/routing/appRoutes.ts +3 -0
  18. package/src/app/routing/routes.tsx +9 -0
  19. package/src/demo/README.md +148 -0
  20. package/src/demo/application/dtos/ArchitecturePrinciple.ts +5 -0
  21. package/src/{types/profileTypes.ts → demo/application/dtos/ProfileFormValues.ts} +1 -1
  22. package/src/demo/application/use-cases/GetArchitecturePrinciplesUseCase.ts +11 -0
  23. package/src/demo/application/use-cases/GetArchitecturePrinciplesUseCaseInterface.ts +5 -0
  24. package/src/demo/application/use-cases/GetDemoUsersUseCase.ts +11 -0
  25. package/src/demo/application/use-cases/GetDemoUsersUseCaseInterface.ts +5 -0
  26. package/src/demo/domain/entities/DemoUser.ts +7 -0
  27. package/src/demo/domain/repositories/ArchitecturePrincipleRepositoryInterface.d.ts +5 -0
  28. package/src/demo/domain/repositories/DemoUserRepositoryInterface.d.ts +5 -0
  29. package/src/demo/infrastructure/repositories/HttpDemoUserRepository.ts +29 -0
  30. package/src/demo/infrastructure/repositories/StaticArchitecturePrincipleRepository.ts +33 -0
  31. package/src/demo/serviceDemo.ts +39 -0
  32. package/src/demo/serviceIdentifiers.ts +6 -0
  33. package/src/demo/ui/components/DemoFooter/DemoFooter.tsx +17 -0
  34. package/src/{components/Footer → demo/ui/components/DemoFooter}/__tests__/Footer.test.tsx +2 -2
  35. package/src/{components/Footer → demo/ui/components/DemoFooter}/__tests__/__snapshots__/Footer.test.tsx.snap +3 -3
  36. package/src/demo/ui/components/DemoFooter/index.ts +1 -0
  37. package/src/demo/ui/components/DemoHeader/DemoHeader.tsx +25 -0
  38. package/src/{components/Header → demo/ui/components/DemoHeader}/__tests__/Header.test.tsx +2 -2
  39. package/src/demo/ui/components/DemoHeader/__tests__/__snapshots__/Header.test.tsx.snap +64 -0
  40. package/src/demo/ui/components/DemoHeader/index.ts +1 -0
  41. package/src/{ui/molecules/Navigation/Navigation.tsx → demo/ui/components/DemoNavigation/DemoNavigation.tsx} +4 -4
  42. package/src/demo/ui/components/DemoNavigation/index.ts +1 -0
  43. package/src/{components → demo/ui/components}/TextInput/TextInput.tsx +3 -3
  44. package/src/{forms → demo/ui/forms}/ProfileForm/ProfileForm.tsx +7 -7
  45. package/src/demo/ui/hooks/useDemoUsersQuery/useDemoUsersQuery.ts +13 -0
  46. package/src/demo/ui/layouts/DemoLayout/DemoLayout.tsx +12 -0
  47. package/src/demo/ui/layouts/MainTemplate/MainTemplate.module.css +21 -0
  48. package/src/{ui/templates → demo/ui/layouts}/MainTemplate/MainTemplate.tsx +7 -7
  49. package/src/demo/ui/pages/DemoHome/DemoHome.tsx +117 -0
  50. package/src/demo/ui/pages/DependencyInjectionDemo/DependencyInjectionDemo.tsx +47 -0
  51. package/src/{pages/Demo → demo/ui/pages}/ReactHookFormDemo/ReactHookFormDemo.tsx +7 -7
  52. package/src/demo/ui/pages/ReactQueryDemo/ReactQueryDemo.module.scss +38 -0
  53. package/src/{pages/Demo → demo/ui/pages}/ReactQueryDemo/ReactQueryDemo.tsx +5 -4
  54. package/src/demo/ui/routing/demoAppRoutes.ts +6 -0
  55. package/src/demo/ui/routing/demoRoutes.tsx +31 -0
  56. package/src/main.ts +2 -2
  57. package/src/shared/README.md +53 -0
  58. package/src/shared/application/README.md +49 -0
  59. package/src/shared/domain/README.md +52 -0
  60. package/src/shared/infrastructure/README.md +51 -0
  61. package/src/{api → shared/infrastructure/http}/fetchApi.ts +1 -1
  62. package/src/shared/ui/README.md +50 -0
  63. package/src/shared/ui/hooks/useService/useService.ts +13 -0
  64. package/tsconfig.json +3 -1
  65. package/vitest.config.mts +5 -1
  66. package/src/api/README.md +0 -65
  67. package/src/api/demoApi.ts +0 -10
  68. package/src/assets/README.md +0 -54
  69. package/src/components/App/App.tsx +0 -18
  70. package/src/components/App/index.ts +0 -1
  71. package/src/components/Footer/Footer.tsx +0 -16
  72. package/src/components/Footer/index.ts +0 -1
  73. package/src/components/Header/Header.tsx +0 -17
  74. package/src/components/Header/__tests__/__snapshots__/Header.test.tsx.snap +0 -37
  75. package/src/components/Header/index.ts +0 -1
  76. package/src/components/README.md +0 -33
  77. package/src/config/README.md +0 -63
  78. package/src/config/index.ts +0 -1
  79. package/src/forms/README.md +0 -142
  80. package/src/hooks/README.md +0 -83
  81. package/src/hooks/api/queryKey.ts +0 -1
  82. package/src/hooks/api/useDemoApi.ts +0 -16
  83. package/src/pages/Demo/Demo.tsx +0 -236
  84. package/src/pages/Demo/ReactHookFormDemo/index.ts +0 -1
  85. package/src/pages/Demo/ReactHookFormDemo/routes.tsx +0 -7
  86. package/src/pages/Demo/ReactQueryDemo/index.ts +0 -1
  87. package/src/pages/Demo/ReactQueryDemo/routes.tsx +0 -7
  88. package/src/pages/Demo/__tests__/Demo.test.tsx +0 -15
  89. package/src/pages/Demo/__tests__/__snapshots__/Demo.test.tsx.snap +0 -557
  90. package/src/pages/Demo/index.ts +0 -1
  91. package/src/pages/Demo/routes.tsx +0 -8
  92. package/src/pages/Layout/Layout.tsx +0 -12
  93. package/src/pages/Layout/index.ts +0 -1
  94. package/src/pages/README.md +0 -91
  95. package/src/pages/UnexpectedError/UnexpectedError.module.css +0 -8
  96. package/src/pages/UnexpectedError/UnexpectedError.tsx +0 -22
  97. package/src/pages/UnexpectedError/index.ts +0 -1
  98. package/src/providers/QueryClientProvider/index.ts +0 -1
  99. package/src/providers/README.md +0 -112
  100. package/src/providers/index.ts +0 -1
  101. package/src/providers/withProviders/index.ts +0 -1
  102. package/src/providers/withProviders/withProviders.tsx +0 -18
  103. package/src/routing/README.md +0 -76
  104. package/src/routing/appRoutes.ts +0 -5
  105. package/src/routing/routerFactory.ts +0 -12
  106. package/src/routing/routes.tsx +0 -13
  107. package/src/types/README.md +0 -62
  108. package/src/types/demoApi.ts +0 -25
  109. package/src/ui/README.md +0 -144
  110. package/src/ui/molecules/Navigation/index.ts +0 -1
  111. package/src/ui/organisms/Footer/Footer.module.css +0 -10
  112. package/src/ui/organisms/Footer/Footer.tsx +0 -10
  113. package/src/ui/organisms/Footer/index.ts +0 -1
  114. package/src/ui/organisms/Header/Header.module.css +0 -17
  115. package/src/ui/organisms/Header/Header.tsx +0 -16
  116. package/src/ui/organisms/Header/index.ts +0 -1
  117. package/src/ui/organisms/MainContent/MainContent.module.css +0 -3
  118. package/src/ui/organisms/MainContent/MainContent.tsx +0 -6
  119. package/src/ui/organisms/MainContent/index.ts +0 -1
  120. package/src/ui/templates/MainTemplate/MainTemplate.module.css +0 -5
  121. package/src/utils/README.md +0 -70
  122. /package/src/{assets → app/assets}/css/index.ts +0 -0
  123. /package/src/{assets → app/assets}/css/mainBody.css +0 -0
  124. /package/src/{assets → app/assets}/css/reset.css +0 -0
  125. /package/src/{config → app/config}/queryClientConfig.ts +0 -0
  126. /package/src/{assets → demo/ui/assets}/images/logo.png +0 -0
  127. /package/src/{assets → demo/ui/assets}/images/templatePlugins.png +0 -0
  128. /package/src/{components/Footer/Footer.module.css → demo/ui/components/DemoFooter/DemoFooter.module.css} +0 -0
  129. /package/src/{components/Header/Header.module.css → demo/ui/components/DemoHeader/DemoHeader.module.css} +0 -0
  130. /package/src/{ui/molecules/Navigation/Navigation.module.css → demo/ui/components/DemoNavigation/DemoNavigation.module.css} +0 -0
  131. /package/src/{ui/atoms → demo/ui/components}/Input/Input.module.scss +0 -0
  132. /package/src/{ui/atoms → demo/ui/components}/Input/Input.tsx +0 -0
  133. /package/src/{ui/atoms → demo/ui/components}/Input/index.ts +0 -0
  134. /package/src/{ui/atoms → demo/ui/components}/Logo/Logo.module.css +0 -0
  135. /package/src/{ui/atoms → demo/ui/components}/Logo/Logo.tsx +0 -0
  136. /package/src/{ui/atoms → demo/ui/components}/Logo/__tests__/Logo.test.tsx +0 -0
  137. /package/src/{ui/atoms → demo/ui/components}/Logo/index.ts +0 -0
  138. /package/src/{ui/atoms → demo/ui/components}/NavLink/NavLink.tsx +0 -0
  139. /package/src/{ui/atoms → demo/ui/components}/NavLink/index.ts +0 -0
  140. /package/src/{components → demo/ui/components}/TextInput/index.ts +0 -0
  141. /package/src/{forms → demo/ui/forms}/ProfileForm/ProfileForm.module.scss +0 -0
  142. /package/src/{forms → demo/ui/forms}/ProfileForm/index.ts +0 -0
  143. /package/src/{ui/templates → demo/ui/layouts}/MainTemplate/index.ts +0 -0
  144. /package/src/{pages/Demo/Demo.module.scss → demo/ui/pages/DemoHome/DemoHome.module.scss} +0 -0
  145. /package/src/{pages/Demo/ReactQueryDemo/ReactQueryDemo.module.scss → demo/ui/pages/DependencyInjectionDemo/DependencyInjectionDemo.module.scss} +0 -0
  146. /package/src/{pages/Demo/ReactHookFormDemo/ReactHookFormDemo.module.css → demo/ui/pages/ReactHookFormDemo/ReactHookFormDemo.module.scss} +0 -0
  147. /package/src/{api → shared/infrastructure/http}/constant.ts +0 -0
  148. /package/src/{types/api.ts → shared/infrastructure/http/fetchApi.type.d.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,46 @@
1
+ ## @pplancq/react-template [2.9.0](https://github.com/pplancq/dev-tools/compare/@pplancq/react-template@2.8.17...@pplancq/react-template@2.9.0) (2026-06-15)
2
+
3
+ ### Features
4
+
5
+ * **react-template:** restructure react-template to Clean Architecture and DDD bounded contexts ([#1742](https://github.com/pplancq/dev-tools/issues/1742)) ([bbd8a9d](https://github.com/pplancq/dev-tools/commit/bbd8a9da2028a3f070993e38bd7140a5edbe6d2c))
6
+
7
+ ### Bug Fixes
8
+
9
+ * **deps:** update commitlint monorepo to ^21.0.2 ([#1769](https://github.com/pplancq/dev-tools/issues/1769)) ([f3c7f42](https://github.com/pplancq/dev-tools/commit/f3c7f42c1229060f6471d68a3bdfc0517543ef3a))
10
+ * **deps:** update dependency @hookform/resolvers to ^5.4.0 ([#1755](https://github.com/pplancq/dev-tools/issues/1755)) ([e7f1d68](https://github.com/pplancq/dev-tools/commit/e7f1d68a868fba6247fe360b8e8b5e9fc6275be4))
11
+ * **deps:** update dependency @rsbuild/core to ^2.0.12 ([#1744](https://github.com/pplancq/dev-tools/issues/1744)) ([22a93b3](https://github.com/pplancq/dev-tools/commit/22a93b3d027b2a88c4bc9f80ecbeb4af91e3f0e6))
12
+ * **deps:** update dependency @rsbuild/plugin-eslint to ^2.0.2 ([#1759](https://github.com/pplancq/dev-tools/issues/1759)) ([eeaa6cb](https://github.com/pplancq/dev-tools/commit/eeaa6cbe616a365066611c39a3ccc36db6598b7c))
13
+ * **deps:** update dependency @rsbuild/plugin-react to ^2.0.1 ([#1766](https://github.com/pplancq/dev-tools/issues/1766)) ([b1527e6](https://github.com/pplancq/dev-tools/commit/b1527e6097daf03e8dbe82959e14899cf11d1086))
14
+ * **deps:** update dependency @rsbuild/plugin-sass to ^1.5.3 ([#1767](https://github.com/pplancq/dev-tools/issues/1767)) ([b25e848](https://github.com/pplancq/dev-tools/commit/b25e848e00e384b3a378ec243ce69c7151ff4c8c))
15
+ * **deps:** update dependency monocart-coverage-reports to ^2.12.12 ([#1768](https://github.com/pplancq/dev-tools/issues/1768)) ([8a5ba24](https://github.com/pplancq/dev-tools/commit/8a5ba24051ff8f7eb6409b5ab6738ebdb01055d9))
16
+ * **deps:** update dependency react-hook-form to ^7.78.0 ([#1756](https://github.com/pplancq/dev-tools/issues/1756)) ([2cccd51](https://github.com/pplancq/dev-tools/commit/2cccd5144d875d0accf485b256ef3d91ca8fe893))
17
+ * **deps:** update dependency stylelint to ^17.13.0 ([#1752](https://github.com/pplancq/dev-tools/issues/1752)) ([acfc13f](https://github.com/pplancq/dev-tools/commit/acfc13f61041ffc9323a3e469c1b2e51fbf3bf9f))
18
+ * **deps:** update react monorepo ([#1745](https://github.com/pplancq/dev-tools/issues/1745)) ([8424cfe](https://github.com/pplancq/dev-tools/commit/8424cfed2645554410e1e7df2632376b26b1fb04))
19
+ * **deps:** update react-query mono repo to ^5.101.0 ([#1749](https://github.com/pplancq/dev-tools/issues/1749)) ([31d0cfd](https://github.com/pplancq/dev-tools/commit/31d0cfdedf9a5c1ed2779cff2a0b8a0fd8a8ac5d))
20
+ * **deps:** update react-router monorepo to ^7.17.0 ([#1763](https://github.com/pplancq/dev-tools/issues/1763)) ([6cfffba](https://github.com/pplancq/dev-tools/commit/6cfffba0a99f0c0dcb4f271ace035e60b2d951d3))
21
+
22
+
23
+ ### Dependencies
24
+
25
+ * **@pplancq/commitlint-config:** upgraded to 4.0.2
26
+ * **@pplancq/eslint-config:** upgraded to 6.0.17
27
+
28
+ ## @pplancq/react-template [2.8.17](https://github.com/pplancq/dev-tools/compare/@pplancq/react-template@2.8.16...@pplancq/react-template@2.8.17) (2026-05-19)
29
+
30
+ ### Bug Fixes
31
+
32
+ * **deps:** update commitlint monorepo to ^21.0.1 ([#1731](https://github.com/pplancq/dev-tools/issues/1731)) ([f0e49f8](https://github.com/pplancq/dev-tools/commit/f0e49f87cd972ddeaef49cc05ee49641d2165a7b))
33
+ * **deps:** update dependency react-router to ^7.15.1 ([#1732](https://github.com/pplancq/dev-tools/issues/1732)) ([d53061d](https://github.com/pplancq/dev-tools/commit/d53061d24a95413a0c01c886f3260c207657c548))
34
+ * **deps:** update react-query mono repo to ^5.100.10 ([#1733](https://github.com/pplancq/dev-tools/issues/1733)) ([3ff5eb6](https://github.com/pplancq/dev-tools/commit/3ff5eb673868b5c67f02209716f90689994dac03))
35
+
36
+
37
+ ### Dependencies
38
+
39
+ * **@pplancq/commitlint-config:** upgraded to 4.0.1
40
+ * **@pplancq/eslint-config:** upgraded to 6.0.16
41
+ * **@pplancq/postcss-config:** upgraded to 3.0.6
42
+ * **@pplancq/prettier-config:** upgraded to 3.0.0
43
+
1
44
  ## @pplancq/react-template [2.8.16](https://github.com/pplancq/dev-tools/compare/@pplancq/react-template@2.8.15...@pplancq/react-template@2.8.16) (2026-05-12)
2
45
 
3
46
  ### Bug Fixes
package/_README.md CHANGED
@@ -81,64 +81,69 @@ Allows you to fix prettier lint errors.
81
81
 
82
82
  To remove the demo application.
83
83
 
84
- ### `npm run migrate:vite`
85
-
86
- To migrate from webpack to vite.
87
-
88
84
  ## 🏗 <span id="project-structure">Project Structure</span>
89
85
 
90
- ```
91
- 📁 my-projet
86
+ ```text
87
+ 📁 my-project
92
88
  ├── 📁 src
93
- │ ├── 📁 ui
94
- │ │ ├── 📁 Atoms
95
- │ │ ├── 📁 Molecules
96
- │ │ ├── 📁 Organisms
97
- │ │ ├── 📁 Templates
98
- │ ├── 📁 components
99
- │ │ ├── 📁 formFields
100
- │ ├── 📁 providers
101
- │ ├── 📁 pages
102
- │ │ ├── 📁 homePage
103
- │ │ ├── 📁 page1
104
- │ │ │ ├── 📁 sousPage1
105
- │ ├── 📁 forms
106
- │ │ ├── 📁 hooks
107
- │ │ ├── 📁 risk
108
- │ │ ├── 📁 contact
109
- │ ├── 📁 hooks
110
- │ │ ├── 📁 api
111
- │ │ ├── 📁 useCustom1
112
- │ │ ├── 📁 useCustom2
113
- │ ├── 📁 utils
114
- │ │ ├── 📁 services
115
- │ │ ├── 📁 tests
116
- │ │ ├── 📁 helpers
117
- │ ├── 📁 routing
118
- │ ├── 📁 api
119
- │ ├── 📁 types
120
- │ ├── 📁 assets
121
- │ ├── 📁 config
89
+ │ ├── 📄 README.md
90
+ │ ├── 📁 app
91
+ │ │ ├── 📄 README.md
92
+ │ │ ├── 📄 App.tsx
93
+ │ │ ├── 📄 AppHTMLElement.tsx
94
+ │ │ ├── 📁 assets
95
+ │ │ ├── 📁 config
96
+ │ │ ├── 📁 providers
97
+ │ │ └── 📁 routing
98
+ │ ├── 📁 shared
99
+ │ │ ├── 📄 README.md
100
+ │ │ ├── 📁 application
101
+ │ │ │ └── 📄 README.md
102
+ │ │ ├── 📁 domain
103
+ │ │ │ └── 📄 README.md
104
+ │ │ ├── 📁 infrastructure
105
+ │ │ │ └── 📄 README.md
106
+ │ │ └── 📁 ui
107
+ │ │ └── 📄 README.md
108
+ │ ├── 📁 demo
109
+ │ │ ├── 📄 README.md
110
+ │ │ ├── 📁 application
111
+ │ │ ├── 📁 domain
112
+ │ │ ├── 📁 infrastructure
113
+ │ │ ├── 📁 ui
114
+ │ │ │ ├── 📁 assets
115
+ │ │ │ ├── 📁 components
116
+ │ │ │ ├── 📁 forms
117
+ │ │ │ ├── 📁 hooks
118
+ │ │ │ ├── 📁 layouts
119
+ │ │ │ ├── 📁 pages
120
+ │ │ │ └── 📁 routing
121
+ │ │ ├── 📄 serviceDemo.ts
122
+ │ │ └── 📄 serviceIdentifiers.ts
123
+ │ ├── 📄 main.ts
124
+ │ └── 📄 react-app-env.d.ts
122
125
  ```
123
126
 
124
127
  ### 📚 Folder Definitions
125
128
 
126
129
  Here is the project folder structure, with a brief description of each folder:
127
130
 
128
- | Folder | Description |
129
- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
130
- | **📁 src** | **_The root directory of the application source code._** |
131
- | [**📁 ui**](./src/ui/README.md) | Contains reusable components designed to be used across projects. Components can be basic (Atoms), more complex (Molecules), higher-level components (Organisms), or page templates (Templates). |
132
- | [**📁&#160;components**](./src/components/README.md) | Contains project-specific reusable components, for example, form components using React Hook Form. |
133
- | [**📁 providers**](./src/providers/README.md) | This folder contains context providers or custom hooks that provide data to the entire application. |
134
- | [**📁 pages**](./src/pages/README.md) | Contains the pages of the application. Each subfolder represents a distinct page or view of the application. |
135
- | [**📁 forms**](./src/forms/README.md) | Contains the forms of the application, grouping hooks related to forms. |
136
- | [**📁 hooks**](./src/hooks/README.md) | Includes custom hooks for various application features, such as API calls with React Query. |
137
- | [**📁 utils**](./src/utils/README.md) | Contains utilities and services such as test files, utility functions, etc. |
138
- | [**📁 routing**](./src/routing/README.md) | This folder is intended for native API calls using the `fetch`. function. These calls are essential for fetching real-time data from external sources, such as remote servers or web services. |
139
- | [**📁 types**](./src/types/README.md) | Provides TypeScript type definitions to enhance the robustness of your code. |
140
- | [**📁 assets**](./src/assets/README.md) | Contains static files such as images, fonts, etc., used in the application. |
141
- | [**📁 config**](./src/config/README.md) | Contains all the important configurations and utilities needed for our project. |
131
+ | Folder | Description |
132
+ | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
133
+ | **📁 src** | **_The root directory of the application source code._** It also contains [`src/README.md`](./src/README.md), which serves as the documentation index. |
134
+ | [**📁 app**](./src/app/README.md) | Owns the application bootstrap layer: root app composition, custom element entry point, routing, providers, global configuration, and app-wide assets. |
135
+ | [**📁 shared**](./src/shared/README.md) | Contains only genuinely reusable cross-context code. In this starter it is intentionally conservative and avoids hosting demo-specific UI. |
136
+ | [**📁 shared/application**](./src/shared/application/README.md) | Shared application-layer abstractions, DTO helpers, or orchestration utilities that can be reused by several bounded contexts. |
137
+ | [**📁 shared/domain**](./src/shared/domain/README.md) | Shared pure types and contracts. This folder must stay framework-free and focused on stable, reusable domain-facing definitions. |
138
+ | [**📁 shared/infrastructure**](./src/shared/infrastructure/README.md) | Shared technical helpers backed by external tools or browser APIs, such as generic HTTP utilities. |
139
+ | [**📁 shared/ui**](./src/shared/ui/README.md) | Shared UI-facing helpers with no feature identity. In the current template it mainly exists for common hooks such as DI-to-React integration. |
140
+ | [**📁 demo**](./src/demo/README.md) | The example bounded context included in the starter. It demonstrates how to structure a feature using `application`, `domain`, `infrastructure`, and `ui`. |
141
+ | **📁 demo/ui/components** | Demo visual components and building blocks. The structure stays practical and readable instead of exposing `atoms`, `molecules`, or `organisms` folders. |
142
+ | **📁 demo/ui/layouts** | Demo layouts used to compose pages. |
143
+ | **📁 demo/ui/pages** | Demo pages such as the overview page and the example feature pages. |
144
+ | **📁 demo/ui/forms** | Demo form composition and form-related UI pieces. |
145
+ | **📁 demo/ui/hooks** | Demo-specific React hooks, such as query hooks that connect the UI to the application layer. |
146
+ | **📁 demo/ui/routing** | Demo route definitions and route path constants consumed by the app router. |
142
147
 
143
148
  ## 🏗 <span id="component-structure">React Component Structure</span>
144
149
 
@@ -171,7 +176,7 @@ export { ComponentName } from './ComponentName';
171
176
  This will allow importing a component like this:
172
177
 
173
178
  ```typescript
174
- import { ComponentName } from '@Front/ComponentName';
179
+ import { ComponentName } from '@Demo/ui/components/ComponentName';
175
180
  ```
176
181
 
177
182
  #### 📄 ComponentName.tsx
@@ -236,13 +241,13 @@ export const ComponentName = () => {
236
241
 
237
242
  ## ⚠️ Caution with Environment Variables
238
243
 
239
- The webpack configuration of this project allows for environment variables to be included in the application bundle. This could potentially expose sensitive information if the bundle is publicly accessible.
244
+ The build configuration of this project allows for environment variables to be included in the application bundle. This could potentially expose sensitive information if the bundle is publicly accessible.
240
245
 
241
246
  It is recommended to only include non-sensitive environment variables in the application bundle. Sensitive information should not be exposed even if the bundle is publicly accessible.
242
247
 
243
248
  Ensure you understand the security implications before including environment variables in your bundle.
244
249
 
245
- Please note that the web configuration pre-filters environment variables via the default prefix ‘FRONT*’. This means that only environment variables starting with ‘FRONT*’ will be included in the bundle. This is an additional layer of security to prevent the accidental exposure of sensitive environment variables.
250
+ Please note that the build configuration pre-filters environment variables via the default prefix `FRONT*`. This means that only environment variables starting with `FRONT*` will be included in the bundle. This is an additional layer of security to prevent the accidental exposure of sensitive environment variables.
246
251
 
247
252
  ## 🙇 <span id="learnmore">Learn More</span>
248
253
 
package/mise.toml CHANGED
@@ -1,3 +1,3 @@
1
1
  [tools]
2
- node = "24.15.0"
3
- npm = "11.14.0"
2
+ node = "24.16.0"
3
+ npm = "11.17.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pplancq/react-template",
3
- "version": "2.8.16",
3
+ "version": "2.9.0",
4
4
  "license": "MIT",
5
5
  "description": "react template",
6
6
  "author": "pplancq <paul.plancq@outlook.fr>",
@@ -13,7 +13,7 @@
13
13
  "bin": {
14
14
  "template-install": "bin/template-install.js"
15
15
  },
16
- "packageManager": "npm@11.14.0",
16
+ "packageManager": "npm@11.17.0",
17
17
  "scripts": {
18
18
  "start": "rsbuild dev",
19
19
  "start:mock": "rsbuild dev --env-mode mock",
@@ -49,53 +49,54 @@
49
49
  "template"
50
50
  ],
51
51
  "dependencies": {
52
- "@hookform/resolvers": "^5.2.2",
53
- "@tanstack/react-query": "^5.100.9",
54
- "@tanstack/react-query-devtools": "^5.100.9",
55
- "react": "^19.2.6",
56
- "react-dom": "^19.2.6",
57
- "react-hook-form": "^7.75.0",
58
- "react-router": "^7.15.0",
52
+ "@hookform/resolvers": "^5.4.0",
53
+ "@tanstack/react-query": "^5.101.0",
54
+ "@tanstack/react-query-devtools": "^5.101.0",
55
+ "inversify": "^8.1.0",
56
+ "react": "^19.2.7",
57
+ "react-dom": "^19.2.7",
58
+ "react-hook-form": "^7.78.0",
59
+ "react-router": "^7.17.0",
59
60
  "yup": "^1.7.1"
60
61
  },
61
62
  "devDependencies": {
62
- "@bdellegrazie/playwright-sonar-reporter": "^0.4.0",
63
- "@commitlint/cli": "^21.0.0",
63
+ "@bdellegrazie/playwright-sonar-reporter": "^0.5.1",
64
+ "@commitlint/cli": "^21.0.2",
64
65
  "@msw/playwright": "^0.6.7",
65
- "@playwright/test": "^1.59.1",
66
+ "@playwright/test": "^1.60.0",
66
67
  "@pplancq/commitlint-config": "*",
67
68
  "@pplancq/eslint-config": "*",
68
69
  "@pplancq/postcss-config": "*",
69
70
  "@pplancq/prettier-config": "*",
70
71
  "@pplancq/stylelint-config": "*",
71
- "@rsbuild/core": "^2.0.5",
72
- "@rsbuild/plugin-eslint": "^1.3.0",
73
- "@rsbuild/plugin-react": "^2.0.0",
74
- "@rsbuild/plugin-sass": "^1.5.2",
72
+ "@rsbuild/core": "^2.0.12",
73
+ "@rsbuild/plugin-eslint": "^2.0.2",
74
+ "@rsbuild/plugin-react": "^2.0.1",
75
+ "@rsbuild/plugin-sass": "^1.5.3",
75
76
  "@testing-library/jest-dom": "^6.9.1",
76
77
  "@testing-library/react": "^16.3.2",
77
78
  "@testing-library/user-event": "^14.6.1",
78
- "@types/react": "^19.2.14",
79
+ "@types/react": "^19.2.17",
79
80
  "@types/react-dom": "^19.2.3",
80
- "@vitejs/plugin-react": "^6.0.1",
81
- "@vitest/coverage-v8": "^4.1.5",
82
- "concurrently": "^9.2.1",
81
+ "@vitejs/plugin-react": "^6.0.2",
82
+ "@vitest/coverage-v8": "^4.1.8",
83
+ "concurrently": "^10.0.3",
83
84
  "eslint": "^9.39.4",
84
- "eslint-plugin-prettier": "^5.5.5",
85
+ "eslint-plugin-prettier": "^5.5.6",
85
86
  "husky": "^9.1.7",
86
87
  "jsdom": "^29.1.1",
87
- "lint-staged": "^17.0.2",
88
- "monocart-coverage-reports": "^2.12.11",
89
- "msw": "^2.14.5",
88
+ "lint-staged": "^17.0.7",
89
+ "monocart-coverage-reports": "^2.12.12",
90
+ "msw": "^2.14.6",
90
91
  "nodemon": "^3.1.14",
91
- "prettier": "^3.8.3",
92
+ "prettier": "^3.8.4",
92
93
  "rsbuild-plugin-stylelint": "^1.2.0",
93
- "stylelint": "^17.11.0",
94
+ "stylelint": "^17.13.0",
94
95
  "stylelint-prettier": "^5.0.3",
95
96
  "tsc-files": "^1.1.4",
96
97
  "typescript": "^6.0.3",
97
98
  "vite-plugin-svgr": "^5.2.0",
98
- "vitest": "^4.1.5",
99
+ "vitest": "^4.1.8",
99
100
  "vitest-axe": "^1.0.0-pre.5",
100
101
  "vitest-sonar-reporter": "^3.0.0"
101
102
  },
@@ -4,79 +4,118 @@ const { resolve } = require('node:path');
4
4
 
5
5
  const resolveSrc = path => resolve(__dirname, `../src${path}`);
6
6
 
7
- rmSync(resolveSrc('/api/demoApi.ts'));
8
-
9
- rmSync(resolveSrc('/assets/css/mainBody.css'));
10
- rmSync(resolveSrc('/assets/css/reset.css'));
11
- writeFileSync(resolveSrc('/assets/css/global.css'), ':root {\n --white-color: #fff;\n}\n', { encoding: 'utf-8' });
12
- let assetsIndex = readFileSync(resolveSrc('/assets/css/index.ts'), { encoding: 'utf-8' });
13
- assetsIndex = assetsIndex.replaceAll("import './reset.css';\nimport './mainBody.css';\n", "import './global.css';\n");
14
- writeFileSync(resolveSrc('/assets/css/index.ts'), assetsIndex, { encoding: 'utf-8' });
15
-
16
- rmSync(resolveSrc('/assets/images/logo.png'));
17
- rmSync(resolveSrc('/assets/images/templatePlugins.png'));
18
-
19
- rmSync(resolveSrc('/components/Footer'), { recursive: true });
20
- rmSync(resolveSrc('/components/Header'), { recursive: true });
21
- rmSync(resolveSrc('/components/TextInput'), { recursive: true });
22
-
23
- rmSync(resolveSrc('/forms/ProfileForm'), { recursive: true });
24
-
25
- rmSync(resolveSrc('/hooks/api/useDemoApi.ts'));
26
- let queryKey = readFileSync(resolveSrc('/hooks/api/queryKey.ts'), { encoding: 'utf-8' });
27
- queryKey = queryKey.replaceAll("export const demoQuery = () => ['dataWithDelay'];\n", '');
28
- writeFileSync(resolveSrc('/hooks/api/queryKey.ts'), queryKey, { encoding: 'utf-8' });
29
-
30
- rmSync(resolveSrc('/pages/Demo'), { recursive: true });
31
- rmSync(resolveSrc('/pages/Layout'), { recursive: true });
32
- rmSync(resolveSrc('/pages/UnexpectedError'), { recursive: true });
33
- mkdirSync(resolveSrc('/pages/Home'));
34
- writeFileSync(resolveSrc('/pages/Home/index.ts'), "export { homeRoutes } from './routes';\n", { encoding: 'utf-8' });
7
+ rmSync(resolveSrc('/demo'), { recursive: true, force: true });
8
+
9
+ rmSync(resolveSrc('/app/assets/css/mainBody.css'), { force: true });
10
+ writeFileSync(resolveSrc('/app/assets/css/global.css'), ':root {\n --white-color: #fff;\n}\n', { encoding: 'utf-8' });
11
+ writeFileSync(resolveSrc('/app/assets/css/index.ts'), "import './reset.css';\nimport './global.css';\n", {
12
+ encoding: 'utf-8',
13
+ });
14
+
15
+ mkdirSync(resolveSrc('/home/domain'), { recursive: true });
16
+ writeFileSync(resolveSrc('/home/domain/.gitkeep'), '', { encoding: 'utf-8' });
17
+
18
+ mkdirSync(resolveSrc('/home/application'), { recursive: true });
19
+ writeFileSync(resolveSrc('/home/application/.gitkeep'), '', { encoding: 'utf-8' });
20
+
21
+ mkdirSync(resolveSrc('/home/infrastructure'), { recursive: true });
22
+ writeFileSync(resolveSrc('/home/infrastructure/.gitkeep'), '', { encoding: 'utf-8' });
23
+
24
+ writeFileSync(resolveSrc('/home/serviceIdentifiers.ts'), 'export const HOME_SERVICES = Object.freeze({});\n', {
25
+ encoding: 'utf-8',
26
+ });
27
+
35
28
  writeFileSync(
36
- resolveSrc('/pages/Home/routes.tsx'),
37
- "import type { RouteObject } from 'react-router';\n" +
38
- "import { Home } from './Home';\n" +
39
- '\n' +
40
- 'export const homeRoutes: RouteObject = {\n' +
41
- ' index: true,\n' +
42
- ' element: <Home />,\n' +
43
- '};\n',
29
+ resolveSrc('/home/serviceHome.ts'),
30
+ [
31
+ "import { ContainerModule } from 'inversify';",
32
+ '',
33
+ 'export const serviceHome: ContainerModule = new ContainerModule(_options => {',
34
+ ' // Register your home context services here',
35
+ '});',
36
+ '',
37
+ ].join('\n'),
44
38
  { encoding: 'utf-8' },
45
39
  );
46
- writeFileSync(resolveSrc('/pages/Home/Home.tsx'), 'export const Home = () => {\n return <div>HomePage</div>;\n};\n', {
47
- encoding: 'utf-8',
48
- });
49
40
 
50
- let appRoutes = readFileSync(resolveSrc('/routing/appRoutes.ts'), { encoding: 'utf-8' });
51
- appRoutes = appRoutes.replaceAll(
52
- "\n reactQueryDemo: '/reactQueryDemo',\n reactHookFormDemo: '/reactHookFormDemo',",
53
- '',
41
+ mkdirSync(resolveSrc('/home/ui/pages/Home'), { recursive: true });
42
+ writeFileSync(
43
+ resolveSrc('/home/ui/pages/Home/Home.tsx'),
44
+ [
45
+ 'export const Home = () => {',
46
+ ' return (',
47
+ ' <section>',
48
+ ' <h1>Home</h1>',
49
+ ' <p>Your demo context has been removed. Start building your first bounded context from here.</p>',
50
+ ' </section>',
51
+ ' );',
52
+ '};',
53
+ '',
54
+ ].join('\n'),
55
+ { encoding: 'utf-8' },
54
56
  );
55
- writeFileSync(resolveSrc('/routing/appRoutes.ts'), appRoutes, { encoding: 'utf-8' });
56
- let routes = readFileSync(resolveSrc('/routing/routes.tsx'), { encoding: 'utf-8' });
57
- routes = routes.replaceAll(
58
- "import { demoRoutes } from '@Front/pages/Demo';",
59
- "import { homeRoutes } from '@Front/pages/Home';",
57
+
58
+ mkdirSync(resolveSrc('/home/ui/routing'), { recursive: true });
59
+ writeFileSync(
60
+ resolveSrc('/home/ui/routing/homeAppRoutes.ts'),
61
+ ['export const homeAppRoutes = Object.freeze({', " home: '/',", '});', ''].join('\n'),
62
+ { encoding: 'utf-8' },
63
+ );
64
+
65
+ writeFileSync(
66
+ resolveSrc('/home/ui/routing/homeRoutes.tsx'),
67
+ [
68
+ "import { Home } from '@Home/ui/pages/Home/Home';",
69
+ "import type { RouteObject } from 'react-router';",
70
+ '',
71
+ 'export const homeRoutes: RouteObject = {',
72
+ ' children: [',
73
+ ' {',
74
+ ' index: true,',
75
+ ' element: <Home />,',
76
+ ' },',
77
+ ' ],',
78
+ '};',
79
+ '',
80
+ ].join('\n'),
81
+ { encoding: 'utf-8' },
82
+ );
83
+
84
+ writeFileSync(
85
+ resolveSrc('/app/config/serviceContainer.ts'),
86
+ [
87
+ "import { serviceHome } from '@Home/serviceHome';",
88
+ "import { Container } from 'inversify';",
89
+ '',
90
+ 'export const serviceContainer = new Container();',
91
+ '',
92
+ 'serviceContainer.load(serviceHome);',
93
+ '',
94
+ ].join('\n'),
95
+ { encoding: 'utf-8' },
60
96
  );
61
- routes = routes.replaceAll("\nimport { Layout } from '@Front/pages/Layout';", '');
62
- routes = routes.replaceAll("\nimport { UnexpectedError } from 'src/pages/UnexpectedError';", '');
63
- routes = routes.replaceAll(
64
- 'element: <Layout />,\n children: [demoRoutes],\n errorElement: <UnexpectedError />,',
65
- 'children: [homeRoutes],',
97
+
98
+ writeFileSync(
99
+ resolveSrc('/app/routing/routes.tsx'),
100
+ [
101
+ "import { homeRoutes } from '@Home/ui/routing/homeRoutes';",
102
+ "import type { RouteObject } from 'react-router';",
103
+ '',
104
+ 'export const routeObject: RouteObject[] = [',
105
+ ' {',
106
+ " path: '/',",
107
+ ' children: [homeRoutes],',
108
+ ' },',
109
+ '];',
110
+ '',
111
+ ].join('\n'),
112
+ { encoding: 'utf-8' },
66
113
  );
67
- writeFileSync(resolveSrc('/routing/routes.tsx'), routes, { encoding: 'utf-8' });
68
-
69
- rmSync(resolveSrc('/types/demoApi.ts'));
70
- rmSync(resolveSrc('/types/profileTypes.ts'));
71
-
72
- rmSync(resolveSrc('/ui/atoms/Input'), { recursive: true });
73
- rmSync(resolveSrc('/ui/atoms/Logo'), { recursive: true });
74
- rmSync(resolveSrc('/ui/atoms/NavLink'), { recursive: true });
75
- rmSync(resolveSrc('/ui/molecules/Navigation'), { recursive: true });
76
- rmSync(resolveSrc('/ui/organisms/Footer'), { recursive: true });
77
- rmSync(resolveSrc('/ui/organisms/Header'), { recursive: true });
78
- rmSync(resolveSrc('/ui/organisms/MainContent'), { recursive: true });
79
- rmSync(resolveSrc('/ui/templates/MainTemplate'), { recursive: true });
114
+
115
+ const tsconfigJson = JSON.parse(readFileSync(resolve(__dirname, '../tsconfig.json'), { encoding: 'utf-8' }));
116
+ delete tsconfigJson.compilerOptions.paths['@Demo/*'];
117
+ tsconfigJson.compilerOptions.paths['@Home/*'] = ['./src/home/*'];
118
+ writeFileSync(resolve(__dirname, '../tsconfig.json'), JSON.stringify(tsconfigJson, null, 2), { encoding: 'utf-8' });
80
119
 
81
120
  const packagesJson = JSON.parse(readFileSync(resolve(__dirname, '../package.json'), { encoding: 'utf-8' }));
82
121
  const { 'remove:demo': _, ...scripts } = packagesJson.scripts;
package/src/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # `src`
2
+
3
+ This directory contains the template source code and its explanatory documentation.
4
+
5
+ ## Architecture Philosophy
6
+
7
+ This starter follows a **hybrid architecture** combining two complementary patterns:
8
+
9
+ - **Clean Architecture** (Robert C. Martin) — code is organized into horizontal layers that enforce a strict
10
+ dependency direction. Dependencies always flow **inward toward the domain**. The domain is the most protected
11
+ layer; it has zero external dependencies.
12
+ - **DDD Bounded Contexts** — code is also organized into vertical slices, each representing an isolated business
13
+ domain. A bounded context owns its full stack: domain, application, infrastructure, and UI.
14
+
15
+ The result is a structure where every folder belongs to either a **horizontal layer** (domain, application,
16
+ infrastructure, ui) or a **vertical slice** (a bounded context such as `demo`), and both dimensions are always
17
+ visible.
18
+
19
+ ## Top-level structure
20
+
21
+ ```
22
+ src/
23
+ ├── app/ # Application bootstrap layer (not a bounded context)
24
+ ├── shared/ # Shared kernel — genuinely cross-context code
25
+ │ ├── domain/
26
+ │ ├── application/
27
+ │ ├── infrastructure/
28
+ │ └── ui/
29
+ └── demo/ # Example bounded context (domain / application / infrastructure / ui)
30
+ ```
31
+
32
+ ## Fundamental dependency rule
33
+
34
+ ```
35
+ UI → Application → Domain
36
+ Infrastructure -.→ Domain (implements its interfaces)
37
+ ```
38
+
39
+ - **Domain** depends on nothing. Pure TypeScript.
40
+ - **Application** depends on Domain only. Orchestrates use cases, defines infrastructure interfaces.
41
+ - **Infrastructure** implements interfaces defined by Domain/Application. May use external libraries.
42
+ - **UI** depends on Application (use cases) and Domain (DTOs). No business logic.
43
+
44
+ This rule applies **within each bounded context** and **within the shared kernel**.
45
+
46
+ ## Path aliases
47
+
48
+ Each first-class section of the source tree has a TypeScript path alias. Use these aliases instead of long
49
+ relative paths; they signal architectural intent and prevent accidental cross-context coupling.
50
+
51
+ | Alias | Maps to |
52
+ | ----------- | -------------- |
53
+ | `@App/*` | `src/app/*` |
54
+ | `@Shared/*` | `src/shared/*` |
55
+ | `@Demo/*` | `src/demo/*` |
56
+ | `@Mocks/*` | `mocks/*` |
57
+
58
+ When you add a real bounded context alongside `demo`, add its own alias to `tsconfig.json`.
59
+
60
+ ## Table of contents
61
+
62
+ 1. [`app/README.md`](./app/README.md) — application bootstrap, composition root, routing, and providers
63
+ 2. [`shared/README.md`](./shared/README.md) — shared kernel concept and usage rules
64
+ 3. [`shared/domain/README.md`](./shared/domain/README.md) — shared pure contracts, types, and domain rules
65
+ 4. [`shared/application/README.md`](./shared/application/README.md) — shared application-layer abstractions
66
+ 5. [`shared/infrastructure/README.md`](./shared/infrastructure/README.md) — shared technical adapters and helpers
67
+ 6. [`shared/ui/README.md`](./shared/ui/README.md) — shared UI-facing hooks and utilities
68
+ 7. [`demo/README.md`](./demo/README.md) — the example bounded context and how to replicate it
69
+
70
+ ## Suggested reading order
71
+
72
+ If you are discovering the template for the first time:
73
+
74
+ 1. This file — understand the big picture
75
+ 2. `app` — see how the application boots and wires everything together
76
+ 3. `shared/domain` — understand why the domain layer is the most protected
77
+ 4. `shared` — understand what the shared kernel is and what it must not become
78
+ 5. `demo` — walk through a complete bounded context layer by layer
79
+
80
+ That sequence starts with the overall architecture, moves to the heart of Clean Architecture (domain purity),
81
+ then shows how a real bounded context puts all the pieces together.
@@ -0,0 +1,18 @@
1
+ import { queryClient } from '@App/config/queryClientConfig';
2
+ import { serviceContainer } from '@App/config/serviceContainer';
3
+ import { Providers } from '@App/providers/Providers/Providers';
4
+ import { Router } from '@App/routing/Router';
5
+
6
+ import '@App/assets/css';
7
+
8
+ type AppProps = {
9
+ basename?: string;
10
+ };
11
+
12
+ export const App = ({ basename }: AppProps) => {
13
+ return (
14
+ <Providers queryClient={queryClient} container={serviceContainer}>
15
+ <Router basename={basename} />
16
+ </Providers>
17
+ );
18
+ };
@@ -1,9 +1,9 @@
1
- import { App } from '@Front/components/App';
1
+ import { App } from '@App/App';
2
2
  import { StrictMode } from 'react';
3
3
  import { createRoot, type Root } from 'react-dom/client';
4
4
 
5
5
  // eslint-disable-next-line import/no-default-export
6
- export default class Bootstrap extends HTMLElement {
6
+ export default class AppHTMLElement extends HTMLElement {
7
7
  private readonly root: Root;
8
8
 
9
9
  private isMounted = false;