@africanies/angular-web-sdk 0.1.2 → 0.1.4
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/12276756491762927325/dist/libs/africanies-theme/README.md +46 -0
- package/.nx/cache/12276756491762927325/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs +215 -0
- package/.nx/cache/12276756491762927325/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +1 -0
- package/.nx/cache/12276756491762927325/dist/libs/africanies-theme/package.json +35 -0
- package/.nx/cache/12276756491762927325/dist/libs/africanies-theme/tailwind-preset.cjs +245 -0
- package/.nx/cache/12276756491762927325/dist/libs/africanies-theme/types/africanies-africanies-theme.d.ts +157 -0
- package/.nx/cache/17491371155400585077/dist/libs/africanies-core/README.md +85 -0
- package/.nx/cache/17491371155400585077/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs +4546 -0
- package/.nx/cache/17491371155400585077/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs.map +1 -0
- package/.nx/cache/17491371155400585077/dist/libs/africanies-core/package.json +31 -0
- package/.nx/cache/17491371155400585077/dist/libs/africanies-core/types/africanies-africanies-core.d.ts +2740 -0
- package/.nx/cache/17499961385238663835/dist/libs/africanies-ui/README.md +68 -0
- package/.nx/cache/17499961385238663835/dist/libs/africanies-ui/assets/brand/africanies-logo-mini.png +0 -0
- package/.nx/cache/17499961385238663835/dist/libs/africanies-ui/assets/brand/africanies-logo.png +0 -0
- package/.nx/cache/17499961385238663835/dist/libs/africanies-ui/assets/brand/africanies-logo.svg +5 -0
- package/.nx/cache/17499961385238663835/dist/libs/africanies-ui/assets/carriers/dhl.svg +7 -0
- package/.nx/cache/17499961385238663835/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs +19375 -0
- package/.nx/cache/17499961385238663835/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +1 -0
- package/.nx/cache/17499961385238663835/dist/libs/africanies-ui/package.json +35 -0
- package/.nx/cache/17499961385238663835/dist/libs/africanies-ui/types/africanies-africanies-ui.d.ts +5490 -0
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/README.md +68 -0
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/assets/brand/africanies-logo-mini.png +0 -0
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/assets/brand/africanies-logo.png +0 -0
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/assets/brand/africanies-logo.svg +5 -0
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/assets/carriers/dhl.svg +7 -0
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs +19291 -0
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +1 -0
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/package.json +35 -0
- package/.nx/cache/3314955264390318442/dist/libs/africanies-ui/types/africanies-africanies-ui.d.ts +5483 -0
- package/.nx/cache/4082520855419352840/dist/libs/africanies-theme/README.md +46 -0
- package/.nx/cache/4082520855419352840/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs +221 -0
- package/.nx/cache/4082520855419352840/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +1 -0
- package/.nx/cache/4082520855419352840/dist/libs/africanies-theme/package.json +35 -0
- package/.nx/cache/4082520855419352840/dist/libs/africanies-theme/tailwind-preset.cjs +253 -0
- package/.nx/cache/4082520855419352840/dist/libs/africanies-theme/types/africanies-africanies-theme.d.ts +166 -0
- package/.nx/cache/run.json +19 -19
- package/.nx/cache/terminalOutputs/12276756491762927325 +21 -0
- package/.nx/cache/terminalOutputs/16279119293212733518 +6 -0
- package/.nx/cache/terminalOutputs/17491371155400585077 +21 -0
- package/.nx/cache/terminalOutputs/17499961385238663835 +21 -0
- package/.nx/cache/terminalOutputs/3017748574492080228 +28 -0
- package/.nx/cache/terminalOutputs/3314955264390318442 +21 -0
- package/.nx/cache/terminalOutputs/4082520855419352840 +21 -0
- package/.nx/cache/terminalOutputs/7126777490381568487 +32 -0
- package/.nx/cache/terminalOutputs/8648260256613557249 +173 -0
- package/.nx/cache/terminalOutputs/9408529484792607601 +6 -0
- package/.nx/workspace-data/0091ABA9-5C90-580D-953C-8C94E763ADB5-v3.db +0 -0
- package/.nx/workspace-data/0091ABA9-5C90-580D-953C-8C94E763ADB5-v3.db-shm +0 -0
- package/.nx/workspace-data/0091ABA9-5C90-580D-953C-8C94E763ADB5-v3.db-wal +0 -0
- package/.nx/workspace-data/d/daemon.log +3296 -0
- package/.nx/workspace-data/d/server-process.json +2 -2
- package/.nx/workspace-data/file-map.json +3422 -3408
- package/.nx/workspace-data/nx_files.nxt +0 -0
- package/.nx/workspace-data/project-graph.json +5 -5
- package/.nx/workspace-data/source-maps.json +0 -80
- package/apps/playground/src/app/snippets/action-menu.snippets.ts +1 -0
- package/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs +1 -1
- package/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs.map +1 -1
- package/dist/libs/africanies-core/package.json +3 -3
- package/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs +6 -0
- package/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +1 -1
- package/dist/libs/africanies-theme/package.json +3 -3
- package/dist/libs/africanies-theme/tailwind-preset.cjs +15 -7
- package/dist/libs/africanies-theme/types/africanies-africanies-theme.d.ts +10 -1
- package/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs +456 -169
- package/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +1 -1
- package/dist/libs/africanies-ui/package.json +5 -5
- package/dist/libs/africanies-ui/types/africanies-africanies-ui.d.ts +111 -31
- package/libs/africanies-core/package.json +3 -3
- package/libs/africanies-core/src/lib/payment-method/payment-method.mapper.spec.ts +15 -0
- package/libs/africanies-core/src/lib/payment-method/payment-method.mapper.ts +1 -2
- package/libs/africanies-theme/package.json +3 -3
- package/libs/africanies-theme/src/lib/mode-color.safelist.ts +4 -0
- package/libs/africanies-theme/src/lib/mode-color.service.ts +11 -0
- package/libs/africanies-theme/tailwind-preset.cjs +15 -7
- package/libs/africanies-ui/package.json +5 -5
- package/libs/africanies-ui/src/index.ts +6 -0
- package/libs/africanies-ui/src/lib/accordion/accordion.component.ts +135 -0
- package/libs/africanies-ui/src/lib/accordion/index.ts +7 -0
- package/libs/africanies-ui/src/lib/action-menu/action-menu.component.ts +84 -17
- package/libs/africanies-ui/src/lib/action-menu/menu-item.ts +19 -2
- package/libs/africanies-ui/src/lib/layout/header-weather.spec.ts +111 -6
- package/libs/africanies-ui/src/lib/layout/header-weather.ts +104 -8
- package/libs/africanies-ui/src/lib/modules/africanies-feedback.module.ts +3 -1
- package/libs/africanies-ui/src/lib/table/table.component.ts +67 -44
- package/package.json +1 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@africanies/africanies-core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/common": "^22.0.0",
|
|
6
6
|
"@angular/core": "^22.0.0",
|
|
7
7
|
"@angular/router": "^22.0.0",
|
|
8
8
|
"rxjs": "^7.8.0",
|
|
9
|
-
"@africanies/africanies-models": "
|
|
10
|
-
"@africanies/africanies-storage": "
|
|
9
|
+
"@africanies/africanies-models": ">=0.0.2 <0.1.0",
|
|
10
|
+
"@africanies/africanies-storage": ">=0.0.1 <0.1.0"
|
|
11
11
|
},
|
|
12
12
|
"sideEffects": false,
|
|
13
13
|
"publishConfig": {
|
|
@@ -76,6 +76,21 @@ describe('payment-method.mapper', () => {
|
|
|
76
76
|
);
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
+
it('unwraps paginated nested currencies', () => {
|
|
80
|
+
const mapped = mapPaymentMethod({
|
|
81
|
+
id: 4,
|
|
82
|
+
name: 'Squad',
|
|
83
|
+
model: 'App\\Models\\Squad',
|
|
84
|
+
currencies: {
|
|
85
|
+
current_page: 1,
|
|
86
|
+
data: WIRE_SQUAD.currencies,
|
|
87
|
+
total: 1,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
expect(mapped.currencies).toHaveLength(1);
|
|
91
|
+
expect(mapped.currencies[0]?.id).toBe(5);
|
|
92
|
+
});
|
|
93
|
+
|
|
79
94
|
it('toPaymentMethodFlag01 serializes booleans and wire flags', () => {
|
|
80
95
|
expect(toPaymentMethodFlag01(true)).toBe('1');
|
|
81
96
|
expect(toPaymentMethodFlag01(false)).toBe('0');
|
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
asNumber,
|
|
16
16
|
asRecord,
|
|
17
17
|
asString,
|
|
18
|
-
mapArray,
|
|
19
18
|
mapList,
|
|
20
19
|
toFlag01,
|
|
21
20
|
} from '../http/wire';
|
|
@@ -101,7 +100,7 @@ export function mapPaymentMethod(raw: unknown): PaymentMethodModel {
|
|
|
101
100
|
deleted_at: asNullableString(record['deleted_at'] ?? record['deletedAt']),
|
|
102
101
|
created_at: asNullableString(record['created_at'] ?? record['createdAt']),
|
|
103
102
|
updated_at: asNullableString(record['updated_at'] ?? record['updatedAt']),
|
|
104
|
-
currencies:
|
|
103
|
+
currencies: mapList(record['currencies'], mapPaymentMethodCurrency),
|
|
105
104
|
};
|
|
106
105
|
}
|
|
107
106
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@africanies/africanies-theme",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/common": "^22.0.0",
|
|
6
6
|
"@angular/core": "^22.0.0",
|
|
7
|
-
"@africanies/africanies-core": "
|
|
8
|
-
"@africanies/africanies-storage": "
|
|
7
|
+
"@africanies/africanies-core": ">=0.0.2 <0.1.0",
|
|
8
|
+
"@africanies/africanies-storage": ">=0.0.1 <0.1.0"
|
|
9
9
|
},
|
|
10
10
|
"sideEffects": false,
|
|
11
11
|
"publishConfig": {
|
|
@@ -11,10 +11,12 @@
|
|
|
11
11
|
* SFN (export / green):
|
|
12
12
|
* text-export bg-export bg-export-subtle bg-export-light border-export
|
|
13
13
|
* hover:bg-export-light hover:bg-export-subtle dark:bg-export/15 dark:hover:bg-export/15
|
|
14
|
+
* dark:bg-[color-mix(in_srgb,#1cbd5d_15%,#212529)]
|
|
14
15
|
*
|
|
15
16
|
* STN (import / orange):
|
|
16
17
|
* text-import bg-import bg-import-subtle bg-import-light border-import
|
|
17
18
|
* hover:bg-import-light hover:bg-import-subtle dark:bg-import/15 dark:hover:bg-import/15
|
|
19
|
+
* dark:bg-[color-mix(in_srgb,#f08829_15%,#212529)]
|
|
18
20
|
*/
|
|
19
21
|
export const MODE_COLOR_SAFELIST = [
|
|
20
22
|
'text-export',
|
|
@@ -26,6 +28,7 @@ export const MODE_COLOR_SAFELIST = [
|
|
|
26
28
|
'hover:bg-export-subtle',
|
|
27
29
|
'dark:bg-export/15',
|
|
28
30
|
'dark:hover:bg-export/15',
|
|
31
|
+
'dark:bg-[color-mix(in_srgb,#1cbd5d_15%,#212529)]',
|
|
29
32
|
'text-import',
|
|
30
33
|
'bg-import',
|
|
31
34
|
'bg-import-subtle',
|
|
@@ -35,4 +38,5 @@ export const MODE_COLOR_SAFELIST = [
|
|
|
35
38
|
'hover:bg-import-subtle',
|
|
36
39
|
'dark:bg-import/15',
|
|
37
40
|
'dark:hover:bg-import/15',
|
|
41
|
+
'dark:bg-[color-mix(in_srgb,#f08829_15%,#212529)]',
|
|
38
42
|
] as const;
|
|
@@ -29,8 +29,15 @@ export interface ModeColorClasses {
|
|
|
29
29
|
ghostPrimary: string;
|
|
30
30
|
/**
|
|
31
31
|
* Soft highlight for selected / active rows (works in dark mode).
|
|
32
|
+
* Dark uses a translucent tint — fine over solid surfaces, not for
|
|
33
|
+
* sticky overlays (see {@link softSolid}).
|
|
32
34
|
*/
|
|
33
35
|
soft: string;
|
|
36
|
+
/**
|
|
37
|
+
* Opaque soft fill — same tint as {@link soft}, but dark mode mixes into
|
|
38
|
+
* ink so scrolled content cannot show through (sticky table headers/cells).
|
|
39
|
+
*/
|
|
40
|
+
softSolid: string;
|
|
34
41
|
/**
|
|
35
42
|
* Soft hover highlight for menus and lists.
|
|
36
43
|
*/
|
|
@@ -74,6 +81,8 @@ export class ModeColorService {
|
|
|
74
81
|
ghostPrimary:
|
|
75
82
|
'bg-transparent text-export border-transparent hover:bg-export-subtle dark:hover:bg-export/15',
|
|
76
83
|
soft: 'bg-export-subtle dark:bg-export/15',
|
|
84
|
+
softSolid:
|
|
85
|
+
'bg-export-subtle dark:bg-[color-mix(in_srgb,#1cbd5d_15%,#212529)]',
|
|
77
86
|
softHover: 'hover:bg-export-subtle dark:hover:bg-export/15',
|
|
78
87
|
};
|
|
79
88
|
}
|
|
@@ -87,6 +96,8 @@ export class ModeColorService {
|
|
|
87
96
|
ghostPrimary:
|
|
88
97
|
'bg-transparent text-import border-transparent hover:bg-import-subtle dark:hover:bg-import/15',
|
|
89
98
|
soft: 'bg-import-subtle dark:bg-import/15',
|
|
99
|
+
softSolid:
|
|
100
|
+
'bg-import-subtle dark:bg-[color-mix(in_srgb,#f08829_15%,#212529)]',
|
|
90
101
|
softHover: 'hover:bg-import-subtle dark:hover:bg-import/15',
|
|
91
102
|
};
|
|
92
103
|
});
|
|
@@ -69,6 +69,11 @@ function africaniesInteractiveCursorPlugin({ addBase }) {
|
|
|
69
69
|
* (`white` / `ink-950`) and `-webkit-text-fill-color` keeps body text on
|
|
70
70
|
* `ink` / white. `.dark` matches `ThemeService` (`class` on `<html>`).
|
|
71
71
|
*
|
|
72
|
+
* WHY one selector per `addBase` key: joining autofill selectors with commas
|
|
73
|
+
* under a single `.dark ${list}` key only scopes the first selector — the rest
|
|
74
|
+
* leak into light mode. WHY no `color` in the long transition: delaying color
|
|
75
|
+
* freezes text when the user toggles light/dark.
|
|
76
|
+
*
|
|
72
77
|
* @param {import('tailwindcss/types/config').PluginAPI} api
|
|
73
78
|
*/
|
|
74
79
|
function africaniesAutofillPlugin({ addBase }) {
|
|
@@ -81,21 +86,24 @@ function africaniesAutofillPlugin({ addBase }) {
|
|
|
81
86
|
'textarea:-webkit-autofill:hover',
|
|
82
87
|
'textarea:-webkit-autofill:focus',
|
|
83
88
|
'textarea:-webkit-autofill:active',
|
|
84
|
-
]
|
|
89
|
+
];
|
|
85
90
|
|
|
86
|
-
|
|
87
|
-
|
|
91
|
+
/** @type {Record<string, Record<string, string>>} */
|
|
92
|
+
const rules = {};
|
|
93
|
+
for (const selector of autofillSelectors) {
|
|
94
|
+
rules[selector] = {
|
|
88
95
|
WebkitTextFillColor: '#212529',
|
|
89
96
|
caretColor: '#212529',
|
|
90
97
|
boxShadow: '0 0 0 1000px #ffffff inset',
|
|
91
98
|
transition: 'background-color 99999s ease-in-out 0s',
|
|
92
|
-
}
|
|
93
|
-
[`.dark ${
|
|
99
|
+
};
|
|
100
|
+
rules[`.dark ${selector}`] = {
|
|
94
101
|
WebkitTextFillColor: '#ffffff',
|
|
95
102
|
caretColor: '#ffffff',
|
|
96
103
|
boxShadow: '0 0 0 1000px #272729 inset',
|
|
97
|
-
}
|
|
98
|
-
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
addBase(rules);
|
|
99
107
|
}
|
|
100
108
|
|
|
101
109
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@africanies/africanies-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/common": "^22.0.0",
|
|
6
6
|
"@angular/core": "^22.0.0",
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
"@angular/forms": "^22.0.0",
|
|
9
9
|
"@angular/router": "^22.0.0",
|
|
10
10
|
"rxjs": "^7.8.0",
|
|
11
|
-
"@africanies/africanies-models": "
|
|
12
|
-
"@africanies/africanies-icons": "
|
|
13
|
-
"@africanies/africanies-core": "
|
|
14
|
-
"@africanies/africanies-theme": "
|
|
11
|
+
"@africanies/africanies-models": ">=0.0.2 <0.1.0",
|
|
12
|
+
"@africanies/africanies-icons": ">=0.0.1 <0.1.0",
|
|
13
|
+
"@africanies/africanies-core": ">=0.0.2 <0.1.0",
|
|
14
|
+
"@africanies/africanies-theme": ">=0.0.1 <0.1.0"
|
|
15
15
|
},
|
|
16
16
|
"sideEffects": false,
|
|
17
17
|
"publishConfig": {
|
|
@@ -32,6 +32,12 @@ export {
|
|
|
32
32
|
type LoadingStateMode,
|
|
33
33
|
} from './lib/feedback';
|
|
34
34
|
|
|
35
|
+
// Accordion (expandable bordered panels)
|
|
36
|
+
export {
|
|
37
|
+
AccordionComponent,
|
|
38
|
+
type AccordionSize,
|
|
39
|
+
} from './lib/accordion';
|
|
40
|
+
|
|
35
41
|
// Alert (inline banners — distinct from ErrorState / Toast)
|
|
36
42
|
export { AlertComponent, type AlertVariant } from './lib/alert';
|
|
37
43
|
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChangeDetectionStrategy,
|
|
3
|
+
Component,
|
|
4
|
+
computed,
|
|
5
|
+
input,
|
|
6
|
+
model,
|
|
7
|
+
} from '@angular/core';
|
|
8
|
+
|
|
9
|
+
import { AfricaniesIconComponent } from '@africanies/africanies-icons';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Visual density for {@link AccordionComponent}.
|
|
13
|
+
*
|
|
14
|
+
* - `md` — page sections (pay review, top-level cards)
|
|
15
|
+
* - `sm` — nested panels (e.g. export boxes inside a manifest box)
|
|
16
|
+
*/
|
|
17
|
+
export type AccordionSize = 'md' | 'sm';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Bordered expandable panel with animated fold — the pattern used on
|
|
21
|
+
* Manifest detail and Make Payment review.
|
|
22
|
+
*
|
|
23
|
+
* Parent owns open state via {@link open} (`model()` / `[(open)]`).
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```html
|
|
27
|
+
* <africanies-accordion
|
|
28
|
+
* title="Customer Information"
|
|
29
|
+
* [open]="isOpen('customer')"
|
|
30
|
+
* (openChange)="onOpenChange('customer', $event)"
|
|
31
|
+
* >
|
|
32
|
+
* <dl>…</dl>
|
|
33
|
+
* </africanies-accordion>
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
@Component({
|
|
37
|
+
selector: 'africanies-accordion',
|
|
38
|
+
standalone: true,
|
|
39
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
40
|
+
imports: [AfricaniesIconComponent],
|
|
41
|
+
host: {
|
|
42
|
+
class: 'block',
|
|
43
|
+
},
|
|
44
|
+
styles: `
|
|
45
|
+
.africanies-accordion-fold {
|
|
46
|
+
display: grid;
|
|
47
|
+
grid-template-rows: 0fr;
|
|
48
|
+
transition: grid-template-rows 200ms ease;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.africanies-accordion-fold-open {
|
|
52
|
+
grid-template-rows: 1fr;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.africanies-accordion-fold-body {
|
|
56
|
+
min-height: 0;
|
|
57
|
+
overflow: hidden;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@media (prefers-reduced-motion: reduce) {
|
|
61
|
+
.africanies-accordion-fold {
|
|
62
|
+
transition: none;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
`,
|
|
66
|
+
template: `
|
|
67
|
+
<div [class]="shellClass()">
|
|
68
|
+
<button
|
|
69
|
+
type="button"
|
|
70
|
+
[class]="triggerClass()"
|
|
71
|
+
[attr.aria-expanded]="open()"
|
|
72
|
+
(click)="toggle()"
|
|
73
|
+
>
|
|
74
|
+
<span class="min-w-0 flex-1 font-medium">
|
|
75
|
+
<ng-content select="[africaniesAccordionTitle]" />
|
|
76
|
+
@if (title()) {
|
|
77
|
+
{{ title() }}
|
|
78
|
+
}
|
|
79
|
+
</span>
|
|
80
|
+
<africanies-icon
|
|
81
|
+
name="chevron-down"
|
|
82
|
+
class="shrink-0 transition-transform duration-200"
|
|
83
|
+
[class.rotate-180]="open()"
|
|
84
|
+
[size]="chevronSize()"
|
|
85
|
+
/>
|
|
86
|
+
</button>
|
|
87
|
+
<div
|
|
88
|
+
class="africanies-accordion-fold"
|
|
89
|
+
[class.africanies-accordion-fold-open]="open()"
|
|
90
|
+
>
|
|
91
|
+
<div class="africanies-accordion-fold-body">
|
|
92
|
+
<div [class]="bodyClass()">
|
|
93
|
+
<ng-content />
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
`,
|
|
99
|
+
})
|
|
100
|
+
export class AccordionComponent {
|
|
101
|
+
/** Plain-text header. Prefer projected `[africaniesAccordionTitle]` for rich titles. */
|
|
102
|
+
readonly title = input('');
|
|
103
|
+
|
|
104
|
+
/** Whether the panel body is expanded. */
|
|
105
|
+
readonly open = model(false);
|
|
106
|
+
|
|
107
|
+
/** Padding / chevron density. */
|
|
108
|
+
readonly size = input<AccordionSize>('md');
|
|
109
|
+
|
|
110
|
+
protected readonly chevronSize = computed(() =>
|
|
111
|
+
this.size() === 'sm' ? 14 : 16,
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
protected readonly shellClass = computed(() =>
|
|
115
|
+
this.size() === 'sm'
|
|
116
|
+
? 'rounded-lg border border-border dark:border-white/10'
|
|
117
|
+
: 'rounded-xl border border-border dark:border-white/10',
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
protected readonly triggerClass = computed(() =>
|
|
121
|
+
this.size() === 'sm'
|
|
122
|
+
? 'flex w-full items-center justify-between gap-3 px-3 py-2 text-left text-ink dark:text-white'
|
|
123
|
+
: 'flex w-full items-center justify-between gap-3 px-4 py-3 text-left text-ink dark:text-white',
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
protected readonly bodyClass = computed(() =>
|
|
127
|
+
this.size() === 'sm'
|
|
128
|
+
? 'border-t border-border px-3 py-2 dark:border-white/10'
|
|
129
|
+
: 'border-t border-border px-4 py-3 dark:border-white/10',
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
protected toggle(): void {
|
|
133
|
+
this.open.update((value) => !value);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -10,14 +10,21 @@ import {
|
|
|
10
10
|
computed,
|
|
11
11
|
contentChild,
|
|
12
12
|
ElementRef,
|
|
13
|
+
inject,
|
|
13
14
|
input,
|
|
14
15
|
signal,
|
|
15
16
|
viewChild,
|
|
16
17
|
} from '@angular/core';
|
|
18
|
+
import { Router } from '@angular/router';
|
|
17
19
|
|
|
18
20
|
import { AfricaniesIconComponent } from '@africanies/africanies-icons';
|
|
19
21
|
|
|
20
22
|
import { ButtonComponent } from '../button/button.component';
|
|
23
|
+
import {
|
|
24
|
+
isModifiedClick,
|
|
25
|
+
navigateNavItem,
|
|
26
|
+
navItemHref,
|
|
27
|
+
} from '../navigation/navigate-nav-item';
|
|
21
28
|
import { ActionMenuTriggerDirective } from './action-menu-trigger.directive';
|
|
22
29
|
import type { AfricaniesMenuItem } from './menu-item';
|
|
23
30
|
|
|
@@ -53,6 +60,9 @@ const MENU_PANEL_POSITIONS: ConnectedPosition[] = [
|
|
|
53
60
|
* clipped by table `overflow`. Default trigger is a ghost ellipsis button;
|
|
54
61
|
* project a custom control with {@link ActionMenuTriggerDirective}.
|
|
55
62
|
*
|
|
63
|
+
* Items with {@link AfricaniesMenuItem.routerLink} render as anchors so users
|
|
64
|
+
* can right-click / modified-click to open in a new tab.
|
|
65
|
+
*
|
|
56
66
|
* @example
|
|
57
67
|
* ```html
|
|
58
68
|
* <!-- Default icon trigger (table row) -->
|
|
@@ -68,7 +78,12 @@ const MENU_PANEL_POSITIONS: ConnectedPosition[] = [
|
|
|
68
78
|
* ```ts
|
|
69
79
|
* rowActions(row: Shipment): AfricaniesMenuItem[] {
|
|
70
80
|
* return [
|
|
71
|
-
* {
|
|
81
|
+
* {
|
|
82
|
+
* label: 'Open',
|
|
83
|
+
* icon: 'eye',
|
|
84
|
+
* routerLink: ['/shipments', row.id],
|
|
85
|
+
* onClick: () => this.open(row),
|
|
86
|
+
* },
|
|
72
87
|
* { label: 'Edit', icon: 'edit', onClick: () => this.edit(row) },
|
|
73
88
|
* {
|
|
74
89
|
* label: 'Delete',
|
|
@@ -156,26 +171,49 @@ const MENU_PANEL_POSITIONS: ConnectedPosition[] = [
|
|
|
156
171
|
role="separator"
|
|
157
172
|
></div>
|
|
158
173
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
174
|
+
@if (item.routerLink !== null && item.routerLink !== undefined) {
|
|
175
|
+
<a
|
|
176
|
+
role="menuitem"
|
|
177
|
+
[id]="itemDomId(i)"
|
|
178
|
+
[class]="itemClass(item, i)"
|
|
179
|
+
[attr.href]="item.disabled ? null : hrefFor(item)"
|
|
180
|
+
[attr.aria-disabled]="item.disabled ? true : null"
|
|
181
|
+
(click)="onRoutedItemClick($event, item)"
|
|
182
|
+
(mouseenter)="activeIndex.set(i)"
|
|
183
|
+
>
|
|
184
|
+
@if (item.icon; as icon) {
|
|
185
|
+
<africanies-icon [name]="icon" [size]="16" class="shrink-0" />
|
|
186
|
+
}
|
|
187
|
+
<span class="min-w-0 flex-1 truncate text-left">{{
|
|
188
|
+
item.label
|
|
189
|
+
}}</span>
|
|
190
|
+
</a>
|
|
191
|
+
} @else {
|
|
192
|
+
<button
|
|
193
|
+
type="button"
|
|
194
|
+
role="menuitem"
|
|
195
|
+
[id]="itemDomId(i)"
|
|
196
|
+
[class]="itemClass(item, i)"
|
|
197
|
+
[disabled]="!!item.disabled"
|
|
198
|
+
(click)="selectItem(item)"
|
|
199
|
+
(mouseenter)="activeIndex.set(i)"
|
|
200
|
+
>
|
|
201
|
+
@if (item.icon; as icon) {
|
|
202
|
+
<africanies-icon [name]="icon" [size]="16" class="shrink-0" />
|
|
203
|
+
}
|
|
204
|
+
<span class="min-w-0 flex-1 truncate text-left">{{
|
|
205
|
+
item.label
|
|
206
|
+
}}</span>
|
|
207
|
+
</button>
|
|
208
|
+
}
|
|
173
209
|
}
|
|
174
210
|
</div>
|
|
175
211
|
</ng-template>
|
|
176
212
|
`,
|
|
177
213
|
})
|
|
178
214
|
export class ActionMenuComponent {
|
|
215
|
+
private readonly router = inject(Router);
|
|
216
|
+
|
|
179
217
|
protected readonly panelPositions = MENU_PANEL_POSITIONS;
|
|
180
218
|
|
|
181
219
|
private readonly panelRef = viewChild<ElementRef<HTMLElement>>('panel');
|
|
@@ -206,7 +244,7 @@ export class ActionMenuComponent {
|
|
|
206
244
|
protected itemClass(item: AfricaniesMenuItem, index: number): string {
|
|
207
245
|
const active = this.activeIndex() === index;
|
|
208
246
|
const base =
|
|
209
|
-
'flex w-full cursor-pointer items-center gap-2 px-3 py-2 text-body-sm transition-colors ' +
|
|
247
|
+
'flex w-full cursor-pointer items-center gap-2 px-3 py-2 text-body-sm no-underline transition-colors ' +
|
|
210
248
|
'disabled:cursor-not-allowed disabled:opacity-50 ' +
|
|
211
249
|
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ink';
|
|
212
250
|
if (item.danger) {
|
|
@@ -225,6 +263,10 @@ export class ActionMenuComponent {
|
|
|
225
263
|
);
|
|
226
264
|
}
|
|
227
265
|
|
|
266
|
+
protected hrefFor(item: AfricaniesMenuItem): string | null {
|
|
267
|
+
return navItemHref(this.router, item);
|
|
268
|
+
}
|
|
269
|
+
|
|
228
270
|
protected onTriggerClick(event: MouseEvent): void {
|
|
229
271
|
event.preventDefault();
|
|
230
272
|
event.stopPropagation();
|
|
@@ -304,11 +346,36 @@ export class ActionMenuComponent {
|
|
|
304
346
|
this.open.set(false);
|
|
305
347
|
}
|
|
306
348
|
|
|
349
|
+
/**
|
|
350
|
+
* Primary click on a routed item: in-app activate via {@link onClick} or
|
|
351
|
+
* router. Modified clicks keep native link behaviour (new tab).
|
|
352
|
+
*/
|
|
353
|
+
protected onRoutedItemClick(event: MouseEvent, item: AfricaniesMenuItem): void {
|
|
354
|
+
if (item.disabled) {
|
|
355
|
+
event.preventDefault();
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
if (isModifiedClick(event)) {
|
|
359
|
+
this.close();
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
event.preventDefault();
|
|
363
|
+
this.activateItem(item);
|
|
364
|
+
}
|
|
365
|
+
|
|
307
366
|
protected selectItem(item: AfricaniesMenuItem): void {
|
|
308
367
|
if (item.disabled) {
|
|
309
368
|
return;
|
|
310
369
|
}
|
|
311
|
-
|
|
370
|
+
this.activateItem(item);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
private activateItem(item: AfricaniesMenuItem): void {
|
|
374
|
+
if (item.onClick) {
|
|
375
|
+
item.onClick();
|
|
376
|
+
} else if (item.routerLink != null) {
|
|
377
|
+
void navigateNavItem(this.router, item, false);
|
|
378
|
+
}
|
|
312
379
|
this.close();
|
|
313
380
|
}
|
|
314
381
|
|
|
@@ -2,14 +2,31 @@ import type { IconName } from '@africanies/africanies-icons';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Option row for {@link ActionMenuComponent}.
|
|
5
|
+
*
|
|
6
|
+
* Set optional {@link routerLink} (and `queryParams` / `fragment`) so the row
|
|
7
|
+
* renders as an `<a href>` — right-click / ⌘-click can open in a new tab.
|
|
8
|
+
* Primary click still runs {@link onClick} when provided; otherwise the menu
|
|
9
|
+
* navigates via the router (same pattern as tabs / segment).
|
|
5
10
|
*/
|
|
6
11
|
export interface AfricaniesMenuItem {
|
|
7
12
|
/** Visible label. */
|
|
8
13
|
label: string;
|
|
9
|
-
/**
|
|
10
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Invoked on primary activation (then the menu closes).
|
|
16
|
+
* Optional when {@link routerLink} is set — the menu navigates instead.
|
|
17
|
+
*/
|
|
18
|
+
onClick?: () => void;
|
|
11
19
|
/** Optional leading icon from `@africanies/africanies-icons`. */
|
|
12
20
|
icon?: IconName;
|
|
21
|
+
/**
|
|
22
|
+
* Optional Angular router link (`string` or commands array).
|
|
23
|
+
* When set, the row is an `<a>` with a real `href` for open-in-new-tab.
|
|
24
|
+
*/
|
|
25
|
+
routerLink?: string | readonly unknown[];
|
|
26
|
+
/** Optional query params passed with {@link routerLink}. */
|
|
27
|
+
queryParams?: Record<string, unknown>;
|
|
28
|
+
/** Optional URL fragment with {@link routerLink}. */
|
|
29
|
+
fragment?: string;
|
|
13
30
|
/** When true, the item cannot be activated. */
|
|
14
31
|
disabled?: boolean;
|
|
15
32
|
/** Destructive styling (e.g. Delete). */
|