@foxeltech/angular-ui 0.7.44 → 0.7.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/components.css +320 -18
  2. package/familjen-grotesk/familjen-grotesk-400-latin-ext.woff2 +0 -0
  3. package/familjen-grotesk/familjen-grotesk-400-latin.woff2 +0 -0
  4. package/familjen-grotesk/familjen-grotesk-400-vietnamese.woff2 +0 -0
  5. package/familjen-grotesk/familjen-grotesk-500-latin-ext.woff2 +0 -0
  6. package/familjen-grotesk/familjen-grotesk-500-latin.woff2 +0 -0
  7. package/familjen-grotesk/familjen-grotesk-500-vietnamese.woff2 +0 -0
  8. package/familjen-grotesk/familjen-grotesk-600-latin-ext.woff2 +0 -0
  9. package/familjen-grotesk/familjen-grotesk-600-latin.woff2 +0 -0
  10. package/familjen-grotesk/familjen-grotesk-600-vietnamese.woff2 +0 -0
  11. package/familjen-grotesk/familjen-grotesk-700-latin-ext.woff2 +0 -0
  12. package/familjen-grotesk/familjen-grotesk-700-latin.woff2 +0 -0
  13. package/familjen-grotesk/familjen-grotesk-700-vietnamese.woff2 +0 -0
  14. package/fesm2022/foxeltech-angular-ui-chart.mjs +197 -24
  15. package/fesm2022/foxeltech-angular-ui-chart.mjs.map +1 -1
  16. package/fesm2022/foxeltech-angular-ui.mjs +504 -108
  17. package/fesm2022/foxeltech-angular-ui.mjs.map +1 -1
  18. package/fonts.css +104 -3
  19. package/package.json +1 -1
  20. package/src/lib/styles/components.css +320 -18
  21. package/src/lib/styles/fonts.css +104 -3
  22. package/src/lib/styles/tailwind.css +12 -0
  23. package/src/lib/styles/theme.css +160 -114
  24. package/src/lib/styles/tokens.css +25 -0
  25. package/src/lib/styles/utilities.css +12 -0
  26. package/src/lib/ui/components/button/button.component.html +2 -0
  27. package/src/lib/ui/components/drawer/drawer.component.scss +3 -1
  28. package/src/lib/ui/components/facets-rail/facets-rail.component.html +1 -6
  29. package/src/lib/ui/components/master-detail/master-detail.component.css +65 -13
  30. package/src/lib/ui/components/master-detail/master-detail.component.html +26 -8
  31. package/src/lib/ui/components/route-skeleton/route-skeleton.component.css +38 -0
  32. package/src/lib/ui/components/route-skeleton/route-skeleton.component.html +184 -0
  33. package/src/lib/ui/components/section-card/section-card.component.html +1 -5
  34. package/src/lib/ui/components/skeleton-dashboard/skeleton-dashboard.component.html +24 -0
  35. package/src/lib/ui/components/skeleton-detail/skeleton-detail.component.html +8 -8
  36. package/src/lib/ui/components/skeleton-facets/skeleton-facets.component.html +15 -0
  37. package/src/lib/ui/components/skeleton-frame/skeleton-frame.component.html +59 -0
  38. package/src/lib/ui/components/skeleton-list/skeleton-list.component.html +6 -6
  39. package/src/lib/ui/components/switch/switch.component.html +1 -1
  40. package/src/lib/ui/components/toast/toast.component.html +6 -6
  41. package/tailwind.css +12 -0
  42. package/theme.css +160 -114
  43. package/tokens.css +25 -0
  44. package/types/foxeltech-angular-ui-chart.d.ts +76 -1
  45. package/types/foxeltech-angular-ui.d.ts +278 -33
  46. package/utilities.css +12 -0
  47. package/src/lib/ui/components/skeleton-table-loading/skeleton-table-loading.component.html +0 -21
  48. package/src/lib/ui/components/skeleton-table-loading/skeleton-table-loading.component.scss +0 -0
  49. package/src/lib/ui/components/tab-component/tab.component.html +0 -1
