@ojiepermana/angular 0.0.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 (51) hide show
  1. package/README.md +237 -0
  2. package/fesm2022/ojiepermana-angular-internal.mjs +58 -0
  3. package/fesm2022/ojiepermana-angular-internal.mjs.map +1 -0
  4. package/fesm2022/ojiepermana-angular-layout.mjs +471 -0
  5. package/fesm2022/ojiepermana-angular-layout.mjs.map +1 -0
  6. package/fesm2022/ojiepermana-angular-shell.mjs +14 -0
  7. package/fesm2022/ojiepermana-angular-shell.mjs.map +1 -0
  8. package/fesm2022/ojiepermana-angular-theme-component.mjs +249 -0
  9. package/fesm2022/ojiepermana-angular-theme-component.mjs.map +1 -0
  10. package/fesm2022/ojiepermana-angular-theme-directive.mjs +29 -0
  11. package/fesm2022/ojiepermana-angular-theme-directive.mjs.map +1 -0
  12. package/fesm2022/ojiepermana-angular-theme-service.mjs +243 -0
  13. package/fesm2022/ojiepermana-angular-theme-service.mjs.map +1 -0
  14. package/fesm2022/ojiepermana-angular-theme.mjs +6 -0
  15. package/fesm2022/ojiepermana-angular-theme.mjs.map +1 -0
  16. package/fesm2022/ojiepermana-angular.mjs +6 -0
  17. package/fesm2022/ojiepermana-angular.mjs.map +1 -0
  18. package/layout/README.md +143 -0
  19. package/layout/styles/index.css +157 -0
  20. package/package.json +59 -0
  21. package/shell/README.md +37 -0
  22. package/styles/index.css +2 -0
  23. package/styles/resets.css +22 -0
  24. package/theme/README.md +382 -0
  25. package/theme/styles/adapters/material-ui/index.css +210 -0
  26. package/theme/styles/index.css +8 -0
  27. package/theme/styles/layout/index.css +1 -0
  28. package/theme/styles/modes/dark.css +84 -0
  29. package/theme/styles/presets/colors/blue.css +10 -0
  30. package/theme/styles/presets/colors/brand.css +11 -0
  31. package/theme/styles/presets/colors/cyan.css +10 -0
  32. package/theme/styles/presets/colors/green.css +10 -0
  33. package/theme/styles/presets/colors/index.css +7 -0
  34. package/theme/styles/presets/colors/orange.css +10 -0
  35. package/theme/styles/presets/colors/purple.css +10 -0
  36. package/theme/styles/presets/colors/red.css +10 -0
  37. package/theme/styles/presets/styles/flat.css +30 -0
  38. package/theme/styles/presets/styles/glass.css +34 -0
  39. package/theme/styles/presets/styles/index.css +2 -0
  40. package/theme/styles/roles/index.css +49 -0
  41. package/theme/styles/tokens/foundation.css +139 -0
  42. package/theme/styles/tokens/semantic.css +87 -0
  43. package/theme/styles/utilities/index.css +88 -0
  44. package/types/ojiepermana-angular-internal.d.ts +26 -0
  45. package/types/ojiepermana-angular-layout.d.ts +90 -0
  46. package/types/ojiepermana-angular-shell.d.ts +12 -0
  47. package/types/ojiepermana-angular-theme-component.d.ts +46 -0
  48. package/types/ojiepermana-angular-theme-directive.d.ts +10 -0
  49. package/types/ojiepermana-angular-theme-service.d.ts +68 -0
  50. package/types/ojiepermana-angular-theme.d.ts +2 -0
  51. package/types/ojiepermana-angular.d.ts +2 -0
