@ojiepermana/angular 21.1.30 → 21.2.4

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.
@@ -1,273 +0,0 @@
1
- # Etos Brand
2
-
3
- Etos implementation lives under `projects/angular/brand/etos`. Published consumers should use `@ojiepermana/angular/etos`.
4
-
5
- This package is the Etos-specific layer on top of the shared Angular libraries. It owns the Etos brand defaults, shell composition, brand stylesheet, and Etos-only UI such as the profile/theme switcher.
6
-
7
- Use this folder for Etos-specific implementation:
8
-
9
- - `core/` contains brand defaults and provider composition.
10
- - `component/` contains Etos-owned UI such as `EtosThemeSwitcherComponent`.
11
- - `shells/` contains `EtosLayoutComponent` and the Etos empty, horizontal, and vertical shells.
12
- - `themes/` contains Etos color, style, layout, and component-facing CSS.
13
- - `navigation/`, `assets/`, and `docs/` can be added when Etos needs brand-specific behavior beyond shared primitives.
14
-
15
- Shared services, types, and primitives stay in the generic libraries:
16
-
17
- - `@ojiepermana/angular/theme`
18
- - `@ojiepermana/angular/layout`
19
- - `@ojiepermana/angular/navigation`
20
-
21
- ## Public entrypoint
22
-
23
- Published consumers should import Etos providers and Etos-owned UI through the short public entrypoint. Shell UI can also be imported through deeper shell aliases:
24
-
25
- ```ts
26
- import {
27
- EtosLayoutComponent,
28
- EtosThemeSwitcherComponent,
29
- ShellPagesComponent,
30
- provideEtosBrand,
31
- provideEtosLayout,
32
- provideEtosTheme,
33
- type EtosBrandOptions,
34
- type EtosThemeSwitcherQuickAction,
35
- type EtosThemeSwitcherUserInfo,
36
- } from '@ojiepermana/angular/etos';
37
-
38
- import { EtosLayoutComponent } from '@ojiepermana/angular/etos/shell/layout';
39
- import { ShellPagesComponent } from '@ojiepermana/angular/etos/shell/pages';
40
- ```
41
-
42
- `@ojiepermana/angular/etos` currently exports:
43
-
44
- - `provideEtosBrand()` to apply the Etos theme and layout defaults together and optionally register navigation items.
45
- - `provideEtosTheme()` to install only the Etos theme wrapper over the shared theme provider.
46
- - `provideEtosLayout()` to install only the Etos layout wrapper over the shared layout provider.
47
- - `EtosLayoutComponent` to render the Etos shell from the current layout mode.
48
- - `EtosThemeSwitcherComponent` and related types for the profile/preferences UI.
49
- - `ShellPagesComponent` for the fixed-header, scroll-main, optional-footer page shell.
50
-
51
- Shell-specific UI is exported through deeper entrypoints:
52
-
53
- - `@ojiepermana/angular/etos/shell/layout` aliases `EtosLayoutComponent`.
54
- - `@ojiepermana/angular/etos/shell/pages` aliases `ShellPagesComponent`.
55
-
56
- ## Provider setup
57
-
58
- Etos ships with these defaults:
59
-
60
- - Theme defaults to brand `etos` with light mode.
61
- - Layout defaults to `vertical` mode with `wide` width.
62
-
63
- Recommended provider configuration:
64
-
65
- ```ts
66
- import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
67
- import { provideRouter } from '@angular/router';
68
- import { type EtosBrandOptions, provideEtosBrand } from '@ojiepermana/angular/etos';
69
-
70
- import { AppNavigation } from './app.navigation';
71
- import { routes } from './app.routes';
72
-
73
- export const etosBrandConfig = {
74
- theme: {
75
- mode: 'light',
76
- },
77
- layout: {
78
- mode: 'vertical',
79
- },
80
- navigation: AppNavigation,
81
- } satisfies EtosBrandOptions;
82
-
83
- export const appConfig: ApplicationConfig = {
84
- providers: [provideBrowserGlobalErrorListeners(), provideRouter(routes), provideEtosBrand(etosBrandConfig)],
85
- };
86
- ```
87
-
88
- `provideEtosBrand()` accepts these Etos-specific options:
89
-
90
- - `theme` merges into the shared Material theme config while keeping the Etos brand tokens.
91
- - `layout` merges into the shared Material layout config while keeping the Etos layout defaults.
92
- - `navigation` registers navigation items during application startup.
93
- - `navigationId` targets a non-default navigation registry id when needed.
94
- - `materialDefaults` defaults to `true`; set it to `false` to skip `withMaterialDefaults()`.
95
-
96
- Use the granular providers when the consumer only needs one part of the Etos stack:
97
-
98
- ```ts
99
- import { ApplicationConfig } from '@angular/core';
100
- import { provideEtosLayout, provideEtosTheme } from '@ojiepermana/angular/etos';
101
-
102
- export const appConfig: ApplicationConfig = {
103
- providers: [provideEtosTheme(), provideEtosLayout({ mode: 'horizontal', width: 'wide' })],
104
- };
105
- ```
106
-
107
- ## Using the brand theme
108
-
109
- The Etos brand theme has two parts:
110
-
111
- - TypeScript setup through one of the Etos providers.
112
- - CSS setup through the Etos stylesheet so the `theme-brand="etos"` tokens are available at runtime.
113
-
114
- App CSS should import the Etos package stylesheet before Tailwind:
115
-
116
- ```css
117
- @import '@ojiepermana/angular/etos/styles';
118
- @import 'tailwindcss';
119
- @import '@ojiepermana/angular/theme/tailwind/theme.css';
120
- ```
121
-
122
- ## Using the layout shell
123
-
124
- `EtosLayoutComponent` is the exported shell component for Etos. It resolves `empty`, `horizontal`, or `vertical` from its `mode` input or from `LayoutService` when the input is omitted.
125
-
126
- This is the same composition pattern used by the Etos demo:
127
-
128
- ```ts
129
- import { ChangeDetectionStrategy, Component } from '@angular/core';
130
- import { RouterLink } from '@angular/router';
131
- import { EtosLayoutComponent } from '@ojiepermana/angular/etos/shell/layout';
132
- import {
133
- type EtosThemeSwitcherQuickAction,
134
- EtosThemeSwitcherComponent,
135
- type EtosThemeSwitcherUserInfo,
136
- } from '@ojiepermana/angular/etos';
137
-
138
- @Component({
139
- selector: 'app-pages',
140
- imports: [RouterLink, EtosLayoutComponent, EtosThemeSwitcherComponent],
141
- template: `
142
- <ng-template #layoutBrand>
143
- <a routerLink="/" class="flex min-w-0 items-center gap-3 px-2 py-1.5 transition-colors">
144
- <span class="text-sm font-semibold leading-none tracking-tight">angular UI</span>
145
- </a>
146
- </ng-template>
147
-
148
- <ng-template #layoutPanel>
149
- <div class="flex h-full w-full min-w-0 items-center justify-start gap-3 px-2 py-0">
150
- <etos-theme-switcher [userInfo]="profileInfo" [quickActions]="quickActions" />
151
-
152
- <div class="min-w-0 flex flex-col gap-px">
153
- <span class="truncate text-sm font-semibold leading-none text-foreground">{{ profileName }}</span>
154
- <span class="truncate text-xs leading-none text-muted-foreground">{{ profileTitle }}</span>
155
- </div>
156
- </div>
157
- </ng-template>
158
-
159
- <etos-layout [layoutBrandTemplate]="layoutBrand" [layoutProfileTemplate]="layoutPanel" />
160
- `,
161
- changeDetection: ChangeDetectionStrategy.OnPush,
162
- })
163
- export class Pages {
164
- protected readonly profileName = 'angular';
165
- protected readonly profileTitle = 'Etos design system navigator';
166
- protected readonly profileInfo = {
167
- name: this.profileName,
168
- subtitle: this.profileTitle,
169
- avatarSrc: '/avatar-ojie.svg',
170
- avatarAlt: 'angular avatar',
171
- } satisfies EtosThemeSwitcherUserInfo;
172
-
173
- protected readonly quickActions = [
174
- { value: 'notifications', label: 'Notifications', icon: 'notifications' },
175
- { value: 'sign-out', label: 'Logout', icon: 'logout', tone: 'destructive' },
176
- ] satisfies readonly EtosThemeSwitcherQuickAction[];
177
- }
178
- ```
179
-
180
- Layout inputs:
181
-
182
- - `mode`: optional explicit override for the active layout mode.
183
- - `layoutBrandTemplate`: used in the horizontal brand area and as the default vertical sidebar header.
184
- - `layoutProfileTemplate`: used in the horizontal profile area and as the default vertical sidebar footer.
185
- - `sidebarHeaderTemplate`: optional vertical-only override for the sidebar header.
186
- - `sidebarFooterTemplate`: optional vertical-only override for the sidebar footer.
187
-
188
- That fallback behavior means a single `layoutBrandTemplate` and `layoutProfileTemplate` pair is enough for most consumers, while vertical layouts can still diverge when needed.
189
-
190
- ## Using the theme switcher
191
-
192
- `EtosThemeSwitcherComponent` is exported from `@ojiepermana/angular/etos` and is intended to live inside the Etos shell profile area or any consumer-owned profile trigger.
193
-
194
- Common inputs and output:
195
-
196
- - `quickActions`: required array rendered in the popup footer. Pass `[]` if you only want the built-in theme and layout controls.
197
- - `userInfo`: object input for `name`, `subtitle`, `avatarSrc`, and `avatarAlt`.
198
- - `userName`, `userSubtitle`, `avatarSrc`, and `avatarAlt`: fallback inputs when `userInfo` is not supplied.
199
- - `notificationShortcut`: configures the standalone notification trigger shown beside the avatar.
200
- - `showNotificationShortcut`: legacy boolean shortcut for rendering the default notification button.
201
- - `popoverSide`, `popoverAlign`, and `popoverSideOffset`: explicit popover placement overrides.
202
- - `actionSelected`: emits the selected quick action or notification shortcut value.
203
-
204
- The popup always exposes theme scheme, layout mode, and layout width controls. The quick action area is fully consumer-driven:
205
-
206
- - Provide the action values and labels you need in `quickActions`.
207
- - Handle actions such as logout in the app consumer through `(actionSelected)`.
208
- - When `notificationShortcut.value` matches one of the `quickActions` values, the matching popup item is removed to avoid duplication.
209
-
210
- Popover defaults now follow the active layout automatically:
211
-
212
- - Vertical layout defaults to `side="top"` and `align="start"`.
213
- - Horizontal and empty layouts default to `side="bottom"` and `align="end"`.
214
-
215
- Only pass `popoverSide`, `popoverAlign`, or `popoverSideOffset` when you need to override those defaults.
216
-
217
- Input shape examples:
218
-
219
- ```ts
220
- profileInfo = {
221
- name: 'angular',
222
- subtitle: 'Etos design system navigator',
223
- avatarSrc: '/avatar-ojie.svg',
224
- avatarAlt: 'angular avatar',
225
- };
226
-
227
- notificationShortcut = {
228
- value: 'notifications',
229
- icon: 'notifications',
230
- ariaLabel: 'Open notifications for angular',
231
- };
232
-
233
- quickActions = [
234
- { value: 'notifications', label: 'Notifications', icon: 'notifications' },
235
- { value: 'sign-out', label: 'Logout', icon: 'logout', tone: 'destructive' },
236
- ];
237
- ```
238
-
239
- Example consumer-owned action handling:
240
-
241
- ```html
242
- <etos-theme-switcher
243
- [userInfo]="profileInfo"
244
- [quickActions]="quickActions"
245
- (actionSelected)="onThemeSwitcherAction($event)" />
246
- ```
247
-
248
- ```ts
249
- onThemeSwitcherAction(action: string): void {
250
- if (action === 'sign-out') {
251
- this.authService.logout();
252
- }
253
- }
254
- ```
255
-
256
- ## Workspace usage in this repository
257
-
258
- The Etos demo under `projects/demo/etos` already uses the short TypeScript entrypoint for provider setup and shell composition:
259
-
260
- - `src/app/app.config.ts` imports `provideEtosBrand` and passes `navigation: AppNavigation`.
261
- - `src/pages/pages.ts` imports `EtosLayoutComponent` and `EtosThemeSwitcherComponent` and wires `layoutBrandTemplate` plus `layoutProfileTemplate`.
262
-
263
- For CSS, the workspace demo currently imports the Etos source stylesheet directly:
264
-
265
- ```css
266
- @import '../../../angular/etos/themes/index.css';
267
- @import 'tailwindcss';
268
- @import '@ojiepermana/angular/theme/tailwind/theme.css';
269
- ```
270
-
271
- That local CSS path is intentional while developing inside this monorepo. Angular resolves bare CSS package imports from `node_modules/@ojiepermana/angular`, while TypeScript imports in the demo resolve through `tsconfig.json` path aliases. After the package is built, published, and installed with the latest exports, consumers should use `@ojiepermana/angular/etos/styles`.
272
-
273
- The older `@ojiepermana/angular/theme/styles/etos.css` path is kept only as a compatibility shim.
@@ -1,4 +0,0 @@
1
- {
2
- "module": "../../fesm2022/ojiepermana-angular-brand-etos.mjs",
3
- "typings": "../../types/ojiepermana-angular-brand-etos.d.ts"
4
- }
@@ -1,73 +0,0 @@
1
- /**
2
- * Etos brand color layer.
3
- */
4
- @layer tokens {
5
- [theme-brand='etos'] {
6
- --brand: 0 0% 64%;
7
- --brand-border-alpha: 0.7;
8
- --brand-background-alpha: 0.7;
9
-
10
- --background: 210 38% 98%;
11
- --surface: 0 0% 89.8%;
12
- --surface-foreground: 211 56% 12%;
13
- --foreground: 211 56% 12%;
14
-
15
- --card: 0 0% 100%;
16
- --card-foreground: 211 56% 12%;
17
-
18
- --popover: 0 0% 100%;
19
- --popover-foreground: 211 56% 12%;
20
-
21
- --muted: 211 34% 94%;
22
- --muted-foreground: 211 24% 38%;
23
-
24
- --border: 211 28% 82%;
25
- --input: 211 28% 82%;
26
-
27
- --primary: 211 95% 29%;
28
- --primary-foreground: 0 0% 100%;
29
- --accent: 211 95% 96%;
30
- --accent-foreground: 211 95% 22%;
31
- --secondary: 211 24% 95%;
32
- --secondary-foreground: 211 75% 24%;
33
- --ring: 211 95% 29%;
34
- }
35
-
36
- [data-mode='dark'][theme-brand='etos'] {
37
- --brand: 0 0% 64%;
38
- --brand-border-alpha: 0.45;
39
- --brand-background-alpha: 0.55;
40
-
41
- --background: 211 38% 9%;
42
- --surface: 211 22% 18%;
43
- --surface-foreground: 210 40% 96%;
44
- --foreground: 210 40% 96%;
45
-
46
- --card: 211 34% 11%;
47
- --card-foreground: 210 40% 96%;
48
-
49
- --popover: 211 34% 11%;
50
- --popover-foreground: 210 40% 96%;
51
-
52
- --muted: 211 22% 18%;
53
- --muted-foreground: 211 18% 70%;
54
-
55
- --border: 211 24% 24%;
56
- --input: 211 24% 24%;
57
-
58
- --accent: 211 58% 18%;
59
- --accent-foreground: 211 90% 84%;
60
- --secondary: 211 24% 18%;
61
- --secondary-foreground: 211 82% 84%;
62
- }
63
- }
64
-
65
- @layer utilities {
66
- .border-brand {
67
- border-color: hsl(var(--brand, var(--border)) / var(--brand-border-alpha, 0.7));
68
- }
69
-
70
- .bg-brand {
71
- background-color: hsl(var(--brand, var(--border)) / var(--brand-background-alpha, 0.7));
72
- }
73
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * Compatibility entry for consumers that resolve the explicit index file.
3
- *
4
- * Keep this publish-safe because ng-packagr copies it verbatim to
5
- * `@ojiepermana/angular/etos/styles/index.css`.
6
- */
7
- @import './package.css';
@@ -1,21 +0,0 @@
1
- /**
2
- * Etos brand layout layer.
3
- */
4
- @layer tokens {
5
- [theme-brand='etos'] {
6
- --layout-shell-padding: clamp(1rem, 2vw, 2rem);
7
- --layout-frame-radius: var(--radius-lg);
8
- --layout-frame-shadow: var(--shadow-sm);
9
- --layout-sidebar-width: 17.5rem;
10
- --layout-main-max-width: 80rem;
11
- --layout-vertical-shell-max-width: calc(var(--layout-sidebar-width) + var(--layout-main-max-width));
12
- --layout-empty-max-width: 24rem;
13
- --layout-empty-padding: clamp(1.5rem, 4vw, 3rem);
14
- --layout-topbar-inline: 0.875rem;
15
- --layout-brand-mark-size: 2rem;
16
- }
17
-
18
- [data-mode='dark'][theme-brand='etos'] {
19
- --layout-frame-shadow: 0 0 0 1px hsl(var(--border));
20
- }
21
- }
@@ -1,15 +0,0 @@
1
- /**
2
- * @ojiepermana/angular/etos — published Etos brand stylesheet.
3
- *
4
- * Import before Tailwind, then import the shared Tailwind token bridge.
5
- */
6
- @import '@ojiepermana/angular/theme/styles/themes/library/_layers.css';
7
- @import '@ojiepermana/angular/theme/styles/themes/mode/index.css';
8
- @import '@ojiepermana/angular/theme/styles/themes/library/color/index.css';
9
- @import '@ojiepermana/angular/theme/styles/themes/library/style/index.css';
10
- @import './color.css';
11
- @import './style.css';
12
- @import './layout.css';
13
- @import '@ojiepermana/angular/theme/styles/themes/library/_tokens.css';
14
- @import '@ojiepermana/angular/theme/styles/themes/library/_material-overrides.css';
15
- @import '@ojiepermana/angular/theme/styles/themes/library/_components.css';
@@ -1,53 +0,0 @@
1
- /**
2
- * Etos brand style layer.
3
- */
4
- @layer tokens {
5
- [theme-brand='etos'] {
6
- --theme-radius-xs: 0.125rem;
7
- --theme-radius-base: 0.375rem;
8
- --theme-radius-sm: calc(var(--theme-radius-base) - 2px);
9
- --theme-radius-md: var(--theme-radius-base);
10
- --theme-radius-lg: calc(var(--theme-radius-base) + 2px);
11
-
12
- --radius: var(--theme-radius-md);
13
- --radius-xs: var(--theme-radius-xs);
14
- --radius-sm: var(--theme-radius-sm);
15
- --radius-md: var(--theme-radius-md);
16
- --radius-lg: var(--theme-radius-lg);
17
-
18
- --border-width: 1px;
19
-
20
- --theme-shadow-sm: 0 1px 0 0 hsl(211 95% 12% / 0.08);
21
- --theme-shadow: 0 2px 4px -2px hsl(211 95% 12% / 0.14);
22
- --theme-shadow-md: 0 8px 18px -14px hsl(211 95% 12% / 0.24);
23
- --theme-shadow-lg: 0 18px 36px -28px hsl(211 95% 12% / 0.34);
24
-
25
- --shadow-sm: var(--theme-shadow-sm);
26
- --shadow: var(--theme-shadow);
27
- --shadow-md: var(--theme-shadow-md);
28
- --shadow-lg: var(--theme-shadow-lg);
29
-
30
- --theme-font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
31
- --theme-font-mono: 'JetBrains Mono', 'Fira Code', monospace;
32
-
33
- --font-sans: var(--theme-font-sans);
34
- --font-mono: var(--theme-font-mono);
35
- --font-weight-bold: 650;
36
- --theme-text-scale: 1;
37
- --nav-font-family: var(--font-sans);
38
- --nav-text-size: calc(var(--text-sm) - 0.125rem);
39
- --nav-text-line-height: var(--text-sm--line-height);
40
- --nav-heading-font-family: var(--font-sans);
41
- --nav-heading-size: var(--text-xs);
42
- --nav-heading-line-height: var(--text-xs--line-height);
43
- --nav-heading-weight: 700;
44
- --nav-heading-letter-spacing: 0.14em;
45
- --nav-badge-font-family: var(--font-sans);
46
- --nav-badge-size: var(--text-xs);
47
- --nav-badge-line-height: var(--text-xs--line-height);
48
- --nav-badge-weight: 600;
49
- --letter-spacing: 0;
50
- --space-unit: 0.25rem;
51
- --layout-topbar-height: 3.25rem;
52
- }
53
- }