@africanies/angular-web-sdk 0.1.10 → 0.1.12
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/{14995846848874973576 → 14892813664845064572}/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs +1634 -1016
- package/.nx/cache/14892813664845064572/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +1 -0
- package/.nx/cache/{14995846848874973576 → 14892813664845064572}/dist/libs/africanies-ui/types/africanies-africanies-ui.d.ts +261 -137
- package/.nx/cache/{14876618240301288353 → 7821397806208783174}/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs +2641 -1011
- package/.nx/cache/7821397806208783174/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +1 -0
- package/.nx/cache/{14876618240301288353 → 7821397806208783174}/dist/libs/africanies-ui/types/africanies-africanies-ui.d.ts +460 -147
- package/.nx/cache/run.json +16 -16
- package/.nx/cache/terminalOutputs/{14876618240301288353 → 14892813664845064572} +2 -2
- package/.nx/cache/terminalOutputs/16208231681037145050 +85 -0
- package/.nx/cache/terminalOutputs/{1446890025183346611 → 17909810599991457481} +15 -7
- package/.nx/cache/terminalOutputs/{7978448102466861029 → 2927637324428060203} +41 -31
- package/.nx/cache/terminalOutputs/{17394769338046050914 → 4787481949164239892} +2 -2
- package/.nx/cache/terminalOutputs/{14995846848874973576 → 7821397806208783174} +2 -2
- 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 +3694 -0
- package/.nx/workspace-data/d/server-process.json +2 -2
- package/.nx/workspace-data/file-map.json +1508 -1478
- package/.nx/workspace-data/nx_files.nxt +0 -0
- package/.nx/workspace-data/project-graph.json +2 -2
- package/README.md +0 -17
- package/apps/playground/src/app/pages/forms-page.ts +70 -14
- package/apps/playground/src/app/snippets/forms.snippets.ts +41 -6
- package/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs +1149 -142
- package/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +1 -1
- package/dist/libs/africanies-ui/types/africanies-africanies-ui.d.ts +205 -18
- package/libs/africanies-ui/src/index.ts +18 -0
- package/libs/africanies-ui/src/lib/forms/index.ts +20 -0
- package/libs/africanies-ui/src/lib/forms/phone-input/index.ts +21 -0
- package/libs/africanies-ui/src/lib/forms/phone-input/phone-codes.ts +264 -0
- package/libs/africanies-ui/src/lib/forms/phone-input/phone-input.component.ts +477 -0
- package/libs/africanies-ui/src/lib/forms/phone-input/phone-input.types.ts +35 -0
- package/libs/africanies-ui/src/lib/forms/phone-input/phone-input.utils.spec.ts +81 -0
- package/libs/africanies-ui/src/lib/forms/phone-input/phone-input.utils.ts +275 -0
- package/libs/africanies-ui/src/lib/modules/africanies-forms.module.ts +2 -0
- package/libs/africanies-ui/src/lib/navigation/segment/segment.component.ts +2 -1
- package/libs/africanies-ui/src/lib/navigation/shipping-mode-switch/shipping-mode-switch.component.spec.ts +15 -0
- package/libs/africanies-ui/src/lib/navigation/shipping-mode-switch/shipping-mode-switch.component.ts +6 -3
- package/libs/africanies-ui/src/lib/table/table.component.ts +70 -65
- package/package.json +1 -1
- package/.nx/cache/13466509747676776487/dist/libs/africanies-core/README.md +0 -85
- package/.nx/cache/13466509747676776487/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs +0 -4634
- package/.nx/cache/13466509747676776487/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs.map +0 -1
- package/.nx/cache/13466509747676776487/dist/libs/africanies-core/package.json +0 -31
- package/.nx/cache/13466509747676776487/dist/libs/africanies-core/types/africanies-africanies-core.d.ts +0 -2743
- package/.nx/cache/14416694322692463866/dist/libs/africanies-models/README.md +0 -60
- package/.nx/cache/14416694322692463866/dist/libs/africanies-models/fesm2022/africanies-africanies-models.mjs +0 -599
- package/.nx/cache/14416694322692463866/dist/libs/africanies-models/fesm2022/africanies-africanies-models.mjs.map +0 -1
- package/.nx/cache/14416694322692463866/dist/libs/africanies-models/package.json +0 -23
- package/.nx/cache/14416694322692463866/dist/libs/africanies-models/types/africanies-africanies-models.d.ts +0 -1452
- package/.nx/cache/14876618240301288353/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +0 -1
- package/.nx/cache/14995846848874973576/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +0 -1
- package/.nx/cache/17626862048742598274/dist/libs/africanies-theme/README.md +0 -46
- package/.nx/cache/17626862048742598274/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs +0 -221
- package/.nx/cache/17626862048742598274/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +0 -1
- package/.nx/cache/17626862048742598274/dist/libs/africanies-theme/package.json +0 -35
- package/.nx/cache/17626862048742598274/dist/libs/africanies-theme/tailwind-preset.cjs +0 -253
- package/.nx/cache/17626862048742598274/dist/libs/africanies-theme/types/africanies-africanies-theme.d.ts +0 -166
- package/.nx/cache/6664915487114632770/dist/libs/africanies-icons/README.md +0 -69
- package/.nx/cache/6664915487114632770/dist/libs/africanies-icons/assets/icons.sprite.svg +0 -1844
- package/.nx/cache/6664915487114632770/dist/libs/africanies-icons/fesm2022/africanies-africanies-icons.mjs +0 -832
- package/.nx/cache/6664915487114632770/dist/libs/africanies-icons/fesm2022/africanies-africanies-icons.mjs.map +0 -1
- package/.nx/cache/6664915487114632770/dist/libs/africanies-icons/package.json +0 -30
- package/.nx/cache/6664915487114632770/dist/libs/africanies-icons/types/africanies-africanies-icons.d.ts +0 -108
- package/.nx/cache/6673686859704879504/dist/libs/africanies-theme/README.md +0 -46
- package/.nx/cache/6673686859704879504/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs +0 -231
- package/.nx/cache/6673686859704879504/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +0 -1
- package/.nx/cache/6673686859704879504/dist/libs/africanies-theme/package.json +0 -35
- package/.nx/cache/6673686859704879504/dist/libs/africanies-theme/tailwind-preset.cjs +0 -262
- package/.nx/cache/6673686859704879504/dist/libs/africanies-theme/types/africanies-africanies-theme.d.ts +0 -174
- package/.nx/cache/9040451482998546630/dist/libs/africanies-core/README.md +0 -85
- package/.nx/cache/9040451482998546630/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs +0 -4511
- package/.nx/cache/9040451482998546630/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs.map +0 -1
- package/.nx/cache/9040451482998546630/dist/libs/africanies-core/package.json +0 -31
- package/.nx/cache/9040451482998546630/dist/libs/africanies-core/types/africanies-africanies-core.d.ts +0 -2741
- package/.nx/cache/terminalOutputs/13466509747676776487 +0 -21
- package/.nx/cache/terminalOutputs/13555699813138069787 +0 -6
- package/.nx/cache/terminalOutputs/14061940909886036014 +0 -173
- package/.nx/cache/terminalOutputs/14416694322692463866 +0 -108
- package/.nx/cache/terminalOutputs/17626862048742598274 +0 -21
- package/.nx/cache/terminalOutputs/6337357866566791975 +0 -6
- package/.nx/cache/terminalOutputs/6664915487114632770 +0 -44
- package/.nx/cache/terminalOutputs/6673686859704879504 +0 -21
- package/.nx/cache/terminalOutputs/783228502946611950 +0 -19
- package/.nx/cache/terminalOutputs/9040451482998546630 +0 -21
- /package/.nx/cache/{14876618240301288353 → 14892813664845064572}/dist/libs/africanies-ui/README.md +0 -0
- /package/.nx/cache/{14876618240301288353 → 14892813664845064572}/dist/libs/africanies-ui/assets/brand/africanies-logo-mini.png +0 -0
- /package/.nx/cache/{14876618240301288353 → 14892813664845064572}/dist/libs/africanies-ui/assets/brand/africanies-logo.png +0 -0
- /package/.nx/cache/{14876618240301288353 → 14892813664845064572}/dist/libs/africanies-ui/assets/brand/africanies-logo.svg +0 -0
- /package/.nx/cache/{14876618240301288353 → 14892813664845064572}/dist/libs/africanies-ui/assets/carriers/dhl.svg +0 -0
- /package/.nx/cache/{14876618240301288353 → 14892813664845064572}/dist/libs/africanies-ui/package.json +0 -0
- /package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/README.md +0 -0
- /package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/assets/brand/africanies-logo-mini.png +0 -0
- /package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/assets/brand/africanies-logo.png +0 -0
- /package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/assets/brand/africanies-logo.svg +0 -0
- /package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/assets/carriers/dhl.svg +0 -0
- /package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/package.json +0 -0
|
@@ -92,7 +92,7 @@ class ButtonComponent {
|
|
|
92
92
|
*/
|
|
93
93
|
hostClass = computed(() => {
|
|
94
94
|
const base = 'relative inline-flex items-center justify-center gap-2 box-border font-sans font-medium rounded-md border transition-colors cursor-pointer ' +
|
|
95
|
-
'focus-visible:outline focus-visible:
|
|
95
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus ' +
|
|
96
96
|
'disabled:opacity-50 disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:cursor-not-allowed';
|
|
97
97
|
const sizes = {
|
|
98
98
|
sm: 'text-body-sm px-2.5 py-0 h-8',
|
|
@@ -112,15 +112,15 @@ class ButtonComponent {
|
|
|
112
112
|
}
|
|
113
113
|
else if (variant === 'flat') {
|
|
114
114
|
variantClass =
|
|
115
|
-
'bg-
|
|
115
|
+
'bg-surface dark:bg-ink-950 text-ink dark:text-white border-control dark:border-white/15 hover:bg-background-hover dark:hover:bg-white/10';
|
|
116
116
|
}
|
|
117
117
|
else if (variant === 'ghost') {
|
|
118
118
|
variantClass =
|
|
119
|
-
'bg-transparent text-ink dark:text-white border-transparent hover:bg-background-
|
|
119
|
+
'bg-transparent text-ink dark:text-white border-transparent hover:bg-background-hover dark:hover:bg-white/10';
|
|
120
120
|
}
|
|
121
121
|
else if (variant === 'ghost-danger') {
|
|
122
122
|
variantClass =
|
|
123
|
-
'bg-transparent text-danger border-transparent hover:bg-danger-subtle dark:hover:bg-danger/10';
|
|
123
|
+
'bg-transparent text-danger-dark border-transparent hover:bg-danger-subtle dark:text-danger dark:hover:bg-danger/10';
|
|
124
124
|
}
|
|
125
125
|
else if (variant === 'underline') {
|
|
126
126
|
variantClass =
|
|
@@ -128,7 +128,7 @@ class ButtonComponent {
|
|
|
128
128
|
}
|
|
129
129
|
else {
|
|
130
130
|
variantClass =
|
|
131
|
-
'bg-danger text-white border-transparent hover:bg-danger-dark';
|
|
131
|
+
'bg-danger-dark text-white border-transparent hover:bg-danger-strong dark:bg-danger dark:hover:bg-danger-dark';
|
|
132
132
|
}
|
|
133
133
|
return `${base} ${sizes[this.size()]} ${variantClass}`;
|
|
134
134
|
}, /* @ts-ignore */
|
|
@@ -271,8 +271,8 @@ class ToastItemComponent {
|
|
|
271
271
|
return v === 'warning' || v === 'danger' ? 'assertive' : 'polite';
|
|
272
272
|
}, /* @ts-ignore */
|
|
273
273
|
...(ngDevMode ? [{ debugName: "a11yLive" }] : /* istanbul ignore next */ []));
|
|
274
|
-
shellClass = computed(() => 'africanies-toast-enter relative flex w-full overflow-hidden rounded-
|
|
275
|
-
'bg-
|
|
274
|
+
shellClass = computed(() => 'africanies-toast-enter relative flex w-full overflow-hidden rounded-panel border border-border ' +
|
|
275
|
+
'bg-surface/95 text-ink shadow-floating backdrop-blur-md ' +
|
|
276
276
|
'dark:border-white/15 dark:bg-ink-950/95 dark:text-white', /* @ts-ignore */
|
|
277
277
|
...(ngDevMode ? [{ debugName: "shellClass" }] : /* istanbul ignore next */ []));
|
|
278
278
|
accentClass = computed(() => `w-1 shrink-0 self-stretch ${accentFill(this.item().variant)}`, /* @ts-ignore */
|
|
@@ -280,11 +280,11 @@ class ToastItemComponent {
|
|
|
280
280
|
iconClass = computed(() => {
|
|
281
281
|
switch (this.item().variant) {
|
|
282
282
|
case 'success':
|
|
283
|
-
return 'text-export dark:text-export-light';
|
|
283
|
+
return 'text-export-strong dark:text-export-light';
|
|
284
284
|
case 'warning':
|
|
285
285
|
return 'text-warning-dark dark:text-warning';
|
|
286
286
|
case 'danger':
|
|
287
|
-
return 'text-danger';
|
|
287
|
+
return 'text-danger-dark dark:text-danger';
|
|
288
288
|
default:
|
|
289
289
|
return 'text-ink-blue dark:text-neutral-300';
|
|
290
290
|
}
|
|
@@ -294,11 +294,11 @@ class ToastItemComponent {
|
|
|
294
294
|
const base = 'm-0 break-words text-body-sm font-semibold';
|
|
295
295
|
switch (this.item().variant) {
|
|
296
296
|
case 'success':
|
|
297
|
-
return `${base} text-export dark:text-export-light`;
|
|
297
|
+
return `${base} text-export-strong dark:text-export-light`;
|
|
298
298
|
case 'warning':
|
|
299
299
|
return `${base} text-warning-dark dark:text-warning`;
|
|
300
300
|
case 'danger':
|
|
301
|
-
return `${base} text-danger`;
|
|
301
|
+
return `${base} text-danger-dark dark:text-danger`;
|
|
302
302
|
default:
|
|
303
303
|
return `${base} text-ink dark:text-white`;
|
|
304
304
|
}
|
|
@@ -1504,9 +1504,9 @@ class ActionMenuComponent {
|
|
|
1504
1504
|
const active = this.activeIndex() === index;
|
|
1505
1505
|
const base = 'flex w-full cursor-pointer items-center gap-2 px-3 py-2 text-body-sm no-underline transition-colors ' +
|
|
1506
1506
|
'disabled:cursor-not-allowed disabled:opacity-50 ' +
|
|
1507
|
-
'focus-visible:outline focus-visible:
|
|
1507
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus';
|
|
1508
1508
|
if (item.danger) {
|
|
1509
|
-
return (`${base} text-danger ` +
|
|
1509
|
+
return (`${base} text-danger-dark dark:text-danger ` +
|
|
1510
1510
|
(active
|
|
1511
1511
|
? 'bg-danger-subtle dark:bg-danger/15'
|
|
1512
1512
|
: 'hover:bg-danger-subtle dark:hover:bg-danger/15'));
|
|
@@ -1710,7 +1710,7 @@ class ActionMenuComponent {
|
|
|
1710
1710
|
>
|
|
1711
1711
|
<div
|
|
1712
1712
|
#panel
|
|
1713
|
-
class="min-w-44 rounded-md border border-border bg-
|
|
1713
|
+
class="min-w-44 rounded-md border border-border bg-surface py-1 shadow-floating outline-none dark:border-white/15 dark:bg-ink-950"
|
|
1714
1714
|
role="menu"
|
|
1715
1715
|
tabindex="-1"
|
|
1716
1716
|
[attr.aria-label]="ariaLabel()"
|
|
@@ -1827,7 +1827,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
1827
1827
|
>
|
|
1828
1828
|
<div
|
|
1829
1829
|
#panel
|
|
1830
|
-
class="min-w-44 rounded-md border border-border bg-
|
|
1830
|
+
class="min-w-44 rounded-md border border-border bg-surface py-1 shadow-floating outline-none dark:border-white/15 dark:bg-ink-950"
|
|
1831
1831
|
role="menu"
|
|
1832
1832
|
tabindex="-1"
|
|
1833
1833
|
[attr.aria-label]="ariaLabel()"
|
|
@@ -2056,10 +2056,10 @@ class ErrorIndicatorComponent {
|
|
|
2056
2056
|
aria-hidden="true"
|
|
2057
2057
|
>
|
|
2058
2058
|
<span
|
|
2059
|
-
class="africanies-error-indicator-dot-ping absolute inset-0 rounded-full bg-
|
|
2059
|
+
class="africanies-error-indicator-dot-ping absolute inset-0 rounded-full bg-danger-dark opacity-75"
|
|
2060
2060
|
></span>
|
|
2061
2061
|
<span
|
|
2062
|
-
class="africanies-error-indicator-dot-core relative size-3 rounded-full bg-
|
|
2062
|
+
class="africanies-error-indicator-dot-core relative size-3 rounded-full bg-danger-dark"
|
|
2063
2063
|
></span>
|
|
2064
2064
|
</span>
|
|
2065
2065
|
|
|
@@ -2074,7 +2074,7 @@ class ErrorIndicatorComponent {
|
|
|
2074
2074
|
type="button"
|
|
2075
2075
|
variant="ghost"
|
|
2076
2076
|
size="sm"
|
|
2077
|
-
class="africanies-error-indicator-retry shrink-0 !min-h-0 !border-transparent !bg-transparent !px-1.5 !py-0.5 !text-danger hover:!bg-danger/10 dark:hover:!bg-danger/20"
|
|
2077
|
+
class="africanies-error-indicator-retry shrink-0 !min-h-0 !border-transparent !bg-transparent !px-1.5 !py-0.5 !text-danger-dark hover:!bg-danger/10 dark:hover:!bg-danger/20"
|
|
2078
2078
|
[class.opacity-50]="disabled()"
|
|
2079
2079
|
[disabled]="disabled()"
|
|
2080
2080
|
(click)="onRetry()"
|
|
@@ -2101,10 +2101,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2101
2101
|
aria-hidden="true"
|
|
2102
2102
|
>
|
|
2103
2103
|
<span
|
|
2104
|
-
class="africanies-error-indicator-dot-ping absolute inset-0 rounded-full bg-
|
|
2104
|
+
class="africanies-error-indicator-dot-ping absolute inset-0 rounded-full bg-danger-dark opacity-75"
|
|
2105
2105
|
></span>
|
|
2106
2106
|
<span
|
|
2107
|
-
class="africanies-error-indicator-dot-core relative size-3 rounded-full bg-
|
|
2107
|
+
class="africanies-error-indicator-dot-core relative size-3 rounded-full bg-danger-dark"
|
|
2108
2108
|
></span>
|
|
2109
2109
|
</span>
|
|
2110
2110
|
|
|
@@ -2119,7 +2119,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2119
2119
|
type="button"
|
|
2120
2120
|
variant="ghost"
|
|
2121
2121
|
size="sm"
|
|
2122
|
-
class="africanies-error-indicator-retry shrink-0 !min-h-0 !border-transparent !bg-transparent !px-1.5 !py-0.5 !text-danger hover:!bg-danger/10 dark:hover:!bg-danger/20"
|
|
2122
|
+
class="africanies-error-indicator-retry shrink-0 !min-h-0 !border-transparent !bg-transparent !px-1.5 !py-0.5 !text-danger-dark hover:!bg-danger/10 dark:hover:!bg-danger/20"
|
|
2123
2123
|
[class.opacity-50]="disabled()"
|
|
2124
2124
|
[disabled]="disabled()"
|
|
2125
2125
|
(click)="onRetry()"
|
|
@@ -2170,8 +2170,8 @@ class ErrorStateComponent {
|
|
|
2170
2170
|
class="flex flex-col items-center justify-center gap-3 py-10 px-4 text-center text-ink dark:text-white"
|
|
2171
2171
|
role="alert"
|
|
2172
2172
|
>
|
|
2173
|
-
<africanies-icon name="warning" [size]="32" class="text-danger" />
|
|
2174
|
-
<p class="m-0 text-body text-danger max-w-md">{{ message() }}</p>
|
|
2173
|
+
<africanies-icon name="warning" [size]="32" class="text-danger-dark dark:text-danger" />
|
|
2174
|
+
<p class="m-0 text-body text-danger-dark max-w-md dark:text-danger">{{ message() }}</p>
|
|
2175
2175
|
<button
|
|
2176
2176
|
africanies-button
|
|
2177
2177
|
type="button"
|
|
@@ -2201,8 +2201,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2201
2201
|
class="flex flex-col items-center justify-center gap-3 py-10 px-4 text-center text-ink dark:text-white"
|
|
2202
2202
|
role="alert"
|
|
2203
2203
|
>
|
|
2204
|
-
<africanies-icon name="warning" [size]="32" class="text-danger" />
|
|
2205
|
-
<p class="m-0 text-body text-danger max-w-md">{{ message() }}</p>
|
|
2204
|
+
<africanies-icon name="warning" [size]="32" class="text-danger-dark dark:text-danger" />
|
|
2205
|
+
<p class="m-0 text-body text-danger-dark max-w-md dark:text-danger">{{ message() }}</p>
|
|
2206
2206
|
<button
|
|
2207
2207
|
africanies-button
|
|
2208
2208
|
type="button"
|
|
@@ -2739,11 +2739,11 @@ class AlertComponent {
|
|
|
2739
2739
|
iconClass = computed(() => {
|
|
2740
2740
|
switch (this.variant()) {
|
|
2741
2741
|
case 'success':
|
|
2742
|
-
return 'text-export dark:text-export-light';
|
|
2742
|
+
return 'text-export-strong dark:text-export-light';
|
|
2743
2743
|
case 'warning':
|
|
2744
2744
|
return 'text-warning-dark dark:text-warning';
|
|
2745
2745
|
case 'danger':
|
|
2746
|
-
return 'text-danger';
|
|
2746
|
+
return 'text-danger-dark dark:text-danger';
|
|
2747
2747
|
default:
|
|
2748
2748
|
return 'text-ink-blue dark:text-neutral-300';
|
|
2749
2749
|
}
|
|
@@ -2753,11 +2753,11 @@ class AlertComponent {
|
|
|
2753
2753
|
const base = 'm-0 text-body font-medium';
|
|
2754
2754
|
switch (this.variant()) {
|
|
2755
2755
|
case 'success':
|
|
2756
|
-
return `${base} text-export dark:text-export-light`;
|
|
2756
|
+
return `${base} text-export-strong dark:text-export-light`;
|
|
2757
2757
|
case 'warning':
|
|
2758
2758
|
return `${base} text-warning-dark dark:text-warning`;
|
|
2759
2759
|
case 'danger':
|
|
2760
|
-
return `${base} text-danger`;
|
|
2760
|
+
return `${base} text-danger-dark dark:text-danger`;
|
|
2761
2761
|
default:
|
|
2762
2762
|
return `${base} text-ink dark:text-white`;
|
|
2763
2763
|
}
|
|
@@ -2860,19 +2860,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2860
2860
|
* Compact status / category label.
|
|
2861
2861
|
*
|
|
2862
2862
|
* Soft fills stay readable in dark mode (translucent accent tints, not
|
|
2863
|
-
* light-only subtle backgrounds).
|
|
2863
|
+
* light-only subtle backgrounds). Pass {@link color} for a custom accent —
|
|
2864
|
+
* text uses that color and the background is a faded mix of the same.
|
|
2864
2865
|
*
|
|
2865
2866
|
* @example
|
|
2866
2867
|
* ```html
|
|
2867
2868
|
* <africanies-chip variant="success">Delivered</africanies-chip>
|
|
2868
|
-
* <africanies-chip variant="
|
|
2869
|
+
* <africanies-chip variant="violet">Priority</africanies-chip>
|
|
2870
|
+
* <africanies-chip color="#0f766e">Pay Later</africanies-chip>
|
|
2869
2871
|
* <africanies-chip variant="warning" [removable]="true" (removed)="clear()">Pending</africanies-chip>
|
|
2870
2872
|
* ```
|
|
2871
2873
|
*/
|
|
2872
2874
|
class ChipComponent {
|
|
2873
|
-
/** Semantic tone. Defaults to `neutral`. */
|
|
2875
|
+
/** Semantic tone. Defaults to `neutral`. Ignored when {@link color} is set. */
|
|
2874
2876
|
variant = input('neutral', /* @ts-ignore */
|
|
2875
2877
|
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
2878
|
+
/**
|
|
2879
|
+
* Optional CSS color (`#7c3aed`, `rgb(…)`, `oklch(…)`, …). When set, overrides
|
|
2880
|
+
* {@link variant}: label uses the color and the fill is a faded mix of it.
|
|
2881
|
+
*/
|
|
2882
|
+
color = input(null, /* @ts-ignore */
|
|
2883
|
+
...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
2876
2884
|
/** Padding / type scale. Defaults to `sm` (table / dense UI). */
|
|
2877
2885
|
size = input('sm', /* @ts-ignore */
|
|
2878
2886
|
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
@@ -2891,6 +2899,12 @@ class ChipComponent {
|
|
|
2891
2899
|
removed = output();
|
|
2892
2900
|
iconSize = computed(() => (this.size() === 'md' ? 14 : 12), /* @ts-ignore */
|
|
2893
2901
|
...(ngDevMode ? [{ debugName: "iconSize" }] : /* istanbul ignore next */ []));
|
|
2902
|
+
/** Trimmed custom accent, or `null` when using a named {@link variant}. */
|
|
2903
|
+
customAccent = computed(() => {
|
|
2904
|
+
const value = this.color()?.trim() ?? '';
|
|
2905
|
+
return value.length > 0 ? value : null;
|
|
2906
|
+
}, /* @ts-ignore */
|
|
2907
|
+
...(ngDevMode ? [{ debugName: "customAccent" }] : /* istanbul ignore next */ []));
|
|
2894
2908
|
hostClass = computed(() => {
|
|
2895
2909
|
const base = 'inline-flex max-w-full items-center gap-1 rounded-md font-sans font-medium ' +
|
|
2896
2910
|
'border border-transparent';
|
|
@@ -2902,21 +2916,35 @@ class ChipComponent {
|
|
|
2902
2916
|
}, /* @ts-ignore */
|
|
2903
2917
|
...(ngDevMode ? [{ debugName: "hostClass" }] : /* istanbul ignore next */ []));
|
|
2904
2918
|
/**
|
|
2905
|
-
* Soft background + text per variant
|
|
2906
|
-
* chips never wash out as near-white
|
|
2907
|
-
*
|
|
2919
|
+
* Soft background + text per variant, or the custom-color host class.
|
|
2920
|
+
* Dark mode uses translucent accents so chips never wash out as near-white
|
|
2921
|
+
* blobs.
|
|
2922
|
+
* @returns Tailwind / host class string for the active tone.
|
|
2908
2923
|
*/
|
|
2909
2924
|
toneClass() {
|
|
2925
|
+
if (this.customAccent()) {
|
|
2926
|
+
return 'africanies-chip--custom';
|
|
2927
|
+
}
|
|
2910
2928
|
switch (this.variant()) {
|
|
2911
2929
|
case 'success':
|
|
2912
2930
|
case 'export':
|
|
2913
|
-
return 'bg-export-subtle text-export dark:bg-export/15 dark:text-export-light';
|
|
2931
|
+
return 'bg-export-subtle text-export-strong dark:bg-export/15 dark:text-export-light';
|
|
2914
2932
|
case 'import':
|
|
2915
|
-
return 'bg-import-subtle text-import dark:bg-import/15 dark:text-import-light';
|
|
2933
|
+
return 'bg-import-subtle text-import-strong dark:bg-import/15 dark:text-import-light';
|
|
2916
2934
|
case 'warning':
|
|
2917
2935
|
return 'bg-warning-subtle text-warning-dark dark:bg-warning/15 dark:text-warning';
|
|
2918
2936
|
case 'danger':
|
|
2919
|
-
return 'bg-danger-subtle text-danger dark:bg-danger/15 dark:text-danger';
|
|
2937
|
+
return 'bg-danger-subtle text-danger-dark dark:bg-danger/15 dark:text-danger';
|
|
2938
|
+
case 'info':
|
|
2939
|
+
return 'bg-info-subtle text-info dark:bg-info/20 dark:text-[#93c5fd]';
|
|
2940
|
+
case 'violet':
|
|
2941
|
+
return 'bg-violet-100 text-violet-800 dark:bg-violet-400/15 dark:text-violet-300';
|
|
2942
|
+
case 'teal':
|
|
2943
|
+
return 'bg-teal-100 text-teal-800 dark:bg-teal-400/15 dark:text-teal-300';
|
|
2944
|
+
case 'rose':
|
|
2945
|
+
return 'bg-rose-100 text-rose-800 dark:bg-rose-400/15 dark:text-rose-300';
|
|
2946
|
+
case 'cyan':
|
|
2947
|
+
return 'bg-cyan-100 text-cyan-800 dark:bg-cyan-400/15 dark:text-cyan-300';
|
|
2920
2948
|
default:
|
|
2921
2949
|
return 'bg-border/60 text-ink dark:bg-white/10 dark:text-neutral-200';
|
|
2922
2950
|
}
|
|
@@ -2929,7 +2957,7 @@ class ChipComponent {
|
|
|
2929
2957
|
this.removed.emit();
|
|
2930
2958
|
}
|
|
2931
2959
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ChipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2932
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: ChipComponent, isStandalone: true, selector: "africanies-chip", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, host: { attributes: { "role": "status" }, properties: { "class": "hostClass()" } }, ngImport: i0, template: `
|
|
2960
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: ChipComponent, isStandalone: true, selector: "africanies-chip", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, host: { attributes: { "role": "status" }, properties: { "class": "hostClass()", "style.--africanies-chip-accent": "customAccent()" } }, ngImport: i0, template: `
|
|
2933
2961
|
@if (icon(); as iconName) {
|
|
2934
2962
|
<africanies-icon [name]="iconName" [size]="iconSize()" class="shrink-0" />
|
|
2935
2963
|
}
|
|
@@ -2937,27 +2965,22 @@ class ChipComponent {
|
|
|
2937
2965
|
@if (removable()) {
|
|
2938
2966
|
<button
|
|
2939
2967
|
type="button"
|
|
2940
|
-
class="inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm opacity-70 transition-opacity hover:opacity-100 focus-visible:outline focus-visible:
|
|
2968
|
+
class="inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm opacity-70 transition-opacity hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus"
|
|
2941
2969
|
[attr.aria-label]="removeLabel()"
|
|
2942
2970
|
(click)="onRemove($event)"
|
|
2943
2971
|
>
|
|
2944
2972
|
<africanies-icon name="close" [size]="12" />
|
|
2945
2973
|
</button>
|
|
2946
2974
|
}
|
|
2947
|
-
`, isInline: true, dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2975
|
+
`, isInline: true, styles: [":host.africanies-chip--custom{color:var(--africanies-chip-accent);background-color:color-mix(in srgb,var(--africanies-chip-accent) 14%,transparent);border-color:color-mix(in srgb,var(--africanies-chip-accent) 28%,transparent)}:host-context(.dark):host.africanies-chip--custom{color:color-mix(in srgb,var(--africanies-chip-accent) 68%,white);background-color:color-mix(in srgb,var(--africanies-chip-accent) 22%,transparent);border-color:color-mix(in srgb,var(--africanies-chip-accent) 40%,transparent)}\n"], dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2948
2976
|
}
|
|
2949
2977
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ChipComponent, decorators: [{
|
|
2950
2978
|
type: Component,
|
|
2951
|
-
args: [{
|
|
2952
|
-
selector: 'africanies-chip',
|
|
2953
|
-
standalone: true,
|
|
2954
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2955
|
-
imports: [AfricaniesIconComponent],
|
|
2956
|
-
host: {
|
|
2979
|
+
args: [{ selector: 'africanies-chip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AfricaniesIconComponent], host: {
|
|
2957
2980
|
'[class]': 'hostClass()',
|
|
2981
|
+
'[style.--africanies-chip-accent]': 'customAccent()',
|
|
2958
2982
|
role: 'status',
|
|
2959
|
-
},
|
|
2960
|
-
template: `
|
|
2983
|
+
}, template: `
|
|
2961
2984
|
@if (icon(); as iconName) {
|
|
2962
2985
|
<africanies-icon [name]="iconName" [size]="iconSize()" class="shrink-0" />
|
|
2963
2986
|
}
|
|
@@ -2965,16 +2988,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2965
2988
|
@if (removable()) {
|
|
2966
2989
|
<button
|
|
2967
2990
|
type="button"
|
|
2968
|
-
class="inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm opacity-70 transition-opacity hover:opacity-100 focus-visible:outline focus-visible:
|
|
2991
|
+
class="inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm opacity-70 transition-opacity hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus"
|
|
2969
2992
|
[attr.aria-label]="removeLabel()"
|
|
2970
2993
|
(click)="onRemove($event)"
|
|
2971
2994
|
>
|
|
2972
2995
|
<africanies-icon name="close" [size]="12" />
|
|
2973
2996
|
</button>
|
|
2974
2997
|
}
|
|
2975
|
-
`,
|
|
2976
|
-
|
|
2977
|
-
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }] } });
|
|
2998
|
+
`, styles: [":host.africanies-chip--custom{color:var(--africanies-chip-accent);background-color:color-mix(in srgb,var(--africanies-chip-accent) 14%,transparent);border-color:color-mix(in srgb,var(--africanies-chip-accent) 28%,transparent)}:host-context(.dark):host.africanies-chip--custom{color:color-mix(in srgb,var(--africanies-chip-accent) 68%,white);background-color:color-mix(in srgb,var(--africanies-chip-accent) 22%,transparent);border-color:color-mix(in srgb,var(--africanies-chip-accent) 40%,transparent)}\n"] }]
|
|
2999
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }] } });
|
|
2978
3000
|
|
|
2979
3001
|
/**
|
|
2980
3002
|
* Compact status / category labels (`africanies-chip`).
|
|
@@ -3180,7 +3202,7 @@ class ContentStackComponent {
|
|
|
3180
3202
|
</p>
|
|
3181
3203
|
}
|
|
3182
3204
|
@if (extraLine()) {
|
|
3183
|
-
<p class="m-0 text-caption text-neutral-
|
|
3205
|
+
<p class="m-0 text-caption text-neutral-600 dark:text-neutral-400">
|
|
3184
3206
|
{{ extraLine() }}
|
|
3185
3207
|
</p>
|
|
3186
3208
|
}
|
|
@@ -3209,7 +3231,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
3209
3231
|
</p>
|
|
3210
3232
|
}
|
|
3211
3233
|
@if (extraLine()) {
|
|
3212
|
-
<p class="m-0 text-caption text-neutral-
|
|
3234
|
+
<p class="m-0 text-caption text-neutral-600 dark:text-neutral-400">
|
|
3213
3235
|
{{ extraLine() }}
|
|
3214
3236
|
</p>
|
|
3215
3237
|
}
|
|
@@ -3782,8 +3804,8 @@ class InfoPopoverComponent {
|
|
|
3782
3804
|
* Bound via `[class]` so arrow position tracks preferred placement.
|
|
3783
3805
|
*/
|
|
3784
3806
|
panelArrowClass = computed(() => {
|
|
3785
|
-
const card = 'relative z-10 w-max max-w-xs rounded-
|
|
3786
|
-
const base = "before:pointer-events-none before:absolute before:z-0 before:h-2.5 before:w-2.5 before:rotate-45 before:border before:border-border before:bg-
|
|
3807
|
+
const card = 'relative z-10 w-max max-w-xs rounded-panel border border-border bg-surface px-4 py-3 text-ink shadow-floating dark:border-white/15 dark:bg-ink-950 dark:text-white';
|
|
3808
|
+
const base = "before:pointer-events-none before:absolute before:z-0 before:h-2.5 before:w-2.5 before:rotate-45 before:border before:border-border before:bg-surface before:content-[''] dark:before:border-white/15 dark:before:bg-ink-950";
|
|
3787
3809
|
switch (this.placement()) {
|
|
3788
3810
|
case 'bottom':
|
|
3789
3811
|
return `${card} ${base} before:left-1/2 before:top-0 before:-translate-x-1/2 before:-translate-y-1/2 before:border-b-0 before:border-r-0`;
|
|
@@ -4083,22 +4105,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
4083
4105
|
* scanner must see full utility names in this package so they survive purge
|
|
4084
4106
|
* when consumers scan the published UI bundle.
|
|
4085
4107
|
*/
|
|
4108
|
+
/**
|
|
4109
|
+
* Inset focus ring — stays inside the control border box.
|
|
4110
|
+
*
|
|
4111
|
+
* Prefer this over `outline` + `outline-offset`. Those paint *outside* the box
|
|
4112
|
+
* and are clipped by `overflow: hidden|clip|auto` ancestors (modals, drawers,
|
|
4113
|
+
* steppers, scroll panes). `box-sizing` does not affect outlines.
|
|
4114
|
+
*/
|
|
4115
|
+
const FORM_FOCUS_WITHIN_CLASS = 'focus-within:outline-none focus-within:ring-2 focus-within:ring-inset focus-within:ring-focus';
|
|
4116
|
+
/** Same inset ring for host / button-style focus-visible. */
|
|
4117
|
+
const FORM_FOCUS_VISIBLE_CLASS = 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus';
|
|
4118
|
+
/** Peer-driven inset ring (checkbox / radio control chrome). */
|
|
4119
|
+
const FORM_FOCUS_VISIBLE_PEER_CLASS = 'peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-inset peer-focus-visible:ring-focus';
|
|
4120
|
+
/** Direct focus (OTP cells and similar). */
|
|
4121
|
+
const FORM_FOCUS_CLASS = 'focus:outline-none focus:ring-2 focus:ring-inset focus:ring-focus';
|
|
4086
4122
|
/** Label above the control. Hidden when empty so callers can omit a label. */
|
|
4087
4123
|
const FORM_LABEL_CLASS = 'block text-body-sm font-medium text-ink dark:text-white mb-1.5 empty:hidden';
|
|
4088
|
-
/**
|
|
4089
|
-
|
|
4090
|
-
|
|
4124
|
+
/**
|
|
4125
|
+
* Default control shell — `h-10` matches md `africanies-button`.
|
|
4126
|
+
*
|
|
4127
|
+
* Focus utilities are inlined (not concatenated) so Tailwind content scanning
|
|
4128
|
+
* always sees the full class names in this string literal.
|
|
4129
|
+
*/
|
|
4130
|
+
const FORM_FIELD_CLASS = 'flex items-center w-full h-10 box-border rounded-control border border-control bg-surface dark:bg-ink-950 text-ink dark:text-white dark:border-white/25 ' +
|
|
4131
|
+
'focus-within:outline-none focus-within:ring-2 focus-within:ring-inset focus-within:ring-focus';
|
|
4091
4132
|
/**
|
|
4092
4133
|
* Error border — `!` so it wins over shell `border-border` /
|
|
4093
4134
|
* `dark:border-white/25` (same specificity; those utilities sort later in the
|
|
4094
4135
|
* generated CSS and otherwise paint over `border-danger`).
|
|
4095
4136
|
*
|
|
4137
|
+
* Use `danger` (`#ff001c`) for both border and focus ring so field chrome
|
|
4138
|
+
* matches validation copy (not the darker accessible `danger-dark` text token).
|
|
4139
|
+
*
|
|
4096
4140
|
* Keep these literals static for Tailwind content scanning in consumer apps.
|
|
4097
4141
|
*/
|
|
4098
|
-
const FORM_FIELD_ERROR_CLASS = '!border-danger dark:!border-danger focus-within:!
|
|
4142
|
+
const FORM_FIELD_ERROR_CLASS = '!border-danger dark:!border-danger focus-within:!ring-danger focus:!ring-danger';
|
|
4099
4143
|
/** Native input / textarea inside a shell. */
|
|
4100
4144
|
const FORM_CONTROL_INNER_CLASS = 'flex-1 min-w-0 min-h-0 h-full w-full bg-transparent border-0 outline-none text-body text-ink dark:text-white px-3 py-0 ' +
|
|
4101
|
-
'placeholder:text-neutral-
|
|
4145
|
+
'placeholder:text-neutral-500 disabled:cursor-not-allowed';
|
|
4102
4146
|
/** Prefix / suffix projection gutters. Hidden when nothing is projected. */
|
|
4103
4147
|
const FORM_AFFIX_CLASS = 'inline-flex items-center shrink-0 px-2.5 text-neutral-600 dark:text-neutral-400 empty:hidden';
|
|
4104
4148
|
/**
|
|
@@ -4113,7 +4157,7 @@ const FORM_DATE_INNER_CLASS = FORM_CONTROL_INNER_CLASS +
|
|
|
4113
4157
|
' cursor-pointer [&::-webkit-calendar-picker-indicator]:cursor-pointer';
|
|
4114
4158
|
/** Hint under the control (hidden when error is shown). */
|
|
4115
4159
|
const FORM_HINT_CLASS = 'mt-1.5 text-caption text-neutral-600 dark:text-neutral-400 m-0';
|
|
4116
|
-
/** Field-level validation message (not ErrorStateComponent). */
|
|
4160
|
+
/** Field-level validation message (not ErrorStateComponent). Matches `#ff001c`. */
|
|
4117
4161
|
const FORM_ERROR_CLASS = 'mt-1.5 text-caption text-danger m-0';
|
|
4118
4162
|
/** Disabled shell — dimmed with not-allowed cursor over the full field chrome. */
|
|
4119
4163
|
const FORM_DISABLED_CLASS = 'opacity-50 cursor-not-allowed';
|
|
@@ -4344,229 +4388,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
4344
4388
|
}]
|
|
4345
4389
|
}], propDecorators: { dateInput: [{ type: i0.ViewChild, args: ['dateInput', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
4346
4390
|
|
|
4347
|
-
let nextRadioId = 0;
|
|
4348
|
-
/**
|
|
4349
|
-
* Radio group following the shared AFRICANIES form field pattern.
|
|
4350
|
-
*
|
|
4351
|
-
* **Prefix/suffix slots are omitted** — radios are mutually exclusive options
|
|
4352
|
-
* with labels; affix projection does not apply.
|
|
4353
|
-
*
|
|
4354
|
-
* Selected ring and center disc follow {@link ModeColorService}
|
|
4355
|
-
* (SFN green / STN orange).
|
|
4356
|
-
*
|
|
4357
|
-
* @typeParam T - Option value type.
|
|
4358
|
-
*
|
|
4359
|
-
* @example
|
|
4360
|
-
* ```html
|
|
4361
|
-
* <africanies-radio
|
|
4362
|
-
* label="Shipment mode"
|
|
4363
|
-
* [options]="modeOptions"
|
|
4364
|
-
* [(value)]="mode"
|
|
4365
|
-
* />
|
|
4366
|
-
* ```
|
|
4367
|
-
*/
|
|
4368
|
-
class RadioComponent {
|
|
4369
|
-
modeColor = inject(ModeColorService);
|
|
4370
|
-
groupName = `africanies-radio-${++nextRadioId}`;
|
|
4371
|
-
hintId = `${this.groupName}-hint`;
|
|
4372
|
-
errorId = `${this.groupName}-error`;
|
|
4373
|
-
labelClass = FORM_LABEL_CLASS;
|
|
4374
|
-
hintClass = FORM_HINT_CLASS;
|
|
4375
|
-
errorClass = FORM_ERROR_CLASS;
|
|
4376
|
-
/** Group legend / label. */
|
|
4377
|
-
label = input('', /* @ts-ignore */
|
|
4378
|
-
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
4379
|
-
/** Helper copy. Hidden while {@link error} is set. */
|
|
4380
|
-
hint = input(undefined, /* @ts-ignore */
|
|
4381
|
-
...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
4382
|
-
/** Field-level validation message. Distinct from `ErrorStateComponent`. */
|
|
4383
|
-
error = input(null, /* @ts-ignore */
|
|
4384
|
-
...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
4385
|
-
/** Options rendered as radios. */
|
|
4386
|
-
options = input([], /* @ts-ignore */
|
|
4387
|
-
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
4388
|
-
/** Selected option value (`[(value)]` + CVA). */
|
|
4389
|
-
value = model(null, /* @ts-ignore */
|
|
4390
|
-
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
4391
|
-
/** Host disable flag (in addition to CVA). */
|
|
4392
|
-
disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
|
|
4393
|
-
transform: booleanAttribute });
|
|
4394
|
-
cvaDisabled = signal(false, /* @ts-ignore */
|
|
4395
|
-
...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
|
|
4396
|
-
disabled = computed(() => this.disabledInput() || this.cvaDisabled(), /* @ts-ignore */
|
|
4397
|
-
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
4398
|
-
describedBy = computed(() => {
|
|
4399
|
-
if (this.error()) {
|
|
4400
|
-
return this.errorId;
|
|
4401
|
-
}
|
|
4402
|
-
if (this.hint()) {
|
|
4403
|
-
return this.hintId;
|
|
4404
|
-
}
|
|
4405
|
-
return null;
|
|
4406
|
-
}, /* @ts-ignore */
|
|
4407
|
-
...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
4408
|
-
onChange = () => undefined;
|
|
4409
|
-
onTouched = () => undefined;
|
|
4410
|
-
trackOption(opt) {
|
|
4411
|
-
return String(opt.value);
|
|
4412
|
-
}
|
|
4413
|
-
isSelected(opt) {
|
|
4414
|
-
return Object.is(this.value(), opt.value);
|
|
4415
|
-
}
|
|
4416
|
-
markClass(opt) {
|
|
4417
|
-
const base = 'pointer-events-none flex size-4 items-center justify-center rounded-full border-2 bg-transparent transition-colors ' +
|
|
4418
|
-
'peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-ink';
|
|
4419
|
-
const err = this.error() ? ' !border-danger dark:!border-danger' : '';
|
|
4420
|
-
if (this.isSelected(opt)) {
|
|
4421
|
-
// Ring uses mode accent; fill stays transparent so the center dot reads clearly.
|
|
4422
|
-
return `${base} ${this.modeColor.classes().border}${err}`;
|
|
4423
|
-
}
|
|
4424
|
-
return `${base} border-neutral-400 dark:border-white${err}`;
|
|
4425
|
-
}
|
|
4426
|
-
/** Selected inner disc — SFN green / STN orange. */
|
|
4427
|
-
dotClass = computed(() => `block size-1.5 rounded-full ${this.modeColor.classes().bg}`, /* @ts-ignore */
|
|
4428
|
-
...(ngDevMode ? [{ debugName: "dotClass" }] : /* istanbul ignore next */ []));
|
|
4429
|
-
/** @param value - Selected option value or `null`. */
|
|
4430
|
-
writeValue(value) {
|
|
4431
|
-
this.value.set(value);
|
|
4432
|
-
}
|
|
4433
|
-
/** @param fn - Selection change callback. */
|
|
4434
|
-
registerOnChange(fn) {
|
|
4435
|
-
this.onChange = fn;
|
|
4436
|
-
}
|
|
4437
|
-
/** @param fn - Blur callback. */
|
|
4438
|
-
registerOnTouched(fn) {
|
|
4439
|
-
this.onTouched = fn;
|
|
4440
|
-
}
|
|
4441
|
-
/** @param isDisabled - Blocks interaction when true. */
|
|
4442
|
-
setDisabledState(isDisabled) {
|
|
4443
|
-
this.cvaDisabled.set(isDisabled);
|
|
4444
|
-
}
|
|
4445
|
-
select(opt) {
|
|
4446
|
-
if (this.disabled() || opt.disabled) {
|
|
4447
|
-
return;
|
|
4448
|
-
}
|
|
4449
|
-
this.value.set(opt.value);
|
|
4450
|
-
this.onChange(opt.value);
|
|
4451
|
-
}
|
|
4452
|
-
onBlur() {
|
|
4453
|
-
this.onTouched();
|
|
4454
|
-
}
|
|
4455
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: RadioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4456
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: RadioComponent, isStandalone: true, selector: "africanies-radio", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { classAttribute: "inline-flex max-w-full" }, providers: [
|
|
4457
|
-
{
|
|
4458
|
-
provide: NG_VALUE_ACCESSOR,
|
|
4459
|
-
useExisting: forwardRef(() => RadioComponent),
|
|
4460
|
-
multi: true,
|
|
4461
|
-
},
|
|
4462
|
-
], ngImport: i0, template: `
|
|
4463
|
-
<fieldset
|
|
4464
|
-
class="m-0 p-0 border-0 min-w-0"
|
|
4465
|
-
[attr.aria-invalid]="error() ? true : null"
|
|
4466
|
-
[attr.aria-describedby]="describedBy()"
|
|
4467
|
-
>
|
|
4468
|
-
<legend [class]="labelClass">{{ label() }}</legend>
|
|
4469
|
-
<div class="flex flex-row flex-wrap gap-x-4 gap-y-2" role="radiogroup">
|
|
4470
|
-
@for (opt of options(); track trackOption(opt)) {
|
|
4471
|
-
<label
|
|
4472
|
-
class="inline-flex items-center gap-2.5 text-body text-ink dark:text-white"
|
|
4473
|
-
[class.opacity-50]="disabled() || opt.disabled"
|
|
4474
|
-
[class.cursor-pointer]="!(disabled() || opt.disabled)"
|
|
4475
|
-
[class.cursor-not-allowed]="disabled() || opt.disabled"
|
|
4476
|
-
>
|
|
4477
|
-
<span class="relative inline-flex size-4 shrink-0">
|
|
4478
|
-
<input
|
|
4479
|
-
type="radio"
|
|
4480
|
-
class="peer absolute inset-0 z-10 m-0 size-full opacity-0"
|
|
4481
|
-
[class.cursor-pointer]="!(disabled() || opt.disabled)"
|
|
4482
|
-
[class.cursor-not-allowed]="disabled() || opt.disabled"
|
|
4483
|
-
[name]="groupName"
|
|
4484
|
-
[checked]="isSelected(opt)"
|
|
4485
|
-
[disabled]="disabled() || !!opt.disabled"
|
|
4486
|
-
(change)="select(opt)"
|
|
4487
|
-
(blur)="onBlur()"
|
|
4488
|
-
/>
|
|
4489
|
-
<span [class]="markClass(opt)" aria-hidden="true">
|
|
4490
|
-
@if (isSelected(opt)) {
|
|
4491
|
-
<span [class]="dotClass()"></span>
|
|
4492
|
-
}
|
|
4493
|
-
</span>
|
|
4494
|
-
</span>
|
|
4495
|
-
<span>{{ opt.label }}</span>
|
|
4496
|
-
</label>
|
|
4497
|
-
}
|
|
4498
|
-
</div>
|
|
4499
|
-
@if (error(); as err) {
|
|
4500
|
-
<p [id]="errorId" [class]="errorClass" role="alert">{{ err }}</p>
|
|
4501
|
-
} @else if (hint(); as h) {
|
|
4502
|
-
<p [id]="hintId" [class]="hintClass">{{ h }}</p>
|
|
4503
|
-
}
|
|
4504
|
-
</fieldset>
|
|
4505
|
-
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4506
|
-
}
|
|
4507
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: RadioComponent, decorators: [{
|
|
4508
|
-
type: Component,
|
|
4509
|
-
args: [{
|
|
4510
|
-
selector: 'africanies-radio',
|
|
4511
|
-
standalone: true,
|
|
4512
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
4513
|
-
host: {
|
|
4514
|
-
class: 'inline-flex max-w-full',
|
|
4515
|
-
},
|
|
4516
|
-
providers: [
|
|
4517
|
-
{
|
|
4518
|
-
provide: NG_VALUE_ACCESSOR,
|
|
4519
|
-
useExisting: forwardRef(() => RadioComponent),
|
|
4520
|
-
multi: true,
|
|
4521
|
-
},
|
|
4522
|
-
],
|
|
4523
|
-
template: `
|
|
4524
|
-
<fieldset
|
|
4525
|
-
class="m-0 p-0 border-0 min-w-0"
|
|
4526
|
-
[attr.aria-invalid]="error() ? true : null"
|
|
4527
|
-
[attr.aria-describedby]="describedBy()"
|
|
4528
|
-
>
|
|
4529
|
-
<legend [class]="labelClass">{{ label() }}</legend>
|
|
4530
|
-
<div class="flex flex-row flex-wrap gap-x-4 gap-y-2" role="radiogroup">
|
|
4531
|
-
@for (opt of options(); track trackOption(opt)) {
|
|
4532
|
-
<label
|
|
4533
|
-
class="inline-flex items-center gap-2.5 text-body text-ink dark:text-white"
|
|
4534
|
-
[class.opacity-50]="disabled() || opt.disabled"
|
|
4535
|
-
[class.cursor-pointer]="!(disabled() || opt.disabled)"
|
|
4536
|
-
[class.cursor-not-allowed]="disabled() || opt.disabled"
|
|
4537
|
-
>
|
|
4538
|
-
<span class="relative inline-flex size-4 shrink-0">
|
|
4539
|
-
<input
|
|
4540
|
-
type="radio"
|
|
4541
|
-
class="peer absolute inset-0 z-10 m-0 size-full opacity-0"
|
|
4542
|
-
[class.cursor-pointer]="!(disabled() || opt.disabled)"
|
|
4543
|
-
[class.cursor-not-allowed]="disabled() || opt.disabled"
|
|
4544
|
-
[name]="groupName"
|
|
4545
|
-
[checked]="isSelected(opt)"
|
|
4546
|
-
[disabled]="disabled() || !!opt.disabled"
|
|
4547
|
-
(change)="select(opt)"
|
|
4548
|
-
(blur)="onBlur()"
|
|
4549
|
-
/>
|
|
4550
|
-
<span [class]="markClass(opt)" aria-hidden="true">
|
|
4551
|
-
@if (isSelected(opt)) {
|
|
4552
|
-
<span [class]="dotClass()"></span>
|
|
4553
|
-
}
|
|
4554
|
-
</span>
|
|
4555
|
-
</span>
|
|
4556
|
-
<span>{{ opt.label }}</span>
|
|
4557
|
-
</label>
|
|
4558
|
-
}
|
|
4559
|
-
</div>
|
|
4560
|
-
@if (error(); as err) {
|
|
4561
|
-
<p [id]="errorId" [class]="errorClass" role="alert">{{ err }}</p>
|
|
4562
|
-
} @else if (hint(); as h) {
|
|
4563
|
-
<p [id]="hintId" [class]="hintClass">{{ h }}</p>
|
|
4564
|
-
}
|
|
4565
|
-
</fieldset>
|
|
4566
|
-
`,
|
|
4567
|
-
}]
|
|
4568
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
4569
|
-
|
|
4570
4391
|
/**
|
|
4571
4392
|
* Tailwind panel classes for each {@link ModalSize}.
|
|
4572
4393
|
*
|
|
@@ -4880,12 +4701,12 @@ class ModalService {
|
|
|
4880
4701
|
],
|
|
4881
4702
|
panelClass: [
|
|
4882
4703
|
'africanies-modal-panel',
|
|
4883
|
-
'bg-
|
|
4704
|
+
'bg-surface',
|
|
4884
4705
|
'dark:bg-ink-950',
|
|
4885
4706
|
'text-ink',
|
|
4886
4707
|
'dark:text-white',
|
|
4887
|
-
'rounded-
|
|
4888
|
-
'shadow-
|
|
4708
|
+
'rounded-panel',
|
|
4709
|
+
'shadow-floating',
|
|
4889
4710
|
'border',
|
|
4890
4711
|
'border-border',
|
|
4891
4712
|
'dark:border-white/15',
|
|
@@ -5809,7 +5630,7 @@ class SelectComponent {
|
|
|
5809
5630
|
<input
|
|
5810
5631
|
#searchInput
|
|
5811
5632
|
type="search"
|
|
5812
|
-
class="w-full rounded-md border border-neutral-300 dark:border-white/25 bg-transparent text-body text-ink dark:text-white px-2.5 py-1.5 outline-none focus-visible:outline focus-visible:
|
|
5633
|
+
class="w-full rounded-md border border-neutral-300 dark:border-white/25 bg-transparent text-body text-ink dark:text-white px-2.5 py-1.5 outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ink"
|
|
5813
5634
|
[value]="searchQuery()"
|
|
5814
5635
|
placeholder="Search…"
|
|
5815
5636
|
(input)="onSearchInput($event)"
|
|
@@ -6137,7 +5958,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
6137
5958
|
<input
|
|
6138
5959
|
#searchInput
|
|
6139
5960
|
type="search"
|
|
6140
|
-
class="w-full rounded-md border border-neutral-300 dark:border-white/25 bg-transparent text-body text-ink dark:text-white px-2.5 py-1.5 outline-none focus-visible:outline focus-visible:
|
|
5961
|
+
class="w-full rounded-md border border-neutral-300 dark:border-white/25 bg-transparent text-body text-ink dark:text-white px-2.5 py-1.5 outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ink"
|
|
6141
5962
|
[value]="searchQuery()"
|
|
6142
5963
|
placeholder="Search…"
|
|
6143
5964
|
(input)="onSearchInput($event)"
|
|
@@ -6804,13 +6625,6 @@ class FilterDrawerPanel {
|
|
|
6804
6625
|
const opt = Array.isArray(selected) ? selected[0] : selected;
|
|
6805
6626
|
this.draft.update((s) => ({ ...s, order: opt?.value }));
|
|
6806
6627
|
}
|
|
6807
|
-
onRadioChange(key, value) {
|
|
6808
|
-
if (value == null) {
|
|
6809
|
-
this.clearField(key);
|
|
6810
|
-
return;
|
|
6811
|
-
}
|
|
6812
|
-
this.setFieldValue(key, value);
|
|
6813
|
-
}
|
|
6814
6628
|
onSelectChange(key, selected) {
|
|
6815
6629
|
const opt = Array.isArray(selected) ? selected[0] : selected;
|
|
6816
6630
|
if (!opt) {
|
|
@@ -6951,14 +6765,21 @@ class FilterDrawerPanel {
|
|
|
6951
6765
|
value,
|
|
6952
6766
|
});
|
|
6953
6767
|
}
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6768
|
+
/**
|
|
6769
|
+
* Boolean Yes/No chips. Prefer field.options when present; otherwise default
|
|
6770
|
+
* colored Yes/No so every boolean filter stays visually distinct.
|
|
6771
|
+
*/
|
|
6772
|
+
booleanOptions(field) {
|
|
6773
|
+
if (field.options?.length) {
|
|
6774
|
+
return field.options;
|
|
6775
|
+
}
|
|
6776
|
+
return [
|
|
6777
|
+
{ value: '1', label: 'Yes', color: '#25945c' },
|
|
6778
|
+
{ value: '0', label: 'No', color: '#FF001C' },
|
|
6779
|
+
];
|
|
6780
|
+
}
|
|
6781
|
+
onReset() {
|
|
6782
|
+
const next = resetFilterState(true, this.draft());
|
|
6962
6783
|
this.draft.set(next);
|
|
6963
6784
|
this.selectedKeys.set([]);
|
|
6964
6785
|
}
|
|
@@ -7204,12 +7025,37 @@ class FilterDrawerPanel {
|
|
|
7204
7025
|
</div>
|
|
7205
7026
|
}
|
|
7206
7027
|
@case ('boolean') {
|
|
7207
|
-
<
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7028
|
+
<div class="flex flex-wrap gap-2">
|
|
7029
|
+
@for (opt of booleanOptions(field); track opt.value) {
|
|
7030
|
+
<button
|
|
7031
|
+
type="button"
|
|
7032
|
+
class="cursor-pointer rounded-md border px-2.5 py-1.5 text-body-sm transition-colors"
|
|
7033
|
+
[style.color]="
|
|
7034
|
+
draft().values[field.key] === opt.value
|
|
7035
|
+
? opt.color ?? null
|
|
7036
|
+
: null
|
|
7037
|
+
"
|
|
7038
|
+
[style.border-color]="
|
|
7039
|
+
draft().values[field.key] === opt.value
|
|
7040
|
+
? opt.color ?? null
|
|
7041
|
+
: null
|
|
7042
|
+
"
|
|
7043
|
+
[style.background-color]="
|
|
7044
|
+
draft().values[field.key] === opt.value && opt.color
|
|
7045
|
+
? opt.color + '1A'
|
|
7046
|
+
: null
|
|
7047
|
+
"
|
|
7048
|
+
[class]="
|
|
7049
|
+
draft().values[field.key] === opt.value
|
|
7050
|
+
? 'font-medium'
|
|
7051
|
+
: 'border-neutral-300 text-neutral-600 hover:border-neutral-400 dark:border-white/15 dark:text-neutral-300'
|
|
7052
|
+
"
|
|
7053
|
+
(click)="setFieldValue(field.key, opt.value)"
|
|
7054
|
+
>
|
|
7055
|
+
{{ opt.label }}
|
|
7056
|
+
</button>
|
|
7057
|
+
}
|
|
7058
|
+
</div>
|
|
7213
7059
|
}
|
|
7214
7060
|
@case ('select') {
|
|
7215
7061
|
<!-- Label already shown in the section header — avoid double label. -->
|
|
@@ -7268,7 +7114,7 @@ class FilterDrawerPanel {
|
|
|
7268
7114
|
type="button"
|
|
7269
7115
|
variant="ghost"
|
|
7270
7116
|
size="sm"
|
|
7271
|
-
class="shrink-0 !min-h-0 self-start !px-1 !py-0 text-neutral-
|
|
7117
|
+
class="shrink-0 !min-h-0 self-start !px-1 !py-0 text-neutral-600 hover:text-ink dark:text-neutral-400 dark:hover:text-white"
|
|
7272
7118
|
aria-label="Dismiss"
|
|
7273
7119
|
(click)="applyError.set(null)"
|
|
7274
7120
|
>
|
|
@@ -7300,7 +7146,7 @@ class FilterDrawerPanel {
|
|
|
7300
7146
|
</div>
|
|
7301
7147
|
</div>
|
|
7302
7148
|
</div>
|
|
7303
|
-
`, isInline: true, dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }, { kind: "component", type: ButtonComponent, selector: "button[africanies-button], a[africanies-button]", inputs: ["variant", "size", "disabled", "loading"] }, { kind: "component", type: DatePickerComponent, selector: "africanies-date-picker", inputs: ["label", "hint", "error", "min", "max", "value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type:
|
|
7149
|
+
`, isInline: true, dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }, { kind: "component", type: ButtonComponent, selector: "button[africanies-button], a[africanies-button]", inputs: ["variant", "size", "disabled", "loading"] }, { kind: "component", type: DatePickerComponent, selector: "africanies-date-picker", inputs: ["label", "hint", "error", "min", "max", "value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: SelectComponent, selector: "africanies-select", inputs: ["label", "hint", "error", "showRetry", "retryLabel", "retryingLabel", "retrying", "loading", "loadingLabel", "placeholder", "options", "selected", "searchable", "allowFreeText", "multiple", "maxSelected", "create", "disabled", "showTriggerIcon", "size"], outputs: ["retry", "searchChange", "optionsChange", "selectedChange"] }, { kind: "component", type: TextInputComponent, selector: "africanies-text-input", inputs: ["label", "hint", "error", "placeholder", "type", "autocomplete", "value", "disabled"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7304
7150
|
}
|
|
7305
7151
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FilterDrawerPanel, decorators: [{
|
|
7306
7152
|
type: Component,
|
|
@@ -7315,7 +7161,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
7315
7161
|
AfricaniesIconComponent,
|
|
7316
7162
|
ButtonComponent,
|
|
7317
7163
|
DatePickerComponent,
|
|
7318
|
-
RadioComponent,
|
|
7319
7164
|
SelectComponent,
|
|
7320
7165
|
TextInputComponent,
|
|
7321
7166
|
],
|
|
@@ -7473,12 +7318,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
7473
7318
|
</div>
|
|
7474
7319
|
}
|
|
7475
7320
|
@case ('boolean') {
|
|
7476
|
-
<
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
|
|
7480
|
-
|
|
7481
|
-
|
|
7321
|
+
<div class="flex flex-wrap gap-2">
|
|
7322
|
+
@for (opt of booleanOptions(field); track opt.value) {
|
|
7323
|
+
<button
|
|
7324
|
+
type="button"
|
|
7325
|
+
class="cursor-pointer rounded-md border px-2.5 py-1.5 text-body-sm transition-colors"
|
|
7326
|
+
[style.color]="
|
|
7327
|
+
draft().values[field.key] === opt.value
|
|
7328
|
+
? opt.color ?? null
|
|
7329
|
+
: null
|
|
7330
|
+
"
|
|
7331
|
+
[style.border-color]="
|
|
7332
|
+
draft().values[field.key] === opt.value
|
|
7333
|
+
? opt.color ?? null
|
|
7334
|
+
: null
|
|
7335
|
+
"
|
|
7336
|
+
[style.background-color]="
|
|
7337
|
+
draft().values[field.key] === opt.value && opt.color
|
|
7338
|
+
? opt.color + '1A'
|
|
7339
|
+
: null
|
|
7340
|
+
"
|
|
7341
|
+
[class]="
|
|
7342
|
+
draft().values[field.key] === opt.value
|
|
7343
|
+
? 'font-medium'
|
|
7344
|
+
: 'border-neutral-300 text-neutral-600 hover:border-neutral-400 dark:border-white/15 dark:text-neutral-300'
|
|
7345
|
+
"
|
|
7346
|
+
(click)="setFieldValue(field.key, opt.value)"
|
|
7347
|
+
>
|
|
7348
|
+
{{ opt.label }}
|
|
7349
|
+
</button>
|
|
7350
|
+
}
|
|
7351
|
+
</div>
|
|
7482
7352
|
}
|
|
7483
7353
|
@case ('select') {
|
|
7484
7354
|
<!-- Label already shown in the section header — avoid double label. -->
|
|
@@ -7537,7 +7407,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
7537
7407
|
type="button"
|
|
7538
7408
|
variant="ghost"
|
|
7539
7409
|
size="sm"
|
|
7540
|
-
class="shrink-0 !min-h-0 self-start !px-1 !py-0 text-neutral-
|
|
7410
|
+
class="shrink-0 !min-h-0 self-start !px-1 !py-0 text-neutral-600 hover:text-ink dark:text-neutral-400 dark:hover:text-white"
|
|
7541
7411
|
aria-label="Dismiss"
|
|
7542
7412
|
(click)="applyError.set(null)"
|
|
7543
7413
|
>
|
|
@@ -7617,11 +7487,11 @@ class DrawerService {
|
|
|
7617
7487
|
],
|
|
7618
7488
|
panelClass: [
|
|
7619
7489
|
'africanies-drawer-panel',
|
|
7620
|
-
'bg-
|
|
7490
|
+
'bg-surface',
|
|
7621
7491
|
'dark:bg-ink-950',
|
|
7622
7492
|
'text-ink',
|
|
7623
7493
|
'dark:text-white',
|
|
7624
|
-
'shadow-
|
|
7494
|
+
'shadow-floating',
|
|
7625
7495
|
'border-l',
|
|
7626
7496
|
'border-border',
|
|
7627
7497
|
'dark:border-white/15',
|
|
@@ -7754,8 +7624,8 @@ class ConfirmDialogComponent {
|
|
|
7754
7624
|
iconWellClass = computed(() => {
|
|
7755
7625
|
const well = 'inline-flex size-14 shrink-0 items-center justify-center rounded-2xl';
|
|
7756
7626
|
return this.options.danger
|
|
7757
|
-
? `${well} bg-danger-subtle text-danger dark:bg-danger/20 dark:text-danger`
|
|
7758
|
-
: `${well} bg-export-subtle text-export dark:bg-export/20 dark:text-export-light`;
|
|
7627
|
+
? `${well} bg-danger-subtle text-danger-dark dark:bg-danger/20 dark:text-danger`
|
|
7628
|
+
: `${well} bg-export-subtle text-export-strong dark:bg-export/20 dark:text-export-light`;
|
|
7759
7629
|
}, /* @ts-ignore */
|
|
7760
7630
|
...(ngDevMode ? [{ debugName: "iconWellClass" }] : /* istanbul ignore next */ []));
|
|
7761
7631
|
constructor() {
|
|
@@ -8141,7 +8011,7 @@ class OverlayFrameComponent {
|
|
|
8141
8011
|
<ng-content select="[africaniesOverlayHeader]" />
|
|
8142
8012
|
</div>
|
|
8143
8013
|
<div
|
|
8144
|
-
class="africanies-overlay-scroll min-h-0 flex-1 overflow-x-clip overflow-y-auto px-
|
|
8014
|
+
class="africanies-overlay-scroll min-h-0 flex-1 overflow-x-clip overflow-y-auto px-1 -mx-1"
|
|
8145
8015
|
>
|
|
8146
8016
|
<ng-content />
|
|
8147
8017
|
</div>
|
|
@@ -8164,7 +8034,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
8164
8034
|
<ng-content select="[africaniesOverlayHeader]" />
|
|
8165
8035
|
</div>
|
|
8166
8036
|
<div
|
|
8167
|
-
class="africanies-overlay-scroll min-h-0 flex-1 overflow-x-clip overflow-y-auto px-
|
|
8037
|
+
class="africanies-overlay-scroll min-h-0 flex-1 overflow-x-clip overflow-y-auto px-1 -mx-1"
|
|
8168
8038
|
>
|
|
8169
8039
|
<ng-content />
|
|
8170
8040
|
</div>
|
|
@@ -9056,7 +8926,7 @@ class CheckboxComponent {
|
|
|
9056
8926
|
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
9057
8927
|
markClass = computed(() => {
|
|
9058
8928
|
const base = 'pointer-events-none flex size-4 items-center justify-center rounded border text-white transition-colors ' +
|
|
9059
|
-
|
|
8929
|
+
FORM_FOCUS_VISIBLE_PEER_CLASS;
|
|
9060
8930
|
const err = this.error() ? ' !border-danger dark:!border-danger' : '';
|
|
9061
8931
|
if (this.value()) {
|
|
9062
8932
|
const c = this.modeColor.classes();
|
|
@@ -9731,7 +9601,7 @@ class FilePreviewDialogComponent {
|
|
|
9731
9601
|
<div
|
|
9732
9602
|
class="flex flex-col items-center gap-3 rounded-md bg-background-welcome px-6 py-10 text-center ring-1 ring-border dark:bg-white/5 dark:ring-white/15"
|
|
9733
9603
|
>
|
|
9734
|
-
<africanies-icon name="eye-slash" [size]="32" class="text-neutral-
|
|
9604
|
+
<africanies-icon name="eye-slash" [size]="32" class="text-neutral-600" />
|
|
9735
9605
|
<p class="m-0 text-body font-medium text-ink dark:text-white">
|
|
9736
9606
|
Preview not available
|
|
9737
9607
|
</p>
|
|
@@ -9801,7 +9671,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
9801
9671
|
<div
|
|
9802
9672
|
class="flex flex-col items-center gap-3 rounded-md bg-background-welcome px-6 py-10 text-center ring-1 ring-border dark:bg-white/5 dark:ring-white/15"
|
|
9803
9673
|
>
|
|
9804
|
-
<africanies-icon name="eye-slash" [size]="32" class="text-neutral-
|
|
9674
|
+
<africanies-icon name="eye-slash" [size]="32" class="text-neutral-600" />
|
|
9805
9675
|
<p class="m-0 text-body font-medium text-ink dark:text-white">
|
|
9806
9676
|
Preview not available
|
|
9807
9677
|
</p>
|
|
@@ -10494,7 +10364,7 @@ class FileUploadComponent {
|
|
|
10494
10364
|
<span> · </span>
|
|
10495
10365
|
<button
|
|
10496
10366
|
type="button"
|
|
10497
|
-
class="cursor-pointer bg-transparent p-0 text-caption font-medium text-ink underline underline-offset-2 hover:text-neutral-700 focus-visible:outline focus-visible:
|
|
10367
|
+
class="cursor-pointer bg-transparent p-0 text-caption font-medium text-ink underline underline-offset-2 hover:text-neutral-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ink dark:text-white dark:hover:text-neutral-200"
|
|
10498
10368
|
(click)="openPreview(item); $event.stopPropagation()"
|
|
10499
10369
|
>
|
|
10500
10370
|
View
|
|
@@ -10794,7 +10664,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
10794
10664
|
<span> · </span>
|
|
10795
10665
|
<button
|
|
10796
10666
|
type="button"
|
|
10797
|
-
class="cursor-pointer bg-transparent p-0 text-caption font-medium text-ink underline underline-offset-2 hover:text-neutral-700 focus-visible:outline focus-visible:
|
|
10667
|
+
class="cursor-pointer bg-transparent p-0 text-caption font-medium text-ink underline underline-offset-2 hover:text-neutral-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ink dark:text-white dark:hover:text-neutral-200"
|
|
10798
10668
|
(click)="openPreview(item); $event.stopPropagation()"
|
|
10799
10669
|
>
|
|
10800
10670
|
View
|
|
@@ -11208,7 +11078,7 @@ class OtpInputComponent {
|
|
|
11208
11078
|
cellClass = computed(() => {
|
|
11209
11079
|
let classes = 'size-10 shrink-0 rounded-md border border-neutral-300 bg-white text-center text-body font-medium text-ink outline-none transition-colors ' +
|
|
11210
11080
|
'dark:border-white/25 dark:bg-ink-950 dark:text-white ' +
|
|
11211
|
-
|
|
11081
|
+
`${FORM_FOCUS_CLASS} disabled:cursor-not-allowed`;
|
|
11212
11082
|
if (this.masked()) {
|
|
11213
11083
|
classes += ' africanies-otp-cell-masked text-body-lg';
|
|
11214
11084
|
}
|
|
@@ -11617,133 +11487,57 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
11617
11487
|
`, styles: [".africanies-otp-cell-masked{-webkit-text-security:disc;text-security:disc}\n"] }]
|
|
11618
11488
|
}], ctorParameters: () => [], propDecorators: { cellInputs: [{ type: i0.ViewChildren, args: ['cellInput', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], length: [{ type: i0.Input, args: [{ isSignal: true, alias: "length", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showResend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showResend", required: false }] }], resendPrompt: [{ type: i0.Input, args: [{ isSignal: true, alias: "resendPrompt", required: false }] }], resendLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "resendLabel", required: false }] }], resendCooldown: [{ type: i0.Input, args: [{ isSignal: true, alias: "resendCooldown", required: false }] }], completed: [{ type: i0.Output, args: ["completed"] }], resend: [{ type: i0.Output, args: ["resend"] }] } });
|
|
11619
11489
|
|
|
11490
|
+
let nextRadioId = 0;
|
|
11620
11491
|
/**
|
|
11621
|
-
* Radio form
|
|
11622
|
-
*/
|
|
11623
|
-
|
|
11624
|
-
let nextSearchComboboxId = 0;
|
|
11625
|
-
const PANEL_POSITIONS = [
|
|
11626
|
-
{
|
|
11627
|
-
originX: 'start',
|
|
11628
|
-
originY: 'bottom',
|
|
11629
|
-
overlayX: 'start',
|
|
11630
|
-
overlayY: 'top',
|
|
11631
|
-
offsetY: 4,
|
|
11632
|
-
},
|
|
11633
|
-
{
|
|
11634
|
-
originX: 'start',
|
|
11635
|
-
originY: 'top',
|
|
11636
|
-
overlayX: 'start',
|
|
11637
|
-
overlayY: 'bottom',
|
|
11638
|
-
offsetY: -4,
|
|
11639
|
-
},
|
|
11640
|
-
];
|
|
11641
|
-
/**
|
|
11642
|
-
* Generic type-as-you-search combobox with a debounced async lookup and
|
|
11643
|
-
* overlay result list.
|
|
11492
|
+
* Radio group following the shared AFRICANIES form field pattern.
|
|
11644
11493
|
*
|
|
11645
|
-
*
|
|
11646
|
-
*
|
|
11647
|
-
* partners, etc. Emits the selected entity via `[(selected)]` / CVA.
|
|
11494
|
+
* **Prefix/suffix slots are omitted** — radios are mutually exclusive options
|
|
11495
|
+
* with labels; affix projection does not apply.
|
|
11648
11496
|
*
|
|
11649
|
-
*
|
|
11650
|
-
*
|
|
11497
|
+
* Selected ring and center disc follow {@link ModeColorService}
|
|
11498
|
+
* (SFN green / STN orange).
|
|
11499
|
+
*
|
|
11500
|
+
* @typeParam T - Option value type.
|
|
11651
11501
|
*
|
|
11652
11502
|
* @example
|
|
11653
11503
|
* ```html
|
|
11654
|
-
* <africanies-
|
|
11655
|
-
* label="
|
|
11656
|
-
* [
|
|
11657
|
-
* [
|
|
11658
|
-
* [optionSubtitle]="customerSubtitle"
|
|
11659
|
-
* [(selected)]="customer"
|
|
11504
|
+
* <africanies-radio
|
|
11505
|
+
* label="Shipment mode"
|
|
11506
|
+
* [options]="modeOptions"
|
|
11507
|
+
* [(value)]="mode"
|
|
11660
11508
|
* />
|
|
11661
11509
|
* ```
|
|
11662
11510
|
*/
|
|
11663
|
-
class
|
|
11664
|
-
|
|
11665
|
-
|
|
11666
|
-
hintId = `${this.
|
|
11667
|
-
errorId = `${this.
|
|
11668
|
-
listboxId = `${this.controlId}-listbox`;
|
|
11511
|
+
class RadioComponent {
|
|
11512
|
+
modeColor = inject(ModeColorService);
|
|
11513
|
+
groupName = `africanies-radio-${++nextRadioId}`;
|
|
11514
|
+
hintId = `${this.groupName}-hint`;
|
|
11515
|
+
errorId = `${this.groupName}-error`;
|
|
11669
11516
|
labelClass = FORM_LABEL_CLASS;
|
|
11670
|
-
affixClass = FORM_AFFIX_CLASS;
|
|
11671
|
-
innerClass = FORM_CONTROL_INNER_CLASS;
|
|
11672
11517
|
hintClass = FORM_HINT_CLASS;
|
|
11673
11518
|
errorClass = FORM_ERROR_CLASS;
|
|
11674
|
-
|
|
11675
|
-
minPanelWidth = 224;
|
|
11676
|
-
triggerOrigin = viewChild(CdkOverlayOrigin, /* @ts-ignore */
|
|
11677
|
-
...(ngDevMode ? [{ debugName: "triggerOrigin" }] : /* istanbul ignore next */ []));
|
|
11678
|
-
querySubject = new Subject();
|
|
11679
|
-
onChange = () => undefined;
|
|
11680
|
-
onTouched = () => undefined;
|
|
11681
|
-
/** Visible field label. */
|
|
11519
|
+
/** Group legend / label. */
|
|
11682
11520
|
label = input('', /* @ts-ignore */
|
|
11683
11521
|
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
11684
|
-
/** Helper copy
|
|
11522
|
+
/** Helper copy. Hidden while {@link error} is set. */
|
|
11685
11523
|
hint = input(undefined, /* @ts-ignore */
|
|
11686
11524
|
...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
11687
|
-
/** Field-level validation message. */
|
|
11525
|
+
/** Field-level validation message. Distinct from `ErrorStateComponent`. */
|
|
11688
11526
|
error = input(null, /* @ts-ignore */
|
|
11689
11527
|
...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
11690
|
-
|
|
11691
|
-
|
|
11692
|
-
|
|
11693
|
-
|
|
11694
|
-
|
|
11695
|
-
|
|
11696
|
-
|
|
11697
|
-
...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
|
|
11698
|
-
/** Async lookup — parent owns HTTP / filtering. */
|
|
11699
|
-
search = input.required(/* @ts-ignore */
|
|
11700
|
-
...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
|
|
11701
|
-
optionLabel = input.required(/* @ts-ignore */
|
|
11702
|
-
...(ngDevMode ? [{ debugName: "optionLabel" }] : /* istanbul ignore next */ []));
|
|
11703
|
-
optionSubtitle = input(undefined, /* @ts-ignore */
|
|
11704
|
-
...(ngDevMode ? [{ debugName: "optionSubtitle" }] : /* istanbul ignore next */ []));
|
|
11705
|
-
optionBadge = input(undefined, /* @ts-ignore */
|
|
11706
|
-
...(ngDevMode ? [{ debugName: "optionBadge" }] : /* istanbul ignore next */ []));
|
|
11707
|
-
optionMark = input(undefined, /* @ts-ignore */
|
|
11708
|
-
...(ngDevMode ? [{ debugName: "optionMark" }] : /* istanbul ignore next */ []));
|
|
11709
|
-
markTooltip = input('Professional Business Plan', /* @ts-ignore */
|
|
11710
|
-
...(ngDevMode ? [{ debugName: "markTooltip" }] : /* istanbul ignore next */ []));
|
|
11711
|
-
trackBy = input((item) => this.optionLabel()(item), /* @ts-ignore */
|
|
11712
|
-
...(ngDevMode ? [{ debugName: "trackBy" }] : /* istanbul ignore next */ []));
|
|
11713
|
-
selected = model(null, /* @ts-ignore */
|
|
11714
|
-
...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
|
|
11715
|
-
queryChange = output();
|
|
11528
|
+
/** Options rendered as radios. */
|
|
11529
|
+
options = input([], /* @ts-ignore */
|
|
11530
|
+
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
11531
|
+
/** Selected option value (`[(value)]` + CVA). */
|
|
11532
|
+
value = model(null, /* @ts-ignore */
|
|
11533
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
11534
|
+
/** Host disable flag (in addition to CVA). */
|
|
11716
11535
|
disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
|
|
11717
11536
|
transform: booleanAttribute });
|
|
11718
11537
|
cvaDisabled = signal(false, /* @ts-ignore */
|
|
11719
11538
|
...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
|
|
11720
11539
|
disabled = computed(() => this.disabledInput() || this.cvaDisabled(), /* @ts-ignore */
|
|
11721
11540
|
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
11722
|
-
query = signal('', /* @ts-ignore */
|
|
11723
|
-
...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
|
|
11724
|
-
open = signal(false, /* @ts-ignore */
|
|
11725
|
-
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
11726
|
-
loading = signal(false, /* @ts-ignore */
|
|
11727
|
-
...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
11728
|
-
options = signal([], /* @ts-ignore */
|
|
11729
|
-
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
11730
|
-
searchError = signal(null, /* @ts-ignore */
|
|
11731
|
-
...(ngDevMode ? [{ debugName: "searchError" }] : /* istanbul ignore next */ []));
|
|
11732
|
-
activeIndex = signal(-1, /* @ts-ignore */
|
|
11733
|
-
...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
|
|
11734
|
-
panelWidth = signal(this.minPanelWidth, /* @ts-ignore */
|
|
11735
|
-
...(ngDevMode ? [{ debugName: "panelWidth" }] : /* istanbul ignore next */ []));
|
|
11736
|
-
shellClass = computed(() => {
|
|
11737
|
-
let classes = FORM_FIELD_CLASS;
|
|
11738
|
-
if (this.error()) {
|
|
11739
|
-
classes += ` ${FORM_FIELD_ERROR_CLASS}`;
|
|
11740
|
-
}
|
|
11741
|
-
if (this.disabled()) {
|
|
11742
|
-
classes += ` ${FORM_DISABLED_CLASS}`;
|
|
11743
|
-
}
|
|
11744
|
-
return classes;
|
|
11745
|
-
}, /* @ts-ignore */
|
|
11746
|
-
...(ngDevMode ? [{ debugName: "shellClass" }] : /* istanbul ignore next */ []));
|
|
11747
11541
|
describedBy = computed(() => {
|
|
11748
11542
|
if (this.error()) {
|
|
11749
11543
|
return this.errorId;
|
|
@@ -11754,58 +11548,357 @@ class SearchComboboxComponent {
|
|
|
11754
11548
|
return null;
|
|
11755
11549
|
}, /* @ts-ignore */
|
|
11756
11550
|
...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
11757
|
-
|
|
11758
|
-
|
|
11759
|
-
|
|
11760
|
-
|
|
11761
|
-
}
|
|
11762
|
-
return this.optionId(index);
|
|
11763
|
-
}, /* @ts-ignore */
|
|
11764
|
-
...(ngDevMode ? [{ debugName: "activeOptionId" }] : /* istanbul ignore next */ []));
|
|
11765
|
-
selectedMark = computed(() => {
|
|
11766
|
-
const sel = this.selected();
|
|
11767
|
-
const fn = this.optionMark();
|
|
11768
|
-
return !!sel && !!fn && fn(sel);
|
|
11769
|
-
}, /* @ts-ignore */
|
|
11770
|
-
...(ngDevMode ? [{ debugName: "selectedMark" }] : /* istanbul ignore next */ []));
|
|
11771
|
-
constructor() {
|
|
11772
|
-
effect(() => {
|
|
11773
|
-
const sel = this.selected();
|
|
11774
|
-
const labelFn = this.optionLabel();
|
|
11775
|
-
if (sel) {
|
|
11776
|
-
this.query.set(labelFn(sel));
|
|
11777
|
-
}
|
|
11778
|
-
});
|
|
11779
|
-
this.querySubject
|
|
11780
|
-
.pipe(debounce(() => timer(Math.max(0, Number(this.debounceMs()) || 0))), distinctUntilChanged(), switchMap((text) => {
|
|
11781
|
-
const trimmed = text.trim();
|
|
11782
|
-
const min = Math.max(0, Number(this.minQueryLength()) || 0);
|
|
11783
|
-
if (trimmed.length < min) {
|
|
11784
|
-
this.options.set([]);
|
|
11785
|
-
this.searchError.set(null);
|
|
11786
|
-
this.loading.set(false);
|
|
11787
|
-
this.open.set(false);
|
|
11788
|
-
return of([]);
|
|
11789
|
-
}
|
|
11790
|
-
this.loading.set(true);
|
|
11791
|
-
this.open.set(true);
|
|
11792
|
-
return this.search()(trimmed).pipe(tap(() => this.searchError.set(null)), catchError((err) => {
|
|
11793
|
-
this.searchError.set(err instanceof Error
|
|
11794
|
-
? err.message
|
|
11795
|
-
: 'Could not load results.');
|
|
11796
|
-
return of([]);
|
|
11797
|
-
}));
|
|
11798
|
-
}), takeUntilDestroyed(this.destroyRef))
|
|
11799
|
-
.subscribe((results) => {
|
|
11800
|
-
this.loading.set(false);
|
|
11801
|
-
this.options.set(results);
|
|
11802
|
-
this.activeIndex.set(results.length ? 0 : -1);
|
|
11803
|
-
if (this.query().trim().length > 0) {
|
|
11804
|
-
this.open.set(true);
|
|
11805
|
-
}
|
|
11806
|
-
});
|
|
11551
|
+
onChange = () => undefined;
|
|
11552
|
+
onTouched = () => undefined;
|
|
11553
|
+
trackOption(opt) {
|
|
11554
|
+
return String(opt.value);
|
|
11807
11555
|
}
|
|
11808
|
-
|
|
11556
|
+
isSelected(opt) {
|
|
11557
|
+
return Object.is(this.value(), opt.value);
|
|
11558
|
+
}
|
|
11559
|
+
markClass(opt) {
|
|
11560
|
+
const base = 'pointer-events-none flex size-4 items-center justify-center rounded-full border-2 bg-transparent transition-colors ' +
|
|
11561
|
+
FORM_FOCUS_VISIBLE_PEER_CLASS;
|
|
11562
|
+
const err = this.error() ? ' !border-danger dark:!border-danger' : '';
|
|
11563
|
+
if (this.isSelected(opt)) {
|
|
11564
|
+
// Ring uses mode accent; fill stays transparent so the center dot reads clearly.
|
|
11565
|
+
return `${base} ${this.modeColor.classes().border}${err}`;
|
|
11566
|
+
}
|
|
11567
|
+
return `${base} border-neutral-400 dark:border-white${err}`;
|
|
11568
|
+
}
|
|
11569
|
+
/** Selected inner disc — SFN green / STN orange. */
|
|
11570
|
+
dotClass = computed(() => `block size-1.5 rounded-full ${this.modeColor.classes().bg}`, /* @ts-ignore */
|
|
11571
|
+
...(ngDevMode ? [{ debugName: "dotClass" }] : /* istanbul ignore next */ []));
|
|
11572
|
+
/** @param value - Selected option value or `null`. */
|
|
11573
|
+
writeValue(value) {
|
|
11574
|
+
this.value.set(value);
|
|
11575
|
+
}
|
|
11576
|
+
/** @param fn - Selection change callback. */
|
|
11577
|
+
registerOnChange(fn) {
|
|
11578
|
+
this.onChange = fn;
|
|
11579
|
+
}
|
|
11580
|
+
/** @param fn - Blur callback. */
|
|
11581
|
+
registerOnTouched(fn) {
|
|
11582
|
+
this.onTouched = fn;
|
|
11583
|
+
}
|
|
11584
|
+
/** @param isDisabled - Blocks interaction when true. */
|
|
11585
|
+
setDisabledState(isDisabled) {
|
|
11586
|
+
this.cvaDisabled.set(isDisabled);
|
|
11587
|
+
}
|
|
11588
|
+
select(opt) {
|
|
11589
|
+
if (this.disabled() || opt.disabled) {
|
|
11590
|
+
return;
|
|
11591
|
+
}
|
|
11592
|
+
this.value.set(opt.value);
|
|
11593
|
+
this.onChange(opt.value);
|
|
11594
|
+
}
|
|
11595
|
+
onBlur() {
|
|
11596
|
+
this.onTouched();
|
|
11597
|
+
}
|
|
11598
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: RadioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11599
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: RadioComponent, isStandalone: true, selector: "africanies-radio", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { classAttribute: "inline-flex max-w-full" }, providers: [
|
|
11600
|
+
{
|
|
11601
|
+
provide: NG_VALUE_ACCESSOR,
|
|
11602
|
+
useExisting: forwardRef(() => RadioComponent),
|
|
11603
|
+
multi: true,
|
|
11604
|
+
},
|
|
11605
|
+
], ngImport: i0, template: `
|
|
11606
|
+
<fieldset
|
|
11607
|
+
class="m-0 p-0 border-0 min-w-0"
|
|
11608
|
+
[attr.aria-invalid]="error() ? true : null"
|
|
11609
|
+
[attr.aria-describedby]="describedBy()"
|
|
11610
|
+
>
|
|
11611
|
+
<legend [class]="labelClass">{{ label() }}</legend>
|
|
11612
|
+
<div class="flex flex-row flex-wrap gap-x-4 gap-y-2" role="radiogroup">
|
|
11613
|
+
@for (opt of options(); track trackOption(opt)) {
|
|
11614
|
+
<label
|
|
11615
|
+
class="inline-flex items-center gap-2.5 text-body text-ink dark:text-white"
|
|
11616
|
+
[class.opacity-50]="disabled() || opt.disabled"
|
|
11617
|
+
[class.cursor-pointer]="!(disabled() || opt.disabled)"
|
|
11618
|
+
[class.cursor-not-allowed]="disabled() || opt.disabled"
|
|
11619
|
+
>
|
|
11620
|
+
<span class="relative inline-flex size-4 shrink-0">
|
|
11621
|
+
<input
|
|
11622
|
+
type="radio"
|
|
11623
|
+
class="peer absolute inset-0 z-10 m-0 size-full opacity-0"
|
|
11624
|
+
[class.cursor-pointer]="!(disabled() || opt.disabled)"
|
|
11625
|
+
[class.cursor-not-allowed]="disabled() || opt.disabled"
|
|
11626
|
+
[name]="groupName"
|
|
11627
|
+
[checked]="isSelected(opt)"
|
|
11628
|
+
[disabled]="disabled() || !!opt.disabled"
|
|
11629
|
+
(change)="select(opt)"
|
|
11630
|
+
(blur)="onBlur()"
|
|
11631
|
+
/>
|
|
11632
|
+
<span [class]="markClass(opt)" aria-hidden="true">
|
|
11633
|
+
@if (isSelected(opt)) {
|
|
11634
|
+
<span [class]="dotClass()"></span>
|
|
11635
|
+
}
|
|
11636
|
+
</span>
|
|
11637
|
+
</span>
|
|
11638
|
+
<span>{{ opt.label }}</span>
|
|
11639
|
+
</label>
|
|
11640
|
+
}
|
|
11641
|
+
</div>
|
|
11642
|
+
@if (error(); as err) {
|
|
11643
|
+
<p [id]="errorId" [class]="errorClass" role="alert">{{ err }}</p>
|
|
11644
|
+
} @else if (hint(); as h) {
|
|
11645
|
+
<p [id]="hintId" [class]="hintClass">{{ h }}</p>
|
|
11646
|
+
}
|
|
11647
|
+
</fieldset>
|
|
11648
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
11649
|
+
}
|
|
11650
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: RadioComponent, decorators: [{
|
|
11651
|
+
type: Component,
|
|
11652
|
+
args: [{
|
|
11653
|
+
selector: 'africanies-radio',
|
|
11654
|
+
standalone: true,
|
|
11655
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
11656
|
+
host: {
|
|
11657
|
+
class: 'inline-flex max-w-full',
|
|
11658
|
+
},
|
|
11659
|
+
providers: [
|
|
11660
|
+
{
|
|
11661
|
+
provide: NG_VALUE_ACCESSOR,
|
|
11662
|
+
useExisting: forwardRef(() => RadioComponent),
|
|
11663
|
+
multi: true,
|
|
11664
|
+
},
|
|
11665
|
+
],
|
|
11666
|
+
template: `
|
|
11667
|
+
<fieldset
|
|
11668
|
+
class="m-0 p-0 border-0 min-w-0"
|
|
11669
|
+
[attr.aria-invalid]="error() ? true : null"
|
|
11670
|
+
[attr.aria-describedby]="describedBy()"
|
|
11671
|
+
>
|
|
11672
|
+
<legend [class]="labelClass">{{ label() }}</legend>
|
|
11673
|
+
<div class="flex flex-row flex-wrap gap-x-4 gap-y-2" role="radiogroup">
|
|
11674
|
+
@for (opt of options(); track trackOption(opt)) {
|
|
11675
|
+
<label
|
|
11676
|
+
class="inline-flex items-center gap-2.5 text-body text-ink dark:text-white"
|
|
11677
|
+
[class.opacity-50]="disabled() || opt.disabled"
|
|
11678
|
+
[class.cursor-pointer]="!(disabled() || opt.disabled)"
|
|
11679
|
+
[class.cursor-not-allowed]="disabled() || opt.disabled"
|
|
11680
|
+
>
|
|
11681
|
+
<span class="relative inline-flex size-4 shrink-0">
|
|
11682
|
+
<input
|
|
11683
|
+
type="radio"
|
|
11684
|
+
class="peer absolute inset-0 z-10 m-0 size-full opacity-0"
|
|
11685
|
+
[class.cursor-pointer]="!(disabled() || opt.disabled)"
|
|
11686
|
+
[class.cursor-not-allowed]="disabled() || opt.disabled"
|
|
11687
|
+
[name]="groupName"
|
|
11688
|
+
[checked]="isSelected(opt)"
|
|
11689
|
+
[disabled]="disabled() || !!opt.disabled"
|
|
11690
|
+
(change)="select(opt)"
|
|
11691
|
+
(blur)="onBlur()"
|
|
11692
|
+
/>
|
|
11693
|
+
<span [class]="markClass(opt)" aria-hidden="true">
|
|
11694
|
+
@if (isSelected(opt)) {
|
|
11695
|
+
<span [class]="dotClass()"></span>
|
|
11696
|
+
}
|
|
11697
|
+
</span>
|
|
11698
|
+
</span>
|
|
11699
|
+
<span>{{ opt.label }}</span>
|
|
11700
|
+
</label>
|
|
11701
|
+
}
|
|
11702
|
+
</div>
|
|
11703
|
+
@if (error(); as err) {
|
|
11704
|
+
<p [id]="errorId" [class]="errorClass" role="alert">{{ err }}</p>
|
|
11705
|
+
} @else if (hint(); as h) {
|
|
11706
|
+
<p [id]="hintId" [class]="hintClass">{{ h }}</p>
|
|
11707
|
+
}
|
|
11708
|
+
</fieldset>
|
|
11709
|
+
`,
|
|
11710
|
+
}]
|
|
11711
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
11712
|
+
|
|
11713
|
+
/**
|
|
11714
|
+
* Radio form control exports.
|
|
11715
|
+
*/
|
|
11716
|
+
|
|
11717
|
+
let nextSearchComboboxId = 0;
|
|
11718
|
+
const PANEL_POSITIONS = [
|
|
11719
|
+
{
|
|
11720
|
+
originX: 'start',
|
|
11721
|
+
originY: 'bottom',
|
|
11722
|
+
overlayX: 'start',
|
|
11723
|
+
overlayY: 'top',
|
|
11724
|
+
offsetY: 4,
|
|
11725
|
+
},
|
|
11726
|
+
{
|
|
11727
|
+
originX: 'start',
|
|
11728
|
+
originY: 'top',
|
|
11729
|
+
overlayX: 'start',
|
|
11730
|
+
overlayY: 'bottom',
|
|
11731
|
+
offsetY: -4,
|
|
11732
|
+
},
|
|
11733
|
+
];
|
|
11734
|
+
/**
|
|
11735
|
+
* Generic type-as-you-search combobox with a debounced async lookup and
|
|
11736
|
+
* overlay result list.
|
|
11737
|
+
*
|
|
11738
|
+
* Pass {@link search} plus {@link optionLabel} (and optional
|
|
11739
|
+
* {@link optionSubtitle}) so the same control works for customers, staff,
|
|
11740
|
+
* partners, etc. Emits the selected entity via `[(selected)]` / CVA.
|
|
11741
|
+
*
|
|
11742
|
+
* @typeParam T - Entity type returned by {@link search} and held in
|
|
11743
|
+
* {@link selected}.
|
|
11744
|
+
*
|
|
11745
|
+
* @example
|
|
11746
|
+
* ```html
|
|
11747
|
+
* <africanies-search-combobox
|
|
11748
|
+
* label="Customer"
|
|
11749
|
+
* [search]="searchCustomers"
|
|
11750
|
+
* [optionLabel]="customerLabel"
|
|
11751
|
+
* [optionSubtitle]="customerSubtitle"
|
|
11752
|
+
* [(selected)]="customer"
|
|
11753
|
+
* />
|
|
11754
|
+
* ```
|
|
11755
|
+
*/
|
|
11756
|
+
class SearchComboboxComponent {
|
|
11757
|
+
destroyRef = inject(DestroyRef);
|
|
11758
|
+
controlId = `africanies-search-combobox-${++nextSearchComboboxId}`;
|
|
11759
|
+
hintId = `${this.controlId}-hint`;
|
|
11760
|
+
errorId = `${this.controlId}-error`;
|
|
11761
|
+
listboxId = `${this.controlId}-listbox`;
|
|
11762
|
+
labelClass = FORM_LABEL_CLASS;
|
|
11763
|
+
affixClass = FORM_AFFIX_CLASS;
|
|
11764
|
+
innerClass = FORM_CONTROL_INNER_CLASS;
|
|
11765
|
+
hintClass = FORM_HINT_CLASS;
|
|
11766
|
+
errorClass = FORM_ERROR_CLASS;
|
|
11767
|
+
panelPositions = PANEL_POSITIONS;
|
|
11768
|
+
minPanelWidth = 224;
|
|
11769
|
+
triggerOrigin = viewChild(CdkOverlayOrigin, /* @ts-ignore */
|
|
11770
|
+
...(ngDevMode ? [{ debugName: "triggerOrigin" }] : /* istanbul ignore next */ []));
|
|
11771
|
+
querySubject = new Subject();
|
|
11772
|
+
onChange = () => undefined;
|
|
11773
|
+
onTouched = () => undefined;
|
|
11774
|
+
/** Visible field label. */
|
|
11775
|
+
label = input('', /* @ts-ignore */
|
|
11776
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
11777
|
+
/** Helper copy under the field. Hidden while {@link error} is set. */
|
|
11778
|
+
hint = input(undefined, /* @ts-ignore */
|
|
11779
|
+
...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
11780
|
+
/** Field-level validation message. */
|
|
11781
|
+
error = input(null, /* @ts-ignore */
|
|
11782
|
+
...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
11783
|
+
placeholder = input('', /* @ts-ignore */
|
|
11784
|
+
...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
11785
|
+
/** Debounce before calling {@link search} (ms). Default 500. */
|
|
11786
|
+
debounceMs = input(500, { ...(ngDevMode ? { debugName: "debounceMs" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
11787
|
+
/** Minimum trimmed query length before search runs. Default 2. */
|
|
11788
|
+
minQueryLength = input(2, { ...(ngDevMode ? { debugName: "minQueryLength" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
11789
|
+
emptyMessage = input('No matches', /* @ts-ignore */
|
|
11790
|
+
...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
|
|
11791
|
+
/** Async lookup — parent owns HTTP / filtering. */
|
|
11792
|
+
search = input.required(/* @ts-ignore */
|
|
11793
|
+
...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
|
|
11794
|
+
optionLabel = input.required(/* @ts-ignore */
|
|
11795
|
+
...(ngDevMode ? [{ debugName: "optionLabel" }] : /* istanbul ignore next */ []));
|
|
11796
|
+
optionSubtitle = input(undefined, /* @ts-ignore */
|
|
11797
|
+
...(ngDevMode ? [{ debugName: "optionSubtitle" }] : /* istanbul ignore next */ []));
|
|
11798
|
+
optionBadge = input(undefined, /* @ts-ignore */
|
|
11799
|
+
...(ngDevMode ? [{ debugName: "optionBadge" }] : /* istanbul ignore next */ []));
|
|
11800
|
+
optionMark = input(undefined, /* @ts-ignore */
|
|
11801
|
+
...(ngDevMode ? [{ debugName: "optionMark" }] : /* istanbul ignore next */ []));
|
|
11802
|
+
markTooltip = input('Professional Business Plan', /* @ts-ignore */
|
|
11803
|
+
...(ngDevMode ? [{ debugName: "markTooltip" }] : /* istanbul ignore next */ []));
|
|
11804
|
+
trackBy = input((item) => this.optionLabel()(item), /* @ts-ignore */
|
|
11805
|
+
...(ngDevMode ? [{ debugName: "trackBy" }] : /* istanbul ignore next */ []));
|
|
11806
|
+
selected = model(null, /* @ts-ignore */
|
|
11807
|
+
...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
|
|
11808
|
+
queryChange = output();
|
|
11809
|
+
disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
|
|
11810
|
+
transform: booleanAttribute });
|
|
11811
|
+
cvaDisabled = signal(false, /* @ts-ignore */
|
|
11812
|
+
...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
|
|
11813
|
+
disabled = computed(() => this.disabledInput() || this.cvaDisabled(), /* @ts-ignore */
|
|
11814
|
+
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
11815
|
+
query = signal('', /* @ts-ignore */
|
|
11816
|
+
...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
|
|
11817
|
+
open = signal(false, /* @ts-ignore */
|
|
11818
|
+
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
11819
|
+
loading = signal(false, /* @ts-ignore */
|
|
11820
|
+
...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
11821
|
+
options = signal([], /* @ts-ignore */
|
|
11822
|
+
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
11823
|
+
searchError = signal(null, /* @ts-ignore */
|
|
11824
|
+
...(ngDevMode ? [{ debugName: "searchError" }] : /* istanbul ignore next */ []));
|
|
11825
|
+
activeIndex = signal(-1, /* @ts-ignore */
|
|
11826
|
+
...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
|
|
11827
|
+
panelWidth = signal(this.minPanelWidth, /* @ts-ignore */
|
|
11828
|
+
...(ngDevMode ? [{ debugName: "panelWidth" }] : /* istanbul ignore next */ []));
|
|
11829
|
+
shellClass = computed(() => {
|
|
11830
|
+
let classes = FORM_FIELD_CLASS;
|
|
11831
|
+
if (this.error()) {
|
|
11832
|
+
classes += ` ${FORM_FIELD_ERROR_CLASS}`;
|
|
11833
|
+
}
|
|
11834
|
+
if (this.disabled()) {
|
|
11835
|
+
classes += ` ${FORM_DISABLED_CLASS}`;
|
|
11836
|
+
}
|
|
11837
|
+
return classes;
|
|
11838
|
+
}, /* @ts-ignore */
|
|
11839
|
+
...(ngDevMode ? [{ debugName: "shellClass" }] : /* istanbul ignore next */ []));
|
|
11840
|
+
describedBy = computed(() => {
|
|
11841
|
+
if (this.error()) {
|
|
11842
|
+
return this.errorId;
|
|
11843
|
+
}
|
|
11844
|
+
if (this.hint()) {
|
|
11845
|
+
return this.hintId;
|
|
11846
|
+
}
|
|
11847
|
+
return null;
|
|
11848
|
+
}, /* @ts-ignore */
|
|
11849
|
+
...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
11850
|
+
activeOptionId = computed(() => {
|
|
11851
|
+
const index = this.activeIndex();
|
|
11852
|
+
if (index < 0 || !this.open()) {
|
|
11853
|
+
return null;
|
|
11854
|
+
}
|
|
11855
|
+
return this.optionId(index);
|
|
11856
|
+
}, /* @ts-ignore */
|
|
11857
|
+
...(ngDevMode ? [{ debugName: "activeOptionId" }] : /* istanbul ignore next */ []));
|
|
11858
|
+
selectedMark = computed(() => {
|
|
11859
|
+
const sel = this.selected();
|
|
11860
|
+
const fn = this.optionMark();
|
|
11861
|
+
return !!sel && !!fn && fn(sel);
|
|
11862
|
+
}, /* @ts-ignore */
|
|
11863
|
+
...(ngDevMode ? [{ debugName: "selectedMark" }] : /* istanbul ignore next */ []));
|
|
11864
|
+
constructor() {
|
|
11865
|
+
effect(() => {
|
|
11866
|
+
const sel = this.selected();
|
|
11867
|
+
const labelFn = this.optionLabel();
|
|
11868
|
+
if (sel) {
|
|
11869
|
+
this.query.set(labelFn(sel));
|
|
11870
|
+
}
|
|
11871
|
+
});
|
|
11872
|
+
this.querySubject
|
|
11873
|
+
.pipe(debounce(() => timer(Math.max(0, Number(this.debounceMs()) || 0))), distinctUntilChanged(), switchMap((text) => {
|
|
11874
|
+
const trimmed = text.trim();
|
|
11875
|
+
const min = Math.max(0, Number(this.minQueryLength()) || 0);
|
|
11876
|
+
if (trimmed.length < min) {
|
|
11877
|
+
this.options.set([]);
|
|
11878
|
+
this.searchError.set(null);
|
|
11879
|
+
this.loading.set(false);
|
|
11880
|
+
this.open.set(false);
|
|
11881
|
+
return of([]);
|
|
11882
|
+
}
|
|
11883
|
+
this.loading.set(true);
|
|
11884
|
+
this.open.set(true);
|
|
11885
|
+
return this.search()(trimmed).pipe(tap(() => this.searchError.set(null)), catchError((err) => {
|
|
11886
|
+
this.searchError.set(err instanceof Error
|
|
11887
|
+
? err.message
|
|
11888
|
+
: 'Could not load results.');
|
|
11889
|
+
return of([]);
|
|
11890
|
+
}));
|
|
11891
|
+
}), takeUntilDestroyed(this.destroyRef))
|
|
11892
|
+
.subscribe((results) => {
|
|
11893
|
+
this.loading.set(false);
|
|
11894
|
+
this.options.set(results);
|
|
11895
|
+
this.activeIndex.set(results.length ? 0 : -1);
|
|
11896
|
+
if (this.query().trim().length > 0) {
|
|
11897
|
+
this.open.set(true);
|
|
11898
|
+
}
|
|
11899
|
+
});
|
|
11900
|
+
}
|
|
11901
|
+
writeValue(value) {
|
|
11809
11902
|
this.selected.set(value);
|
|
11810
11903
|
this.query.set(value ? this.optionLabel()(value) : '');
|
|
11811
11904
|
}
|
|
@@ -12091,7 +12184,7 @@ class SearchComboboxComponent {
|
|
|
12091
12184
|
} @else if (hint(); as h) {
|
|
12092
12185
|
<p [id]="hintId" [class]="hintClass">{{ h }}</p>
|
|
12093
12186
|
}
|
|
12094
|
-
`, isInline: true, dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }, { kind: "component", type: ChipComponent, selector: "africanies-chip", inputs: ["variant", "size", "icon", "removable", "removeLabel"], outputs: ["removed"] }, { kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "component", type: TooltipComponent, selector: "africanies-tooltip", inputs: ["text", "placement", "icon", "ariaLabel", "disabled"] }, { kind: "directive", type: TooltipTriggerDirective, selector: "[africaniesTooltipTrigger]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
12187
|
+
`, isInline: true, dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }, { kind: "component", type: ChipComponent, selector: "africanies-chip", inputs: ["variant", "color", "size", "icon", "removable", "removeLabel"], outputs: ["removed"] }, { kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "component", type: TooltipComponent, selector: "africanies-tooltip", inputs: ["text", "placement", "icon", "ariaLabel", "disabled"] }, { kind: "directive", type: TooltipTriggerDirective, selector: "[africaniesTooltipTrigger]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
12095
12188
|
}
|
|
12096
12189
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SearchComboboxComponent, decorators: [{
|
|
12097
12190
|
type: Component,
|
|
@@ -12603,7 +12696,7 @@ class ToggleComponent {
|
|
|
12603
12696
|
[id]="controlId"
|
|
12604
12697
|
type="button"
|
|
12605
12698
|
role="switch"
|
|
12606
|
-
class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-border p-0.5 box-border transition-colors focus-visible:outline focus-visible:
|
|
12699
|
+
class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-border p-0.5 box-border transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ink dark:border-white/15"
|
|
12607
12700
|
[ngClass]="trackClass()"
|
|
12608
12701
|
[attr.aria-checked]="on()"
|
|
12609
12702
|
[attr.aria-busy]="loading() ? true : null"
|
|
@@ -12665,7 +12758,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
12665
12758
|
[id]="controlId"
|
|
12666
12759
|
type="button"
|
|
12667
12760
|
role="switch"
|
|
12668
|
-
class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-border p-0.5 box-border transition-colors focus-visible:outline focus-visible:
|
|
12761
|
+
class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-border p-0.5 box-border transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ink dark:border-white/15"
|
|
12669
12762
|
[ngClass]="trackClass()"
|
|
12670
12763
|
[attr.aria-checked]="on()"
|
|
12671
12764
|
[attr.aria-busy]="loading() ? true : null"
|
|
@@ -13215,6 +13308,10 @@ const DEFAULT_LINK_ACTIVE$2 = {
|
|
|
13215
13308
|
/**
|
|
13216
13309
|
* Compact segmented control for view modes and filters.
|
|
13217
13310
|
*
|
|
13311
|
+
* Selected option uses a **solid brand pill** (white label) on a neutral track —
|
|
13312
|
+
* same pattern as the portal shipping-mode toggle. With exactly two options the
|
|
13313
|
+
* pill slides; with more options each selected chip fills in place.
|
|
13314
|
+
*
|
|
13218
13315
|
* ## Router mode (URL is source of truth)
|
|
13219
13316
|
*
|
|
13220
13317
|
* Set `routerLink` (and optional `queryParams`) on items. The selected pill
|
|
@@ -13264,15 +13361,16 @@ class SegmentComponent {
|
|
|
13264
13361
|
*/
|
|
13265
13362
|
keepScroll = input(true, { ...(ngDevMode ? { debugName: "keepScroll" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
13266
13363
|
url = toSignal(this.router.events.pipe(filter((e) => e instanceof NavigationEnd), map(() => this.router.url), startWith(this.router.url)), { initialValue: this.router.url });
|
|
13267
|
-
|
|
13268
|
-
|
|
13269
|
-
|
|
13270
|
-
|
|
13271
|
-
|
|
13364
|
+
/** Two equal options → portal-style sliding brand pill. */
|
|
13365
|
+
useSlidingThumb = computed(() => this.items().length === 2, /* @ts-ignore */
|
|
13366
|
+
...(ngDevMode ? [{ debugName: "useSlidingThumb" }] : /* istanbul ignore next */ []));
|
|
13367
|
+
/** Index of the active option (0 / 1 for the sliding thumb). */
|
|
13368
|
+
activeIndex = computed(() => {
|
|
13369
|
+
const list = this.items();
|
|
13370
|
+
const idx = list.findIndex((item) => this.isItemActive(item));
|
|
13371
|
+
return idx < 0 ? 0 : idx;
|
|
13272
13372
|
}, /* @ts-ignore */
|
|
13273
|
-
...(ngDevMode ? [{ debugName: "
|
|
13274
|
-
idleClass = computed(() => 'font-medium text-neutral-600 hover:text-ink dark:text-neutral-400 dark:hover:text-white', /* @ts-ignore */
|
|
13275
|
-
...(ngDevMode ? [{ debugName: "idleClass" }] : /* istanbul ignore next */ []));
|
|
13373
|
+
...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
|
|
13276
13374
|
constructor() {
|
|
13277
13375
|
effect(() => {
|
|
13278
13376
|
this.url();
|
|
@@ -13297,6 +13395,56 @@ class SegmentComponent {
|
|
|
13297
13395
|
}
|
|
13298
13396
|
return this.activeId() === item.id;
|
|
13299
13397
|
}
|
|
13398
|
+
/**
|
|
13399
|
+
* Sliding thumb fill. STN / SFN options keep their own brand color so the
|
|
13400
|
+
* pill matches mode identity; other pairs follow the active theme primary.
|
|
13401
|
+
*/
|
|
13402
|
+
thumbFillClass() {
|
|
13403
|
+
const active = this.items()[this.activeIndex()];
|
|
13404
|
+
return this.brandFillFor(active?.id ?? null);
|
|
13405
|
+
}
|
|
13406
|
+
/**
|
|
13407
|
+
* Option chrome: sliding mode keeps labels transparent over the thumb;
|
|
13408
|
+
* multi-option mode paints a solid selected chip in place.
|
|
13409
|
+
*
|
|
13410
|
+
* @param item - Option being rendered.
|
|
13411
|
+
* @returns Class string for the control.
|
|
13412
|
+
*/
|
|
13413
|
+
optionChrome(item) {
|
|
13414
|
+
const base = 'relative z-10 inline-flex min-w-0 items-center justify-center gap-1.5 rounded-md px-3 py-1.5 text-center text-body-sm no-underline transition-colors duration-150';
|
|
13415
|
+
const active = this.isItemActive(item);
|
|
13416
|
+
if (this.useSlidingThumb()) {
|
|
13417
|
+
return (base +
|
|
13418
|
+
' w-full ' +
|
|
13419
|
+
(active
|
|
13420
|
+
? 'font-semibold text-white'
|
|
13421
|
+
: 'font-medium text-ink hover:text-ink dark:text-neutral-300 dark:hover:text-white'));
|
|
13422
|
+
}
|
|
13423
|
+
if (active) {
|
|
13424
|
+
return `${base} font-semibold text-white shadow-sm ${this.brandFillFor(item.id)}`;
|
|
13425
|
+
}
|
|
13426
|
+
return (base +
|
|
13427
|
+
' font-medium text-ink hover:bg-white/70 hover:text-ink dark:text-neutral-300 dark:hover:bg-white/10 dark:hover:text-white');
|
|
13428
|
+
}
|
|
13429
|
+
/**
|
|
13430
|
+
* Solid brand fill for a selected option / sliding thumb.
|
|
13431
|
+
*
|
|
13432
|
+
* Light + dark use the same SFN green / STN orange primaries so the control
|
|
13433
|
+
* stays mode-identifiable on both surfaces (portal primary, not soft tint).
|
|
13434
|
+
* Class strings are full literals so Tailwind keeps them.
|
|
13435
|
+
*
|
|
13436
|
+
* @param id - Option id (`stn` / `sfn` get fixed brands; else theme primary).
|
|
13437
|
+
* @returns Background utility classes.
|
|
13438
|
+
*/
|
|
13439
|
+
brandFillFor(id) {
|
|
13440
|
+
if (id === 'stn') {
|
|
13441
|
+
return 'bg-import dark:bg-import';
|
|
13442
|
+
}
|
|
13443
|
+
if (id === 'sfn') {
|
|
13444
|
+
return 'bg-export dark:bg-export';
|
|
13445
|
+
}
|
|
13446
|
+
return this.modeColor.classes().activeFill;
|
|
13447
|
+
}
|
|
13300
13448
|
selectLocal(item) {
|
|
13301
13449
|
if (item.disabled || item.routerLink != null) {
|
|
13302
13450
|
return;
|
|
@@ -13323,18 +13471,31 @@ class SegmentComponent {
|
|
|
13323
13471
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SegmentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13324
13472
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SegmentComponent, isStandalone: true, selector: "africanies-segment", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, activeId: { classPropertyName: "activeId", publicName: "activeId", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, linkActiveOptions: { classPropertyName: "linkActiveOptions", publicName: "linkActiveOptions", isSignal: true, isRequired: false, transformFunction: null }, keepScroll: { classPropertyName: "keepScroll", publicName: "keepScroll", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeId: "activeIdChange" }, ngImport: i0, template: `
|
|
13325
13473
|
<div
|
|
13326
|
-
class="inline-
|
|
13474
|
+
class="relative inline-grid max-w-full rounded-lg bg-[#f0f2f5] p-1 dark:bg-[#2a2c31]"
|
|
13327
13475
|
role="group"
|
|
13328
13476
|
[attr.aria-label]="ariaLabel()"
|
|
13477
|
+
[class.grid-cols-2]="useSlidingThumb()"
|
|
13478
|
+
[class.inline-flex]="!useSlidingThumb()"
|
|
13479
|
+
[class.flex-wrap]="!useSlidingThumb()"
|
|
13480
|
+
[class.gap-1]="!useSlidingThumb()"
|
|
13329
13481
|
>
|
|
13482
|
+
@if (useSlidingThumb()) {
|
|
13483
|
+
<div
|
|
13484
|
+
class="africanies-segment-thumb pointer-events-none absolute top-1 bottom-1 left-1 rounded-md shadow-sm transition-transform duration-200 ease-out motion-reduce:transition-none"
|
|
13485
|
+
[class]="thumbFillClass()"
|
|
13486
|
+
[style.transform]="
|
|
13487
|
+
activeIndex() === 1
|
|
13488
|
+
? 'translateX(calc(100% + 0.25rem))'
|
|
13489
|
+
: 'translateX(0)'
|
|
13490
|
+
"
|
|
13491
|
+
aria-hidden="true"
|
|
13492
|
+
></div>
|
|
13493
|
+
}
|
|
13494
|
+
|
|
13330
13495
|
@for (item of items(); track item.id) {
|
|
13331
13496
|
@if (item.routerLink !== null && item.routerLink !== undefined) {
|
|
13332
13497
|
<a
|
|
13333
|
-
[class]="
|
|
13334
|
-
segmentChrome() +
|
|
13335
|
-
' ' +
|
|
13336
|
-
(isItemActive(item) ? selectedClass() : idleClass())
|
|
13337
|
-
"
|
|
13498
|
+
[class]="optionChrome(item)"
|
|
13338
13499
|
[class.cursor-pointer]="!item.disabled"
|
|
13339
13500
|
[class.cursor-not-allowed]="item.disabled"
|
|
13340
13501
|
[class.opacity-50]="item.disabled"
|
|
@@ -13351,11 +13512,7 @@ class SegmentComponent {
|
|
|
13351
13512
|
} @else {
|
|
13352
13513
|
<button
|
|
13353
13514
|
type="button"
|
|
13354
|
-
[class]="
|
|
13355
|
-
segmentChrome() +
|
|
13356
|
-
' ' +
|
|
13357
|
-
(isItemActive(item) ? selectedClass() : idleClass())
|
|
13358
|
-
"
|
|
13515
|
+
[class]="optionChrome(item)"
|
|
13359
13516
|
[disabled]="!!item.disabled"
|
|
13360
13517
|
[class.cursor-pointer]="!item.disabled"
|
|
13361
13518
|
[class.cursor-not-allowed]="item.disabled"
|
|
@@ -13370,29 +13527,37 @@ class SegmentComponent {
|
|
|
13370
13527
|
}
|
|
13371
13528
|
}
|
|
13372
13529
|
</div>
|
|
13373
|
-
`, isInline: true, dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
13530
|
+
`, isInline: true, styles: [":host .africanies-segment-thumb{width:calc((100% - .5rem)/2)}\n"], dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
13374
13531
|
}
|
|
13375
13532
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SegmentComponent, decorators: [{
|
|
13376
13533
|
type: Component,
|
|
13377
|
-
args: [{
|
|
13378
|
-
selector: 'africanies-segment',
|
|
13379
|
-
standalone: true,
|
|
13380
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
13381
|
-
imports: [AfricaniesIconComponent],
|
|
13382
|
-
template: `
|
|
13534
|
+
args: [{ selector: 'africanies-segment', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AfricaniesIconComponent], template: `
|
|
13383
13535
|
<div
|
|
13384
|
-
class="inline-
|
|
13536
|
+
class="relative inline-grid max-w-full rounded-lg bg-[#f0f2f5] p-1 dark:bg-[#2a2c31]"
|
|
13385
13537
|
role="group"
|
|
13386
13538
|
[attr.aria-label]="ariaLabel()"
|
|
13539
|
+
[class.grid-cols-2]="useSlidingThumb()"
|
|
13540
|
+
[class.inline-flex]="!useSlidingThumb()"
|
|
13541
|
+
[class.flex-wrap]="!useSlidingThumb()"
|
|
13542
|
+
[class.gap-1]="!useSlidingThumb()"
|
|
13387
13543
|
>
|
|
13544
|
+
@if (useSlidingThumb()) {
|
|
13545
|
+
<div
|
|
13546
|
+
class="africanies-segment-thumb pointer-events-none absolute top-1 bottom-1 left-1 rounded-md shadow-sm transition-transform duration-200 ease-out motion-reduce:transition-none"
|
|
13547
|
+
[class]="thumbFillClass()"
|
|
13548
|
+
[style.transform]="
|
|
13549
|
+
activeIndex() === 1
|
|
13550
|
+
? 'translateX(calc(100% + 0.25rem))'
|
|
13551
|
+
: 'translateX(0)'
|
|
13552
|
+
"
|
|
13553
|
+
aria-hidden="true"
|
|
13554
|
+
></div>
|
|
13555
|
+
}
|
|
13556
|
+
|
|
13388
13557
|
@for (item of items(); track item.id) {
|
|
13389
13558
|
@if (item.routerLink !== null && item.routerLink !== undefined) {
|
|
13390
13559
|
<a
|
|
13391
|
-
[class]="
|
|
13392
|
-
segmentChrome() +
|
|
13393
|
-
' ' +
|
|
13394
|
-
(isItemActive(item) ? selectedClass() : idleClass())
|
|
13395
|
-
"
|
|
13560
|
+
[class]="optionChrome(item)"
|
|
13396
13561
|
[class.cursor-pointer]="!item.disabled"
|
|
13397
13562
|
[class.cursor-not-allowed]="item.disabled"
|
|
13398
13563
|
[class.opacity-50]="item.disabled"
|
|
@@ -13409,11 +13574,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
13409
13574
|
} @else {
|
|
13410
13575
|
<button
|
|
13411
13576
|
type="button"
|
|
13412
|
-
[class]="
|
|
13413
|
-
segmentChrome() +
|
|
13414
|
-
' ' +
|
|
13415
|
-
(isItemActive(item) ? selectedClass() : idleClass())
|
|
13416
|
-
"
|
|
13577
|
+
[class]="optionChrome(item)"
|
|
13417
13578
|
[disabled]="!!item.disabled"
|
|
13418
13579
|
[class.cursor-pointer]="!item.disabled"
|
|
13419
13580
|
[class.cursor-not-allowed]="item.disabled"
|
|
@@ -13428,10 +13589,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
13428
13589
|
}
|
|
13429
13590
|
}
|
|
13430
13591
|
</div>
|
|
13431
|
-
`,
|
|
13432
|
-
}]
|
|
13592
|
+
`, styles: [":host .africanies-segment-thumb{width:calc((100% - .5rem)/2)}\n"] }]
|
|
13433
13593
|
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], activeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeId", required: false }] }, { type: i0.Output, args: ["activeIdChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], linkActiveOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "linkActiveOptions", required: false }] }], keepScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepScroll", required: false }] }] } });
|
|
13434
13594
|
|
|
13595
|
+
const PANEL_OPEN_STORAGE_KEY = 'africanies-shipping-mode-panel-open';
|
|
13596
|
+
function readStoredPanelOpen() {
|
|
13597
|
+
if (typeof localStorage === 'undefined') {
|
|
13598
|
+
return true;
|
|
13599
|
+
}
|
|
13600
|
+
try {
|
|
13601
|
+
const raw = localStorage.getItem(PANEL_OPEN_STORAGE_KEY);
|
|
13602
|
+
if (raw === null) {
|
|
13603
|
+
return true;
|
|
13604
|
+
}
|
|
13605
|
+
return raw !== '0' && raw !== 'false';
|
|
13606
|
+
}
|
|
13607
|
+
catch {
|
|
13608
|
+
return true;
|
|
13609
|
+
}
|
|
13610
|
+
}
|
|
13611
|
+
function writeStoredPanelOpen(open) {
|
|
13612
|
+
if (typeof localStorage === 'undefined') {
|
|
13613
|
+
return;
|
|
13614
|
+
}
|
|
13615
|
+
try {
|
|
13616
|
+
localStorage.setItem(PANEL_OPEN_STORAGE_KEY, open ? '1' : '0');
|
|
13617
|
+
}
|
|
13618
|
+
catch {
|
|
13619
|
+
// Private mode / quota — panel still toggles in-session.
|
|
13620
|
+
}
|
|
13621
|
+
}
|
|
13435
13622
|
/**
|
|
13436
13623
|
* Shared globe + plane glyph for STN / SFN. STN paints it rotated 180°.
|
|
13437
13624
|
*
|
|
@@ -13446,12 +13633,13 @@ const SHIPPING_MODE_GLYPH = `M88.42,68.75a48.8,48.8,0,0,1-4.74,11.1h9.89a7.67,7.
|
|
|
13446
13633
|
* import orange; **from Nigeria** uses export green. Both tiles keep equal
|
|
13447
13634
|
* chrome so unselected does not look like floating text.
|
|
13448
13635
|
*
|
|
13449
|
-
* Project into `<africanies-side-nav>` with the `
|
|
13636
|
+
* Project into `<africanies-side-nav>` with the `pre-nav` attribute (above the
|
|
13637
|
+
* nav list). `footer` still works for legacy placement under the list.
|
|
13450
13638
|
*
|
|
13451
13639
|
* @example
|
|
13452
13640
|
* ```html
|
|
13453
13641
|
* <africanies-side-nav [items]="nav" [(collapsed)]="collapsed">
|
|
13454
|
-
* <africanies-shipping-mode-switch
|
|
13642
|
+
* <africanies-shipping-mode-switch pre-nav [collapsed]="collapsed()" />
|
|
13455
13643
|
* </africanies-side-nav>
|
|
13456
13644
|
* ```
|
|
13457
13645
|
*/
|
|
@@ -13472,13 +13660,32 @@ class ShippingModeSwitchComponent {
|
|
|
13472
13660
|
* Icon-only stacked tiles when the side nav rail is collapsed.
|
|
13473
13661
|
*/
|
|
13474
13662
|
collapsed = input(false, { ...(ngDevMode ? { debugName: "collapsed" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
13663
|
+
/**
|
|
13664
|
+
* When true, the mode tiles are visible. Persisted in `localStorage`.
|
|
13665
|
+
* Two-way bindable for hosts that need to force-open (e.g. onboarding).
|
|
13666
|
+
*/
|
|
13667
|
+
panelOpen = model(readStoredPanelOpen(), /* @ts-ignore */
|
|
13668
|
+
...(ngDevMode ? [{ debugName: "panelOpen" }] : /* istanbul ignore next */ []));
|
|
13475
13669
|
/** Active mode from {@link ShippingModeService}. */
|
|
13476
13670
|
mode = this.shipping.mode;
|
|
13477
|
-
|
|
13671
|
+
modeChipLabel = computed(() => this.mode() === 'stn' ? 'STN' : 'SFN', /* @ts-ignore */
|
|
13672
|
+
...(ngDevMode ? [{ debugName: "modeChipLabel" }] : /* istanbul ignore next */ []));
|
|
13673
|
+
modeChipVariant = computed(() => (this.mode() === 'stn' ? 'import' : 'export'), /* @ts-ignore */
|
|
13674
|
+
...(ngDevMode ? [{ debugName: "modeChipVariant" }] : /* istanbul ignore next */ []));
|
|
13675
|
+
/** Host padding / divider — sits above the nav list (`border-b`). */
|
|
13478
13676
|
hostClass = computed(() => this.collapsed()
|
|
13479
|
-
? 'block shrink-0 border-
|
|
13480
|
-
: 'block shrink-0 border-
|
|
13677
|
+
? 'block shrink-0 border-b border-border px-1.5 py-2 dark:border-white/10'
|
|
13678
|
+
: 'block shrink-0 border-b border-border px-2 py-2.5 dark:border-white/10', /* @ts-ignore */
|
|
13481
13679
|
...(ngDevMode ? [{ debugName: "hostClass" }] : /* istanbul ignore next */ []));
|
|
13680
|
+
constructor() {
|
|
13681
|
+
effect(() => {
|
|
13682
|
+
writeStoredPanelOpen(this.panelOpen());
|
|
13683
|
+
});
|
|
13684
|
+
}
|
|
13685
|
+
/** Show or hide the mode tiles. */
|
|
13686
|
+
togglePanel() {
|
|
13687
|
+
this.panelOpen.update((open) => !open);
|
|
13688
|
+
}
|
|
13482
13689
|
/**
|
|
13483
13690
|
* Requests a mode change through {@link ShippingModeService.requestModeChange}
|
|
13484
13691
|
* so feature guards (e.g. Create Shipment confirm) can run first.
|
|
@@ -13501,82 +13708,153 @@ class ShippingModeSwitchComponent {
|
|
|
13501
13708
|
const selected = this.mode() === option;
|
|
13502
13709
|
const compact = this.collapsed();
|
|
13503
13710
|
const base = 'flex w-full cursor-pointer flex-col items-center justify-center gap-1 rounded-lg border text-center text-caption font-medium transition-colors ' +
|
|
13504
|
-
'focus-visible:outline focus-visible:
|
|
13505
|
-
(compact ? 'min-h-
|
|
13506
|
-
const idle = 'border-
|
|
13711
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus ' +
|
|
13712
|
+
(compact ? 'size-9 min-h-0 px-0 py-0' : 'min-h-[4.5rem] px-1.5 py-2');
|
|
13713
|
+
const idle = 'border-control bg-surface text-ink hover:bg-background-hover dark:border-white/15 dark:bg-ink-950 dark:text-white dark:hover:bg-white/10';
|
|
13507
13714
|
if (option === 'stn') {
|
|
13508
13715
|
return selected
|
|
13509
|
-
? `${base} border-import bg-import text-white`
|
|
13716
|
+
? `${base} border-import-strong bg-import-strong text-white dark:border-import dark:bg-import`
|
|
13510
13717
|
: `${base} ${idle}`;
|
|
13511
13718
|
}
|
|
13512
13719
|
return selected
|
|
13513
|
-
? `${base} border-export bg-export text-white`
|
|
13720
|
+
? `${base} border-export bg-export text-white dark:border-export dark:bg-export`
|
|
13514
13721
|
: `${base} ${idle}`;
|
|
13515
13722
|
}
|
|
13516
13723
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ShippingModeSwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13517
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: ShippingModeSwitchComponent, isStandalone: true, selector: "africanies-shipping-mode-switch", inputs: { collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClass()" } }, ngImport: i0, template: `
|
|
13518
|
-
@if (
|
|
13519
|
-
|
|
13520
|
-
|
|
13521
|
-
|
|
13522
|
-
|
|
13523
|
-
|
|
13524
|
-
}
|
|
13525
|
-
<div
|
|
13526
|
-
class="grid gap-1.5"
|
|
13527
|
-
[class.grid-cols-1]="collapsed()"
|
|
13528
|
-
[class.grid-cols-2]="!collapsed()"
|
|
13529
|
-
role="radiogroup"
|
|
13530
|
-
aria-label="Shipping mode"
|
|
13531
|
-
>
|
|
13532
|
-
<button
|
|
13533
|
-
type="button"
|
|
13534
|
-
role="radio"
|
|
13535
|
-
[attr.aria-checked]="mode() === 'stn'"
|
|
13536
|
-
aria-label="Shipping to Nigeria"
|
|
13537
|
-
[class]="cardClass('stn')"
|
|
13538
|
-
(click)="select('stn')"
|
|
13724
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: ShippingModeSwitchComponent, isStandalone: true, selector: "africanies-shipping-mode-switch", inputs: { collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, panelOpen: { classPropertyName: "panelOpen", publicName: "panelOpen", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { panelOpen: "panelOpenChange" }, host: { properties: { "class": "hostClass()" } }, ngImport: i0, template: `
|
|
13725
|
+
@if (collapsed()) {
|
|
13726
|
+
<!-- Narrow rail: icon tiles only — chip + chevron reads as cramped. -->
|
|
13727
|
+
<div
|
|
13728
|
+
class="grid grid-cols-1 gap-1.5"
|
|
13729
|
+
role="radiogroup"
|
|
13730
|
+
aria-label="Shipping mode"
|
|
13539
13731
|
>
|
|
13540
|
-
<
|
|
13541
|
-
|
|
13542
|
-
|
|
13543
|
-
aria-
|
|
13544
|
-
|
|
13732
|
+
<button
|
|
13733
|
+
type="button"
|
|
13734
|
+
role="radio"
|
|
13735
|
+
[attr.aria-checked]="mode() === 'stn'"
|
|
13736
|
+
aria-label="Shipping to Nigeria"
|
|
13737
|
+
title="Shipping to Nigeria"
|
|
13738
|
+
[class]="cardClass('stn')"
|
|
13739
|
+
(click)="select('stn')"
|
|
13545
13740
|
>
|
|
13546
|
-
<
|
|
13547
|
-
|
|
13548
|
-
|
|
13549
|
-
|
|
13550
|
-
|
|
13551
|
-
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13555
|
-
|
|
13556
|
-
|
|
13557
|
-
|
|
13558
|
-
|
|
13559
|
-
|
|
13560
|
-
|
|
13561
|
-
|
|
13562
|
-
|
|
13563
|
-
<svg
|
|
13564
|
-
viewBox="0 0 122.88 107.54"
|
|
13565
|
-
class="h-6 w-6 shrink-0"
|
|
13566
|
-
aria-hidden="true"
|
|
13567
|
-
focusable="false"
|
|
13741
|
+
<svg
|
|
13742
|
+
viewBox="0 0 122.88 107.54"
|
|
13743
|
+
class="h-5 w-5 shrink-0 rotate-180"
|
|
13744
|
+
aria-hidden="true"
|
|
13745
|
+
focusable="false"
|
|
13746
|
+
>
|
|
13747
|
+
<path [attr.d]="glyphPath()" fill="currentColor" />
|
|
13748
|
+
</svg>
|
|
13749
|
+
</button>
|
|
13750
|
+
<button
|
|
13751
|
+
type="button"
|
|
13752
|
+
role="radio"
|
|
13753
|
+
[attr.aria-checked]="mode() === 'sfn'"
|
|
13754
|
+
aria-label="Shipping from Nigeria"
|
|
13755
|
+
title="Shipping from Nigeria"
|
|
13756
|
+
[class]="cardClass('sfn')"
|
|
13757
|
+
(click)="select('sfn')"
|
|
13568
13758
|
>
|
|
13569
|
-
<
|
|
13570
|
-
|
|
13571
|
-
|
|
13572
|
-
|
|
13573
|
-
|
|
13574
|
-
|
|
13575
|
-
|
|
13759
|
+
<svg
|
|
13760
|
+
viewBox="0 0 122.88 107.54"
|
|
13761
|
+
class="h-5 w-5 shrink-0"
|
|
13762
|
+
aria-hidden="true"
|
|
13763
|
+
focusable="false"
|
|
13764
|
+
>
|
|
13765
|
+
<path [attr.d]="glyphPath()" fill="currentColor" />
|
|
13766
|
+
</svg>
|
|
13767
|
+
</button>
|
|
13768
|
+
</div>
|
|
13769
|
+
} @else {
|
|
13770
|
+
<div class="mb-2 flex items-center gap-1.5">
|
|
13771
|
+
<p
|
|
13772
|
+
class="m-0 shrink-0 px-1 text-caption font-semibold uppercase tracking-wide text-neutral-600 dark:text-neutral-400"
|
|
13773
|
+
>
|
|
13774
|
+
Shipping mode
|
|
13775
|
+
</p>
|
|
13776
|
+
<!-- STN / SFN chip only when the tiles are collapsed — open panel already shows both modes. -->
|
|
13777
|
+
@if (!panelOpen()) {
|
|
13778
|
+
<africanies-chip [variant]="modeChipVariant()" size="sm">
|
|
13779
|
+
{{ modeChipLabel() }}
|
|
13780
|
+
</africanies-chip>
|
|
13576
13781
|
}
|
|
13577
|
-
|
|
13578
|
-
|
|
13579
|
-
|
|
13782
|
+
<span class="min-w-0 flex-1" aria-hidden="true"></span>
|
|
13783
|
+
<button
|
|
13784
|
+
type="button"
|
|
13785
|
+
class="inline-flex size-7 shrink-0 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"
|
|
13786
|
+
[attr.aria-label]="
|
|
13787
|
+
panelOpen() ? 'Hide shipping modes' : 'Show shipping modes'
|
|
13788
|
+
"
|
|
13789
|
+
[attr.aria-expanded]="panelOpen()"
|
|
13790
|
+
(click)="togglePanel()"
|
|
13791
|
+
>
|
|
13792
|
+
<africanies-icon
|
|
13793
|
+
[name]="panelOpen() ? 'chevron-up' : 'chevron-down'"
|
|
13794
|
+
[size]="14"
|
|
13795
|
+
/>
|
|
13796
|
+
</button>
|
|
13797
|
+
</div>
|
|
13798
|
+
|
|
13799
|
+
<div
|
|
13800
|
+
class="grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none"
|
|
13801
|
+
[style.grid-template-rows]="panelOpen() ? '1fr' : '0fr'"
|
|
13802
|
+
[attr.aria-hidden]="!panelOpen()"
|
|
13803
|
+
[class.pointer-events-none]="!panelOpen()"
|
|
13804
|
+
>
|
|
13805
|
+
<div class="min-h-0 overflow-hidden">
|
|
13806
|
+
<div
|
|
13807
|
+
class="grid grid-cols-2 gap-1.5"
|
|
13808
|
+
role="radiogroup"
|
|
13809
|
+
aria-label="Shipping mode"
|
|
13810
|
+
>
|
|
13811
|
+
<button
|
|
13812
|
+
type="button"
|
|
13813
|
+
role="radio"
|
|
13814
|
+
[attr.aria-checked]="mode() === 'stn'"
|
|
13815
|
+
aria-label="Shipping to Nigeria"
|
|
13816
|
+
[class]="cardClass('stn')"
|
|
13817
|
+
(click)="select('stn')"
|
|
13818
|
+
>
|
|
13819
|
+
<svg
|
|
13820
|
+
viewBox="0 0 122.88 107.54"
|
|
13821
|
+
class="h-6 w-6 shrink-0 rotate-180"
|
|
13822
|
+
aria-hidden="true"
|
|
13823
|
+
focusable="false"
|
|
13824
|
+
>
|
|
13825
|
+
<path [attr.d]="glyphPath()" fill="currentColor" />
|
|
13826
|
+
</svg>
|
|
13827
|
+
<span class="flex flex-col leading-tight">
|
|
13828
|
+
<span>Shipping</span>
|
|
13829
|
+
<span>to Nigeria</span>
|
|
13830
|
+
</span>
|
|
13831
|
+
</button>
|
|
13832
|
+
<button
|
|
13833
|
+
type="button"
|
|
13834
|
+
role="radio"
|
|
13835
|
+
[attr.aria-checked]="mode() === 'sfn'"
|
|
13836
|
+
aria-label="Shipping from Nigeria"
|
|
13837
|
+
[class]="cardClass('sfn')"
|
|
13838
|
+
(click)="select('sfn')"
|
|
13839
|
+
>
|
|
13840
|
+
<svg
|
|
13841
|
+
viewBox="0 0 122.88 107.54"
|
|
13842
|
+
class="h-6 w-6 shrink-0"
|
|
13843
|
+
aria-hidden="true"
|
|
13844
|
+
focusable="false"
|
|
13845
|
+
>
|
|
13846
|
+
<path [attr.d]="glyphPath()" fill="currentColor" />
|
|
13847
|
+
</svg>
|
|
13848
|
+
<span class="flex flex-col leading-tight">
|
|
13849
|
+
<span>Shipping</span>
|
|
13850
|
+
<span>from Nigeria</span>
|
|
13851
|
+
</span>
|
|
13852
|
+
</button>
|
|
13853
|
+
</div>
|
|
13854
|
+
</div>
|
|
13855
|
+
</div>
|
|
13856
|
+
}
|
|
13857
|
+
`, isInline: true, dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }, { kind: "component", type: ChipComponent, selector: "africanies-chip", inputs: ["variant", "color", "size", "icon", "removable", "removeLabel"], outputs: ["removed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
13580
13858
|
}
|
|
13581
13859
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ShippingModeSwitchComponent, decorators: [{
|
|
13582
13860
|
type: Component,
|
|
@@ -13584,74 +13862,146 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
13584
13862
|
selector: 'africanies-shipping-mode-switch',
|
|
13585
13863
|
standalone: true,
|
|
13586
13864
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
13865
|
+
imports: [AfricaniesIconComponent, ChipComponent],
|
|
13587
13866
|
host: {
|
|
13588
13867
|
'[class]': 'hostClass()',
|
|
13589
13868
|
},
|
|
13590
13869
|
template: `
|
|
13591
|
-
@if (
|
|
13592
|
-
|
|
13593
|
-
|
|
13594
|
-
|
|
13595
|
-
|
|
13596
|
-
|
|
13597
|
-
}
|
|
13598
|
-
<div
|
|
13599
|
-
class="grid gap-1.5"
|
|
13600
|
-
[class.grid-cols-1]="collapsed()"
|
|
13601
|
-
[class.grid-cols-2]="!collapsed()"
|
|
13602
|
-
role="radiogroup"
|
|
13603
|
-
aria-label="Shipping mode"
|
|
13604
|
-
>
|
|
13605
|
-
<button
|
|
13606
|
-
type="button"
|
|
13607
|
-
role="radio"
|
|
13608
|
-
[attr.aria-checked]="mode() === 'stn'"
|
|
13609
|
-
aria-label="Shipping to Nigeria"
|
|
13610
|
-
[class]="cardClass('stn')"
|
|
13611
|
-
(click)="select('stn')"
|
|
13870
|
+
@if (collapsed()) {
|
|
13871
|
+
<!-- Narrow rail: icon tiles only — chip + chevron reads as cramped. -->
|
|
13872
|
+
<div
|
|
13873
|
+
class="grid grid-cols-1 gap-1.5"
|
|
13874
|
+
role="radiogroup"
|
|
13875
|
+
aria-label="Shipping mode"
|
|
13612
13876
|
>
|
|
13613
|
-
<
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
aria-
|
|
13617
|
-
|
|
13877
|
+
<button
|
|
13878
|
+
type="button"
|
|
13879
|
+
role="radio"
|
|
13880
|
+
[attr.aria-checked]="mode() === 'stn'"
|
|
13881
|
+
aria-label="Shipping to Nigeria"
|
|
13882
|
+
title="Shipping to Nigeria"
|
|
13883
|
+
[class]="cardClass('stn')"
|
|
13884
|
+
(click)="select('stn')"
|
|
13618
13885
|
>
|
|
13619
|
-
<
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
|
|
13626
|
-
|
|
13627
|
-
|
|
13628
|
-
|
|
13629
|
-
|
|
13630
|
-
|
|
13631
|
-
|
|
13632
|
-
|
|
13633
|
-
|
|
13634
|
-
|
|
13635
|
-
|
|
13636
|
-
<svg
|
|
13637
|
-
viewBox="0 0 122.88 107.54"
|
|
13638
|
-
class="h-6 w-6 shrink-0"
|
|
13639
|
-
aria-hidden="true"
|
|
13640
|
-
focusable="false"
|
|
13886
|
+
<svg
|
|
13887
|
+
viewBox="0 0 122.88 107.54"
|
|
13888
|
+
class="h-5 w-5 shrink-0 rotate-180"
|
|
13889
|
+
aria-hidden="true"
|
|
13890
|
+
focusable="false"
|
|
13891
|
+
>
|
|
13892
|
+
<path [attr.d]="glyphPath()" fill="currentColor" />
|
|
13893
|
+
</svg>
|
|
13894
|
+
</button>
|
|
13895
|
+
<button
|
|
13896
|
+
type="button"
|
|
13897
|
+
role="radio"
|
|
13898
|
+
[attr.aria-checked]="mode() === 'sfn'"
|
|
13899
|
+
aria-label="Shipping from Nigeria"
|
|
13900
|
+
title="Shipping from Nigeria"
|
|
13901
|
+
[class]="cardClass('sfn')"
|
|
13902
|
+
(click)="select('sfn')"
|
|
13641
13903
|
>
|
|
13642
|
-
<
|
|
13643
|
-
|
|
13644
|
-
|
|
13645
|
-
|
|
13646
|
-
|
|
13647
|
-
|
|
13648
|
-
|
|
13904
|
+
<svg
|
|
13905
|
+
viewBox="0 0 122.88 107.54"
|
|
13906
|
+
class="h-5 w-5 shrink-0"
|
|
13907
|
+
aria-hidden="true"
|
|
13908
|
+
focusable="false"
|
|
13909
|
+
>
|
|
13910
|
+
<path [attr.d]="glyphPath()" fill="currentColor" />
|
|
13911
|
+
</svg>
|
|
13912
|
+
</button>
|
|
13913
|
+
</div>
|
|
13914
|
+
} @else {
|
|
13915
|
+
<div class="mb-2 flex items-center gap-1.5">
|
|
13916
|
+
<p
|
|
13917
|
+
class="m-0 shrink-0 px-1 text-caption font-semibold uppercase tracking-wide text-neutral-600 dark:text-neutral-400"
|
|
13918
|
+
>
|
|
13919
|
+
Shipping mode
|
|
13920
|
+
</p>
|
|
13921
|
+
<!-- STN / SFN chip only when the tiles are collapsed — open panel already shows both modes. -->
|
|
13922
|
+
@if (!panelOpen()) {
|
|
13923
|
+
<africanies-chip [variant]="modeChipVariant()" size="sm">
|
|
13924
|
+
{{ modeChipLabel() }}
|
|
13925
|
+
</africanies-chip>
|
|
13649
13926
|
}
|
|
13650
|
-
|
|
13651
|
-
|
|
13927
|
+
<span class="min-w-0 flex-1" aria-hidden="true"></span>
|
|
13928
|
+
<button
|
|
13929
|
+
type="button"
|
|
13930
|
+
class="inline-flex size-7 shrink-0 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"
|
|
13931
|
+
[attr.aria-label]="
|
|
13932
|
+
panelOpen() ? 'Hide shipping modes' : 'Show shipping modes'
|
|
13933
|
+
"
|
|
13934
|
+
[attr.aria-expanded]="panelOpen()"
|
|
13935
|
+
(click)="togglePanel()"
|
|
13936
|
+
>
|
|
13937
|
+
<africanies-icon
|
|
13938
|
+
[name]="panelOpen() ? 'chevron-up' : 'chevron-down'"
|
|
13939
|
+
[size]="14"
|
|
13940
|
+
/>
|
|
13941
|
+
</button>
|
|
13942
|
+
</div>
|
|
13943
|
+
|
|
13944
|
+
<div
|
|
13945
|
+
class="grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none"
|
|
13946
|
+
[style.grid-template-rows]="panelOpen() ? '1fr' : '0fr'"
|
|
13947
|
+
[attr.aria-hidden]="!panelOpen()"
|
|
13948
|
+
[class.pointer-events-none]="!panelOpen()"
|
|
13949
|
+
>
|
|
13950
|
+
<div class="min-h-0 overflow-hidden">
|
|
13951
|
+
<div
|
|
13952
|
+
class="grid grid-cols-2 gap-1.5"
|
|
13953
|
+
role="radiogroup"
|
|
13954
|
+
aria-label="Shipping mode"
|
|
13955
|
+
>
|
|
13956
|
+
<button
|
|
13957
|
+
type="button"
|
|
13958
|
+
role="radio"
|
|
13959
|
+
[attr.aria-checked]="mode() === 'stn'"
|
|
13960
|
+
aria-label="Shipping to Nigeria"
|
|
13961
|
+
[class]="cardClass('stn')"
|
|
13962
|
+
(click)="select('stn')"
|
|
13963
|
+
>
|
|
13964
|
+
<svg
|
|
13965
|
+
viewBox="0 0 122.88 107.54"
|
|
13966
|
+
class="h-6 w-6 shrink-0 rotate-180"
|
|
13967
|
+
aria-hidden="true"
|
|
13968
|
+
focusable="false"
|
|
13969
|
+
>
|
|
13970
|
+
<path [attr.d]="glyphPath()" fill="currentColor" />
|
|
13971
|
+
</svg>
|
|
13972
|
+
<span class="flex flex-col leading-tight">
|
|
13973
|
+
<span>Shipping</span>
|
|
13974
|
+
<span>to Nigeria</span>
|
|
13975
|
+
</span>
|
|
13976
|
+
</button>
|
|
13977
|
+
<button
|
|
13978
|
+
type="button"
|
|
13979
|
+
role="radio"
|
|
13980
|
+
[attr.aria-checked]="mode() === 'sfn'"
|
|
13981
|
+
aria-label="Shipping from Nigeria"
|
|
13982
|
+
[class]="cardClass('sfn')"
|
|
13983
|
+
(click)="select('sfn')"
|
|
13984
|
+
>
|
|
13985
|
+
<svg
|
|
13986
|
+
viewBox="0 0 122.88 107.54"
|
|
13987
|
+
class="h-6 w-6 shrink-0"
|
|
13988
|
+
aria-hidden="true"
|
|
13989
|
+
focusable="false"
|
|
13990
|
+
>
|
|
13991
|
+
<path [attr.d]="glyphPath()" fill="currentColor" />
|
|
13992
|
+
</svg>
|
|
13993
|
+
<span class="flex flex-col leading-tight">
|
|
13994
|
+
<span>Shipping</span>
|
|
13995
|
+
<span>from Nigeria</span>
|
|
13996
|
+
</span>
|
|
13997
|
+
</button>
|
|
13998
|
+
</div>
|
|
13999
|
+
</div>
|
|
14000
|
+
</div>
|
|
14001
|
+
}
|
|
13652
14002
|
`,
|
|
13653
14003
|
}]
|
|
13654
|
-
}], propDecorators: { collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }] } });
|
|
14004
|
+
}], ctorParameters: () => [], propDecorators: { collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], panelOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelOpen", required: false }] }, { type: i0.Output, args: ["panelOpenChange"] }] } });
|
|
13655
14005
|
|
|
13656
14006
|
/**
|
|
13657
14007
|
* Side-nav shipping mode switcher (`africanies-shipping-mode-switch`).
|
|
@@ -13797,7 +14147,10 @@ const DEFAULT_LINK_ACTIVE$1 = {
|
|
|
13797
14147
|
* ## Parent items with children
|
|
13798
14148
|
* **Expanded rail:** branches start open by default (`expandBranchesByDefault`).
|
|
13799
14149
|
* Clicking a parent only opens/closes the branch (no route change). When any
|
|
13800
|
-
* branch is open, a collapse-all control sits above the list (top right).
|
|
14150
|
+
* branch is open, a sticky collapse-all control sits above the list (top right).
|
|
14151
|
+
* The rail expand/collapse control stays pinned in the logo header. Project
|
|
14152
|
+
* chrome above the scrollable list with `pre-nav` (e.g. shipping modes) or
|
|
14153
|
+
* below with `footer`.
|
|
13801
14154
|
* **Collapsed rail:** clicking a parent expands the rail, opens the
|
|
13802
14155
|
* branch, and activates the first enabled child (router or `activeId`).
|
|
13803
14156
|
*
|
|
@@ -13910,6 +14263,10 @@ class SideNavComponent {
|
|
|
13910
14263
|
collapseAllBranches() {
|
|
13911
14264
|
this.openBranches.set(new Set());
|
|
13912
14265
|
}
|
|
14266
|
+
/** Open every parent branch (e.g. so the collapse-all control is visible). */
|
|
14267
|
+
expandAllBranches() {
|
|
14268
|
+
this.openBranches.set(new Set(this.collectParentIds(this.items())));
|
|
14269
|
+
}
|
|
13913
14270
|
onItemEnter(id) {
|
|
13914
14271
|
if (this.collapsed()) {
|
|
13915
14272
|
this.hoverId.set(id);
|
|
@@ -13942,7 +14299,7 @@ class SideNavComponent {
|
|
|
13942
14299
|
}
|
|
13943
14300
|
rowClass(item) {
|
|
13944
14301
|
const base = 'group relative flex w-full items-center gap-2 rounded-lg text-body-sm no-underline transition-colors ' +
|
|
13945
|
-
'focus-visible:outline focus-visible:
|
|
14302
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus ' +
|
|
13946
14303
|
(this.collapsed() ? 'justify-center px-1.5 py-2' : 'px-3 py-2') +
|
|
13947
14304
|
(item.disabled ? ' cursor-not-allowed opacity-50' : ' cursor-pointer');
|
|
13948
14305
|
const leaf = this.isLeafActive(item);
|
|
@@ -13956,17 +14313,17 @@ class SideNavComponent {
|
|
|
13956
14313
|
if (ancestor) {
|
|
13957
14314
|
return `${base} bg-transparent ${colors.text} font-semibold`;
|
|
13958
14315
|
}
|
|
13959
|
-
return (`${base} font-medium text-neutral-600 hover:bg-background-
|
|
14316
|
+
return (`${base} font-medium text-neutral-600 hover:bg-background-hover hover:text-ink ` +
|
|
13960
14317
|
'dark:text-neutral-400 dark:hover:bg-white/10 dark:hover:text-white');
|
|
13961
14318
|
}
|
|
13962
14319
|
childRowClass(item) {
|
|
13963
14320
|
const base = 'relative flex w-full items-center gap-2 rounded-lg px-3 py-1.5 text-body-sm no-underline transition-colors ' +
|
|
13964
|
-
'focus-visible:outline focus-visible:
|
|
14321
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus ' +
|
|
13965
14322
|
(item.disabled ? 'cursor-not-allowed opacity-50 ' : 'cursor-pointer ');
|
|
13966
14323
|
if (this.isLeafActive(item)) {
|
|
13967
14324
|
return `${base} ${this.modeColor.classes().activeFill} font-semibold`;
|
|
13968
14325
|
}
|
|
13969
|
-
return (`${base} font-medium text-neutral-600 hover:bg-background-
|
|
14326
|
+
return (`${base} font-medium text-neutral-600 hover:bg-background-hover hover:text-ink ` +
|
|
13970
14327
|
'dark:text-neutral-400 dark:hover:bg-white/10 dark:hover:text-white');
|
|
13971
14328
|
}
|
|
13972
14329
|
/**
|
|
@@ -14109,13 +14466,13 @@ class SideNavComponent {
|
|
|
14109
14466
|
return null;
|
|
14110
14467
|
}
|
|
14111
14468
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SideNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
14112
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SideNavComponent, isStandalone: true, selector: "africanies-side-nav", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, activeId: { classPropertyName: "activeId", publicName: "activeId", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, expandParents: { classPropertyName: "expandParents", publicName: "expandParents", isSignal: true, isRequired: false, transformFunction: null }, expandBranchesByDefault: { classPropertyName: "expandBranchesByDefault", publicName: "expandBranchesByDefault", isSignal: true, isRequired: false, transformFunction: null }, linkActiveOptions: { classPropertyName: "linkActiveOptions", publicName: "linkActiveOptions", isSignal: true, isRequired: false, transformFunction: null }, showLogo: { classPropertyName: "showLogo", publicName: "showLogo", isSignal: true, isRequired: false, transformFunction: null }, logoSrc: { classPropertyName: "logoSrc", publicName: "logoSrc", isSignal: true, isRequired: false, transformFunction: null }, logoMiniSrc: { classPropertyName: "logoMiniSrc", publicName: "logoMiniSrc", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange", activeId: "activeIdChange" }, host: { classAttribute: "relative z-20 block h-full" }, ngImport: i0, template: " <aside\n class=\"relative flex h-full flex-col overflow-visible border-r border-border bg-white transition-[width] duration-200 ease-out dark:border-white/10 dark:bg-ink-950\"\n [style.width]=\"collapsed() ? '3.75rem' : '15rem'\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n <div\n class=\"pointer-events-none absolute inset-y-0 left-0 w-[3px] transition-colors\"\n [class]=\"modeColor.classes().bg\"\n aria-hidden=\"true\"\n ></div>\n\n <div\n class=\"flex shrink-0 items-center gap-2 border-b border-border py-3 dark:border-white/10\"\n [class.flex-col]=\"collapsed()\"\n [class.px-3]=\"collapsed()\"\n [class.pl-4]=\"!collapsed()\"\n [class.pr-2]=\"!collapsed()\"\n >\n @if (collapsed()) {\n @if (showLogo()) {\n <img\n [src]=\"resolvedMiniLogo()\"\n alt=\"African Import Export Solutions\"\n class=\"size-8 shrink-0 object-contain\"\n />\n }\n } @else {\n @if (showLogo()) {\n <div class=\"min-w-0 flex-1\">\n <img\n [src]=\"resolvedFullLogo()\"\n alt=\"African Import Export Solutions\"\n class=\"h-9 max-w-full object-contain object-left\"\n />\n </div>\n } @else {\n <div\n class=\"min-w-0 flex-1 truncate text-body-sm font-semibold text-ink dark:text-white\"\n >\n <ng-content select=\"[brand]\" />\n </div>\n }\n }\n <button\n type=\"button\"\n class=\"inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-md text-neutral-600 transition-colors hover:bg-background-welcome hover:text-ink focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink dark:text-neutral-400 dark:hover:bg-white/10 dark:hover:text-white\"\n [attr.aria-label]=\"\n collapsed() ? 'Expand navigation' : 'Collapse navigation'\n \"\n [attr.aria-expanded]=\"!collapsed()\"\n (click)=\"toggleCollapsed()\"\n >\n <africanies-icon\n [name]=\"collapsed() ? 'angle-double-right' : 'angle-double-left'\"\n [size]=\"16\"\n />\n </button>\n </div>\n\n <nav class=\"africanies-overlay-scroll relative flex-1 overflow-y-auto overflow-x-visible px-3 py-3\">\n @if (!collapsed() && expandParents() && hasOpenBranches()) {\n <button\n type=\"button\"\n class=\"absolute right-1.5 top-1.5 z-10 inline-flex size-7 cursor-pointer items-center justify-center rounded-md bg-white text-neutral-500 shadow-sm ring-1 ring-border/80 transition-colors hover:bg-background-welcome hover:text-ink focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink dark:bg-ink-950 dark:text-neutral-400 dark:ring-white/15 dark:hover:bg-white/10 dark:hover:text-white\"\n aria-label=\"Collapse all\"\n (click)=\"collapseAllBranches()\"\n >\n <africanies-icon name=\"compress\" [size]=\"14\" />\n </button>\n }\n <ul class=\"m-0 flex list-none flex-col gap-0.5 p-0\">\n @for (item of items(); track item.id) {\n <li\n class=\"relative overflow-visible\"\n (mouseenter)=\"onItemEnter(item.id)\"\n (mouseleave)=\"onItemLeave(item.id)\"\n >\n @if (item.routerLink !== null && item.routerLink !== undefined) {\n <a\n [routerLink]=\"item.disabled ? null : item.routerLink\"\n [queryParams]=\"item.queryParams\"\n [fragment]=\"item.fragment\"\n [class]=\"rowClass(item)\"\n [attr.aria-current]=\"isLeafActive(item) ? 'page' : null\"\n [attr.aria-expanded]=\"\n item.children?.length ? isBranchOpen(item.id) : null\n \"\n [attr.aria-disabled]=\"item.disabled ? true : null\"\n (click)=\"onActivate(item, $event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowInner\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n [class]=\"rowClass(item)\"\n [disabled]=\"!!item.disabled\"\n [attr.aria-current]=\"isLeafActive(item) ? 'page' : null\"\n [attr.aria-expanded]=\"\n item.children?.length ? isBranchOpen(item.id) : null\n \"\n (click)=\"onActivate(item, $event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowInner\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </button>\n }\n\n @if (!collapsed() && item.children?.length) {\n <div\n class=\"grid transition-[grid-template-rows] duration-200 ease-out\"\n [style.grid-template-rows]=\"\n isBranchOpen(item.id) ? '1fr' : '0fr'\n \"\n [attr.aria-hidden]=\"!isBranchOpen(item.id)\"\n [class.pointer-events-none]=\"!isBranchOpen(item.id)\"\n >\n <ul\n class=\"relative m-0 mt-0.5 min-h-0 list-none space-y-0.5 overflow-hidden py-1 pl-4 before:absolute before:bottom-1 before:left-[1.35rem] before:top-0 before:w-px before:bg-border dark:before:bg-white/15\"\n >\n @for (child of item.children; track child.id) {\n <li\n class=\"transition-opacity duration-200 ease-out\"\n [class.opacity-0]=\"!isBranchOpen(item.id)\"\n [class.opacity-100]=\"isBranchOpen(item.id)\"\n >\n @if (\n child.routerLink !== null &&\n child.routerLink !== undefined\n ) {\n <a\n [routerLink]=\"child.disabled ? null : child.routerLink\"\n [queryParams]=\"child.queryParams\"\n [fragment]=\"child.fragment\"\n [class]=\"childRowClass(child)\"\n [attr.aria-current]=\"\n isLeafActive(child) ? 'page' : null\n \"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon\n [name]=\"icon\"\n [size]=\"14\"\n class=\"shrink-0 opacity-80\"\n />\n }\n <span class=\"truncate\">{{ child.label }}</span>\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: false,\n }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n [class]=\"childRowClass(child)\"\n [disabled]=\"!!child.disabled\"\n [attr.aria-current]=\"\n isLeafActive(child) ? 'page' : null\n \"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon\n [name]=\"icon\"\n [size]=\"14\"\n class=\"shrink-0 opacity-80\"\n />\n }\n <span class=\"truncate\">{{ child.label }}</span>\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: false,\n }\"\n />\n </button>\n }\n </li>\n }\n </ul>\n </div>\n }\n\n @if (collapsed() && hoverId() === item.id) {\n <div\n class=\"absolute left-full top-0 z-50 ml-2 min-w-[11rem] overflow-hidden rounded-md border border-border bg-ink text-white shadow-lg dark:border-white/15\"\n role=\"tooltip\"\n >\n <div\n class=\"absolute inset-y-0 left-0 w-1\"\n [class]=\"modeColor.classes().bg\"\n aria-hidden=\"true\"\n ></div>\n <div class=\"border-b border-white/10 px-3 py-2 pl-4\">\n <p class=\"m-0 text-body-sm font-semibold\">{{ item.label }}</p>\n </div>\n @if (item.children?.length) {\n <ul class=\"m-0 list-none space-y-0.5 p-1.5\">\n @for (child of item.children; track child.id) {\n <li>\n @if (\n child.routerLink !== null &&\n child.routerLink !== undefined\n ) {\n <a\n [routerLink]=\"\n child.disabled ? null : child.routerLink\n \"\n [queryParams]=\"child.queryParams\"\n [fragment]=\"child.fragment\"\n class=\"relative flex items-center gap-2 rounded px-2.5 py-1.5 text-body-sm text-white/85 no-underline transition-colors hover:bg-white/10 hover:text-white\"\n [class.opacity-50]=\"child.disabled\"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon [name]=\"icon\" [size]=\"14\" />\n }\n {{ child.label }}\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: true,\n }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n class=\"relative flex w-full items-center gap-2 rounded px-2.5 py-1.5 text-left text-body-sm text-white/85 transition-colors hover:bg-white/10 hover:text-white\"\n [disabled]=\"!!child.disabled\"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon [name]=\"icon\" [size]=\"14\" />\n }\n {{ child.label }}\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: true,\n }\"\n />\n </button>\n }\n </li>\n }\n </ul>\n }\n </div>\n }\n </li>\n }\n </ul>\n </nav>\n\n <ng-content select=\"[footer]\" />\n </aside>\n\n <ng-template #rowInner let-item>\n <span class=\"inline-flex size-5 shrink-0 items-center justify-center\">\n @if (item.icon; as icon) {\n <africanies-icon [name]=\"icon\" [size]=\"16\" />\n } @else {\n <span\n class=\"size-1.5 rounded-full bg-current opacity-70\"\n aria-hidden=\"true\"\n ></span>\n }\n </span>\n @if (!collapsed()) {\n <span class=\"min-w-0 flex-1 truncate text-left\">{{ item.label }}</span>\n @if (item.children?.length) {\n <africanies-icon\n name=\"chevron-down\"\n [size]=\"14\"\n class=\"shrink-0 opacity-70 transition-transform duration-200 ease-out\"\n [class.rotate-180]=\"isBranchOpen(item.id)\"\n />\n }\n }\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: item.badge,\n compact: collapsed(),\n }\"\n />\n </ng-template>\n\n <ng-template #navBadge let-visible=\"visible\" let-compact=\"compact\">\n @if (visible) {\n <span\n class=\"pointer-events-none absolute z-10 overflow-visible\"\n [class]=\"compact ? 'right-0.5 top-0.5 h-2 w-2' : 'right-1.5 top-1 h-2 w-2'\"\n aria-hidden=\"true\"\n >\n <span\n class=\"africanies-side-nav-badge-ping absolute left-1/2 top-1/2 size-2 rounded-full bg-danger\"\n ></span>\n <span\n class=\"absolute left-1/2 top-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-danger ring-2 ring-white dark:ring-ink\"\n ></span>\n </span>\n }\n </ng-template>", styles: ["@keyframes africanies-side-nav-badge-pulse{0%{transform:translate(-50%,-50%) scale(.85);opacity:.9}70%{transform:translate(-50%,-50%) scale(2.4);opacity:0}to{transform:translate(-50%,-50%) scale(2.4);opacity:0}}.africanies-side-nav-badge-ping{animation:africanies-side-nav-badge-pulse 1.4s cubic-bezier(0,0,.2,1) infinite}@media(prefers-reduced-motion:reduce){.africanies-side-nav-badge-ping{animation:none;opacity:.5}}\n"], dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
14469
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SideNavComponent, isStandalone: true, selector: "africanies-side-nav", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, activeId: { classPropertyName: "activeId", publicName: "activeId", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, expandParents: { classPropertyName: "expandParents", publicName: "expandParents", isSignal: true, isRequired: false, transformFunction: null }, expandBranchesByDefault: { classPropertyName: "expandBranchesByDefault", publicName: "expandBranchesByDefault", isSignal: true, isRequired: false, transformFunction: null }, linkActiveOptions: { classPropertyName: "linkActiveOptions", publicName: "linkActiveOptions", isSignal: true, isRequired: false, transformFunction: null }, showLogo: { classPropertyName: "showLogo", publicName: "showLogo", isSignal: true, isRequired: false, transformFunction: null }, logoSrc: { classPropertyName: "logoSrc", publicName: "logoSrc", isSignal: true, isRequired: false, transformFunction: null }, logoMiniSrc: { classPropertyName: "logoMiniSrc", publicName: "logoMiniSrc", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange", activeId: "activeIdChange" }, host: { classAttribute: "relative z-20 block h-full min-h-0" }, ngImport: i0, template: " <aside\n class=\"relative flex h-full min-h-0 flex-col overflow-visible border-r border-border bg-surface transition-[width] duration-200 ease-out dark:border-white/10 dark:bg-ink-950\"\n [style.width]=\"collapsed() ? '3.75rem' : '15rem'\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n <div\n class=\"pointer-events-none absolute inset-y-0 left-0 w-[3px] transition-colors\"\n [class]=\"modeColor.classes().bg\"\n aria-hidden=\"true\"\n ></div>\n\n <div\n class=\"sticky top-0 z-20 flex shrink-0 items-center gap-2 border-b border-border bg-surface py-3 dark:border-white/10 dark:bg-ink-950\"\n [class.flex-col]=\"collapsed()\"\n [class.px-3]=\"collapsed()\"\n [class.pl-4]=\"!collapsed()\"\n [class.pr-2]=\"!collapsed()\"\n >\n @if (collapsed()) {\n @if (showLogo()) {\n <img\n [src]=\"resolvedMiniLogo()\"\n alt=\"African Import Export Solutions\"\n class=\"size-8 shrink-0 object-contain\"\n />\n }\n } @else {\n @if (showLogo()) {\n <div class=\"min-w-0 flex-1\">\n <img\n [src]=\"resolvedFullLogo()\"\n alt=\"African Import Export Solutions\"\n class=\"h-9 max-w-full object-contain object-left\"\n />\n </div>\n } @else {\n <div\n class=\"min-w-0 flex-1 truncate text-body-sm font-semibold text-ink dark:text-white\"\n >\n <ng-content select=\"[brand]\" />\n </div>\n }\n }\n <button\n type=\"button\"\n class=\"inline-flex size-8 shrink-0 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\"\n data-onboarding=\"nav-collapse\"\n [attr.aria-label]=\"\n collapsed() ? 'Expand navigation' : 'Collapse navigation'\n \"\n [attr.aria-expanded]=\"!collapsed()\"\n (click)=\"toggleCollapsed()\"\n >\n <africanies-icon\n [name]=\"collapsed() ? 'angle-double-right' : 'angle-double-left'\"\n [size]=\"16\"\n />\n </button>\n </div>\n\n <ng-content select=\"[pre-nav]\" />\n\n <nav\n class=\"africanies-overlay-scroll relative min-h-0 flex-1 overflow-y-auto overflow-x-visible px-3 py-3\"\n >\n @if (!collapsed() && expandParents() && hasOpenBranches()) {\n <!-- Zero-height sticky host: keeps the control pinned without reserving a row. -->\n <div class=\"sticky top-0 z-20 h-0 overflow-visible\">\n <button\n type=\"button\"\n class=\"absolute -right-2 -top-1 inline-flex size-7 cursor-pointer items-center justify-center rounded-md bg-surface text-neutral-600 shadow-sm ring-1 ring-border-strong 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:bg-ink-950 dark:text-neutral-400 dark:ring-white/15 dark:hover:bg-ink-surface dark:hover:text-white\"\n data-onboarding=\"nav-branches-collapse\"\n aria-label=\"Collapse all\"\n (click)=\"collapseAllBranches()\"\n >\n <africanies-icon name=\"compress\" [size]=\"14\" />\n </button>\n </div>\n }\n <ul class=\"m-0 flex list-none flex-col gap-0.5 p-0\">\n @for (item of items(); track item.id) {\n <li\n class=\"relative overflow-visible last:mb-0\"\n [class.mb-3]=\"!collapsed() && !item.children?.length\"\n (mouseenter)=\"onItemEnter(item.id)\"\n (mouseleave)=\"onItemLeave(item.id)\"\n >\n @if (item.routerLink !== null && item.routerLink !== undefined) {\n <a\n [routerLink]=\"item.disabled ? null : item.routerLink\"\n [queryParams]=\"item.queryParams\"\n [fragment]=\"item.fragment\"\n [class]=\"rowClass(item)\"\n [attr.aria-current]=\"isLeafActive(item) ? 'page' : null\"\n [attr.aria-expanded]=\"\n item.children?.length ? isBranchOpen(item.id) : null\n \"\n [attr.aria-disabled]=\"item.disabled ? true : null\"\n (click)=\"onActivate(item, $event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowInner\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n [class]=\"rowClass(item)\"\n [disabled]=\"!!item.disabled\"\n [attr.aria-current]=\"isLeafActive(item) ? 'page' : null\"\n [attr.aria-expanded]=\"\n item.children?.length ? isBranchOpen(item.id) : null\n \"\n (click)=\"onActivate(item, $event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowInner\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </button>\n }\n\n @if (!collapsed() && item.children?.length) {\n <div\n class=\"grid transition-[grid-template-rows] duration-200 ease-out\"\n [style.grid-template-rows]=\"\n isBranchOpen(item.id) ? '1fr' : '0fr'\n \"\n [attr.aria-hidden]=\"!isBranchOpen(item.id)\"\n [class.pointer-events-none]=\"!isBranchOpen(item.id)\"\n >\n <ul\n class=\"relative m-0 mt-0.5 min-h-0 list-none space-y-0.5 overflow-hidden py-1 pl-4 before:absolute before:bottom-1 before:left-[1.35rem] before:top-0 before:w-px before:bg-border dark:before:bg-white/15\"\n >\n @for (child of item.children; track child.id) {\n <li\n class=\"transition-opacity duration-200 ease-out\"\n [class.opacity-0]=\"!isBranchOpen(item.id)\"\n [class.opacity-100]=\"isBranchOpen(item.id)\"\n >\n @if (\n child.routerLink !== null &&\n child.routerLink !== undefined\n ) {\n <a\n [routerLink]=\"child.disabled ? null : child.routerLink\"\n [queryParams]=\"child.queryParams\"\n [fragment]=\"child.fragment\"\n [class]=\"childRowClass(child)\"\n [attr.aria-current]=\"\n isLeafActive(child) ? 'page' : null\n \"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon\n [name]=\"icon\"\n [size]=\"14\"\n class=\"shrink-0 opacity-80\"\n />\n }\n <span class=\"truncate\">{{ child.label }}</span>\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: false,\n }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n [class]=\"childRowClass(child)\"\n [disabled]=\"!!child.disabled\"\n [attr.aria-current]=\"\n isLeafActive(child) ? 'page' : null\n \"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon\n [name]=\"icon\"\n [size]=\"14\"\n class=\"shrink-0 opacity-80\"\n />\n }\n <span class=\"truncate\">{{ child.label }}</span>\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: false,\n }\"\n />\n </button>\n }\n </li>\n }\n </ul>\n </div>\n }\n\n @if (collapsed() && hoverId() === item.id) {\n <div\n class=\"absolute left-full top-0 z-50 ml-2 min-w-[11rem] overflow-hidden rounded-md border border-border bg-ink text-white shadow-lg dark:border-white/15\"\n role=\"tooltip\"\n >\n <div\n class=\"absolute inset-y-0 left-0 w-1\"\n [class]=\"modeColor.classes().bg\"\n aria-hidden=\"true\"\n ></div>\n <div class=\"border-b border-white/10 px-3 py-2 pl-4\">\n <p class=\"m-0 text-body-sm font-semibold\">{{ item.label }}</p>\n </div>\n @if (item.children?.length) {\n <ul class=\"m-0 list-none space-y-0.5 p-1.5\">\n @for (child of item.children; track child.id) {\n <li>\n @if (\n child.routerLink !== null &&\n child.routerLink !== undefined\n ) {\n <a\n [routerLink]=\"\n child.disabled ? null : child.routerLink\n \"\n [queryParams]=\"child.queryParams\"\n [fragment]=\"child.fragment\"\n class=\"relative flex items-center gap-2 rounded px-2.5 py-1.5 text-body-sm text-white/85 no-underline transition-colors hover:bg-white/10 hover:text-white\"\n [class.opacity-50]=\"child.disabled\"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon [name]=\"icon\" [size]=\"14\" />\n }\n {{ child.label }}\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: true,\n }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n class=\"relative flex w-full items-center gap-2 rounded px-2.5 py-1.5 text-left text-body-sm text-white/85 transition-colors hover:bg-white/10 hover:text-white\"\n [disabled]=\"!!child.disabled\"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon [name]=\"icon\" [size]=\"14\" />\n }\n {{ child.label }}\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: true,\n }\"\n />\n </button>\n }\n </li>\n }\n </ul>\n }\n </div>\n }\n </li>\n }\n </ul>\n </nav>\n\n <ng-content select=\"[footer]\" />\n </aside>\n\n <ng-template #rowInner let-item>\n <span class=\"inline-flex size-5 shrink-0 items-center justify-center\">\n @if (item.icon; as icon) {\n <africanies-icon [name]=\"icon\" [size]=\"16\" />\n } @else {\n <span\n class=\"size-1.5 rounded-full bg-current opacity-70\"\n aria-hidden=\"true\"\n ></span>\n }\n </span>\n @if (!collapsed()) {\n <span class=\"min-w-0 flex-1 truncate text-left\">{{ item.label }}</span>\n @if (item.children?.length) {\n <africanies-icon\n name=\"chevron-down\"\n [size]=\"14\"\n class=\"shrink-0 opacity-70 transition-transform duration-200 ease-out\"\n [class.rotate-180]=\"isBranchOpen(item.id)\"\n />\n }\n }\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: item.badge,\n compact: collapsed(),\n }\"\n />\n </ng-template>\n\n <ng-template #navBadge let-visible=\"visible\" let-compact=\"compact\">\n @if (visible) {\n <span\n class=\"pointer-events-none absolute z-10 overflow-visible\"\n [class]=\"compact ? 'right-0.5 top-0.5 h-2 w-2' : 'right-1.5 top-1 h-2 w-2'\"\n aria-hidden=\"true\"\n >\n <span\n class=\"africanies-side-nav-badge-ping absolute left-1/2 top-1/2 size-2 rounded-full bg-danger\"\n ></span>\n <span\n class=\"absolute left-1/2 top-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-danger ring-2 ring-white dark:ring-ink\"\n ></span>\n </span>\n }\n </ng-template>", styles: ["@keyframes africanies-side-nav-badge-pulse{0%{transform:translate(-50%,-50%) scale(.85);opacity:.9}70%{transform:translate(-50%,-50%) scale(2.4);opacity:0}to{transform:translate(-50%,-50%) scale(2.4);opacity:0}}.africanies-side-nav-badge-ping{animation:africanies-side-nav-badge-pulse 1.4s cubic-bezier(0,0,.2,1) infinite}@media(prefers-reduced-motion:reduce){.africanies-side-nav-badge-ping{animation:none;opacity:.5}}\n"], dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
14113
14470
|
}
|
|
14114
14471
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SideNavComponent, decorators: [{
|
|
14115
14472
|
type: Component,
|
|
14116
14473
|
args: [{ selector: 'africanies-side-nav', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AfricaniesIconComponent, RouterLink, NgTemplateOutlet], host: {
|
|
14117
|
-
class: 'relative z-20 block h-full',
|
|
14118
|
-
}, template: " <aside\n class=\"relative flex h-full flex-col overflow-visible border-r border-border bg-white transition-[width] duration-200 ease-out dark:border-white/10 dark:bg-ink-950\"\n [style.width]=\"collapsed() ? '3.75rem' : '15rem'\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n <div\n class=\"pointer-events-none absolute inset-y-0 left-0 w-[3px] transition-colors\"\n [class]=\"modeColor.classes().bg\"\n aria-hidden=\"true\"\n ></div>\n\n <div\n class=\"flex shrink-0 items-center gap-2 border-b border-border py-3 dark:border-white/10\"\n [class.flex-col]=\"collapsed()\"\n [class.px-3]=\"collapsed()\"\n [class.pl-4]=\"!collapsed()\"\n [class.pr-2]=\"!collapsed()\"\n >\n @if (collapsed()) {\n @if (showLogo()) {\n <img\n [src]=\"resolvedMiniLogo()\"\n alt=\"African Import Export Solutions\"\n class=\"size-8 shrink-0 object-contain\"\n />\n }\n } @else {\n @if (showLogo()) {\n <div class=\"min-w-0 flex-1\">\n <img\n [src]=\"resolvedFullLogo()\"\n alt=\"African Import Export Solutions\"\n class=\"h-9 max-w-full object-contain object-left\"\n />\n </div>\n } @else {\n <div\n class=\"min-w-0 flex-1 truncate text-body-sm font-semibold text-ink dark:text-white\"\n >\n <ng-content select=\"[brand]\" />\n </div>\n }\n }\n <button\n type=\"button\"\n class=\"inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-md text-neutral-600 transition-colors hover:bg-background-welcome hover:text-ink focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink dark:text-neutral-400 dark:hover:bg-white/10 dark:hover:text-white\"\n [attr.aria-label]=\"\n collapsed() ? 'Expand navigation' : 'Collapse navigation'\n \"\n [attr.aria-expanded]=\"!collapsed()\"\n (click)=\"toggleCollapsed()\"\n >\n <africanies-icon\n [name]=\"collapsed() ? 'angle-double-right' : 'angle-double-left'\"\n [size]=\"16\"\n />\n </button>\n </div>\n\n <nav class=\"africanies-overlay-scroll relative flex-1 overflow-y-auto overflow-x-visible px-3 py-3\">\n @if (!collapsed() && expandParents() && hasOpenBranches()) {\n <button\n type=\"button\"\n class=\"absolute right-1.5 top-1.5 z-10 inline-flex size-7 cursor-pointer items-center justify-center rounded-md bg-white text-neutral-500 shadow-sm ring-1 ring-border/80 transition-colors hover:bg-background-welcome hover:text-ink focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink dark:bg-ink-950 dark:text-neutral-400 dark:ring-white/15 dark:hover:bg-white/10 dark:hover:text-white\"\n aria-label=\"Collapse all\"\n (click)=\"collapseAllBranches()\"\n >\n <africanies-icon name=\"compress\" [size]=\"14\" />\n </button>\n }\n <ul class=\"m-0 flex list-none flex-col gap-0.5 p-0\">\n @for (item of items(); track item.id) {\n <li\n class=\"relative overflow-visible\"\n (mouseenter)=\"onItemEnter(item.id)\"\n (mouseleave)=\"onItemLeave(item.id)\"\n >\n @if (item.routerLink !== null && item.routerLink !== undefined) {\n <a\n [routerLink]=\"item.disabled ? null : item.routerLink\"\n [queryParams]=\"item.queryParams\"\n [fragment]=\"item.fragment\"\n [class]=\"rowClass(item)\"\n [attr.aria-current]=\"isLeafActive(item) ? 'page' : null\"\n [attr.aria-expanded]=\"\n item.children?.length ? isBranchOpen(item.id) : null\n \"\n [attr.aria-disabled]=\"item.disabled ? true : null\"\n (click)=\"onActivate(item, $event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowInner\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n [class]=\"rowClass(item)\"\n [disabled]=\"!!item.disabled\"\n [attr.aria-current]=\"isLeafActive(item) ? 'page' : null\"\n [attr.aria-expanded]=\"\n item.children?.length ? isBranchOpen(item.id) : null\n \"\n (click)=\"onActivate(item, $event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowInner\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </button>\n }\n\n @if (!collapsed() && item.children?.length) {\n <div\n class=\"grid transition-[grid-template-rows] duration-200 ease-out\"\n [style.grid-template-rows]=\"\n isBranchOpen(item.id) ? '1fr' : '0fr'\n \"\n [attr.aria-hidden]=\"!isBranchOpen(item.id)\"\n [class.pointer-events-none]=\"!isBranchOpen(item.id)\"\n >\n <ul\n class=\"relative m-0 mt-0.5 min-h-0 list-none space-y-0.5 overflow-hidden py-1 pl-4 before:absolute before:bottom-1 before:left-[1.35rem] before:top-0 before:w-px before:bg-border dark:before:bg-white/15\"\n >\n @for (child of item.children; track child.id) {\n <li\n class=\"transition-opacity duration-200 ease-out\"\n [class.opacity-0]=\"!isBranchOpen(item.id)\"\n [class.opacity-100]=\"isBranchOpen(item.id)\"\n >\n @if (\n child.routerLink !== null &&\n child.routerLink !== undefined\n ) {\n <a\n [routerLink]=\"child.disabled ? null : child.routerLink\"\n [queryParams]=\"child.queryParams\"\n [fragment]=\"child.fragment\"\n [class]=\"childRowClass(child)\"\n [attr.aria-current]=\"\n isLeafActive(child) ? 'page' : null\n \"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon\n [name]=\"icon\"\n [size]=\"14\"\n class=\"shrink-0 opacity-80\"\n />\n }\n <span class=\"truncate\">{{ child.label }}</span>\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: false,\n }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n [class]=\"childRowClass(child)\"\n [disabled]=\"!!child.disabled\"\n [attr.aria-current]=\"\n isLeafActive(child) ? 'page' : null\n \"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon\n [name]=\"icon\"\n [size]=\"14\"\n class=\"shrink-0 opacity-80\"\n />\n }\n <span class=\"truncate\">{{ child.label }}</span>\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: false,\n }\"\n />\n </button>\n }\n </li>\n }\n </ul>\n </div>\n }\n\n @if (collapsed() && hoverId() === item.id) {\n <div\n class=\"absolute left-full top-0 z-50 ml-2 min-w-[11rem] overflow-hidden rounded-md border border-border bg-ink text-white shadow-lg dark:border-white/15\"\n role=\"tooltip\"\n >\n <div\n class=\"absolute inset-y-0 left-0 w-1\"\n [class]=\"modeColor.classes().bg\"\n aria-hidden=\"true\"\n ></div>\n <div class=\"border-b border-white/10 px-3 py-2 pl-4\">\n <p class=\"m-0 text-body-sm font-semibold\">{{ item.label }}</p>\n </div>\n @if (item.children?.length) {\n <ul class=\"m-0 list-none space-y-0.5 p-1.5\">\n @for (child of item.children; track child.id) {\n <li>\n @if (\n child.routerLink !== null &&\n child.routerLink !== undefined\n ) {\n <a\n [routerLink]=\"\n child.disabled ? null : child.routerLink\n \"\n [queryParams]=\"child.queryParams\"\n [fragment]=\"child.fragment\"\n class=\"relative flex items-center gap-2 rounded px-2.5 py-1.5 text-body-sm text-white/85 no-underline transition-colors hover:bg-white/10 hover:text-white\"\n [class.opacity-50]=\"child.disabled\"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon [name]=\"icon\" [size]=\"14\" />\n }\n {{ child.label }}\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: true,\n }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n class=\"relative flex w-full items-center gap-2 rounded px-2.5 py-1.5 text-left text-body-sm text-white/85 transition-colors hover:bg-white/10 hover:text-white\"\n [disabled]=\"!!child.disabled\"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon [name]=\"icon\" [size]=\"14\" />\n }\n {{ child.label }}\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: true,\n }\"\n />\n </button>\n }\n </li>\n }\n </ul>\n }\n </div>\n }\n </li>\n }\n </ul>\n </nav>\n\n <ng-content select=\"[footer]\" />\n </aside>\n\n <ng-template #rowInner let-item>\n <span class=\"inline-flex size-5 shrink-0 items-center justify-center\">\n @if (item.icon; as icon) {\n <africanies-icon [name]=\"icon\" [size]=\"16\" />\n } @else {\n <span\n class=\"size-1.5 rounded-full bg-current opacity-70\"\n aria-hidden=\"true\"\n ></span>\n }\n </span>\n @if (!collapsed()) {\n <span class=\"min-w-0 flex-1 truncate text-left\">{{ item.label }}</span>\n @if (item.children?.length) {\n <africanies-icon\n name=\"chevron-down\"\n [size]=\"14\"\n class=\"shrink-0 opacity-70 transition-transform duration-200 ease-out\"\n [class.rotate-180]=\"isBranchOpen(item.id)\"\n />\n }\n }\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: item.badge,\n compact: collapsed(),\n }\"\n />\n </ng-template>\n\n <ng-template #navBadge let-visible=\"visible\" let-compact=\"compact\">\n @if (visible) {\n <span\n class=\"pointer-events-none absolute z-10 overflow-visible\"\n [class]=\"compact ? 'right-0.5 top-0.5 h-2 w-2' : 'right-1.5 top-1 h-2 w-2'\"\n aria-hidden=\"true\"\n >\n <span\n class=\"africanies-side-nav-badge-ping absolute left-1/2 top-1/2 size-2 rounded-full bg-danger\"\n ></span>\n <span\n class=\"absolute left-1/2 top-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-danger ring-2 ring-white dark:ring-ink\"\n ></span>\n </span>\n }\n </ng-template>", styles: ["@keyframes africanies-side-nav-badge-pulse{0%{transform:translate(-50%,-50%) scale(.85);opacity:.9}70%{transform:translate(-50%,-50%) scale(2.4);opacity:0}to{transform:translate(-50%,-50%) scale(2.4);opacity:0}}.africanies-side-nav-badge-ping{animation:africanies-side-nav-badge-pulse 1.4s cubic-bezier(0,0,.2,1) infinite}@media(prefers-reduced-motion:reduce){.africanies-side-nav-badge-ping{animation:none;opacity:.5}}\n"] }]
|
|
14474
|
+
class: 'relative z-20 block h-full min-h-0',
|
|
14475
|
+
}, template: " <aside\n class=\"relative flex h-full min-h-0 flex-col overflow-visible border-r border-border bg-surface transition-[width] duration-200 ease-out dark:border-white/10 dark:bg-ink-950\"\n [style.width]=\"collapsed() ? '3.75rem' : '15rem'\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n <div\n class=\"pointer-events-none absolute inset-y-0 left-0 w-[3px] transition-colors\"\n [class]=\"modeColor.classes().bg\"\n aria-hidden=\"true\"\n ></div>\n\n <div\n class=\"sticky top-0 z-20 flex shrink-0 items-center gap-2 border-b border-border bg-surface py-3 dark:border-white/10 dark:bg-ink-950\"\n [class.flex-col]=\"collapsed()\"\n [class.px-3]=\"collapsed()\"\n [class.pl-4]=\"!collapsed()\"\n [class.pr-2]=\"!collapsed()\"\n >\n @if (collapsed()) {\n @if (showLogo()) {\n <img\n [src]=\"resolvedMiniLogo()\"\n alt=\"African Import Export Solutions\"\n class=\"size-8 shrink-0 object-contain\"\n />\n }\n } @else {\n @if (showLogo()) {\n <div class=\"min-w-0 flex-1\">\n <img\n [src]=\"resolvedFullLogo()\"\n alt=\"African Import Export Solutions\"\n class=\"h-9 max-w-full object-contain object-left\"\n />\n </div>\n } @else {\n <div\n class=\"min-w-0 flex-1 truncate text-body-sm font-semibold text-ink dark:text-white\"\n >\n <ng-content select=\"[brand]\" />\n </div>\n }\n }\n <button\n type=\"button\"\n class=\"inline-flex size-8 shrink-0 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\"\n data-onboarding=\"nav-collapse\"\n [attr.aria-label]=\"\n collapsed() ? 'Expand navigation' : 'Collapse navigation'\n \"\n [attr.aria-expanded]=\"!collapsed()\"\n (click)=\"toggleCollapsed()\"\n >\n <africanies-icon\n [name]=\"collapsed() ? 'angle-double-right' : 'angle-double-left'\"\n [size]=\"16\"\n />\n </button>\n </div>\n\n <ng-content select=\"[pre-nav]\" />\n\n <nav\n class=\"africanies-overlay-scroll relative min-h-0 flex-1 overflow-y-auto overflow-x-visible px-3 py-3\"\n >\n @if (!collapsed() && expandParents() && hasOpenBranches()) {\n <!-- Zero-height sticky host: keeps the control pinned without reserving a row. -->\n <div class=\"sticky top-0 z-20 h-0 overflow-visible\">\n <button\n type=\"button\"\n class=\"absolute -right-2 -top-1 inline-flex size-7 cursor-pointer items-center justify-center rounded-md bg-surface text-neutral-600 shadow-sm ring-1 ring-border-strong 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:bg-ink-950 dark:text-neutral-400 dark:ring-white/15 dark:hover:bg-ink-surface dark:hover:text-white\"\n data-onboarding=\"nav-branches-collapse\"\n aria-label=\"Collapse all\"\n (click)=\"collapseAllBranches()\"\n >\n <africanies-icon name=\"compress\" [size]=\"14\" />\n </button>\n </div>\n }\n <ul class=\"m-0 flex list-none flex-col gap-0.5 p-0\">\n @for (item of items(); track item.id) {\n <li\n class=\"relative overflow-visible last:mb-0\"\n [class.mb-3]=\"!collapsed() && !item.children?.length\"\n (mouseenter)=\"onItemEnter(item.id)\"\n (mouseleave)=\"onItemLeave(item.id)\"\n >\n @if (item.routerLink !== null && item.routerLink !== undefined) {\n <a\n [routerLink]=\"item.disabled ? null : item.routerLink\"\n [queryParams]=\"item.queryParams\"\n [fragment]=\"item.fragment\"\n [class]=\"rowClass(item)\"\n [attr.aria-current]=\"isLeafActive(item) ? 'page' : null\"\n [attr.aria-expanded]=\"\n item.children?.length ? isBranchOpen(item.id) : null\n \"\n [attr.aria-disabled]=\"item.disabled ? true : null\"\n (click)=\"onActivate(item, $event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowInner\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n [class]=\"rowClass(item)\"\n [disabled]=\"!!item.disabled\"\n [attr.aria-current]=\"isLeafActive(item) ? 'page' : null\"\n [attr.aria-expanded]=\"\n item.children?.length ? isBranchOpen(item.id) : null\n \"\n (click)=\"onActivate(item, $event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowInner\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </button>\n }\n\n @if (!collapsed() && item.children?.length) {\n <div\n class=\"grid transition-[grid-template-rows] duration-200 ease-out\"\n [style.grid-template-rows]=\"\n isBranchOpen(item.id) ? '1fr' : '0fr'\n \"\n [attr.aria-hidden]=\"!isBranchOpen(item.id)\"\n [class.pointer-events-none]=\"!isBranchOpen(item.id)\"\n >\n <ul\n class=\"relative m-0 mt-0.5 min-h-0 list-none space-y-0.5 overflow-hidden py-1 pl-4 before:absolute before:bottom-1 before:left-[1.35rem] before:top-0 before:w-px before:bg-border dark:before:bg-white/15\"\n >\n @for (child of item.children; track child.id) {\n <li\n class=\"transition-opacity duration-200 ease-out\"\n [class.opacity-0]=\"!isBranchOpen(item.id)\"\n [class.opacity-100]=\"isBranchOpen(item.id)\"\n >\n @if (\n child.routerLink !== null &&\n child.routerLink !== undefined\n ) {\n <a\n [routerLink]=\"child.disabled ? null : child.routerLink\"\n [queryParams]=\"child.queryParams\"\n [fragment]=\"child.fragment\"\n [class]=\"childRowClass(child)\"\n [attr.aria-current]=\"\n isLeafActive(child) ? 'page' : null\n \"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon\n [name]=\"icon\"\n [size]=\"14\"\n class=\"shrink-0 opacity-80\"\n />\n }\n <span class=\"truncate\">{{ child.label }}</span>\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: false,\n }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n [class]=\"childRowClass(child)\"\n [disabled]=\"!!child.disabled\"\n [attr.aria-current]=\"\n isLeafActive(child) ? 'page' : null\n \"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon\n [name]=\"icon\"\n [size]=\"14\"\n class=\"shrink-0 opacity-80\"\n />\n }\n <span class=\"truncate\">{{ child.label }}</span>\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: false,\n }\"\n />\n </button>\n }\n </li>\n }\n </ul>\n </div>\n }\n\n @if (collapsed() && hoverId() === item.id) {\n <div\n class=\"absolute left-full top-0 z-50 ml-2 min-w-[11rem] overflow-hidden rounded-md border border-border bg-ink text-white shadow-lg dark:border-white/15\"\n role=\"tooltip\"\n >\n <div\n class=\"absolute inset-y-0 left-0 w-1\"\n [class]=\"modeColor.classes().bg\"\n aria-hidden=\"true\"\n ></div>\n <div class=\"border-b border-white/10 px-3 py-2 pl-4\">\n <p class=\"m-0 text-body-sm font-semibold\">{{ item.label }}</p>\n </div>\n @if (item.children?.length) {\n <ul class=\"m-0 list-none space-y-0.5 p-1.5\">\n @for (child of item.children; track child.id) {\n <li>\n @if (\n child.routerLink !== null &&\n child.routerLink !== undefined\n ) {\n <a\n [routerLink]=\"\n child.disabled ? null : child.routerLink\n \"\n [queryParams]=\"child.queryParams\"\n [fragment]=\"child.fragment\"\n class=\"relative flex items-center gap-2 rounded px-2.5 py-1.5 text-body-sm text-white/85 no-underline transition-colors hover:bg-white/10 hover:text-white\"\n [class.opacity-50]=\"child.disabled\"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon [name]=\"icon\" [size]=\"14\" />\n }\n {{ child.label }}\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: true,\n }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n class=\"relative flex w-full items-center gap-2 rounded px-2.5 py-1.5 text-left text-body-sm text-white/85 transition-colors hover:bg-white/10 hover:text-white\"\n [disabled]=\"!!child.disabled\"\n (click)=\"onActivate(child, $event)\"\n >\n @if (child.icon; as icon) {\n <africanies-icon [name]=\"icon\" [size]=\"14\" />\n }\n {{ child.label }}\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: child.badge,\n compact: true,\n }\"\n />\n </button>\n }\n </li>\n }\n </ul>\n }\n </div>\n }\n </li>\n }\n </ul>\n </nav>\n\n <ng-content select=\"[footer]\" />\n </aside>\n\n <ng-template #rowInner let-item>\n <span class=\"inline-flex size-5 shrink-0 items-center justify-center\">\n @if (item.icon; as icon) {\n <africanies-icon [name]=\"icon\" [size]=\"16\" />\n } @else {\n <span\n class=\"size-1.5 rounded-full bg-current opacity-70\"\n aria-hidden=\"true\"\n ></span>\n }\n </span>\n @if (!collapsed()) {\n <span class=\"min-w-0 flex-1 truncate text-left\">{{ item.label }}</span>\n @if (item.children?.length) {\n <africanies-icon\n name=\"chevron-down\"\n [size]=\"14\"\n class=\"shrink-0 opacity-70 transition-transform duration-200 ease-out\"\n [class.rotate-180]=\"isBranchOpen(item.id)\"\n />\n }\n }\n <ng-container\n [ngTemplateOutlet]=\"navBadge\"\n [ngTemplateOutletContext]=\"{\n visible: item.badge,\n compact: collapsed(),\n }\"\n />\n </ng-template>\n\n <ng-template #navBadge let-visible=\"visible\" let-compact=\"compact\">\n @if (visible) {\n <span\n class=\"pointer-events-none absolute z-10 overflow-visible\"\n [class]=\"compact ? 'right-0.5 top-0.5 h-2 w-2' : 'right-1.5 top-1 h-2 w-2'\"\n aria-hidden=\"true\"\n >\n <span\n class=\"africanies-side-nav-badge-ping absolute left-1/2 top-1/2 size-2 rounded-full bg-danger\"\n ></span>\n <span\n class=\"absolute left-1/2 top-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-danger ring-2 ring-white dark:ring-ink\"\n ></span>\n </span>\n }\n </ng-template>", styles: ["@keyframes africanies-side-nav-badge-pulse{0%{transform:translate(-50%,-50%) scale(.85);opacity:.9}70%{transform:translate(-50%,-50%) scale(2.4);opacity:0}to{transform:translate(-50%,-50%) scale(2.4);opacity:0}}.africanies-side-nav-badge-ping{animation:africanies-side-nav-badge-pulse 1.4s cubic-bezier(0,0,.2,1) infinite}@media(prefers-reduced-motion:reduce){.africanies-side-nav-badge-ping{animation:none;opacity:.5}}\n"] }]
|
|
14119
14476
|
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }, { type: i0.Output, args: ["collapsedChange"] }], activeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeId", required: false }] }, { type: i0.Output, args: ["activeIdChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], expandParents: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandParents", required: false }] }], expandBranchesByDefault: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandBranchesByDefault", required: false }] }], linkActiveOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "linkActiveOptions", required: false }] }], showLogo: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLogo", required: false }] }], logoSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoSrc", required: false }] }], logoMiniSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoMiniSrc", required: false }] }] } });
|
|
14120
14477
|
|
|
14121
14478
|
/**
|
|
@@ -14644,7 +15001,7 @@ class AppShellContentHeaderComponent {
|
|
|
14644
15001
|
<div class="flex min-w-0 items-center gap-2 sm:gap-3">
|
|
14645
15002
|
@if (showBackButton()) {
|
|
14646
15003
|
<a
|
|
14647
|
-
class="inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-lg text-neutral-600 transition-colors hover:bg-background-
|
|
15004
|
+
class="inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-lg 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"
|
|
14648
15005
|
[attr.aria-label]="backLabel()"
|
|
14649
15006
|
[routerLink]="backTarget()!.routerLink"
|
|
14650
15007
|
[queryParams]="backTarget()!.queryParams"
|
|
@@ -14690,7 +15047,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
14690
15047
|
<div class="flex min-w-0 items-center gap-2 sm:gap-3">
|
|
14691
15048
|
@if (showBackButton()) {
|
|
14692
15049
|
<a
|
|
14693
|
-
class="inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-lg text-neutral-600 transition-colors hover:bg-background-
|
|
15050
|
+
class="inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-lg 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"
|
|
14694
15051
|
[attr.aria-label]="backLabel()"
|
|
14695
15052
|
[routerLink]="backTarget()!.routerLink"
|
|
14696
15053
|
[queryParams]="backTarget()!.queryParams"
|
|
@@ -14855,28 +15212,32 @@ class AvatarMenuComponent {
|
|
|
14855
15212
|
showCaret = input(true, { ...(ngDevMode ? { debugName: "showCaret" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
14856
15213
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AvatarMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
14857
15214
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AvatarMenuComponent, isStandalone: true, selector: "africanies-avatar-menu", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showCaret: { classPropertyName: "showCaret", publicName: "showCaret", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
14858
|
-
|
|
14859
|
-
|
|
14860
|
-
|
|
14861
|
-
|
|
14862
|
-
|
|
14863
|
-
<button
|
|
14864
|
-
type="button"
|
|
14865
|
-
africaniesActionMenuTrigger
|
|
14866
|
-
class="inline-flex cursor-pointer items-center gap-1 rounded-lg p-0.5 pr-1 transition-colors hover:bg-background-welcome focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink disabled:cursor-not-allowed disabled:opacity-50 dark:hover:bg-white/10"
|
|
14867
|
-
[attr.aria-label]="ariaLabel()"
|
|
15215
|
+
@if (menuItems().length > 0) {
|
|
15216
|
+
<africanies-action-menu
|
|
15217
|
+
[items]="menuItems()"
|
|
15218
|
+
[ariaLabel]="ariaLabel()"
|
|
15219
|
+
[disabled]="disabled()"
|
|
14868
15220
|
>
|
|
14869
|
-
<
|
|
14870
|
-
|
|
14871
|
-
|
|
14872
|
-
|
|
14873
|
-
|
|
14874
|
-
|
|
14875
|
-
|
|
14876
|
-
|
|
14877
|
-
|
|
14878
|
-
|
|
14879
|
-
|
|
15221
|
+
<button
|
|
15222
|
+
type="button"
|
|
15223
|
+
africaniesActionMenuTrigger
|
|
15224
|
+
class="inline-flex cursor-pointer items-center gap-1 rounded-lg p-0.5 pr-1 transition-colors hover:bg-background-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus disabled:cursor-not-allowed disabled:opacity-50 dark:hover:bg-white/10"
|
|
15225
|
+
[attr.aria-label]="ariaLabel()"
|
|
15226
|
+
>
|
|
15227
|
+
<africanies-avatar [name]="name()" [src]="src()" [size]="size()" />
|
|
15228
|
+
@if (showCaret()) {
|
|
15229
|
+
<africanies-icon
|
|
15230
|
+
name="chevron-down"
|
|
15231
|
+
[size]="14"
|
|
15232
|
+
class="shrink-0 text-neutral-600 dark:text-neutral-400"
|
|
15233
|
+
aria-hidden="true"
|
|
15234
|
+
/>
|
|
15235
|
+
}
|
|
15236
|
+
</button>
|
|
15237
|
+
</africanies-action-menu>
|
|
15238
|
+
} @else {
|
|
15239
|
+
<africanies-avatar [name]="name()" [src]="src()" [size]="size()" />
|
|
15240
|
+
}
|
|
14880
15241
|
`, isInline: true, dependencies: [{ kind: "component", type: AvatarComponent, selector: "africanies-avatar", inputs: ["name", "src", "alt", "size"] }, { kind: "component", type: ActionMenuComponent, selector: "africanies-action-menu", inputs: ["items", "ariaLabel", "disabled"] }, { kind: "directive", type: ActionMenuTriggerDirective, selector: "[africaniesActionMenuTrigger]" }, { kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
14881
15242
|
}
|
|
14882
15243
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AvatarMenuComponent, decorators: [{
|
|
@@ -14892,28 +15253,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
14892
15253
|
AfricaniesIconComponent,
|
|
14893
15254
|
],
|
|
14894
15255
|
template: `
|
|
14895
|
-
|
|
14896
|
-
|
|
14897
|
-
|
|
14898
|
-
|
|
14899
|
-
|
|
14900
|
-
<button
|
|
14901
|
-
type="button"
|
|
14902
|
-
africaniesActionMenuTrigger
|
|
14903
|
-
class="inline-flex cursor-pointer items-center gap-1 rounded-lg p-0.5 pr-1 transition-colors hover:bg-background-welcome focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ink disabled:cursor-not-allowed disabled:opacity-50 dark:hover:bg-white/10"
|
|
14904
|
-
[attr.aria-label]="ariaLabel()"
|
|
15256
|
+
@if (menuItems().length > 0) {
|
|
15257
|
+
<africanies-action-menu
|
|
15258
|
+
[items]="menuItems()"
|
|
15259
|
+
[ariaLabel]="ariaLabel()"
|
|
15260
|
+
[disabled]="disabled()"
|
|
14905
15261
|
>
|
|
14906
|
-
<
|
|
14907
|
-
|
|
14908
|
-
|
|
14909
|
-
|
|
14910
|
-
|
|
14911
|
-
|
|
14912
|
-
|
|
14913
|
-
|
|
14914
|
-
|
|
14915
|
-
|
|
14916
|
-
|
|
15262
|
+
<button
|
|
15263
|
+
type="button"
|
|
15264
|
+
africaniesActionMenuTrigger
|
|
15265
|
+
class="inline-flex cursor-pointer items-center gap-1 rounded-lg p-0.5 pr-1 transition-colors hover:bg-background-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus disabled:cursor-not-allowed disabled:opacity-50 dark:hover:bg-white/10"
|
|
15266
|
+
[attr.aria-label]="ariaLabel()"
|
|
15267
|
+
>
|
|
15268
|
+
<africanies-avatar [name]="name()" [src]="src()" [size]="size()" />
|
|
15269
|
+
@if (showCaret()) {
|
|
15270
|
+
<africanies-icon
|
|
15271
|
+
name="chevron-down"
|
|
15272
|
+
[size]="14"
|
|
15273
|
+
class="shrink-0 text-neutral-600 dark:text-neutral-400"
|
|
15274
|
+
aria-hidden="true"
|
|
15275
|
+
/>
|
|
15276
|
+
}
|
|
15277
|
+
</button>
|
|
15278
|
+
</africanies-action-menu>
|
|
15279
|
+
} @else {
|
|
15280
|
+
<africanies-avatar [name]="name()" [src]="src()" [size]="size()" />
|
|
15281
|
+
}
|
|
14917
15282
|
`,
|
|
14918
15283
|
}]
|
|
14919
15284
|
}], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], menuItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuItems", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showCaret: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCaret", required: false }] }] } });
|
|
@@ -14941,9 +15306,9 @@ class NotificationDrawerPanel {
|
|
|
14941
15306
|
viewLinkClass = computed(() => {
|
|
14942
15307
|
const base = 'inline-flex cursor-pointer items-center gap-1 self-start text-caption font-semibold underline underline-offset-[3px] transition-colors';
|
|
14943
15308
|
if (this.shipping.mode() === 'stn') {
|
|
14944
|
-
return `${base} text-import decoration-import/35 hover:decoration-import dark:text-import-light dark:decoration-import-light/40 dark:hover:decoration-import-light`;
|
|
15309
|
+
return `${base} text-import-strong decoration-import-strong/35 hover:decoration-import-strong dark:text-import-light dark:decoration-import-light/40 dark:hover:decoration-import-light`;
|
|
14945
15310
|
}
|
|
14946
|
-
return `${base} text-export decoration-export/35 hover:decoration-export dark:text-export-light dark:decoration-export-light/40 dark:hover:decoration-export-light`;
|
|
15311
|
+
return `${base} text-export-strong decoration-export-strong/35 hover:decoration-export-strong dark:text-export-light dark:decoration-export-light/40 dark:hover:decoration-export-light`;
|
|
14947
15312
|
}, /* @ts-ignore */
|
|
14948
15313
|
...(ngDevMode ? [{ debugName: "viewLinkClass" }] : /* istanbul ignore next */ []));
|
|
14949
15314
|
title = computed(() => this.data.title ?? 'Notifications', /* @ts-ignore */
|
|
@@ -15289,7 +15654,7 @@ class NotificationDrawerPanel {
|
|
|
15289
15654
|
{{ title() }}
|
|
15290
15655
|
</h2>
|
|
15291
15656
|
@if (hasUnread()) {
|
|
15292
|
-
<p class="m-0 text-caption text-neutral-
|
|
15657
|
+
<p class="m-0 text-caption text-neutral-600 dark:text-neutral-400">
|
|
15293
15658
|
{{ unreadCount() }} unread
|
|
15294
15659
|
</p>
|
|
15295
15660
|
}
|
|
@@ -15335,7 +15700,7 @@ class NotificationDrawerPanel {
|
|
|
15335
15700
|
<africanies-icon
|
|
15336
15701
|
name="spinner"
|
|
15337
15702
|
[size]="24"
|
|
15338
|
-
class="animate-spin text-neutral-
|
|
15703
|
+
class="animate-spin text-neutral-600 dark:text-neutral-400"
|
|
15339
15704
|
/>
|
|
15340
15705
|
<p class="m-0 text-body-sm text-neutral-600 dark:text-neutral-400">
|
|
15341
15706
|
Loading notifications…
|
|
@@ -15402,7 +15767,7 @@ class NotificationDrawerPanel {
|
|
|
15402
15767
|
</h3>
|
|
15403
15768
|
@if (item.timestamp) {
|
|
15404
15769
|
<time
|
|
15405
|
-
class="shrink-0 whitespace-nowrap text-[11px] tabular-nums text-neutral-
|
|
15770
|
+
class="shrink-0 whitespace-nowrap text-[11px] tabular-nums text-neutral-600 dark:text-neutral-400"
|
|
15406
15771
|
[dateTime]="item.timestamp"
|
|
15407
15772
|
>
|
|
15408
15773
|
{{ formatTimestamp(item.timestamp) }}
|
|
@@ -15481,7 +15846,7 @@ class NotificationDrawerPanel {
|
|
|
15481
15846
|
>
|
|
15482
15847
|
@if (loadingMore()) {
|
|
15483
15848
|
<span
|
|
15484
|
-
class="inline-flex items-center gap-2 text-caption text-neutral-
|
|
15849
|
+
class="inline-flex items-center gap-2 text-caption text-neutral-600 dark:text-neutral-400"
|
|
15485
15850
|
aria-live="polite"
|
|
15486
15851
|
>
|
|
15487
15852
|
<africanies-icon name="spinner" [size]="14" class="animate-spin" />
|
|
@@ -15520,7 +15885,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
15520
15885
|
{{ title() }}
|
|
15521
15886
|
</h2>
|
|
15522
15887
|
@if (hasUnread()) {
|
|
15523
|
-
<p class="m-0 text-caption text-neutral-
|
|
15888
|
+
<p class="m-0 text-caption text-neutral-600 dark:text-neutral-400">
|
|
15524
15889
|
{{ unreadCount() }} unread
|
|
15525
15890
|
</p>
|
|
15526
15891
|
}
|
|
@@ -15566,7 +15931,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
15566
15931
|
<africanies-icon
|
|
15567
15932
|
name="spinner"
|
|
15568
15933
|
[size]="24"
|
|
15569
|
-
class="animate-spin text-neutral-
|
|
15934
|
+
class="animate-spin text-neutral-600 dark:text-neutral-400"
|
|
15570
15935
|
/>
|
|
15571
15936
|
<p class="m-0 text-body-sm text-neutral-600 dark:text-neutral-400">
|
|
15572
15937
|
Loading notifications…
|
|
@@ -15633,7 +15998,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
15633
15998
|
</h3>
|
|
15634
15999
|
@if (item.timestamp) {
|
|
15635
16000
|
<time
|
|
15636
|
-
class="shrink-0 whitespace-nowrap text-[11px] tabular-nums text-neutral-
|
|
16001
|
+
class="shrink-0 whitespace-nowrap text-[11px] tabular-nums text-neutral-600 dark:text-neutral-400"
|
|
15637
16002
|
[dateTime]="item.timestamp"
|
|
15638
16003
|
>
|
|
15639
16004
|
{{ formatTimestamp(item.timestamp) }}
|
|
@@ -15712,7 +16077,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
15712
16077
|
>
|
|
15713
16078
|
@if (loadingMore()) {
|
|
15714
16079
|
<span
|
|
15715
|
-
class="inline-flex items-center gap-2 text-caption text-neutral-
|
|
16080
|
+
class="inline-flex items-center gap-2 text-caption text-neutral-600 dark:text-neutral-400"
|
|
15716
16081
|
aria-live="polite"
|
|
15717
16082
|
>
|
|
15718
16083
|
<africanies-icon name="spinner" [size]="14" class="animate-spin" />
|
|
@@ -16016,10 +16381,10 @@ function hashString(value) {
|
|
|
16016
16381
|
}
|
|
16017
16382
|
|
|
16018
16383
|
/** Bump when cache shape or city resolution strategy changes. */
|
|
16019
|
-
const CACHE_KEY = 'africanies-header-weather-
|
|
16384
|
+
const CACHE_KEY = 'africanies-header-weather-v7';
|
|
16020
16385
|
const FETCH_MS = 4_000;
|
|
16021
16386
|
const BROWSER_GEO_MS = 3_500;
|
|
16022
|
-
/** IP fallback — city string is
|
|
16387
|
+
/** IP fallback — city string is used only when reverse-geocode is empty. */
|
|
16023
16388
|
const GEO_URL = 'https://get.geojs.io/v1/ip/geo.json';
|
|
16024
16389
|
/** Client reverse-geocode so the label matches the forecast coordinates. */
|
|
16025
16390
|
const REVERSE_GEO_URL = 'https://api.bigdatacloud.net/data/reverse-geocode-client';
|
|
@@ -16066,9 +16431,13 @@ function mapWmoWeatherCode(code) {
|
|
|
16066
16431
|
* Short condition label for the header weather chip.
|
|
16067
16432
|
*
|
|
16068
16433
|
* @param kind - Coarse forecast kind.
|
|
16069
|
-
* @
|
|
16434
|
+
* @param hour - Local hour; clear days show as Sunny, nights as Clear.
|
|
16435
|
+
* @returns Display label such as `Rain` or `Sunny`.
|
|
16070
16436
|
*/
|
|
16071
|
-
function headerWeatherLabel(kind) {
|
|
16437
|
+
function headerWeatherLabel(kind, hour = new Date().getHours()) {
|
|
16438
|
+
if (kind === 'clear') {
|
|
16439
|
+
return hour >= 19 || hour < 6 ? 'Clear' : 'Sunny';
|
|
16440
|
+
}
|
|
16072
16441
|
return WEATHER_LABELS[kind];
|
|
16073
16442
|
}
|
|
16074
16443
|
/**
|
|
@@ -16092,8 +16461,7 @@ function headerWeatherIcon(kind, hour) {
|
|
|
16092
16461
|
*
|
|
16093
16462
|
* Coordinates prefer the browser Geolocation API (accurate for travellers;
|
|
16094
16463
|
* may prompt once). Otherwise IP geo is used. The city label is reverse-
|
|
16095
|
-
* geocoded from those coordinates
|
|
16096
|
-
* Nigeria (many networks resolve as Lagos).
|
|
16464
|
+
* geocoded from those coordinates, with the IP city as a fallback.
|
|
16097
16465
|
*
|
|
16098
16466
|
* Fails closed: missing browser APIs, timeouts, and HTTP errors all return
|
|
16099
16467
|
* `null` so the greeting can stay time-of-day only. Cached per local hour
|
|
@@ -16156,10 +16524,16 @@ function readCache(hour) {
|
|
|
16156
16524
|
if (parsed.hour !== hour || !parsed.kind) {
|
|
16157
16525
|
return null;
|
|
16158
16526
|
}
|
|
16527
|
+
// City-less entries (e.g. browser geo + failed reverse) used to stick for
|
|
16528
|
+
// the hour — treat them as a miss so we can recover the location label.
|
|
16529
|
+
const city = asCity(parsed.city);
|
|
16530
|
+
if (!city) {
|
|
16531
|
+
return null;
|
|
16532
|
+
}
|
|
16159
16533
|
return {
|
|
16160
16534
|
kind: parsed.kind,
|
|
16161
16535
|
temperatureC: parsed.temperatureC,
|
|
16162
|
-
city
|
|
16536
|
+
city,
|
|
16163
16537
|
};
|
|
16164
16538
|
}
|
|
16165
16539
|
catch {
|
|
@@ -16176,26 +16550,32 @@ function writeCache(value) {
|
|
|
16176
16550
|
}
|
|
16177
16551
|
/**
|
|
16178
16552
|
* Prefer device coordinates when available (may prompt once); otherwise fall
|
|
16179
|
-
* back to IP geo. IP
|
|
16180
|
-
*
|
|
16553
|
+
* back to IP geo. IP is always fetched in parallel so its city can backfill
|
|
16554
|
+
* the label when reverse-geocode is empty (browser geo has no city string).
|
|
16181
16555
|
*/
|
|
16182
16556
|
async function resolveCoordinates(fetchFn) {
|
|
16183
|
-
const browser = await
|
|
16557
|
+
const [browser, ipGeo] = await Promise.all([
|
|
16558
|
+
tryBrowserGeolocation(),
|
|
16559
|
+
fetchIpGeo(fetchFn),
|
|
16560
|
+
]);
|
|
16561
|
+
const ipCity = asCity(ipGeo?.city);
|
|
16184
16562
|
if (browser) {
|
|
16185
|
-
return browser;
|
|
16563
|
+
return { ...browser, fallbackCity: ipCity };
|
|
16186
16564
|
}
|
|
16187
|
-
const
|
|
16188
|
-
const
|
|
16189
|
-
const longitude = asNumber(geo?.longitude);
|
|
16565
|
+
const latitude = asNumber(ipGeo?.latitude);
|
|
16566
|
+
const longitude = asNumber(ipGeo?.longitude);
|
|
16190
16567
|
if (latitude === null || longitude === null) {
|
|
16191
16568
|
return null;
|
|
16192
16569
|
}
|
|
16193
16570
|
return {
|
|
16194
16571
|
latitude,
|
|
16195
16572
|
longitude,
|
|
16196
|
-
fallbackCity:
|
|
16573
|
+
fallbackCity: ipCity,
|
|
16197
16574
|
};
|
|
16198
16575
|
}
|
|
16576
|
+
async function fetchIpGeo(fetchFn) {
|
|
16577
|
+
return (await fetchJson(fetchFn, GEO_URL));
|
|
16578
|
+
}
|
|
16199
16579
|
async function tryBrowserGeolocation() {
|
|
16200
16580
|
if (typeof navigator === 'undefined' ||
|
|
16201
16581
|
typeof navigator.geolocation?.getCurrentPosition !== 'function') {
|
|
@@ -16380,26 +16760,33 @@ class AppShellHeaderComponent {
|
|
|
16380
16760
|
if (temp === undefined || !Number.isFinite(temp)) {
|
|
16381
16761
|
return null;
|
|
16382
16762
|
}
|
|
16383
|
-
return
|
|
16763
|
+
return String(Math.round(temp));
|
|
16384
16764
|
}, /* @ts-ignore */
|
|
16385
16765
|
...(ngDevMode ? [{ debugName: "weatherTemp" }] : /* istanbul ignore next */ []));
|
|
16386
|
-
|
|
16766
|
+
weatherCondition = computed(() => {
|
|
16387
16767
|
const forecast = this.weather();
|
|
16388
16768
|
if (!forecast) {
|
|
16389
16769
|
return '';
|
|
16390
16770
|
}
|
|
16391
|
-
return
|
|
16771
|
+
return headerWeatherLabel(forecast.kind, this.now().getHours());
|
|
16392
16772
|
}, /* @ts-ignore */
|
|
16393
|
-
...(ngDevMode ? [{ debugName: "
|
|
16773
|
+
...(ngDevMode ? [{ debugName: "weatherCondition" }] : /* istanbul ignore next */ []));
|
|
16774
|
+
weatherCity = computed(() => {
|
|
16775
|
+
const city = this.weather()?.city?.trim();
|
|
16776
|
+
return city || null;
|
|
16777
|
+
}, /* @ts-ignore */
|
|
16778
|
+
...(ngDevMode ? [{ debugName: "weatherCity" }] : /* istanbul ignore next */ []));
|
|
16394
16779
|
weatherAriaLabel = computed(() => {
|
|
16395
16780
|
const forecast = this.weather();
|
|
16396
16781
|
if (!forecast) {
|
|
16397
16782
|
return 'Weather';
|
|
16398
16783
|
}
|
|
16399
|
-
const condition =
|
|
16784
|
+
const condition = this.weatherCondition().toLowerCase();
|
|
16400
16785
|
const temp = this.weatherTemp();
|
|
16401
|
-
const city =
|
|
16402
|
-
const degrees = temp === null
|
|
16786
|
+
const city = this.weatherCity();
|
|
16787
|
+
const degrees = temp === null
|
|
16788
|
+
? condition
|
|
16789
|
+
: `${temp} degrees Celsius, ${condition}`;
|
|
16403
16790
|
return city ? `Weather in ${city}: ${degrees}` : `Weather: ${degrees}`;
|
|
16404
16791
|
}, /* @ts-ignore */
|
|
16405
16792
|
...(ngDevMode ? [{ debugName: "weatherAriaLabel" }] : /* istanbul ignore next */ []));
|
|
@@ -16469,7 +16856,7 @@ class AppShellHeaderComponent {
|
|
|
16469
16856
|
@if (greeting(); as hello) {
|
|
16470
16857
|
<div class="min-w-0 overflow-hidden">
|
|
16471
16858
|
<p
|
|
16472
|
-
class="m-0 truncate text-caption leading-none text-neutral-
|
|
16859
|
+
class="m-0 truncate text-caption leading-none text-neutral-600 dark:text-neutral-400"
|
|
16473
16860
|
>
|
|
16474
16861
|
{{ hello.kicker }}
|
|
16475
16862
|
</p>
|
|
@@ -16495,19 +16882,21 @@ class AppShellHeaderComponent {
|
|
|
16495
16882
|
<africanies-icon
|
|
16496
16883
|
[name]="weatherIcon()"
|
|
16497
16884
|
[size]="18"
|
|
16498
|
-
class="text-neutral-
|
|
16885
|
+
class="text-neutral-600 dark:text-neutral-400"
|
|
16499
16886
|
/>
|
|
16500
16887
|
@if (weatherTemp(); as temp) {
|
|
16501
16888
|
<span
|
|
16502
16889
|
class="text-body-sm font-medium tabular-nums tracking-tight text-ink dark:text-white"
|
|
16503
16890
|
>
|
|
16504
|
-
{{ temp }}°
|
|
16891
|
+
{{ temp }}°C
|
|
16505
16892
|
</span>
|
|
16506
16893
|
}
|
|
16507
16894
|
<span
|
|
16508
|
-
class="hidden text-caption text-neutral-
|
|
16895
|
+
class="hidden text-caption text-neutral-600 md:inline dark:text-neutral-400"
|
|
16509
16896
|
>
|
|
16510
|
-
{{
|
|
16897
|
+
{{ weatherCondition() }}@if (weatherCity(); as city) {
|
|
16898
|
+
· {{ city }}
|
|
16899
|
+
}
|
|
16511
16900
|
</span>
|
|
16512
16901
|
</div>
|
|
16513
16902
|
}
|
|
@@ -16515,7 +16904,7 @@ class AppShellHeaderComponent {
|
|
|
16515
16904
|
@if (showClock()) {
|
|
16516
16905
|
<div class="flex items-baseline gap-2" aria-live="polite">
|
|
16517
16906
|
<time
|
|
16518
|
-
class="hidden text-caption text-neutral-
|
|
16907
|
+
class="hidden text-caption text-neutral-600 md:inline dark:text-neutral-400"
|
|
16519
16908
|
[dateTime]="nowIso()"
|
|
16520
16909
|
>
|
|
16521
16910
|
{{ now() | date: clockDateFormat() }}
|
|
@@ -16545,7 +16934,7 @@ class AppShellHeaderComponent {
|
|
|
16545
16934
|
@if (showNotifications()) {
|
|
16546
16935
|
<button
|
|
16547
16936
|
type="button"
|
|
16548
|
-
class="relative inline-flex size-9 cursor-pointer items-center justify-center rounded-lg text-neutral-600 transition-colors hover:bg-background-
|
|
16937
|
+
class="relative inline-flex size-9 cursor-pointer items-center justify-center rounded-lg 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"
|
|
16549
16938
|
[attr.aria-label]="notificationAriaLabel()"
|
|
16550
16939
|
(click)="openNotifications()"
|
|
16551
16940
|
>
|
|
@@ -16566,18 +16955,26 @@ class AppShellHeaderComponent {
|
|
|
16566
16955
|
}
|
|
16567
16956
|
|
|
16568
16957
|
@if (userName()) {
|
|
16569
|
-
|
|
16570
|
-
|
|
16571
|
-
|
|
16572
|
-
|
|
16573
|
-
|
|
16574
|
-
|
|
16958
|
+
@if (userMenuItems().length > 0) {
|
|
16959
|
+
<africanies-avatar-menu
|
|
16960
|
+
[name]="userName()!"
|
|
16961
|
+
[src]="userAvatarSrc()"
|
|
16962
|
+
[menuItems]="userMenuItems()"
|
|
16963
|
+
[size]="'md'"
|
|
16964
|
+
/>
|
|
16965
|
+
} @else {
|
|
16966
|
+
<africanies-avatar
|
|
16967
|
+
[name]="userName()!"
|
|
16968
|
+
[src]="userAvatarSrc()"
|
|
16969
|
+
size="md"
|
|
16970
|
+
/>
|
|
16971
|
+
}
|
|
16575
16972
|
}
|
|
16576
16973
|
</div>
|
|
16577
16974
|
}
|
|
16578
16975
|
</div>
|
|
16579
16976
|
</div>
|
|
16580
|
-
`, isInline: true, dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }, { kind: "component", type: AvatarMenuComponent, selector: "africanies-avatar-menu", inputs: ["name", "src", "menuItems", "size", "ariaLabel", "disabled", "showCaret"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
16977
|
+
`, isInline: true, dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }, { kind: "component", type: AvatarComponent, selector: "africanies-avatar", inputs: ["name", "src", "alt", "size"] }, { kind: "component", type: AvatarMenuComponent, selector: "africanies-avatar-menu", inputs: ["name", "src", "menuItems", "size", "ariaLabel", "disabled", "showCaret"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
16581
16978
|
}
|
|
16582
16979
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AppShellHeaderComponent, decorators: [{
|
|
16583
16980
|
type: Component,
|
|
@@ -16585,7 +16982,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
16585
16982
|
selector: 'africanies-app-shell-header',
|
|
16586
16983
|
standalone: true,
|
|
16587
16984
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
16588
|
-
imports: [
|
|
16985
|
+
imports: [
|
|
16986
|
+
AfricaniesIconComponent,
|
|
16987
|
+
AvatarComponent,
|
|
16988
|
+
AvatarMenuComponent,
|
|
16989
|
+
DatePipe,
|
|
16990
|
+
],
|
|
16589
16991
|
template: `
|
|
16590
16992
|
<div
|
|
16591
16993
|
class="flex min-w-0 items-center gap-2 px-3 py-2.5 sm:gap-4 sm:px-6 sm:py-3"
|
|
@@ -16596,7 +16998,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
16596
16998
|
@if (greeting(); as hello) {
|
|
16597
16999
|
<div class="min-w-0 overflow-hidden">
|
|
16598
17000
|
<p
|
|
16599
|
-
class="m-0 truncate text-caption leading-none text-neutral-
|
|
17001
|
+
class="m-0 truncate text-caption leading-none text-neutral-600 dark:text-neutral-400"
|
|
16600
17002
|
>
|
|
16601
17003
|
{{ hello.kicker }}
|
|
16602
17004
|
</p>
|
|
@@ -16622,19 +17024,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
16622
17024
|
<africanies-icon
|
|
16623
17025
|
[name]="weatherIcon()"
|
|
16624
17026
|
[size]="18"
|
|
16625
|
-
class="text-neutral-
|
|
17027
|
+
class="text-neutral-600 dark:text-neutral-400"
|
|
16626
17028
|
/>
|
|
16627
17029
|
@if (weatherTemp(); as temp) {
|
|
16628
17030
|
<span
|
|
16629
17031
|
class="text-body-sm font-medium tabular-nums tracking-tight text-ink dark:text-white"
|
|
16630
17032
|
>
|
|
16631
|
-
{{ temp }}°
|
|
17033
|
+
{{ temp }}°C
|
|
16632
17034
|
</span>
|
|
16633
17035
|
}
|
|
16634
17036
|
<span
|
|
16635
|
-
class="hidden text-caption text-neutral-
|
|
17037
|
+
class="hidden text-caption text-neutral-600 md:inline dark:text-neutral-400"
|
|
16636
17038
|
>
|
|
16637
|
-
{{
|
|
17039
|
+
{{ weatherCondition() }}@if (weatherCity(); as city) {
|
|
17040
|
+
· {{ city }}
|
|
17041
|
+
}
|
|
16638
17042
|
</span>
|
|
16639
17043
|
</div>
|
|
16640
17044
|
}
|
|
@@ -16642,7 +17046,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
16642
17046
|
@if (showClock()) {
|
|
16643
17047
|
<div class="flex items-baseline gap-2" aria-live="polite">
|
|
16644
17048
|
<time
|
|
16645
|
-
class="hidden text-caption text-neutral-
|
|
17049
|
+
class="hidden text-caption text-neutral-600 md:inline dark:text-neutral-400"
|
|
16646
17050
|
[dateTime]="nowIso()"
|
|
16647
17051
|
>
|
|
16648
17052
|
{{ now() | date: clockDateFormat() }}
|
|
@@ -16672,7 +17076,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
16672
17076
|
@if (showNotifications()) {
|
|
16673
17077
|
<button
|
|
16674
17078
|
type="button"
|
|
16675
|
-
class="relative inline-flex size-9 cursor-pointer items-center justify-center rounded-lg text-neutral-600 transition-colors hover:bg-background-
|
|
17079
|
+
class="relative inline-flex size-9 cursor-pointer items-center justify-center rounded-lg 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"
|
|
16676
17080
|
[attr.aria-label]="notificationAriaLabel()"
|
|
16677
17081
|
(click)="openNotifications()"
|
|
16678
17082
|
>
|
|
@@ -16693,12 +17097,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
16693
17097
|
}
|
|
16694
17098
|
|
|
16695
17099
|
@if (userName()) {
|
|
16696
|
-
|
|
16697
|
-
|
|
16698
|
-
|
|
16699
|
-
|
|
16700
|
-
|
|
16701
|
-
|
|
17100
|
+
@if (userMenuItems().length > 0) {
|
|
17101
|
+
<africanies-avatar-menu
|
|
17102
|
+
[name]="userName()!"
|
|
17103
|
+
[src]="userAvatarSrc()"
|
|
17104
|
+
[menuItems]="userMenuItems()"
|
|
17105
|
+
[size]="'md'"
|
|
17106
|
+
/>
|
|
17107
|
+
} @else {
|
|
17108
|
+
<africanies-avatar
|
|
17109
|
+
[name]="userName()!"
|
|
17110
|
+
[src]="userAvatarSrc()"
|
|
17111
|
+
size="md"
|
|
17112
|
+
/>
|
|
17113
|
+
}
|
|
16702
17114
|
}
|
|
16703
17115
|
</div>
|
|
16704
17116
|
}
|
|
@@ -16874,14 +17286,14 @@ class AppShellComponent {
|
|
|
16874
17286
|
// Preview embeds: absolute/h-full so the drawer stays inside the frame.
|
|
16875
17287
|
// Production: h-dvh so the rail fills the viewport (h-full only matches parent).
|
|
16876
17288
|
if (preview === 'desktop') {
|
|
16877
|
-
return 'z-50 shrink-0 self-start sticky top-0 block h-full';
|
|
17289
|
+
return 'z-50 shrink-0 self-start sticky top-0 block h-full min-h-0';
|
|
16878
17290
|
}
|
|
16879
17291
|
if (preview === 'mobile' || preview === 'tablet') {
|
|
16880
17292
|
return open
|
|
16881
|
-
? 'z-50 shrink-0 self-start absolute inset-y-0 left-0 h-full shadow-xl'
|
|
17293
|
+
? 'z-50 shrink-0 self-start absolute inset-y-0 left-0 h-full min-h-0 shadow-xl'
|
|
16882
17294
|
: 'hidden';
|
|
16883
17295
|
}
|
|
16884
|
-
const base = 'z-50 shrink-0 self-start h-dvh';
|
|
17296
|
+
const base = 'z-50 shrink-0 self-start h-dvh min-h-0';
|
|
16885
17297
|
if (open) {
|
|
16886
17298
|
return `${base} fixed inset-y-0 left-0 shadow-xl lg:sticky lg:top-0 lg:block`;
|
|
16887
17299
|
}
|
|
@@ -16917,13 +17329,13 @@ class AppShellComponent {
|
|
|
16917
17329
|
this.mobileNavOpen.set(false);
|
|
16918
17330
|
}
|
|
16919
17331
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AppShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
16920
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AppShellComponent, isStandalone: true, selector: "africanies-app-shell", inputs: { contentWidth: { classPropertyName: "contentWidth", publicName: "contentWidth", isSignal: true, isRequired: false, transformFunction: null }, showAccent: { classPropertyName: "showAccent", publicName: "showAccent", isSignal: true, isRequired: false, transformFunction: null }, showHeaderChrome: { classPropertyName: "showHeaderChrome", publicName: "showHeaderChrome", isSignal: true, isRequired: false, transformFunction: null }, layoutPreview: { classPropertyName: "layoutPreview", publicName: "layoutPreview", isSignal: true, isRequired: false, transformFunction: null }, headerTitle: { classPropertyName: "headerTitle", publicName: "headerTitle", isSignal: true, isRequired: false, transformFunction: null }, headerSubtitle: { classPropertyName: "headerSubtitle", publicName: "headerSubtitle", isSignal: true, isRequired: false, transformFunction: null }, breadcrumbs: { classPropertyName: "breadcrumbs", publicName: "breadcrumbs", isSignal: true, isRequired: false, transformFunction: null }, catalogNav: { classPropertyName: "catalogNav", publicName: "catalogNav", isSignal: true, isRequired: false, transformFunction: null }, showContentBack: { classPropertyName: "showContentBack", publicName: "showContentBack", isSignal: true, isRequired: false, transformFunction: null }, contentBackLink: { classPropertyName: "contentBackLink", publicName: "contentBackLink", isSignal: true, isRequired: false, transformFunction: null }, contentBackLabel: { classPropertyName: "contentBackLabel", publicName: "contentBackLabel", isSignal: true, isRequired: false, transformFunction: null }, userName: { classPropertyName: "userName", publicName: "userName", isSignal: true, isRequired: false, transformFunction: null }, greetingName: { classPropertyName: "greetingName", publicName: "greetingName", isSignal: true, isRequired: false, transformFunction: null }, userAvatarSrc: { classPropertyName: "userAvatarSrc", publicName: "userAvatarSrc", isSignal: true, isRequired: false, transformFunction: null }, userMenuItems: { classPropertyName: "userMenuItems", publicName: "userMenuItems", isSignal: true, isRequired: false, transformFunction: null }, notifications: { classPropertyName: "notifications", publicName: "notifications", isSignal: true, isRequired: false, transformFunction: null }, notificationsTitle: { classPropertyName: "notificationsTitle", publicName: "notificationsTitle", isSignal: true, isRequired: false, transformFunction: null }, showClock: { classPropertyName: "showClock", publicName: "showClock", isSignal: true, isRequired: false, transformFunction: null }, showNotifications: { classPropertyName: "showNotifications", publicName: "showNotifications", isSignal: true, isRequired: false, transformFunction: null }, clockDateFormat: { classPropertyName: "clockDateFormat", publicName: "clockDateFormat", isSignal: true, isRequired: false, transformFunction: null }, clockFormat: { classPropertyName: "clockFormat", publicName: "clockFormat", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClass()" } }, queries: [{ propertyName: "customHeader", first: true, predicate: AppShellHeaderSlotDirective, descendants: true, isSignal: true }], ngImport: i0, template: " <div [class]=\"shellRootClass()\">\n @if (mobileNavOpen()) {\n <button\n type=\"button\"\n class=\"absolute inset-0 z-40 cursor-pointer bg-ink/40\"\n [class.lg:hidden]=\"!layoutPreview()\"\n aria-label=\"Close navigation\"\n (click)=\"closeMobileNav()\"\n ></button>\n }\n\n <div [class]=\"sidenavHostClass()\">\n <ng-content select=\"[sidenav]\" />\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col\">\n @if (showMobileBar()) {\n <div\n class=\"flex shrink-0 items-center gap-2 border-b border-border px-3 py-2 dark:border-white/10\"\n [class.lg:hidden]=\"!layoutPreview()\"\n >\n <button\n type=\"button\"\n class=\"inline-flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-lg border border-
|
|
17332
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AppShellComponent, isStandalone: true, selector: "africanies-app-shell", inputs: { contentWidth: { classPropertyName: "contentWidth", publicName: "contentWidth", isSignal: true, isRequired: false, transformFunction: null }, showAccent: { classPropertyName: "showAccent", publicName: "showAccent", isSignal: true, isRequired: false, transformFunction: null }, showHeaderChrome: { classPropertyName: "showHeaderChrome", publicName: "showHeaderChrome", isSignal: true, isRequired: false, transformFunction: null }, layoutPreview: { classPropertyName: "layoutPreview", publicName: "layoutPreview", isSignal: true, isRequired: false, transformFunction: null }, headerTitle: { classPropertyName: "headerTitle", publicName: "headerTitle", isSignal: true, isRequired: false, transformFunction: null }, headerSubtitle: { classPropertyName: "headerSubtitle", publicName: "headerSubtitle", isSignal: true, isRequired: false, transformFunction: null }, breadcrumbs: { classPropertyName: "breadcrumbs", publicName: "breadcrumbs", isSignal: true, isRequired: false, transformFunction: null }, catalogNav: { classPropertyName: "catalogNav", publicName: "catalogNav", isSignal: true, isRequired: false, transformFunction: null }, showContentBack: { classPropertyName: "showContentBack", publicName: "showContentBack", isSignal: true, isRequired: false, transformFunction: null }, contentBackLink: { classPropertyName: "contentBackLink", publicName: "contentBackLink", isSignal: true, isRequired: false, transformFunction: null }, contentBackLabel: { classPropertyName: "contentBackLabel", publicName: "contentBackLabel", isSignal: true, isRequired: false, transformFunction: null }, userName: { classPropertyName: "userName", publicName: "userName", isSignal: true, isRequired: false, transformFunction: null }, greetingName: { classPropertyName: "greetingName", publicName: "greetingName", isSignal: true, isRequired: false, transformFunction: null }, userAvatarSrc: { classPropertyName: "userAvatarSrc", publicName: "userAvatarSrc", isSignal: true, isRequired: false, transformFunction: null }, userMenuItems: { classPropertyName: "userMenuItems", publicName: "userMenuItems", isSignal: true, isRequired: false, transformFunction: null }, notifications: { classPropertyName: "notifications", publicName: "notifications", isSignal: true, isRequired: false, transformFunction: null }, notificationsTitle: { classPropertyName: "notificationsTitle", publicName: "notificationsTitle", isSignal: true, isRequired: false, transformFunction: null }, showClock: { classPropertyName: "showClock", publicName: "showClock", isSignal: true, isRequired: false, transformFunction: null }, showNotifications: { classPropertyName: "showNotifications", publicName: "showNotifications", isSignal: true, isRequired: false, transformFunction: null }, clockDateFormat: { classPropertyName: "clockDateFormat", publicName: "clockDateFormat", isSignal: true, isRequired: false, transformFunction: null }, clockFormat: { classPropertyName: "clockFormat", publicName: "clockFormat", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClass()" } }, queries: [{ propertyName: "customHeader", first: true, predicate: AppShellHeaderSlotDirective, descendants: true, isSignal: true }], ngImport: i0, template: " <div [class]=\"shellRootClass()\">\n @if (mobileNavOpen()) {\n <button\n type=\"button\"\n class=\"absolute inset-0 z-40 cursor-pointer bg-ink/40\"\n [class.lg:hidden]=\"!layoutPreview()\"\n aria-label=\"Close navigation\"\n (click)=\"closeMobileNav()\"\n ></button>\n }\n\n <div [class]=\"sidenavHostClass()\">\n <ng-content select=\"[sidenav]\" />\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col\">\n @if (showMobileBar()) {\n <div\n class=\"flex shrink-0 items-center gap-2 border-b border-border px-3 py-2 dark:border-white/10\"\n [class.lg:hidden]=\"!layoutPreview()\"\n >\n <button\n type=\"button\"\n class=\"inline-flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-lg border border-control text-ink transition-colors hover:bg-background-hover dark:border-white/15 dark:text-white dark:hover:bg-white/10\"\n [attr.aria-label]=\"mobileNavOpen() ? 'Close navigation' : 'Open navigation'\"\n [attr.aria-expanded]=\"mobileNavOpen()\"\n (click)=\"toggleMobileNav()\"\n >\n <africanies-icon name=\"align-justify\" [size]=\"18\" />\n </button>\n <img\n [src]=\"logoMiniUrl\"\n alt=\"African Import Export Solutions\"\n class=\"h-7 w-auto object-contain\"\n />\n </div>\n }\n\n <div\n class=\"sticky top-0 z-30 border-b border-border bg-surface/90 backdrop-blur-md dark:border-white/10 dark:bg-ink-950/90\"\n >\n @if (hasCustomHeader()) {\n <ng-content select=\"[africaniesAppShellHeader]\" />\n } @else if (showHeaderChrome()) {\n <africanies-app-shell-header\n [userName]=\"userName()\"\n [greetingName]=\"greetingName()\"\n [userAvatarSrc]=\"userAvatarSrc()\"\n [userMenuItems]=\"userMenuItems()\"\n [notifications]=\"notifications()\"\n [notificationsTitle]=\"notificationsTitle()\"\n [showClock]=\"showClock()\"\n [showNotifications]=\"showNotifications()\"\n [clockDateFormat]=\"clockDateFormat()\"\n [clockFormat]=\"clockFormat()\"\n [density]=\"headerDensity()\"\n />\n }\n @if (showAccent()) {\n <div\n class=\"h-0.5 w-full transition-colors duration-300\"\n [class]=\"modeColor.classes().bg\"\n aria-hidden=\"true\"\n ></div>\n }\n </div>\n\n <main [class]=\"mainClass()\">\n @if (showContentChrome()) {\n <africanies-app-shell-content-header\n [breadcrumbs]=\"breadcrumbs()\"\n [title]=\"headerTitle()\"\n [subtitle]=\"headerSubtitle()\"\n [url]=\"currentUrl()\"\n [catalogNav]=\"catalogNav()\"\n [showBack]=\"showContentBack()\"\n [backLink]=\"contentBackLink()\"\n [backLabel]=\"contentBackLabel()\"\n />\n }\n <ng-content />\n </main>\n </div>\n </div>", dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }, { kind: "component", type: AppShellContentHeaderComponent, selector: "africanies-app-shell-content-header", inputs: ["breadcrumbs", "title", "subtitle", "url", "catalogNav", "showBack", "backLink", "backLabel"] }, { kind: "component", type: AppShellHeaderComponent, selector: "africanies-app-shell-header", inputs: ["userName", "greetingName", "userAvatarSrc", "userMenuItems", "notifications", "notificationsTitle", "onNotificationMarkRead", "onNotificationMarkAllRead", "onNotificationLoadPage", "showClock", "showNotifications", "density", "clockDateFormat", "clockFormat"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
16921
17333
|
}
|
|
16922
17334
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AppShellComponent, decorators: [{
|
|
16923
17335
|
type: Component,
|
|
16924
17336
|
args: [{ selector: 'africanies-app-shell', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AfricaniesIconComponent, AppShellContentHeaderComponent, AppShellHeaderComponent], host: {
|
|
16925
17337
|
'[class]': 'hostClass()',
|
|
16926
|
-
}, template: " <div [class]=\"shellRootClass()\">\n @if (mobileNavOpen()) {\n <button\n type=\"button\"\n class=\"absolute inset-0 z-40 cursor-pointer bg-ink/40\"\n [class.lg:hidden]=\"!layoutPreview()\"\n aria-label=\"Close navigation\"\n (click)=\"closeMobileNav()\"\n ></button>\n }\n\n <div [class]=\"sidenavHostClass()\">\n <ng-content select=\"[sidenav]\" />\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col\">\n @if (showMobileBar()) {\n <div\n class=\"flex shrink-0 items-center gap-2 border-b border-border px-3 py-2 dark:border-white/10\"\n [class.lg:hidden]=\"!layoutPreview()\"\n >\n <button\n type=\"button\"\n class=\"inline-flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-lg border border-
|
|
17338
|
+
}, template: " <div [class]=\"shellRootClass()\">\n @if (mobileNavOpen()) {\n <button\n type=\"button\"\n class=\"absolute inset-0 z-40 cursor-pointer bg-ink/40\"\n [class.lg:hidden]=\"!layoutPreview()\"\n aria-label=\"Close navigation\"\n (click)=\"closeMobileNav()\"\n ></button>\n }\n\n <div [class]=\"sidenavHostClass()\">\n <ng-content select=\"[sidenav]\" />\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col\">\n @if (showMobileBar()) {\n <div\n class=\"flex shrink-0 items-center gap-2 border-b border-border px-3 py-2 dark:border-white/10\"\n [class.lg:hidden]=\"!layoutPreview()\"\n >\n <button\n type=\"button\"\n class=\"inline-flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-lg border border-control text-ink transition-colors hover:bg-background-hover dark:border-white/15 dark:text-white dark:hover:bg-white/10\"\n [attr.aria-label]=\"mobileNavOpen() ? 'Close navigation' : 'Open navigation'\"\n [attr.aria-expanded]=\"mobileNavOpen()\"\n (click)=\"toggleMobileNav()\"\n >\n <africanies-icon name=\"align-justify\" [size]=\"18\" />\n </button>\n <img\n [src]=\"logoMiniUrl\"\n alt=\"African Import Export Solutions\"\n class=\"h-7 w-auto object-contain\"\n />\n </div>\n }\n\n <div\n class=\"sticky top-0 z-30 border-b border-border bg-surface/90 backdrop-blur-md dark:border-white/10 dark:bg-ink-950/90\"\n >\n @if (hasCustomHeader()) {\n <ng-content select=\"[africaniesAppShellHeader]\" />\n } @else if (showHeaderChrome()) {\n <africanies-app-shell-header\n [userName]=\"userName()\"\n [greetingName]=\"greetingName()\"\n [userAvatarSrc]=\"userAvatarSrc()\"\n [userMenuItems]=\"userMenuItems()\"\n [notifications]=\"notifications()\"\n [notificationsTitle]=\"notificationsTitle()\"\n [showClock]=\"showClock()\"\n [showNotifications]=\"showNotifications()\"\n [clockDateFormat]=\"clockDateFormat()\"\n [clockFormat]=\"clockFormat()\"\n [density]=\"headerDensity()\"\n />\n }\n @if (showAccent()) {\n <div\n class=\"h-0.5 w-full transition-colors duration-300\"\n [class]=\"modeColor.classes().bg\"\n aria-hidden=\"true\"\n ></div>\n }\n </div>\n\n <main [class]=\"mainClass()\">\n @if (showContentChrome()) {\n <africanies-app-shell-content-header\n [breadcrumbs]=\"breadcrumbs()\"\n [title]=\"headerTitle()\"\n [subtitle]=\"headerSubtitle()\"\n [url]=\"currentUrl()\"\n [catalogNav]=\"catalogNav()\"\n [showBack]=\"showContentBack()\"\n [backLink]=\"contentBackLink()\"\n [backLabel]=\"contentBackLabel()\"\n />\n }\n <ng-content />\n </main>\n </div>\n </div>" }]
|
|
16927
17339
|
}], propDecorators: { customHeader: [{ type: i0.ContentChild, args: [i0.forwardRef(() => AppShellHeaderSlotDirective), { isSignal: true }] }], contentWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentWidth", required: false }] }], showAccent: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAccent", required: false }] }], showHeaderChrome: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeaderChrome", required: false }] }], layoutPreview: [{ type: i0.Input, args: [{ isSignal: true, alias: "layoutPreview", required: false }] }], headerTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerTitle", required: false }] }], headerSubtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerSubtitle", required: false }] }], breadcrumbs: [{ type: i0.Input, args: [{ isSignal: true, alias: "breadcrumbs", required: false }] }], catalogNav: [{ type: i0.Input, args: [{ isSignal: true, alias: "catalogNav", required: false }] }], showContentBack: [{ type: i0.Input, args: [{ isSignal: true, alias: "showContentBack", required: false }] }], contentBackLink: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentBackLink", required: false }] }], contentBackLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentBackLabel", required: false }] }], userName: [{ type: i0.Input, args: [{ isSignal: true, alias: "userName", required: false }] }], greetingName: [{ type: i0.Input, args: [{ isSignal: true, alias: "greetingName", required: false }] }], userAvatarSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "userAvatarSrc", required: false }] }], userMenuItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "userMenuItems", required: false }] }], notifications: [{ type: i0.Input, args: [{ isSignal: true, alias: "notifications", required: false }] }], notificationsTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "notificationsTitle", required: false }] }], showClock: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClock", required: false }] }], showNotifications: [{ type: i0.Input, args: [{ isSignal: true, alias: "showNotifications", required: false }] }], clockDateFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "clockDateFormat", required: false }] }], clockFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "clockFormat", required: false }] }] } });
|
|
16928
17340
|
|
|
16929
17341
|
/**
|
|
@@ -17051,7 +17463,7 @@ class ImageComponent {
|
|
|
17051
17463
|
|
|
17052
17464
|
@if (showPlaceholder()) {
|
|
17053
17465
|
<div
|
|
17054
|
-
class="absolute inset-0 flex items-center justify-center bg-neutral-200 text-neutral-
|
|
17466
|
+
class="absolute inset-0 flex items-center justify-center bg-neutral-200 text-neutral-600 dark:bg-white/10 dark:text-neutral-400"
|
|
17055
17467
|
[class.animate-pulse]="pending()"
|
|
17056
17468
|
aria-hidden="true"
|
|
17057
17469
|
>
|
|
@@ -17107,7 +17519,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
17107
17519
|
|
|
17108
17520
|
@if (showPlaceholder()) {
|
|
17109
17521
|
<div
|
|
17110
|
-
class="absolute inset-0 flex items-center justify-center bg-neutral-200 text-neutral-
|
|
17522
|
+
class="absolute inset-0 flex items-center justify-center bg-neutral-200 text-neutral-600 dark:bg-white/10 dark:text-neutral-400"
|
|
17111
17523
|
[class.animate-pulse]="pending()"
|
|
17112
17524
|
aria-hidden="true"
|
|
17113
17525
|
>
|
|
@@ -17461,7 +17873,7 @@ class PaginationComponent {
|
|
|
17461
17873
|
@for (item of pageItems(); track trackPageItem(item, $index)) {
|
|
17462
17874
|
@if (item === 'ellipsis') {
|
|
17463
17875
|
<span
|
|
17464
|
-
class="inline-flex min-w-8 items-center justify-center text-body-sm text-neutral-
|
|
17876
|
+
class="inline-flex min-w-8 items-center justify-center text-body-sm text-neutral-600 dark:text-neutral-400"
|
|
17465
17877
|
aria-hidden="true"
|
|
17466
17878
|
>
|
|
17467
17879
|
…
|
|
@@ -17562,7 +17974,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
17562
17974
|
@for (item of pageItems(); track trackPageItem(item, $index)) {
|
|
17563
17975
|
@if (item === 'ellipsis') {
|
|
17564
17976
|
<span
|
|
17565
|
-
class="inline-flex min-w-8 items-center justify-center text-body-sm text-neutral-
|
|
17977
|
+
class="inline-flex min-w-8 items-center justify-center text-body-sm text-neutral-600 dark:text-neutral-400"
|
|
17566
17978
|
aria-hidden="true"
|
|
17567
17979
|
>
|
|
17568
17980
|
…
|
|
@@ -17608,15 +18020,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
17608
18020
|
* `<ng-template africaniesCellDef="key">` templates. Columns without a matching
|
|
17609
18021
|
* template fall back to rendering `row[key]` as plain text.
|
|
17610
18022
|
*
|
|
17611
|
-
* Optional toolbar: top-left **
|
|
17612
|
-
*
|
|
18023
|
+
* Optional toolbar: top-left **shipping mode** segment on its own row above
|
|
18024
|
+
* Refresh / Filter / Export (on by default; `[showShippingMode]="false"` to
|
|
18025
|
+
* hide) and **Refresh** (`showRefresh` →
|
|
18026
|
+
* {@link refreshClick}). Refresh is hidden while
|
|
18027
|
+
* the body shows empty or error — those states expose Retry instead.
|
|
17613
18028
|
* While {@link refreshing} is true the rows stay on screen — the refresh icon
|
|
17614
18029
|
* spins (do not swap to a blocking loader). Use {@link loading} when the page
|
|
17615
|
-
* of data is changing (pagination / size): rows stay on screen
|
|
17616
|
-
*
|
|
17617
|
-
*
|
|
17618
|
-
* rows
|
|
17619
|
-
* mounted.
|
|
18030
|
+
* of data is changing (pagination / size): rows stay on screen, a keep-rows
|
|
18031
|
+
* overlay covers the grid, and the built-in pager shows a circular spinner
|
|
18032
|
+
* beside the page controls; the body loader appears only when there are no
|
|
18033
|
+
* rows yet (first load) or the host cleared rows for a shipping-mode switch
|
|
18034
|
+
* (STN ↔ SFN). Toolbar and column headers stay mounted.
|
|
17620
18035
|
* top-right **Filters** then **Export** (`showFilter` / `showExport`). The table
|
|
17621
18036
|
* does not own fetch, filter, or export logic — the host handles those events.
|
|
17622
18037
|
*
|
|
@@ -17638,8 +18053,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
17638
18053
|
* and never reorder local rows.
|
|
17639
18054
|
*
|
|
17640
18055
|
* **Expandable rows:** project `<ng-template africaniesRowDetail="Label" let-row>`
|
|
17641
|
-
* templates. A leading chevron column appears; the expanded panel
|
|
17642
|
-
*
|
|
18056
|
+
* templates. A leading chevron column appears; the expanded panel sticks to the
|
|
18057
|
+
* scrollport width (so it does not scroll horizontally with the columns) and
|
|
18058
|
+
* lays out label/value pairs in a wrapping auto-fill grid.
|
|
17643
18059
|
*
|
|
17644
18060
|
* @typeParam T - Row record shape.
|
|
17645
18061
|
*
|
|
@@ -17675,9 +18091,54 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
17675
18091
|
* to the left when rows are expandable. Override with
|
|
17676
18092
|
* {@link TableColumn.sticky}. Sticky columns use a slightly thicker bottom
|
|
17677
18093
|
* border (and opaque fill) so dividers stay visible while scrolling.
|
|
18094
|
+
*
|
|
18095
|
+
* **Sticky header (desktop):** when {@link stickyHeader} is true (default),
|
|
18096
|
+
* large screens scroll the grid inside a capped viewport and keep `th` pinned
|
|
18097
|
+
* to the top of that scrollport. Mobile keeps horizontal-only overflow so
|
|
18098
|
+
* page scroll is unchanged.
|
|
17678
18099
|
*/
|
|
17679
18100
|
class TableComponent {
|
|
17680
|
-
|
|
18101
|
+
destroyRef = inject(DestroyRef);
|
|
18102
|
+
shipping = inject(ShippingModeService);
|
|
18103
|
+
/** Local STN / SFN segment options for {@link showShippingMode}. */
|
|
18104
|
+
shippingModeItems = [
|
|
18105
|
+
{ id: 'stn', label: 'Shipping to Nigeria' },
|
|
18106
|
+
{ id: 'sfn', label: 'Shipping from Nigeria' },
|
|
18107
|
+
];
|
|
18108
|
+
/**
|
|
18109
|
+
* Segment selection mirror of {@link ShippingModeService.mode}. Kept local
|
|
18110
|
+
* so a denied {@link ShippingModeService.requestModeChange} can snap the
|
|
18111
|
+
* pills back when the service mode did not change.
|
|
18112
|
+
*/
|
|
18113
|
+
shippingModeActiveId = signal('sfn', /* @ts-ignore */
|
|
18114
|
+
...(ngDevMode ? [{ debugName: "shippingModeActiveId" }] : /* istanbul ignore next */ []));
|
|
18115
|
+
/** Scrollport that owns horizontal overflow for the main grid. */
|
|
18116
|
+
scrollport = viewChild('scrollport', /* @ts-ignore */
|
|
18117
|
+
...(ngDevMode ? [{ debugName: "scrollport" }] : /* istanbul ignore next */ []));
|
|
18118
|
+
/**
|
|
18119
|
+
* Visible width of {@link scrollport}. Applied to the expand panel so
|
|
18120
|
+
* details stay within the viewport and do not scroll with the columns.
|
|
18121
|
+
*/
|
|
18122
|
+
scrollportWidthPx = signal(0, /* @ts-ignore */
|
|
18123
|
+
...(ngDevMode ? [{ debugName: "scrollportWidthPx" }] : /* istanbul ignore next */ []));
|
|
18124
|
+
constructor() {
|
|
18125
|
+
effect(() => {
|
|
18126
|
+
this.shippingModeActiveId.set(this.shipping.mode());
|
|
18127
|
+
});
|
|
18128
|
+
afterNextRender(() => {
|
|
18129
|
+
const el = this.scrollport()?.nativeElement;
|
|
18130
|
+
if (!el) {
|
|
18131
|
+
return;
|
|
18132
|
+
}
|
|
18133
|
+
const sync = () => {
|
|
18134
|
+
this.scrollportWidthPx.set(el.clientWidth);
|
|
18135
|
+
};
|
|
18136
|
+
sync();
|
|
18137
|
+
const observer = new ResizeObserver(sync);
|
|
18138
|
+
observer.observe(el);
|
|
18139
|
+
this.destroyRef.onDestroy(() => observer.disconnect());
|
|
18140
|
+
});
|
|
18141
|
+
}
|
|
17681
18142
|
/**
|
|
17682
18143
|
* When false, hides row expansion even if {@link RowDetailDefDirective}
|
|
17683
18144
|
* templates are projected. Defaults to true.
|
|
@@ -17693,6 +18154,12 @@ class TableComponent {
|
|
|
17693
18154
|
/** Column definitions (header chrome + keys). */
|
|
17694
18155
|
columns = input.required(/* @ts-ignore */
|
|
17695
18156
|
...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
18157
|
+
/**
|
|
18158
|
+
* When true (default), pin column headers while scrolling the grid on
|
|
18159
|
+
* large screens (`lg+`). Uses a capped scrollport so sticky works with
|
|
18160
|
+
* horizontal overflow. Set false to keep the previous unconstrained layout.
|
|
18161
|
+
*/
|
|
18162
|
+
stickyHeader = input(true, { ...(ngDevMode ? { debugName: "stickyHeader" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
17696
18163
|
/**
|
|
17697
18164
|
* Row records to render. Empty arrays show {@link EmptyStateComponent} in
|
|
17698
18165
|
* the body unless {@link loading} or {@link error} is set. Missing `data`
|
|
@@ -17706,6 +18173,13 @@ class TableComponent {
|
|
|
17706
18173
|
*/
|
|
17707
18174
|
sort = input(null, /* @ts-ignore */
|
|
17708
18175
|
...(ngDevMode ? [{ debugName: "sort" }] : /* istanbul ignore next */ []));
|
|
18176
|
+
/**
|
|
18177
|
+
* Show the Shipping to / from Nigeria segment above the table (top-left).
|
|
18178
|
+
* On by default; set `[showShippingMode]="false"` to hide (e.g. modals).
|
|
18179
|
+
* Writes through {@link ShippingModeService.requestModeChange} so feature
|
|
18180
|
+
* guards still run.
|
|
18181
|
+
*/
|
|
18182
|
+
showShippingMode = input(true, { ...(ngDevMode ? { debugName: "showShippingMode" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
17709
18183
|
/**
|
|
17710
18184
|
* Show a Refresh button above the table (top-left) once rows are on screen.
|
|
17711
18185
|
* Hidden during in-grid empty/error — those use Retry in the body. Host refetches
|
|
@@ -17723,9 +18197,9 @@ class TableComponent {
|
|
|
17723
18197
|
refreshing = input(false, { ...(ngDevMode ? { debugName: "refreshing" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
17724
18198
|
/**
|
|
17725
18199
|
* Page of data is loading (first load, shipping-mode switch, pagination,
|
|
17726
|
-
* page size). When rows are already on screen,
|
|
17727
|
-
* and
|
|
17728
|
-
* dropped STN/SFN rows after a mode switch), the body shows
|
|
18200
|
+
* page size). When rows are already on screen, a keep-rows overlay covers
|
|
18201
|
+
* the grid and the pager shows a spinner; when there are no rows (first
|
|
18202
|
+
* load or the host dropped STN/SFN rows after a mode switch), the body shows
|
|
17729
18203
|
* {@link LoadingStateComponent}. Distinct from {@link refreshing}.
|
|
17730
18204
|
*/
|
|
17731
18205
|
loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
@@ -17837,6 +18311,26 @@ class TableComponent {
|
|
|
17837
18311
|
/** Top-left Refresh — only when rows are on screen (empty/error use in-body Retry). */
|
|
17838
18312
|
showToolbarRefresh = computed(() => this.showRefresh() && this.bodyKind() === 'rows', /* @ts-ignore */
|
|
17839
18313
|
...(ngDevMode ? [{ debugName: "showToolbarRefresh" }] : /* istanbul ignore next */ []));
|
|
18314
|
+
/**
|
|
18315
|
+
* Applies a shipping-mode segment selection through
|
|
18316
|
+
* {@link ShippingModeService.requestModeChange}.
|
|
18317
|
+
*
|
|
18318
|
+
* @param id - Segment id (`stn` / `sfn`) or null.
|
|
18319
|
+
*/
|
|
18320
|
+
onShippingModeChange(id) {
|
|
18321
|
+
if (id !== 'stn' && id !== 'sfn') {
|
|
18322
|
+
return;
|
|
18323
|
+
}
|
|
18324
|
+
this.shippingModeActiveId.set(id);
|
|
18325
|
+
if (id === this.shipping.mode()) {
|
|
18326
|
+
return;
|
|
18327
|
+
}
|
|
18328
|
+
this.shipping.requestModeChange(id).subscribe((ok) => {
|
|
18329
|
+
if (!ok) {
|
|
18330
|
+
this.shippingModeActiveId.set(this.shipping.mode());
|
|
18331
|
+
}
|
|
18332
|
+
});
|
|
18333
|
+
}
|
|
17840
18334
|
visibleRowIds = computed(() => this.rowList().map((row, index) => this.rowId(row, index)), /* @ts-ignore */
|
|
17841
18335
|
...(ngDevMode ? [{ debugName: "visibleRowIds" }] : /* istanbul ignore next */ []));
|
|
17842
18336
|
someRowsExpanded = computed(() => {
|
|
@@ -17896,11 +18390,12 @@ class TableComponent {
|
|
|
17896
18390
|
return 'border-b border-border dark:border-white/10';
|
|
17897
18391
|
}
|
|
17898
18392
|
/**
|
|
17899
|
-
* Opaque
|
|
17900
|
-
*
|
|
18393
|
+
* Opaque header fill (sticky-safe). Neutral chrome — not mode-accented.
|
|
18394
|
+
* Light `#f0f2f5` / dark elevated ink surface.
|
|
18395
|
+
* @returns Background utility classes.
|
|
17901
18396
|
*/
|
|
17902
18397
|
headerSoftClass() {
|
|
17903
|
-
return
|
|
18398
|
+
return 'bg-[#f0f2f5] dark:bg-[#2a2c31]';
|
|
17904
18399
|
}
|
|
17905
18400
|
/**
|
|
17906
18401
|
* Body row classes — row marker for hover styles, plus hide cell borders on
|
|
@@ -17971,10 +18466,21 @@ class TableComponent {
|
|
|
17971
18466
|
? 'border-b-[1.5px] '
|
|
17972
18467
|
: 'border-b ';
|
|
17973
18468
|
return (border +
|
|
17974
|
-
'border-border whitespace-normal wrap-break-word px-[1.125rem] py-4 font-medium text-neutral-
|
|
18469
|
+
'border-border whitespace-normal wrap-break-word px-[1.125rem] py-4 font-medium text-neutral-500 dark:border-white/10 dark:text-neutral-400 ' +
|
|
17975
18470
|
this.headerSoftClass() +
|
|
17976
18471
|
' ' +
|
|
17977
|
-
this.stickySurfaceClass(col, 'head')
|
|
18472
|
+
this.stickySurfaceClass(col, 'head') +
|
|
18473
|
+
(sticky ? '' : this.headerStickClass()));
|
|
18474
|
+
}
|
|
18475
|
+
/**
|
|
18476
|
+
* Vertical pin for scrolling header cells on desktop. Pinned left/right
|
|
18477
|
+
* headers get `lg:top-0` from {@link stickyPinClass} instead.
|
|
18478
|
+
*/
|
|
18479
|
+
headerStickClass() {
|
|
18480
|
+
if (!this.stickyHeader()) {
|
|
18481
|
+
return '';
|
|
18482
|
+
}
|
|
18483
|
+
return ' lg:sticky lg:top-0 lg:z-[3] print:static';
|
|
17978
18484
|
}
|
|
17979
18485
|
/**
|
|
17980
18486
|
* Body cell classes, including sticky pin when set.
|
|
@@ -18013,9 +18519,13 @@ class TableComponent {
|
|
|
18013
18519
|
const side = edge === 'right' ? 'sticky right-0 z-[1]' : 'sticky left-0 z-[1]';
|
|
18014
18520
|
if (surface === 'head') {
|
|
18015
18521
|
// Fill comes from {@link headerSoftClass} on the cell — do not re-tint.
|
|
18016
|
-
|
|
18522
|
+
// Corner pins also stick vertically on desktop when stickyHeader is on.
|
|
18523
|
+
const vertical = this.stickyHeader()
|
|
18524
|
+
? ' z-[2] lg:top-0 lg:z-[4] print:static'
|
|
18525
|
+
: ' z-[2]';
|
|
18526
|
+
return `${side}${vertical}`;
|
|
18017
18527
|
}
|
|
18018
|
-
const fill = 'bg-
|
|
18528
|
+
const fill = 'bg-surface dark:bg-ink-surface';
|
|
18019
18529
|
return `${side} ${fill}`;
|
|
18020
18530
|
}
|
|
18021
18531
|
/**
|
|
@@ -18121,89 +18631,112 @@ class TableComponent {
|
|
|
18121
18631
|
this.sortChange.emit({ key, direction });
|
|
18122
18632
|
}
|
|
18123
18633
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18124
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: TableComponent, isStandalone: true, selector: "africanies-table", inputs: { expandable: { classPropertyName: "expandable", publicName: "expandable", isSignal: true, isRequired: false, transformFunction: null }, rowTrackBy: { classPropertyName: "rowTrackBy", publicName: "rowTrackBy", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, showRefresh: { classPropertyName: "showRefresh", publicName: "showRefresh", isSignal: true, isRequired: false, transformFunction: null }, refreshLabel: { classPropertyName: "refreshLabel", publicName: "refreshLabel", isSignal: true, isRequired: false, transformFunction: null }, refreshing: { classPropertyName: "refreshing", publicName: "refreshing", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingLabel: { classPropertyName: "loadingLabel", publicName: "loadingLabel", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, showFilter: { classPropertyName: "showFilter", publicName: "showFilter", isSignal: true, isRequired: false, transformFunction: null }, filterLabel: { classPropertyName: "filterLabel", publicName: "filterLabel", isSignal: true, isRequired: false, transformFunction: null }, filterCount: { classPropertyName: "filterCount", publicName: "filterCount", isSignal: true, isRequired: false, transformFunction: null }, showExport: { classPropertyName: "showExport", publicName: "showExport", isSignal: true, isRequired: false, transformFunction: null }, exportLabel: { classPropertyName: "exportLabel", publicName: "exportLabel", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowExpandChange: "rowExpandChange", sortChange: "sortChange", refreshClick: "refreshClick", filterClick: "filterClick", exportClick: "exportClick", pageChange: "pageChange", sizeChange: "sizeChange" }, host: { classAttribute: "block w-full min-w-0" }, queries: [{ propertyName: "cellDefs", predicate: CellDefDirective, isSignal: true }, { propertyName: "headerCellDefs", predicate: HeaderCellDefDirective, isSignal: true }, { propertyName: "rowDetailDefs", predicate: RowDetailDefDirective, isSignal: true }], ngImport: i0, template: `
|
|
18634
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: TableComponent, isStandalone: true, selector: "africanies-table", inputs: { expandable: { classPropertyName: "expandable", publicName: "expandable", isSignal: true, isRequired: false, transformFunction: null }, rowTrackBy: { classPropertyName: "rowTrackBy", publicName: "rowTrackBy", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, stickyHeader: { classPropertyName: "stickyHeader", publicName: "stickyHeader", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, showShippingMode: { classPropertyName: "showShippingMode", publicName: "showShippingMode", isSignal: true, isRequired: false, transformFunction: null }, showRefresh: { classPropertyName: "showRefresh", publicName: "showRefresh", isSignal: true, isRequired: false, transformFunction: null }, refreshLabel: { classPropertyName: "refreshLabel", publicName: "refreshLabel", isSignal: true, isRequired: false, transformFunction: null }, refreshing: { classPropertyName: "refreshing", publicName: "refreshing", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingLabel: { classPropertyName: "loadingLabel", publicName: "loadingLabel", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, showFilter: { classPropertyName: "showFilter", publicName: "showFilter", isSignal: true, isRequired: false, transformFunction: null }, filterLabel: { classPropertyName: "filterLabel", publicName: "filterLabel", isSignal: true, isRequired: false, transformFunction: null }, filterCount: { classPropertyName: "filterCount", publicName: "filterCount", isSignal: true, isRequired: false, transformFunction: null }, showExport: { classPropertyName: "showExport", publicName: "showExport", isSignal: true, isRequired: false, transformFunction: null }, exportLabel: { classPropertyName: "exportLabel", publicName: "exportLabel", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowExpandChange: "rowExpandChange", sortChange: "sortChange", refreshClick: "refreshClick", filterClick: "filterClick", exportClick: "exportClick", pageChange: "pageChange", sizeChange: "sizeChange" }, host: { classAttribute: "block w-full min-w-0" }, queries: [{ propertyName: "cellDefs", predicate: CellDefDirective, isSignal: true }, { propertyName: "headerCellDefs", predicate: HeaderCellDefDirective, isSignal: true }, { propertyName: "rowDetailDefs", predicate: RowDetailDefDirective, isSignal: true }], viewQueries: [{ propertyName: "scrollport", first: true, predicate: ["scrollport"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
18125
18635
|
<div
|
|
18126
18636
|
class="flex w-full min-w-0 flex-col gap-3"
|
|
18127
18637
|
[attr.aria-busy]="loading() || refreshing() || null"
|
|
18128
18638
|
>
|
|
18129
|
-
@if (
|
|
18130
|
-
|
|
18131
|
-
|
|
18132
|
-
|
|
18133
|
-
|
|
18134
|
-
|
|
18135
|
-
|
|
18136
|
-
|
|
18137
|
-
|
|
18138
|
-
|
|
18139
|
-
|
|
18140
|
-
|
|
18141
|
-
|
|
18142
|
-
|
|
18143
|
-
|
|
18144
|
-
|
|
18145
|
-
|
|
18146
|
-
|
|
18147
|
-
|
|
18148
|
-
|
|
18149
|
-
|
|
18150
|
-
|
|
18151
|
-
|
|
18152
|
-
|
|
18153
|
-
|
|
18154
|
-
|
|
18155
|
-
|
|
18156
|
-
|
|
18157
|
-
size="sm"
|
|
18158
|
-
[attr.aria-label]="filterLabel()"
|
|
18159
|
-
(click)="filterClick.emit()"
|
|
18160
|
-
>
|
|
18161
|
-
<africanies-icon name="filter" [size]="16" />
|
|
18162
|
-
{{ filterLabel() }}
|
|
18163
|
-
@if (filterCount() > 0) {
|
|
18164
|
-
<span
|
|
18165
|
-
class="inline-flex min-w-5 items-center justify-center rounded-full bg-ink px-1.5 py-0.5 text-caption font-semibold tabular-nums text-white dark:bg-white dark:text-ink"
|
|
18639
|
+
@if (
|
|
18640
|
+
showShippingMode() ||
|
|
18641
|
+
showRefresh() ||
|
|
18642
|
+
showFilter() ||
|
|
18643
|
+
showExport()
|
|
18644
|
+
) {
|
|
18645
|
+
<div class="flex w-full min-w-0 flex-col gap-3">
|
|
18646
|
+
@if (showShippingMode()) {
|
|
18647
|
+
<africanies-segment
|
|
18648
|
+
class="min-w-0 self-start"
|
|
18649
|
+
[items]="shippingModeItems"
|
|
18650
|
+
[activeId]="shippingModeActiveId()"
|
|
18651
|
+
ariaLabel="Shipping mode"
|
|
18652
|
+
(activeIdChange)="onShippingModeChange($event)"
|
|
18653
|
+
/>
|
|
18654
|
+
}
|
|
18655
|
+
@if (showToolbarRefresh() || showFilter() || showExport()) {
|
|
18656
|
+
<div class="flex flex-wrap items-center justify-between gap-2">
|
|
18657
|
+
<div class="flex min-w-0 flex-wrap items-center gap-2">
|
|
18658
|
+
@if (showToolbarRefresh()) {
|
|
18659
|
+
<button
|
|
18660
|
+
africanies-button
|
|
18661
|
+
type="button"
|
|
18662
|
+
variant="flat"
|
|
18663
|
+
size="sm"
|
|
18664
|
+
[disabled]="loading() || refreshing()"
|
|
18665
|
+
[attr.aria-label]="refreshLabel()"
|
|
18666
|
+
(click)="refreshClick.emit()"
|
|
18166
18667
|
>
|
|
18167
|
-
|
|
18168
|
-
|
|
18668
|
+
<africanies-icon
|
|
18669
|
+
name="refresh"
|
|
18670
|
+
[size]="16"
|
|
18671
|
+
[class]="refreshing() ? 'animate-spin' : ''"
|
|
18672
|
+
/>
|
|
18673
|
+
{{ refreshLabel() }}
|
|
18674
|
+
</button>
|
|
18169
18675
|
}
|
|
18170
|
-
</
|
|
18171
|
-
|
|
18172
|
-
|
|
18173
|
-
|
|
18174
|
-
|
|
18175
|
-
|
|
18176
|
-
|
|
18177
|
-
|
|
18178
|
-
|
|
18179
|
-
|
|
18180
|
-
|
|
18181
|
-
|
|
18182
|
-
|
|
18183
|
-
|
|
18184
|
-
|
|
18185
|
-
|
|
18676
|
+
</div>
|
|
18677
|
+
<div class="flex items-center gap-2">
|
|
18678
|
+
@if (showFilter()) {
|
|
18679
|
+
<button
|
|
18680
|
+
africanies-button
|
|
18681
|
+
type="button"
|
|
18682
|
+
variant="flat"
|
|
18683
|
+
size="sm"
|
|
18684
|
+
[attr.aria-label]="filterLabel()"
|
|
18685
|
+
(click)="filterClick.emit()"
|
|
18686
|
+
>
|
|
18687
|
+
<africanies-icon name="filter" [size]="16" />
|
|
18688
|
+
{{ filterLabel() }}
|
|
18689
|
+
@if (filterCount() > 0) {
|
|
18690
|
+
<span
|
|
18691
|
+
class="inline-flex min-w-5 items-center justify-center rounded-full bg-ink px-1.5 py-0.5 text-caption font-semibold tabular-nums text-white dark:bg-white dark:text-ink"
|
|
18692
|
+
>
|
|
18693
|
+
{{ filterCount() }}
|
|
18694
|
+
</span>
|
|
18695
|
+
}
|
|
18696
|
+
</button>
|
|
18697
|
+
}
|
|
18698
|
+
@if (showExport()) {
|
|
18699
|
+
<button
|
|
18700
|
+
africanies-button
|
|
18701
|
+
type="button"
|
|
18702
|
+
variant="flat"
|
|
18703
|
+
size="sm"
|
|
18704
|
+
[attr.aria-label]="exportLabel()"
|
|
18705
|
+
(click)="exportClick.emit()"
|
|
18706
|
+
>
|
|
18707
|
+
<africanies-icon name="download" [size]="16" />
|
|
18708
|
+
{{ exportLabel() }}
|
|
18709
|
+
</button>
|
|
18710
|
+
}
|
|
18711
|
+
</div>
|
|
18712
|
+
</div>
|
|
18713
|
+
}
|
|
18186
18714
|
</div>
|
|
18187
18715
|
}
|
|
18188
18716
|
|
|
18189
18717
|
@if (staleError(); as staleMessage) {
|
|
18190
|
-
<
|
|
18191
|
-
|
|
18192
|
-
|
|
18193
|
-
|
|
18194
|
-
|
|
18195
|
-
|
|
18196
|
-
|
|
18197
|
-
/>
|
|
18198
|
-
</div>
|
|
18718
|
+
<africanies-error-indicator
|
|
18719
|
+
class="w-full"
|
|
18720
|
+
[error]="staleMessage"
|
|
18721
|
+
retryText="Refresh"
|
|
18722
|
+
[refreshing]="refreshing()"
|
|
18723
|
+
(retry)="refreshClick.emit()"
|
|
18724
|
+
/>
|
|
18199
18725
|
}
|
|
18200
18726
|
|
|
18201
18727
|
<div
|
|
18202
|
-
class="min-w-0 w-full overflow-
|
|
18728
|
+
class="relative min-w-0 w-full overflow-hidden rounded-panel border border-border bg-surface dark:border-white/10 dark:bg-ink-surface"
|
|
18203
18729
|
>
|
|
18204
|
-
<
|
|
18205
|
-
|
|
18730
|
+
<div
|
|
18731
|
+
#scrollport
|
|
18732
|
+
class="africanies-table-scrollport min-w-0 w-full overflow-x-auto"
|
|
18733
|
+
[class.lg:max-h-[min(70dvh,calc(100dvh-12rem))]]="stickyHeader()"
|
|
18734
|
+
[class.lg:overflow-auto]="stickyHeader() && !paginationLoading()"
|
|
18735
|
+
[class.pointer-events-none]="paginationLoading()"
|
|
18206
18736
|
>
|
|
18737
|
+
<table
|
|
18738
|
+
class="w-max min-w-full table-auto border-separate border-spacing-0 bg-inherit text-left text-body text-ink dark:text-white"
|
|
18739
|
+
>
|
|
18207
18740
|
<thead [class]="headerRowClass()">
|
|
18208
18741
|
<tr>
|
|
18209
18742
|
@if (isExpandable()) {
|
|
@@ -18214,7 +18747,7 @@ class TableComponent {
|
|
|
18214
18747
|
@if (someRowsExpanded()) {
|
|
18215
18748
|
<button
|
|
18216
18749
|
type="button"
|
|
18217
|
-
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-
|
|
18750
|
+
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-500 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"
|
|
18218
18751
|
aria-label="Collapse all"
|
|
18219
18752
|
(click)="collapseAllRows()"
|
|
18220
18753
|
>
|
|
@@ -18223,7 +18756,7 @@ class TableComponent {
|
|
|
18223
18756
|
} @else {
|
|
18224
18757
|
<button
|
|
18225
18758
|
type="button"
|
|
18226
|
-
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-
|
|
18759
|
+
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-500 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"
|
|
18227
18760
|
aria-label="Expand all"
|
|
18228
18761
|
[disabled]="rowList().length === 0"
|
|
18229
18762
|
(click)="expandAllRows()"
|
|
@@ -18237,7 +18770,8 @@ class TableComponent {
|
|
|
18237
18770
|
<th
|
|
18238
18771
|
scope="col"
|
|
18239
18772
|
[class]="headerCellClass(col)"
|
|
18240
|
-
[style.width]="col.width ?? null"
|
|
18773
|
+
[style.width]="col.width ?? col.maxWidth ?? null"
|
|
18774
|
+
[style.max-width]="col.maxWidth ?? null"
|
|
18241
18775
|
>
|
|
18242
18776
|
@if (headerTemplateFor(col.key); as headerTpl) {
|
|
18243
18777
|
<ng-container
|
|
@@ -18246,7 +18780,7 @@ class TableComponent {
|
|
|
18246
18780
|
} @else if (col.sortable) {
|
|
18247
18781
|
<button
|
|
18248
18782
|
type="button"
|
|
18249
|
-
class="inline-flex cursor-pointer items-center gap-1 rounded-sm font-medium text-neutral-
|
|
18783
|
+
class="inline-flex cursor-pointer items-center gap-1 rounded-sm font-medium text-neutral-500 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"
|
|
18250
18784
|
(click)="onSortHeaderClick(col.key)"
|
|
18251
18785
|
>
|
|
18252
18786
|
<span>{{ col.header }}</span>
|
|
@@ -18302,7 +18836,7 @@ class TableComponent {
|
|
|
18302
18836
|
<td [class]="expandBodyClass(i)">
|
|
18303
18837
|
<button
|
|
18304
18838
|
type="button"
|
|
18305
|
-
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-600 transition-colors hover:bg-background-
|
|
18839
|
+
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"
|
|
18306
18840
|
[attr.aria-label]="
|
|
18307
18841
|
isRowExpanded(row, i)
|
|
18308
18842
|
? 'Collapse row details'
|
|
@@ -18321,7 +18855,8 @@ class TableComponent {
|
|
|
18321
18855
|
@for (col of columns(); track col.key) {
|
|
18322
18856
|
<td
|
|
18323
18857
|
[class]="bodyCellClass(col, i)"
|
|
18324
|
-
[style.width]="col.width ?? null"
|
|
18858
|
+
[style.width]="col.width ?? col.maxWidth ?? null"
|
|
18859
|
+
[style.max-width]="col.maxWidth ?? null"
|
|
18325
18860
|
>
|
|
18326
18861
|
@if (templateFor(col.key); as tpl) {
|
|
18327
18862
|
<ng-container
|
|
@@ -18341,41 +18876,52 @@ class TableComponent {
|
|
|
18341
18876
|
[class.border-border]="isRowExpanded(row, i)"
|
|
18342
18877
|
[class.dark:border-white/10]="isRowExpanded(row, i)"
|
|
18343
18878
|
>
|
|
18344
|
-
<td class="p-0 align-top" [attr.colspan]="
|
|
18879
|
+
<td class="p-0 align-top" [attr.colspan]="colSpan()">
|
|
18880
|
+
<!-- Sticky must sit outside overflow-hidden or it pins
|
|
18881
|
+
to the full table width and scrolls with the row. -->
|
|
18345
18882
|
<div
|
|
18346
|
-
class="
|
|
18347
|
-
[style.
|
|
18348
|
-
|
|
18349
|
-
"
|
|
18350
|
-
[attr.aria-hidden]="!isRowExpanded(row, i)"
|
|
18351
|
-
[class.pointer-events-none]="!isRowExpanded(row, i)"
|
|
18883
|
+
class="africanies-table-expand-panel bg-surface-sunken dark:bg-white/[0.05]"
|
|
18884
|
+
[style.width.px]="scrollportWidthPx() || null"
|
|
18885
|
+
[style.maxWidth.px]="scrollportWidthPx() || null"
|
|
18352
18886
|
>
|
|
18353
18887
|
<div
|
|
18354
|
-
class="
|
|
18888
|
+
class="grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none"
|
|
18889
|
+
[style.grid-template-rows]="
|
|
18890
|
+
isRowExpanded(row, i) ? '1fr' : '0fr'
|
|
18891
|
+
"
|
|
18892
|
+
[attr.aria-hidden]="!isRowExpanded(row, i)"
|
|
18893
|
+
[class.pointer-events-none]="!isRowExpanded(row, i)"
|
|
18355
18894
|
>
|
|
18356
|
-
<
|
|
18357
|
-
class="
|
|
18358
|
-
[class.opacity-0]="!isRowExpanded(row, i)"
|
|
18359
|
-
[class.opacity-100]="isRowExpanded(row, i)"
|
|
18895
|
+
<div
|
|
18896
|
+
class="min-h-0 overflow-x-hidden overflow-y-hidden border-t border-border-strong dark:border-white/10"
|
|
18360
18897
|
>
|
|
18361
|
-
|
|
18362
|
-
|
|
18363
|
-
|
|
18364
|
-
|
|
18365
|
-
|
|
18366
|
-
|
|
18367
|
-
|
|
18368
|
-
|
|
18369
|
-
|
|
18370
|
-
>
|
|
18371
|
-
<
|
|
18372
|
-
|
|
18373
|
-
|
|
18374
|
-
|
|
18375
|
-
|
|
18376
|
-
|
|
18377
|
-
|
|
18378
|
-
|
|
18898
|
+
<dl
|
|
18899
|
+
class="m-0 grid grid-cols-[repeat(auto-fill,minmax(11rem,1fr))] gap-x-6 gap-y-3 overflow-x-hidden px-[1.125rem] py-4 transition-opacity duration-200 ease-out motion-reduce:transition-none"
|
|
18900
|
+
[class.opacity-0]="!isRowExpanded(row, i)"
|
|
18901
|
+
[class.opacity-100]="isRowExpanded(row, i)"
|
|
18902
|
+
>
|
|
18903
|
+
@for (
|
|
18904
|
+
detail of rowDetailDefs();
|
|
18905
|
+
track detail.label()
|
|
18906
|
+
) {
|
|
18907
|
+
<div class="min-w-0">
|
|
18908
|
+
<dt
|
|
18909
|
+
class="m-0 text-caption font-medium text-neutral-600 dark:text-neutral-400"
|
|
18910
|
+
>
|
|
18911
|
+
{{ detail.label() }}
|
|
18912
|
+
</dt>
|
|
18913
|
+
<dd
|
|
18914
|
+
class="m-0 mt-0.5 break-words text-body-sm text-ink dark:text-white"
|
|
18915
|
+
>
|
|
18916
|
+
<ng-container
|
|
18917
|
+
[ngTemplateOutlet]="detail.template"
|
|
18918
|
+
[ngTemplateOutletContext]="cellContext(row)"
|
|
18919
|
+
/>
|
|
18920
|
+
</dd>
|
|
18921
|
+
</div>
|
|
18922
|
+
}
|
|
18923
|
+
</dl>
|
|
18924
|
+
</div>
|
|
18379
18925
|
</div>
|
|
18380
18926
|
</div>
|
|
18381
18927
|
</td>
|
|
@@ -18386,6 +18932,23 @@ class TableComponent {
|
|
|
18386
18932
|
}
|
|
18387
18933
|
</tbody>
|
|
18388
18934
|
</table>
|
|
18935
|
+
</div>
|
|
18936
|
+
@if (paginationLoading()) {
|
|
18937
|
+
<div
|
|
18938
|
+
class="absolute inset-0 z-[5] bg-surface/70 dark:bg-ink-950/70"
|
|
18939
|
+
data-testid="africanies-table-keep-rows-loading"
|
|
18940
|
+
aria-hidden="true"
|
|
18941
|
+
>
|
|
18942
|
+
<div
|
|
18943
|
+
class="sticky top-0 flex h-[min(70dvh,100%)] items-center justify-center px-4"
|
|
18944
|
+
>
|
|
18945
|
+
<africanies-loading-state
|
|
18946
|
+
mode="inline"
|
|
18947
|
+
[message]="loadingLabel()"
|
|
18948
|
+
/>
|
|
18949
|
+
</div>
|
|
18950
|
+
</div>
|
|
18951
|
+
}
|
|
18389
18952
|
</div>
|
|
18390
18953
|
|
|
18391
18954
|
@if (meta(); as pager) {
|
|
@@ -18398,7 +18961,7 @@ class TableComponent {
|
|
|
18398
18961
|
/>
|
|
18399
18962
|
}
|
|
18400
18963
|
</div>
|
|
18401
|
-
`, isInline: true, styles: [":host tr.africanies-table-row:hover>td{background-color:#
|
|
18964
|
+
`, isInline: true, styles: [":host tr.africanies-table-row:hover>td{background-color:#e9eef5}:host-context(.dark) tr.africanies-table-row:hover>td{background-color:#272729}:host .africanies-table-scrollport{container-type:inline-size;container-name:africanies-table}:host .africanies-table-expand-panel{position:sticky;left:0;z-index:1;box-sizing:border-box;width:100cqi;max-width:100cqi;overflow-x:hidden}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ButtonComponent, selector: "button[africanies-button], a[africanies-button]", inputs: ["variant", "size", "disabled", "loading"] }, { kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }, { kind: "component", type: EmptyStateComponent, selector: "africanies-empty-state", inputs: ["message", "refreshing"], outputs: ["retry"] }, { kind: "component", type: ErrorIndicatorComponent, selector: "africanies-error-indicator", inputs: ["error", "retryText", "refreshing", "refreshingText", "disabled"], outputs: ["retry"] }, { kind: "component", type: ErrorStateComponent, selector: "africanies-error-state", inputs: ["message", "refreshing"], outputs: ["retry"] }, { kind: "component", type: LoadingStateComponent, selector: "africanies-loading-state", inputs: ["message", "mode"] }, { kind: "component", type: PaginationComponent, selector: "africanies-pagination", inputs: ["meta", "disabled", "loading", "pageSizes"], outputs: ["pageChange", "sizeChange"] }, { kind: "component", type: SegmentComponent, selector: "africanies-segment", inputs: ["items", "activeId", "ariaLabel", "linkActiveOptions", "keepScroll"], outputs: ["activeIdChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
18402
18965
|
}
|
|
18403
18966
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: TableComponent, decorators: [{
|
|
18404
18967
|
type: Component,
|
|
@@ -18411,6 +18974,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18411
18974
|
ErrorStateComponent,
|
|
18412
18975
|
LoadingStateComponent,
|
|
18413
18976
|
PaginationComponent,
|
|
18977
|
+
SegmentComponent,
|
|
18414
18978
|
], host: {
|
|
18415
18979
|
class: 'block w-full min-w-0',
|
|
18416
18980
|
}, template: `
|
|
@@ -18418,84 +18982,107 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18418
18982
|
class="flex w-full min-w-0 flex-col gap-3"
|
|
18419
18983
|
[attr.aria-busy]="loading() || refreshing() || null"
|
|
18420
18984
|
>
|
|
18421
|
-
@if (
|
|
18422
|
-
|
|
18423
|
-
|
|
18424
|
-
|
|
18425
|
-
|
|
18426
|
-
|
|
18427
|
-
|
|
18428
|
-
|
|
18429
|
-
|
|
18430
|
-
|
|
18431
|
-
|
|
18432
|
-
|
|
18433
|
-
|
|
18434
|
-
|
|
18435
|
-
|
|
18436
|
-
|
|
18437
|
-
|
|
18438
|
-
|
|
18439
|
-
|
|
18440
|
-
|
|
18441
|
-
|
|
18442
|
-
|
|
18443
|
-
|
|
18444
|
-
|
|
18445
|
-
|
|
18446
|
-
|
|
18447
|
-
|
|
18448
|
-
|
|
18449
|
-
size="sm"
|
|
18450
|
-
[attr.aria-label]="filterLabel()"
|
|
18451
|
-
(click)="filterClick.emit()"
|
|
18452
|
-
>
|
|
18453
|
-
<africanies-icon name="filter" [size]="16" />
|
|
18454
|
-
{{ filterLabel() }}
|
|
18455
|
-
@if (filterCount() > 0) {
|
|
18456
|
-
<span
|
|
18457
|
-
class="inline-flex min-w-5 items-center justify-center rounded-full bg-ink px-1.5 py-0.5 text-caption font-semibold tabular-nums text-white dark:bg-white dark:text-ink"
|
|
18985
|
+
@if (
|
|
18986
|
+
showShippingMode() ||
|
|
18987
|
+
showRefresh() ||
|
|
18988
|
+
showFilter() ||
|
|
18989
|
+
showExport()
|
|
18990
|
+
) {
|
|
18991
|
+
<div class="flex w-full min-w-0 flex-col gap-3">
|
|
18992
|
+
@if (showShippingMode()) {
|
|
18993
|
+
<africanies-segment
|
|
18994
|
+
class="min-w-0 self-start"
|
|
18995
|
+
[items]="shippingModeItems"
|
|
18996
|
+
[activeId]="shippingModeActiveId()"
|
|
18997
|
+
ariaLabel="Shipping mode"
|
|
18998
|
+
(activeIdChange)="onShippingModeChange($event)"
|
|
18999
|
+
/>
|
|
19000
|
+
}
|
|
19001
|
+
@if (showToolbarRefresh() || showFilter() || showExport()) {
|
|
19002
|
+
<div class="flex flex-wrap items-center justify-between gap-2">
|
|
19003
|
+
<div class="flex min-w-0 flex-wrap items-center gap-2">
|
|
19004
|
+
@if (showToolbarRefresh()) {
|
|
19005
|
+
<button
|
|
19006
|
+
africanies-button
|
|
19007
|
+
type="button"
|
|
19008
|
+
variant="flat"
|
|
19009
|
+
size="sm"
|
|
19010
|
+
[disabled]="loading() || refreshing()"
|
|
19011
|
+
[attr.aria-label]="refreshLabel()"
|
|
19012
|
+
(click)="refreshClick.emit()"
|
|
18458
19013
|
>
|
|
18459
|
-
|
|
18460
|
-
|
|
19014
|
+
<africanies-icon
|
|
19015
|
+
name="refresh"
|
|
19016
|
+
[size]="16"
|
|
19017
|
+
[class]="refreshing() ? 'animate-spin' : ''"
|
|
19018
|
+
/>
|
|
19019
|
+
{{ refreshLabel() }}
|
|
19020
|
+
</button>
|
|
18461
19021
|
}
|
|
18462
|
-
</
|
|
18463
|
-
|
|
18464
|
-
|
|
18465
|
-
|
|
18466
|
-
|
|
18467
|
-
|
|
18468
|
-
|
|
18469
|
-
|
|
18470
|
-
|
|
18471
|
-
|
|
18472
|
-
|
|
18473
|
-
|
|
18474
|
-
|
|
18475
|
-
|
|
18476
|
-
|
|
18477
|
-
|
|
19022
|
+
</div>
|
|
19023
|
+
<div class="flex items-center gap-2">
|
|
19024
|
+
@if (showFilter()) {
|
|
19025
|
+
<button
|
|
19026
|
+
africanies-button
|
|
19027
|
+
type="button"
|
|
19028
|
+
variant="flat"
|
|
19029
|
+
size="sm"
|
|
19030
|
+
[attr.aria-label]="filterLabel()"
|
|
19031
|
+
(click)="filterClick.emit()"
|
|
19032
|
+
>
|
|
19033
|
+
<africanies-icon name="filter" [size]="16" />
|
|
19034
|
+
{{ filterLabel() }}
|
|
19035
|
+
@if (filterCount() > 0) {
|
|
19036
|
+
<span
|
|
19037
|
+
class="inline-flex min-w-5 items-center justify-center rounded-full bg-ink px-1.5 py-0.5 text-caption font-semibold tabular-nums text-white dark:bg-white dark:text-ink"
|
|
19038
|
+
>
|
|
19039
|
+
{{ filterCount() }}
|
|
19040
|
+
</span>
|
|
19041
|
+
}
|
|
19042
|
+
</button>
|
|
19043
|
+
}
|
|
19044
|
+
@if (showExport()) {
|
|
19045
|
+
<button
|
|
19046
|
+
africanies-button
|
|
19047
|
+
type="button"
|
|
19048
|
+
variant="flat"
|
|
19049
|
+
size="sm"
|
|
19050
|
+
[attr.aria-label]="exportLabel()"
|
|
19051
|
+
(click)="exportClick.emit()"
|
|
19052
|
+
>
|
|
19053
|
+
<africanies-icon name="download" [size]="16" />
|
|
19054
|
+
{{ exportLabel() }}
|
|
19055
|
+
</button>
|
|
19056
|
+
}
|
|
19057
|
+
</div>
|
|
19058
|
+
</div>
|
|
19059
|
+
}
|
|
18478
19060
|
</div>
|
|
18479
19061
|
}
|
|
18480
19062
|
|
|
18481
19063
|
@if (staleError(); as staleMessage) {
|
|
18482
|
-
<
|
|
18483
|
-
|
|
18484
|
-
|
|
18485
|
-
|
|
18486
|
-
|
|
18487
|
-
|
|
18488
|
-
|
|
18489
|
-
/>
|
|
18490
|
-
</div>
|
|
19064
|
+
<africanies-error-indicator
|
|
19065
|
+
class="w-full"
|
|
19066
|
+
[error]="staleMessage"
|
|
19067
|
+
retryText="Refresh"
|
|
19068
|
+
[refreshing]="refreshing()"
|
|
19069
|
+
(retry)="refreshClick.emit()"
|
|
19070
|
+
/>
|
|
18491
19071
|
}
|
|
18492
19072
|
|
|
18493
19073
|
<div
|
|
18494
|
-
class="min-w-0 w-full overflow-
|
|
19074
|
+
class="relative min-w-0 w-full overflow-hidden rounded-panel border border-border bg-surface dark:border-white/10 dark:bg-ink-surface"
|
|
18495
19075
|
>
|
|
18496
|
-
<
|
|
18497
|
-
|
|
19076
|
+
<div
|
|
19077
|
+
#scrollport
|
|
19078
|
+
class="africanies-table-scrollport min-w-0 w-full overflow-x-auto"
|
|
19079
|
+
[class.lg:max-h-[min(70dvh,calc(100dvh-12rem))]]="stickyHeader()"
|
|
19080
|
+
[class.lg:overflow-auto]="stickyHeader() && !paginationLoading()"
|
|
19081
|
+
[class.pointer-events-none]="paginationLoading()"
|
|
18498
19082
|
>
|
|
19083
|
+
<table
|
|
19084
|
+
class="w-max min-w-full table-auto border-separate border-spacing-0 bg-inherit text-left text-body text-ink dark:text-white"
|
|
19085
|
+
>
|
|
18499
19086
|
<thead [class]="headerRowClass()">
|
|
18500
19087
|
<tr>
|
|
18501
19088
|
@if (isExpandable()) {
|
|
@@ -18506,7 +19093,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18506
19093
|
@if (someRowsExpanded()) {
|
|
18507
19094
|
<button
|
|
18508
19095
|
type="button"
|
|
18509
|
-
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-
|
|
19096
|
+
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-500 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"
|
|
18510
19097
|
aria-label="Collapse all"
|
|
18511
19098
|
(click)="collapseAllRows()"
|
|
18512
19099
|
>
|
|
@@ -18515,7 +19102,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18515
19102
|
} @else {
|
|
18516
19103
|
<button
|
|
18517
19104
|
type="button"
|
|
18518
|
-
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-
|
|
19105
|
+
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-500 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"
|
|
18519
19106
|
aria-label="Expand all"
|
|
18520
19107
|
[disabled]="rowList().length === 0"
|
|
18521
19108
|
(click)="expandAllRows()"
|
|
@@ -18529,7 +19116,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18529
19116
|
<th
|
|
18530
19117
|
scope="col"
|
|
18531
19118
|
[class]="headerCellClass(col)"
|
|
18532
|
-
[style.width]="col.width ?? null"
|
|
19119
|
+
[style.width]="col.width ?? col.maxWidth ?? null"
|
|
19120
|
+
[style.max-width]="col.maxWidth ?? null"
|
|
18533
19121
|
>
|
|
18534
19122
|
@if (headerTemplateFor(col.key); as headerTpl) {
|
|
18535
19123
|
<ng-container
|
|
@@ -18538,7 +19126,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18538
19126
|
} @else if (col.sortable) {
|
|
18539
19127
|
<button
|
|
18540
19128
|
type="button"
|
|
18541
|
-
class="inline-flex cursor-pointer items-center gap-1 rounded-sm font-medium text-neutral-
|
|
19129
|
+
class="inline-flex cursor-pointer items-center gap-1 rounded-sm font-medium text-neutral-500 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"
|
|
18542
19130
|
(click)="onSortHeaderClick(col.key)"
|
|
18543
19131
|
>
|
|
18544
19132
|
<span>{{ col.header }}</span>
|
|
@@ -18594,7 +19182,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18594
19182
|
<td [class]="expandBodyClass(i)">
|
|
18595
19183
|
<button
|
|
18596
19184
|
type="button"
|
|
18597
|
-
class="inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-neutral-600 transition-colors hover:bg-background-
|
|
19185
|
+
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"
|
|
18598
19186
|
[attr.aria-label]="
|
|
18599
19187
|
isRowExpanded(row, i)
|
|
18600
19188
|
? 'Collapse row details'
|
|
@@ -18613,7 +19201,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18613
19201
|
@for (col of columns(); track col.key) {
|
|
18614
19202
|
<td
|
|
18615
19203
|
[class]="bodyCellClass(col, i)"
|
|
18616
|
-
[style.width]="col.width ?? null"
|
|
19204
|
+
[style.width]="col.width ?? col.maxWidth ?? null"
|
|
19205
|
+
[style.max-width]="col.maxWidth ?? null"
|
|
18617
19206
|
>
|
|
18618
19207
|
@if (templateFor(col.key); as tpl) {
|
|
18619
19208
|
<ng-container
|
|
@@ -18633,41 +19222,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18633
19222
|
[class.border-border]="isRowExpanded(row, i)"
|
|
18634
19223
|
[class.dark:border-white/10]="isRowExpanded(row, i)"
|
|
18635
19224
|
>
|
|
18636
|
-
<td class="p-0 align-top" [attr.colspan]="
|
|
19225
|
+
<td class="p-0 align-top" [attr.colspan]="colSpan()">
|
|
19226
|
+
<!-- Sticky must sit outside overflow-hidden or it pins
|
|
19227
|
+
to the full table width and scrolls with the row. -->
|
|
18637
19228
|
<div
|
|
18638
|
-
class="
|
|
18639
|
-
[style.
|
|
18640
|
-
|
|
18641
|
-
"
|
|
18642
|
-
[attr.aria-hidden]="!isRowExpanded(row, i)"
|
|
18643
|
-
[class.pointer-events-none]="!isRowExpanded(row, i)"
|
|
19229
|
+
class="africanies-table-expand-panel bg-surface-sunken dark:bg-white/[0.05]"
|
|
19230
|
+
[style.width.px]="scrollportWidthPx() || null"
|
|
19231
|
+
[style.maxWidth.px]="scrollportWidthPx() || null"
|
|
18644
19232
|
>
|
|
18645
19233
|
<div
|
|
18646
|
-
class="
|
|
19234
|
+
class="grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none"
|
|
19235
|
+
[style.grid-template-rows]="
|
|
19236
|
+
isRowExpanded(row, i) ? '1fr' : '0fr'
|
|
19237
|
+
"
|
|
19238
|
+
[attr.aria-hidden]="!isRowExpanded(row, i)"
|
|
19239
|
+
[class.pointer-events-none]="!isRowExpanded(row, i)"
|
|
18647
19240
|
>
|
|
18648
|
-
<
|
|
18649
|
-
class="
|
|
18650
|
-
[class.opacity-0]="!isRowExpanded(row, i)"
|
|
18651
|
-
[class.opacity-100]="isRowExpanded(row, i)"
|
|
19241
|
+
<div
|
|
19242
|
+
class="min-h-0 overflow-x-hidden overflow-y-hidden border-t border-border-strong dark:border-white/10"
|
|
18652
19243
|
>
|
|
18653
|
-
|
|
18654
|
-
|
|
18655
|
-
|
|
18656
|
-
|
|
18657
|
-
|
|
18658
|
-
|
|
18659
|
-
|
|
18660
|
-
|
|
18661
|
-
|
|
18662
|
-
>
|
|
18663
|
-
<
|
|
18664
|
-
|
|
18665
|
-
|
|
18666
|
-
|
|
18667
|
-
|
|
18668
|
-
|
|
18669
|
-
|
|
18670
|
-
|
|
19244
|
+
<dl
|
|
19245
|
+
class="m-0 grid grid-cols-[repeat(auto-fill,minmax(11rem,1fr))] gap-x-6 gap-y-3 overflow-x-hidden px-[1.125rem] py-4 transition-opacity duration-200 ease-out motion-reduce:transition-none"
|
|
19246
|
+
[class.opacity-0]="!isRowExpanded(row, i)"
|
|
19247
|
+
[class.opacity-100]="isRowExpanded(row, i)"
|
|
19248
|
+
>
|
|
19249
|
+
@for (
|
|
19250
|
+
detail of rowDetailDefs();
|
|
19251
|
+
track detail.label()
|
|
19252
|
+
) {
|
|
19253
|
+
<div class="min-w-0">
|
|
19254
|
+
<dt
|
|
19255
|
+
class="m-0 text-caption font-medium text-neutral-600 dark:text-neutral-400"
|
|
19256
|
+
>
|
|
19257
|
+
{{ detail.label() }}
|
|
19258
|
+
</dt>
|
|
19259
|
+
<dd
|
|
19260
|
+
class="m-0 mt-0.5 break-words text-body-sm text-ink dark:text-white"
|
|
19261
|
+
>
|
|
19262
|
+
<ng-container
|
|
19263
|
+
[ngTemplateOutlet]="detail.template"
|
|
19264
|
+
[ngTemplateOutletContext]="cellContext(row)"
|
|
19265
|
+
/>
|
|
19266
|
+
</dd>
|
|
19267
|
+
</div>
|
|
19268
|
+
}
|
|
19269
|
+
</dl>
|
|
19270
|
+
</div>
|
|
18671
19271
|
</div>
|
|
18672
19272
|
</div>
|
|
18673
19273
|
</td>
|
|
@@ -18678,6 +19278,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18678
19278
|
}
|
|
18679
19279
|
</tbody>
|
|
18680
19280
|
</table>
|
|
19281
|
+
</div>
|
|
19282
|
+
@if (paginationLoading()) {
|
|
19283
|
+
<div
|
|
19284
|
+
class="absolute inset-0 z-[5] bg-surface/70 dark:bg-ink-950/70"
|
|
19285
|
+
data-testid="africanies-table-keep-rows-loading"
|
|
19286
|
+
aria-hidden="true"
|
|
19287
|
+
>
|
|
19288
|
+
<div
|
|
19289
|
+
class="sticky top-0 flex h-[min(70dvh,100%)] items-center justify-center px-4"
|
|
19290
|
+
>
|
|
19291
|
+
<africanies-loading-state
|
|
19292
|
+
mode="inline"
|
|
19293
|
+
[message]="loadingLabel()"
|
|
19294
|
+
/>
|
|
19295
|
+
</div>
|
|
19296
|
+
</div>
|
|
19297
|
+
}
|
|
18681
19298
|
</div>
|
|
18682
19299
|
|
|
18683
19300
|
@if (meta(); as pager) {
|
|
@@ -18690,8 +19307,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18690
19307
|
/>
|
|
18691
19308
|
}
|
|
18692
19309
|
</div>
|
|
18693
|
-
`, styles: [":host tr.africanies-table-row:hover>td{background-color:#
|
|
18694
|
-
}], propDecorators: { expandable: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandable", required: false }] }], rowTrackBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowTrackBy", required: false }] }], rowExpandChange: [{ type: i0.Output, args: ["rowExpandChange"] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], sort: [{ type: i0.Input, args: [{ isSignal: true, alias: "sort", required: false }] }], showRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRefresh", required: false }] }], refreshLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "refreshLabel", required: false }] }], refreshing: [{ type: i0.Input, args: [{ isSignal: true, alias: "refreshing", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingLabel", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], showFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFilter", required: false }] }], filterLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterLabel", required: false }] }], filterCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterCount", required: false }] }], showExport: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExport", required: false }] }], exportLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportLabel", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], refreshClick: [{ type: i0.Output, args: ["refreshClick"] }], filterClick: [{ type: i0.Output, args: ["filterClick"] }], exportClick: [{ type: i0.Output, args: ["exportClick"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], sizeChange: [{ type: i0.Output, args: ["sizeChange"] }], cellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => CellDefDirective), { isSignal: true }] }], headerCellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => HeaderCellDefDirective), { isSignal: true }] }], rowDetailDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => RowDetailDefDirective), { isSignal: true }] }] } });
|
|
19310
|
+
`, styles: [":host tr.africanies-table-row:hover>td{background-color:#e9eef5}:host-context(.dark) tr.africanies-table-row:hover>td{background-color:#272729}:host .africanies-table-scrollport{container-type:inline-size;container-name:africanies-table}:host .africanies-table-expand-panel{position:sticky;left:0;z-index:1;box-sizing:border-box;width:100cqi;max-width:100cqi;overflow-x:hidden}\n"] }]
|
|
19311
|
+
}], ctorParameters: () => [], propDecorators: { scrollport: [{ type: i0.ViewChild, args: ['scrollport', { isSignal: true }] }], expandable: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandable", required: false }] }], rowTrackBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowTrackBy", required: false }] }], rowExpandChange: [{ type: i0.Output, args: ["rowExpandChange"] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], stickyHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "stickyHeader", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], sort: [{ type: i0.Input, args: [{ isSignal: true, alias: "sort", required: false }] }], showShippingMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "showShippingMode", required: false }] }], showRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRefresh", required: false }] }], refreshLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "refreshLabel", required: false }] }], refreshing: [{ type: i0.Input, args: [{ isSignal: true, alias: "refreshing", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingLabel", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], showFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFilter", required: false }] }], filterLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterLabel", required: false }] }], filterCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterCount", required: false }] }], showExport: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExport", required: false }] }], exportLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportLabel", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], refreshClick: [{ type: i0.Output, args: ["refreshClick"] }], filterClick: [{ type: i0.Output, args: ["filterClick"] }], exportClick: [{ type: i0.Output, args: ["exportClick"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], sizeChange: [{ type: i0.Output, args: ["sizeChange"] }], cellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => CellDefDirective), { isSignal: true }] }], headerCellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => HeaderCellDefDirective), { isSignal: true }] }], rowDetailDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => RowDetailDefDirective), { isSignal: true }] }] } });
|
|
18695
19312
|
|
|
18696
19313
|
/**
|
|
18697
19314
|
* Presentational table with template-based cells.
|
|
@@ -18837,7 +19454,7 @@ class StepperComponent {
|
|
|
18837
19454
|
if (past) {
|
|
18838
19455
|
return 'cursor-pointer text-ink hover:bg-background-welcome dark:text-white dark:hover:bg-white/10';
|
|
18839
19456
|
}
|
|
18840
|
-
return 'opacity-40 text-neutral-
|
|
19457
|
+
return 'opacity-40 text-neutral-600 dark:text-neutral-400';
|
|
18841
19458
|
}
|
|
18842
19459
|
stepBadgeClass(index) {
|
|
18843
19460
|
const base = 'inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full border text-body-sm font-medium';
|
|
@@ -18845,7 +19462,7 @@ class StepperComponent {
|
|
|
18845
19462
|
const c = this.modeColor.classes();
|
|
18846
19463
|
return `${base} ${c.border} ${c.bg} text-white`;
|
|
18847
19464
|
}
|
|
18848
|
-
return `${base} border-
|
|
19465
|
+
return `${base} border-control bg-surface text-neutral-600 dark:border-white/20 dark:bg-ink-950 dark:text-neutral-400`;
|
|
18849
19466
|
}
|
|
18850
19467
|
canActivate(index) {
|
|
18851
19468
|
if (index === this.activeIndex()) {
|
|
@@ -18870,7 +19487,7 @@ class StepperComponent {
|
|
|
18870
19487
|
<div class="flex flex-col gap-5 text-ink dark:text-white">
|
|
18871
19488
|
<div class="flex flex-col gap-2">
|
|
18872
19489
|
<p
|
|
18873
|
-
class="m-0 text-caption font-medium uppercase tracking-wide text-neutral-
|
|
19490
|
+
class="m-0 text-caption font-medium uppercase tracking-wide text-neutral-600 dark:text-neutral-400"
|
|
18874
19491
|
>
|
|
18875
19492
|
Step {{ activeIndex() + 1 }} of {{ steps().length }}
|
|
18876
19493
|
<span
|
|
@@ -18899,7 +19516,7 @@ class StepperComponent {
|
|
|
18899
19516
|
<li class="flex min-w-0 shrink-0 items-center gap-1">
|
|
18900
19517
|
<button
|
|
18901
19518
|
type="button"
|
|
18902
|
-
class="inline-flex max-w-38 items-center gap-2 rounded-lg px-2 py-1.5 text-left transition-colors focus-visible:outline-
|
|
19519
|
+
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"
|
|
18903
19520
|
[class]="headerButtonClass(i)"
|
|
18904
19521
|
[attr.aria-current]="i === activeIndex() ? 'step' : null"
|
|
18905
19522
|
[disabled]="!canActivate(i)"
|
|
@@ -18938,7 +19555,7 @@ class StepperComponent {
|
|
|
18938
19555
|
}
|
|
18939
19556
|
</div>
|
|
18940
19557
|
</div>
|
|
18941
|
-
`, isInline: true, styles: [".africanies-step-rail{scrollbar-width:thin}.africanies-step-body{min-width:0;overflow-x:clip;padding-inline:
|
|
19558
|
+
`, isInline: true, styles: [".africanies-step-rail{scrollbar-width:thin}.africanies-step-body{min-width:0;overflow-x:clip;padding-inline:4px;margin-inline:-4px}.africanies-step-pane{min-width:0;will-change:opacity,transform}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
18942
19559
|
}
|
|
18943
19560
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: StepperComponent, decorators: [{
|
|
18944
19561
|
type: Component,
|
|
@@ -18946,7 +19563,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18946
19563
|
<div class="flex flex-col gap-5 text-ink dark:text-white">
|
|
18947
19564
|
<div class="flex flex-col gap-2">
|
|
18948
19565
|
<p
|
|
18949
|
-
class="m-0 text-caption font-medium uppercase tracking-wide text-neutral-
|
|
19566
|
+
class="m-0 text-caption font-medium uppercase tracking-wide text-neutral-600 dark:text-neutral-400"
|
|
18950
19567
|
>
|
|
18951
19568
|
Step {{ activeIndex() + 1 }} of {{ steps().length }}
|
|
18952
19569
|
<span
|
|
@@ -18975,7 +19592,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
18975
19592
|
<li class="flex min-w-0 shrink-0 items-center gap-1">
|
|
18976
19593
|
<button
|
|
18977
19594
|
type="button"
|
|
18978
|
-
class="inline-flex max-w-38 items-center gap-2 rounded-lg px-2 py-1.5 text-left transition-colors focus-visible:outline-
|
|
19595
|
+
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"
|
|
18979
19596
|
[class]="headerButtonClass(i)"
|
|
18980
19597
|
[attr.aria-current]="i === activeIndex() ? 'step' : null"
|
|
18981
19598
|
[disabled]="!canActivate(i)"
|
|
@@ -19014,7 +19631,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
19014
19631
|
}
|
|
19015
19632
|
</div>
|
|
19016
19633
|
</div>
|
|
19017
|
-
`, styles: [".africanies-step-rail{scrollbar-width:thin}.africanies-step-body{min-width:0;overflow-x:clip;padding-inline:
|
|
19634
|
+
`, styles: [".africanies-step-rail{scrollbar-width:thin}.africanies-step-body{min-width:0;overflow-x:clip;padding-inline:4px;margin-inline:-4px}.africanies-step-pane{min-width:0;will-change:opacity,transform}\n"] }]
|
|
19018
19635
|
}], ctorParameters: () => [], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: true }] }], activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: true }] }], linear: [{ type: i0.Input, args: [{ isSignal: true, alias: "linear", required: false }] }], animateSteps: [{ type: i0.Input, args: [{ isSignal: true, alias: "animateSteps", required: false }] }], activeIndexChange: [{ type: i0.Output, args: ["activeIndexChange"] }], stepDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StepDefDirective), { isSignal: true }] }], stepPane: [{ type: i0.ViewChild, args: ['stepPane', { isSignal: true }] }] } });
|
|
19019
19636
|
|
|
19020
19637
|
/**
|
|
@@ -19275,6 +19892,7 @@ class AfricaniesNavigationModule {
|
|
|
19275
19892
|
BreadcrumbComponent,
|
|
19276
19893
|
TabsComponent,
|
|
19277
19894
|
SegmentComponent,
|
|
19895
|
+
ShippingModeSwitchComponent,
|
|
19278
19896
|
SideNavComponent] });
|
|
19279
19897
|
}
|
|
19280
19898
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesNavigationModule, decorators: [{
|