@africanies/angular-web-sdk 0.1.7 → 0.1.8
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/.nx/cache/{4082520855419352840 → 15302120112746851896}/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs +30 -8
- package/.nx/cache/15302120112746851896/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +1 -0
- package/.nx/cache/{4082520855419352840 → 15302120112746851896}/dist/libs/africanies-theme/tailwind-preset.cjs +89 -12
- package/.nx/cache/{4082520855419352840 → 15302120112746851896}/dist/libs/africanies-theme/types/africanies-africanies-theme.d.ts +14 -4
- package/.nx/cache/{17491371155400585077 → 18393832731522001121}/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs +139 -51
- package/.nx/cache/18393832731522001121/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs.map +1 -0
- package/.nx/cache/{17491371155400585077 → 18393832731522001121}/dist/libs/africanies-core/types/africanies-africanies-core.d.ts +14 -11
- package/.nx/cache/5151121439688073678/dist/libs/africanies-icons/README.md +69 -0
- package/.nx/cache/5151121439688073678/dist/libs/africanies-icons/assets/icons.sprite.svg +1851 -0
- package/.nx/cache/5151121439688073678/dist/libs/africanies-icons/fesm2022/africanies-africanies-icons.mjs +833 -0
- package/.nx/cache/5151121439688073678/dist/libs/africanies-icons/fesm2022/africanies-africanies-icons.mjs.map +1 -0
- package/.nx/cache/5151121439688073678/dist/libs/africanies-icons/package.json +30 -0
- package/.nx/cache/5151121439688073678/dist/libs/africanies-icons/types/africanies-africanies-icons.d.ts +108 -0
- package/.nx/cache/877026836685850193/dist/libs/africanies-models/README.md +60 -0
- package/.nx/cache/877026836685850193/dist/libs/africanies-models/fesm2022/africanies-africanies-models.mjs +613 -0
- package/.nx/cache/877026836685850193/dist/libs/africanies-models/fesm2022/africanies-africanies-models.mjs.map +1 -0
- package/.nx/cache/877026836685850193/dist/libs/africanies-models/package.json +23 -0
- package/.nx/cache/877026836685850193/dist/libs/africanies-models/types/africanies-africanies-models.d.ts +1452 -0
- package/.nx/cache/{17499961385238663835 → 9406544675747598148}/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs +765 -615
- package/.nx/cache/9406544675747598148/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +1 -0
- package/.nx/cache/{17499961385238663835 → 9406544675747598148}/dist/libs/africanies-ui/types/africanies-africanies-ui.d.ts +149 -116
- package/.nx/cache/run.json +40 -40
- package/.nx/cache/terminalOutputs/{7126777490381568487 → 15149466893522345489} +10 -5
- package/.nx/cache/terminalOutputs/{4082520855419352840 → 15302120112746851896} +1 -1
- package/.nx/cache/terminalOutputs/{8648260256613557249 → 15835338512221847842} +18 -8
- package/.nx/cache/terminalOutputs/{9408529484792607601 → 17960163310445607219} +1 -1
- package/.nx/cache/terminalOutputs/{17491371155400585077 → 18393832731522001121} +2 -2
- package/.nx/cache/terminalOutputs/{3314955264390318442 → 5151121439688073678} +6 -6
- package/.nx/cache/terminalOutputs/7462873189468732296 +17 -0
- package/.nx/cache/terminalOutputs/8032148447904822353 +184 -182
- package/.nx/cache/terminalOutputs/{12276756491762927325 → 877026836685850193} +7 -7
- package/.nx/cache/terminalOutputs/9406544675747598148 +21 -0
- package/.nx/workspace-data/0091ABA9-5C90-580D-953C-8C94E763ADB5-v3.db +0 -0
- package/.nx/workspace-data/0091ABA9-5C90-580D-953C-8C94E763ADB5-v3.db-shm +0 -0
- package/.nx/workspace-data/0091ABA9-5C90-580D-953C-8C94E763ADB5-v3.db-wal +0 -0
- package/.nx/workspace-data/d/daemon.log +2353 -0
- package/.nx/workspace-data/d/server-process.json +2 -2
- package/.nx/workspace-data/file-map.json +1802 -1736
- package/.nx/workspace-data/nx_files.nxt +0 -0
- package/.nx/workspace-data/project-graph.json +7 -2
- package/apps/playground/src/app/pages/tokens-page.ts +17 -13
- package/apps/playground/src/app/snippets/filters.snippets.ts +10 -0
- package/dist/libs/africanies-icons/assets/icons.sprite.svg +7 -0
- package/dist/libs/africanies-icons/fesm2022/africanies-africanies-icons.mjs +1 -0
- package/dist/libs/africanies-icons/fesm2022/africanies-africanies-icons.mjs.map +1 -1
- package/dist/libs/africanies-icons/types/africanies-africanies-icons.d.ts +2 -2
- package/dist/libs/africanies-models/fesm2022/africanies-africanies-models.mjs +22 -8
- package/dist/libs/africanies-models/fesm2022/africanies-africanies-models.mjs.map +1 -1
- package/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs +22 -10
- package/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +1 -1
- package/dist/libs/africanies-theme/tailwind-preset.cjs +84 -16
- package/dist/libs/africanies-theme/types/africanies-africanies-theme.d.ts +4 -2
- package/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs +555 -425
- package/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +1 -1
- package/dist/libs/africanies-ui/types/africanies-africanies-ui.d.ts +140 -110
- package/libs/africanies-icons/src/assets/icons.sprite.svg +7 -0
- package/libs/africanies-icons/src/lib/icon-name.ts +1 -0
- package/libs/africanies-models/src/lib/filters/configs/seed-configs.ts +22 -8
- package/libs/africanies-theme/src/lib/mode-color.safelist.ts +12 -0
- package/libs/africanies-theme/src/lib/mode-color.service.spec.ts +55 -0
- package/libs/africanies-theme/src/lib/mode-color.service.ts +11 -11
- package/libs/africanies-theme/tailwind-preset.cjs +84 -16
- package/libs/africanies-ui/src/lib/action-menu/action-menu.component.ts +3 -3
- package/libs/africanies-ui/src/lib/alert/alert.component.ts +4 -4
- package/libs/africanies-ui/src/lib/avatar/avatar-menu.component.ts +2 -2
- package/libs/africanies-ui/src/lib/button/button.component.spec.ts +7 -7
- package/libs/africanies-ui/src/lib/button/button.component.ts +5 -5
- package/libs/africanies-ui/src/lib/chip/chip.component.ts +4 -4
- package/libs/africanies-ui/src/lib/content-stack/content-stack.component.ts +1 -1
- package/libs/africanies-ui/src/lib/feedback/error-indicator.component.ts +3 -3
- package/libs/africanies-ui/src/lib/feedback/error-state.component.ts +2 -2
- package/libs/africanies-ui/src/lib/filters/filter-drawer.panel.ts +44 -27
- package/libs/africanies-ui/src/lib/forms/checkbox/checkbox.component.ts +2 -1
- package/libs/africanies-ui/src/lib/forms/file-upload/file-preview.dialog.ts +1 -1
- package/libs/africanies-ui/src/lib/forms/file-upload/file-upload.component.ts +1 -1
- package/libs/africanies-ui/src/lib/forms/form-field.classes.ts +36 -6
- package/libs/africanies-ui/src/lib/forms/otp-input/otp-input.component.ts +2 -1
- package/libs/africanies-ui/src/lib/forms/radio/radio.component.ts +2 -1
- package/libs/africanies-ui/src/lib/forms/select/select.component.ts +1 -1
- package/libs/africanies-ui/src/lib/forms/toggle/toggle.component.ts +1 -1
- package/libs/africanies-ui/src/lib/image/image.component.ts +1 -1
- package/libs/africanies-ui/src/lib/info-popover/info-popover.component.ts +2 -2
- package/libs/africanies-ui/src/lib/layout/app-shell-content-header.component.ts +1 -1
- package/libs/africanies-ui/src/lib/layout/app-shell-header.component.ts +5 -5
- package/libs/africanies-ui/src/lib/layout/app-shell.component.html +2 -2
- package/libs/africanies-ui/src/lib/layout/app-shell.component.ts +3 -3
- package/libs/africanies-ui/src/lib/navigation/shipping-mode-switch/shipping-mode-switch.component.ts +6 -6
- package/libs/africanies-ui/src/lib/navigation/side-nav/africanies-side-nav.component.html +21 -13
- package/libs/africanies-ui/src/lib/navigation/side-nav/africanies-side-nav.component.ts +13 -7
- package/libs/africanies-ui/src/lib/notifications/notification-drawer.panel.ts +6 -6
- package/libs/africanies-ui/src/lib/overlay/confirm-dialog.component.ts +2 -2
- package/libs/africanies-ui/src/lib/overlay/drawer.service.ts +2 -2
- package/libs/africanies-ui/src/lib/overlay/modal.service.ts +3 -3
- package/libs/africanies-ui/src/lib/overlay/overlay-frame.component.ts +1 -1
- package/libs/africanies-ui/src/lib/pagination/pagination.component.ts +1 -1
- package/libs/africanies-ui/src/lib/stepper/stepper.component.ts +7 -7
- package/libs/africanies-ui/src/lib/table/table-column.ts +9 -0
- package/libs/africanies-ui/src/lib/table/table.component.spec.ts +99 -0
- package/libs/africanies-ui/src/lib/table/table.component.ts +72 -30
- package/libs/africanies-ui/src/lib/toast/toast-item.component.ts +6 -6
- package/package.json +1 -1
- package/svg/hand-coins.svg +9 -0
- package/.nx/cache/12276756491762927325/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs +0 -215
- package/.nx/cache/12276756491762927325/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +0 -1
- package/.nx/cache/12276756491762927325/dist/libs/africanies-theme/tailwind-preset.cjs +0 -245
- package/.nx/cache/12276756491762927325/dist/libs/africanies-theme/types/africanies-africanies-theme.d.ts +0 -157
- package/.nx/cache/17491371155400585077/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs.map +0 -1
- package/.nx/cache/17499961385238663835/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +0 -1
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/README.md +0 -68
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/assets/brand/africanies-logo-mini.png +0 -0
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/assets/brand/africanies-logo.png +0 -0
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/assets/brand/africanies-logo.svg +0 -5
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/assets/carriers/dhl.svg +0 -7
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs +0 -19291
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +0 -1
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/package.json +0 -35
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/types/africanies-africanies-ui.d.ts +0 -5483
- package/.nx/cache/4082520855419352840/dist/libs/africanies-theme/README.md +0 -46
- package/.nx/cache/4082520855419352840/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +0 -1
- package/.nx/cache/4082520855419352840/dist/libs/africanies-theme/package.json +0 -35
- package/.nx/cache/terminalOutputs/17499961385238663835 +0 -21
- package/.nx/cache/terminalOutputs/3017748574492080228 +0 -28
- /package/.nx/cache/{12276756491762927325 → 15302120112746851896}/dist/libs/africanies-theme/README.md +0 -0
- /package/.nx/cache/{12276756491762927325 → 15302120112746851896}/dist/libs/africanies-theme/package.json +0 -0
- /package/.nx/cache/{17491371155400585077 → 18393832731522001121}/dist/libs/africanies-core/README.md +0 -0
- /package/.nx/cache/{17491371155400585077 → 18393832731522001121}/dist/libs/africanies-core/package.json +0 -0
- /package/.nx/cache/{17499961385238663835 → 9406544675747598148}/dist/libs/africanies-ui/README.md +0 -0
- /package/.nx/cache/{17499961385238663835 → 9406544675747598148}/dist/libs/africanies-ui/assets/brand/africanies-logo-mini.png +0 -0
- /package/.nx/cache/{17499961385238663835 → 9406544675747598148}/dist/libs/africanies-ui/assets/brand/africanies-logo.png +0 -0
- /package/.nx/cache/{17499961385238663835 → 9406544675747598148}/dist/libs/africanies-ui/assets/brand/africanies-logo.svg +0 -0
- /package/.nx/cache/{17499961385238663835 → 9406544675747598148}/dist/libs/africanies-ui/assets/carriers/dhl.svg +0 -0
- /package/.nx/cache/{17499961385238663835 → 9406544675747598148}/dist/libs/africanies-ui/package.json +0 -0
- /package/.nx/cache/terminalOutputs/{16279119293212733518 → 14005735098959303198} +0 -0
|
@@ -161,8 +161,8 @@ export class ConfirmDialogComponent {
|
|
|
161
161
|
const well =
|
|
162
162
|
'inline-flex size-14 shrink-0 items-center justify-center rounded-2xl';
|
|
163
163
|
return this.options.danger
|
|
164
|
-
? `${well} bg-danger-subtle text-danger dark:bg-danger/20 dark:text-danger`
|
|
165
|
-
: `${well} bg-export-subtle text-export dark:bg-export/20 dark:text-export-light`;
|
|
164
|
+
? `${well} bg-danger-subtle text-danger-dark dark:bg-danger/20 dark:text-danger`
|
|
165
|
+
: `${well} bg-export-subtle text-export-strong dark:bg-export/20 dark:text-export-light`;
|
|
166
166
|
});
|
|
167
167
|
|
|
168
168
|
constructor() {
|
|
@@ -63,11 +63,11 @@ export class DrawerService implements OverlayOpener {
|
|
|
63
63
|
],
|
|
64
64
|
panelClass: [
|
|
65
65
|
'africanies-drawer-panel',
|
|
66
|
-
'bg-
|
|
66
|
+
'bg-surface',
|
|
67
67
|
'dark:bg-ink-950',
|
|
68
68
|
'text-ink',
|
|
69
69
|
'dark:text-white',
|
|
70
|
-
'shadow-
|
|
70
|
+
'shadow-floating',
|
|
71
71
|
'border-l',
|
|
72
72
|
'border-border',
|
|
73
73
|
'dark:border-white/15',
|
|
@@ -151,12 +151,12 @@ export class ModalService implements OverlayOpener {
|
|
|
151
151
|
],
|
|
152
152
|
panelClass: [
|
|
153
153
|
'africanies-modal-panel',
|
|
154
|
-
'bg-
|
|
154
|
+
'bg-surface',
|
|
155
155
|
'dark:bg-ink-950',
|
|
156
156
|
'text-ink',
|
|
157
157
|
'dark:text-white',
|
|
158
|
-
'rounded-
|
|
159
|
-
'shadow-
|
|
158
|
+
'rounded-panel',
|
|
159
|
+
'shadow-floating',
|
|
160
160
|
'border',
|
|
161
161
|
'border-border',
|
|
162
162
|
'dark:border-white/15',
|
|
@@ -83,7 +83,7 @@ export class OverlayFooterDirective {}
|
|
|
83
83
|
<ng-content select="[africaniesOverlayHeader]" />
|
|
84
84
|
</div>
|
|
85
85
|
<div
|
|
86
|
-
class="africanies-overlay-scroll min-h-0 flex-1 overflow-x-clip overflow-y-auto px-
|
|
86
|
+
class="africanies-overlay-scroll min-h-0 flex-1 overflow-x-clip overflow-y-auto px-1 -mx-1"
|
|
87
87
|
>
|
|
88
88
|
<ng-content />
|
|
89
89
|
</div>
|
|
@@ -144,7 +144,7 @@ type PageItem = number | 'ellipsis';
|
|
|
144
144
|
@for (item of pageItems(); track trackPageItem(item, $index)) {
|
|
145
145
|
@if (item === 'ellipsis') {
|
|
146
146
|
<span
|
|
147
|
-
class="inline-flex min-w-8 items-center justify-center text-body-sm text-neutral-
|
|
147
|
+
class="inline-flex min-w-8 items-center justify-center text-body-sm text-neutral-600 dark:text-neutral-400"
|
|
148
148
|
aria-hidden="true"
|
|
149
149
|
>
|
|
150
150
|
…
|
|
@@ -53,9 +53,9 @@ function prefersReducedMotion(): boolean {
|
|
|
53
53
|
.africanies-step-body {
|
|
54
54
|
min-width: 0;
|
|
55
55
|
overflow-x: clip;
|
|
56
|
-
/*
|
|
57
|
-
padding-inline:
|
|
58
|
-
margin-inline: -
|
|
56
|
+
/* 4 px breathing room so any remaining external focus rings are not clipped */
|
|
57
|
+
padding-inline: 4px;
|
|
58
|
+
margin-inline: -4px;
|
|
59
59
|
}
|
|
60
60
|
.africanies-step-pane {
|
|
61
61
|
min-width: 0;
|
|
@@ -66,7 +66,7 @@ function prefersReducedMotion(): boolean {
|
|
|
66
66
|
<div class="flex flex-col gap-5 text-ink dark:text-white">
|
|
67
67
|
<div class="flex flex-col gap-2">
|
|
68
68
|
<p
|
|
69
|
-
class="m-0 text-caption font-medium uppercase tracking-wide text-neutral-
|
|
69
|
+
class="m-0 text-caption font-medium uppercase tracking-wide text-neutral-600 dark:text-neutral-400"
|
|
70
70
|
>
|
|
71
71
|
Step {{ activeIndex() + 1 }} of {{ steps().length }}
|
|
72
72
|
<span
|
|
@@ -95,7 +95,7 @@ function prefersReducedMotion(): boolean {
|
|
|
95
95
|
<li class="flex min-w-0 shrink-0 items-center gap-1">
|
|
96
96
|
<button
|
|
97
97
|
type="button"
|
|
98
|
-
class="inline-flex max-w-38 items-center gap-2 rounded-lg px-2 py-1.5 text-left transition-colors focus-visible:outline-
|
|
98
|
+
class="inline-flex max-w-38 items-center gap-2 rounded-lg px-2 py-1.5 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ink disabled:cursor-not-allowed"
|
|
99
99
|
[class]="headerButtonClass(i)"
|
|
100
100
|
[attr.aria-current]="i === activeIndex() ? 'step' : null"
|
|
101
101
|
[disabled]="!canActivate(i)"
|
|
@@ -223,7 +223,7 @@ export class StepperComponent {
|
|
|
223
223
|
if (past) {
|
|
224
224
|
return 'cursor-pointer text-ink hover:bg-background-welcome dark:text-white dark:hover:bg-white/10';
|
|
225
225
|
}
|
|
226
|
-
return 'opacity-40 text-neutral-
|
|
226
|
+
return 'opacity-40 text-neutral-600 dark:text-neutral-400';
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
protected stepBadgeClass(index: number): string {
|
|
@@ -233,7 +233,7 @@ export class StepperComponent {
|
|
|
233
233
|
const c = this.modeColor.classes();
|
|
234
234
|
return `${base} ${c.border} ${c.bg} text-white`;
|
|
235
235
|
}
|
|
236
|
-
return `${base} border-
|
|
236
|
+
return `${base} border-control bg-surface text-neutral-600 dark:border-white/20 dark:bg-ink-950 dark:text-neutral-400`;
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
protected canActivate(index: number): boolean {
|
|
@@ -34,6 +34,15 @@ export interface TableColumn<T = unknown> {
|
|
|
34
34
|
*/
|
|
35
35
|
width?: string;
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Optional CSS max-width (e.g. `'14rem'`).
|
|
39
|
+
*
|
|
40
|
+
* Caps growth for text-heavy columns without forcing a large minimum the
|
|
41
|
+
* way {@link width} can. Prefer this for Name / Description / Message when
|
|
42
|
+
* other columns should stay compact.
|
|
43
|
+
*/
|
|
44
|
+
maxWidth?: string;
|
|
45
|
+
|
|
37
46
|
/**
|
|
38
47
|
* Pin the column while the table scrolls horizontally.
|
|
39
48
|
*
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Component, signal } from '@angular/core';
|
|
2
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
3
|
+
|
|
4
|
+
import { ShippingModeService } from '@africanies/africanies-core';
|
|
5
|
+
import type { ShippingMode } from '@africanies/africanies-models';
|
|
6
|
+
|
|
7
|
+
import { TableComponent } from './table.component';
|
|
8
|
+
import type { TableColumn } from './table-column';
|
|
9
|
+
|
|
10
|
+
interface Row {
|
|
11
|
+
id: number;
|
|
12
|
+
name: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@Component({
|
|
16
|
+
standalone: true,
|
|
17
|
+
imports: [TableComponent],
|
|
18
|
+
template: `
|
|
19
|
+
<africanies-table
|
|
20
|
+
[columns]="columns"
|
|
21
|
+
[rows]="rows()"
|
|
22
|
+
[loading]="loading()"
|
|
23
|
+
[error]="error()"
|
|
24
|
+
loadingLabel="Loading page…"
|
|
25
|
+
/>
|
|
26
|
+
`,
|
|
27
|
+
})
|
|
28
|
+
class TableHostComponent {
|
|
29
|
+
readonly columns: TableColumn<Row>[] = [{ key: 'name', header: 'Name' }];
|
|
30
|
+
readonly rows = signal<Row[]>([]);
|
|
31
|
+
readonly loading = signal(false);
|
|
32
|
+
readonly error = signal<string | null>(null);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describe('TableComponent keep-rows loading', () => {
|
|
36
|
+
let fixture: ComponentFixture<TableHostComponent>;
|
|
37
|
+
let host: TableHostComponent;
|
|
38
|
+
|
|
39
|
+
beforeEach(async () => {
|
|
40
|
+
const mode = signal<ShippingMode>('sfn');
|
|
41
|
+
await TestBed.configureTestingModule({
|
|
42
|
+
imports: [TableHostComponent],
|
|
43
|
+
providers: [
|
|
44
|
+
{
|
|
45
|
+
provide: ShippingModeService,
|
|
46
|
+
useValue: {
|
|
47
|
+
mode: mode.asReadonly(),
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
}).compileComponents();
|
|
52
|
+
|
|
53
|
+
fixture = TestBed.createComponent(TableHostComponent);
|
|
54
|
+
host = fixture.componentInstance;
|
|
55
|
+
fixture.detectChanges();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
afterEach(() => {
|
|
59
|
+
fixture.destroy();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('shows a keep-rows overlay when loading with rows on screen', () => {
|
|
63
|
+
host.rows.set([{ id: 1, name: 'Ada' }]);
|
|
64
|
+
host.loading.set(true);
|
|
65
|
+
fixture.detectChanges();
|
|
66
|
+
|
|
67
|
+
const root = fixture.nativeElement as HTMLElement;
|
|
68
|
+
expect(
|
|
69
|
+
root.querySelector('[data-testid="africanies-table-keep-rows-loading"]'),
|
|
70
|
+
).not.toBeNull();
|
|
71
|
+
expect(root.textContent).toContain('Ada');
|
|
72
|
+
expect(root.textContent).toContain('Loading page…');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('uses the in-grid body loader on first load with no rows', () => {
|
|
76
|
+
host.rows.set([]);
|
|
77
|
+
host.loading.set(true);
|
|
78
|
+
fixture.detectChanges();
|
|
79
|
+
|
|
80
|
+
const root = fixture.nativeElement as HTMLElement;
|
|
81
|
+
expect(
|
|
82
|
+
root.querySelector('[data-testid="africanies-table-keep-rows-loading"]'),
|
|
83
|
+
).toBeNull();
|
|
84
|
+
expect(root.textContent).toContain('Loading page…');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('shows a full-width stale error when rows remain after a failed fetch', () => {
|
|
88
|
+
host.rows.set([{ id: 1, name: 'Ada' }]);
|
|
89
|
+
host.error.set('Could not load page.');
|
|
90
|
+
fixture.detectChanges();
|
|
91
|
+
|
|
92
|
+
const root = fixture.nativeElement as HTMLElement;
|
|
93
|
+
const indicator = root.querySelector('africanies-error-indicator');
|
|
94
|
+
expect(indicator).not.toBeNull();
|
|
95
|
+
expect(indicator?.className).toContain('w-full');
|
|
96
|
+
expect(root.textContent).toContain('Could not load page.');
|
|
97
|
+
expect(root.textContent).toContain('Ada');
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -39,11 +39,11 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
39
39
|
* Hidden while the body shows empty or error — those states expose Retry instead.
|
|
40
40
|
* While {@link refreshing} is true the rows stay on screen — the refresh icon
|
|
41
41
|
* spins (do not swap to a blocking loader). Use {@link loading} when the page
|
|
42
|
-
* of data is changing (pagination / size): rows stay on screen
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* rows
|
|
46
|
-
* mounted.
|
|
42
|
+
* of data is changing (pagination / size): rows stay on screen, a keep-rows
|
|
43
|
+
* overlay covers the grid, and the built-in pager shows a circular spinner
|
|
44
|
+
* beside the page controls; the body loader appears only when there are no
|
|
45
|
+
* rows yet (first load) or the host cleared rows for a shipping-mode switch
|
|
46
|
+
* (STN ↔ SFN). Toolbar and column headers stay mounted.
|
|
47
47
|
* top-right **Filters** then **Export** (`showFilter` / `showExport`). The table
|
|
48
48
|
* does not own fetch, filter, or export logic — the host handles those events.
|
|
49
49
|
*
|
|
@@ -102,6 +102,11 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
102
102
|
* to the left when rows are expandable. Override with
|
|
103
103
|
* {@link TableColumn.sticky}. Sticky columns use a slightly thicker bottom
|
|
104
104
|
* border (and opaque fill) so dividers stay visible while scrolling.
|
|
105
|
+
*
|
|
106
|
+
* **Sticky header (desktop):** when {@link stickyHeader} is true (default),
|
|
107
|
+
* large screens scroll the grid inside a capped viewport and keep `th` pinned
|
|
108
|
+
* to the top of that scrollport. Mobile keeps horizontal-only overflow so
|
|
109
|
+
* page scroll is unchanged.
|
|
105
110
|
*/
|
|
106
111
|
@Component({
|
|
107
112
|
selector: 'africanies-table',
|
|
@@ -124,7 +129,7 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
124
129
|
/* Full-row hover: sticky action cells use an opaque fill that would
|
|
125
130
|
otherwise mask a <tr> background. Paint every cell the same way. */
|
|
126
131
|
:host tr.africanies-table-row:hover > td {
|
|
127
|
-
background-color: #
|
|
132
|
+
background-color: #e9eef5;
|
|
128
133
|
}
|
|
129
134
|
:host-context(.dark) tr.africanies-table-row:hover > td {
|
|
130
135
|
background-color: #272729;
|
|
@@ -196,19 +201,19 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
196
201
|
}
|
|
197
202
|
|
|
198
203
|
@if (staleError(); as staleMessage) {
|
|
199
|
-
<
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
/>
|
|
207
|
-
</div>
|
|
204
|
+
<africanies-error-indicator
|
|
205
|
+
class="w-full"
|
|
206
|
+
[error]="staleMessage"
|
|
207
|
+
retryText="Refresh"
|
|
208
|
+
[refreshing]="refreshing()"
|
|
209
|
+
(retry)="refreshClick.emit()"
|
|
210
|
+
/>
|
|
208
211
|
}
|
|
209
212
|
|
|
210
213
|
<div
|
|
211
|
-
class="min-w-0 w-full overflow-x-auto rounded-
|
|
214
|
+
class="relative min-w-0 w-full overflow-x-auto rounded-panel border border-border bg-surface dark:border-white/10 dark:bg-ink-surface"
|
|
215
|
+
[class.lg:max-h-[min(70dvh,calc(100dvh-12rem))]]="stickyHeader()"
|
|
216
|
+
[class.lg:overflow-auto]="stickyHeader()"
|
|
212
217
|
>
|
|
213
218
|
<table
|
|
214
219
|
class="w-max min-w-full table-auto border-separate border-spacing-0 bg-inherit text-left text-body text-ink dark:text-white"
|
|
@@ -223,7 +228,7 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
223
228
|
@if (someRowsExpanded()) {
|
|
224
229
|
<button
|
|
225
230
|
type="button"
|
|
226
|
-
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-600 transition-colors hover:bg-
|
|
231
|
+
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-600 transition-colors hover:bg-surface hover:text-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus dark:text-neutral-400 dark:hover:bg-white/10 dark:hover:text-white"
|
|
227
232
|
aria-label="Collapse all"
|
|
228
233
|
(click)="collapseAllRows()"
|
|
229
234
|
>
|
|
@@ -232,7 +237,7 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
232
237
|
} @else {
|
|
233
238
|
<button
|
|
234
239
|
type="button"
|
|
235
|
-
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-600 transition-colors hover:bg-
|
|
240
|
+
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-600 transition-colors hover:bg-surface hover:text-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus disabled:cursor-not-allowed disabled:opacity-40 dark:text-neutral-400 dark:hover:bg-white/10 dark:hover:text-white"
|
|
236
241
|
aria-label="Expand all"
|
|
237
242
|
[disabled]="rowList().length === 0"
|
|
238
243
|
(click)="expandAllRows()"
|
|
@@ -246,7 +251,8 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
246
251
|
<th
|
|
247
252
|
scope="col"
|
|
248
253
|
[class]="headerCellClass(col)"
|
|
249
|
-
[style.width]="col.width ?? null"
|
|
254
|
+
[style.width]="col.width ?? col.maxWidth ?? null"
|
|
255
|
+
[style.max-width]="col.maxWidth ?? null"
|
|
250
256
|
>
|
|
251
257
|
@if (headerTemplateFor(col.key); as headerTpl) {
|
|
252
258
|
<ng-container
|
|
@@ -255,7 +261,7 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
255
261
|
} @else if (col.sortable) {
|
|
256
262
|
<button
|
|
257
263
|
type="button"
|
|
258
|
-
class="inline-flex cursor-pointer items-center gap-1 rounded-sm font-medium text-neutral-600 hover:text-ink focus-visible:outline focus-visible:
|
|
264
|
+
class="inline-flex cursor-pointer items-center gap-1 rounded-sm font-medium text-neutral-600 hover:text-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus dark:text-neutral-400 dark:hover:text-white"
|
|
259
265
|
(click)="onSortHeaderClick(col.key)"
|
|
260
266
|
>
|
|
261
267
|
<span>{{ col.header }}</span>
|
|
@@ -311,7 +317,7 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
311
317
|
<td [class]="expandBodyClass(i)">
|
|
312
318
|
<button
|
|
313
319
|
type="button"
|
|
314
|
-
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-600 transition-colors hover:bg-background-
|
|
320
|
+
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-600 transition-colors hover:bg-background-hover hover:text-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus dark:text-neutral-400 dark:hover:bg-white/10 dark:hover:text-white"
|
|
315
321
|
[attr.aria-label]="
|
|
316
322
|
isRowExpanded(row, i)
|
|
317
323
|
? 'Collapse row details'
|
|
@@ -330,7 +336,8 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
330
336
|
@for (col of columns(); track col.key) {
|
|
331
337
|
<td
|
|
332
338
|
[class]="bodyCellClass(col, i)"
|
|
333
|
-
[style.width]="col.width ?? null"
|
|
339
|
+
[style.width]="col.width ?? col.maxWidth ?? null"
|
|
340
|
+
[style.max-width]="col.maxWidth ?? null"
|
|
334
341
|
>
|
|
335
342
|
@if (templateFor(col.key); as tpl) {
|
|
336
343
|
<ng-container
|
|
@@ -360,7 +367,7 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
360
367
|
[class.pointer-events-none]="!isRowExpanded(row, i)"
|
|
361
368
|
>
|
|
362
369
|
<div
|
|
363
|
-
class="min-h-0 overflow-hidden border-t border-border
|
|
370
|
+
class="min-h-0 overflow-hidden border-t border-border-strong bg-surface-sunken dark:border-white/10 dark:bg-white/[0.05]"
|
|
364
371
|
>
|
|
365
372
|
<dl
|
|
366
373
|
class="m-0 grid gap-x-6 gap-y-3 px-[1.125rem] py-4 transition-opacity duration-200 ease-out motion-reduce:transition-none sm:grid-cols-2 lg:grid-cols-3"
|
|
@@ -370,7 +377,7 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
370
377
|
@for (detail of rowDetailDefs(); track detail.label()) {
|
|
371
378
|
<div class="min-w-0">
|
|
372
379
|
<dt
|
|
373
|
-
class="m-0 text-caption font-medium text-neutral-
|
|
380
|
+
class="m-0 text-caption font-medium text-neutral-600 dark:text-neutral-400"
|
|
374
381
|
>
|
|
375
382
|
{{ detail.label() }}
|
|
376
383
|
</dt>
|
|
@@ -395,6 +402,18 @@ import { TableColumn, TableSortChange } from './table-column';
|
|
|
395
402
|
}
|
|
396
403
|
</tbody>
|
|
397
404
|
</table>
|
|
405
|
+
@if (paginationLoading()) {
|
|
406
|
+
<div
|
|
407
|
+
class="pointer-events-none absolute inset-0 z-[5] flex items-start justify-center bg-surface/70 px-4 pt-16 dark:bg-ink-950/70"
|
|
408
|
+
data-testid="africanies-table-keep-rows-loading"
|
|
409
|
+
aria-hidden="true"
|
|
410
|
+
>
|
|
411
|
+
<africanies-loading-state
|
|
412
|
+
mode="inline"
|
|
413
|
+
[message]="loadingLabel()"
|
|
414
|
+
/>
|
|
415
|
+
</div>
|
|
416
|
+
}
|
|
398
417
|
</div>
|
|
399
418
|
|
|
400
419
|
@if (meta(); as pager) {
|
|
@@ -431,6 +450,13 @@ export class TableComponent<T = unknown> {
|
|
|
431
450
|
/** Column definitions (header chrome + keys). */
|
|
432
451
|
readonly columns = input.required<TableColumn<T>[]>();
|
|
433
452
|
|
|
453
|
+
/**
|
|
454
|
+
* When true (default), pin column headers while scrolling the grid on
|
|
455
|
+
* large screens (`lg+`). Uses a capped scrollport so sticky works with
|
|
456
|
+
* horizontal overflow. Set false to keep the previous unconstrained layout.
|
|
457
|
+
*/
|
|
458
|
+
readonly stickyHeader = input(true, { transform: booleanAttribute });
|
|
459
|
+
|
|
434
460
|
/**
|
|
435
461
|
* Row records to render. Empty arrays show {@link EmptyStateComponent} in
|
|
436
462
|
* the body unless {@link loading} or {@link error} is set. Missing `data`
|
|
@@ -463,9 +489,9 @@ export class TableComponent<T = unknown> {
|
|
|
463
489
|
|
|
464
490
|
/**
|
|
465
491
|
* Page of data is loading (first load, shipping-mode switch, pagination,
|
|
466
|
-
* page size). When rows are already on screen,
|
|
467
|
-
* and
|
|
468
|
-
* dropped STN/SFN rows after a mode switch), the body shows
|
|
492
|
+
* page size). When rows are already on screen, a keep-rows overlay covers
|
|
493
|
+
* the grid and the pager shows a spinner; when there are no rows (first
|
|
494
|
+
* load or the host dropped STN/SFN rows after a mode switch), the body shows
|
|
469
495
|
* {@link LoadingStateComponent}. Distinct from {@link refreshing}.
|
|
470
496
|
*/
|
|
471
497
|
readonly loading = input(false, { transform: booleanAttribute });
|
|
@@ -754,10 +780,22 @@ export class TableComponent<T = unknown> {
|
|
|
754
780
|
'border-border whitespace-normal wrap-break-word px-[1.125rem] py-4 font-medium text-neutral-600 dark:border-white/10 dark:text-neutral-400 ' +
|
|
755
781
|
this.headerSoftClass() +
|
|
756
782
|
' ' +
|
|
757
|
-
this.stickySurfaceClass(col, 'head')
|
|
783
|
+
this.stickySurfaceClass(col, 'head') +
|
|
784
|
+
(sticky ? '' : this.headerStickClass())
|
|
758
785
|
);
|
|
759
786
|
}
|
|
760
787
|
|
|
788
|
+
/**
|
|
789
|
+
* Vertical pin for scrolling header cells on desktop. Pinned left/right
|
|
790
|
+
* headers get `lg:top-0` from {@link stickyPinClass} instead.
|
|
791
|
+
*/
|
|
792
|
+
protected headerStickClass(): string {
|
|
793
|
+
if (!this.stickyHeader()) {
|
|
794
|
+
return '';
|
|
795
|
+
}
|
|
796
|
+
return ' lg:sticky lg:top-0 lg:z-[3] print:static';
|
|
797
|
+
}
|
|
798
|
+
|
|
761
799
|
/**
|
|
762
800
|
* Body cell classes, including sticky pin when set.
|
|
763
801
|
* Sticky expand/actions columns use a 1.5px bottom border; scrolling cells
|
|
@@ -804,9 +842,13 @@ export class TableComponent<T = unknown> {
|
|
|
804
842
|
edge === 'right' ? 'sticky right-0 z-[1]' : 'sticky left-0 z-[1]';
|
|
805
843
|
if (surface === 'head') {
|
|
806
844
|
// Fill comes from {@link headerSoftClass} on the cell — do not re-tint.
|
|
807
|
-
|
|
845
|
+
// Corner pins also stick vertically on desktop when stickyHeader is on.
|
|
846
|
+
const vertical = this.stickyHeader()
|
|
847
|
+
? ' z-[2] lg:top-0 lg:z-[4] print:static'
|
|
848
|
+
: ' z-[2]';
|
|
849
|
+
return `${side}${vertical}`;
|
|
808
850
|
}
|
|
809
|
-
const fill = 'bg-
|
|
851
|
+
const fill = 'bg-surface dark:bg-ink-surface';
|
|
810
852
|
return `${side} ${fill}`;
|
|
811
853
|
}
|
|
812
854
|
|
|
@@ -260,8 +260,8 @@ export class ToastItemComponent {
|
|
|
260
260
|
|
|
261
261
|
protected readonly shellClass = computed(
|
|
262
262
|
() =>
|
|
263
|
-
'africanies-toast-enter relative flex w-full overflow-hidden rounded-
|
|
264
|
-
'bg-
|
|
263
|
+
'africanies-toast-enter relative flex w-full overflow-hidden rounded-panel border border-border ' +
|
|
264
|
+
'bg-surface/95 text-ink shadow-floating backdrop-blur-md ' +
|
|
265
265
|
'dark:border-white/15 dark:bg-ink-950/95 dark:text-white',
|
|
266
266
|
);
|
|
267
267
|
|
|
@@ -272,11 +272,11 @@ export class ToastItemComponent {
|
|
|
272
272
|
protected readonly iconClass = computed(() => {
|
|
273
273
|
switch (this.item().variant) {
|
|
274
274
|
case 'success':
|
|
275
|
-
return 'text-export dark:text-export-light';
|
|
275
|
+
return 'text-export-strong dark:text-export-light';
|
|
276
276
|
case 'warning':
|
|
277
277
|
return 'text-warning-dark dark:text-warning';
|
|
278
278
|
case 'danger':
|
|
279
|
-
return 'text-danger';
|
|
279
|
+
return 'text-danger-dark dark:text-danger';
|
|
280
280
|
default:
|
|
281
281
|
return 'text-ink-blue dark:text-neutral-300';
|
|
282
282
|
}
|
|
@@ -286,11 +286,11 @@ export class ToastItemComponent {
|
|
|
286
286
|
const base = 'm-0 break-words text-body-sm font-semibold';
|
|
287
287
|
switch (this.item().variant) {
|
|
288
288
|
case 'success':
|
|
289
|
-
return `${base} text-export dark:text-export-light`;
|
|
289
|
+
return `${base} text-export-strong dark:text-export-light`;
|
|
290
290
|
case 'warning':
|
|
291
291
|
return `${base} text-warning-dark dark:text-warning`;
|
|
292
292
|
case 'danger':
|
|
293
|
-
return `${base} text-danger`;
|
|
293
|
+
return `${base} text-danger-dark dark:text-danger`;
|
|
294
294
|
default:
|
|
295
295
|
return `${base} text-ink dark:text-white`;
|
|
296
296
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<svg width="16" height="15" viewBox="0 0 16 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path
|
|
3
|
+
fill-rule="evenodd"
|
|
4
|
+
clip-rule="evenodd"
|
|
5
|
+
d="M0.142433 5.8125C0.142433 6.8115 0.394433 7.74975 0.836933 8.5695C0.62996 8.65739 0.447722 8.79474 0.30621 8.96949C0.164697 9.14424 0.0682364 9.35105 0.0252912 9.57178C-0.0176541 9.7925 -0.00577094 10.0204 0.0598977 10.2354C0.125566 10.4505 0.243013 10.6462 0.401933 10.8053L3.64643 14.049C3.95198 14.3546 4.32385 14.5858 4.73318 14.7244C5.14251 14.8631 5.57829 14.9055 6.00668 14.8485L10.4924 14.25H12.8924V15H15.5174V13.875H14.0174V8.25H15.5174V7.125H12.8924V7.875H11.3909C11.7249 6.99496 11.8402 6.04697 11.7269 5.11253C11.6135 4.17809 11.2749 3.28516 10.7402 2.51051C10.2054 1.73585 9.49058 1.10266 8.65704 0.665352C7.8235 0.228047 6.89622 -0.00028052 5.95493 2.58646e-07C4.41336 2.58646e-07 2.93493 0.612387 1.84488 1.70244C0.75482 2.7925 0.142433 4.27093 0.142433 5.8125ZM5.95493 1.125C5.0719 1.12517 4.20686 1.37472 3.45942 1.84492C2.71198 2.31512 2.11253 2.98685 1.73009 3.78277C1.34765 4.57869 1.19776 5.46644 1.29769 6.3438C1.39762 7.22116 1.7433 8.05247 2.29493 8.742L4.64768 9.7995C4.6685 9.54613 4.74629 9.30073 4.87525 9.08164C5.00421 8.86255 5.18101 8.67542 5.39243 8.53425V8.25H4.64243V7.125H6.14243C6.24189 7.125 6.33727 7.08549 6.4076 7.01517C6.47792 6.94484 6.51743 6.84946 6.51743 6.75C6.51743 6.65054 6.47792 6.55516 6.4076 6.48483C6.33727 6.41451 6.24189 6.375 6.14243 6.375H5.76743C5.40208 6.37536 5.04916 6.24237 4.77491 6.00099C4.50066 5.7596 4.32393 5.42642 4.2779 5.06398C4.23187 4.70155 4.3197 4.33477 4.52491 4.03249C4.73012 3.73022 5.03859 3.51323 5.39243 3.42225V2.625H6.51743V3.375H7.26743V4.5H5.76743C5.66798 4.5 5.57259 4.53951 5.50227 4.60984C5.43194 4.68016 5.39243 4.77554 5.39243 4.875C5.39243 4.97446 5.43194 5.06984 5.50227 5.14017C5.57259 5.21049 5.66798 5.25 5.76743 5.25H6.14243C6.50778 5.24964 6.8607 5.38263 7.13496 5.62402C7.40921 5.8654 7.58593 6.19858 7.63196 6.56102C7.67799 6.92345 7.59016 7.29023 7.38495 7.59251C7.17975 7.89478 6.87127 8.11177 6.51743 8.20275V8.25H9.23843L10.1249 7.9545C10.4921 7.23989 10.6693 6.44291 10.6398 5.64006C10.6102 4.8372 10.3748 4.05542 9.95615 3.36973C9.53748 2.68405 8.94961 2.11748 8.24894 1.72439C7.54827 1.33131 6.75833 1.12491 5.95493 1.125ZM5.62343 11.4705L1.47593 9.60675C1.42279 9.58303 1.36303 9.57868 1.30701 9.59444C1.25099 9.6102 1.20227 9.64509 1.16929 9.69304C1.13632 9.74098 1.12118 9.79897 1.1265 9.85691C1.13182 9.91486 1.15727 9.96911 1.19843 10.0103L4.44143 13.2533C4.6248 13.4368 4.84801 13.5756 5.09372 13.6588C5.33943 13.7421 5.60103 13.7675 5.85818 13.7333L10.4182 13.125H12.8924V9H10.5464L9.42143 9.375H6.32993C6.18075 9.375 6.03767 9.43426 5.93219 9.53975C5.8267 9.64524 5.76743 9.78832 5.76743 9.9375C5.76743 10.0867 5.8267 10.2298 5.93219 10.3352C6.03767 10.4407 6.18075 10.5 6.32993 10.5H9.56243L10.4774 11.415L9.68243 12.21L9.09743 11.625H6.32993C6.07793 11.625 5.83793 11.5695 5.62343 11.4705Z"
|
|
6
|
+
fill="#1C2E45"
|
|
7
|
+
fill-opacity="0.6"
|
|
8
|
+
/>
|
|
9
|
+
</svg>
|