@edsis/ui 0.0.2 → 0.0.3
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.
- package/empty/README.md +1 -1
- package/fesm2022/edsis-ui-accordion.mjs +15 -15
- package/fesm2022/edsis-ui-alert-dialog.mjs +27 -27
- package/fesm2022/edsis-ui-alert.mjs +12 -12
- package/fesm2022/edsis-ui-aspect-ratio.mjs +3 -3
- package/fesm2022/edsis-ui-avatar.mjs +18 -18
- package/fesm2022/edsis-ui-badge.mjs +3 -3
- package/fesm2022/edsis-ui-breadcrumb.mjs +21 -21
- package/fesm2022/edsis-ui-button-group.mjs +9 -9
- package/fesm2022/edsis-ui-button.mjs +3 -3
- package/fesm2022/edsis-ui-calendar.mjs +3 -3
- package/fesm2022/edsis-ui-card.mjs +21 -21
- package/fesm2022/edsis-ui-carousel.mjs +18 -18
- package/fesm2022/edsis-ui-chart.mjs +80 -78
- package/fesm2022/edsis-ui-chart.mjs.map +1 -1
- package/fesm2022/edsis-ui-checkbox.mjs +3 -3
- package/fesm2022/edsis-ui-collapsible.mjs +12 -12
- package/fesm2022/edsis-ui-combobox.mjs +3 -3
- package/fesm2022/edsis-ui-command.mjs +41 -35
- package/fesm2022/edsis-ui-command.mjs.map +1 -1
- package/fesm2022/edsis-ui-composer.mjs +21 -21
- package/fesm2022/edsis-ui-context-menu.mjs +13 -7
- package/fesm2022/edsis-ui-context-menu.mjs.map +1 -1
- package/fesm2022/edsis-ui-date-picker.mjs +3 -3
- package/fesm2022/edsis-ui-dialog.mjs +27 -23
- package/fesm2022/edsis-ui-dialog.mjs.map +1 -1
- package/fesm2022/edsis-ui-dropdown-menu.mjs +58 -46
- package/fesm2022/edsis-ui-dropdown-menu.mjs.map +1 -1
- package/fesm2022/edsis-ui-editor.mjs +22 -20
- package/fesm2022/edsis-ui-editor.mjs.map +1 -1
- package/fesm2022/edsis-ui-empty.mjs +18 -18
- package/fesm2022/edsis-ui-form.mjs +38 -38
- package/fesm2022/edsis-ui-form.mjs.map +1 -1
- package/fesm2022/edsis-ui-hover-card.mjs +34 -13
- package/fesm2022/edsis-ui-hover-card.mjs.map +1 -1
- package/fesm2022/edsis-ui-input-group.mjs +18 -18
- package/fesm2022/edsis-ui-input-otp.mjs +15 -15
- package/fesm2022/edsis-ui-input.mjs +3 -3
- package/fesm2022/edsis-ui-item.mjs +30 -30
- package/fesm2022/edsis-ui-kanban.mjs +27 -27
- package/fesm2022/edsis-ui-kbd.mjs +6 -6
- package/fesm2022/edsis-ui-label.mjs +3 -3
- package/fesm2022/edsis-ui-layout-services.mjs +6 -0
- package/fesm2022/edsis-ui-layout-services.mjs.map +1 -0
- package/fesm2022/edsis-ui-layout-types.mjs +6 -0
- package/fesm2022/edsis-ui-layout-types.mjs.map +1 -0
- package/fesm2022/edsis-ui-layout.mjs +572 -0
- package/fesm2022/edsis-ui-layout.mjs.map +1 -0
- package/fesm2022/edsis-ui-menubar.mjs +22 -16
- package/fesm2022/edsis-ui-menubar.mjs.map +1 -1
- package/fesm2022/edsis-ui-native-select.mjs +9 -9
- package/fesm2022/edsis-ui-nav-service.mjs +343 -0
- package/fesm2022/edsis-ui-nav-service.mjs.map +1 -0
- package/fesm2022/edsis-ui-nav.mjs +2340 -0
- package/fesm2022/edsis-ui-nav.mjs.map +1 -0
- package/fesm2022/edsis-ui-navigation-menu.mjs +30 -24
- package/fesm2022/edsis-ui-navigation-menu.mjs.map +1 -1
- package/fesm2022/edsis-ui-page.mjs +397 -0
- package/fesm2022/edsis-ui-page.mjs.map +1 -0
- package/fesm2022/edsis-ui-pagination.mjs +3 -3
- package/fesm2022/edsis-ui-pillbox.mjs +16 -16
- package/fesm2022/edsis-ui-pillbox.mjs.map +1 -1
- package/fesm2022/edsis-ui-popover.mjs +16 -10
- package/fesm2022/edsis-ui-popover.mjs.map +1 -1
- package/fesm2022/edsis-ui-progress.mjs +3 -3
- package/fesm2022/edsis-ui-radio.mjs +6 -6
- package/fesm2022/edsis-ui-resizable.mjs +12 -12
- package/fesm2022/edsis-ui-scroll-area.mjs +3 -3
- package/fesm2022/edsis-ui-select.mjs +6 -6
- package/fesm2022/edsis-ui-separator.mjs +3 -3
- package/fesm2022/edsis-ui-sheet.mjs +27 -23
- package/fesm2022/edsis-ui-sheet.mjs.map +1 -1
- package/fesm2022/edsis-ui-skeleton.mjs +3 -3
- package/fesm2022/edsis-ui-slider.mjs +6 -6
- package/fesm2022/edsis-ui-spinner.mjs +3 -3
- package/fesm2022/edsis-ui-switch.mjs +3 -3
- package/fesm2022/edsis-ui-table.mjs +24 -24
- package/fesm2022/edsis-ui-tabs.mjs +18 -18
- package/fesm2022/edsis-ui-textarea.mjs +3 -3
- package/fesm2022/edsis-ui-theme.mjs +209 -0
- package/fesm2022/edsis-ui-theme.mjs.map +1 -0
- package/fesm2022/edsis-ui-timeline.mjs +18 -18
- package/fesm2022/edsis-ui-toast.mjs +3 -3
- package/fesm2022/edsis-ui-toggle-group.mjs +9 -9
- package/fesm2022/edsis-ui-toggle.mjs +3 -3
- package/fesm2022/edsis-ui-tooltip.mjs +12 -12
- package/layout/README.md +454 -0
- package/nav/README.md +96 -0
- package/package.json +31 -2
- package/page/README.md +46 -0
- package/types/edsis-ui-command.d.ts +4 -1
- package/types/edsis-ui-context-menu.d.ts +2 -1
- package/types/edsis-ui-dropdown-menu.d.ts +5 -2
- package/types/edsis-ui-editor.d.ts +1 -0
- package/types/edsis-ui-hover-card.d.ts +3 -1
- package/types/edsis-ui-layout-services.d.ts +1 -0
- package/types/edsis-ui-layout-types.d.ts +1 -0
- package/types/edsis-ui-layout.d.ts +153 -0
- package/types/edsis-ui-menubar.d.ts +2 -0
- package/types/edsis-ui-nav-service.d.ts +138 -0
- package/types/edsis-ui-nav.d.ts +205 -0
- package/types/edsis-ui-navigation-menu.d.ts +2 -0
- package/types/edsis-ui-page.d.ts +137 -0
- package/types/edsis-ui-popover.d.ts +2 -1
- package/types/edsis-ui-theme.d.ts +71 -0
package/layout/README.md
ADDED
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
# @edsis/ui/layout
|
|
2
|
+
|
|
3
|
+
Primitive layout projection untuk menyusun shell UI dengan satu root `ui-layout`, satu variant layout (`vertical`, `horizontal`, atau `empty`), slot `ui-layout-nav`, dan area `ui-layout-content` yang menjadi scroll container utama.
|
|
4
|
+
|
|
5
|
+
README ini mendokumentasikan seluruh API publik yang diekspor oleh package agar consumer bisa memahami kontrak komponen, type, service, dan perilaku layout tanpa perlu membaca source code.
|
|
6
|
+
|
|
7
|
+
## Entry points
|
|
8
|
+
|
|
9
|
+
`@edsis/ui/layout` adalah root entry point yang mengekspor seluruh primitive utama, `LayoutService`, seluruh type, constants, dan guards.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import {
|
|
13
|
+
LayoutService,
|
|
14
|
+
UiLayoutComponent,
|
|
15
|
+
UiLayoutContentComponent,
|
|
16
|
+
UiLayoutEmptyComponent,
|
|
17
|
+
UiLayoutHorizontalComponent,
|
|
18
|
+
UiLayoutNavComponent,
|
|
19
|
+
UiLayoutVerticalComponent,
|
|
20
|
+
type UiLayoutStyle,
|
|
21
|
+
type UiLayoutSurface,
|
|
22
|
+
type UiLayoutType,
|
|
23
|
+
type UiLayoutWidth,
|
|
24
|
+
} from '@edsis/ui/layout';
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Secondary entry point tetap tersedia bila consumer ingin import yang lebih eksplisit.
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { LayoutService } from '@edsis/ui/layout/services';
|
|
31
|
+
import {
|
|
32
|
+
UI_LAYOUT_DEFAULT_STYLE,
|
|
33
|
+
UI_LAYOUT_DEFAULT_SURFACE,
|
|
34
|
+
UI_LAYOUT_DEFAULT_TYPE,
|
|
35
|
+
UI_LAYOUT_DEFAULT_WIDTH,
|
|
36
|
+
UI_LAYOUT_APPEARANCE_STORAGE_KEY,
|
|
37
|
+
UI_LAYOUT_STYLES,
|
|
38
|
+
UI_LAYOUT_SURFACE_STORAGE_KEY,
|
|
39
|
+
UI_LAYOUT_STYLE_STORAGE_KEY,
|
|
40
|
+
UI_LAYOUT_SURFACES,
|
|
41
|
+
UI_LAYOUT_TYPES,
|
|
42
|
+
UI_LAYOUT_TYPE_STORAGE_KEY,
|
|
43
|
+
UI_LAYOUT_WIDTHS,
|
|
44
|
+
UI_LAYOUT_WIDTH_STORAGE_KEY,
|
|
45
|
+
isUiLayoutSurface,
|
|
46
|
+
isUiLayoutStyle,
|
|
47
|
+
isUiLayoutType,
|
|
48
|
+
isUiLayoutWidth,
|
|
49
|
+
type UiLayoutContextValue,
|
|
50
|
+
type UiLayoutStyle,
|
|
51
|
+
type UiLayoutSurface,
|
|
52
|
+
type UiLayoutType,
|
|
53
|
+
type UiLayoutWidth,
|
|
54
|
+
} from '@edsis/ui/layout/types';
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Catatan:
|
|
58
|
+
|
|
59
|
+
- Root entry point dan secondary entry point mengekspor symbol yang sama. Gunakan secondary entry point jika consumer ingin dependency path yang lebih eksplisit untuk `services` atau `types`.
|
|
60
|
+
- Untuk kasus halaman yang membaca preferensi persisted, source of truth tetap berada di `LayoutService`.
|
|
61
|
+
|
|
62
|
+
## Mental model
|
|
63
|
+
|
|
64
|
+
Struktur yang direkomendasikan adalah sebagai berikut.
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<ui-layout>
|
|
68
|
+
<ui-layout-vertical | ui-layout-horizontal | ui-layout-empty>
|
|
69
|
+
<ui-layout-nav>...</ui-layout-nav>
|
|
70
|
+
<ui-layout-content>...</ui-layout-content>
|
|
71
|
+
</ui-layout-vertical | ui-layout-horizontal | ui-layout-empty>
|
|
72
|
+
</ui-layout>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Aturan penggunaannya:
|
|
76
|
+
|
|
77
|
+
- Gunakan tepat satu variant layout di dalam `ui-layout`.
|
|
78
|
+
- Untuk layout `vertical` dan `horizontal`, urutan child yang umum adalah `ui-layout-nav` lalu `ui-layout-content`.
|
|
79
|
+
- Untuk layout `empty`, biasanya cukup `ui-layout-content`.
|
|
80
|
+
- `ui-layout-content` adalah area yang memiliki `overflow-auto`, jadi konten utama sebaiknya ditempatkan di sana.
|
|
81
|
+
- Pada mode `vertical`, lebar nav mengikuti kontennya sendiri (`w-max`), bukan dipaksa oleh root layout.
|
|
82
|
+
|
|
83
|
+
## Quick start
|
|
84
|
+
|
|
85
|
+
### Vertical
|
|
86
|
+
|
|
87
|
+
```html
|
|
88
|
+
<ui-layout surface="grid" appearance="border-rail" width="full">
|
|
89
|
+
<ui-layout-vertical>
|
|
90
|
+
<ui-layout-nav ariaLabel="Primary navigation">
|
|
91
|
+
<aside class="flex h-full w-56 flex-col gap-4 bg-card/80 p-4">Navigation</aside>
|
|
92
|
+
</ui-layout-nav>
|
|
93
|
+
|
|
94
|
+
<ui-layout-content class="bg-background/80 p-6"> Content </ui-layout-content>
|
|
95
|
+
</ui-layout-vertical>
|
|
96
|
+
</ui-layout>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Horizontal
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<ui-layout surface="line-horizontal" appearance="flat" width="wide">
|
|
103
|
+
<ui-layout-horizontal>
|
|
104
|
+
<ui-layout-nav ariaLabel="Top navigation">
|
|
105
|
+
<header class="flex h-full items-center px-4">Navigation</header>
|
|
106
|
+
</ui-layout-nav>
|
|
107
|
+
|
|
108
|
+
<ui-layout-content class="p-6">Content</ui-layout-content>
|
|
109
|
+
</ui-layout-horizontal>
|
|
110
|
+
</ui-layout>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Empty
|
|
114
|
+
|
|
115
|
+
```html
|
|
116
|
+
<ui-layout surface="flat" appearance="flat" width="container">
|
|
117
|
+
<ui-layout-empty>
|
|
118
|
+
<ui-layout-content class="py-8"> Content </ui-layout-content>
|
|
119
|
+
</ui-layout-empty>
|
|
120
|
+
</ui-layout>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Pola page-level yang direkomendasikan
|
|
124
|
+
|
|
125
|
+
Untuk halaman yang memiliki default sendiri tetapi tetap harus tunduk pada nilai local storage yang sudah tersimpan, pakai `LayoutService.registerDefaults(...)` sekali di level page, lalu bind root `ui-layout` ke signal service.
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
|
129
|
+
import {
|
|
130
|
+
LayoutService,
|
|
131
|
+
UiLayoutComponent,
|
|
132
|
+
UiLayoutContentComponent,
|
|
133
|
+
UiLayoutHorizontalComponent,
|
|
134
|
+
UiLayoutNavComponent,
|
|
135
|
+
} from '@edsis/ui/layout';
|
|
136
|
+
|
|
137
|
+
@Component({
|
|
138
|
+
selector: 'demo-board',
|
|
139
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
140
|
+
imports: [UiLayoutComponent, UiLayoutHorizontalComponent, UiLayoutNavComponent, UiLayoutContentComponent],
|
|
141
|
+
template: `
|
|
142
|
+
<ui-layout [surface]="layout.surface()" [appearance]="layout.appearance()" [width]="layout.width()">
|
|
143
|
+
<ui-layout-horizontal>
|
|
144
|
+
<ui-layout-nav ariaLabel="Board navigation">...</ui-layout-nav>
|
|
145
|
+
<ui-layout-content>...</ui-layout-content>
|
|
146
|
+
</ui-layout-horizontal>
|
|
147
|
+
</ui-layout>
|
|
148
|
+
`,
|
|
149
|
+
})
|
|
150
|
+
export class DemoBoardComponent {
|
|
151
|
+
protected readonly layout = inject(LayoutService).registerDefaults({
|
|
152
|
+
surface: 'grid',
|
|
153
|
+
appearance: 'border-rail',
|
|
154
|
+
type: 'horizontal',
|
|
155
|
+
width: 'container',
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Dengan pola ini:
|
|
161
|
+
|
|
162
|
+
- consumer cukup mendeklarasikan default sekali
|
|
163
|
+
- nilai valid yang sudah ada di local storage tidak akan ditimpa
|
|
164
|
+
- `layout.type()` bisa langsung dipakai untuk memilih variant `vertical`, `horizontal`, atau `empty`
|
|
165
|
+
- root `ui-layout` selalu merender nilai final dari service, bukan hanya fallback dari template
|
|
166
|
+
|
|
167
|
+
## API reference
|
|
168
|
+
|
|
169
|
+
### `UiLayoutComponent`
|
|
170
|
+
|
|
171
|
+
Root wrapper yang mengatur background surface, appearance frame, width mode, dan sinkronisasi fallback state ke `LayoutService`.
|
|
172
|
+
|
|
173
|
+
Selector: `ui-layout`
|
|
174
|
+
|
|
175
|
+
Inputs:
|
|
176
|
+
|
|
177
|
+
| Input | Type | Default | Deskripsi |
|
|
178
|
+
| -------------- | ----------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
179
|
+
| `surface` | `UiLayoutSurface` | `'flat'` | Menentukan fallback background root layout. Jika local storage `layout-surface` berisi nilai valid, nilai storage yang dipakai. |
|
|
180
|
+
| `appearance` | `UiLayoutStyle or null` | `null` | API template utama untuk menentukan fallback appearance frame. Jika input ini kosong, primitive mencoba alias `layout-style`, lalu fallback efektif akhirnya `flat`. |
|
|
181
|
+
| `layout-style` | `UiLayoutStyle or null` | `null` | Alias kompatibilitas untuk template lama. Tetap dibaca sebagai fallback, tetapi API yang direkomendasikan adalah `appearance`. |
|
|
182
|
+
| `width` | `UiLayoutWidth` | `'full'` | Menentukan fallback padding outer dan perilaku container frame. Jika local storage `layout-width` berisi nilai valid, nilai storage yang dipakai. |
|
|
183
|
+
| `class` | `string` | `''` | Menambahkan class pada host `ui-layout`. |
|
|
184
|
+
|
|
185
|
+
Behavior:
|
|
186
|
+
|
|
187
|
+
- Mendaftarkan default `surface`, `appearance`, dan `width` ke `LayoutService` hanya saat local storage belum memiliki nilai valid.
|
|
188
|
+
- Nilai visual final selalu dibaca kembali dari `LayoutService`, sehingga stored preference menang atas fallback input.
|
|
189
|
+
- Menambahkan atribut host `data-surface`, `data-layout-appearance`, `data-layout-style`, `data-layout-width`, dan `data-layout-type`.
|
|
190
|
+
- Root tidak menyediakan input `type`. Type aktif dikendalikan oleh variant layout yang dirender, atau oleh consumer melalui `LayoutService.registerDefaults({ type })` sebelum template mengevaluasi `layout.type()`.
|
|
191
|
+
- Selalu merender frame border.
|
|
192
|
+
- Jika `appearance="border-rail"`, root menambah rail dekoratif di empat sudut frame dan memanjangkan garis sudut itu sampai tepi viewport.
|
|
193
|
+
- Jika `width="container"`, frame dipusatkan mulai breakpoint `lg` dengan container behavior.
|
|
194
|
+
|
|
195
|
+
### `UiLayoutVerticalComponent`
|
|
196
|
+
|
|
197
|
+
Variant layout untuk shell dua kolom: nav di kiri, content di kanan.
|
|
198
|
+
|
|
199
|
+
Selector: `ui-layout-vertical`
|
|
200
|
+
|
|
201
|
+
Inputs:
|
|
202
|
+
|
|
203
|
+
| Input | Type | Default | Deskripsi |
|
|
204
|
+
| ------- | -------- | ------- | ------------------------------------------------- |
|
|
205
|
+
| `class` | `string` | `''` | Menambahkan class pada host `ui-layout-vertical`. |
|
|
206
|
+
|
|
207
|
+
Behavior:
|
|
208
|
+
|
|
209
|
+
- Mengatur `LayoutService.type` menjadi `'vertical'`.
|
|
210
|
+
- Menggunakan grid `grid-cols-[auto_minmax(0,1fr)]`.
|
|
211
|
+
- Dalam mode `border-rail`, host dibuat `overflow-visible` agar rail nav/frame dapat mengekstensi keluar area frame.
|
|
212
|
+
|
|
213
|
+
### `UiLayoutHorizontalComponent`
|
|
214
|
+
|
|
215
|
+
Variant layout untuk shell bertumpuk vertikal: nav di atas, content mengisi sisa tinggi.
|
|
216
|
+
|
|
217
|
+
Selector: `ui-layout-horizontal`
|
|
218
|
+
|
|
219
|
+
Inputs:
|
|
220
|
+
|
|
221
|
+
| Input | Type | Default | Deskripsi |
|
|
222
|
+
| ------- | -------- | ------- | --------------------------------------------------- |
|
|
223
|
+
| `class` | `string` | `''` | Menambahkan class pada host `ui-layout-horizontal`. |
|
|
224
|
+
|
|
225
|
+
Behavior:
|
|
226
|
+
|
|
227
|
+
- Mengatur `LayoutService.type` menjadi `'horizontal'`.
|
|
228
|
+
- Menggunakan flex column untuk menyusun nav dan content.
|
|
229
|
+
- Tidak merender rail nav vertikal khusus.
|
|
230
|
+
|
|
231
|
+
### `UiLayoutEmptyComponent`
|
|
232
|
+
|
|
233
|
+
Variant layout tanpa nav, dipakai untuk halaman yang hanya memiliki satu area konten.
|
|
234
|
+
|
|
235
|
+
Selector: `ui-layout-empty`
|
|
236
|
+
|
|
237
|
+
Inputs:
|
|
238
|
+
|
|
239
|
+
| Input | Type | Default | Deskripsi |
|
|
240
|
+
| ------- | -------- | ------- | ---------------------------------------------- |
|
|
241
|
+
| `class` | `string` | `''` | Menambahkan class pada host `ui-layout-empty`. |
|
|
242
|
+
|
|
243
|
+
Behavior:
|
|
244
|
+
|
|
245
|
+
- Mengatur `LayoutService.type` menjadi `'empty'`.
|
|
246
|
+
- Menyediakan wrapper penuh untuk satu area konten.
|
|
247
|
+
- `ui-layout-nav` akan tersembunyi jika tetap dirender di mode ini.
|
|
248
|
+
|
|
249
|
+
### `UiLayoutNavComponent`
|
|
250
|
+
|
|
251
|
+
Wrapper untuk slot navigasi.
|
|
252
|
+
|
|
253
|
+
Selector: `ui-layout-nav`
|
|
254
|
+
|
|
255
|
+
Inputs:
|
|
256
|
+
|
|
257
|
+
| Input | Type | Default | Deskripsi |
|
|
258
|
+
| ----------- | -------- | --------------------- | ------------------------------------------------ |
|
|
259
|
+
| `ariaLabel` | `string` | `'Layout navigation'` | Label aksesibilitas untuk landmark `navigation`. |
|
|
260
|
+
| `class` | `string` | `''` | Menambahkan class pada host `ui-layout-nav`. |
|
|
261
|
+
|
|
262
|
+
Behavior:
|
|
263
|
+
|
|
264
|
+
- Host selalu memiliki `role="navigation"`.
|
|
265
|
+
- Menambahkan atribut host `data-layout-type`, `data-layout-appearance`, dan `data-layout-style`.
|
|
266
|
+
- Pada layout `horizontal`, nav menggunakan tinggi tetap `h-12`.
|
|
267
|
+
- Pada layout `vertical`, nav menggunakan `w-max max-w-full`, sehingga lebar nav mengikuti isi child.
|
|
268
|
+
- Pada layout `vertical` dengan `appearance="border-rail"`, komponen ini merender rail vertikal di sisi kanan nav, termasuk ekstensinya ke atas dan bawah viewport.
|
|
269
|
+
- Pada layout `empty`, nav disembunyikan.
|
|
270
|
+
|
|
271
|
+
Catatan penggunaan:
|
|
272
|
+
|
|
273
|
+
- Untuk mode `border-rail`, jangan tambahkan `border-r` manual pada konten nav bila yang diinginkan adalah rail bawaan primitive.
|
|
274
|
+
- Styling visual isi nav sebaiknya ditempatkan pada elemen child di dalam `ui-layout-nav`, bukan dengan mengandalkan border host.
|
|
275
|
+
|
|
276
|
+
### `UiLayoutContentComponent`
|
|
277
|
+
|
|
278
|
+
Wrapper untuk area konten utama yang scrollable.
|
|
279
|
+
|
|
280
|
+
Selector: `ui-layout-content`
|
|
281
|
+
|
|
282
|
+
Inputs:
|
|
283
|
+
|
|
284
|
+
| Input | Type | Default | Deskripsi |
|
|
285
|
+
| ------- | -------- | ------- | ------------------------------------------------ |
|
|
286
|
+
| `class` | `string` | `''` | Menambahkan class pada host `ui-layout-content`. |
|
|
287
|
+
|
|
288
|
+
Behavior:
|
|
289
|
+
|
|
290
|
+
- Selalu menggunakan `overflow-auto`.
|
|
291
|
+
- Pada layout `horizontal`, konten memakai `flex-1` agar mengisi sisa tinggi setelah nav.
|
|
292
|
+
- Pada layout `vertical`, konten mengisi tinggi penuh kolom kanan.
|
|
293
|
+
- Pada layout `empty`, konten memakai `h-full w-full`.
|
|
294
|
+
- Jika `LayoutService.width()` adalah `'container'`, konten juga dipusatkan mulai `lg` dengan `lg:container lg:mx-auto`.
|
|
295
|
+
|
|
296
|
+
## Surface API
|
|
297
|
+
|
|
298
|
+
Nilai `surface` yang tersedia berasal dari `UI_LAYOUT_SURFACES`.
|
|
299
|
+
|
|
300
|
+
| Nilai | Efek visual |
|
|
301
|
+
| ------------------- | -------------------------------------------------------------------------- |
|
|
302
|
+
| `'flat'` | Background polos `bg-background`. |
|
|
303
|
+
| `'grid'` | Pola grid tipis dua arah. |
|
|
304
|
+
| `'honeycome'` | Pola radial rapat. Nama API dieja `honeycome` agar sesuai export saat ini. |
|
|
305
|
+
| `'line-vertical'` | Garis vertikal berulang. |
|
|
306
|
+
| `'line-horizontal'` | Garis horizontal berulang. |
|
|
307
|
+
|
|
308
|
+
## Appearance API
|
|
309
|
+
|
|
310
|
+
Nilai `appearance` yang tersedia berasal dari `UI_LAYOUT_STYLES`.
|
|
311
|
+
|
|
312
|
+
| Nilai | Efek visual |
|
|
313
|
+
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
314
|
+
| `'flat'` | Frame tetap memiliki border 1px tanpa rail luar. |
|
|
315
|
+
| `'border-rail'` | Frame memiliki border lebih tebal dan rail dekoratif pada sudut frame; untuk layout vertical, nav juga mendapat rail kanan yang mengekstensi ke atas dan bawah viewport. |
|
|
316
|
+
|
|
317
|
+
Gunakan `appearance` di template Angular. Alias `layout-style` tetap tersedia untuk kompatibilitas template lama. Nilai persisted untuk appearance disimpan dengan key local storage `layout-appearance`.
|
|
318
|
+
|
|
319
|
+
## Width API
|
|
320
|
+
|
|
321
|
+
Nilai `width` yang tersedia berasal dari `UI_LAYOUT_WIDTHS`.
|
|
322
|
+
|
|
323
|
+
| Nilai | Perilaku |
|
|
324
|
+
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
325
|
+
| `'full'` | Root menggunakan padding `p-4`, frame dan content tetap full width. |
|
|
326
|
+
| `'wide'` | Di bawah `lg` tampil seperti `full`, mulai `lg` memakai padding `p-12` di root. |
|
|
327
|
+
| `'container'` | Di bawah `lg` tampil seperti `full`, mulai `lg` root memakai `py-16` tanpa padding horizontal, lalu frame/content dipusatkan dengan container behavior. |
|
|
328
|
+
|
|
329
|
+
Ringkasnya:
|
|
330
|
+
|
|
331
|
+
- `wide` dan `container` sengaja collapse ke tampilan `full` di bawah breakpoint `lg`.
|
|
332
|
+
- Perbedaan utama `container` muncul mulai `lg`, saat frame dan content tidak lagi full bleed secara horizontal.
|
|
333
|
+
|
|
334
|
+
## `LayoutService`
|
|
335
|
+
|
|
336
|
+
Service state kecil untuk menyimpan konteks layout aktif dan persistence ke local storage.
|
|
337
|
+
|
|
338
|
+
Import:
|
|
339
|
+
|
|
340
|
+
```ts
|
|
341
|
+
import { LayoutService } from '@edsis/ui/layout/services';
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Readonly signals:
|
|
345
|
+
|
|
346
|
+
| Properti | Type | Deskripsi |
|
|
347
|
+
| ------------ | ------------------------- | --------------------------------------------------- |
|
|
348
|
+
| `surface` | `Signal<UiLayoutSurface>` | Surface layout aktif. |
|
|
349
|
+
| `type` | `Signal<UiLayoutType>` | Type layout aktif. |
|
|
350
|
+
| `appearance` | `Signal<UiLayoutStyle>` | Appearance layout aktif. |
|
|
351
|
+
| `style` | `Signal<UiLayoutStyle>` | Alias kompatibilitas untuk appearance layout aktif. |
|
|
352
|
+
| `width` | `Signal<UiLayoutWidth>` | Width mode aktif. |
|
|
353
|
+
|
|
354
|
+
Methods:
|
|
355
|
+
|
|
356
|
+
| Method | Signature | Deskripsi |
|
|
357
|
+
| --------------------- | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
358
|
+
| `registerSurface` | `(surface: UiLayoutSurface) => void` | Mendaftarkan fallback `layout-surface` ke local storage hanya jika storage belum memiliki nilai valid. Jika sudah ada nilai valid, service tetap memakai nilai yang tersimpan. |
|
|
359
|
+
| `registerType` | `(type: UiLayoutType) => void` | Mendaftarkan fallback `layout-type` ke local storage hanya jika storage belum memiliki nilai valid. Jika sudah ada nilai valid, service tetap memakai nilai yang tersimpan. |
|
|
360
|
+
| `registerAppearance` | `(appearance: UiLayoutStyle) => void` | Mendaftarkan fallback `layout-appearance` ke local storage hanya jika storage belum memiliki nilai valid. Jika sudah ada nilai valid, service tetap memakai nilai yang tersimpan. |
|
|
361
|
+
| `registerStyle` | `(style: UiLayoutStyle) => void` | Alias kompatibilitas untuk `registerAppearance(...)`. |
|
|
362
|
+
| `registerWidth` | `(width: UiLayoutWidth) => void` | Mendaftarkan fallback `layout-width` ke local storage hanya jika storage belum memiliki nilai valid. Jika sudah ada nilai valid, service tetap memakai nilai yang tersimpan. |
|
|
363
|
+
| `registerDefaults` | `(defaults: { surface?, appearance?, type?, width? }) => this` | Mendaftarkan beberapa fallback sekaligus. Ini adalah API yang direkomendasikan untuk page-level default karena consumer cukup memanggil satu method dan tetap menghormati nilai storage yang sudah valid. |
|
|
364
|
+
| `setSurface` | `(surface: UiLayoutSurface) => void` | Menulis surface ke signal dan local storage. |
|
|
365
|
+
| `setType` | `(type: UiLayoutType) => void` | Menulis type ke signal dan local storage. |
|
|
366
|
+
| `setAppearance` | `(appearance: UiLayoutStyle) => void` | Menulis appearance ke signal dan local storage `layout-appearance`. |
|
|
367
|
+
| `setStyle` | `(style: UiLayoutStyle) => void` | Alias kompatibilitas untuk `setAppearance(...)`. |
|
|
368
|
+
| `setWidth` | `(width: UiLayoutWidth) => void` | Menulis width ke signal dan local storage. |
|
|
369
|
+
| `getStoredSurface` | `() => UiLayoutSurface` | Membaca surface yang valid dari storage atau default. |
|
|
370
|
+
| `getStoredType` | `() => UiLayoutType` | Membaca type yang valid dari storage atau default. |
|
|
371
|
+
| `getStoredAppearance` | `() => UiLayoutStyle` | Membaca appearance yang valid dari storage atau default. |
|
|
372
|
+
| `getStoredStyle` | `() => UiLayoutStyle` | Alias kompatibilitas untuk `getStoredAppearance()`. |
|
|
373
|
+
| `getStoredWidth` | `() => UiLayoutWidth` | Membaca width yang valid dari storage atau default. |
|
|
374
|
+
|
|
375
|
+
Persistence behavior:
|
|
376
|
+
|
|
377
|
+
- Storage key: `layout-surface`, `layout-type`, `layout-appearance`, dan `layout-width`.
|
|
378
|
+
- Default value: `flat`, `vertical`, `flat`, dan `full`.
|
|
379
|
+
- `registerDefaults(...)` adalah API yang direkomendasikan untuk menetapkan default per halaman tanpa menimpa nilai valid yang sudah tersimpan sebelumnya.
|
|
380
|
+
- Method `registerSurface(...)`, `registerType(...)`, `registerAppearance(...)`, dan `registerWidth(...)` tetap tersedia bila consumer memang perlu registrasi yang lebih granular.
|
|
381
|
+
- Legacy storage key `layout-style` masih dibaca untuk kompatibilitas dan akan dibersihkan ketika appearance ditulis ulang ke `layout-appearance`.
|
|
382
|
+
- Aman untuk SSR karena hanya mengakses `localStorage` saat runtime browser tersedia.
|
|
383
|
+
|
|
384
|
+
Contoh penggunaan:
|
|
385
|
+
|
|
386
|
+
```ts
|
|
387
|
+
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
|
388
|
+
import { LayoutService } from '@edsis/ui/layout/services';
|
|
389
|
+
|
|
390
|
+
@Component({
|
|
391
|
+
selector: 'demo-layout-toggle',
|
|
392
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
393
|
+
template: `
|
|
394
|
+
<button type="button" (click)="layout.setAppearance('flat')">Flat</button>
|
|
395
|
+
<button type="button" (click)="layout.setAppearance('border-rail')">Border rail</button>
|
|
396
|
+
`,
|
|
397
|
+
})
|
|
398
|
+
export class DemoLayoutToggleComponent {
|
|
399
|
+
readonly layout = inject(LayoutService);
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## Types, constants, dan guards
|
|
404
|
+
|
|
405
|
+
Seluruh symbol berikut diekspor dari `@edsis/ui/layout/types`.
|
|
406
|
+
|
|
407
|
+
### Types
|
|
408
|
+
|
|
409
|
+
| Symbol | Nilai |
|
|
410
|
+
| ---------------------- | --------------------------------------------------------------------------------------------------------- |
|
|
411
|
+
| `UiLayoutType` | `vertical`, `horizontal`, `empty` |
|
|
412
|
+
| `UiLayoutSurface` | `flat`, `grid`, `honeycome`, `line-vertical`, `line-horizontal` |
|
|
413
|
+
| `UiLayoutStyle` | `flat`, `border-rail` |
|
|
414
|
+
| `UiLayoutWidth` | `full`, `wide`, `container` |
|
|
415
|
+
| `UiLayoutContextValue` | Objekt berbentuk `{ surface, type, appearance, style, width }` yang masing-masing berupa readonly signal. |
|
|
416
|
+
|
|
417
|
+
### Constants
|
|
418
|
+
|
|
419
|
+
| Symbol | Nilai |
|
|
420
|
+
| ---------------------------------- | ------------------------------------------------------------------- |
|
|
421
|
+
| `UI_LAYOUT_TYPES` | `['vertical', 'horizontal', 'empty']` |
|
|
422
|
+
| `UI_LAYOUT_SURFACES` | `['flat', 'grid', 'honeycome', 'line-vertical', 'line-horizontal']` |
|
|
423
|
+
| `UI_LAYOUT_STYLES` | `['flat', 'border-rail']` |
|
|
424
|
+
| `UI_LAYOUT_WIDTHS` | `['full', 'wide', 'container']` |
|
|
425
|
+
| `UI_LAYOUT_DEFAULT_SURFACE` | `'flat'` |
|
|
426
|
+
| `UI_LAYOUT_DEFAULT_TYPE` | `'vertical'` |
|
|
427
|
+
| `UI_LAYOUT_DEFAULT_STYLE` | `'flat'` |
|
|
428
|
+
| `UI_LAYOUT_DEFAULT_WIDTH` | `'full'` |
|
|
429
|
+
| `UI_LAYOUT_SURFACE_STORAGE_KEY` | `'layout-surface'` |
|
|
430
|
+
| `UI_LAYOUT_APPEARANCE_STORAGE_KEY` | `'layout-appearance'` |
|
|
431
|
+
| `UI_LAYOUT_TYPE_STORAGE_KEY` | `'layout-type'` |
|
|
432
|
+
| `UI_LAYOUT_STYLE_STORAGE_KEY` | `'layout-style'` `(legacy compatibility key)` |
|
|
433
|
+
| `UI_LAYOUT_WIDTH_STORAGE_KEY` | `'layout-width'` |
|
|
434
|
+
|
|
435
|
+
### Guards
|
|
436
|
+
|
|
437
|
+
- `isUiLayoutSurface(value: string | null): value is UiLayoutSurface`
|
|
438
|
+
Memvalidasi string terhadap daftar surface yang didukung.
|
|
439
|
+
- `isUiLayoutType(value: string | null): value is UiLayoutType`
|
|
440
|
+
Memvalidasi string terhadap daftar type yang didukung.
|
|
441
|
+
- `isUiLayoutStyle(value: string | null): value is UiLayoutStyle`
|
|
442
|
+
Memvalidasi string terhadap daftar style yang didukung.
|
|
443
|
+
- `isUiLayoutWidth(value: string | null): value is UiLayoutWidth`
|
|
444
|
+
Memvalidasi string terhadap daftar width yang didukung.
|
|
445
|
+
|
|
446
|
+
## Consumer guidance
|
|
447
|
+
|
|
448
|
+
- Gunakan `appearance` di template. `layout-style` dipertahankan hanya untuk kompatibilitas.
|
|
449
|
+
- Untuk halaman yang punya default layout sendiri, utamakan `inject(LayoutService).registerDefaults({...})` sekali di level page daripada memanggil empat method `register...` terpisah.
|
|
450
|
+
- Jika halaman harus merender variant berdasarkan preferensi yang tersimpan, pakai `layout.type()` sebagai sumber branching dan bind root `ui-layout` ke `layout.surface()`, `layout.appearance()`, dan `layout.width()`.
|
|
451
|
+
- Tempatkan scroll page utama di `ui-layout-content`, bukan di root `ui-layout`.
|
|
452
|
+
- Untuk `vertical + border-rail`, biarkan primitive yang merender rail kanan nav; hindari border manual yang menduplikasi garis itu.
|
|
453
|
+
- Semua primitive menerima input `class`, jadi styling tambahan paling aman diberikan lewat class host atau child content.
|
|
454
|
+
- Jika consumer perlu membaca state layout aktif dari komponen lain, inject `LayoutService` dan baca signal readonly-nya.
|
package/nav/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Nav
|
|
2
|
+
|
|
3
|
+
`@edsis/ui/nav` renders input-driven navigation with configurable appearances and instance-aware state.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { UiNavComponent, UiNavFooterComponent, UiNavHeaderComponent, type UiNavItem } from '@edsis/ui/nav';
|
|
7
|
+
import { NavService } from '@edsis/ui/nav/service';
|
|
8
|
+
|
|
9
|
+
const items: UiNavItem[] = [
|
|
10
|
+
{ id: 'dashboard', title: 'Dashboard', link: '/dashboard', icon: 'dashboard' },
|
|
11
|
+
{
|
|
12
|
+
id: 'reports',
|
|
13
|
+
title: 'Reports',
|
|
14
|
+
type: 'collapsible',
|
|
15
|
+
children: [{ id: 'monthly', title: 'Monthly', link: '/reports/monthly' }],
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```html
|
|
21
|
+
<ui-nav id="erp-sidebar" [data]="items" orientation="vertical" appearance="sidebar" class="h-full">
|
|
22
|
+
<ui-nav-header class="px-1" [toggle]="true">
|
|
23
|
+
<div class="text-sm font-semibold">Workspace</div>
|
|
24
|
+
</ui-nav-header>
|
|
25
|
+
|
|
26
|
+
<ui-nav-footer class="p-3">
|
|
27
|
+
<button type="button">Sign out</button>
|
|
28
|
+
</ui-nav-footer>
|
|
29
|
+
</ui-nav>
|
|
30
|
+
|
|
31
|
+
<ui-nav id="erp-topbar" [data]="items" orientation="horizontal" appearance="navbar" />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API Notes
|
|
35
|
+
|
|
36
|
+
- `data` is the preferred source of navigation data.
|
|
37
|
+
- `items` is still accepted as a compatibility alias while consumers migrate.
|
|
38
|
+
- `orientation` accepts `vertical` or `horizontal`.
|
|
39
|
+
- `appearance` depends on `orientation`:
|
|
40
|
+
- vertical: `sidebar` or `dockbar`
|
|
41
|
+
- horizontal: `navbar` or `flyout`
|
|
42
|
+
- `id` identifies a navigation instance so multiple navs can keep distinct service state.
|
|
43
|
+
- `position` accepts `left` or `right` for vertical navigation.
|
|
44
|
+
- `collapsed` controls the icon-only sidebar state.
|
|
45
|
+
- `dockbarMode` accepts `sticky` or `drawer` for vertical `dockbar`.
|
|
46
|
+
- Angular Router is supported for internal links through `link`, `queryParams`, `fragment`, `exactMatch`, and `isActiveMatchOptions`.
|
|
47
|
+
- External links can use `href` or `link` with `externalLink: true`.
|
|
48
|
+
- `openedIds` owns collapsible state and supports two-way binding.
|
|
49
|
+
- `itemSelected` emits for action, router, and external items.
|
|
50
|
+
- `compact` is still supported as a compatibility alias for collapsed vertical sidebars.
|
|
51
|
+
- `ui-nav-header` is optional, accepts Tailwind classes through `class`, and can render a built-in collapse toggle with `[toggle]="true"`.
|
|
52
|
+
- `ui-nav-footer` is optional and accepts Tailwind classes through `class`.
|
|
53
|
+
- `ui-nav-main` is rendered automatically by `ui-nav`, wraps the active navigation renderer, and owns the scrollable region between optional header and footer slots.
|
|
54
|
+
|
|
55
|
+
## Nav Service
|
|
56
|
+
|
|
57
|
+
`@edsis/ui/nav/service` exposes `NavService` as a singleton registry for navigation appearance and overlay state.
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { NavService } from '@edsis/ui/nav/service';
|
|
61
|
+
|
|
62
|
+
const nav = inject(NavService);
|
|
63
|
+
|
|
64
|
+
nav.setAppearance('erp-sidebar', 'dockbar');
|
|
65
|
+
nav.setCollapsed('erp-sidebar', true);
|
|
66
|
+
nav.toggleCollapsed('erp-sidebar');
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Service defaults are stored in `localStorage` under:
|
|
70
|
+
|
|
71
|
+
- `nav-vertical-appearance`
|
|
72
|
+
- `nav-horizontal-appearance`
|
|
73
|
+
|
|
74
|
+
Instance preferences are stored under:
|
|
75
|
+
|
|
76
|
+
- `nav:{id}:orientation`
|
|
77
|
+
- `nav:{id}:appearance`
|
|
78
|
+
- `nav:{id}:position`
|
|
79
|
+
- `nav:{id}:collapsed`
|
|
80
|
+
- `nav:{id}:dockbar-mode`
|
|
81
|
+
|
|
82
|
+
## Icons
|
|
83
|
+
|
|
84
|
+
`ui-nav` does not load icon fonts or depend on an icon package. Pass an optional icon template when you need custom rendering.
|
|
85
|
+
|
|
86
|
+
```html
|
|
87
|
+
<ui-nav [items]="items">
|
|
88
|
+
<ng-template uiNavIcon let-icon>
|
|
89
|
+
<span class="material-symbols-outlined" aria-hidden="true">{{ icon }}</span>
|
|
90
|
+
</ng-template>
|
|
91
|
+
</ui-nav>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Boundaries
|
|
95
|
+
|
|
96
|
+
This entry point must stay consumer-agnostic. Layout and theme composition belong to the consumer layer, while nav appearance defaults, instance registration, and overlay state now live inside `NavService`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edsis/ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/edsis/angular.git"
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
},
|
|
12
12
|
"peerDependencies": {
|
|
13
13
|
"@angular/common": "^21.2.0",
|
|
14
|
-
"@angular/core": "^21.2.0"
|
|
14
|
+
"@angular/core": "^21.2.0",
|
|
15
|
+
"@angular/router": "^21.2.0"
|
|
15
16
|
},
|
|
16
17
|
"dependencies": {
|
|
17
18
|
"@types/d3-array": "^3.2.2",
|
|
@@ -201,6 +202,18 @@
|
|
|
201
202
|
"types": "./types/edsis-ui-label.d.ts",
|
|
202
203
|
"default": "./fesm2022/edsis-ui-label.mjs"
|
|
203
204
|
},
|
|
205
|
+
"./layout": {
|
|
206
|
+
"types": "./types/edsis-ui-layout.d.ts",
|
|
207
|
+
"default": "./fesm2022/edsis-ui-layout.mjs"
|
|
208
|
+
},
|
|
209
|
+
"./layout/services": {
|
|
210
|
+
"types": "./types/edsis-ui-layout-services.d.ts",
|
|
211
|
+
"default": "./fesm2022/edsis-ui-layout-services.mjs"
|
|
212
|
+
},
|
|
213
|
+
"./layout/types": {
|
|
214
|
+
"types": "./types/edsis-ui-layout-types.d.ts",
|
|
215
|
+
"default": "./fesm2022/edsis-ui-layout-types.mjs"
|
|
216
|
+
},
|
|
204
217
|
"./menubar": {
|
|
205
218
|
"types": "./types/edsis-ui-menubar.d.ts",
|
|
206
219
|
"default": "./fesm2022/edsis-ui-menubar.mjs"
|
|
@@ -209,10 +222,22 @@
|
|
|
209
222
|
"types": "./types/edsis-ui-native-select.d.ts",
|
|
210
223
|
"default": "./fesm2022/edsis-ui-native-select.mjs"
|
|
211
224
|
},
|
|
225
|
+
"./nav": {
|
|
226
|
+
"types": "./types/edsis-ui-nav.d.ts",
|
|
227
|
+
"default": "./fesm2022/edsis-ui-nav.mjs"
|
|
228
|
+
},
|
|
229
|
+
"./nav/service": {
|
|
230
|
+
"types": "./types/edsis-ui-nav-service.d.ts",
|
|
231
|
+
"default": "./fesm2022/edsis-ui-nav-service.mjs"
|
|
232
|
+
},
|
|
212
233
|
"./navigation-menu": {
|
|
213
234
|
"types": "./types/edsis-ui-navigation-menu.d.ts",
|
|
214
235
|
"default": "./fesm2022/edsis-ui-navigation-menu.mjs"
|
|
215
236
|
},
|
|
237
|
+
"./page": {
|
|
238
|
+
"types": "./types/edsis-ui-page.d.ts",
|
|
239
|
+
"default": "./fesm2022/edsis-ui-page.mjs"
|
|
240
|
+
},
|
|
216
241
|
"./pagination": {
|
|
217
242
|
"types": "./types/edsis-ui-pagination.d.ts",
|
|
218
243
|
"default": "./fesm2022/edsis-ui-pagination.mjs"
|
|
@@ -281,6 +306,10 @@
|
|
|
281
306
|
"types": "./types/edsis-ui-textarea.d.ts",
|
|
282
307
|
"default": "./fesm2022/edsis-ui-textarea.mjs"
|
|
283
308
|
},
|
|
309
|
+
"./theme": {
|
|
310
|
+
"types": "./types/edsis-ui-theme.d.ts",
|
|
311
|
+
"default": "./fesm2022/edsis-ui-theme.mjs"
|
|
312
|
+
},
|
|
284
313
|
"./timeline": {
|
|
285
314
|
"types": "./types/edsis-ui-timeline.d.ts",
|
|
286
315
|
"default": "./fesm2022/edsis-ui-timeline.mjs"
|
package/page/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# @edsis/ui/page
|
|
2
|
+
|
|
3
|
+
Primitive page shell untuk layout halaman dengan pendekatan nested component.
|
|
4
|
+
|
|
5
|
+
## Components
|
|
6
|
+
|
|
7
|
+
- `ui-page`
|
|
8
|
+
- `ui-page-header`
|
|
9
|
+
- `ui-page-content`
|
|
10
|
+
- `ui-page-footer`
|
|
11
|
+
- `ui-page-side`
|
|
12
|
+
- `ui-page-side-toggle`
|
|
13
|
+
|
|
14
|
+
`ui-page-side-toggle` menerima projected content untuk label atau ikon kustom. Jika tidak ada projected content, komponen akan memakai ikon fallback bawaan.
|
|
15
|
+
|
|
16
|
+
## Variants
|
|
17
|
+
|
|
18
|
+
- `stacked`
|
|
19
|
+
- `side`
|
|
20
|
+
|
|
21
|
+
## Side Modes
|
|
22
|
+
|
|
23
|
+
- `sticky`
|
|
24
|
+
- `drawer`
|
|
25
|
+
- `overlay`
|
|
26
|
+
|
|
27
|
+
## Example
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<ui-page variant="side" position="left">
|
|
31
|
+
<ui-page-header>
|
|
32
|
+
<ui-page-side-toggle ariaLabel="Toggle side">
|
|
33
|
+
<span>Open filters</span>
|
|
34
|
+
</ui-page-side-toggle>
|
|
35
|
+
<h1>Page title</h1>
|
|
36
|
+
</ui-page-header>
|
|
37
|
+
|
|
38
|
+
<ui-page-side mode="overlay">
|
|
39
|
+
<p>Filters</p>
|
|
40
|
+
</ui-page-side>
|
|
41
|
+
|
|
42
|
+
<ui-page-content>
|
|
43
|
+
<p>Main content</p>
|
|
44
|
+
</ui-page-content>
|
|
45
|
+
</ui-page>
|
|
46
|
+
```
|