@ojiepermana/angular-theme 22.0.36 → 22.0.41
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/README.md +25 -12
- package/fesm2022/ojiepermana-angular-theme-layout-wrapper.mjs +72 -22
- package/fesm2022/ojiepermana-angular-theme-layout.mjs +14 -2
- package/fesm2022/ojiepermana-angular-theme-page.mjs +251 -101
- package/fesm2022/ojiepermana-angular-theme-styles.mjs +19 -0
- package/layout/README.md +21 -19
- package/package.json +3 -3
- package/page/README.md +53 -15
- package/styles/README.md +11 -3
- package/styles/css/base/theme.css +26 -46
- package/styles/css/base/tokens.css +46 -38
- package/styles/css/color/amber.css +2 -0
- package/styles/css/color/blue.css +2 -0
- package/styles/css/color/cyan.css +2 -0
- package/styles/css/color/emerald.css +2 -0
- package/styles/css/color/fuchsia.css +2 -0
- package/styles/css/color/green.css +2 -0
- package/styles/css/color/indigo.css +2 -0
- package/styles/css/color/lime.css +2 -0
- package/styles/css/color/orange.css +2 -0
- package/styles/css/color/pink.css +2 -0
- package/styles/css/color/purple.css +2 -0
- package/styles/css/color/red.css +2 -0
- package/styles/css/color/rose.css +2 -0
- package/styles/css/color/sky.css +2 -0
- package/styles/css/color/teal.css +2 -0
- package/styles/css/color/violet.css +2 -0
- package/styles/css/color/yellow.css +2 -0
- package/styles/css/neutral/gray.css +2 -0
- package/styles/css/neutral/mauve.css +2 -0
- package/styles/css/neutral/mist.css +2 -0
- package/styles/css/neutral/neutral.css +2 -0
- package/styles/css/neutral/olive.css +2 -0
- package/styles/css/neutral/slate.css +2 -0
- package/styles/css/neutral/stone.css +2 -0
- package/styles/css/neutral/taupe.css +2 -0
- package/styles/css/neutral/zinc.css +2 -0
- package/types/ojiepermana-angular-theme-layout-wrapper.d.ts +39 -6
- package/types/ojiepermana-angular-theme-layout.d.ts +1 -0
- package/types/ojiepermana-angular-theme-page.d.ts +88 -36
- package/types/ojiepermana-angular-theme-styles.d.ts +1 -0
package/layout/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @ojiepermana/angular-theme/layout
|
|
2
2
|
|
|
3
|
-
Primitive layout projection untuk menyusun shell UI dengan satu root `Layout`, satu variant layout (`vertical`, `horizontal`, `empty`, atau `fluid`), slot `
|
|
3
|
+
Primitive layout projection untuk menyusun shell UI dengan satu root `Layout`, satu variant layout (`vertical`, `horizontal`, `empty`, atau `fluid`), slot `LayoutNavigation`, dan area `LayoutContent` yang menjadi scroll container utama.
|
|
4
4
|
|
|
5
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
6
|
|
|
@@ -65,17 +65,17 @@ Struktur yang direkomendasikan adalah sebagai berikut.
|
|
|
65
65
|
|
|
66
66
|
```html
|
|
67
67
|
<Layout>
|
|
68
|
-
<LayoutVertical |
|
|
68
|
+
<LayoutVertical | LayoutHorizontal | LayoutEmpty | LayoutFluid>
|
|
69
69
|
<LayoutNavigation>...</LayoutNavigation>
|
|
70
70
|
<LayoutContent>...</LayoutContent>
|
|
71
|
-
</
|
|
71
|
+
</LayoutVertical | LayoutHorizontal | LayoutEmpty | LayoutFluid>
|
|
72
72
|
</Layout>
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
Aturan penggunaannya:
|
|
76
76
|
|
|
77
77
|
- Gunakan tepat satu variant layout di dalam `Layout`.
|
|
78
|
-
- Untuk layout `vertical` dan `horizontal`, urutan child yang umum adalah `
|
|
78
|
+
- Untuk layout `vertical` dan `horizontal`, urutan child yang umum adalah `LayoutNavigation` lalu `LayoutContent`.
|
|
79
79
|
- Untuk layout `empty`, biasanya cukup `LayoutContent`.
|
|
80
80
|
- Untuk layout `fluid`, child dapat berupa konten page tunggal yang ingin dipusatkan terhadap frame.
|
|
81
81
|
- `LayoutContent` adalah area yang memiliki `overflow-auto`, jadi konten utama sebaiknya ditempatkan di sana.
|
|
@@ -194,13 +194,14 @@ Selector: `Layout`
|
|
|
194
194
|
|
|
195
195
|
Inputs:
|
|
196
196
|
|
|
197
|
-
| Input | Type | Default | Deskripsi
|
|
198
|
-
| ------------------- | -------------------------- | -------- |
|
|
199
|
-
| `surface` | `LayoutSurface` | `'flat'` | Menentukan fallback background root layout. Jika local storage `layout-surface` berisi nilai valid, nilai storage yang dipakai.
|
|
200
|
-
| `appearance` | `LayoutAppearance or null` | `null` | API template untuk menentukan fallback appearance frame. Jika input ini kosong, primitive mencoba alias `layout-appearance`, lalu fallback efektif akhirnya `flat`.
|
|
201
|
-
| `layout-appearance` | `LayoutAppearance or null` | `null` | Alias simetris dengan `nav-appearance` pada navigation (kosakata sama `flat \| border-rail`). Memberi `appearance` yang sama ke shell & nav membuat keduanya seragam.
|
|
202
|
-
| `width` | `LayoutWidth` | `'full'` | Menentukan fallback padding outer dan perilaku container frame. Jika local storage `layout-width` berisi nilai valid, nilai storage yang dipakai.
|
|
203
|
-
| `
|
|
197
|
+
| Input | Type | Default | Deskripsi |
|
|
198
|
+
| ------------------- | -------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
199
|
+
| `surface` | `LayoutSurface` | `'flat'` | Menentukan fallback background root layout. Jika local storage `layout-surface` berisi nilai valid, nilai storage yang dipakai. |
|
|
200
|
+
| `appearance` | `LayoutAppearance or null` | `null` | API template untuk menentukan fallback appearance frame. Jika input ini kosong, primitive mencoba alias `layout-appearance`, lalu fallback efektif akhirnya `flat`. |
|
|
201
|
+
| `layout-appearance` | `LayoutAppearance or null` | `null` | Alias simetris dengan `nav-appearance` pada navigation (kosakata sama `flat \| border-rail`). Memberi `appearance` yang sama ke shell & nav membuat keduanya seragam. |
|
|
202
|
+
| `width` | `LayoutWidth` | `'full'` | Menentukan fallback padding outer dan perilaku container frame. Jika local storage `layout-width` berisi nilai valid, nilai storage yang dipakai. |
|
|
203
|
+
| `layout-type` | `LayoutType or null` | `null` | Override eksplisit type aktif (`vertical \| horizontal \| empty \| fluid`). Jika di-set, menjadi sumber kebenaran type dan menimpa variant `Layout*`. Jika `null`, variant yang menetapkan. |
|
|
204
|
+
| `class` | `string` | `''` | Menambahkan class pada host `Layout`. |
|
|
204
205
|
|
|
205
206
|
Behavior:
|
|
206
207
|
|
|
@@ -208,7 +209,7 @@ Behavior:
|
|
|
208
209
|
- Jika input manual kosong, primitive mendaftarkan default `surface`, `appearance`, dan `width` ke `LayoutService` hanya saat local storage belum memiliki nilai valid.
|
|
209
210
|
- Nilai visual final selalu dibaca kembali dari `LayoutService`, sehingga child primitive tetap membaca state yang sama selama instance aktif.
|
|
210
211
|
- Menambahkan atribut host `data-surface`, `data-layout-appearance`, `data-layout-width`, dan `data-layout-type`.
|
|
211
|
-
- Root
|
|
212
|
+
- Root menyediakan input opsional `layout-type`. Bila di-set, input ini menjadi sumber kebenaran type aktif dan menimpa variant layout yang dirender (override in-memory tanpa menulis `localStorage`). Bila `null`, type aktif dikendalikan oleh variant layout yang dirender, atau oleh consumer melalui `LayoutService.registerDefaults({ type })` sebelum template mengevaluasi `layout.type()`.
|
|
212
213
|
- Selalu merender frame border.
|
|
213
214
|
- Jika `appearance="border-rail"`, root menambah rail dekoratif di empat sudut frame, rail inset horizontal, dan rail vertikal sekunder di luar sisi kiri-kanan frame sehingga frame terlihat seperti memiliki double rail.
|
|
214
215
|
- Jika `width="container"`, frame dipusatkan mulai breakpoint `lg` dengan container behavior.
|
|
@@ -266,20 +267,21 @@ Behavior:
|
|
|
266
267
|
|
|
267
268
|
- Mengatur `LayoutService.type` menjadi `'empty'` hanya untuk state aktif dan tidak menulis `localStorage`.
|
|
268
269
|
- Menyediakan wrapper penuh untuk satu area konten.
|
|
269
|
-
- `
|
|
270
|
+
- `LayoutNavigation` akan tersembunyi jika tetap dirender di mode ini.
|
|
270
271
|
|
|
271
272
|
### `LayoutNavigationComponent`
|
|
272
273
|
|
|
273
274
|
Wrapper untuk slot navigasi.
|
|
274
275
|
|
|
275
|
-
Selector: `
|
|
276
|
+
Selector: `LayoutNavigation`
|
|
276
277
|
|
|
277
278
|
Inputs:
|
|
278
279
|
|
|
279
|
-
| Input
|
|
280
|
-
|
|
|
281
|
-
| `ariaLabel`
|
|
282
|
-
| `
|
|
280
|
+
| Input | Type | Default | Deskripsi |
|
|
281
|
+
| ------------ | ---------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
282
|
+
| `ariaLabel` | `string` | `'Layout navigation'` | Label aksesibilitas untuk landmark `navigation`. |
|
|
283
|
+
| `railOffset` | `string \| null` | `null` | Override offset rail vertikal nav (mode `vertical + border-rail`). Jika `null`, mengikuti preview rail offset dari nav yang diproyeksikan. |
|
|
284
|
+
| `class` | `string` | `''` | Menambahkan class pada host `LayoutNavigation`. |
|
|
283
285
|
|
|
284
286
|
Behavior:
|
|
285
287
|
|
|
@@ -293,7 +295,7 @@ Behavior:
|
|
|
293
295
|
Catatan penggunaan:
|
|
294
296
|
|
|
295
297
|
- Untuk mode `border-rail`, jangan tambahkan `border-r` manual pada konten nav bila yang diinginkan adalah rail bawaan primitive.
|
|
296
|
-
- Styling visual isi nav sebaiknya ditempatkan pada elemen child di dalam `
|
|
298
|
+
- Styling visual isi nav sebaiknya ditempatkan pada elemen child di dalam `LayoutNavigation`, bukan dengan mengandalkan border host.
|
|
297
299
|
|
|
298
300
|
### `LayoutContentComponent`
|
|
299
301
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ojiepermana/angular-theme",
|
|
3
|
-
"version": "22.0.
|
|
3
|
+
"version": "22.0.41",
|
|
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.
|
|
17
|
-
"@ojiepermana/angular-component": "^22.0.
|
|
16
|
+
"@ojiepermana/angular-navigation": "^22.0.41",
|
|
17
|
+
"@ojiepermana/angular-component": "^22.0.41",
|
|
18
18
|
"rxjs": ">=7.8.0"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
package/page/README.md
CHANGED
|
@@ -21,22 +21,48 @@ Dokumentasi ini mengikuti API publik terbaru dari `@ojiepermana/angular-theme/pa
|
|
|
21
21
|
|
|
22
22
|
### `Page`
|
|
23
23
|
|
|
24
|
-
| Input
|
|
25
|
-
|
|
|
26
|
-
| `variant`
|
|
27
|
-
| `scroll`
|
|
28
|
-
| `height`
|
|
29
|
-
| `
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
24
|
+
| Input | Type | Default | Keterangan |
|
|
25
|
+
| ------------ | ----------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
26
|
+
| `variant` | `'stacked' \| 'side'` | `'stacked'` | Menentukan struktur utama page shell. |
|
|
27
|
+
| `scroll` | `'content' \| 'page'` | `'content'` | Menentukan apakah body slot scroll sendiri atau seluruh root `Page` scroll bersama. |
|
|
28
|
+
| `height` | `'auto' \| 'fix'` | `'auto'` | Mengontrol tinggi `PageHeader` dan `PageFooter`. |
|
|
29
|
+
| `appearance` | `'flat' \| 'border-rail'` | `'flat'` | Appearance visual yang dibagi dengan layout/navigation; menyeragamkan border header/footer (`border-rail` = 1.5px). |
|
|
30
|
+
| `position` | `'left' \| 'right'` | `'left'` | Posisi default untuk `PageSide` jika side tidak memberi override sendiri. |
|
|
31
|
+
| `sideMode` | `'sticky' \| 'drawer' \| 'overlay'` | `'sticky'` | Mode default untuk `PageSide` jika side tidak memberi override sendiri. |
|
|
32
|
+
| `sideWidth` | `string` | `'16rem'` | Lebar default side rail; dipakai juga untuk drawer dan overlay. |
|
|
33
|
+
| `sideOpen` | `boolean \| null` | `null` | Saat `null`, state side tidak dikontrol dari parent. Saat `true/false`, komponen masuk controlled mode. |
|
|
34
|
+
| `class` | `string` | `''` | Class tambahan pada host `Page`. |
|
|
34
35
|
|
|
35
36
|
| Output | Payload | Keterangan |
|
|
36
37
|
| ---------------- | --------- | -------------------------------------------------------------------------------------------- |
|
|
37
38
|
| `sideOpenChange` | `boolean` | Emit setiap ada permintaan buka/tutup side, baik dari toggle, backdrop, maupun tombol `Esc`. |
|
|
38
39
|
|
|
39
|
-
`Page` juga menambahkan atribut host `data-page-variant`, `data-page-height`, `data-page-scroll`, `data-page-position`, `data-page-side-mode`, dan `data-page-side-open` untuk styling atau inspeksi.
|
|
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.
|
|
41
|
+
|
|
42
|
+
### Apps launcher (layout `empty`)
|
|
43
|
+
|
|
44
|
+
Saat `Page` dirender di dalam layout `empty`, sebuah tombol icon-only tanpa border (ikon `apps`) muncul **otomatis** di pojok kanan-atas dan membuka **main navigation** (`id="main"`) sebagai flyout. Penempatannya menyesuaikan struktur `Page`:
|
|
45
|
+
|
|
46
|
+
- Ada `PageHeader` → tombol menyatu di kanan header.
|
|
47
|
+
- Tanpa `PageHeader` (mis. hanya `PageDashboard`) → tombol mengambang di atas konten.
|
|
48
|
+
|
|
49
|
+
Tombol hanya muncul ketika layout aktif `empty` dan nav target punya data. Di layout lain (`vertical`/`horizontal`/`fluid`) tombol tidak dirender karena navigasi utama sudah terlihat.
|
|
50
|
+
|
|
51
|
+
| Input | Type | Default | Keterangan |
|
|
52
|
+
| -------------- | --------- | ------------------- | ------------------------------------------------------------ |
|
|
53
|
+
| `appsLauncher` | `boolean` | `true` | Aktif/nonaktifkan apps-launcher pada layout `empty`. |
|
|
54
|
+
| `appsNavId` | `string` | `'main'` | Id navigasi yang disurface oleh apps-launcher. |
|
|
55
|
+
| `appsIcon` | `string` | `'apps'` | Nama ikon Material untuk tombol. |
|
|
56
|
+
| `appsLabel` | `string` | `'Open navigation'` | Label/aria-label tombol icon-only (untuk aksesibilitas AXE). |
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<!-- Dashboard tanpa header: tombol apps mengambang di kanan-atas saat layout empty. -->
|
|
60
|
+
<Page variant="stacked">
|
|
61
|
+
<PageDashboard>
|
|
62
|
+
<p>Konten dashboard.</p>
|
|
63
|
+
</PageDashboard>
|
|
64
|
+
</Page>
|
|
65
|
+
```
|
|
40
66
|
|
|
41
67
|
## Slot API
|
|
42
68
|
|
|
@@ -63,7 +89,7 @@ Dokumentasi ini mengikuti API publik terbaru dari `@ojiepermana/angular-theme/pa
|
|
|
63
89
|
|
|
64
90
|
| Input / Output | Type | Default | Keterangan |
|
|
65
91
|
| -------------- | --------- | -------------------- | ----------------------------------------------------------- |
|
|
66
|
-
| `ariaLabel` | `string` | `'Toggle
|
|
92
|
+
| `ariaLabel` | `string` | `'Toggle page side'` | Label aksesibilitas untuk tombol toggle. |
|
|
67
93
|
| `class` | `string` | `''` | Class tambahan pada host toggle. |
|
|
68
94
|
| `toggled` | `boolean` | - | Emit nilai open state terbaru setelah tombol toggle diklik. |
|
|
69
95
|
|
|
@@ -75,7 +101,7 @@ Dokumentasi ini mengikuti API publik terbaru dari `@ojiepermana/angular-theme/pa
|
|
|
75
101
|
## Scroll Modes
|
|
76
102
|
|
|
77
103
|
- `content` (default): `PageContent` atau `PageDashboard` menjadi area scroll. Pada variant `side`, `PageSide` dan body slot yang dipakai sama-sama stretch ke parent dan masing-masing punya scroll sendiri.
|
|
78
|
-
- `
|
|
104
|
+
- `page`: seluruh isi `Page` menjadi area scroll. Header, content, footer, dan pada variant `side` juga `PageSide` akan mengikuti tinggi content induk tanpa scroll internal.
|
|
79
105
|
|
|
80
106
|
## Height Modes
|
|
81
107
|
|
|
@@ -86,7 +112,7 @@ Dalam mode `fix`, pastikan isi header/footer memang dirancang sebagai rail ringk
|
|
|
86
112
|
|
|
87
113
|
## Behavior Summary
|
|
88
114
|
|
|
89
|
-
| Variant | `scroll="content"` | `scroll="
|
|
115
|
+
| Variant | `scroll="content"` | `scroll="page"` |
|
|
90
116
|
| --------- | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
91
117
|
| `stacked` | `PageContent` atau `PageDashboard` stretch ke tinggi yang tersedia dan menjadi area scroll | seluruh `Page` scroll bersama; header, content, footer ikut satu kanvas |
|
|
92
118
|
| `side` | `PageSide` dan body slot (`PageContent`/`PageDashboard`) sama-sama stretch ke parent dan punya scroll sendiri | `PageSide` dan body slot mengikuti tinggi content induk tanpa scroll internal |
|
|
@@ -126,6 +152,18 @@ Saat memakai `height="fix"`, slot berikut tidak boleh melebihi tinggi tetap yang
|
|
|
126
152
|
|
|
127
153
|
### Stacked dashboard surface
|
|
128
154
|
|
|
155
|
+
`PageDashboard` berdiri sendiri — tidak memerlukan `PageHeader` maupun `PageFooter`. Gunakan slot ini ketika area utama secara semantik adalah dashboard atau board analitik.
|
|
156
|
+
|
|
157
|
+
```html
|
|
158
|
+
<Page variant="stacked">
|
|
159
|
+
<PageDashboard>
|
|
160
|
+
<p>Gunakan slot ini ketika area utama secara semantik adalah dashboard atau board analitik.</p>
|
|
161
|
+
</PageDashboard>
|
|
162
|
+
</Page>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`PageHeader` dan `PageFooter` tetap opsional bila memang dibutuhkan:
|
|
166
|
+
|
|
129
167
|
```html
|
|
130
168
|
<Page variant="stacked">
|
|
131
169
|
<PageHeader>
|
|
@@ -133,7 +171,7 @@ Saat memakai `height="fix"`, slot berikut tidak boleh melebihi tinggi tetap yang
|
|
|
133
171
|
</PageHeader>
|
|
134
172
|
|
|
135
173
|
<PageDashboard>
|
|
136
|
-
<p>
|
|
174
|
+
<p>Dashboard dengan header dan footer eksplisit.</p>
|
|
137
175
|
</PageDashboard>
|
|
138
176
|
|
|
139
177
|
<PageFooter>
|
package/styles/README.md
CHANGED
|
@@ -12,7 +12,9 @@ export const appConfig = {
|
|
|
12
12
|
mode: 'light',
|
|
13
13
|
color: 'base', // accent: base, red…rose, brand
|
|
14
14
|
neutral: 'base', // gray family: base, slate, gray, zinc, …
|
|
15
|
-
|
|
15
|
+
radius: 'md', // corner radius: none, sm, md, lg, xl, full
|
|
16
|
+
space: 'normal', // spacing density: compact, normal, relaxed, spacious
|
|
17
|
+
brand: '221 83% 53%', // warna brand consumer (HSL triplet, atau { color, foreground })
|
|
16
18
|
}),
|
|
17
19
|
],
|
|
18
20
|
};
|
|
@@ -23,10 +25,16 @@ export const appConfig = {
|
|
|
23
25
|
- `mode` mem-bootstrap `ThemeModeService` dan default mode yang disimpan di storage.
|
|
24
26
|
- `color` mem-bootstrap `ThemeColorService`; accent palette awal (`<html theme-color>`).
|
|
25
27
|
- `neutral` keluarga neutral awal (`<html theme-neutral>`); berkomposisi dengan accent.
|
|
28
|
+
- `radius` mem-bootstrap `ThemeRadiusService`; preset corner radius awal (`<html theme-radius>`).
|
|
29
|
+
Menggerakkan knob `--radius-base` sehingga seluruh skala `--radius-*` dan utility `rounded-*` ikut.
|
|
30
|
+
- `space` mem-bootstrap `ThemeSpaceService`; preset spacing density awal (`<html theme-space>`).
|
|
31
|
+
Menggerakkan knob `--spacing-base` sehingga setiap utility `p-*`/`m-*`/`gap-*`/`w-*`/`h-*` ikut.
|
|
26
32
|
- `brand` mem-bootstrap `ThemeBrandService`; set `--brand` / utility `bg-brand` dan preset
|
|
27
|
-
accent `theme-color='brand'`.
|
|
33
|
+
accent `theme-color='brand'`. Menerima string HSL triplet atau `{ color, foreground }`.
|
|
34
|
+
Bisa diubah runtime via `setBrand()`, persist di storage.
|
|
28
35
|
- `icons.materialSymbols` mengontrol preload stylesheet Material Symbols pada bootstrap aplikasi.
|
|
29
|
-
- Pilihan yang dipersist (`theme-color` / `theme-neutral` / `theme-
|
|
36
|
+
- Pilihan yang dipersist (`theme-color` / `theme-neutral` / `theme-radius` / `theme-space` /
|
|
37
|
+
`theme-brand`) menang atas default.
|
|
30
38
|
|
|
31
39
|
## Default Behavior
|
|
32
40
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
--border-width-base: 1px;
|
|
21
21
|
|
|
22
|
-
--shadow-base: 0 1px 2px hsl(
|
|
22
|
+
--shadow-base: 0 1px 2px hsl(0 0% 3.9% / 0.08);
|
|
23
23
|
|
|
24
24
|
--duration-base: 200ms;
|
|
25
25
|
--ease-base: cubic-bezier(0.4, 0, 0.2, 1);
|
|
@@ -82,10 +82,10 @@
|
|
|
82
82
|
* re-emitted by the Tailwind @theme mapping as var(--theme-shadow-*) in the
|
|
83
83
|
* later `theme` layer, so pointing either alias back at --shadow-* would
|
|
84
84
|
* create a var() cycle that invalidates the whole chain. */
|
|
85
|
-
--shadow-xs-base: 0 1px 1px hsl(
|
|
86
|
-
--shadow-md-base: 0 4px 6px hsl(
|
|
87
|
-
--shadow-lg-base: 0 10px 15px hsl(
|
|
88
|
-
--shadow-xl-base: 0 20px 25px hsl(
|
|
85
|
+
--shadow-xs-base: 0 1px 1px hsl(0 0% 3.9% / 0.05);
|
|
86
|
+
--shadow-md-base: 0 4px 6px hsl(0 0% 3.9% / 0.08);
|
|
87
|
+
--shadow-lg-base: 0 10px 15px hsl(0 0% 3.9% / 0.1);
|
|
88
|
+
--shadow-xl-base: 0 20px 25px hsl(0 0% 3.9% / 0.12);
|
|
89
89
|
--shadow-xs: var(--shadow-xs-base);
|
|
90
90
|
--shadow-sm: var(--shadow-base);
|
|
91
91
|
--shadow-md: var(--shadow-md-base);
|
|
@@ -157,12 +157,15 @@
|
|
|
157
157
|
--timeline-indicator-rose: 349 89% 60%;
|
|
158
158
|
--timeline-indicator-rose-foreground: 0 0% 100%;
|
|
159
159
|
|
|
160
|
-
--layout-grid-line
|
|
160
|
+
/* --layout-grid-line is defined per-mode in base/tokens.css and per-neutral
|
|
161
|
+
* by the generated theme-neutral CSS, so the surface grid keeps constant
|
|
162
|
+
* contrast across every neutral — not just base. Opacity is the global
|
|
163
|
+
* subtlety knob shared by all grid surfaces (grid / honeycome / line-*). */
|
|
161
164
|
--layout-grid-line-opacity: 0.18;
|
|
162
165
|
--layout-grid-dot-opacity: 0.22;
|
|
163
166
|
|
|
164
|
-
--overlay-backdrop:
|
|
165
|
-
--overlay-backdrop-strong:
|
|
167
|
+
--overlay-backdrop: 0 0% 3.9% / 0.5;
|
|
168
|
+
--overlay-backdrop-strong: 0 0% 3.9% / 0.4;
|
|
166
169
|
|
|
167
170
|
--editor-highlight: 48 96% 80%;
|
|
168
171
|
|
|
@@ -187,40 +190,10 @@
|
|
|
187
190
|
:root,
|
|
188
191
|
[data-mode='light'] {
|
|
189
192
|
color-scheme: light;
|
|
190
|
-
|
|
191
|
-
--background: 0 0% 100%;
|
|
192
|
-
--foreground: 240 10% 3.9%;
|
|
193
|
-
|
|
194
|
-
--card: 0 0% 100%;
|
|
195
|
-
--card-foreground: 240 10% 3.9%;
|
|
196
|
-
|
|
197
|
-
--popover: 0 0% 100%;
|
|
198
|
-
--popover-foreground: 240 10% 3.9%;
|
|
199
|
-
|
|
200
|
-
--muted: 240 4.8% 95.9%;
|
|
201
|
-
--muted-foreground: 240 3.8% 46.1%;
|
|
202
|
-
|
|
203
|
-
--border: 240 5.9% 90%;
|
|
204
|
-
--input: 240 5.9% 90%;
|
|
205
193
|
}
|
|
206
194
|
|
|
207
195
|
[data-mode='dark'] {
|
|
208
196
|
color-scheme: dark;
|
|
209
|
-
|
|
210
|
-
--background: 240 10% 3.9%;
|
|
211
|
-
--foreground: 0 0% 98%;
|
|
212
|
-
|
|
213
|
-
--card: 240 10% 3.9%;
|
|
214
|
-
--card-foreground: 0 0% 98%;
|
|
215
|
-
|
|
216
|
-
--popover: 240 10% 3.9%;
|
|
217
|
-
--popover-foreground: 0 0% 98%;
|
|
218
|
-
|
|
219
|
-
--muted: 240 3.7% 15.9%;
|
|
220
|
-
--muted-foreground: 240 5% 64.9%;
|
|
221
|
-
|
|
222
|
-
--border: 240 3.7% 15.9%;
|
|
223
|
-
--input: 240 3.7% 15.9%;
|
|
224
197
|
}
|
|
225
198
|
}
|
|
226
199
|
|
|
@@ -238,11 +211,17 @@
|
|
|
238
211
|
--info: 217 91% 60%;
|
|
239
212
|
--info-foreground: 0 0% 100%;
|
|
240
213
|
|
|
214
|
+
/*
|
|
215
|
+
* Chart series palette. --chart-1 follows the selected accent (--primary)
|
|
216
|
+
* so the primary series always reflects the picked theme color; --chart-2..5
|
|
217
|
+
* mirror the shadcn/ui chart palette for distinguishable supporting series.
|
|
218
|
+
* Each stays overridable per-theme via the --theme-chart-* hook.
|
|
219
|
+
*/
|
|
241
220
|
--chart-1: var(--theme-chart-1, var(--primary));
|
|
242
|
-
--chart-2: var(--theme-chart-2,
|
|
243
|
-
--chart-3: var(--theme-chart-3,
|
|
244
|
-
--chart-4: var(--theme-chart-4,
|
|
245
|
-
--chart-5: var(--theme-chart-5,
|
|
221
|
+
--chart-2: var(--theme-chart-2, 173 58% 39%);
|
|
222
|
+
--chart-3: var(--theme-chart-3, 197 37% 24%);
|
|
223
|
+
--chart-4: var(--theme-chart-4, 43 74% 66%);
|
|
224
|
+
--chart-5: var(--theme-chart-5, 27 87% 67%);
|
|
246
225
|
|
|
247
226
|
--sidebar: var(--card);
|
|
248
227
|
--sidebar-background: var(--sidebar);
|
|
@@ -273,10 +252,11 @@
|
|
|
273
252
|
|
|
274
253
|
--editor-highlight: 48 70% 30%;
|
|
275
254
|
|
|
255
|
+
/* Chart palette (dark) — --chart-1 follows --primary; rest track shadcn/ui. */
|
|
276
256
|
--chart-1: var(--theme-chart-1, var(--primary));
|
|
277
|
-
--chart-2: var(--theme-chart-2,
|
|
278
|
-
--chart-3: var(--theme-chart-3,
|
|
279
|
-
--chart-4: var(--theme-chart-4,
|
|
280
|
-
--chart-5: var(--theme-chart-5,
|
|
257
|
+
--chart-2: var(--theme-chart-2, 160 60% 45%);
|
|
258
|
+
--chart-3: var(--theme-chart-3, 30 80% 55%);
|
|
259
|
+
--chart-4: var(--theme-chart-4, 280 65% 60%);
|
|
260
|
+
--chart-5: var(--theme-chart-5, 340 75% 55%);
|
|
281
261
|
}
|
|
282
262
|
}
|
|
@@ -7,39 +7,44 @@
|
|
|
7
7
|
--highlight-border-alpha: 0.7;
|
|
8
8
|
--highlight-background-alpha: 0.7;
|
|
9
9
|
|
|
10
|
-
--background:
|
|
10
|
+
--background: 0 0% 98%;
|
|
11
11
|
--surface: 0 0% 89.8%;
|
|
12
|
-
--surface-foreground:
|
|
13
|
-
--foreground:
|
|
12
|
+
--surface-foreground: 0 0% 12%;
|
|
13
|
+
--foreground: 0 0% 12%;
|
|
14
14
|
|
|
15
15
|
--card: 0 0% 100%;
|
|
16
|
-
--card-foreground:
|
|
16
|
+
--card-foreground: 0 0% 12%;
|
|
17
17
|
|
|
18
18
|
--popover: 0 0% 100%;
|
|
19
|
-
--popover-foreground:
|
|
19
|
+
--popover-foreground: 0 0% 12%;
|
|
20
20
|
|
|
21
|
-
--muted:
|
|
22
|
-
--muted-foreground:
|
|
21
|
+
--muted: 0 0% 94%;
|
|
22
|
+
--muted-foreground: 0 0% 38%;
|
|
23
23
|
|
|
24
|
-
--border:
|
|
25
|
-
--input:
|
|
24
|
+
--border: 0 0% 82%;
|
|
25
|
+
--input: 0 0% 82%;
|
|
26
|
+
|
|
27
|
+
/* Surface-grid line for the base neutral. Explicit (not var(--border)) so the
|
|
28
|
+
* grid keeps the same ~16-point lightness gap vs --background that every
|
|
29
|
+
* generated neutral targets — base is no longer a special case. */
|
|
30
|
+
--layout-grid-line: 0 0% 82%;
|
|
26
31
|
|
|
27
32
|
/* Base accent = near-black neutral (FluxUI "base"); inverts to near-white in
|
|
28
33
|
* dark mode (see :root[data-mode='dark'] below). Accent palettes
|
|
29
34
|
* (theme-color) override these at higher specificity. */
|
|
30
|
-
--primary:
|
|
35
|
+
--primary: 0 0% 10%;
|
|
31
36
|
--primary-foreground: 0 0% 100%;
|
|
32
|
-
--accent:
|
|
33
|
-
--accent-foreground:
|
|
34
|
-
--secondary:
|
|
35
|
-
--secondary-foreground:
|
|
36
|
-
--ring:
|
|
37
|
+
--accent: 0 0% 95%;
|
|
38
|
+
--accent-foreground: 0 0% 14%;
|
|
39
|
+
--secondary: 0 0% 95%;
|
|
40
|
+
--secondary-foreground: 0 0% 18%;
|
|
41
|
+
--ring: 0 0% 16%;
|
|
37
42
|
|
|
38
43
|
/* Brand identity color — set by the consumer via ThemeBrandService
|
|
39
44
|
* (provideUiTheme({ brand }) or setBrand()). Concrete (not var(--primary))
|
|
40
45
|
* so the theme-color='brand' preset never forms a var() cycle. Defaults to
|
|
41
46
|
* the base accent and inverts in dark mode. */
|
|
42
|
-
--brand:
|
|
47
|
+
--brand: 0 0% 10%;
|
|
43
48
|
--brand-foreground: 0 0% 100%;
|
|
44
49
|
|
|
45
50
|
--radius-base: 0.625rem;
|
|
@@ -53,17 +58,17 @@
|
|
|
53
58
|
* --shadow-* — the Tailwind @theme mapping re-emits
|
|
54
59
|
* --shadow-*: var(--theme-shadow-*) in the later `theme` layer, which
|
|
55
60
|
* turns that into a var() cycle and invalidates both tokens. */
|
|
56
|
-
--shadow-base: 0 1px 0 0 hsl(
|
|
57
|
-
--shadow-md-base: 0 8px 18px -14px hsl(
|
|
58
|
-
--shadow-lg-base: 0 18px 36px -28px hsl(
|
|
59
|
-
--shadow-xl-base: 0 24px 48px -36px hsl(
|
|
61
|
+
--shadow-base: 0 1px 0 0 hsl(0 0% 12% / 0.08);
|
|
62
|
+
--shadow-md-base: 0 8px 18px -14px hsl(0 0% 12% / 0.24);
|
|
63
|
+
--shadow-lg-base: 0 18px 36px -28px hsl(0 0% 12% / 0.34);
|
|
64
|
+
--shadow-xl-base: 0 24px 48px -36px hsl(0 0% 12% / 0.4);
|
|
60
65
|
--shadow-sm: var(--shadow-base);
|
|
61
66
|
--shadow-md: var(--shadow-md-base);
|
|
62
67
|
--shadow-lg: var(--shadow-lg-base);
|
|
63
68
|
--shadow-xl: var(--shadow-xl-base);
|
|
64
69
|
|
|
65
70
|
--theme-shadow-sm: var(--shadow-base);
|
|
66
|
-
--theme-shadow: 0 2px 4px -2px hsl(
|
|
71
|
+
--theme-shadow: 0 2px 4px -2px hsl(0 0% 12% / 0.14);
|
|
67
72
|
--theme-shadow-md: var(--shadow-md-base);
|
|
68
73
|
--theme-shadow-lg: var(--shadow-lg-base);
|
|
69
74
|
--theme-shadow-xl: var(--shadow-xl-base);
|
|
@@ -114,36 +119,39 @@
|
|
|
114
119
|
--highlight-border-alpha: 0.45;
|
|
115
120
|
--highlight-background-alpha: 0.55;
|
|
116
121
|
|
|
117
|
-
--background:
|
|
118
|
-
--surface:
|
|
119
|
-
--surface-foreground:
|
|
120
|
-
--foreground:
|
|
122
|
+
--background: 0 0% 9%;
|
|
123
|
+
--surface: 0 0% 18%;
|
|
124
|
+
--surface-foreground: 0 0% 96%;
|
|
125
|
+
--foreground: 0 0% 96%;
|
|
126
|
+
|
|
127
|
+
--card: 0 0% 11%;
|
|
128
|
+
--card-foreground: 0 0% 96%;
|
|
121
129
|
|
|
122
|
-
--
|
|
123
|
-
--
|
|
130
|
+
--popover: 0 0% 11%;
|
|
131
|
+
--popover-foreground: 0 0% 96%;
|
|
124
132
|
|
|
125
|
-
--
|
|
126
|
-
--
|
|
133
|
+
--muted: 0 0% 18%;
|
|
134
|
+
--muted-foreground: 0 0% 70%;
|
|
127
135
|
|
|
128
|
-
--
|
|
129
|
-
--
|
|
136
|
+
--border: 0 0% 24%;
|
|
137
|
+
--input: 0 0% 24%;
|
|
130
138
|
|
|
131
|
-
|
|
132
|
-
--
|
|
139
|
+
/* Surface-grid line for the base neutral (dark). See light block. */
|
|
140
|
+
--layout-grid-line: 0 0% 24%;
|
|
133
141
|
|
|
134
142
|
/* Base accent inverts: near-white primary on dark. */
|
|
135
143
|
--primary: 0 0% 98%;
|
|
136
|
-
--primary-foreground:
|
|
137
|
-
--accent:
|
|
144
|
+
--primary-foreground: 0 0% 12%;
|
|
145
|
+
--accent: 0 0% 16%;
|
|
138
146
|
--accent-foreground: 0 0% 98%;
|
|
139
|
-
--secondary:
|
|
147
|
+
--secondary: 0 0% 18%;
|
|
140
148
|
--secondary-foreground: 0 0% 96%;
|
|
141
149
|
--ring: 0 0% 85%;
|
|
142
150
|
|
|
143
151
|
--brand: 0 0% 98%;
|
|
144
|
-
--brand-foreground:
|
|
152
|
+
--brand-foreground: 0 0% 12%;
|
|
145
153
|
|
|
146
|
-
--shadow-base: 0 1px 0 0 hsl(
|
|
154
|
+
--shadow-base: 0 1px 0 0 hsl(0 0% 96% / 0.08);
|
|
147
155
|
--shadow-sm: var(--shadow-base);
|
|
148
156
|
--theme-shadow-sm: var(--shadow-base);
|
|
149
157
|
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
--muted-foreground: 38 18% 40%;
|
|
16
16
|
--border: 38 28% 87%;
|
|
17
17
|
--input: 38 28% 87%;
|
|
18
|
+
--layout-grid-line: 38 28% 82%;
|
|
18
19
|
--primary: 38 92% 48%;
|
|
19
20
|
--primary-foreground: 0 0% 12%;
|
|
20
21
|
--accent: 38 55% 94%;
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
--muted-foreground: 38 18% 64%;
|
|
39
40
|
--border: 38 23% 18%;
|
|
40
41
|
--input: 38 23% 18%;
|
|
42
|
+
--layout-grid-line: 38 23% 23%;
|
|
41
43
|
--primary: 38 92% 58%;
|
|
42
44
|
--primary-foreground: 0 0% 10%;
|
|
43
45
|
--accent: 38 46% 18%;
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
--muted-foreground: 221 17% 40%;
|
|
16
16
|
--border: 221 25% 87%;
|
|
17
17
|
--input: 221 25% 87%;
|
|
18
|
+
--layout-grid-line: 221 25% 82%;
|
|
18
19
|
--primary: 221 83% 48%;
|
|
19
20
|
--primary-foreground: 0 0% 100%;
|
|
20
21
|
--accent: 221 50% 94%;
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
--muted-foreground: 221 17% 64%;
|
|
39
40
|
--border: 221 21% 18%;
|
|
40
41
|
--input: 221 21% 18%;
|
|
42
|
+
--layout-grid-line: 221 21% 23%;
|
|
41
43
|
--primary: 221 83% 58%;
|
|
42
44
|
--primary-foreground: 0 0% 100%;
|
|
43
45
|
--accent: 221 42% 18%;
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
--muted-foreground: 191 17% 40%;
|
|
16
16
|
--border: 191 26% 87%;
|
|
17
17
|
--input: 191 26% 87%;
|
|
18
|
+
--layout-grid-line: 191 26% 82%;
|
|
18
19
|
--primary: 191 85% 48%;
|
|
19
20
|
--primary-foreground: 0 0% 100%;
|
|
20
21
|
--accent: 191 51% 94%;
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
--muted-foreground: 191 17% 64%;
|
|
39
40
|
--border: 191 21% 18%;
|
|
40
41
|
--input: 191 21% 18%;
|
|
42
|
+
--layout-grid-line: 191 21% 23%;
|
|
41
43
|
--primary: 191 85% 58%;
|
|
42
44
|
--primary-foreground: 0 0% 100%;
|
|
43
45
|
--accent: 191 43% 18%;
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
--muted-foreground: 160 16% 40%;
|
|
16
16
|
--border: 160 23% 87%;
|
|
17
17
|
--input: 160 23% 87%;
|
|
18
|
+
--layout-grid-line: 160 23% 82%;
|
|
18
19
|
--primary: 160 78% 48%;
|
|
19
20
|
--primary-foreground: 0 0% 100%;
|
|
20
21
|
--accent: 160 47% 94%;
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
--muted-foreground: 160 16% 64%;
|
|
39
40
|
--border: 160 20% 18%;
|
|
40
41
|
--input: 160 20% 18%;
|
|
42
|
+
--layout-grid-line: 160 20% 23%;
|
|
41
43
|
--primary: 160 78% 58%;
|
|
42
44
|
--primary-foreground: 0 0% 100%;
|
|
43
45
|
--accent: 160 39% 18%;
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
--muted-foreground: 292 16% 40%;
|
|
16
16
|
--border: 292 24% 87%;
|
|
17
17
|
--input: 292 24% 87%;
|
|
18
|
+
--layout-grid-line: 292 24% 82%;
|
|
18
19
|
--primary: 292 80% 48%;
|
|
19
20
|
--primary-foreground: 0 0% 100%;
|
|
20
21
|
--accent: 292 48% 94%;
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
--muted-foreground: 292 16% 64%;
|
|
39
40
|
--border: 292 20% 18%;
|
|
40
41
|
--input: 292 20% 18%;
|
|
42
|
+
--layout-grid-line: 292 20% 23%;
|
|
41
43
|
--primary: 292 80% 58%;
|
|
42
44
|
--primary-foreground: 0 0% 100%;
|
|
43
45
|
--accent: 292 40% 18%;
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
--muted-foreground: 142 14% 40%;
|
|
16
16
|
--border: 142 21% 87%;
|
|
17
17
|
--input: 142 21% 87%;
|
|
18
|
+
--layout-grid-line: 142 21% 82%;
|
|
18
19
|
--primary: 142 69% 48%;
|
|
19
20
|
--primary-foreground: 0 0% 100%;
|
|
20
21
|
--accent: 142 41% 94%;
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
--muted-foreground: 142 14% 64%;
|
|
39
40
|
--border: 142 17% 18%;
|
|
40
41
|
--input: 142 17% 18%;
|
|
42
|
+
--layout-grid-line: 142 17% 23%;
|
|
41
43
|
--primary: 142 69% 58%;
|
|
42
44
|
--primary-foreground: 0 0% 100%;
|
|
43
45
|
--accent: 142 35% 18%;
|