@ojiepermana/angular 22.2.0 → 22.2.2

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 (129) hide show
  1. package/README.md +18 -7
  2. package/component/icon/README.md +40 -13
  3. package/fesm2022/ojiepermana-angular-chart-area.mjs +3 -3
  4. package/fesm2022/ojiepermana-angular-chart-bar.mjs +5 -5
  5. package/fesm2022/ojiepermana-angular-chart-core.mjs +33 -33
  6. package/fesm2022/ojiepermana-angular-chart-line.mjs +5 -5
  7. package/fesm2022/ojiepermana-angular-chart-pie.mjs +5 -5
  8. package/fesm2022/ojiepermana-angular-chart-primitives.mjs +33 -33
  9. package/fesm2022/ojiepermana-angular-chart-radar.mjs +5 -5
  10. package/fesm2022/ojiepermana-angular-chart-radial.mjs +5 -5
  11. package/fesm2022/ojiepermana-angular-chart-scatter.mjs +3 -3
  12. package/fesm2022/ojiepermana-angular-component-accordion.mjs +17 -17
  13. package/fesm2022/ojiepermana-angular-component-alert-dialog.mjs +27 -27
  14. package/fesm2022/ojiepermana-angular-component-alert.mjs +12 -12
  15. package/fesm2022/ojiepermana-angular-component-aspect-ratio.mjs +3 -3
  16. package/fesm2022/ojiepermana-angular-component-avatar.mjs +18 -18
  17. package/fesm2022/ojiepermana-angular-component-badge.mjs +9 -9
  18. package/fesm2022/ojiepermana-angular-component-breadcrumb.mjs +21 -21
  19. package/fesm2022/ojiepermana-angular-component-button-group.mjs +10 -10
  20. package/fesm2022/ojiepermana-angular-component-button.mjs +4 -4
  21. package/fesm2022/ojiepermana-angular-component-calendar.mjs +5 -5
  22. package/fesm2022/ojiepermana-angular-component-card.mjs +27 -24
  23. package/fesm2022/ojiepermana-angular-component-carousel.mjs +18 -18
  24. package/fesm2022/ojiepermana-angular-component-checkbox.mjs +4 -4
  25. package/fesm2022/ojiepermana-angular-component-collapsible.mjs +12 -12
  26. package/fesm2022/ojiepermana-angular-component-combobox.mjs +3 -3
  27. package/fesm2022/ojiepermana-angular-component-command.mjs +28 -28
  28. package/fesm2022/ojiepermana-angular-component-composer.mjs +22 -22
  29. package/fesm2022/ojiepermana-angular-component-context-menu.mjs +3 -3
  30. package/fesm2022/ojiepermana-angular-component-date-picker.mjs +5 -5
  31. package/fesm2022/ojiepermana-angular-component-dialog.mjs +22 -22
  32. package/fesm2022/ojiepermana-angular-component-drawer.mjs +1 -2
  33. package/fesm2022/ojiepermana-angular-component-dropdown-menu.mjs +39 -39
  34. package/fesm2022/ojiepermana-angular-component-editor.mjs +21 -21
  35. package/fesm2022/ojiepermana-angular-component-empty.mjs +19 -19
  36. package/fesm2022/ojiepermana-angular-component-form.mjs +36 -36
  37. package/fesm2022/ojiepermana-angular-component-hover-card.mjs +9 -9
  38. package/fesm2022/ojiepermana-angular-component-icon.mjs +114 -105
  39. package/fesm2022/ojiepermana-angular-component-input-group.mjs +19 -19
  40. package/fesm2022/ojiepermana-angular-component-input-otp.mjs +16 -16
  41. package/fesm2022/ojiepermana-angular-component-input.mjs +6 -6
  42. package/fesm2022/ojiepermana-angular-component-item.mjs +31 -31
  43. package/fesm2022/ojiepermana-angular-component-kanban.mjs +29 -29
  44. package/fesm2022/ojiepermana-angular-component-kbd.mjs +7 -7
  45. package/fesm2022/ojiepermana-angular-component-label.mjs +3 -3
  46. package/fesm2022/ojiepermana-angular-component-menubar.mjs +13 -13
  47. package/fesm2022/ojiepermana-angular-component-native-select.mjs +14 -14
  48. package/fesm2022/ojiepermana-angular-component-navigation-menu.mjs +21 -21
  49. package/fesm2022/ojiepermana-angular-component-pagination.mjs +3 -3
  50. package/fesm2022/ojiepermana-angular-component-pillbox.mjs +16 -16
  51. package/fesm2022/ojiepermana-angular-component-popover.mjs +6 -6
  52. package/fesm2022/ojiepermana-angular-component-progress.mjs +3 -3
  53. package/fesm2022/ojiepermana-angular-component-radio.mjs +7 -7
  54. package/fesm2022/ojiepermana-angular-component-resizable.mjs +12 -12
  55. package/fesm2022/ojiepermana-angular-component-scroll-area.mjs +3 -3
  56. package/fesm2022/ojiepermana-angular-component-segmented-control.mjs +6 -8
  57. package/fesm2022/ojiepermana-angular-component-select.mjs +8 -8
  58. package/fesm2022/ojiepermana-angular-component-separator.mjs +3 -3
  59. package/fesm2022/ojiepermana-angular-component-sheet.mjs +41 -28
  60. package/fesm2022/ojiepermana-angular-component-skeleton.mjs +3 -3
  61. package/fesm2022/ojiepermana-angular-component-slider.mjs +10 -10
  62. package/fesm2022/ojiepermana-angular-component-spinner.mjs +3 -3
  63. package/fesm2022/ojiepermana-angular-component-switch.mjs +4 -4
  64. package/fesm2022/ojiepermana-angular-component-table.mjs +24 -24
  65. package/fesm2022/ojiepermana-angular-component-tabs.mjs +18 -18
  66. package/fesm2022/ojiepermana-angular-component-textarea.mjs +6 -6
  67. package/fesm2022/ojiepermana-angular-component-timeline.mjs +19 -19
  68. package/fesm2022/ojiepermana-angular-component-toast.mjs +5 -5
  69. package/fesm2022/ojiepermana-angular-component-toggle-group.mjs +9 -9
  70. package/fesm2022/ojiepermana-angular-component-toggle.mjs +5 -5
  71. package/fesm2022/ojiepermana-angular-component-tooltip.mjs +15 -15
  72. package/fesm2022/ojiepermana-angular-component-utils-scale.mjs +3 -3
  73. package/fesm2022/ojiepermana-angular-navigation-icon.mjs +3 -3
  74. package/fesm2022/{ojiepermana-angular-navigation-navigation-badge-count.component-BKCeWzml.mjs → ojiepermana-angular-navigation-navigation-badge-count.component-4RIokl1C.mjs} +3 -3
  75. package/fesm2022/{ojiepermana-angular-navigation-navigation-dockbar-menu.component-DFEJK2jD.mjs → ojiepermana-angular-navigation-navigation-dockbar-menu.component-CGfu2V6f.mjs} +23 -15
  76. package/fesm2022/{ojiepermana-angular-navigation-navigation-entry-grid.component-mpK9Ar08.mjs → ojiepermana-angular-navigation-navigation-entry-grid.component-zBCXDa4c.mjs} +38 -66
  77. package/fesm2022/{ojiepermana-angular-navigation-navigation-flyout-menu.component-BPgH7FJk.mjs → ojiepermana-angular-navigation-navigation-flyout-menu.component-DYkYIIHd.mjs} +14 -13
  78. package/fesm2022/{ojiepermana-angular-navigation-navigation-horizontal.component-DMpYcD9t.mjs → ojiepermana-angular-navigation-navigation-horizontal.component-LNTertHr.mjs} +5 -5
  79. package/fesm2022/{ojiepermana-angular-navigation-navigation-item.component-Basp5SIk.mjs → ojiepermana-angular-navigation-navigation-item.component-DiGOcizS.mjs} +42 -52
  80. package/fesm2022/{ojiepermana-angular-navigation-navigation-list.component-YUzHI9Pj.mjs → ojiepermana-angular-navigation-navigation-list.component-DB22Gl-5.mjs} +22 -6
  81. package/fesm2022/ojiepermana-angular-navigation-service.mjs +16 -6
  82. package/fesm2022/ojiepermana-angular-navigation-types.mjs +113 -1
  83. package/fesm2022/ojiepermana-angular-navigation.mjs +304 -93
  84. package/fesm2022/ojiepermana-angular-theme-component-settings.mjs +137 -72
  85. package/fesm2022/ojiepermana-angular-theme-layout-services.mjs +6 -6
  86. package/fesm2022/ojiepermana-angular-theme-layout-wrapper.mjs +265 -49
  87. package/fesm2022/ojiepermana-angular-theme-layout.mjs +30 -30
  88. package/fesm2022/ojiepermana-angular-theme-page-core.mjs +3 -3
  89. package/fesm2022/ojiepermana-angular-theme-page-filter.mjs +7 -7
  90. package/fesm2022/ojiepermana-angular-theme-page-overview.mjs +3 -3
  91. package/fesm2022/ojiepermana-angular-theme-page-root.mjs +8 -6
  92. package/fesm2022/ojiepermana-angular-theme-page-side.mjs +7 -7
  93. package/fesm2022/ojiepermana-angular-theme-page-slots.mjs +12 -12
  94. package/fesm2022/ojiepermana-angular-theme-shell-services.mjs +3 -3
  95. package/fesm2022/ojiepermana-angular-theme-shell.mjs +16 -12
  96. package/fesm2022/ojiepermana-angular-theme-styles.mjs +17 -33
  97. package/navigation/README.md +70 -19
  98. package/package.json +3 -2
  99. package/theme/README.md +4 -10
  100. package/theme/page/README.md +2 -0
  101. package/theme/shell/README.md +5 -1
  102. package/theme/styles/README.md +32 -8
  103. package/theme/styles/css/base/components.css +13 -9
  104. package/theme/styles/css/base/tailwind.css +43 -0
  105. package/theme/styles/css/base/theme.css +4 -25
  106. package/theme/styles/css/base/tokens.css +21 -0
  107. package/theme/styles/css/fonts.css +85 -0
  108. package/types/ojiepermana-angular-chart-radar.d.ts +2 -1
  109. package/types/ojiepermana-angular-component-avatar.d.ts +2 -1
  110. package/types/ojiepermana-angular-component-calendar.d.ts +2 -1
  111. package/types/ojiepermana-angular-component-card.d.ts +7 -2
  112. package/types/ojiepermana-angular-component-command.d.ts +1 -1
  113. package/types/ojiepermana-angular-component-editor.d.ts +2 -1
  114. package/types/ojiepermana-angular-component-icon.d.ts +64 -79
  115. package/types/ojiepermana-angular-component-input-otp.d.ts +2 -1
  116. package/types/ojiepermana-angular-component-pillbox.d.ts +2 -1
  117. package/types/ojiepermana-angular-component-radio.d.ts +2 -1
  118. package/types/ojiepermana-angular-component-resizable.d.ts +2 -1
  119. package/types/ojiepermana-angular-component-segmented-control.d.ts +1 -1
  120. package/types/ojiepermana-angular-component-select.d.ts +2 -1
  121. package/types/ojiepermana-angular-navigation-service.d.ts +8 -0
  122. package/types/ojiepermana-angular-navigation-types.d.ts +48 -3
  123. package/types/ojiepermana-angular-navigation.d.ts +59 -8
  124. package/types/ojiepermana-angular-theme-component-settings.d.ts +5 -3
  125. package/types/ojiepermana-angular-theme-layout-services.d.ts +2 -1
  126. package/types/ojiepermana-angular-theme-layout-wrapper.d.ts +52 -4
  127. package/types/ojiepermana-angular-theme-page-root.d.ts +1 -1
  128. package/types/ojiepermana-angular-theme-shell-services.d.ts +2 -1
  129. package/types/ojiepermana-angular-theme-styles.d.ts +0 -12
