@ojiepermana/angular-theme 22.0.43 → 22.0.44

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.
@@ -198,10 +198,10 @@ class ThemeModeService {
198
198
  return;
199
199
  }
200
200
  }
201
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.3", ngImport: i0, type: ThemeModeService, deps: [], target: i0.ɵɵFactoryTarget.Service });
202
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.3", ngImport: i0, type: ThemeModeService });
201
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeModeService, deps: [], target: i0.ɵɵFactoryTarget.Service });
202
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.4", ngImport: i0, type: ThemeModeService });
203
203
  }
204
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.3", ngImport: i0, type: ThemeModeService, decorators: [{
204
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeModeService, decorators: [{
205
205
  type: Service
206
206
  }], ctorParameters: () => [] });
207
207
 
@@ -312,10 +312,10 @@ class ThemeBrandService {
312
312
  return;
313
313
  }
314
314
  }
315
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.3", ngImport: i0, type: ThemeBrandService, deps: [], target: i0.ɵɵFactoryTarget.Service });
316
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.3", ngImport: i0, type: ThemeBrandService });
315
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeBrandService, deps: [], target: i0.ɵɵFactoryTarget.Service });
316
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.4", ngImport: i0, type: ThemeBrandService });
317
317
  }
318
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.3", ngImport: i0, type: ThemeBrandService, decorators: [{
318
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeBrandService, decorators: [{
319
319
  type: Service
320
320
  }], ctorParameters: () => [] });
321
321
 
@@ -394,10 +394,10 @@ class ThemeColorService {
394
394
  return;
395
395
  }
396
396
  }
397
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.3", ngImport: i0, type: ThemeColorService, deps: [], target: i0.ɵɵFactoryTarget.Service });
398
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.3", ngImport: i0, type: ThemeColorService });
397
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeColorService, deps: [], target: i0.ɵɵFactoryTarget.Service });
398
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.4", ngImport: i0, type: ThemeColorService });
399
399
  }
400
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.3", ngImport: i0, type: ThemeColorService, decorators: [{
400
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeColorService, decorators: [{
401
401
  type: Service
402
402
  }], ctorParameters: () => [] });
403
403
 
@@ -472,10 +472,10 @@ class ThemeRadiusService {
472
472
  return;
473
473
  }
474
474
  }
475
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.3", ngImport: i0, type: ThemeRadiusService, deps: [], target: i0.ɵɵFactoryTarget.Service });
476
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.3", ngImport: i0, type: ThemeRadiusService });
475
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeRadiusService, deps: [], target: i0.ɵɵFactoryTarget.Service });
476
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.4", ngImport: i0, type: ThemeRadiusService });
477
477
  }
478
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.3", ngImport: i0, type: ThemeRadiusService, decorators: [{
478
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeRadiusService, decorators: [{
479
479
  type: Service
480
480
  }], ctorParameters: () => [] });
481
481
 
@@ -532,10 +532,10 @@ class ThemeSpaceService {
532
532
  return;
533
533
  }
534
534
  }
535
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.3", ngImport: i0, type: ThemeSpaceService, deps: [], target: i0.ɵɵFactoryTarget.Service });
536
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.3", ngImport: i0, type: ThemeSpaceService });
535
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeSpaceService, deps: [], target: i0.ɵɵFactoryTarget.Service });
536
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.4", ngImport: i0, type: ThemeSpaceService });
537
537
  }
538
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.3", ngImport: i0, type: ThemeSpaceService, decorators: [{
538
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeSpaceService, decorators: [{
539
539
  type: Service
540
540
  }], ctorParameters: () => [] });
541
541
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ojiepermana/angular-theme",
3
- "version": "22.0.43",
3
+ "version": "22.0.44",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/edsis/angular.git"
@@ -13,8 +13,8 @@
13
13
  "@angular/common": ">=22.0.0",
14
14
  "@angular/core": ">=22.0.0",
15
15
  "@angular/router": ">=22.0.0",
16
- "@ojiepermana/angular-navigation": "^22.0.43",
17
- "@ojiepermana/angular-component": "^22.0.43",
16
+ "@ojiepermana/angular-navigation": "^22.0.44",
17
+ "@ojiepermana/angular-component": "^22.0.44",
18
18
  "rxjs": ">=7.8.0"
19
19
  },