package/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # @ojiepermana/angular
2
+
3
+ Theme and layout primitives for Angular applications.
4
+
5
+ This package is organized around secondary entry points. The root TypeScript package is intentionally empty, so application code should not import APIs from `@ojiepermana/angular` directly.
6
+
7
+ ## Current Package Shape
8
+
9
+ Use these entry points in application code:
10
+
11
+ - `@ojiepermana/angular/theme/service`
12
+ - `@ojiepermana/angular/theme/component`
13
+ - `@ojiepermana/angular/theme/directive`
14
+ - `@ojiepermana/angular/layout`
15
+ - `@ojiepermana/angular/shell`
16
+ - `@ojiepermana/angular/styles/index.css`
17
+ - `@ojiepermana/angular/styles/resets.css` for optional application-level resets
18
+
19
+ Do not import consumer code from:
20
+
21
+ - `@ojiepermana/angular`
22
+ - `@ojiepermana/angular/internal`
23
+
24
+ ## What The Library Provides
25
+
26
+ - Theme runtime state through `ThemeService` and `provideNgTheme()` for scheme, color, and style.
27
+ - Theme host mirroring through `ThemeHostDirective`.
28
+ - Theme controls through `StyleSwitcherComponent`, `ColorPickerComponent`, and `SchemeSwitcherComponent`.
29
+ - Layout runtime state through `LayoutService` and `provideNgLayout()` for shell mode and container width.
30
+ - Combined runtime registration through `provideNgShell()`.
31
+ - Layout host mirroring through `LayoutHostDirective`.
32
+ - Reusable shell components through `LayoutVerticalComponent` and `LayoutHorizontalComponent`.
33
+ - Layout controls through `LayoutModeSwitcherComponent` and `LayoutContainerSwitcherComponent`.
34
+ - A combined stylesheet bundle through `@ojiepermana/angular/styles/index.css`.
35
+
36
+ ## Requirements
37
+
38
+ The published package currently declares peer dependencies for:
39
+
40
+ - `@angular/common` `^21.2.0`
41
+ - `@angular/core` `^21.2.0`
42
+ - `@angular/cdk` `^21.0.0`
43
+ - `@angular/material` `^21.0.0`
44
+ - `@lucide/angular` `>=1.0.0`
45
+ - `tailwindcss` `>=4.0.0`
46
+
47
+ If you use the layout shells, your application should also already be using Angular Router because the shell components render `RouterOutlet`.
48
+
49
+ ## Runtime Contract
50
+
51
+ ### Theme Runtime
52
+
53
+ `ThemeService` writes these values to `document.documentElement`:
54
+
55
+ - `.dark` when the resolved scheme is dark.
56
+ - `style.color-scheme` with the resolved browser color scheme.
57
+ - `data-theme-scheme`
58
+ - `data-theme-color`
59
+ - `data-theme-style`
60
+
61
+ Theme persistence keys:
62
+
63
+ - `theme-scheme`
64
+ - `theme-color`
65
+ - `theme-style`
66
+
67
+ ### Layout Runtime
68
+
69
+ `LayoutService` writes these values to `document.documentElement`:
70
+
71
+ - `data-layout-mode`
72
+ - `data-layout-container`
73
+
74
+ Layout persistence keys:
75
+
76
+ - `layout-mode`
77
+ - `layout-container`
78
+
79
+ Legacy `ng-theme:v2:*` keys are migrated automatically by the owning runtime service when they are read.
80
+
81
+ Deprecated config fields `storageKey` and `storageVersion` have been removed from the public config interfaces. The persistence keys are now fixed by the library runtime.
82
+
83
+ Theme color labels can be localized through `provideNgTheme({ colorLabels: { ... } })`, and layout shells now prefer the internal `shell-content` marker over the deprecated HTML `content` element name.
84
+
85
+ ## Styling Model
86
+
87
+ - `@ojiepermana/angular/styles/index.css` is the canonical aggregate bundle for applications. It imports theme first, then layout.
88
+ - Application-level resets are intentionally not bundled. Import `@ojiepermana/angular/styles/resets.css` only if you want the library's optional reset helpers.
89
+ - Theme and layout stylesheet sources remain internal composition layers behind the aggregate bundle.
90
+ - Semantic tokens are the visual source of truth.
91
+ - Angular Material is the behavior layer and consumes the shared theme variables.
92
+
93
+ ## Quick Start
94
+
95
+ ### 1. Register Providers
96
+
97
+ ```ts
98
+ import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
99
+ import { provideRouter } from '@angular/router';
100
+ import { provideNgShell } from '@ojiepermana/angular/shell';
101
+
102
+ import { routes } from './app.routes';
103
+
104
+ export const appConfig: ApplicationConfig = {
105
+ providers: [
106
+ provideBrowserGlobalErrorListeners(),
107
+ provideRouter(routes),
108
+ provideNgShell({
109
+ theme: {
110
+ defaultScheme: 'system',
111
+ defaultColor: 'brand',
112
+ defaultStyle: 'flat',
113
+ },
114
+ layout: {
115
+ defaultMode: 'vertical',
116
+ defaultContainer: 'boxed',
117
+ },
118
+ }),
119
+ ],
120
+ };
121
+ ```
122
+
123
+ ### 2. Register Styles
124
+
125
+ ```css
126
+ @import '@ojiepermana/angular/styles/index.css';
127
+ @import 'tailwindcss';
128
+ ```
129
+
130
+ Use this aggregate import for consumer applications.
131
+
132
+ If your application also wants the library's optional reset helpers, add this before the aggregate bundle:
133
+
134
+ ```css
135
+ @import '@ojiepermana/angular/styles/resets.css';
136
+ @import '@ojiepermana/angular/styles/index.css';
137
+ @import 'tailwindcss';
138
+ ```
139
+
140
+ ### 3. Compose A Shell
141
+
142
+ ```ts
143
+ import { ChangeDetectionStrategy, Component } from '@angular/core';
144
+ import {
145
+ LayoutContainerSwitcherComponent,
146
+ LayoutVerticalComponent,
147
+ } from '@ojiepermana/angular/layout';
148
+ import {
149
+ StyleSwitcherComponent,
150
+ ColorPickerComponent,
151
+ SchemeSwitcherComponent,
152
+ } from '@ojiepermana/angular/theme/component';
153
+
154
+ @Component({
155
+ selector: 'app-shell',
156
+ imports: [
157
+ StyleSwitcherComponent,
158
+ ColorPickerComponent,
159
+ LayoutContainerSwitcherComponent,
160
+ LayoutVerticalComponent,
161
+ SchemeSwitcherComponent,
162
+ ],
163
+ template: `
164
+ <vertical>
165
+ <nav navigation class="flex h-full w-full flex-col gap-6 px-4 py-5">
166
+ <div class="flex items-center gap-1">
167
+ <style-switcher />
168
+ <layout-container-switcher />
169
+ <scheme-switcher />
170
+ </div>
171
+
172
+ <color-picker />
173
+ </nav>
174
+ </vertical>
175
+ `,
176
+ changeDetection: ChangeDetectionStrategy.OnPush,
177
+ })
178
+ export class AppShellComponent {}
179
+ ```
180
+
181
+ ### 4. Mirror Runtime State To A Subtree
182
+
183
+ ```html
184
+ <section ngtThemeHost ngtLayoutHost>
185
+ <ng-content />
186
+ </section>
187
+ ```
188
+
189
+ ## Entry Point Summary
190
+
191
+ ### `@ojiepermana/angular/theme/service`
192
+
193
+ - `ThemeService`
194
+ - `provideNgTheme`
195
+ - `NG_THEME_CONFIG`
196
+ - `ThemeScheme`
197
+ - `ThemeColor`
198
+ - `ThemeColorOption`
199
+ - `ThemeStyle`
200
+ - `NgThemeConfig`
201
+
202
+ ### `@ojiepermana/angular/theme/component`
203
+
204
+ - `StyleSwitcherComponent`
205
+ - `ColorPickerComponent`
206
+ - `SchemeSwitcherComponent`
207
+
208
+ ### `@ojiepermana/angular/theme/directive`
209
+
210
+ - `ThemeHostDirective`
211
+
212
+ ### `@ojiepermana/angular/layout`
213
+
214
+ - `LayoutService`
215
+ - `provideNgLayout`
216
+ - `NG_LAYOUT_CONFIG`
217
+ - `LayoutMode`
218
+ - `LayoutContainer`
219
+ - `NgLayoutConfig`
220
+ - `LayoutHostDirective`
221
+ - `LayoutVerticalComponent`
222
+ - `LayoutHorizontalComponent`
223
+ - `LayoutModeSwitcherComponent`
224
+ - `LayoutContainerSwitcherComponent`
225
+
226
+ ### `@ojiepermana/angular/shell`
227
+
228
+ - `provideNgShell`
229
+ - `NgShellConfig`
230
+
231
+ ## Notes For Contributors
232
+
233
+ - Keep public imports domain-based through the documented secondary entry points.
234
+ - Document `@ojiepermana/angular/styles/index.css` as the consumer stylesheet entry point.
235
+ - Treat `@ojiepermana/angular/internal` as implementation-only. It exists so library entry points can share code without turning that code into a supported consumer contract.
236
+ - Do not add exports to `@ojiepermana/angular` unless the package contract changes intentionally.
237
+ - Keep the root README, theme README, layout README, and entrypoint smoke tests aligned whenever the public surface changes.
@@ -0,0 +1,58 @@
1
+ import { provideLucideConfig } from '@lucide/angular';
2
+
3
+ const libraryLucideConfigProvider = provideLucideConfig({
4
+ absoluteStrokeWidth: true,
5
+ strokeWidth: 1.35,
6
+ });
7
+
8
+ class LocalStorageStateAdapter {
9
+ config;
10
+ constructor(config) {
11
+ this.config = config;
12
+ }
13
+ clear(axis) {
14
+ if (!this.config.isBrowser || !this.config.storage) {
15
+ return;
16
+ }
17
+ this.config.storage.removeItem(this.key(axis));
18
+ this.config.storage.removeItem(this.legacyKey(axis));
19
+ }
20
+ persist(axis, value) {
21
+ if (!this.config.isBrowser || !this.config.storage) {
22
+ return;
23
+ }
24
+ this.config.storage.setItem(this.key(axis), value);
25
+ this.config.storage.removeItem(this.legacyKey(axis));
26
+ }
27
+ read(axis, fallback, isValid) {
28
+ if (!this.config.isBrowser || !this.config.storage) {
29
+ return fallback;
30
+ }
31
+ const storedValue = this.config.storage.getItem(this.key(axis));
32
+ if (storedValue && isValid(storedValue)) {
33
+ return storedValue;
34
+ }
35
+ const legacyValue = this.config.storage.getItem(this.legacyKey(axis));
36
+ if (legacyValue && isValid(legacyValue)) {
37
+ this.config.storage.setItem(this.key(axis), legacyValue);
38
+ this.config.storage.removeItem(this.legacyKey(axis));
39
+ return legacyValue;
40
+ }
41
+ return fallback;
42
+ }
43
+ key(axis) {
44
+ return this.config.keys[axis];
45
+ }
46
+ legacyKey(axis) {
47
+ return `${this.config.legacyPrefix}:${axis}`;
48
+ }
49
+ }
50
+
51
+ /* Internal composition utilities for library entrypoints. Not part of the supported consumer API. */
52
+
53
+ /**
54
+ * Generated bundle index. Do not edit.
55
+ */
56
+
57
+ export { LocalStorageStateAdapter, libraryLucideConfigProvider };
58
+ //# sourceMappingURL=ojiepermana-angular-internal.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ojiepermana-angular-internal.mjs","sources":["../../../projects/library/internal/src/lucide-config.provider.ts","../../../projects/library/internal/src/local-storage-state.ts","../../../projects/library/internal/public-api.ts","../../../projects/library/internal/ojiepermana-angular-internal.ts"],"sourcesContent":["import { provideLucideConfig } from '@lucide/angular';\n\nexport const libraryLucideConfigProvider = provideLucideConfig({\n absoluteStrokeWidth: true,\n strokeWidth: 1.35,\n});\n","interface StorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n}\n\ninterface LocalStorageStateAdapterConfig<Axis extends string> {\n readonly isBrowser: boolean;\n readonly storage: StorageLike | null;\n readonly keys: Record<Axis, string>;\n readonly legacyPrefix: string;\n}\n\nexport class LocalStorageStateAdapter<Axis extends string> {\n constructor(private readonly config: LocalStorageStateAdapterConfig<Axis>) {}\n\n clear(axis: Axis): void {\n if (!this.config.isBrowser || !this.config.storage) {\n return;\n }\n\n this.config.storage.removeItem(this.key(axis));\n this.config.storage.removeItem(this.legacyKey(axis));\n }\n\n persist(axis: Axis, value: string): void {\n if (!this.config.isBrowser || !this.config.storage) {\n return;\n }\n\n this.config.storage.setItem(this.key(axis), value);\n this.config.storage.removeItem(this.legacyKey(axis));\n }\n\n read<T extends string>(axis: Axis, fallback: T, isValid: (value: string) => value is T): T {\n if (!this.config.isBrowser || !this.config.storage) {\n return fallback;\n }\n\n const storedValue = this.config.storage.getItem(this.key(axis));\n\n if (storedValue && isValid(storedValue)) {\n return storedValue;\n }\n\n const legacyValue = this.config.storage.getItem(this.legacyKey(axis));\n\n if (legacyValue && isValid(legacyValue)) {\n this.config.storage.setItem(this.key(axis), legacyValue);\n this.config.storage.removeItem(this.legacyKey(axis));\n return legacyValue;\n }\n\n return fallback;\n }\n\n private key(axis: Axis): string {\n return this.config.keys[axis];\n }\n\n private legacyKey(axis: Axis): string {\n return `${this.config.legacyPrefix}:${axis}`;\n }\n}\n","/* Internal composition utilities for library entrypoints. Not part of the supported consumer API. */\n\nexport { libraryLucideConfigProvider } from './src/lucide-config.provider';\nexport { LocalStorageStateAdapter } from './src/local-storage-state';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAEO,MAAM,2BAA2B,GAAG,mBAAmB,CAAC;AAC7D,IAAA,mBAAmB,EAAE,IAAI;AACzB,IAAA,WAAW,EAAE,IAAI;AAClB,CAAA;;MCQY,wBAAwB,CAAA;AACN,IAAA,MAAA;AAA7B,IAAA,WAAA,CAA6B,MAA4C,EAAA;QAA5C,IAAA,CAAA,MAAM,GAAN,MAAM;IAAyC;AAE5E,IAAA,KAAK,CAAC,IAAU,EAAA;AACd,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;YAClD;QACF;AAEA,QAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC9C,QAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtD;IAEA,OAAO,CAAC,IAAU,EAAE,KAAa,EAAA;AAC/B,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;YAClD;QACF;AAEA,QAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;AAClD,QAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtD;AAEA,IAAA,IAAI,CAAmB,IAAU,EAAE,QAAW,EAAE,OAAsC,EAAA;AACpF,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;AAClD,YAAA,OAAO,QAAQ;QACjB;AAEA,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAE/D,QAAA,IAAI,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,EAAE;AACvC,YAAA,OAAO,WAAW;QACpB;AAEA,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAErE,QAAA,IAAI,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,EAAE;AACvC,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;AACxD,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACpD,YAAA,OAAO,WAAW;QACpB;AAEA,QAAA,OAAO,QAAQ;IACjB;AAEQ,IAAA,GAAG,CAAC,IAAU,EAAA;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;IAC/B;AAEQ,IAAA,SAAS,CAAC,IAAU,EAAA;QAC1B,OAAO,CAAA,EAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE;IAC9C;AACD;;AC/DD;;ACAA;;AAEG;;;;"}