@@ -1,17 +1,33 @@
1
- <div class="flex flex-col lg:flex-row items-start gap-xl" [style.--fx-md-list-width]="listWidth()">
1
+ <!-- 3 cụm CHUNG chiều cao, mỗi cụm SCROLL RIÊNG (anh Tú chốt 03/09).
2
+ `items-stretch` + chiều cao đặt trên hàng (xem .fx-md-row trong CSS) để
3
+ cả ba pane bằng nhau; mỗi pane là flex-col + min-h-0 và chỉ phần thân
4
+ `overflow-auto flex-1` cuộn — header/filter/paginator đứng yên.
5
+ ⚠️ Hướng hàng + chiều cao do CONTAINER QUERY trong CSS quyết định (theo
6
+ bề rộng của chính hàng), KHÔNG phải `lg:flex-row`. Đừng thêm lại class
7
+ `lg:*` ở đây — `lg` trong lib là 1080px và viewport là proxy sai; xem
8
+ ghi chú đầu master-detail.component.css. -->
9
+ <div
10
+ class="fx-md-row flex flex-col items-stretch gap-xl"
11
+ [style.--fx-md-list-width]="listWidth()"
12
+ [style.--fx-md-pane-h]="paneHeight()"
13
+ >
2
14
  <!-- Facets rail (V2 3-column lookup) — wrapper always rendered so ng-content
3
15
  stays unconditional; hidden when the host projects nothing. -->
4
- <div class="fx-md-facets card-common bg-surface" [class.hidden]="!hasFacets">
5
- <ng-content select="[mdFacets]"></ng-content>
16
+ <div
17
+ class="fx-md-facets card-common bg-surface flex flex-col min-h-0"
18
+ [class.hidden]="!hasFacets"
19
+ >
20
+ <div class="flex-1 min-h-0 overflow-auto pr-xs">
21
+ <ng-content select="[mdFacets]"></ng-content>
22
+ </div>
6
23
  </div>
7
24
 
8
25
  <!-- Master: list pane -->
9
- <div class="fx-md-list card-common">
26
+ <div class="fx-md-list card-common flex flex-col min-h-0">
10
27
  <ng-content select="[mdHeader]"></ng-content>
11
28
  <ng-content select="[mdFilters]"></ng-content>
12
29
  <div
13
- class="flex flex-col gap-normal overflow-auto pr-xs"
14
- [style.maxHeight]="maxListHeight()"
30
+ class="flex flex-col gap-normal overflow-auto pr-xs flex-1 min-h-0"
15
31
  role="listbox"
16
32
  [attr.aria-label]="listLabel() || null"
17
33
  >
@@ -83,7 +99,8 @@
83
99
  </div>
84
100
 
85
101
  <!-- Detail pane -->
86
- <div class="w-full lg:flex-1 min-w-0">
102
+ <div class="fx-md-detail w-full min-w-0 flex flex-col min-h-0">
103
+ <div class="flex-1 min-h-0 overflow-auto">
87
104
  @if (table.selected) {
88
105
  @if (table.detailBusy) {
89
106
  <fx-ui-skeleton-detail [cards]="skeletonCards()"></fx-ui-skeleton-detail>
@@ -94,9 +111,10 @@
94
111
  ></ng-container>
95
112
  }
96
113
  } @else {
97
- <div class="card-common flex items-center justify-center h-[300px]">
114
+ <div class="card-common flex items-center justify-center h-full min-h-[300px]">
98
115
  <fx-ui-empty-state [message]="emptyMessage()"></fx-ui-empty-state>
99
116
  </div>
100
117
  }
118
+ </div>
101
119
  </div>
102
120
  </div>
