@foxeltech/angular-ui 0.4.0 → 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.
- package/archivo/archivo-400-latin-ext.woff2 +0 -0
- package/archivo/archivo-400-latin.woff2 +0 -0
- package/archivo/archivo-400-vietnamese.woff2 +0 -0
- package/archivo/archivo-500-latin-ext.woff2 +0 -0
- package/archivo/archivo-500-latin.woff2 +0 -0
- package/archivo/archivo-500-vietnamese.woff2 +0 -0
- package/archivo/archivo-600-latin-ext.woff2 +0 -0
- package/archivo/archivo-600-latin.woff2 +0 -0
- package/archivo/archivo-600-vietnamese.woff2 +0 -0
- package/archivo/archivo-700-latin-ext.woff2 +0 -0
- package/archivo/archivo-700-latin.woff2 +0 -0
- package/archivo/archivo-700-vietnamese.woff2 +0 -0
- package/components.css +332 -30
- package/dialogs.css +2 -2
- package/familjen-grotesk/familjen-grotesk-400-latin-ext.woff2 +0 -0
- package/familjen-grotesk/familjen-grotesk-400-latin.woff2 +0 -0
- package/familjen-grotesk/familjen-grotesk-400-vietnamese.woff2 +0 -0
- package/familjen-grotesk/familjen-grotesk-500-latin-ext.woff2 +0 -0
- package/familjen-grotesk/familjen-grotesk-500-latin.woff2 +0 -0
- package/familjen-grotesk/familjen-grotesk-500-vietnamese.woff2 +0 -0
- package/familjen-grotesk/familjen-grotesk-600-latin-ext.woff2 +0 -0
- package/familjen-grotesk/familjen-grotesk-600-latin.woff2 +0 -0
- package/familjen-grotesk/familjen-grotesk-600-vietnamese.woff2 +0 -0
- package/familjen-grotesk/familjen-grotesk-700-latin-ext.woff2 +0 -0
- package/familjen-grotesk/familjen-grotesk-700-latin.woff2 +0 -0
- package/familjen-grotesk/familjen-grotesk-700-vietnamese.woff2 +0 -0
- package/fesm2022/foxeltech-angular-ui-chart.mjs +381 -40
- package/fesm2022/foxeltech-angular-ui-chart.mjs.map +1 -1
- package/fesm2022/foxeltech-angular-ui-flow.mjs +176 -3
- package/fesm2022/foxeltech-angular-ui-flow.mjs.map +1 -1
- package/fesm2022/foxeltech-angular-ui-rich-text.mjs +2 -2
- package/fesm2022/foxeltech-angular-ui-rich-text.mjs.map +1 -1
- package/fesm2022/foxeltech-angular-ui.mjs +1327 -151
- package/fesm2022/foxeltech-angular-ui.mjs.map +1 -1
- package/fonts.css +558 -133
- package/ibm-plex-mono/ibm-plex-mono-400-cyrillic-ext.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-400-cyrillic.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-400-latin-ext.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-400-latin.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-400-vietnamese.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-500-cyrillic-ext.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-500-cyrillic.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-500-latin-ext.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-500-latin.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-500-vietnamese.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-600-cyrillic-ext.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-600-cyrillic.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-600-latin-ext.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-600-latin.woff2 +0 -0
- package/ibm-plex-mono/ibm-plex-mono-600-vietnamese.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-400-cyrillic-ext.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-400-cyrillic.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-400-greek.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-400-latin-ext.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-400-latin.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-400-vietnamese.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-500-cyrillic-ext.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-500-cyrillic.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-500-greek.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-500-latin-ext.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-500-latin.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-500-vietnamese.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-600-cyrillic-ext.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-600-cyrillic.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-600-greek.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-600-latin-ext.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-600-latin.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-600-vietnamese.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-700-cyrillic-ext.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-700-cyrillic.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-700-greek.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-700-latin-ext.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-700-latin.woff2 +0 -0
- package/jetbrains-mono/jetbrains-mono-700-vietnamese.woff2 +0 -0
- package/newsreader/newsreader-400-latin-ext.woff2 +0 -0
- package/newsreader/newsreader-400-latin.woff2 +0 -0
- package/newsreader/newsreader-400-vietnamese.woff2 +0 -0
- package/newsreader/newsreader-500-latin-ext.woff2 +0 -0
- package/newsreader/newsreader-500-latin.woff2 +0 -0
- package/newsreader/newsreader-500-vietnamese.woff2 +0 -0
- package/newsreader/newsreader-600-latin-ext.woff2 +0 -0
- package/newsreader/newsreader-600-latin.woff2 +0 -0
- package/newsreader/newsreader-600-vietnamese.woff2 +0 -0
- package/package.json +5 -2
- package/source-serif-4/source-serif-4-400-cyrillic-ext.woff2 +0 -0
- package/source-serif-4/source-serif-4-400-cyrillic.woff2 +0 -0
- package/source-serif-4/source-serif-4-400-greek.woff2 +0 -0
- package/source-serif-4/source-serif-4-400-latin-ext.woff2 +0 -0
- package/source-serif-4/source-serif-4-400-latin.woff2 +0 -0
- package/source-serif-4/source-serif-4-400-vietnamese.woff2 +0 -0
- package/source-serif-4/source-serif-4-600-cyrillic-ext.woff2 +0 -0
- package/source-serif-4/source-serif-4-600-cyrillic.woff2 +0 -0
- package/source-serif-4/source-serif-4-600-greek.woff2 +0 -0
- package/source-serif-4/source-serif-4-600-latin-ext.woff2 +0 -0
- package/source-serif-4/source-serif-4-600-latin.woff2 +0 -0
- package/source-serif-4/source-serif-4-600-vietnamese.woff2 +0 -0
- package/src/lib/styles/components.css +332 -30
- package/src/lib/styles/dialogs.css +2 -2
- package/src/lib/styles/fonts.css +558 -133
- package/src/lib/styles/tailwind.css +13 -1
- package/src/lib/styles/theme.css +642 -69
- package/src/lib/styles/tokens.css +81 -19
- package/src/lib/styles/utilities.css +16 -1
- package/src/lib/ui/components/bar-list/bar-list.component.html +29 -0
- package/src/lib/ui/components/button/button.component.html +9 -5
- package/src/lib/ui/components/checkbox/checkbox.component.html +1 -1
- package/src/lib/ui/components/code-block/code-block.component.html +8 -0
- package/src/lib/ui/components/drawer/drawer.component.html +35 -12
- package/src/lib/ui/components/drawer/drawer.component.scss +106 -18
- package/src/lib/ui/components/facets-rail/facets-rail.component.html +37 -0
- package/src/lib/ui/components/filter-pills/filter-pills.component.html +16 -0
- package/src/lib/ui/components/kanban-board/kanban-board.component.scss +9 -9
- package/src/lib/ui/components/list-row/list-row.component.html +20 -0
- package/src/lib/ui/components/master-detail/master-detail.component.css +79 -5
- package/src/lib/ui/components/master-detail/master-detail.component.html +57 -7
- package/src/lib/ui/components/pending-badge/pending-badge.component.html +15 -0
- package/src/lib/ui/components/pipeline-stepper/pipeline-stepper.component.html +45 -0
- package/src/lib/ui/components/project-card/project-card.component.html +102 -0
- package/src/lib/ui/components/radio-button/radio-button.component.html +1 -1
- package/src/lib/ui/components/radio-button-toggle/radio-button-toggle.component.html +1 -1
- package/src/lib/ui/components/route-skeleton/route-skeleton.component.css +38 -0
- package/src/lib/ui/components/route-skeleton/route-skeleton.component.html +184 -0
- package/src/lib/ui/components/sample-frame/sample-frame.component.html +18 -0
- package/src/lib/ui/components/score-badge/score-badge.component.html +7 -0
- package/src/lib/ui/components/screenshot-frame/screenshot-frame.component.html +40 -0
- package/src/lib/ui/components/section-card/section-card.component.html +15 -6
- package/src/lib/ui/components/segmented/segmented.component.html +42 -0
- package/src/lib/ui/components/segmented/segmented.component.scss +12 -0
- package/src/lib/ui/components/skeleton-dashboard/skeleton-dashboard.component.html +24 -0
- package/src/lib/ui/components/skeleton-detail/skeleton-detail.component.html +8 -8
- package/src/lib/ui/components/skeleton-facets/skeleton-facets.component.html +15 -0
- package/src/lib/ui/components/skeleton-frame/skeleton-frame.component.html +59 -0
- package/src/lib/ui/components/skeleton-list/skeleton-list.component.html +6 -6
- package/src/lib/ui/components/slider/slider.component.html +2 -2
- package/src/lib/ui/components/sparkbar/sparkbar.component.html +14 -0
- package/src/lib/ui/components/stage-dots/stage-dots.component.html +13 -0
- package/src/lib/ui/components/stat-cards/stat-cards.component.html +44 -11
- package/src/lib/ui/components/status-dot/status-dot.component.html +13 -0
- package/src/lib/ui/components/switch/switch.component.html +1 -1
- package/src/lib/ui/components/tab-group/tab-group.component.html +37 -8
- package/src/lib/ui/components/tab-group/tab-group.component.scss +41 -1
- package/src/lib/ui/components/tag/tag.component.html +2 -2
- package/src/lib/ui/components/theme-picker/theme-picker.component.html +44 -0
- package/src/lib/ui/components/toast/toast.component.html +6 -6
- package/src/lib/ui/components/tree-diagram/tree-diagram.component.html +3 -3
- package/tailwind.css +13 -1
- package/theme.css +642 -69
- package/tokens.css +81 -19
- package/types/foxeltech-angular-ui-chart.d.ts +90 -3
- package/types/foxeltech-angular-ui-flow.d.ts +83 -1
- package/types/foxeltech-angular-ui.d.ts +909 -48
- package/utilities.css +16 -1
- package/BeVietnamPro/BeVietnamPro-Bold.woff2 +0 -0
- package/BeVietnamPro/BeVietnamPro-ExtraLight.woff2 +0 -0
- package/BeVietnamPro/BeVietnamPro-Light.woff2 +0 -0
- package/BeVietnamPro/BeVietnamPro-Medium.woff2 +0 -0
- package/BeVietnamPro/BeVietnamPro-Regular.woff2 +0 -0
- package/BeVietnamPro/BeVietnamPro-SemiBold.woff2 +0 -0
- package/BeVietnamPro/BeVietnamPro-Thin.woff2 +0 -0
- package/SpaceMono-Regular.woff2 +0 -0
- package/dm-sans/DMSans-Bold.woff2 +0 -0
- package/dm-sans/DMSans-Light.woff2 +0 -0
- package/dm-sans/DMSans-Medium.woff2 +0 -0
- package/dm-sans/DMSans-Regular.woff2 +0 -0
- package/dm-sans/DMSans-SemiBold.woff2 +0 -0
- package/dm-sans/DMSans-Thin.woff2 +0 -0
- package/orbitron/Orbitron-Bold.woff2 +0 -0
- package/orbitron/Orbitron-Medium.woff2 +0 -0
- package/orbitron/Orbitron-Regular.woff2 +0 -0
- package/orbitron/Orbitron-SemiBold.woff2 +0 -0
- package/roboto/Roboto-Black.woff2 +0 -0
- package/roboto/Roboto-BlackItalic.woff2 +0 -0
- package/roboto/Roboto-Bold.woff2 +0 -0
- package/roboto/Roboto-BoldCondensed.woff2 +0 -0
- package/roboto/Roboto-BoldCondensedItalic.woff2 +0 -0
- package/roboto/Roboto-BoldItalic.woff2 +0 -0
- package/roboto/Roboto-Condensed.woff2 +0 -0
- package/roboto/Roboto-CondensedItalic.woff2 +0 -0
- package/roboto/Roboto-Italic.woff2 +0 -0
- package/roboto/Roboto-Light.woff2 +0 -0
- package/roboto/Roboto-LightItalic.woff2 +0 -0
- package/roboto/Roboto-Medium.woff2 +0 -0
- package/roboto/Roboto-MediumItalic.woff2 +0 -0
- package/roboto/Roboto-Regular.woff2 +0 -0
- package/roboto/Roboto-Thin.woff2 +0 -0
- package/roboto/Roboto-ThinItalic.woff2 +0 -0
- package/src/lib/ui/components/skeleton-table-loading/skeleton-table-loading.component.html +0 -21
- package/src/lib/ui/components/skeleton-table-loading/skeleton-table-loading.component.scss +0 -0
- package/src/lib/ui/components/tab-component/tab.component.html +0 -1
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
<div class="card-common">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
@if (titleStyle() === 'eyebrow') {
|
|
3
|
+
<div class="flex items-baseline justify-between gap-normal mb-large">
|
|
4
|
+
<span class="txt-eyebrow">{{ title() }}</span>
|
|
5
|
+
@if (aside()) {
|
|
6
|
+
<span class="txt-utility-description text-right">{{ aside() }}</span>
|
|
7
|
+
}
|
|
8
|
+
</div>
|
|
9
|
+
} @else {
|
|
10
|
+
<div class="flex items-center gap-normal mb-large">
|
|
11
|
+
@if (icon) {
|
|
12
|
+
<fx-ui-hero-icon [ngClass]="iconClass" [icon]="icon" [size]="18"></fx-ui-hero-icon>
|
|
13
|
+
}
|
|
14
|
+
<span class="txt-heading-06">{{ title() }}</span>
|
|
15
|
+
</div>
|
|
16
|
+
}
|
|
8
17
|
<ng-content></ng-content>
|
|
9
18
|
</div>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<div
|
|
2
|
+
class="relative inline-grid max-w-full grid-flow-col auto-cols-fr items-stretch p-[3px] bg-surface-sunken border border-border rounded-full"
|
|
3
|
+
role="group"
|
|
4
|
+
[attr.aria-label]="ariaLabel()"
|
|
5
|
+
>
|
|
6
|
+
<!-- Sliding thumb: one element that translates to the active option -->
|
|
7
|
+
@if (activeIndex() >= 0) {
|
|
8
|
+
<span
|
|
9
|
+
aria-hidden="true"
|
|
10
|
+
class="fx-segmented__thumb absolute top-[3px] bottom-[3px] left-[3px] rounded-full pointer-events-none"
|
|
11
|
+
[class]="thumbClass()"
|
|
12
|
+
[style.width]="thumbWidth()"
|
|
13
|
+
[style.transform]="thumbTransform()"
|
|
14
|
+
></span>
|
|
15
|
+
}
|
|
16
|
+
@for (option of options(); track option.value) {
|
|
17
|
+
<button
|
|
18
|
+
type="button"
|
|
19
|
+
(click)="select(option)"
|
|
20
|
+
[disabled]="option.disabled"
|
|
21
|
+
[attr.aria-pressed]="option.value === value()"
|
|
22
|
+
class="relative z-[1] flex min-w-0 items-center justify-center gap-xs px-semi py-[5px] rounded-full text-[13px] leading-none font-medium whitespace-nowrap transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
23
|
+
[class]="optionClass(option)"
|
|
24
|
+
>
|
|
25
|
+
@if (option.icon) {
|
|
26
|
+
<fx-ui-hero-icon [icon]="option.icon" [size]="14" class="flex" />
|
|
27
|
+
}
|
|
28
|
+
<!-- text-box trims Archivo's uneven leading → true optical centering
|
|
29
|
+
(Chrome 128+/Safari 18.2+; older browsers ignore it harmlessly).
|
|
30
|
+
truncate adds overflow:hidden, and the trimmed box ends at cap
|
|
31
|
+
height / baseline — so the dot on "i" and the tail on "y" fall
|
|
32
|
+
outside it and get clipped. py/-my pair gives both back without
|
|
33
|
+
changing the control's height. -->
|
|
34
|
+
<span class="min-w-0 truncate py-[3px] -my-[3px] [text-box:trim-both_cap_alphabetic]">{{ option.label }}</span>
|
|
35
|
+
@if (option.count !== undefined) {
|
|
36
|
+
<span class="txt-tag-label px-small rounded-pill bg-neutral-soft text-neutral-soft-fg">
|
|
37
|
+
{{ option.count }}
|
|
38
|
+
</span>
|
|
39
|
+
}
|
|
40
|
+
</button>
|
|
41
|
+
}
|
|
42
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* The thumb's motion is owned HERE, not by template utilities: consuming apps
|
|
2
|
+
can (and do — host theme fade) ship unlayered global `transition` rules that
|
|
3
|
+
override the Tailwind utilities layer and freeze the slide. Component styles
|
|
4
|
+
are unlayered + scoped, so they win. (anh Tú 29/08) */
|
|
5
|
+
.fx-segmented__thumb {
|
|
6
|
+
transition: transform 0.2s cubic-bezier(0.2, 0.9, 0.2, 1), width 0.2s cubic-bezier(0.2, 0.9, 0.2, 1);
|
|
7
|
+
will-change: transform;
|
|
8
|
+
|
|
9
|
+
@media (prefers-reduced-motion: reduce) {
|
|
10
|
+
transition: none;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -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
|
|
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
|
|
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
|
|
7
|
-
<div class="h-3 w-3/4 rounded
|
|
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
|
|
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
|
|
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
|
|
17
|
-
<div class="h-3 rounded
|
|
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
|
|
2
|
-
@for (r of
|
|
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
|
|
6
|
-
<div class="h-4 flex-1 rounded
|
|
7
|
-
<div class="h-5 w-12 rounded-full
|
|
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
|
|
9
|
+
<div class="h-3 w-3/4 rounded skeleton-load"></div>
|
|
10
10
|
</div>
|
|
11
11
|
}
|
|
12
12
|
</div>
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
[ngClass]="{ 'flex-col h-48': vertical() }"
|
|
19
19
|
>
|
|
20
20
|
<div
|
|
21
|
-
class="relative flex-1 rounded-full bg-
|
|
22
|
-
[ngClass]="{ 'w-1 rotate-0 h-full w-auto bg-
|
|
21
|
+
class="relative flex-1 rounded-full bg-track h-2"
|
|
22
|
+
[ngClass]="{ 'w-1 rotate-0 h-full w-auto bg-track': vertical() }"
|
|
23
23
|
>
|
|
24
24
|
@if (!vertical()) {
|
|
25
25
|
<div
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<div
|
|
2
|
+
class="flex items-end gap-[2px]"
|
|
3
|
+
[style.height.px]="height()"
|
|
4
|
+
role="img"
|
|
5
|
+
[attr.aria-label]="'Trend: ' + values().join(', ')"
|
|
6
|
+
>
|
|
7
|
+
@for (bar of bars(); track $index) {
|
|
8
|
+
<div
|
|
9
|
+
class="flex-1 min-w-[3px] rounded-[1px] opacity-80"
|
|
10
|
+
[ngClass]="barClass()"
|
|
11
|
+
[style.height.%]="bar"
|
|
12
|
+
></div>
|
|
13
|
+
}
|
|
14
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<div class="flex items-center gap-xs" role="tablist">
|
|
2
|
+
@for (i of dots(); track i) {
|
|
3
|
+
<button
|
|
4
|
+
type="button"
|
|
5
|
+
role="tab"
|
|
6
|
+
[attr.aria-selected]="i === current()"
|
|
7
|
+
[attr.aria-label]="'Stage ' + (i + 1)"
|
|
8
|
+
class="h-1.5 rounded-full cursor-pointer transition-all duration-150 hover:opacity-70"
|
|
9
|
+
[ngClass]="dotClass(i)"
|
|
10
|
+
(click)="dotClick.emit(i)"
|
|
11
|
+
></button>
|
|
12
|
+
}
|
|
13
|
+
</div>
|
|
@@ -1,18 +1,51 @@
|
|
|
1
1
|
<div class="grid gap-normal" [ngStyle]="{ 'grid-template-columns': gridColumns }">
|
|
2
2
|
@for (card of cards(); track card.label) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
@if (variant() === 'figure') {
|
|
4
|
+
<div class="card-common flex flex-col gap-small min-w-0">
|
|
5
|
+
<span class="txt-utility-caption text-text-secondary truncate">{{ card.label }}</span>
|
|
6
|
+
<span
|
|
7
|
+
class="txt-heading-03"
|
|
8
|
+
[ngClass]="numClass(card)"
|
|
9
|
+
style="font-family: var(--og-font-figure)"
|
|
10
|
+
>{{ card.value }}</span
|
|
8
11
|
>
|
|
9
|
-
|
|
12
|
+
@if (card.sub) {
|
|
13
|
+
<span class="txt-utility-caption" [ngClass]="subClass(card)">{{ card.sub }}</span>
|
|
14
|
+
}
|
|
15
|
+
@if (card.spark?.length) {
|
|
16
|
+
<fx-ui-sparkbar class="mt-xs" [values]="card.spark!" [height]="16" [tone]="card.tone ?? null" />
|
|
17
|
+
}
|
|
18
|
+
</div>
|
|
19
|
+
} @else {
|
|
20
|
+
<div class="card-common flex items-center gap-normal">
|
|
21
|
+
@if (card.icon) {
|
|
22
|
+
<div
|
|
23
|
+
class="w-10 h-10 rounded-lg flex items-center justify-center shrink-0"
|
|
24
|
+
[ngClass]="boxClass(card)"
|
|
25
|
+
>
|
|
26
|
+
<fx-ui-hero-icon [icon]="card.icon" [size]="20"></fx-ui-hero-icon>
|
|
27
|
+
</div>
|
|
28
|
+
}
|
|
29
|
+
<div class="flex flex-col min-w-0 flex-1">
|
|
30
|
+
<div class="flex items-baseline gap-small">
|
|
31
|
+
<span
|
|
32
|
+
class="txt-heading-04"
|
|
33
|
+
[ngClass]="numClass(card)"
|
|
34
|
+
style="font-family: var(--og-font-figure)"
|
|
35
|
+
>{{ card.value }}</span
|
|
36
|
+
>
|
|
37
|
+
@if (card.delta) {
|
|
38
|
+
<span class="text-xs font-semibold" [ngClass]="deltaClass(card)">
|
|
39
|
+
{{ card.delta.direction === 'up' ? '▲' : '▼' }} {{ card.delta.value }}
|
|
40
|
+
</span>
|
|
41
|
+
}
|
|
42
|
+
</div>
|
|
43
|
+
<span class="txt-utility-caption text-text-secondary truncate">{{ card.label }}</span>
|
|
44
|
+
@if (card.spark?.length) {
|
|
45
|
+
<fx-ui-sparkbar class="mt-xs" [values]="card.spark!" [height]="16" [tone]="card.tone ?? null" />
|
|
46
|
+
}
|
|
10
47
|
</div>
|
|
11
|
-
}
|
|
12
|
-
<div class="flex flex-col min-w-0">
|
|
13
|
-
<span class="txt-heading-04" [ngClass]="numClass(card)">{{ card.value }}</span>
|
|
14
|
-
<span class="txt-utility-caption text-text-secondary truncate">{{ card.label }}</span>
|
|
15
48
|
</div>
|
|
16
|
-
|
|
49
|
+
}
|
|
17
50
|
}
|
|
18
51
|
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<span
|
|
2
|
+
class="relative inline-flex shrink-0"
|
|
3
|
+
[style.width.px]="size()"
|
|
4
|
+
[style.height.px]="size()"
|
|
5
|
+
>
|
|
6
|
+
@if (pulse()) {
|
|
7
|
+
<span
|
|
8
|
+
class="absolute inline-flex h-full w-full rounded-full opacity-60 animate-ping motion-reduce:animate-none"
|
|
9
|
+
[ngClass]="dotClass()"
|
|
10
|
+
></span>
|
|
11
|
+
}
|
|
12
|
+
<span class="relative inline-flex h-full w-full rounded-full" [ngClass]="dotClass()"></span>
|
|
13
|
+
</span>
|
|
@@ -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
|
-
'
|
|
9
|
+
'tone-solid-success': value && !disabled,
|
|
10
10
|
'bg-button-default': !value && !disabled,
|
|
11
11
|
'bg-bg-hover': disabled
|
|
12
12
|
}"
|
|
@@ -26,8 +26,14 @@
|
|
|
26
26
|
#tabList
|
|
27
27
|
role="tablist"
|
|
28
28
|
class="relative flex overflow-x-auto no-scrollbar scroll-smooth"
|
|
29
|
+
[class.fx-tabs-frame]="variant() === 'page'"
|
|
29
30
|
(scroll)="onScroll()"
|
|
30
31
|
>
|
|
32
|
+
<!-- 'page' variant: one raised pill that SLIDES to the active tab
|
|
33
|
+
(anh Tú 29/08 — same motion as fx-ui-segmented) -->
|
|
34
|
+
@if (variant() === 'page') {
|
|
35
|
+
<span #pagePill aria-hidden="true" class="fx-tabs-pill"></span>
|
|
36
|
+
}
|
|
31
37
|
@for (tab of tabs(); track tab; let i = $index) {
|
|
32
38
|
<button
|
|
33
39
|
type="button"
|
|
@@ -37,31 +43,54 @@
|
|
|
37
43
|
(click)="selectTab(i)"
|
|
38
44
|
(keydown)="onTabKeydown($event, i)"
|
|
39
45
|
class="tab-btn tab-bar-btn"
|
|
46
|
+
[class.tab-bar-btn-page]="variant() === 'page'"
|
|
40
47
|
>
|
|
41
|
-
<div class="flex flex-row items-center justify-center">
|
|
48
|
+
<div class="flex flex-row items-center justify-center gap-xs">
|
|
42
49
|
@if (tab.icon) {
|
|
43
50
|
<fx-ui-hero-icon
|
|
44
51
|
[icon]="tab.icon"
|
|
45
|
-
[size]="20"
|
|
52
|
+
[size]="variant() === 'page' ? 14 : 20"
|
|
46
53
|
class="flex mr-[2px]"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
[ngClass]="
|
|
55
|
+
variant() === 'page'
|
|
56
|
+
? i === activeIndex
|
|
57
|
+
? 'text-strong'
|
|
58
|
+
: 'text-text-placeholder'
|
|
59
|
+
: i === activeIndex
|
|
60
|
+
? 'text-accent-fg mb-small'
|
|
61
|
+
: 'text-text-placeholder'
|
|
62
|
+
"
|
|
51
63
|
></fx-ui-hero-icon>
|
|
52
64
|
}
|
|
53
65
|
<div
|
|
54
66
|
[ngClass]="
|
|
55
|
-
|
|
67
|
+
variant() === 'page'
|
|
68
|
+
? i === activeIndex
|
|
69
|
+
? 'text-[13px] leading-none font-semibold text-strong [text-box:trim-both_cap_alphabetic]'
|
|
70
|
+
: 'text-[13px] leading-none font-medium text-muted [text-box:trim-both_cap_alphabetic]'
|
|
71
|
+
: i === activeIndex
|
|
72
|
+
? 'txt-field-label text-accent-fg'
|
|
73
|
+
: 'txt-placeholder'
|
|
56
74
|
"
|
|
57
75
|
>
|
|
58
76
|
{{ tab.label() }}
|
|
59
77
|
</div>
|
|
78
|
+
@if (tab.count() !== null) {
|
|
79
|
+
<span
|
|
80
|
+
class="txt-tag-label px-normal py-[1px] rounded-pill"
|
|
81
|
+
[ngClass]="badgeClass(tab)"
|
|
82
|
+
style="font-family: var(--og-font-figure)"
|
|
83
|
+
>
|
|
84
|
+
{{ tab.count() }}
|
|
85
|
+
</span>
|
|
86
|
+
}
|
|
60
87
|
</div>
|
|
61
88
|
</button>
|
|
62
89
|
}
|
|
63
90
|
|
|
64
|
-
|
|
91
|
+
@if (variant() !== 'page') {
|
|
92
|
+
<span #underline class="underline" style="width: 0; transform: translateX(0)"></span>
|
|
93
|
+
}
|
|
65
94
|
</div>
|
|
66
95
|
|
|
67
96
|
<button
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
position: absolute;
|
|
29
29
|
bottom: 0;
|
|
30
30
|
height: 2px;
|
|
31
|
-
background-color: rgb(var(--
|
|
31
|
+
background-color: rgb(var(--og-accent));
|
|
32
32
|
transition: transform 0.25s cubic-bezier(0.2, 0.9, 0.2, 1),
|
|
33
33
|
width 0.25s cubic-bezier(0.2, 0.9, 0.2, 1);
|
|
34
34
|
will-change: transform, width;
|
|
@@ -49,3 +49,43 @@
|
|
|
49
49
|
.tab-bar-btn {
|
|
50
50
|
@apply relative px-large py-normal text-sm whitespace-nowrap transition-colors duration-200;
|
|
51
51
|
}
|
|
52
|
+
|
|
53
|
+
/* V2 'page' variant: workspace tab strip — pills inside a rounded frame
|
|
54
|
+
(design refs 02..04), active pill lifted on the raised surface. */
|
|
55
|
+
.fx-tabs-frame {
|
|
56
|
+
/* w-fit: the frame hugs its tabs (design refs 02..04) instead of spanning the
|
|
57
|
+
page; max-w-full keeps the inner scroll working when tabs overflow.
|
|
58
|
+
rounded-full: the design strip is a capsule in every theme, not the
|
|
59
|
+
theme control radius (refs 02..04 — anh Tú 28/08). */
|
|
60
|
+
@apply gap-xs p-[3px] w-fit max-w-full bg-surface-sunken border border-border rounded-full;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.tab-bar-btn-page {
|
|
64
|
+
/* py 5px: the design strip is slim (~36px capsule) — anh Tú 28/08.
|
|
65
|
+
The active background lives on .fx-tabs-pill (sliding thumb), so the
|
|
66
|
+
button itself only switches text colour. z-index keeps it above the pill. */
|
|
67
|
+
@apply px-semi py-[5px] rounded-full border border-transparent text-muted z-[1];
|
|
68
|
+
|
|
69
|
+
&[aria-selected='false']:hover {
|
|
70
|
+
@apply text-strong;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* Sliding active pill for the 'page' variant — positioned from the active
|
|
75
|
+
tab's offsetLeft/offsetWidth (tabs hug content, widths differ), so it
|
|
76
|
+
scrolls with the strip and needs no scroll-time recompute. */
|
|
77
|
+
.fx-tabs-pill {
|
|
78
|
+
@apply absolute rounded-full bg-surface-raised border border-border shadow-sm pointer-events-none;
|
|
79
|
+
top: 3px; /* frame p-[3px] inset */
|
|
80
|
+
bottom: 3px;
|
|
81
|
+
left: 0;
|
|
82
|
+
width: 0;
|
|
83
|
+
transform: translateX(0);
|
|
84
|
+
transition:
|
|
85
|
+
transform 0.25s cubic-bezier(0.2, 0.9, 0.2, 1),
|
|
86
|
+
width 0.25s cubic-bezier(0.2, 0.9, 0.2, 1);
|
|
87
|
+
will-change: transform, width;
|
|
88
|
+
@media (prefers-reduced-motion: reduce) {
|
|
89
|
+
transition: none;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
>
|
|
12
12
|
@if (icon) {
|
|
13
13
|
<fx-ui-hero-icon
|
|
14
|
-
[class]="`flex txt-tag-${type()} ${solid() && type() !== 'default' ? 'text-
|
|
14
|
+
[class]="`flex txt-tag-${type()} ${solid() && type() !== 'default' ? 'text-surface' : ''}`"
|
|
15
15
|
[icon]="icon"
|
|
16
16
|
[size]="18"
|
|
17
17
|
></fx-ui-hero-icon>
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
<div [class]="`txt-tag-${type()} ${solid() && type() !== 'default' ? 'text-
|
|
20
|
+
<div [class]="`txt-tag-${type()} ${solid() && type() !== 'default' ? 'text-surface font-medium' : ''}`">
|
|
21
21
|
{{ label() }}
|
|
22
22
|
</div>
|
|
23
23
|
</div>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<button
|
|
2
|
+
type="button"
|
|
3
|
+
[matMenuTriggerFor]="themeMenu"
|
|
4
|
+
class="flex items-center gap-small px-normal py-small rounded-control border border-border-default bg-transparent cursor-pointer hover:bg-bg-hover transition-colors"
|
|
5
|
+
aria-label="Change theme"
|
|
6
|
+
>
|
|
7
|
+
<span
|
|
8
|
+
class="w-4 h-4 rounded-full border border-border-strong/30 shrink-0"
|
|
9
|
+
[style.background]="
|
|
10
|
+
'linear-gradient(135deg, ' +
|
|
11
|
+
currentMeta().accent +
|
|
12
|
+
' 50%, ' +
|
|
13
|
+
currentMeta().pageBg +
|
|
14
|
+
' 50%)'
|
|
15
|
+
"
|
|
16
|
+
></span>
|
|
17
|
+
<span class="txt-body-01 hidden md:inline">{{ currentMeta().label }}</span>
|
|
18
|
+
<fx-ui-hero-icon icon="chevron-down" [size]="14" class="flex text-text-secondary" />
|
|
19
|
+
</button>
|
|
20
|
+
|
|
21
|
+
<mat-menu #themeMenu="matMenu">
|
|
22
|
+
@for (theme of themes; track theme.name) {
|
|
23
|
+
<button
|
|
24
|
+
mat-menu-item
|
|
25
|
+
type="button"
|
|
26
|
+
(click)="select(theme.name)"
|
|
27
|
+
[attr.aria-current]="theme.name === current() ? 'true' : null"
|
|
28
|
+
>
|
|
29
|
+
<div class="flex items-center gap-normal min-w-40">
|
|
30
|
+
<span
|
|
31
|
+
class="w-5 h-5 rounded-full border border-border-strong/30 shrink-0"
|
|
32
|
+
[style.background]="
|
|
33
|
+
'linear-gradient(135deg, ' + theme.accent + ' 50%, ' + theme.pageBg + ' 50%)'
|
|
34
|
+
"
|
|
35
|
+
></span>
|
|
36
|
+
<span class="txt-body-01 flex-1">{{ theme.label }}</span>
|
|
37
|
+
<span class="txt-utility-description">{{ theme.dark ? 'Dark' : 'Light' }}</span>
|
|
38
|
+
@if (theme.name === current()) {
|
|
39
|
+
<fx-ui-hero-icon icon="check" [size]="16" class="flex text-text-selected" />
|
|
40
|
+
}
|
|
41
|
+
</div>
|
|
42
|
+
</button>
|
|
43
|
+
}
|
|
44
|
+
</mat-menu>
|
|
@@ -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-
|
|
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="
|
|
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="
|
|
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="
|
|
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="
|
|
40
|
+
class="tone-fg-information"
|
|
41
41
|
></fx-ui-hero-icon>
|
|
42
42
|
} }
|
|
43
43
|
</div>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<!-- ROOT -->
|
|
4
4
|
<div
|
|
5
5
|
#root
|
|
6
|
-
class="mx-auto w-fit bg-
|
|
6
|
+
class="mx-auto w-fit bg-accent text-accent-contrast px-7 py-3 rounded-md font-semibold text-center"
|
|
7
7
|
>
|
|
8
8
|
{{ data().label }}
|
|
9
9
|
</div>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
@for (child of data().children; track child) {
|
|
14
14
|
<div
|
|
15
15
|
#child
|
|
16
|
-
class="w-48 bg-
|
|
16
|
+
class="w-48 bg-surface-raised text-strong border border-border px-4 py-4 rounded-lg text-center"
|
|
17
17
|
>
|
|
18
18
|
<div class="font-semibold text-lg">{{ child.label }}</div>
|
|
19
19
|
<div class="mt-1 text-sm opacity-90">{{ child.status }}</div>
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
[attr.y1]="line.y1"
|
|
34
34
|
[attr.x2]="line.x2"
|
|
35
35
|
[attr.y2]="line.y2"
|
|
36
|
-
stroke="
|
|
36
|
+
stroke="rgb(var(--og-border-strong))"
|
|
37
37
|
stroke-width="2"
|
|
38
38
|
/>
|
|
39
39
|
}
|