@ojiepermana/angular 22.1.11 → 22.1.13

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 (340) hide show
  1. package/README.md +32 -26
  2. package/chart/README.md +272 -0
  3. package/component/README.md +89 -0
  4. package/component/accordion/README.md +195 -0
  5. package/component/alert/README.md +184 -0
  6. package/component/alert-dialog/README.md +255 -0
  7. package/component/aspect-ratio/README.md +116 -0
  8. package/component/avatar/README.md +182 -0
  9. package/component/badge/README.md +143 -0
  10. package/component/breadcrumb/README.md +223 -0
  11. package/component/button/README.md +141 -0
  12. package/component/button-group/README.md +214 -0
  13. package/component/calendar/README.md +137 -0
  14. package/component/card/README.md +232 -0
  15. package/component/carousel/README.md +276 -0
  16. package/component/checkbox/README.md +153 -0
  17. package/component/collapsible/README.md +216 -0
  18. package/component/combobox/README.md +202 -0
  19. package/component/command/README.md +287 -0
  20. package/component/composer/README.md +241 -0
  21. package/component/context-menu/README.md +268 -0
  22. package/component/date-picker/README.md +202 -0
  23. package/component/dialog/README.md +276 -0
  24. package/component/drawer/README.md +147 -0
  25. package/component/dropdown-menu/README.md +336 -0
  26. package/component/editor/README.md +152 -0
  27. package/component/empty/README.md +193 -0
  28. package/component/form/README.md +216 -0
  29. package/component/hover-card/README.md +150 -0
  30. package/component/icon/README.md +25 -0
  31. package/component/input/README.md +160 -0
  32. package/component/input-group/README.md +245 -0
  33. package/component/input-otp/README.md +331 -0
  34. package/component/item/README.md +254 -0
  35. package/component/kanban/README.md +81 -0
  36. package/component/kbd/README.md +141 -0
  37. package/component/label/README.md +137 -0
  38. package/component/menubar/README.md +270 -0
  39. package/component/native-select/README.md +176 -0
  40. package/component/navigation-menu/README.md +165 -0
  41. package/component/pagination/README.md +151 -0
  42. package/component/pillbox/README.md +68 -0
  43. package/component/popover/README.md +54 -0
  44. package/component/progress/README.md +160 -0
  45. package/component/radio/README.md +212 -0
  46. package/component/resizable/README.md +178 -0
  47. package/component/scroll-area/README.md +150 -0
  48. package/component/select/README.md +228 -0
  49. package/component/separator/README.md +175 -0
  50. package/component/sheet/README.md +190 -0
  51. package/component/skeleton/README.md +158 -0
  52. package/component/slider/README.md +207 -0
  53. package/component/spinner/README.md +160 -0
  54. package/component/switch/README.md +170 -0
  55. package/component/table/README.md +292 -0
  56. package/component/tabs/README.md +220 -0
  57. package/component/textarea/README.md +169 -0
  58. package/component/timeline/README.md +94 -0
  59. package/component/toast/README.md +173 -0
  60. package/component/toggle/README.md +133 -0
  61. package/component/toggle-group/README.md +234 -0
  62. package/component/tooltip/README.md +230 -0
  63. package/fesm2022/ojiepermana-angular-chart-area.mjs +289 -3
  64. package/fesm2022/ojiepermana-angular-chart-bar.mjs +722 -3
  65. package/fesm2022/ojiepermana-angular-chart-core.mjs +1482 -3
  66. package/fesm2022/ojiepermana-angular-chart-line.mjs +294 -3
  67. package/fesm2022/ojiepermana-angular-chart-pie.mjs +291 -3
  68. package/fesm2022/ojiepermana-angular-chart-primitives.mjs +1301 -3
  69. package/fesm2022/ojiepermana-angular-chart-radar.mjs +421 -3
  70. package/fesm2022/ojiepermana-angular-chart-radial.mjs +295 -3
  71. package/fesm2022/ojiepermana-angular-chart-scatter.mjs +306 -3
  72. package/fesm2022/ojiepermana-angular-chart.mjs +12 -3
  73. package/fesm2022/ojiepermana-angular-component-accordion.mjs +267 -3
  74. package/fesm2022/ojiepermana-angular-component-alert-dialog.mjs +359 -3
  75. package/fesm2022/ojiepermana-angular-component-alert.mjs +101 -3
  76. package/fesm2022/ojiepermana-angular-component-aspect-ratio.mjs +31 -3
  77. package/fesm2022/ojiepermana-angular-component-avatar.mjs +139 -3
  78. package/fesm2022/ojiepermana-angular-component-badge.mjs +57 -3
  79. package/fesm2022/ojiepermana-angular-component-breadcrumb.mjs +192 -3
  80. package/fesm2022/ojiepermana-angular-component-button-group.mjs +95 -3
  81. package/fesm2022/ojiepermana-angular-component-button.mjs +73 -3
  82. package/fesm2022/ojiepermana-angular-component-calendar.mjs +718 -3
  83. package/fesm2022/ojiepermana-angular-component-card.mjs +167 -3
  84. package/fesm2022/ojiepermana-angular-component-carousel.mjs +326 -3
  85. package/fesm2022/ojiepermana-angular-component-checkbox.mjs +190 -3
  86. package/fesm2022/ojiepermana-angular-component-collapsible.mjs +117 -3
  87. package/fesm2022/ojiepermana-angular-component-combobox.mjs +327 -3
  88. package/fesm2022/ojiepermana-angular-component-command.mjs +351 -3
  89. package/fesm2022/ojiepermana-angular-component-composer.mjs +359 -3
  90. package/fesm2022/ojiepermana-angular-component-context-menu.mjs +158 -3
  91. package/fesm2022/ojiepermana-angular-component-date-picker.mjs +482 -3
  92. package/fesm2022/ojiepermana-angular-component-dialog.mjs +400 -3
  93. package/fesm2022/ojiepermana-angular-component-drawer.mjs +1 -3
  94. package/fesm2022/ojiepermana-angular-component-dropdown-menu.mjs +689 -3
  95. package/fesm2022/ojiepermana-angular-component-editor.mjs +511 -3
  96. package/fesm2022/ojiepermana-angular-component-empty.mjs +134 -3
  97. package/fesm2022/ojiepermana-angular-component-form.mjs +438 -3
  98. package/fesm2022/ojiepermana-angular-component-hover-card.mjs +273 -3
  99. package/fesm2022/ojiepermana-angular-component-icon.mjs +139 -3
  100. package/fesm2022/ojiepermana-angular-component-input-group.mjs +176 -3
  101. package/fesm2022/ojiepermana-angular-component-input-otp.mjs +550 -3
  102. package/fesm2022/ojiepermana-angular-component-input.mjs +52 -3
  103. package/fesm2022/ojiepermana-angular-component-item.mjs +264 -3
  104. package/fesm2022/ojiepermana-angular-component-kanban.mjs +310 -3
  105. package/fesm2022/ojiepermana-angular-component-kbd.mjs +48 -3
  106. package/fesm2022/ojiepermana-angular-component-label.mjs +27 -3
  107. package/fesm2022/ojiepermana-angular-component-menubar.mjs +327 -3
  108. package/fesm2022/ojiepermana-angular-component-native-select.mjs +62 -3
  109. package/fesm2022/ojiepermana-angular-component-navigation-menu.mjs +378 -3
  110. package/fesm2022/ojiepermana-angular-component-pagination.mjs +238 -3
  111. package/fesm2022/ojiepermana-angular-component-pillbox.mjs +999 -3
  112. package/fesm2022/ojiepermana-angular-component-popover.mjs +201 -3
  113. package/fesm2022/ojiepermana-angular-component-progress.mjs +57 -3
  114. package/fesm2022/ojiepermana-angular-component-radio.mjs +180 -3
  115. package/fesm2022/ojiepermana-angular-component-resizable.mjs +493 -3
  116. package/fesm2022/ojiepermana-angular-component-scroll-area.mjs +51 -3
  117. package/fesm2022/ojiepermana-angular-component-segmented-control.mjs +227 -3
  118. package/fesm2022/ojiepermana-angular-component-select.mjs +609 -3
  119. package/fesm2022/ojiepermana-angular-component-separator.mjs +31 -3
  120. package/fesm2022/ojiepermana-angular-component-sheet.mjs +407 -3
  121. package/fesm2022/ojiepermana-angular-component-skeleton.mjs +25 -3
  122. package/fesm2022/ojiepermana-angular-component-slider.mjs +456 -3
  123. package/fesm2022/ojiepermana-angular-component-spinner.mjs +56 -3
  124. package/fesm2022/ojiepermana-angular-component-switch.mjs +145 -3
  125. package/fesm2022/ojiepermana-angular-component-table.mjs +155 -3
  126. package/fesm2022/ojiepermana-angular-component-tabs.mjs +315 -3
  127. package/fesm2022/ojiepermana-angular-component-textarea.mjs +46 -3
  128. package/fesm2022/ojiepermana-angular-component-timeline.mjs +237 -3
  129. package/fesm2022/ojiepermana-angular-component-toast.mjs +241 -3
  130. package/fesm2022/ojiepermana-angular-component-toggle-group.mjs +290 -3
  131. package/fesm2022/ojiepermana-angular-component-toggle.mjs +76 -3
  132. package/fesm2022/ojiepermana-angular-component-tooltip.mjs +519 -3
  133. package/fesm2022/ojiepermana-angular-component-utils-core.mjs +310 -3
  134. package/fesm2022/ojiepermana-angular-component-utils-overlay.mjs +62 -3
  135. package/fesm2022/ojiepermana-angular-component-utils-scale.mjs +34 -3
  136. package/fesm2022/ojiepermana-angular-component-utils.mjs +3 -2
  137. package/fesm2022/ojiepermana-angular-component.mjs +4 -4
  138. package/fesm2022/ojiepermana-angular-navigation-core.mjs +21 -3
  139. package/fesm2022/ojiepermana-angular-navigation-icon.mjs +20 -3
  140. package/fesm2022/ojiepermana-angular-navigation-navigation-badge-count.component-CDBxQ8rk.mjs +91 -0
  141. package/fesm2022/ojiepermana-angular-navigation-navigation-dockbar-menu.component-DBQHdvGa.mjs +512 -0
  142. package/fesm2022/ojiepermana-angular-navigation-navigation-entry-grid.component-Cd-jh6tg.mjs +623 -0
  143. package/fesm2022/ojiepermana-angular-navigation-navigation-flyout-menu.component-BCGvhoYj.mjs +404 -0
  144. package/fesm2022/ojiepermana-angular-navigation-navigation-horizontal.component-Dk_03e-6.mjs +466 -0
  145. package/fesm2022/ojiepermana-angular-navigation-ojiepermana-angular-navigation-DNKU6viC.mjs +2642 -0
  146. package/fesm2022/ojiepermana-angular-navigation-service.mjs +725 -3
  147. package/fesm2022/ojiepermana-angular-navigation-types.mjs +65 -4
  148. package/fesm2022/ojiepermana-angular-navigation.mjs +4 -10
  149. package/fesm2022/ojiepermana-angular-sdk.mjs +204 -4
  150. package/fesm2022/ojiepermana-angular-theme-component-settings.mjs +1387 -3
  151. package/fesm2022/ojiepermana-angular-theme-layout-services.mjs +331 -3
  152. package/fesm2022/ojiepermana-angular-theme-layout-types.mjs +45 -4
  153. package/fesm2022/ojiepermana-angular-theme-layout-wrapper.mjs +1044 -3
  154. package/fesm2022/ojiepermana-angular-theme-layout.mjs +729 -3
  155. package/fesm2022/ojiepermana-angular-theme-page-core.mjs +381 -3
  156. package/fesm2022/ojiepermana-angular-theme-page-filter.mjs +267 -3
  157. package/fesm2022/ojiepermana-angular-theme-page-root.mjs +361 -3
  158. package/fesm2022/ojiepermana-angular-theme-page-side.mjs +198 -3
  159. package/fesm2022/ojiepermana-angular-theme-page-slots.mjs +110 -3
  160. package/fesm2022/ojiepermana-angular-theme-page.mjs +7 -2
  161. package/fesm2022/ojiepermana-angular-theme-shell-services.mjs +338 -3
  162. package/fesm2022/ojiepermana-angular-theme-shell-types.mjs +160 -4
  163. package/fesm2022/ojiepermana-angular-theme-shell.mjs +811 -3
  164. package/fesm2022/ojiepermana-angular-theme-styles.mjs +783 -3
  165. package/fesm2022/ojiepermana-angular-theme.mjs +4 -4
  166. package/fesm2022/ojiepermana-angular.mjs +6 -11
  167. package/navigation/README.md +374 -0
  168. package/package.json +81 -20
  169. package/sdk/README.md +212 -0
  170. package/sdk/schematics/collection.json +20 -0
  171. package/sdk/schematics/init/index.js +83 -0
  172. package/sdk/schematics/init/schema.json +19 -0
  173. package/sdk/schematics/ng-add/index.js +147 -0
  174. package/sdk/schematics/ng-add/schema.json +14 -0
  175. package/sdk/schematics/package.json +3 -0
  176. package/sdk/schematics/sdk/index.js +175 -0
  177. package/sdk/schematics/sdk/schema.json +19 -0
  178. package/sdk/sdk.config.example.json +24 -0
  179. package/sdk/src/config/loader.js +43 -0
  180. package/sdk/src/config/schema.js +59 -0
  181. package/sdk/src/emit/client.js +251 -0
  182. package/sdk/src/emit/metadata.js +310 -0
  183. package/sdk/src/emit/models.js +104 -0
  184. package/sdk/src/emit/navigation.js +56 -0
  185. package/sdk/src/emit/operations.js +118 -0
  186. package/sdk/src/emit/public-api.js +54 -0
  187. package/sdk/src/emit/services.js +110 -0
  188. package/sdk/src/engine.js +67 -0
  189. package/sdk/src/layout/per-domain.js +360 -0
  190. package/sdk/src/package.json +3 -0
  191. package/sdk/src/parser/bundle.js +25 -0
  192. package/sdk/src/parser/ir.js +429 -0
  193. package/sdk/src/parser/types.js +7 -0
  194. package/sdk/src/render/template.js +152 -0
  195. package/sdk/src/writer/index.js +286 -0
  196. package/theme/README.md +126 -0
  197. package/theme/component/settings/README.md +135 -0
  198. package/theme/layout/README.md +539 -0
  199. package/theme/page/README.md +453 -0
  200. package/theme/shell/README.md +340 -0
  201. package/theme/styles/README.md +178 -0
  202. package/theme/styles/css/base/components.css +553 -0
  203. package/theme/styles/css/base/index.css +14 -0
  204. package/theme/styles/css/base/package.css +9 -0
  205. package/theme/styles/css/base/prefers-dark.css +86 -0
  206. package/theme/styles/css/base/print.css +62 -0
  207. package/theme/styles/css/base/status.css +38 -0
  208. package/theme/styles/css/base/tailwind.css +165 -0
  209. package/theme/styles/css/base/theme.css +374 -0
  210. package/theme/styles/css/base/tokens.css +361 -0
  211. package/theme/styles/css/color/amber.css +72 -0
  212. package/theme/styles/css/color/blue.css +72 -0
  213. package/theme/styles/css/color/brand.css +38 -0
  214. package/theme/styles/css/color/cyan.css +72 -0
  215. package/theme/styles/css/color/emerald.css +72 -0
  216. package/theme/styles/css/color/fuchsia.css +72 -0
  217. package/theme/styles/css/color/green.css +72 -0
  218. package/theme/styles/css/color/index.css +19 -0
  219. package/theme/styles/css/color/indigo.css +72 -0
  220. package/theme/styles/css/color/lime.css +72 -0
  221. package/theme/styles/css/color/orange.css +72 -0
  222. package/theme/styles/css/color/pink.css +72 -0
  223. package/theme/styles/css/color/purple.css +72 -0
  224. package/theme/styles/css/color/red.css +72 -0
  225. package/theme/styles/css/color/rose.css +72 -0
  226. package/theme/styles/css/color/sky.css +72 -0
  227. package/theme/styles/css/color/teal.css +72 -0
  228. package/theme/styles/css/color/violet.css +72 -0
  229. package/theme/styles/css/color/yellow.css +72 -0
  230. package/theme/styles/css/index.css +18 -0
  231. package/theme/styles/css/neutral/gray.css +63 -0
  232. package/theme/styles/css/neutral/index.css +11 -0
  233. package/theme/styles/css/neutral/mauve.css +63 -0
  234. package/theme/styles/css/neutral/mist.css +63 -0
  235. package/theme/styles/css/neutral/neutral.css +63 -0
  236. package/theme/styles/css/neutral/olive.css +63 -0
  237. package/theme/styles/css/neutral/slate.css +63 -0
  238. package/theme/styles/css/neutral/stone.css +63 -0
  239. package/theme/styles/css/neutral/taupe.css +63 -0
  240. package/theme/styles/css/neutral/zinc.css +63 -0
  241. package/theme/styles/css/radius/index.css +30 -0
  242. package/theme/styles/css/space/index.css +20 -0
  243. package/types/ojiepermana-angular-chart-area.d.ts +76 -1
  244. package/types/ojiepermana-angular-chart-bar.d.ts +201 -1
  245. package/types/ojiepermana-angular-chart-core.d.ts +811 -1
  246. package/types/ojiepermana-angular-chart-line.d.ts +75 -1
  247. package/types/ojiepermana-angular-chart-pie.d.ts +131 -1
  248. package/types/ojiepermana-angular-chart-primitives.d.ts +291 -1
  249. package/types/ojiepermana-angular-chart-radar.d.ts +116 -1
  250. package/types/ojiepermana-angular-chart-radial.d.ts +116 -1
  251. package/types/ojiepermana-angular-chart-scatter.d.ts +125 -1
  252. package/types/ojiepermana-angular-chart.d.ts +2 -1
  253. package/types/ojiepermana-angular-component-accordion.d.ts +85 -1
  254. package/types/ojiepermana-angular-component-alert-dialog.d.ts +140 -1
  255. package/types/ojiepermana-angular-component-alert.d.ts +42 -1
  256. package/types/ojiepermana-angular-component-aspect-ratio.d.ts +12 -1
  257. package/types/ojiepermana-angular-component-avatar.d.ts +56 -1
  258. package/types/ojiepermana-angular-component-badge.d.ts +24 -1
  259. package/types/ojiepermana-angular-component-breadcrumb.d.ts +46 -1
  260. package/types/ojiepermana-angular-component-button-group.d.ts +26 -1
  261. package/types/ojiepermana-angular-component-button.d.ts +27 -1
  262. package/types/ojiepermana-angular-component-calendar.d.ts +111 -1
  263. package/types/ojiepermana-angular-component-card.d.ts +69 -1
  264. package/types/ojiepermana-angular-component-carousel.d.ts +86 -1
  265. package/types/ojiepermana-angular-component-checkbox.d.ts +42 -1
  266. package/types/ojiepermana-angular-component-collapsible.d.ts +42 -1
  267. package/types/ojiepermana-angular-component-combobox.d.ts +60 -1
  268. package/types/ojiepermana-angular-component-command.d.ts +130 -1
  269. package/types/ojiepermana-angular-component-composer.d.ts +90 -1
  270. package/types/ojiepermana-angular-component-context-menu.d.ts +54 -1
  271. package/types/ojiepermana-angular-component-date-picker.d.ts +109 -1
  272. package/types/ojiepermana-angular-component-dialog.d.ts +136 -1
  273. package/types/ojiepermana-angular-component-drawer.d.ts +1 -1
  274. package/types/ojiepermana-angular-component-dropdown-menu.d.ts +248 -1
  275. package/types/ojiepermana-angular-component-editor.d.ts +135 -1
  276. package/types/ojiepermana-angular-component-empty.d.ts +50 -1
  277. package/types/ojiepermana-angular-component-form.d.ts +159 -1
  278. package/types/ojiepermana-angular-component-hover-card.d.ts +75 -1
  279. package/types/ojiepermana-angular-component-icon.d.ts +89 -1
  280. package/types/ojiepermana-angular-component-input-group.d.ts +51 -1
  281. package/types/ojiepermana-angular-component-input-otp.d.ts +155 -1
  282. package/types/ojiepermana-angular-component-input.d.ts +21 -1
  283. package/types/ojiepermana-angular-component-item.d.ts +93 -1
  284. package/types/ojiepermana-angular-component-kanban.d.ts +70 -1
  285. package/types/ojiepermana-angular-component-kbd.d.ts +16 -1
  286. package/types/ojiepermana-angular-component-label.d.ts +11 -1
  287. package/types/ojiepermana-angular-component-menubar.d.ts +93 -1
  288. package/types/ojiepermana-angular-component-native-select.d.ts +26 -1
  289. package/types/ojiepermana-angular-component-navigation-menu.d.ts +104 -1
  290. package/types/ojiepermana-angular-component-pagination.d.ts +33 -1
  291. package/types/ojiepermana-angular-component-pillbox.d.ts +222 -1
  292. package/types/ojiepermana-angular-component-popover.d.ts +66 -1
  293. package/types/ojiepermana-angular-component-progress.d.ts +17 -1
  294. package/types/ojiepermana-angular-component-radio.d.ts +60 -1
  295. package/types/ojiepermana-angular-component-resizable.d.ts +117 -1
  296. package/types/ojiepermana-angular-component-scroll-area.d.ts +19 -1
  297. package/types/ojiepermana-angular-component-segmented-control.d.ts +58 -1
  298. package/types/ojiepermana-angular-component-select.d.ts +122 -1
  299. package/types/ojiepermana-angular-component-separator.d.ts +14 -1
  300. package/types/ojiepermana-angular-component-sheet.d.ts +130 -1
  301. package/types/ojiepermana-angular-component-skeleton.d.ts +10 -1
  302. package/types/ojiepermana-angular-component-slider.d.ts +83 -1
  303. package/types/ojiepermana-angular-component-spinner.d.ts +13 -1
  304. package/types/ojiepermana-angular-component-switch.d.ts +44 -1
  305. package/types/ojiepermana-angular-component-table.d.ts +57 -1
  306. package/types/ojiepermana-angular-component-tabs.d.ts +124 -1
  307. package/types/ojiepermana-angular-component-textarea.d.ts +17 -1
  308. package/types/ojiepermana-angular-component-timeline.d.ts +64 -1
  309. package/types/ojiepermana-angular-component-toast.d.ts +64 -1
  310. package/types/ojiepermana-angular-component-toggle-group.d.ts +90 -1
  311. package/types/ojiepermana-angular-component-toggle.d.ts +25 -1
  312. package/types/ojiepermana-angular-component-tooltip.d.ts +143 -1
  313. package/types/ojiepermana-angular-component-utils-core.d.ts +184 -1
  314. package/types/ojiepermana-angular-component-utils-overlay.d.ts +21 -1
  315. package/types/ojiepermana-angular-component-utils-scale.d.ts +19 -1
  316. package/types/ojiepermana-angular-component-utils.d.ts +2 -1
  317. package/types/ojiepermana-angular-component.d.ts +2 -1
  318. package/types/ojiepermana-angular-navigation-core.d.ts +59 -1
  319. package/types/ojiepermana-angular-navigation-icon.d.ts +12 -1
  320. package/types/ojiepermana-angular-navigation-service.d.ts +116 -1
  321. package/types/ojiepermana-angular-navigation-types.d.ts +144 -1
  322. package/types/ojiepermana-angular-navigation.d.ts +507 -1
  323. package/types/ojiepermana-angular-sdk.d.ts +89 -1
  324. package/types/ojiepermana-angular-theme-component-settings.d.ts +154 -1
  325. package/types/ojiepermana-angular-theme-layout-services.d.ts +147 -1
  326. package/types/ojiepermana-angular-theme-layout-types.d.ts +40 -1
  327. package/types/ojiepermana-angular-theme-layout-wrapper.d.ts +299 -1
  328. package/types/ojiepermana-angular-theme-layout.d.ts +129 -1
  329. package/types/ojiepermana-angular-theme-page-core.d.ts +157 -1
  330. package/types/ojiepermana-angular-theme-page-filter.d.ts +77 -1
  331. package/types/ojiepermana-angular-theme-page-root.d.ts +88 -1
  332. package/types/ojiepermana-angular-theme-page-side.d.ts +50 -1
  333. package/types/ojiepermana-angular-theme-page-slots.d.ts +40 -1
  334. package/types/ojiepermana-angular-theme-page.d.ts +5 -1
  335. package/types/ojiepermana-angular-theme-shell-services.d.ts +193 -1
  336. package/types/ojiepermana-angular-theme-shell-types.d.ts +105 -1
  337. package/types/ojiepermana-angular-theme-shell.d.ts +100 -1
  338. package/types/ojiepermana-angular-theme-styles.d.ts +319 -1
  339. package/types/ojiepermana-angular-theme.d.ts +2 -1
  340. package/types/ojiepermana-angular.d.ts +5 -5