@@ -0,0 +1,38 @@
1
+ /* Cùng cơ chế với master-detail: hàng 3 cụm quyết định theo BỀ RỘNG CỦA CHÍNH
2
+ NÓ (container query), không theo viewport. Nếu chỗ này còn dùng `lg:` thì
3
+ skeleton và màn thật sẽ lật ở hai ngưỡng khác nhau — xem ghi chú đầu
4
+ master-detail.component.css. */
5
+ :host {
6
+ display: block;
7
+ container-type: inline-size;
8
+ container-name: fx-rs;
9
+ }
10
+
11
+ .fx-rs-row {
12
+ display: flex;
13
+ flex-direction: column;
14
+ gap: var(--spacing-xl, 1.5rem);
15
+ }
16
+
17
+ /* Ngưỡng + bề rộng panes giữ y hệt master-detail để skeleton không nhảy hình
18
+ khi dữ liệu về. */
19
+ @container fx-rs (min-width: 968px) {
20
+ .fx-rs-row {
21
+ flex-direction: row;
22
+ align-items: stretch;
23
+ height: calc(100vh - 300px);
24
+ min-height: 420px;
25
+ }
26
+
27
+ .fx-rs-facets {
28
+ flex: 0 1 230px;
29
+ min-width: 200px;
30
+ max-width: 260px;
31
+ }
32
+
33
+ .fx-rs-list {
34
+ flex: 0 1 420px;
35
+ min-width: 320px;
36
+ max-width: 420px;
37
+ }
38
+ }
@@ -0,0 +1,184 @@
1
+ <div class="w-full flex flex-col gap-xl">
2
+ @for (b of blocks(); track $index) {
3
+ @switch (b.kind) {
4
+ @case ('heading') {
5
+ <div data-fx-skel="heading" class="flex flex-col md:flex-row md:items-start justify-between gap-normal">
6
+ <div class="flex flex-col gap-small">
7
+ <div class="skeleton-load h-7 w-64"></div>
8
+ <div class="skeleton-load h-3 w-32"></div>
9
+ </div>
10
+ @if (items(b, 2).length) {
11
+ <div class="flex items-center gap-normal">
12
+ @for (a of items(b, 2); track a) {
13
+ <div class="skeleton-load h-9 rounded-lg" [class]="a === 0 ? 'w-28' : 'w-32'"></div>
14
+ }
15
+ </div>
16
+ }
17
+ </div>
18
+ }
19
+
20
+ @case ('toolbar') {
21
+ <div data-fx-skel="toolbar" class="flex flex-wrap items-center gap-normal">
22
+ <div class="skeleton-load h-9 w-72 rounded-lg"></div>
23
+ @for (f of items(b, 2); track f) {
24
+ <div class="skeleton-load h-7 rounded-full" [class]="f % 2 ? 'w-24' : 'w-20'"></div>
25
+ }
26
+ </div>
27
+ }
28
+
29
+ @case ('table') {
30
+ <!-- Bảng: mỗi Ô là một `.skeleton-load` riêng, đúng cách
31
+ `fx-ui-table-cell [loading]` làm trên bảng thật. -->
32
+ <div data-fx-skel="table" class="card-common overflow-x-auto">
33
+ <table class="w-full">
34
+ <thead>
35
+ <tr class="border-b border-border-default">
36
+ @for (c of cols(b); track c) {
37
+ <th class="px-normal py-semi text-left">
38
+ <div class="skeleton-load h-3" [style.width.%]="headWidth(c)"></div>
39
+ </th>
40
+ }
41
+ </tr>
42
+ </thead>
43
+ <tbody>
44
+ @for (r of rows(b); track r) {
45
+ <tr class="border-b border-border-subtle">
46
+ @for (c of cols(b); track c) {
47
+ <td class="px-normal py-semi align-middle">
48
+ <div class="skeleton-load h-4" [style.width.%]="cellWidth(r, c)"></div>
49
+ </td>
50
+ }
51
+ </tr>
52
+ }
53
+ </tbody>
54
+ </table>
55
+ </div>
56
+ }
57
+
58
+ @case ('stat-cards') {
59
+ <div data-fx-skel="stat-cards" class="grid gap-normal grid-cols-2 md:grid-cols-4">
60
+ @for (i of items(b, 4); track i) {
61
+ <div class="card-common flex flex-col gap-normal">
62
+ <div class="skeleton-load h-3 w-16"></div>
63
+ <div class="skeleton-load h-8 w-24"></div>
64
+ <div class="skeleton-load h-3 w-20"></div>
65
+ </div>
66
+ }
67
+ </div>
68
+ }
69
+
70
+ @case ('kpi-strip') {
71
+ <!-- MỘT card chia cột (kiểu app-dash-kpi-row), không phải các tile rời -->
72
+ <div data-fx-skel="kpi-strip" class="card-common !p-0">
73
+ <div class="grid grid-cols-2 md:grid-cols-4">
74
+ @for (i of items(b, 4); track i) {
75
+ <div
76
+ class="flex flex-col gap-normal px-xl py-large border-border-subtle"
77
+ [class.border-l]="!$first"
78
+ >
79
+ <div class="skeleton-load h-3 w-20"></div>
80
+ <div class="skeleton-load h-9 w-28"></div>
81
+ <div class="skeleton-load h-3 w-24"></div>
82
+ </div>
83
+ }
84
+ </div>
85
+ </div>
86
+ }
87
+
88
+ @case ('panels') {
89
+ <div data-fx-skel="panels" class="grid gap-xl" [class]="gridClass(b)">
90
+ @for (i of items(b, 2); track i) {
91
+ <div class="card-common flex flex-col gap-large">
92
+ <div class="skeleton-load h-4 w-1/3"></div>
93
+ <div class="flex items-end gap-normal h-40">
94
+ @for (x of bars; track x) {
95
+ <div class="skeleton-load flex-1 rounded-t" [style.height.%]="barHeight(x)"></div>
96
+ }
97
+ </div>
98
+ </div>
99
+ }
100
+ </div>
101
+ }
102
+
103
+ @case ('cards') {
104
+ <div data-fx-skel="cards" class="grid gap-xl" [class]="gridClass(b)">
105
+ @for (i of items(b, 6); track i) {
106
+ <div class="card-common flex flex-col gap-normal">
107
+ <div class="flex items-center gap-normal">
108
+ <div class="skeleton-load w-9 h-9 rounded-lg shrink-0"></div>
109
+ <div class="flex flex-col gap-small flex-1 min-w-0">
110
+ <div class="skeleton-load h-4 w-3/4"></div>
111
+ <div class="skeleton-load h-3 w-1/2"></div>
112
+ </div>
113
+ <div class="skeleton-load h-5 w-14 rounded-full shrink-0"></div>
114
+ </div>
115
+ <div class="grid grid-cols-4 gap-normal pt-normal border-t border-border-subtle">
116
+ @for (m of [0, 1, 2, 3]; track m) {
117
+ <div class="flex flex-col gap-small">
118
+ <div class="skeleton-load h-2.5 w-full"></div>
119
+ <div class="skeleton-load h-4 w-2/3"></div>
120
+ </div>
121
+ }
122
+ </div>
123
+ </div>
124
+ }
125
+ </div>
126
+ }
127
+
128
+ @case ('card') {
129
+ <div data-fx-skel="card" class="card-common flex flex-col gap-large">
130
+ <div class="skeleton-load h-4 w-1/3"></div>
131
+ <div class="flex flex-col gap-normal">
132
+ @for (r of [0, 1, 2, 3]; track r) {
133
+ <div class="skeleton-load h-3" [style.width.%]="cellWidth(r, 1)"></div>
134
+ }
135
+ </div>
136
+ </div>
137
+ }
138
+
139
+ @case ('tabs') {
140
+ <div data-fx-skel="tabs" class="flex items-center gap-large border-b border-border-default pb-normal">
141
+ @for (t of items(b, 6); track t) {
142
+ <div class="flex items-center gap-small">
143
+ <div class="skeleton-load w-4 h-4"></div>
144
+ <div class="skeleton-load h-3 w-16"></div>
145
+ </div>
146
+ }
147
+ </div>
148
+ }
149
+
150
+ @case ('facets') {
151
+ <div data-fx-skel="facets" class="fx-rs-row">
152
+ <div class="fx-rs-facets card-common overflow-hidden">
153
+ <fx-ui-skeleton-facets />
154
+ </div>
155
+ <div class="fx-rs-list card-common overflow-hidden">
156
+ <fx-ui-skeleton-list [rows]="6" />
157
+ </div>
158
+ <div class="flex-1 min-w-0 overflow-hidden">
159
+ <fx-ui-skeleton-detail />
160
+ </div>
161
+ </div>
162
+ }
163
+
164
+ @case ('detail') {
165
+ <fx-ui-skeleton-detail data-fx-skel="detail" />
166
+ }
167
+
168
+ @case ('form') {
169
+ <div data-fx-skel="form" class="card-common flex flex-col gap-large">
170
+ @for (r of [0, 1, 2, 3]; track r) {
171
+ <div class="flex flex-col gap-small">
172
+ <div class="skeleton-load h-3 w-24"></div>
173
+ <div class="skeleton-load h-9 w-full rounded-lg"></div>
174
+ </div>
175
+ }
176
+ <div class="flex justify-end gap-normal">
177
+ <div class="skeleton-load h-9 w-24 rounded-lg"></div>
178
+ <div class="skeleton-load h-9 w-28 rounded-lg"></div>
179
+ </div>
180
+ </div>
181
+ }
182
+ }
183
+ }
184
+ </div>
@@ -1,11 +1,7 @@
1
1
  <div class="card-common">