@@ -3,6 +3,8 @@ import { Component, booleanAttribute, computed, inject, input } from "@angular/c
3
3
  import { cn } from "@ojiepermana/angular/component/utils/core";
4
4
  import { SHELL_WINDOW_BRIDGE, ShellService, ShellService as ShellService$1, WEB_SHELL_WINDOW_BRIDGE, createTauriShellWindowBridge, isTauriRuntime, provideShellWindowBridge, provideTauriShellWindowBridge } from "@ojiepermana/angular/theme/shell/services";
5
5
  import { SHELL_COLORS, SHELL_COLOR_STORAGE_KEY, SHELL_DEFAULT_COLOR, SHELL_DEFAULT_COLOR as SHELL_DEFAULT_COLOR$1, SHELL_DEFAULT_DEVICE, SHELL_DEFAULT_DEVICE as SHELL_DEFAULT_DEVICE$1, SHELL_DEFAULT_FRAME, SHELL_DEFAULT_FRAME as SHELL_DEFAULT_FRAME$1, SHELL_DEFAULT_MODE, SHELL_DEFAULT_PLATFORM, SHELL_DEFAULT_WINDOW_STATE, SHELL_DEVICES, SHELL_DEVICE_STORAGE_KEY, SHELL_FRAMES, SHELL_FRAME_STORAGE_KEY, SHELL_MODES, SHELL_MODE_DEVICES, SHELL_MODE_STORAGE_KEY, SHELL_PLATFORMS, SHELL_WINDOW_STATES, defaultShellDeviceForMode, isShellColor, isShellDevice, isShellDeviceForMode, isShellFrame, isShellMode, isShellPlatform, isShellWindowState, normalizeShellColor, normalizeShellDevice, normalizeShellFrame, normalizeShellMode, resolveShellDeviceForMode, resolveShellDeviceForMode as resolveShellDeviceForMode$1, resolveShellFrameForMode, resolveShellFrameForMode as resolveShellFrameForMode$1, shellDevicesForMode } from "@ojiepermana/angular/theme/shell/types";