@@ -0,0 +1,286 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.writeStandalone = writeStandalone;
4
+ exports.writeLibrary = writeLibrary;
5
+ exports.writeSecondaryEntrypoint = writeSecondaryEntrypoint;
6
+ const node_fs_1 = require("node:fs");
7
+ const node_path_1 = require("node:path");
8
+ const template_1 = require("../render/template");
9
+ const ROOT_ENTRYPOINT = '';
10
+ const VIRTUAL_ROOT = '/__sdk__';
11
+ /**
12
+ * No-op writer for the standalone mode — returns emitted files unchanged. Kept
13
+ * as a named function so modes are composable from a single switch at the
14
+ * engine layer.
15
+ */
16
+ function writeStandalone(files) {
17
+ return files;
18
+ }
19
+ /**
20
+ * Library mode: add `ng-package.json`, `package.json`, and a top-level README
21
+ * so the `output` folder can be built with ng-packagr directly.
22
+ */
23
+ function writeLibrary(files, ir, target, workspaceRoot, outputDir) {
24
+ const normalizedFiles = rewriteCrossEntrypointImports(files, target, workspaceRoot, outputDir);
25
+ const ngPackage = {
26
+ $schema: toPosixPath((0, node_path_1.relative)(outputDir, (0, node_path_1.resolve)(workspaceRoot, 'node_modules/ng-packagr/ng-package.schema.json'))),
27
+ dest: resolveLibraryDestPath(workspaceRoot, outputDir),
28
+ lib: { entryFile: 'public-api.ts' },
29
+ };
30
+ const pkg = {
31
+ name: target.packageName,
32
+ version: target.packageVersion,
33
+ description: `Generated SDK for ${ir.title} ${ir.version}`,
34
+ peerDependencies: {
35
+ '@angular/common': '>=22.1.0',
36
+ '@angular/core': '>=22.1.0',
37
+ rxjs: '>=7.8.0',
38
+ },
39
+ sideEffects: false,
40
+ };
41
+ return [
42
+ ...normalizedFiles,
43
+ createNgPackageFile('ng-package.json', ngPackage),
44
+ ...createNestedEntrypointNgPackages(normalizedFiles),
45
+ {
46
+ path: 'package.json',
47
+ content: (0, template_1.finalize)(JSON.stringify(pkg, null, 2)),
48
+ },
49
+ ...createLibraryTsConfigFiles(workspaceRoot, outputDir),
50
+ {
51
+ path: 'README.md',
52
+ content: (0, template_1.finalize)(`# ${target.packageName}\n\nGenerated SDK for **${ir.title}** v${ir.version}.\n\nThis folder was generated by the local SDK generator. Do not edit by hand.\n`),
53
+ },
54
+ ];
55
+ }
56
+ /**
57
+ * Secondary-entrypoint mode: same file set as standalone, plus a minimal
58
+ * `ng-package.json` pointing at `public-api.ts`. Meant to live **inside** an
59
+ * existing library (e.g. `projects/angular/sdk-api/`) so ng-packagr picks it
60
+ * up automatically as a secondary entrypoint of the parent library.
61
+ */
62
+ function writeSecondaryEntrypoint(files, _ir, target, workspaceRoot, outputDir) {
63
+ const normalizedFiles = rewriteCrossEntrypointImports(files, target, workspaceRoot, outputDir);
64
+ const ngPackage = {
65
+ lib: { entryFile: 'public-api.ts' },
66
+ };
67
+ return [
68
+ ...normalizedFiles,
69
+ createNgPackageFile('ng-package.json', ngPackage),
70
+ ...createNestedEntrypointNgPackages(normalizedFiles),
71
+ ];
72
+ }
73
+ function rewriteCrossEntrypointImports(files, target, workspaceRoot, outputDir) {
74
+ const entrypointDirs = collectEntrypointDirs(files);
75
+ if (entrypointDirs.length <= 1) {
76
+ return [...files];
77
+ }
78
+ const packageImportBase = resolvePackageImportBase(target, workspaceRoot, outputDir);
79
+ if (!packageImportBase) {
80
+ return [...files];
81
+ }
82
+ const knownFiles = new Set(files.map((file) => file.path));
83
+ return files.map((file) => {
84
+ const owner = findEntrypointOwner(file.path, entrypointDirs);
85
+ return {
86
+ ...file,
87
+ content: file.content.replace(/(from\s+['"])([^'"]+)(['"])/g, (_match, prefix, spec, suffix) => {
88
+ const nextSpec = rewriteModuleSpecifier(spec, file.path, owner, entrypointDirs, knownFiles, packageImportBase);
89
+ return `${prefix}${nextSpec}${suffix}`;
90
+ }),
91
+ };
92
+ });
93
+ }
94
+ function rewriteModuleSpecifier(specifier, currentPath, currentOwner, entrypointDirs, knownFiles, packageImportBase) {
95
+ if (!specifier.startsWith('./') && !specifier.startsWith('../')) {
96
+ return specifier;
97
+ }
98
+ const targetPath = resolveVirtualFilePath(currentPath, specifier, knownFiles);
99
+ if (!targetPath) {
100
+ return specifier;
101
+ }
102
+ const targetOwner = findEntrypointOwner(targetPath, entrypointDirs);
103
+ if (targetOwner === currentOwner) {
104
+ return specifier;
105
+ }
106
+ return buildEntrypointImport(packageImportBase, targetOwner);
107
+ }
108
+ function resolveVirtualFilePath(currentPath, specifier, knownFiles) {
109
+ const currentAbs = node_path_1.posix.join(VIRTUAL_ROOT, currentPath);
110
+ const resolved = node_path_1.posix.normalize(node_path_1.posix.join((0, node_path_1.dirname)(currentAbs), specifier));
111
+ const candidates = [
112
+ `${resolved}.ts`,
113
+ `${resolved}/index.ts`,
114
+ `${resolved}/public-api.ts`,
115
+ resolved,
116
+ ];
117
+ for (const candidate of candidates) {
118
+ if (!candidate.startsWith(`${VIRTUAL_ROOT}/`)) {
119
+ continue;
120
+ }
121
+ const relativePath = candidate.slice(VIRTUAL_ROOT.length + 1);
122
+ if (knownFiles.has(relativePath)) {
123
+ return relativePath;
124
+ }
125
+ }
126
+ return undefined;
127
+ }
128
+ function resolvePackageImportBase(target, workspaceRoot, outputDir) {
129
+ if (target.mode === 'library') {
130
+ return target.packageName;
131
+ }
132
+ if (target.mode !== 'secondary-entrypoint') {
133
+ return '';
134
+ }
135
+ return inferSecondaryEntrypointPackageName(workspaceRoot, outputDir, target.packageName);
136
+ }
137
+ function inferSecondaryEntrypointPackageName(workspaceRoot, outputDir, fallback) {
138
+ let currentDir = outputDir;
139
+ let nearestPackageDir;
140
+ let nearestPackagrDir;
141
+ while (isWithinWorkspace(currentDir, workspaceRoot)) {
142
+ const packageJsonPath = (0, node_path_1.resolve)(currentDir, 'package.json');
143
+ if ((0, node_fs_1.existsSync)(packageJsonPath)) {
144
+ nearestPackageDir ??= currentDir;
145
+ if ((0, node_fs_1.existsSync)((0, node_path_1.resolve)(currentDir, 'ng-package.json'))) {
146
+ nearestPackagrDir = currentDir;
147
+ break;
148
+ }
149
+ }
150
+ if (currentDir === workspaceRoot) {
151
+ break;
152
+ }
153
+ const parentDir = (0, node_path_1.dirname)(currentDir);
154
+ if (parentDir === currentDir) {
155
+ break;
156
+ }
157
+ currentDir = parentDir;
158
+ }
159
+ const packageDir = nearestPackagrDir ?? nearestPackageDir;
160
+ if (!packageDir) {
161
+ return fallback;
162
+ }
163
+ const packageName = readPackageName(packageDir);
164
+ if (!packageName) {
165
+ return fallback;
166
+ }
167
+ const relativeOutput = toPosixPath((0, node_path_1.relative)(packageDir, outputDir)).replace(/^\.\//, '');
168
+ if (!relativeOutput || relativeOutput === '.') {
169
+ return packageName;
170
+ }
171
+ return `${packageName}/${relativeOutput}`;
172
+ }
173
+ function readPackageName(packageDir) {
174
+ const packageJsonPath = (0, node_path_1.resolve)(packageDir, 'package.json');
175
+ if (!(0, node_fs_1.existsSync)(packageJsonPath)) {
176
+ return undefined;
177
+ }
178
+ let raw;
179
+ try {
180
+ raw = JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, 'utf8'));
181
+ }
182
+ catch (cause) {
183
+ throw new Error(`Failed to read ${packageJsonPath}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
184
+ }
185
+ return typeof raw.name === 'string' && raw.name.length > 0 ? raw.name : undefined;
186
+ }
187
+ function isWithinWorkspace(candidate, workspaceRoot) {
188
+ const rel = (0, node_path_1.relative)(workspaceRoot, candidate);
189
+ return rel === '' || (!rel.startsWith('..') && !(0, node_path_1.isAbsolute)(rel));
190
+ }
191
+ function collectEntrypointDirs(files) {
192
+ const dirs = new Set();
193
+ for (const file of files) {
194
+ if (file.path === 'public-api.ts') {
195
+ dirs.add(ROOT_ENTRYPOINT);
196
+ continue;
197
+ }
198
+ if (!file.path.endsWith('/public-api.ts')) {
199
+ continue;
200
+ }
201
+ dirs.add(file.path.slice(0, -'/public-api.ts'.length));
202
+ }
203
+ return [...dirs].sort((left, right) => right.length - left.length || left.localeCompare(right));
204
+ }
205
+ function findEntrypointOwner(filePath, entrypointDirs) {
206
+ for (const entrypointDir of entrypointDirs) {
207
+ if (entrypointDir === ROOT_ENTRYPOINT) {
208
+ continue;
209
+ }
210
+ if (filePath === `${entrypointDir}/public-api.ts` || filePath.startsWith(`${entrypointDir}/`)) {
211
+ return entrypointDir;
212
+ }
213
+ }
214
+ return ROOT_ENTRYPOINT;
215
+ }
216
+ function buildEntrypointImport(packageImportBase, entrypointDir) {
217
+ return entrypointDir ? `${packageImportBase}/${entrypointDir}` : packageImportBase;
218
+ }
219
+ function createNestedEntrypointNgPackages(files) {
220
+ return collectSecondaryEntrypointDirs(files).map((dir) => createNgPackageFile(`${dir}/ng-package.json`, {
221
+ lib: { entryFile: 'public-api.ts' },
222
+ }));
223
+ }
224
+ function collectSecondaryEntrypointDirs(files) {
225
+ const dirs = new Set();
226
+ for (const file of files) {
227
+ if (!file.path.endsWith('/public-api.ts')) {
228
+ continue;
229
+ }
230
+ dirs.add(file.path.slice(0, -'/public-api.ts'.length));
231
+ }
232
+ return [...dirs].sort();
233
+ }
234
+ function resolveLibraryDestPath(workspaceRoot, outputDir) {
235
+ const outputFolderName = (0, node_path_1.basename)(outputDir) || 'sdk';
236
+ return toPosixPath((0, node_path_1.relative)(outputDir, (0, node_path_1.resolve)(workspaceRoot, 'dist', outputFolderName)));
237
+ }
238
+ function createLibraryTsConfigFiles(workspaceRoot, outputDir) {
239
+ const rootTsConfig = toPosixPath((0, node_path_1.relative)(outputDir, (0, node_path_1.resolve)(workspaceRoot, 'tsconfig.json')));
240
+ const outDir = toPosixPath((0, node_path_1.relative)(outputDir, (0, node_path_1.resolve)(workspaceRoot, 'out-tsc/lib')));
241
+ const distDir = toRecursiveGlob((0, node_path_1.relative)(outputDir, (0, node_path_1.resolve)(workspaceRoot, 'dist')));
242
+ const nodeModulesDir = toRecursiveGlob((0, node_path_1.relative)(outputDir, (0, node_path_1.resolve)(workspaceRoot, 'node_modules')));
243
+ const tsconfigLib = {
244
+ extends: rootTsConfig,
245
+ compilerOptions: {
246
+ outDir,
247
+ declaration: true,
248
+ declarationMap: true,
249
+ types: [],
250
+ },
251
+ include: ['public-api.ts', '**/public-api.ts'],
252
+ exclude: ['**/*.spec.ts', distDir, nodeModulesDir],
253
+ };
254
+ const tsconfigLibProd = {
255
+ extends: './tsconfig.lib.json',
256
+ compilerOptions: {
257
+ declarationMap: false,
258
+ },
259
+ angularCompilerOptions: {
260
+ compilationMode: 'partial',
261
+ },
262
+ };
263
+ return [
264
+ {
265
+ path: 'tsconfig.lib.json',
266
+ content: (0, template_1.finalize)(JSON.stringify(tsconfigLib, null, 2)),
267
+ },
268
+ {
269
+ path: 'tsconfig.lib.prod.json',
270
+ content: (0, template_1.finalize)(JSON.stringify(tsconfigLibProd, null, 2)),
271
+ },
272
+ ];
273
+ }
274
+ function toRecursiveGlob(value) {
275
+ const normalized = toPosixPath(value).replace(/\/+$/, '');
276
+ return normalized === '.' ? './**' : `${normalized}/**`;
277
+ }
278
+ function toPosixPath(value) {
279
+ return value.split('\\').join('/');
280
+ }
281
+ function createNgPackageFile(path, content) {
282
+ return {
283
+ path,
284
+ content: (0, template_1.finalize)(JSON.stringify(content, null, 2)),
285
+ };
286
+ }
@@ -0,0 +1,126 @@
1
+ # @ojiepermana/angular/theme
2
+
3
+ Theme layer for the `@ojiepermana/angular` design system: a runtime provider
4
+ (mode / color / neutral / brand), design tokens, and the Tailwind v4 CSS that the
5
+ components are styled against.
6
+
7
+ ```bash
8
+ bun add @ojiepermana/angular
9
+ # or: npm install @ojiepermana/angular
10
+ ```
11
+
12
+ Everything below is reached through the `theme` subpath of that one package.
13
+
14
+ ## Entry points
15
+
16
+ | Import path | Contents |
17
+ | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
18
+ | `@ojiepermana/angular/theme/styles` | `provideUiTheme`, `ThemeModeService`, `ThemeColorService`, `ThemeBrandService`, `ThemeRadiusService`, `ThemeSpaceService`, … |
19
+ | `@ojiepermana/angular/theme/component/settings` | Navigation-aligned right-side settings drawer; theme axes plus optional consumer-owned layout/navigation adapter |
20
+ | `@ojiepermana/angular/theme/layout` | Layout shell building blocks |
21
+ | `@ojiepermana/angular/theme/shell` | Application shell root: `<Shell>` with `mode` / `device` / `color` axes, its own desktop titlebar, and the Tauri/Electron window bridge |
22
+ | `@ojiepermana/angular/theme/page` | Page-level scaffolding |
23
+ | `@ojiepermana/angular/theme/theme.css` | Base tokens + component styles only — lightweight, no runtime axes |
24
+ | `@ojiepermana/angular/theme/theme-full.css` | Base + every runtime axis (color, neutral, radius, space) — needed for `ThemeColorService`/`ThemeNeutralService` switching |
25
+ | `@ojiepermana/angular/theme/styles/css/*` | Raw CSS assets (per-axis color + neutral palettes, Tailwind map) |
26
+
27
+ ## Tailwind v4 setup
28
+
29
+ The CSS is published with the package and addressable by name. Use `theme-full.css`
30
+ for the full design system (runtime color/neutral switching); use the lightweight
31
+ `theme.css` plus only the axes you need for a smaller bundle.
32
+
33
+ ```css
34
+ /* styles.css — full design system */
35
+ @import '@ojiepermana/angular/theme/theme-full.css'; /* base + all color + neutral palettes */
36
+ @import 'tailwindcss';
37
+ @import '@ojiepermana/angular/theme/styles/css/base/tailwind.css'; /* maps tokens → bg-primary, bg-brand, text-foreground, … */
38
+ ```
39
+
40
+ For a lightweight setup, import the base then opt in to specific axes:
41
+
42
+ ```css
43
+ /* styles.css — base + only the axes you use */
44
+ @import '@ojiepermana/angular/theme/theme.css'; /* base tokens + components, no axes */
45
+ @import 'tailwindcss';
46
+ @import '@ojiepermana/angular/theme/styles/css/base/tailwind.css';
47
+ @import '@ojiepermana/angular/theme/styles/css/color/index.css'; /* opt in to accent palettes */
48
+ @import '@ojiepermana/angular/theme/styles/css/neutral/index.css'; /* opt in to neutral families */
49
+ ```
50
+
51
+ Requires Tailwind CSS `^4.3.0`.
52
+
53
+ ## Provider
54
+
55
+ ```ts
56
+ import { provideUiTheme } from '@ojiepermana/angular/theme/styles';
57
+
58
+ export const appConfig = {
59
+ providers: [
60
+ provideUiTheme({
61
+ mode: 'light',
62
+ color: 'base', // accent palette (base, red…rose, brand)
63
+ neutral: 'base', // gray family (base, slate, gray, zinc, …)
64
+ radius: 'md', // corner radius preset (none, xs, sm, md, xl, full)
65
+ space: 'normal', // spacing density preset (compact, normal, relaxed, spacious)
66
+ brand: { color: '221 83% 53%', foreground: '0 0% 100%' }, // consumer brand
67
+ }),
68
+ ],
69
+ };
70
+ ```
71
+
72
+ - `mode` — bootstraps `ThemeModeService` and persists the default mode (`light` / `dark` / `system`).
73
+ - `color` — bootstraps `ThemeColorService`; initial accent palette (`<html theme-color>`).
74
+ - `neutral` — initial neutral family (`<html theme-neutral>`); composes with any accent.
75
+ - `radius` — bootstraps `ThemeRadiusService`; initial corner-radius preset (`<html theme-radius>`).
76
+ Drives the single `--radius-base` knob so the whole `--radius-*` scale and `rounded-*`
77
+ utilities follow. Values: `none`, `xs`, `sm`, `md` (default), `xl`, `full`;
78
+ each uses Tailwind's stock radius value with the same name.
79
+ - `space` — bootstraps `ThemeSpaceService`; initial spacing-density preset (`<html theme-space>`).
80
+ Drives the single `--spacing-base` knob so every `p-*` / `m-*` / `gap-*` / `w-*` / `h-*`
81
+ utility follows. Values: `compact`, `normal` (default), `relaxed`, `spacious`.
82
+ - `brand` — bootstraps `ThemeBrandService`; sets `--brand` / `bg-brand` and the
83
+ `theme-color='brand'` accent preset. Accepts an HSL triplet string (`'221 83% 53%'`)
84
+ or `{ color, foreground }`. Settable at runtime via `setBrand()`.
85
+
86
+ A persisted choice (localStorage `theme-color` / `theme-neutral` / `theme-radius` /
87
+ `theme-space` / `theme-brand`) always wins over the configured default.
88
+
89
+ ### Color system (FluxUI-style)
90
+
91
+ Four independent axes switch at runtime via attribute selectors on `<html>`:
92
+
93
+ - **accent** (`theme-color`) — `base` (core), `red … rose`, and `brand`. Each
94
+ re-tints the full palette. `base` = no override.
95
+ - **neutral** (`theme-neutral`) — `base` (core), `slate`, `gray`, `zinc`, `neutral`,
96
+ `stone`, `mauve`, `olive`, `mist`, `taupe`. Overrides the gray family and Layout's
97
+ decorative pattern source, and is layered after accent so it wins both token groups.
98
+ With neutral `base`, surface patterns follow the active accent; every other neutral
99
+ gives them its own soft family hue.
100
+ - **radius** (`theme-radius`) — `none`, `xs`, `sm`, `md` (default), `xl`, `full`.
101
+ Sets the `--radius-base` knob; the full `--radius-*` scale and `rounded-*` utilities follow.
102
+ - **space** (`theme-space`) — `compact`, `normal` (default), `relaxed`, `spacious`.
103
+ Sets the `--spacing-base` knob; every `p-*` / `m-*` / `gap-*` / `w-*` / `h-*` utility follows.
104
+
105
+ `theme-full.css` (i.e. `styles/css/index.css`) bundles the core base theme plus
106
+ every accent and neutral palette, so switching needs no runtime CSS loading. The
107
+ lightweight `theme.css` ships base only — import the axis files you need on top of
108
+ it (or use `theme-full.css`) to enable runtime switching.
109
+
110
+ ### Material Symbols icons (opt-in)
111
+
112
+ `provideUiTheme()` makes **no external network request by default**. To preload the
113
+ Material Symbols font from Google Fonts:
114
+
115
+ ```ts
116
+ provideUiTheme({ icons: { materialSymbols: true } });
117
+ ```
118
+
119
+ Leave it off (the default) for privacy / offline / strict CSP, and self-host the
120
+ font in your own stylesheet if you need it.
121
+
122
+ ## Support and security
123
+
124
+ Angular 22.1–22.x CSR/browser usage is supported; SSR, prerendering, and hydration are not. See the
125
+ bundled `SUPPORT.md`. Report suspected vulnerabilities privately using the instructions in the
126
+ bundled `SECURITY.md`. This package is MIT licensed; see the bundled `LICENSE`.
@@ -0,0 +1,135 @@
1
+ # Theme settings
2
+
3
+ Navigation-aligned settings inspector for the runtime theme axes. It is a
4
+ right-side drawer with an optional native button or link-style trigger. Theme
5
+ choices apply and persist immediately; an optional adapter also exposes layout
6
+ and navigation preferences.
7
+
8
+ ## Import
9
+
10
+ ```ts
11
+ import { ThemeSettingsComponent } from '@ojiepermana/angular/theme/component/settings';
12
+ ```
13
+
14
+ ## Navigation button
15
+
16
+ ```ts
17
+ @Component({
18
+ imports: [ThemeSettingsComponent],
19
+ template: `
20
+ <NavigationFooterAction>
21
+ <ThemeSettings trigger-icon-only />
22
+ </NavigationFooterAction>
23
+ `,
24
+ })
25
+ export class AppNavigation {}
26
+ ```
27
+
28
+ The built-in button is focusable, exposes `aria-haspopup="dialog"` and reflects
29
+ the drawer state with `aria-expanded`. Use `trigger="link"` when the trigger
30
+ should read as a text link while retaining button semantics for the action.
31
+
32
+ ## External state
33
+
34
+ ```html
35
+ <button type="button" (click)="themeOpen.set(true)">Personalize theme</button>
36
+ <ThemeSettings [(open)]="themeOpen" [show-trigger]="false" />
37
+ ```
38
+
39
+ The drawer uses the shared Drawer/Sheet overlay: focus is trapped while it is
40
+ open; Escape, backdrop click, and the close controls dismiss it; focus returns
41
+ to the opening trigger. Its header and footer use the navigation topbar height,
42
+ semantic borders, and theme tokens so it sits naturally beside a layout shell.
43
+
44
+ ## Shell
45
+
46
+ Directly below **Theme** sits a **Shell** section with all three shell axes, driven
47
+ by `ShellService` — so they need no adapter and each persists to its own key:
48
+
49
+ | Control | Values | Storage key |
50
+ | -------------- | --------------------------------------- | -------------- |
51
+ | `Shell mode` | `web` / `desktop` / `tablet` / `mobile` | `shell-mode` |
52
+ | `Shell device` | the devices the active mode can host | `shell-device` |
53
+ | `Shell color` | `Sync` / `Native` | `shell-color` |
54
+
55
+ `Shell device` is filtered by the active mode rather than showing all seven with
56
+ most disabled — `web` hosts one device, `desktop` three. It also displays the value
57
+ `<Shell>` would actually render: `ShellService.device()` is a _preference_ that may
58
+ belong to another form factor (a stored `macos` survives a temporary `web` mode), so
59
+ the control shows that preference corrected to the current mode.
60
+
61
+ `Shell color` decides whether the desktop titlebar follows the theme axes above
62
+ (`sync`) or paints the active device's own native chrome (`default`).
63
+
64
+ `Shell mode` constrains the next section: everything but `web` owns the whole surface, so
65
+ there is no page for the layout frame to be inset within. On those modes the width
66
+ picker is disabled down to `full` and says why — see
67
+ [`@ojiepermana/angular/theme/shell`](../../shell/README.md#mode-locks-the-layout-width).
68
+ The user's own width choice is preserved, not overwritten, so switching back to
69
+ `web` restores it.
70
+
71
+ ## Layout and navigation adapter
72
+
73
+ The Theme and Shell sections are always available in any app using
74
+ `provideUiTheme()`. The ordered **Layout** and **Navigation** sections need an
75
+ adapter on `THEME_SETTINGS_ADAPTER`. Use the published default:
76
+
77
+ ```ts
78
+ import { provideThemeSettingsAdapter } from '@ojiepermana/angular/theme/component/settings';
79
+
80
+ export const appConfig = {
81
+ providers: [provideUiTheme({ ... }), provideThemeSettingsAdapter()],
82
+ };
83
+ ```
84
+
85
+ `ThemeSettingsDefaultAdapter` delegates surface, appearance, and width to
86
+ `LayoutService`, and owns layout type, nav type, and nav type mode itself —
87
+ `<Layout>` writes `type` back to follow nav orientation, so reading
88
+ `layout.type()` would drift from the operator's choice. It persists those three
89
+ under `layout-type`, `nav-type`, and `nav-type-mode`, reads them back with a safe
90
+ fallback, and stores nothing but presentation choices. Storage that is missing,
91
+ blocked, or holding a foreign value falls back to the default without throwing.
92
+
93
+ Incoherent axis pairs auto-correct, so the rendered shell never lands in an
94
+ impossible state. The rules are exported for consumers building their own
95
+ settings panel:
96
+
97
+ | Helper | Answers |
98
+ | ----------------------- | ------------------------------------------------------ |
99
+ | `allowedNavTypes()` | which nav types a layout type and shell mode allow |
100
+ | `allowedNavTypeModes()` | which presentation modes a nav type offers |
101
+ | `isWidthEnabled()` | whether `fluid` width means anything for a layout type |
102
+
103
+ A consumer that needs different behavior can still implement
104
+ `ThemeSettingsAdapter` by hand and provide it on the token directly; the default
105
+ adapter is a convenience, not a requirement.
106
+
107
+ ```ts
108
+ import {
109
+ THEME_SETTINGS_ADAPTER,
110
+ type ThemeSettingsAdapter,
111
+ } from '@ojiepermana/angular/theme/component/settings';
112
+
113
+ @Service()
114
+ export class AppLayoutSettings implements ThemeSettingsAdapter {
115
+ // Signals: appearance, surface, layoutType, width, navType, navTypeMode
116
+ // Setters for each axis; persist the values in the consumer app.
117
+ }
118
+
119
+ export const appConfig = {
120
+ providers: [{ provide: THEME_SETTINGS_ADAPTER, useExisting: AppLayoutSettings }],
121
+ };
122
+ ```
123
+
124
+ `navTypeMode` is contextual: sidebar supports **Default** / **Collapsed**,
125
+ dockbar supports **Sticky** / **Drawer**, and horizontal navigation stays at
126
+ **Default**.
127
+
128
+ For `shell mode = desktop` together with `layoutType = horizontal`, `navType`
129
+ has exactly one valid value: **Desktop**. This is a shell choice rather than a
130
+ fifth navigation primitive: the desktop titlebar remains the chrome, while the
131
+ wrapper hides desktop/mobile navigation and gives the content the same focused
132
+ behavior as an `empty` layout. Persist it through
133
+ `ThemeSettingsNavigationType`; entering that shell/layout pair normalizes the
134
+ value to `desktop`, while leaving it normalizes to the first valid nav for the
135
+ new combination.