2
2
  @if (titleStyle() === 'eyebrow') {
3
3
  <div class="flex items-baseline justify-between gap-normal mb-large">
4
- <span
5
- class="txt-table-header uppercase"
6
- style="letter-spacing: var(--og-tracking-label)"
7
- >{{ title() }}</span
8
- >
4
+ <span class="txt-eyebrow">{{ title() }}</span>
9
5
  @if (aside()) {
10
6
  <span class="txt-utility-description text-right">{{ aside() }}</span>
11
7
  }
@@ -0,0 +1,24 @@
1
+ <div class="flex flex-col gap-xl">
2
+ <div class="grid gap-xl grid-cols-2 md:grid-cols-4">
3
+ @for (k of kpiList(); track k) {
4
+ <div class="card-common flex flex-col gap-normal">
5
+ <div class="h-3 w-16 rounded skeleton-load"></div>
6
+ <div class="h-7 w-24 rounded skeleton-load"></div>
7
+ <div class="h-3 w-20 rounded skeleton-load"></div>
8
+ </div>
9
+ }
10
+ </div>
11
+
12
+ <div class="grid gap-xl grid-cols-1 md:grid-cols-2">
13
+ @for (p of panelList(); track p) {
14
+ <div class="card-common flex flex-col gap-large">
15
+ <div class="h-4 w-1/3 rounded skeleton-load"></div>
16
+ <div class="flex items-end gap-normal h-40">
17
+ @for (b of barList(); track b) {
18
+ <div class="flex-1 rounded-t skeleton-load" [style.height.%]="barHeight(b)"></div>
19
+ }
20
+ </div>
21
+ </div>
22
+ }
23
+ </div>
24
+ </div>
@@ -1,20 +1,20 @@
1
- <div class="flex flex-col gap-xl animate-pulse">
1
+ <div class="flex flex-col gap-xl">
2
2
  <div class="card-common">
3
3
  <div class="flex items-start gap-normal">
4
- <div class="w-10 h-10 rounded-lg bg-bg-hover shrink-0"></div>
4
+ <div class="w-10 h-10 rounded-lg skeleton-load shrink-0"></div>
5
5
  <div class="flex-1 min-w-0 flex flex-col gap-normal">
6
- <div class="h-5 w-1/2 rounded bg-bg-hover"></div>
7
- <div class="h-3 w-3/4 rounded bg-bg-hover"></div>
6
+ <div class="h-5 w-1/2 rounded skeleton-load"></div>
7
+ <div class="h-3 w-3/4 rounded skeleton-load"></div>
8
8
  </div>
9
9
  </div>
10
10
  </div>
11
11
 
12
- @for (c of range(cards()); track c) {
12
+ @for (c of cardList(); track c) {
13
13
  <div class="card-common flex flex-col gap-large">
14
- <div class="h-4 w-1/3 rounded bg-bg-hover"></div>
14
+ <div class="h-4 w-1/3 rounded skeleton-load"></div>
15
15
  <div class="flex flex-col gap-normal">
16
- @for (r of range(rows()); track r) {
17
- <div class="h-3 rounded bg-bg-hover" [style.width.%]="rowWidth(r)"></div>
16
+ @for (r of rowList(); track r) {
17
+ <div class="h-3 rounded skeleton-load" [style.width.%]="rowWidth(r)"></div>
18
18
  }
19
19
  </div>
20
20
  </div>
@@ -0,0 +1,15 @@
1
+ <div class="flex flex-col gap-xl">
2
+ @for (g of groupList(); track g) {
3
+ <div class="flex flex-col gap-normal">
4
+ <div class="h-3 w-20 rounded skeleton-load"></div>
5
+ <div class="flex flex-col gap-small">
6
+ @for (r of rowList(); track r) {
7
+ <div class="flex items-center gap-normal">
8
+ <div class="w-3.5 h-3.5 rounded skeleton-load shrink-0"></div>
9
+ <div class="h-3 rounded skeleton-load" [style.width.%]="rowWidth(r)"></div>
10
+ </div>
11
+ }
12
+ </div>
13
+ </div>
14
+ }
15
+ </div>
@@ -0,0 +1,59 @@
1
+ <div class="flex h-screen w-full overflow-hidden bg-bg-primary">
2
+ <!-- drawer -->
3
+ <div
4
+ class="hidden md:flex w-[260px] shrink-0 flex-col gap-xl border-r border-border-subtle p-semi"
5
+ >
6
+ <div class="flex items-center gap-normal">
7
+ <div class="w-6 h-6 rounded skeleton-load shrink-0"></div>
8
+ <div class="flex flex-col gap-small flex-1 min-w-0">
9
+ <div class="h-3.5 w-20 rounded skeleton-load"></div>
10
+ <div class="h-2.5 w-full rounded skeleton-load"></div>
11
+ </div>
12
+ </div>
13
+
14
+ <div class="flex flex-col gap-small">
15
+ @for (n of navList(); track n) {
16
+ <div class="flex items-center gap-normal py-1">
17
+ <div class="w-4 h-4 rounded skeleton-load shrink-0"></div>
18
+ <div class="h-3 rounded skeleton-load" [style.width.%]="navWidth(n)"></div>
19
+ </div>
20
+ }
21
+ </div>
22
+
23
+ <div class="mt-auto flex items-center gap-normal border-t border-border-subtle pt-semi">
24
+ <div class="w-8 h-8 rounded-full skeleton-load shrink-0"></div>
25
+ <div class="flex flex-col gap-small flex-1 min-w-0">
26
+ <div class="h-3 w-24 rounded skeleton-load"></div>
27
+ <div class="h-2.5 w-32 rounded skeleton-load"></div>
28
+ </div>
29
+ </div>
30
+ </div>
31
+
32
+ <div class="flex flex-1 min-w-0 flex-col">
33
+ <!-- topbar -->
34
+ <div
35
+ class="flex h-14 shrink-0 items-center gap-normal border-b border-border-subtle px-semi"
36
+ >
37
+ <div class="h-3.5 w-40 rounded skeleton-load"></div>
38
+ <div class="ml-auto h-8 w-32 rounded-lg skeleton-load"></div>
39
+ </div>
40
+
41
+ <!-- content: dựng đúng composition của route đích nếu đã biết -->
42
+ <div class="flex-1 min-h-0 overflow-hidden p-semi">
43
+ @if (contentHint(); as hint) {
44
+ <fx-ui-route-skeleton [hint]="hint" />
45
+ } @else {
46
+ <div class="flex flex-col gap-xl">
47
+ <div class="h-6 w-1/4 rounded skeleton-load"></div>
48
+ <div class="grid gap-xl grid-cols-2 md:grid-cols-4">
49
+ <div class="h-24 rounded-lg skeleton-load"></div>
50
+ <div class="h-24 rounded-lg skeleton-load"></div>
51
+ <div class="h-24 rounded-lg skeleton-load"></div>
52
+ <div class="h-24 rounded-lg skeleton-load"></div>
53
+ </div>
54
+ <div class="h-64 rounded-lg skeleton-load"></div>
55
+ </div>
56
+ }
57
+ </div>
58
+ </div>
59
+ </div>
@@ -1,12 +1,12 @@
1
- <div class="flex flex-col gap-normal animate-pulse">
2
- @for (r of range(rows()); track r) {
1
+ <div class="flex flex-col gap-normal">
2
+ @for (r of rowList(); track r) {
3
3
  <div class="rounded-lg border border-border-default p-semi">
4
4
  <div class="flex items-center gap-normal mb-small">
5
- <div class="w-8 h-8 rounded-lg bg-bg-hover shrink-0"></div>
6
- <div class="h-4 flex-1 rounded bg-bg-hover"></div>
7
- <div class="h-5 w-12 rounded-full bg-bg-hover shrink-0"></div>
5
+ <div class="w-8 h-8 rounded-lg skeleton-load shrink-0"></div>
6
+ <div class="h-4 flex-1 rounded skeleton-load"></div>
7
+ <div class="h-5 w-12 rounded-full skeleton-load shrink-0"></div>
8
8
  </div>
9
- <div class="h-3 w-3/4 rounded bg-bg-hover"></div>
9
+ <div class="h-3 w-3/4 rounded skeleton-load"></div>
10
10
  </div>
11
11
  }
12
12
  </div>
@@ -6,7 +6,7 @@
6
6
  [disabled]="disabled"
7
7
  class="relative flex items-center w-10 h-5 rounded-full transition-colors duration-300 cursor-pointer disabled:cursor-not-allowed focus-visible:ring-2 focus-visible:ring-primary/50"
8
8
  [ngClass]="{
9
- 'bg-success': value && !disabled,
9
+ 'tone-solid-success': value && !disabled,
10
10
  'bg-button-default': !value && !disabled,
11
11
  'bg-bg-hover': disabled
12
12
  }"
@@ -4,8 +4,8 @@
4
4
  [attr.role]="type() === 'error' ? 'alert' : 'status'"
5
5
  class="flex border-l-[3px] items-center bg-bg-primary gap-semi min-w-[250px] max-w-[400px] px-large py-semi rounded shadow-lg transition-all duration-300 ease-in-out transform opacity-100 translate-y-0"
6
6
  [ngClass]="{
7
- 'border-success': type() === 'success',
8
- 'border-critical': type() === 'error',
7
+ 'tone-border-success': type() === 'success',
8
+ 'tone-border-danger': type() === 'error',
9
9
  'border-warning': type() === 'warning',
10
10
  'border-information': type() === 'info'
11
11
  }"
@@ -16,28 +16,28 @@
16
16
  icon="check-circle"
17
17
  [solid]="true"
18
18
  [size]="30"
19
- class="text-success"
19
+ class="tone-fg-success"
20
20
  ></fx-ui-hero-icon>
21
21
  } @case('error') {
22
22
  <fx-ui-hero-icon
23
23
  icon="exclamation-circle"
24
24
  [solid]="true"
25
25
  [size]="30"
26
- class="text-critical"
26
+ class="tone-fg-danger"
27
27
  ></fx-ui-hero-icon>
28
28
  } @case('warning') {
29
29
  <fx-ui-hero-icon
30
30
  icon="exclamation-triangle"
31
31
  [solid]="true"
32
32
  [size]="30"
33
- class="text-warning"
33
+ class="tone-fg-warning"
34
34
  ></fx-ui-hero-icon>
35
35
  } @default {
36
36
  <fx-ui-hero-icon
37
37
  icon="information-circle"
38
38
  [solid]="true"
39
39
  [size]="30"
40
- class="text-information"
40
+ class="tone-fg-information"
41
41
  ></fx-ui-hero-icon>
42
42
  } }
43
43
  </div>
package/tailwind.css CHANGED
@@ -18,3 +18,15 @@ body {
18
18
  width: 100%;
19
19
  background: rgb(var(--bg-primary));
20
20
  }
21
+
22
+ /* Typography nền lấy từ design demo: 13.5px / 1.45 / antialiased.
23
+ ⚠️ ĐẶT TRÊN `body`, TUYỆT ĐỐI KHÔNG ĐẶT TRÊN `html`. `rem` luôn quy chiếu
24
+ về phần tử gốc (`html`), nên set font-size ở `html` sẽ đổi gốc rem
25
+ 16px → 13.5px và làm CO 15,6% toàn bộ thang spacing (--spacing-* tính
26
+ bằng rem) lẫn mọi cỡ chữ text-* — chứ không chỉ chữ thừa hưởng.
27
+ Demo cũng đặt trên một DIV (.og-root), giữ rem = 16px. */
28
+ body {
29
+ font-size: var(--og-fs-md);
30
+ line-height: 1.45;
31
+ -webkit-font-smoothing: antialiased;
32
+ }