20
20
  "dependencies": {
package/page/README.md CHANGED
@@ -13,9 +13,12 @@ Dokumentasi ini mengikuti API publik terbaru dari `@ojiepermana/angular-theme/pa
13
13
  - `PageFooter`
14
14
  - `PageSide`
15
15
  - `PageSideToggle`
16
+ - `PageFilter`
17
+ - `PageFilterToggle`
16
18
 
17
19
  `PageSideToggle` menerima projected content untuk label atau ikon kustom. Jika tidak ada projected content, komponen akan memakai ikon fallback bawaan.
18
20
  `PageDashboard` mengikuti perilaku layout dan scroll yang sama dengan `PageContent`, tetapi disediakan sebagai slot semantik untuk dashboard, board, dan surface analitik.
21
+ `PageFilter` adalah slot filter yang bisa diletakkan **stacked** (bar di antara `PageHeader` dan `PageContent`) atau **side** (kolom di samping `PageContent`). `PageFilterToggle` mengontrol `PageFilter` saat memakai mode `drawer`/`overlay`.
19
22
 
20
23
  ## Root API
21
24
 
@@ -31,13 +34,15 @@ Dokumentasi ini mengikuti API publik terbaru dari `@ojiepermana/angular-theme/pa
31
34
  | `sideMode` | `'sticky' \| 'drawer' \| 'overlay'` | `'sticky'` | Mode default untuk `PageSide` jika side tidak memberi override sendiri. |
32
35
  | `sideWidth` | `string` | `'16rem'` | Lebar default side rail; dipakai juga untuk drawer dan overlay. |
33
36
  | `sideOpen` | `boolean \| null` | `null` | Saat `null`, state side tidak dikontrol dari parent. Saat `true/false`, komponen masuk controlled mode. |
37
+ | `filterOpen` | `boolean \| null` | `null` | Controlled state untuk `PageFilter` drawer/overlay. `null` = uncontrolled (dikelola toggle/backdrop/Esc). |
34
38
  | `class` | `string` | `''` | Class tambahan pada host `Page`. |
35
39
 
36
- | Output | Payload | Keterangan |
37
- | ---------------- | --------- | -------------------------------------------------------------------------------------------- |
38
- | `sideOpenChange` | `boolean` | Emit setiap ada permintaan buka/tutup side, baik dari toggle, backdrop, maupun tombol `Esc`. |
40
+ | Output | Payload | Keterangan |
41
+ | ------------------ | --------- | ------------------------------------------------------------------------------------------------- |
42
+ | `sideOpenChange` | `boolean` | Emit setiap ada permintaan buka/tutup side, baik dari toggle, backdrop, maupun tombol `Esc`. |
43
+ | `filterOpenChange` | `boolean` | Emit setiap ada permintaan buka/tutup filter (drawer/overlay), baik dari toggle, backdrop, `Esc`. |
39
44
 
40
- `Page` juga menambahkan atribut host `data-page-variant`, `data-page-height`, `data-page-scroll`, `data-page-appearance`, `data-page-position`, `data-page-side-mode`, dan `data-page-side-open` untuk styling atau inspeksi.
45
+ `Page` juga menambahkan atribut host `data-page-variant`, `data-page-height`, `data-page-scroll`, `data-page-appearance`, `data-page-position`, `data-page-side-mode`, dan `data-page-side-open` untuk styling atau inspeksi. Saat `PageFilter` aktif, ditambahkan pula `data-page-filter-placement`, `data-page-filter-mode`, dan `data-page-filter-open`.
41
46
 
42
47
  ### Apps launcher (layout `empty`)
43
48
 
@@ -77,13 +82,14 @@ Tombol hanya muncul ketika layout aktif `empty` dan nav target punya data. Di la
77
82
 
78
83
  ### `PageSide`
79
84
 
80
- | Input | Type | Default | Keterangan |
81
- | ------------ | ----------------------------------- | ---------- | ----------------------------------------------------------------------------------------------- |
82
- | `mode` | `'sticky' \| 'drawer' \| 'overlay'` | `'sticky'` | Override mode side untuk instance tersebut. |
83
- | `position` | `'left' \| 'right' \| null` | `null` | Override posisi side untuk instance tersebut. Jika `null`, memakai nilai dari root `Page`. |
84
- | `width` | `string \| null` | `null` | Override lebar side untuk instance tersebut. Jika `null`, memakai `sideWidth` dari root `Page`. |
85
- | `closeOnEsc` | `boolean` | `true` | Berlaku untuk `drawer` dan `overlay`; menutup side ketika tombol `Esc` ditekan. |
86
- | `class` | `string` | `''` | Class tambahan pada host `PageSide`. |
85
+ | Input | Type | Default | Keterangan |
86
+ | ------------ | ----------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------ |
87
+ | `mode` | `'sticky' \| 'drawer' \| 'overlay'` | `'sticky'` | Override mode side untuk instance tersebut. |
88
+ | `position` | `'left' \| 'right' \| null` | `null` | Override posisi side untuk instance tersebut. Jika `null`, memakai nilai dari root `Page`. |
89
+ | `width` | `string \| null` | `null` | Override lebar side untuk instance tersebut. Jika `null`, memakai `sideWidth` dari root `Page`. |
90
+ | `closeOnEsc` | `boolean` | `true` | Berlaku untuk `drawer` dan `overlay`; menutup side ketika tombol `Esc` ditekan. |
91
+ | `ariaLabel` | `string` | `'Side panel'` | Nama aksesibilitas panel saat `drawer`/`overlay` (dipasang sebagai `aria-label` pada `role="dialog"`). |
92
+ | `class` | `string` | `''` | Class tambahan pada host `PageSide`. |
87
93
 
88
94
  ### `PageSideToggle`
89
95
 
@@ -93,6 +99,31 @@ Tombol hanya muncul ketika layout aktif `empty` dan nav target punya data. Di la
93
99
  | `class` | `string` | `''` | Class tambahan pada host toggle. |
94
100
  | `toggled` | `boolean` | - | Emit nilai open state terbaru setelah tombol toggle diklik. |
95
101
 
102
+ ### `PageFilter`
103
+
104
+ | Input | Type | Default | Keterangan |
105
+ | ------------- | ----------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- |
106
+ | `placement` | `'stacked' \| 'side'` | `'stacked'` | `stacked` = bar di antara `PageHeader` dan `PageContent`; `side` = kolom di samping `PageContent`. |
107
+ | `mode` | `'sticky' \| 'drawer' \| 'overlay'` | `'sticky'` | Hanya berlaku untuk `placement="side"`. `placement="stacked"` selalu `sticky`. |
108
+ | `position` | `'left' \| 'right' \| null` | `null` | Posisi kolom saat `side`. Jika `null`, memakai default (`left`). |
109
+ | `width` | `string \| null` | `null` | Lebar kolom saat `side`. Jika `null`, memakai `18rem`. |
110
+ | `closeOnEsc` | `boolean` | `true` | Berlaku untuk `drawer`/`overlay`; menutup filter ketika tombol `Esc` ditekan. |
111
+ | `collapsible` | `boolean` | `false` | Khusus `placement="stacked"`: bar bisa dibuka/tutup lewat `PageFilterToggle`, default tertutup. Diabaikan untuk `side`. |
112
+ | `ariaLabel` | `string` | `'Filters'` | Nama aksesibilitas panel saat `drawer`/`overlay` (dipasang sebagai `aria-label` pada `role="dialog"`). |
113
+ | `class` | `string` | `''` | Class tambahan pada host `PageFilter`. |
114
+
115
+ `PageFilter` menambahkan atribut host `data-page-slot="filter"`, `data-page-filter-placement`, `data-page-filter-mode`, `data-page-filter-open`, dan `data-page-position`.
116
+
117
+ Aksesibilitas: pada mode `drawer`/`overlay`, panel menjadi `role="dialog"` (dengan `aria-modal` untuk `overlay`), fokus dipindahkan ke panel saat terbuka dan dikembalikan ke pemicu saat tertutup, dan saat tertutup panel diberi `inert` sehingga isinya keluar dari tab order. `PageSide` memakai pola yang sama. Menekan `Esc` (atau mengklik backdrop overlay) menutup semua panel mengambang yang sedang terbuka.
118
+
119
+ ### `PageFilterToggle`
120
+
121
+ | Input / Output | Type | Default | Keterangan |
122
+ | -------------- | --------- | ---------------------- | ----------------------------------------------------------- |
123
+ | `ariaLabel` | `string` | `'Toggle page filter'` | Label aksesibilitas untuk tombol toggle filter. |
124
+ | `class` | `string` | `''` | Class tambahan pada host toggle. |
125
+ | `toggled` | `boolean` | - | Emit nilai open state terbaru setelah tombol toggle diklik. |
126
+
96
127
  ## Variants
97
128
 
98
129
  - `stacked`
@@ -130,6 +161,15 @@ Saat memakai `height="fix"`, slot berikut tidak boleh melebihi tinggi tetap yang
130
161
  - `drawer`
131
162
  - `overlay`
132
163
 
164
+ ## Filter Placement
165
+
166
+ `PageFilter` punya dua placement yang orthogonal terhadap `variant` `Page`:
167
+
168
+ - `stacked` (default): filter menjadi bar selebar content di antara `PageHeader` dan `PageContent`. Filter mendorong content ke bawah; pada `scroll="content"`, content mengisi tinggi sisa dan scroll sendiri (filter `shrink-0`). Pada `scroll="page"`, bar dipin (`sticky top-0`) agar tetap terjangkau saat page scroll.
169
+ - `side`: filter menjadi kolom di samping content. Mode `sticky` mendorong content ke samping (push); mode `drawer`/`overlay` mengambang di atas content dan dikontrol via `PageFilterToggle`, backdrop, atau tombol `Esc`.
170
+
171
+ Karena independen dari `variant`, side filter bisa hidup berdampingan dengan `PageSide` — `PageSide` tetap menjadi rail terluar dan `PageFilter` menjadi kolom yang lebih dekat ke content (`[PageSide | PageFilter | PageContent]`).
172
+
133
173
  ## Examples
134
174
 
135
175
  ### Stacked with content scroll
@@ -275,3 +315,109 @@ Saat memakai `height="fix"`, slot berikut tidak boleh melebihi tinggi tetap yang
275
315
  </PageDashboard>
276
316
  </Page>
277
317
  ```
318
+
319
+ ### Stacked filter (bar antara header dan content)
320
+
321
+ ```html
322
+ <Page variant="stacked">
323
+ <PageHeader>
324
+ <h1>Orders</h1>
325
+ </PageHeader>
326
+
327
+ <PageFilter placement="stacked">
328
+ <input type="search" aria-label="Cari order" placeholder="Cari…" />
329
+ <button type="button">Status</button>
330
+ <button type="button">Tanggal</button>
331
+ </PageFilter>
332
+
333
+ <PageContent>
334
+ <p>Content mengisi tinggi sisa dan scroll sendiri di bawah bar filter.</p>
335
+ </PageContent>
336
+ </Page>
337
+ ```
338
+
339
+ ### Collapsible stacked filter
340
+
341
+ ```html
342
+ <Page variant="stacked">
343
+ <PageHeader>
344
+ <PageFilterToggle ariaLabel="Toggle filters">
345
+ <span>Filters</span>
346
+ </PageFilterToggle>
347
+ <h1>Orders</h1>
348
+ </PageHeader>
349
+
350
+ <!-- Default tertutup; toggle membuka/menutup bar. -->
351
+ <PageFilter placement="stacked" collapsible>
352
+ <input type="search" aria-label="Cari order" placeholder="Cari…" />
353
+ <button type="button">Status</button>
354
+ </PageFilter>
355
+
356
+ <PageContent>
357
+ <p>Saat filter tertutup, content mengisi kembali ruang bar.</p>
358
+ </PageContent>
359
+ </Page>
360
+ ```
361
+
362
+ ### Side filter (sticky push)
363
+
364
+ ```html
365
+ <Page variant="stacked">
366
+ <PageHeader>
367
+ <h1>Catalog</h1>
368
+ </PageHeader>
369
+
370
+ <PageFilter placement="side" mode="sticky" position="left" width="18rem">
371
+ <p>Facet filter; mendorong content ke samping.</p>
372
+ </PageFilter>
373
+
374
+ <PageContent>
375
+ <p>Hasil produk.</p>
376
+ </PageContent>
377
+ </Page>
378
+ ```
379
+
380
+ ### Side filter (controlled drawer)
381
+
382
+ ```html
383
+ <Page [filterOpen]="filterOpen()" (filterOpenChange)="filterOpen.set($event)">
384
+ <PageHeader>
385
+ <PageFilterToggle ariaLabel="Toggle filter">
386
+ <span>Filter</span>
387
+ </PageFilterToggle>
388
+ <h1>Catalog</h1>
389
+ </PageHeader>
390
+
391
+ <PageFilter placement="side" mode="drawer" position="right">
392
+ <p>Drawer filter mengikuti state dari parent.</p>
393
+ </PageFilter>
394
+
395
+ <PageContent>
396
+ <p>Hasil produk.</p>
397
+ </PageContent>
398
+ </Page>
399
+ ```
400
+
401
+ ### Filter dan side rail berdampingan
402
+
403
+ `PageSide` (rail terluar) dan `PageFilter` (`placement="side"`) bisa aktif bersamaan: `[PageSide | PageFilter | PageContent]`.
404
+
405
+ ```html
406
+ <Page variant="side" position="left">
407
+ <PageHeader>
408
+ <h1>Workspace</h1>
409
+ </PageHeader>
410
+
411
+ <PageSide mode="sticky">
412
+ <p>Navigasi.</p>
413
+ </PageSide>
414
+
415
+ <PageFilter placement="side" position="left">
416
+ <p>Filter.</p>
417
+ </PageFilter>
418
+
419
+ <PageContent>
420
+ <p>Content.</p>
421
+ </PageContent>
422
+ </Page>
423
+ ```