6
+ import { LucideGrip } from "@lucide/angular";
7
+ import { provideIcons } from "@ojiepermana/angular/component/icon";
6
8
  import { NavigationContainerComponent, NavigationFlyoutComponent, NavigationFooterComponent, NavigationHeaderComponent } from "@ojiepermana/angular/navigation";
7
9
  import { NAVIGATION_ADAPTER } from "@ojiepermana/angular/navigation/core";
8
10
  import { LayoutService } from "@ojiepermana/angular/theme/layout/services";
@@ -13,7 +15,7 @@ var ShellNavigationFlyoutComponent = class ShellNavigationFlyoutComponent {
13
15
  layout = inject(LayoutService, { optional: true });
14
16
  identity = inject(LayoutIdentityService, { optional: true });
15
17
  enabled = input(true, ...ngDevMode ? [{ debugName: "enabled" }] : /* istanbul ignore next */ []);
16
- icon = input("apps", ...ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []);
18
+ icon = input("grip", ...ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []);
17
19
  label = input("Open navigation", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
18
20
  navigationId = `__shell-navigation-${shellNavigationFlyoutInstanceId += 1}`;
19
21
  navigationSource = this.navigation.data(LAYOUT_DESKTOP_NAVIGATION_DATA_ID);
@@ -24,7 +26,7 @@ var ShellNavigationFlyoutComponent = class ShellNavigationFlyoutComponent {
24
26
  user = computed(() => this.identity?.user() ?? null, ...ngDevMode ? [{ debugName: "user" }] : /* istanbul ignore next */ []);
25
27
  static ɵfac = i0.ɵɵngDeclareFactory({
26
28
  minVersion: "12.0.0",
27
- version: "22.2.0",
29
+ version: "22.2.3",
28
30
  ngImport: i0,
29
31
  type: ShellNavigationFlyoutComponent,
30
32
  deps: [],
@@ -32,7 +34,7 @@ var ShellNavigationFlyoutComponent = class ShellNavigationFlyoutComponent {
32
34
  });
33
35
  static ɵcmp = i0.ɵɵngDeclareComponent({
34
36
  minVersion: "17.0.0",
35
- version: "22.2.0",
37
+ version: "22.2.3",
36
38
  type: ShellNavigationFlyoutComponent,
37
39
  isStandalone: true,
38
40
  selector: "ShellNavigationFlyout",
@@ -64,6 +66,7 @@ var ShellNavigationFlyoutComponent = class ShellNavigationFlyoutComponent {
64
66
  styleAttribute: "--nav-flyout-floating-width: 100vw; --nav-flyout-floating-max-width: 100vw; --nav-flyout-floating-radius: 0 0 var(--shell-frame-radius) var(--shell-frame-radius);",
65
67
  classAttribute: "contents"
66
68
  },
69
+ providers: [provideIcons(LucideGrip)],
67
70
  ngImport: i0,
68
71
  template: `
69
72
  @if (showsFlyout()) {
@@ -174,13 +177,14 @@ var ShellNavigationFlyoutComponent = class ShellNavigationFlyoutComponent {
174
177
  };
175
178
  i0.ɵɵngDeclareClassMetadata({
176
179
  minVersion: "12.0.0",
177
- version: "22.2.0",
180
+ version: "22.2.3",
178
181
  ngImport: i0,
179
182
  type: ShellNavigationFlyoutComponent,
180
183
  decorators: [{
181
184
  type: Component,
182
185
  args: [{
183
186
  selector: "ShellNavigationFlyout",
187
+ providers: [provideIcons(LucideGrip)],
184
188
  imports: [
185
189
  NavigationContainerComponent,
186
190
  NavigationFlyoutComponent,
@@ -279,7 +283,7 @@ var ShellBarComponent = class ShellBarComponent {
279
283
  restoreLabel = input("Restore window", ...ngDevMode ? [{ debugName: "restoreLabel" }] : /* istanbul ignore next */ []);
280
284
  closeLabel = input("Close window", ...ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []);
281
285
  navigationFlyout = input(true, ...ngDevMode ? [{ debugName: "navigationFlyout" }] : /* istanbul ignore next */ []);
282
- navigationFlyoutIcon = input("apps", ...ngDevMode ? [{ debugName: "navigationFlyoutIcon" }] : /* istanbul ignore next */ []);
286
+ navigationFlyoutIcon = input("grip", ...ngDevMode ? [{ debugName: "navigationFlyoutIcon" }] : /* istanbul ignore next */ []);
283
287
  navigationFlyoutLabel = input("Open navigation", ...ngDevMode ? [{ debugName: "navigationFlyoutLabel" }] : /* istanbul ignore next */ []);
284
288
  class = input("", ...ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []);
285
289
  maximizeToggleLabel = computed(() => this.shell.isMaximized() ? this.restoreLabel() : this.maximizeLabel(), ...ngDevMode ? [{ debugName: "maximizeToggleLabel" }] : /* istanbul ignore next */ []);
@@ -310,7 +314,7 @@ var ShellBarComponent = class ShellBarComponent {
310
314
  }
311
315
  static ɵfac = i0.ɵɵngDeclareFactory({
312
316
  minVersion: "12.0.0",
313
- version: "22.2.0",
317
+ version: "22.2.3",
314
318
  ngImport: i0,
315
319
  type: ShellBarComponent,
316
320
  deps: [],
@@ -318,7 +322,7 @@ var ShellBarComponent = class ShellBarComponent {
318
322
  });
319
323
  static ɵcmp = i0.ɵɵngDeclareComponent({
320
324
  minVersion: "17.0.0",
321
- version: "22.2.0",
325
+ version: "22.2.3",
322
326
  type: ShellBarComponent,
323
327
  isStandalone: true,
324
328
  selector: "ShellBar",
@@ -615,7 +619,7 @@ var ShellBarComponent = class ShellBarComponent {
615
619
  };
616
620
  i0.ɵɵngDeclareClassMetadata({
617
621
  minVersion: "12.0.0",
618
- version: "22.2.0",
622
+ version: "22.2.3",
619
623
  ngImport: i0,
620
624
  type: ShellBarComponent,
621
625
  decorators: [{
@@ -943,7 +947,7 @@ var ShellComponent = class ShellComponent {
943
947
  ...ngDevMode ? { debugName: "navigationFlyout" } : /* istanbul ignore next */ {},
944
948
  transform: booleanAttribute
945
949
  });
946
- navigationFlyoutIcon = input("apps", ...ngDevMode ? [{ debugName: "navigationFlyoutIcon" }] : /* istanbul ignore next */ []);
950
+ navigationFlyoutIcon = input("grip", ...ngDevMode ? [{ debugName: "navigationFlyoutIcon" }] : /* istanbul ignore next */ []);
947
951
  navigationFlyoutLabel = input("Open navigation", ...ngDevMode ? [{ debugName: "navigationFlyoutLabel" }] : /* istanbul ignore next */ []);
948
952
  class = input("", ...ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []);
949
953
  resolvedMode = computed(() => this.mode() ?? this.shell.mode(), ...ngDevMode ? [{ debugName: "resolvedMode" }] : /* istanbul ignore next */ []);
@@ -954,7 +958,7 @@ var ShellComponent = class ShellComponent {
954
958
  hostClasses = computed(() => cn("relative isolate flex h-dvh w-full min-w-0 flex-col overflow-hidden text-foreground", this.showsBar() && this.drag() && "shell-drag-region", this.resolvedColor() === "sync" || this.resolvedFrame() === "modern" ? "bg-[hsl(var(--shell-bar-background))]" : "bg-layout-canvas", this.class()), ...ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []);
955
959
  static ɵfac = i0.ɵɵngDeclareFactory({
956
960
  minVersion: "12.0.0",
957
- version: "22.2.0",
961
+ version: "22.2.3",
958
962
  ngImport: i0,
959
963
  type: ShellComponent,
960
964
  deps: [],
@@ -962,7 +966,7 @@ var ShellComponent = class ShellComponent {
962
966
  });
963
967
  static ɵcmp = i0.ɵɵngDeclareComponent({
964
968
  minVersion: "17.0.0",
965
- version: "22.2.0",
969
+ version: "22.2.3",
966
970
  type: ShellComponent,
967
971
  isStandalone: true,
968
972
  selector: "Shell",
@@ -1155,7 +1159,7 @@ var ShellComponent = class ShellComponent {
1155
1159
  };
1156
1160
  i0.ɵɵngDeclareClassMetadata({
1157
1161
  minVersion: "12.0.0",
1158
- version: "22.2.0",
1162
+ version: "22.2.3",
1159
1163
  ngImport: i0,
1160
1164
  type: ShellComponent,
1161
1165
  decorators: [{
@@ -1,6 +1,6 @@
1
- import { DOCUMENT, isPlatformBrowser } from "@angular/common";
1
+ import { DOCUMENT } from "@angular/common";
2
2
  import * as i0 from "@angular/core";
3
- import { DestroyRef, InjectionToken, PLATFORM_ID, Service, computed, effect, inject, makeEnvironmentProviders, provideEnvironmentInitializer, signal } from "@angular/core";
3
+ import { DestroyRef, InjectionToken, Service, computed, effect, inject, makeEnvironmentProviders, provideEnvironmentInitializer, signal } from "@angular/core";
4
4
  import { documentLocalStorage } from "@ojiepermana/angular/component/utils/core";
5
5
  function persistedSignal(options) {
6
6
  const documentRef = options.documentRef !== void 0 ? options.documentRef : inject(DOCUMENT, { optional: true });
@@ -374,7 +374,7 @@ var ThemeBrandService = class ThemeBrandService {
374
374
  }
375
375
  static ɵfac = i0.ɵɵngDeclareFactory({
376
376
  minVersion: "12.0.0",
377
- version: "22.2.0",
377
+ version: "22.2.3",
378
378
  ngImport: i0,
379
379
  type: ThemeBrandService,
380
380
  deps: [],
@@ -382,14 +382,14 @@ var ThemeBrandService = class ThemeBrandService {
382
382
  });
383
383
  static ɵprov = i0.ɵɵngDeclareService({
384
384
  minVersion: "22.0.0",
385
- version: "22.2.0",
385
+ version: "22.2.3",
386
386
  ngImport: i0,
387
387
  type: ThemeBrandService
388
388
  });
389
389
  };
390
390
  i0.ɵɵngDeclareClassMetadata({
391
391
  minVersion: "12.0.0",
392
- version: "22.2.0",
392
+ version: "22.2.3",
393
393
  ngImport: i0,
394
394
  type: ThemeBrandService,
395
395
  decorators: [{ type: Service }],
@@ -419,7 +419,7 @@ var ThemeColorService = class ThemeColorService {
419
419
  }
420
420
  static ɵfac = i0.ɵɵngDeclareFactory({
421
421
  minVersion: "12.0.0",
422
- version: "22.2.0",
422
+ version: "22.2.3",
423
423
  ngImport: i0,
424
424
  type: ThemeColorService,
425
425
  deps: [],
@@ -427,14 +427,14 @@ var ThemeColorService = class ThemeColorService {
427
427
  });
428
428
  static ɵprov = i0.ɵɵngDeclareService({
429
429
  minVersion: "22.0.0",
430
- version: "22.2.0",
430
+ version: "22.2.3",
431
431
  ngImport: i0,
432
432
  type: ThemeColorService
433
433
  });
434
434
  };
435
435
  i0.ɵɵngDeclareClassMetadata({
436
436
  minVersion: "12.0.0",
437
- version: "22.2.0",
437
+ version: "22.2.3",
438
438
  ngImport: i0,
439
439
  type: ThemeColorService,
440
440
  decorators: [{ type: Service }]
@@ -460,7 +460,7 @@ var ThemeModeService = class ThemeModeService {
460
460
  }
461
461
  static ɵfac = i0.ɵɵngDeclareFactory({
462
462
  minVersion: "12.0.0",
463
- version: "22.2.0",
463
+ version: "22.2.3",
464
464
  ngImport: i0,
465
465
  type: ThemeModeService,
466
466
  deps: [],
@@ -468,14 +468,14 @@ var ThemeModeService = class ThemeModeService {
468
468
  });
469
469
  static ɵprov = i0.ɵɵngDeclareService({
470
470
  minVersion: "22.0.0",
471
- version: "22.2.0",
471
+ version: "22.2.3",
472
472
  ngImport: i0,
473
473
  type: ThemeModeService
474
474
  });
475
475
  };
476
476
  i0.ɵɵngDeclareClassMetadata({
477
477
  minVersion: "12.0.0",
478
- version: "22.2.0",
478
+ version: "22.2.3",
479
479
  ngImport: i0,
480
480
  type: ThemeModeService,
481
481
  decorators: [{ type: Service }]
@@ -503,7 +503,7 @@ var ThemeRadiusService = class ThemeRadiusService {
503
503
  }
504
504
  static ɵfac = i0.ɵɵngDeclareFactory({
505
505
  minVersion: "12.0.0",
506
- version: "22.2.0",
506
+ version: "22.2.3",
507
507
  ngImport: i0,
508
508
  type: ThemeRadiusService,
509
509
  deps: [],
@@ -511,14 +511,14 @@ var ThemeRadiusService = class ThemeRadiusService {
511
511
  });
512
512
  static ɵprov = i0.ɵɵngDeclareService({
513
513
  minVersion: "22.0.0",
514
- version: "22.2.0",
514
+ version: "22.2.3",
515
515
  ngImport: i0,
516
516
  type: ThemeRadiusService
517
517
  });
518
518
  };
519
519
  i0.ɵɵngDeclareClassMetadata({
520
520
  minVersion: "12.0.0",
521
- version: "22.2.0",
521
+ version: "22.2.3",
522
522
  ngImport: i0,
523
523
  type: ThemeRadiusService,
524
524
  decorators: [{ type: Service }]
@@ -537,7 +537,7 @@ var ThemeSpaceService = class ThemeSpaceService {
537
537
  }
538
538
  static ɵfac = i0.ɵɵngDeclareFactory({
539
539
  minVersion: "12.0.0",
540
- version: "22.2.0",
540
+ version: "22.2.3",
541
541
  ngImport: i0,
542
542
  type: ThemeSpaceService,
543
543
  deps: [],
@@ -545,27 +545,23 @@ var ThemeSpaceService = class ThemeSpaceService {
545
545
  });
546
546
  static ɵprov = i0.ɵɵngDeclareService({
547
547
  minVersion: "22.0.0",
548
- version: "22.2.0",
548
+ version: "22.2.3",
549
549
  ngImport: i0,
550
550
  type: ThemeSpaceService
551
551
  });
552
552
  };
553
553
  i0.ɵɵngDeclareClassMetadata({
554
554
  minVersion: "12.0.0",
555
- version: "22.2.0",
555
+ version: "22.2.3",
556
556
  ngImport: i0,
557
557
  type: ThemeSpaceService,
558
558
  decorators: [{ type: Service }]
559
559
  });
560
- const MATERIAL_SYMBOLS_FONT_ATTR = "data-icon-font";
561
- const MATERIAL_SYMBOLS_FONT_ID = "material-symbols";
562
- const MATERIAL_SYMBOLS_FONT_HREF = "https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&family=Material+Symbols+Sharp:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=block";
563
560
  function provideUiTheme(options = {}) {
564
561
  return makeEnvironmentProviders([{
565
562
  provide: THEME_OPTIONS,
566
563
  useValue: options
567
564
  }, provideEnvironmentInitializer(() => {
568
- if (options.icons?.materialSymbols === true) loadMaterialSymbolsStylesheet();
569
565
  inject(ThemeModeService);
570
566
  inject(ThemeColorService);
571
567
  inject(ThemeBrandService);
@@ -573,16 +569,4 @@ function provideUiTheme(options = {}) {
573
569
  inject(ThemeSpaceService);
574
570
  })]);
575
571
  }
576
- function loadMaterialSymbolsStylesheet() {
577
- const documentRef = inject(DOCUMENT, { optional: true });
578
- const platformId = inject(PLATFORM_ID);
579
- const head = documentRef?.head;
580
- if (!isPlatformBrowser(platformId) || !head) return;
581
- if (head.querySelector(`link[${MATERIAL_SYMBOLS_FONT_ATTR}="${MATERIAL_SYMBOLS_FONT_ID}"]`)) return;
582
- const link = head.ownerDocument.createElement("link");
583
- link.rel = "stylesheet";
584
- link.href = MATERIAL_SYMBOLS_FONT_HREF;
585
- link.setAttribute(MATERIAL_SYMBOLS_FONT_ATTR, MATERIAL_SYMBOLS_FONT_ID);
586
- head.appendChild(link);
587
- }
588
572
  export { DEFAULT_THEME_COLOR, DEFAULT_THEME_MODE, DEFAULT_THEME_NEUTRAL, DEFAULT_THEME_RADIUS, DEFAULT_THEME_SPACE, RESOLVED_THEME_MODES, THEME_BRAND_STORAGE_KEY, THEME_COLORS, THEME_COLOR_STORAGE_KEY, THEME_MODES, THEME_MODE_STORAGE_KEY, THEME_NEUTRALS, THEME_NEUTRAL_STORAGE_KEY, THEME_OPTIONS, THEME_RADII, THEME_RADIUS_STORAGE_KEY, THEME_SPACES, THEME_SPACE_STORAGE_KEY, ThemeBrandService, ThemeColorService, ThemeModeService, ThemeRadiusService, ThemeSpaceService, htmlAttributeEffect, htmlStylePropertyEffect, isResolvedThemeMode, isThemeColor, isThemeMode, isThemeNeutral, isThemeRadius, isThemeSpace, normalizeThemeColor, normalizeThemeMode, normalizeThemeNeutral, normalizeThemeRadius, normalizeThemeSpace, persistedHtmlAttributeSignal, persistedSignal, prefersDarkSignal, provideUiTheme };
@@ -5,7 +5,7 @@
5
5
  ```ts
6
6
  import {
7
7
  NavigationContainerComponent,
8
- NavigationSidebarComponent, // type: NavigationDockbar/Navbar/FlyoutComponent
8
+ NavigationSidebarComponent, // type: NavigationDockbar/Minidock/Navbar/FlyoutComponent
9
9
  NavigationHeaderComponent,
10
10
  NavigationContentComponent,
11
11
  NavigationFooterComponent,
@@ -44,17 +44,17 @@ const items: NavigationItem[] = [
44
44
  </Navigation>
45
45
  ```
46
46
 
47
- Type dipilih lewat komponen anak deklaratif — `NavigationSidebar`, `NavigationDockbar`, `NavigationNavbar`, atau `NavigationFlyout` — satu type hidup per `<Navigation>`. Di dalam type, `NavigationHeader` dan `NavigationFooter` opsional, sedangkan `NavigationContent` selalu dirender (otomatis dibuat bila tidak diproyeksikan).
47
+ Type dipilih lewat komponen anak deklaratif (`NavigationSidebar`, `NavigationDockbar`, `NavigationMinidock`, `NavigationNavbar`, atau `NavigationFlyout`), satu type hidup per `<Navigation>`. Di dalam type, `NavigationHeader` dan `NavigationFooter` opsional, sedangkan `NavigationContent` selalu dirender (otomatis dibuat bila tidak diproyeksikan).
48
48
 
49
49
  ## API Notes
50
50
 
51
51
  - `data` is the source of navigation data.
52
- - Type is declared by the child component: `NavigationSidebar`/`NavigationDockbar` (vertical), `NavigationNavbar`/`NavigationFlyout` (horizontal). Orientation is implied by the type child.
52
+ - Type is declared by the child component: `NavigationSidebar`/`NavigationDockbar`/`NavigationMinidock` (vertical), `NavigationNavbar`/`NavigationFlyout` (horizontal). Orientation is implied by the type child.
53
53
  - `id` identifies a navigation instance so multiple navs can keep distinct service state.
54
54
  - `data-id` optionally publishes the input data under a different registry id. This lets a
55
55
  mobile mirror use isolated state (`id="main-mobile"`) while exposing the same data contract
56
56
  as the desktop navigation (`data-id="main"`).
57
- - `position` on `NavigationSidebar`/`NavigationDockbar` accepts `left` or `right` (vertical).
57
+ - `position` on `NavigationSidebar`/`NavigationDockbar`/`NavigationMinidock` accepts `left` or `right` (vertical).
58
58
  - `collapsed` on `NavigationSidebar` controls the icon-only sidebar state.
59
59
  - `mode` on `NavigationDockbar` accepts `sticky` or `drawer`.
60
60
  - `dockbar-route-context` on `NavigationDockbar` opts into Router-aware header, rail deduplication,
@@ -64,7 +64,7 @@ Type dipilih lewat komponen anak deklaratif — `NavigationSidebar`, `Navigation
64
64
  `NavigationItem.badge.source` or route `data.navigationBadge`.
65
65
  - `ariaLabel` overrides the host navigation label and defaults to `Primary navigation`.
66
66
  - `label` on `NavigationFlyout` sets the single trigger label and defaults to `Menu`.
67
- - `icon` on `NavigationFlyout` renders a Material Symbols icon on the trigger; `icon-position` (`start`/`end`) sets its placement and `icon-only` hides the label visually while keeping it as the accessible name (compact mode is always icon-only and falls back to the `menu` icon).
67
+ - `icon` on `NavigationFlyout` renders a Lucide icon on the trigger (the name must be registered with `provideIcons()`); `icon-position` (`start`/`end`) sets its placement and `icon-only` hides the label visually while keeping it as the accessible name (compact mode is always icon-only and falls back to the `menu` icon).
68
68
  - `nav-position` on `NavigationNavbar`/`NavigationFlyout` accepts `top` (default) or `bottom`. With `bottom`, the navbar grid panel opens upward with squared bottom corners, and the flyout panel anchors to the container's bottom edge with the tab row docked at the bottom — seamless for bars placed below the content.
69
69
  - `nav-appearance` on `NavigationNavbar`/`NavigationFlyout` accepts `flat` or `border-rail` (same vocabulary as the layout's `layout-appearance`). `border-rail` squares the panel (no rounding), frames entry icons with dimmed blueprint-style rail lines plus dashed center cross lines (instead of rounded boxes), renders the nested-collapse rail dashed, and replaces hover/active backgrounds with primary-colored text. `flat` keeps the current visuals.
70
70
  - The `navbar` type renders root items inline immediately; clicking a group (hover does not open it) opens a full-width grid panel below the bar with the same flyout-style entries, responsive columns, and nested collapse. Root group triggers intentionally render without a chevron; open state remains available through the trigger styling and `aria-expanded`.
@@ -109,19 +109,20 @@ Inputs pada `<Navigation>` (container):
109
109
 
110
110
  Inputs pada komponen type:
111
111
 
112
- | Component | API | Type | Notes |
113
- | ------------------- | ----------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------- |
114
- | `NavigationSidebar` | `position` | `left \| right \| null` | Side the rail docks to. |
115
- | `NavigationSidebar` | `collapsed` | `boolean \| null` | Controls collapsed vertical sidebar state. |
116
- | `NavigationSidebar` | `nav-sidebar-collapse` | `boolean` | Enables hover-driven preview expansion on collapsed sidebars. |
117
- | `NavigationSidebar` | `previewExpanded` | `boolean` | Forces a collapsed sidebar to render expanded for preview. |
118
- | `NavigationDockbar` | `mode` | `sticky \| drawer \| null` | Docked aside beside the rail, or overlay drawer. |
119
- | `NavigationDockbar` | `position` | `left \| right \| null` | Side the rail docks to. |
120
- | `NavigationDockbar` | `dockbar-route-context` | `boolean \| NavigationDockbarRouteConfig \| null` | Opt-in Router context and optional overrides. |
121
- | `NavigationDockbar` | `dockbar-badge` | `NavigationBadgeContext` | Reactive badge sources keyed by item or route metadata. |
122
- | `NavigationNavbar` | `nav-appearance` | `flat \| border-rail` | Style variant. `border-rail` = squared panel, dashed icon rails, no hover bg. |
123
- | `NavigationFlyout` | `label` | `string` | Trigger label. Defaults to `Menu`. |
124
- | `NavigationFlyout` | `nav-appearance` | `flat \| border-rail` | Style variant. `border-rail` = squared panel, dashed icon rails, no hover bg. |
112
+ | Component | API | Type | Notes |
113
+ | -------------------- | ----------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------- |
114
+ | `NavigationSidebar` | `position` | `left \| right \| null` | Side the rail docks to. |
115
+ | `NavigationSidebar` | `collapsed` | `boolean \| null` | Controls collapsed vertical sidebar state. |
116
+ | `NavigationSidebar` | `nav-sidebar-collapse` | `boolean` | Enables hover-driven preview expansion on collapsed sidebars. |
117
+ | `NavigationSidebar` | `previewExpanded` | `boolean` | Forces a collapsed sidebar to render expanded for preview. |
118
+ | `NavigationDockbar` | `mode` | `sticky \| drawer \| null` | Docked aside beside the rail, or overlay drawer. |
119
+ | `NavigationDockbar` | `position` | `left \| right \| null` | Side the rail docks to. |
120
+ | `NavigationDockbar` | `dockbar-route-context` | `boolean \| NavigationDockbarRouteConfig \| null` | Opt-in Router context and optional overrides. |
121
+ | `NavigationDockbar` | `dockbar-badge` | `NavigationBadgeContext` | Reactive badge sources keyed by item or route metadata. |
122
+ | `NavigationMinidock` | `position` | `left \| right \| null` | Side the rail docks to. The separating border is set through `class`. |
123
+ | `NavigationNavbar` | `nav-appearance` | `flat \| border-rail` | Style variant. `border-rail` = squared panel, dashed icon rails, no hover bg. |
124
+ | `NavigationFlyout` | `label` | `string` | Trigger label. Defaults to `Menu`. |
125
+ | `NavigationFlyout` | `nav-appearance` | `flat \| border-rail` | Style variant. `border-rail` = squared panel, dashed icon rails, no hover bg. |
125
126
 
126
127
  Semua type juga menerima `class` untuk kelas tambahan pada elemen shell-nya.
127
128
 
@@ -149,6 +150,56 @@ Semua type juga menerima `class` untuk kelas tambahan pada elemen shell-nya.
149
150
  | `columns` | `number` | Column count for `mega` style items. |
150
151
  | `children` | `readonly NavigationItem[]` | Nested items. Trees can be deeper than one level. |
151
152
 
153
+ ## Minidock
154
+
155
+ `NavigationMinidock` is a permanent vertical icon rail. It renders exactly like a collapsed
156
+ sidebar (`--layout-sidebar-collapsed-width`, `--nav-rail-item-size`, a tooltip per item, a two
157
+ letter fallback for items without an icon), but it never expands: there is no `collapsed` input,
158
+ no `nav-sidebar-collapse`, no hover or focus preview, no header toggle, and
159
+ `NavigationService.toggleCollapsed()` does nothing for it. Its stored `nav-type-mode` is always
160
+ `default`.
161
+
162
+ ```html
163
+ <Navigation id="app-rail" [data]="items" class="h-full">
164
+ <NavigationMinidock class="border-r border-border" />
165
+ </Navigation>
166
+ ```
167
+
168
+ The data contract is strict. Minidock only accepts `basic`, `item`, or untyped items without
169
+ children, plus `divider` and `spacer`. Any `group`, `collapsible`, `collapsable`, `mega`, or
170
+ `aside` item, or any item with non empty `children` (hidden items included), throws an `Error`
171
+ in development **and production**. The error reaches Angular's `ErrorHandler` and names the item
172
+ index, its title, and the rejected type, for example
173
+ `Item [2] "Component" bertipe "group".`
174
+
175
+ Flatten grouped data with `toMinidockItems()` from `@ojiepermana/angular/navigation/types`.
176
+ It is a pure function whose output always passes that check, and it is the safe path for data
177
+ that comes from a backend:
178
+
179
+ ```ts
180
+ import { toMinidockItems } from '@ojiepermana/angular/navigation/types';
181
+
182
+ protected readonly railItems = computed(() => toMinidockItems(this.items()));
183
+ ```
184
+
185
+ - Leaves are kept as the same object, unless a parent's `isHidden` has to be merged in.
186
+ - `group` and `mega` (at any level) become a divider boundary and their content is flattened;
187
+ an empty group adds no divider.
188
+ - `collapsible`, `collapsable`, and `aside` are dropped as parents; their children are lifted.
189
+ - Leading, trailing, and repeated dividers are compacted; `spacer` survives only at the top level.
190
+ - A leaf whose `id` repeats is kept once (first occurrence wins).
191
+ - A lifted leaf is hidden when any of its parents is hidden, and a group's boundary divider hides
192
+ with that group.
193
+
194
+ A `spacer` pushes every item after it to the bottom of the rail. `LayoutWrapperDefault` offers
195
+ the type as `nav-type="minidock"` on a vertical layout: it renders `LayoutNavMinidock` with
196
+ `toMinidockItems(data())` under the data id `main-minidock`, and keeps publishing the full
197
+ `data()` under `main`.
198
+
199
+ Adding `'minidock'` widens `NavigationVerticalType` (and so `NavigationType`). The change is
200
+ additive, but a consumer `switch` that is exhaustive over `NavigationType` needs a `minidock`
201
+ branch before it compiles again.
202
+
152
203
  ## Route-aware dockbar
153
204
 
154
205
  The feature is opt-in so existing dockbar, sidebar, navbar, and flyout consumers keep their
@@ -326,7 +377,7 @@ Any other navigation id, such as `erp-navbar`, only keeps its state in memory fo
326
377
 
327
378
  ## Icons
328
379
 
329
- Saat `item.icon` tersedia, `nav` akan merender Material Symbols secara default melalui `@ojiepermana/angular/component/icon`. Jalankan `provideUiTheme()` untuk preload global, atau biarkan `IconComponent` melakukan lazy-load saat icon pertama dipakai.
380
+ Saat `item.icon` tersedia, `nav` merender ikon Lucide secara default melalui `@ojiepermana/angular/component/icon`. `item.icon` adalah nama kebab Lucide (misalnya `layout-dashboard`) dan harus didaftarkan lewat `provideIcons()` di aplikasi; ikon tetap milik komponen navigasi (toggle header, chevron, tombol tutup dockbar, ikon rute fallback `route`) didaftarkan oleh komponennya sendiri. Nama yang tidak terdaftar tidak merender ikon dan menulis satu warning di dev mode.
330
381
 
331
382
  ```html
332
383
  <Navigation [data]="items">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ojiepermana/angular",
3
- "version": "22.2.0",
3
+ "version": "22.2.2",
4
4
  "description": "Accessible, tree-shakable Angular 22 design system from ojiepermana: UI components, charts, navigation shells, theme tokens, and an OpenAPI SDK generator.",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -43,6 +43,7 @@
43
43
  "@angular/material": ">=22.2.0 <23.0.0",
44
44
  "@angular/platform-browser": ">=22.2.0 <23.0.0",
45
45
  "@angular/router": ">=22.2.0 <23.0.0",
46
+ "@lucide/angular": ">=1.61.0 <2.0.0",
46
47
  "rxjs": ">=7.8.0 <8.0.0"
47
48
  },
48
49
  "peerDependenciesMeta": {
@@ -502,5 +503,5 @@
502
503
  "module": "fesm2022/ojiepermana-angular.mjs",
503
504
  "typings": "types/ojiepermana-angular.d.ts",
504
505
  "type": "module",
505
- "gitHead": "3b69b91d27302f5e63547b54b0a63e29386445db"
506
+ "gitHead": "915ddb2641dfdf3c3f256276f3c2eafd5ab31e64"
506
507
  }
package/theme/README.md CHANGED
@@ -107,17 +107,11 @@ every accent and neutral palette, so switching needs no runtime CSS loading. The
107
107
  lightweight `theme.css` ships base only — import the axis files you need on top of
108
108
  it (or use `theme-full.css`) to enable runtime switching.
109
109
 
110
- ### Material Symbols icons (opt-in)
110
+ ### Icons
111
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.
112
+ `provideUiTheme()` makes **no external network request** and loads no icon font. Icons are
113
+ Lucide SVGs registered with `provideIcons()` from `{{packageName}}/component/icon`; the theme
114
+ only supplies the `--icon-size` and `--icon-stroke-width` tokens that `<Icon>` reads.
121
115
 
122
116
  ## Support and security
123
117
 
@@ -76,6 +76,8 @@ Saat `Page` dirender di dalam layout `empty`, sebuah tombol icon-only tanpa bord
76
76
 
77
77
  Tombol hanya muncul ketika layout aktif `empty` dan nav target punya data. Di layout lain (`vertical`/`horizontal`/`fluid`) tombol tidak dirender karena navigasi utama sudah terlihat.
78
78
 
79
+ Saat `LayoutWrapperDefault` memakai `nav-type="desktop"` dan layout `empty`, data navigasi diterbitkan ke `main` untuk launcher `Page`, bukan ke titlebar `Shell`. Hanya launcher di kanan `PageHeader` (atau di atas konten bila tanpa header) yang tampil. Item mini dock dan navigasinya tetap tersedia.
80
+
79
81
  | Input | Type | Default | Keterangan |
80
82
  | -------------- | --------- | ------------------- | ------------------------------------------------------------ |
81
83
  | `appsLauncher` | `boolean` | `true` | Aktif/nonaktifkan apps-launcher pada layout `empty`. |
@@ -245,7 +245,11 @@ window-width popover:
245
245
  - Windows and Linux — before consumer `[shellBarStart]` content, at the far left
246
246
  opposite the window controls.
247
247
 
248
- The trigger is rendered only when desktop navigation data exists. It keeps a real
248
+ The trigger is rendered only when desktop navigation data exists. On an `empty`
249
+ layout, `LayoutWrapperDefault` publishes that data under `main` for the `Page`
250
+ launcher instead, so the titlebar does not add a duplicate button. Other layouts
251
+ keep their titlebar navigation, and minidock items remain independent.
252
+ The trigger keeps a real
249
253
  button, `aria-haspopup="menu"`, an explicit accessible name, visible keyboard
250
254
  focus, and the established semantic shell/navigation tokens. Its surface stays
251
255
  transparent, including hover and open states, while the icon inherits the exact
@@ -33,19 +33,43 @@ export const appConfig = {
33
33
  - `brand` mem-bootstrap `ThemeBrandService`; set `--brand` / utility `bg-brand` dan preset
34
34
  accent `theme-color='brand'`. Menerima string HSL triplet atau `{ color, foreground }`.
35
35
  Bisa diubah runtime via `setBrand()`, persist di storage.
36
- - `icons.materialSymbols` mengontrol preload stylesheet Material Symbols pada bootstrap aplikasi.
37
36
  - Pilihan yang dipersist (`theme-color` / `theme-neutral` / `theme-radius` / `theme-space` /
38
37
  `theme-brand`) menang atas default.
39
38
 
40
39
  ## Default Behavior
41
40
 
42
- - Material Symbols **tidak** di-preload secara default (opt-in). Tanpa konfigurasi,
43
- `provideUiTheme()` tidak melakukan request jaringan eksternal apa pun — ramah privasi,
44
- offline, dan CSP.
45
- - Untuk mengaktifkan preload font dari Google Fonts, set `icons.materialSymbols` ke `true`,
46
- atau self-host font Material Symbols dan `@import` sendiri di stylesheet Anda.
47
- - Jika memakai `@ojiepermana/angular/component/icon` tanpa provider tema, aktifkan
48
- `provideMaterialSymbols()` dari entrypoint icon atau self-host stylesheet font sendiri.
41
+ - `provideUiTheme()` tidak melakukan request jaringan eksternal apa pun dan tidak memuat font ikon:
42
+ ikon adalah SVG Lucide dari peer `@lucide/angular`, didaftarkan lewat `provideIcons()` dari
43
+ `@ojiepermana/angular/component/icon`. Tema hanya menyediakan token `--icon-size` (default `1.5rem`)
44
+ dan `--icon-stroke-width` (default `2`) yang dibaca komponen `<Icon>`.
45
+ - Opsi `icons` di `provideUiTheme()` (`icons.materialSymbols`) sudah dihapus bersama Material Symbols;
46
+ hapus opsi itu dari konfigurasi Anda.
47
+
48
+ ## Font
49
+
50
+ Token `--theme-font-sans` (`'Inter', …`) dan `--theme-font-mono` (`'JetBrains Mono', …`) hanya
51
+ menamai font; tema tidak memuat file font apa pun dan paket tidak membawa biner font. Tanpa langkah
52
+ di bawah, teks memakai font yang kebetulan terpasang di mesin pengunjung.
53
+
54
+ Untuk memuatnya, impor lembar opsional setelah tema dan sajikan file woff2 dari origin Anda sendiri:
55
+
56
+ ```css
57
+ @import '@ojiepermana/angular/theme/theme.css';
58
+ @import '@ojiepermana/angular/theme/styles/css/fonts.css';
59
+ ```
60
+
61
+ - `fonts.css` mendeklarasikan `@font-face` untuk `/fonts/inter/InterVariable.woff2` (dan varian
62
+ italic) serta `/fonts/jetbrains-mono/JetBrainsMono-{Regular,Medium,Bold}.woff2`, semuanya
63
+ `font-display: swap`. Ambil file dari rilis resmi [Inter](https://github.com/rsms/inter) dan
64
+ [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) (keduanya SIL OFL 1.1). Path lain?
65
+ Salin `fonts.css` dan ubah `url()`-nya.
66
+ - Lembar itu juga menambahkan face `Inter Fallback` (Arial lokal dengan metrik Inter) ke
67
+ `--theme-font-sans`, sehingga pergantian ke Inter tidak menggeser layout.
68
+ - Preload hanya file Inter tegak:
69
+ `<link rel="preload" href="/fonts/inter/InterVariable.woff2" as="font" type="font/woff2" crossorigin>`.
70
+ Browser hanya mengunduh face lain (italic, mono 500/700) saat halaman benar-benar memakainya.
71
+ - Showcase memakai persis susunan ini (`apps/showcase/public/fonts/`), dan CSP `font-src 'self'`
72
+ sudah mengizinkannya.
49
73
 
50
74
  ## Token Semantik Status
51
75
 
@@ -91,6 +91,19 @@
91
91
  }
92
92
  }
93
93
 
94
+ /* Vestibular safety for every component, including the ones without their
95
+ * own motion-reduce variant: motion collapses to an instant state change. */
96
+ @media (prefers-reduced-motion: reduce) {
97
+ *,
98
+ *::before,
99
+ *::after {
100
+ animation-duration: 0.01ms !important;
101
+ animation-iteration-count: 1 !important;
102
+ transition-duration: 0.01ms !important;
103
+ scroll-behavior: auto !important;
104
+ }
105
+ }
106
+
94
107
  @media (pointer: coarse) {
95
108
  :where(
96
109
  button,
@@ -107,15 +120,6 @@
107
120
  }
108
121
 
109
122
  @layer components {
110
- /* Icon family per appearance: Material Symbols Rounded is the default
111
- * (IconComponent's own fallback); any border-rail scope — the layout axis
112
- * (data-layout-appearance) or a navigation type-style (data-type-style) —
113
- * swaps the inherited token to Sharp so every <Icon> inside follows. */
114
- [data-layout-appearance='border-rail'],
115
- [data-type-style='border-rail'] {
116
- --icon-font-family: 'Material Symbols Sharp';
117
- }
118
-
119
123
  .nav-text {
120
124
  font-family: var(--nav-font-family, var(--font-sans));
121
125
  font-size: var(--nav-text-size, var(--text-base));