@mk-kit/ui 0.41.0 → 0.42.0
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/README.md +3 -3
- package/fesm2022/mk-kit-ui-core.mjs +87 -0
- package/fesm2022/mk-kit-ui-core.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-data.mjs +368 -13
- package/fesm2022/mk-kit-ui-data.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-datetime.mjs +2 -2
- package/fesm2022/mk-kit-ui-datetime.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-directives.mjs +395 -2
- package/fesm2022/mk-kit-ui-directives.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-dnd.mjs +183 -29
- package/fesm2022/mk-kit-ui-dnd.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-forms.mjs +6 -4
- package/fesm2022/mk-kit-ui-forms.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-table.mjs +26 -6
- package/fesm2022/mk-kit-ui-table.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/mk-kit.css +604 -0
- package/types/mk-kit-ui-core.d.ts +48 -1
- package/types/mk-kit-ui-data.d.ts +158 -3
- package/types/mk-kit-ui-directives.d.ts +234 -3
- package/types/mk-kit-ui-dnd.d.ts +96 -14
- package/types/mk-kit-ui-forms.d.ts +6 -4
- package/types/mk-kit-ui-table.d.ts +38 -4
package/types/mk-kit-ui-dnd.d.ts
CHANGED
|
@@ -11,29 +11,64 @@ import { TemplateRef } from '@angular/core';
|
|
|
11
11
|
* Its look (grab cursor, muted colour, `touch-action: none`) ships as the
|
|
12
12
|
* global `.mk-drag-handle` class in the theme stylesheet.
|
|
13
13
|
*
|
|
14
|
+
* **Decorative grip** — a non-focusable element (`<span>`, `<mk-icon>`): the
|
|
15
|
+
* item itself stays the keyboard target (`role="button"`, focusable), so the
|
|
16
|
+
* grip should be `aria-hidden`:
|
|
17
|
+
*
|
|
14
18
|
* ```html
|
|
15
19
|
* <div mkDrag [mkDragData]="row">
|
|
16
20
|
* <span mkDragHandle aria-hidden="true">⠿</span>
|
|
17
21
|
* {{ row.name }}
|
|
18
22
|
* </div>
|
|
19
23
|
* ```
|
|
24
|
+
*
|
|
25
|
+
* **Focusable grip** — a `<button>` (or any element with `tabindex`): the
|
|
26
|
+
* handle becomes the keyboard target instead. The item is then a plain
|
|
27
|
+
* container (no role, not focusable), so rows may hold inputs, links and
|
|
28
|
+
* other buttons without nesting interactive controls, and `<li>` items keep
|
|
29
|
+
* valid list semantics. Give it an accessible name:
|
|
30
|
+
*
|
|
31
|
+
* ```html
|
|
32
|
+
* <li mkDrag [mkDragData]="row">
|
|
33
|
+
* <button type="button" mkDragHandle [attr.aria-label]="'Reorder ' + row.name">⠿</button>
|
|
34
|
+
* <input mkInput [(ngModel)]="row.name" />
|
|
35
|
+
* </li>
|
|
36
|
+
* ```
|
|
20
37
|
*/
|
|
21
38
|
declare class MkDragHandle {
|
|
22
39
|
/** The handle's host element. */
|
|
23
40
|
readonly element: HTMLElement;
|
|
41
|
+
/**
|
|
42
|
+
* Whether the handle can take keyboard focus itself — a native control
|
|
43
|
+
* (`<button>`, …), a link with `href`, or any element with a `tabindex`.
|
|
44
|
+
* A focusable handle carries the keyboard drag for its `[mkDrag]`.
|
|
45
|
+
*/
|
|
46
|
+
isFocusable(): boolean;
|
|
24
47
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkDragHandle, never>;
|
|
25
48
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MkDragHandle, "[mkDragHandle]", ["mkDragHandle"], {}, {}, never, never, true, never>;
|
|
26
49
|
}
|
|
27
50
|
|
|
28
51
|
/**
|
|
29
52
|
* Makes an item inside a `[mkDropList]` draggable — by pointer (mouse / touch /
|
|
30
|
-
* pen) **and** by keyboard (WCAG 2.1.1).
|
|
31
|
-
*
|
|
32
|
-
*
|
|
53
|
+
* pen) **and** by keyboard (WCAG 2.1.1). Every move is announced via
|
|
54
|
+
* {@link MkLiveAnnouncer}. Which element carries the keyboard interaction
|
|
55
|
+
* depends on the handle:
|
|
56
|
+
*
|
|
57
|
+
* - **No handle, or a decorative one** (`<span mkDragHandle aria-hidden>`):
|
|
58
|
+
* the item itself is focusable and exposes `aria-roledescription="Draggable
|
|
59
|
+
* item"` with `role="button"` — or `role="option"` when it is an `<li>` of a
|
|
60
|
+
* `<ul mkDropList>`, which then becomes a labelled `listbox` (an `<li>` may
|
|
61
|
+
* not take the `button` role).
|
|
62
|
+
* - **A focusable handle** (`<button mkDragHandle aria-label="…">`, or any
|
|
63
|
+
* handle with `tabindex`): the handle is the keyboard target and receives
|
|
64
|
+
* the `aria-roledescription` / `aria-pressed` / `aria-grabbed` state; the
|
|
65
|
+
* item stays a plain container with no role and no `tabindex`, so it can hold
|
|
66
|
+
* inputs, links and buttons of its own (no nested interactive controls) and
|
|
67
|
+
* `<li>` items keep their list semantics.
|
|
33
68
|
*
|
|
34
|
-
* Keyboard: focus
|
|
35
|
-
* keys to move it (crossing into connected lists at the ends /
|
|
36
|
-
* perpendicular axis), **Space/Enter** to drop, **Escape** to cancel.
|
|
69
|
+
* Keyboard: focus the item (or its handle) and press **Space/Enter** to pick
|
|
70
|
+
* it up, **Arrow** keys to move it (crossing into connected lists at the ends /
|
|
71
|
+
* across the perpendicular axis), **Space/Enter** to drop, **Escape** to cancel.
|
|
37
72
|
*
|
|
38
73
|
* Touch: a swipe scrolls the page as usual — the drag only arms after a
|
|
39
74
|
* long-press ({@link mkDragTouchDelay}, default 300 ms). While armed the item
|
|
@@ -46,9 +81,9 @@ declare class MkDragHandle {
|
|
|
46
81
|
* synchronously on release so drops land exactly where the pointer ended.
|
|
47
82
|
*
|
|
48
83
|
* ```html
|
|
49
|
-
* <
|
|
84
|
+
* <div mkDrag [mkDragData]="row" [mkDragDisabled]="row.locked">
|
|
50
85
|
* <span mkDragHandle aria-hidden="true">⠿</span> {{ row.title }}
|
|
51
|
-
* </
|
|
86
|
+
* </div>
|
|
52
87
|
* ```
|
|
53
88
|
*
|
|
54
89
|
* @typeParam T item data type.
|
|
@@ -82,6 +117,20 @@ declare class MkDrag<T = unknown> {
|
|
|
82
117
|
* inner handle would start the outer drag and inner dnd would never work.
|
|
83
118
|
*/
|
|
84
119
|
protected readonly ownHandles: _angular_core.Signal<MkDragHandle[]>;
|
|
120
|
+
/**
|
|
121
|
+
* The handle that carries the keyboard drag — the first of this item's
|
|
122
|
+
* handles that is focusable on its own (a `<button mkDragHandle>`, say).
|
|
123
|
+
* `null` when the item itself is the keyboard target.
|
|
124
|
+
*/
|
|
125
|
+
readonly keyboardHandle: _angular_core.Signal<MkDragHandle | null>;
|
|
126
|
+
/**
|
|
127
|
+
* The role the item itself exposes: `null` when a focusable handle carries
|
|
128
|
+
* the interaction; `option` inside a list that resolved to a `listbox`
|
|
129
|
+
* (`<ul mkDropList>` / `<li mkDrag>`); `button` otherwise.
|
|
130
|
+
*/
|
|
131
|
+
protected readonly itemRole: _angular_core.Signal<"button" | "option" | null>;
|
|
132
|
+
/** The element keyboard events act on: the focusable handle, else the item. */
|
|
133
|
+
private keyboardTarget;
|
|
85
134
|
/** True while a pointer drag is in progress. */
|
|
86
135
|
protected readonly dragging: _angular_core.WritableSignal<boolean>;
|
|
87
136
|
/** True while the item is "picked up" for keyboard movement. */
|
|
@@ -105,6 +154,8 @@ declare class MkDrag<T = unknown> {
|
|
|
105
154
|
private originLeft;
|
|
106
155
|
private originTop;
|
|
107
156
|
private preview;
|
|
157
|
+
constructor();
|
|
158
|
+
private toggleAttr;
|
|
108
159
|
private readonly moveHandler;
|
|
109
160
|
private readonly upHandler;
|
|
110
161
|
private readonly cancelHandler;
|
|
@@ -168,7 +219,7 @@ declare class MkDrag<T = unknown> {
|
|
|
168
219
|
private finishPointer;
|
|
169
220
|
private commitPointer;
|
|
170
221
|
protected onKeyDown(event: Event): void;
|
|
171
|
-
protected
|
|
222
|
+
protected onFocusOut(event: Event): void;
|
|
172
223
|
private pickUp;
|
|
173
224
|
private stepPrimary;
|
|
174
225
|
private stepList;
|
|
@@ -228,14 +279,29 @@ declare class MkDrag<T = unknown> {
|
|
|
228
279
|
* The array bound to `mkDropListData` is **not** mutated for you — handle
|
|
229
280
|
* `mkDropListDropped` and call {@link mkMoveItemInArray} / {@link mkTransferArrayItem}.
|
|
230
281
|
*
|
|
282
|
+
* Semantics follow the host element and its items, so the tree is always
|
|
283
|
+
* valid ARIA:
|
|
284
|
+
*
|
|
285
|
+
* - any host other than `<ul>`/`<ol>` is a `role="group"` (named by
|
|
286
|
+
* `mkDropListLabel`) of `role="button"` items;
|
|
287
|
+
* - a `<ul>`/`<ol>` whose `<li mkDrag>` items all carry a *focusable*
|
|
288
|
+
* `[mkDragHandle]` stays a plain list — the handles are the controls;
|
|
289
|
+
* - a `<ul>`/`<ol>` whose items are themselves the keyboard targets becomes a
|
|
290
|
+
* `listbox` of `option`s (an `<li>` may not be a `button`); give it a
|
|
291
|
+
* `mkDropListLabel`, listboxes need a name.
|
|
292
|
+
*
|
|
293
|
+
* A `role` you set in the template is kept, and `aria-orientation` is only
|
|
294
|
+
* exposed on roles that allow it (`listbox`, `toolbar`, `tree`, …) — the
|
|
295
|
+
* keyboard model handles both axes regardless.
|
|
296
|
+
*
|
|
231
297
|
* ```html
|
|
232
|
-
* <
|
|
233
|
-
*
|
|
234
|
-
*
|
|
298
|
+
* <div mkDropList [mkDropListData]="todo()" mkDropListLabel="To do"
|
|
299
|
+
* mkDropListId="todo" [mkDropListConnectedTo]="['done']"
|
|
300
|
+
* (mkDropListDropped)="drop($event)">
|
|
235
301
|
* @for (t of todo(); track t.id) {
|
|
236
|
-
* <
|
|
302
|
+
* <div mkDrag [mkDragData]="t">{{ t.title }}</div>
|
|
237
303
|
* }
|
|
238
|
-
* </
|
|
304
|
+
* </div>
|
|
239
305
|
* ```
|
|
240
306
|
*
|
|
241
307
|
* @typeParam T item data type.
|
|
@@ -268,6 +334,22 @@ declare class MkDropList<T = unknown> {
|
|
|
268
334
|
private readonly autoId;
|
|
269
335
|
/** Announceable name: the label when set, otherwise the resolved id. */
|
|
270
336
|
readonly label: _angular_core.Signal<string>;
|
|
337
|
+
/** A `role` written in the template — always kept. */
|
|
338
|
+
private readonly explicitRole;
|
|
339
|
+
private readonly isNativeList;
|
|
340
|
+
/**
|
|
341
|
+
* The role the host exposes. One set in the template wins. A `<ul>`/`<ol>`
|
|
342
|
+
* keeps its implicit `list` role (`null` — nothing is written) while every
|
|
343
|
+
* item hands the keyboard drag to a focusable handle, and becomes a
|
|
344
|
+
* `listbox` (its items `option`s) otherwise. Any other element is a `group`.
|
|
345
|
+
*/
|
|
346
|
+
readonly role: _angular_core.Signal<string | null>;
|
|
347
|
+
/** Whether `aria-orientation` is valid on the effective role. */
|
|
348
|
+
protected readonly orientationAllowed: _angular_core.Signal<boolean>;
|
|
349
|
+
/** A static `aria-label` written in the template, kept when no label input is set. */
|
|
350
|
+
private readonly staticAriaLabel;
|
|
351
|
+
/** Accessible name of the list: `mkDropListLabel`, else the template's own. */
|
|
352
|
+
protected readonly ariaLabel: _angular_core.Signal<string | null>;
|
|
271
353
|
/** Connected-list ids, normalised to a plain array. */
|
|
272
354
|
readonly connectedTo: _angular_core.Signal<readonly string[]>;
|
|
273
355
|
/** The `mkDrag` items projected into this list, in DOM order. */
|
|
@@ -1681,10 +1681,12 @@ declare class MkRepeaterEmpty {
|
|
|
1681
1681
|
*
|
|
1682
1682
|
* With `reorderable`, each row gets a drag handle wired through the dnd
|
|
1683
1683
|
* module's touch-safe handle-based configuration (a swipe on the row body
|
|
1684
|
-
* still scrolls the page).
|
|
1685
|
-
*
|
|
1686
|
-
*
|
|
1687
|
-
*
|
|
1684
|
+
* still scrolls the page). The handle button is the only control the dnd
|
|
1685
|
+
* layer adds — rows stay plain list items, so the inputs and buttons inside
|
|
1686
|
+
* them are never nested in an interactive role. Reordering also works by
|
|
1687
|
+
* keyboard: focus the handle and press Space/Enter to pick up, arrows to
|
|
1688
|
+
* move, Space/Enter to drop, Escape to cancel. Each completed reorder is
|
|
1689
|
+
* announced via {@link MkLiveAnnouncer}.
|
|
1688
1690
|
*
|
|
1689
1691
|
* ```html
|
|
1690
1692
|
* <mk-repeater [(items)]="rows" [min]="1" [max]="10" reorderable
|
|
@@ -178,12 +178,29 @@ interface MkGroupToggle {
|
|
|
178
178
|
/** Whether the group is now collapsed. */
|
|
179
179
|
collapsed: boolean;
|
|
180
180
|
}
|
|
181
|
-
/** Options for {@link MkTable.
|
|
182
|
-
interface
|
|
181
|
+
/** Options for {@link MkTable.getExportRows} — which rows and columns to export. */
|
|
182
|
+
interface MkTableExportRowsOptions {
|
|
183
183
|
/** Export only the selected rows (default: every row). */
|
|
184
184
|
selectedOnly?: boolean;
|
|
185
185
|
/** Restrict to these column keys, in table order (default: every column). */
|
|
186
186
|
columns?: readonly string[];
|
|
187
|
+
}
|
|
188
|
+
/** What {@link MkTable.getExportRows} returns: the rows and the columns to write them with. */
|
|
189
|
+
interface MkTableExportRows<T> {
|
|
190
|
+
/**
|
|
191
|
+
* The rows in display order — sorted the way they are shown, tree children
|
|
192
|
+
* flattened under their parent (expanded or not), selection applied when
|
|
193
|
+
* `selectedOnly` was set.
|
|
194
|
+
*/
|
|
195
|
+
rows: T[];
|
|
196
|
+
/**
|
|
197
|
+
* The columns in the table's current (user-reordered) order, restricted to
|
|
198
|
+
* the requested keys, each with its header and formatter.
|
|
199
|
+
*/
|
|
200
|
+
columns: MkCsvColumn<T>[];
|
|
201
|
+
}
|
|
202
|
+
/** Options for {@link MkTable.exportCsv}. */
|
|
203
|
+
interface MkTableExportOptions extends MkCsvExportOptions, MkTableExportRowsOptions {
|
|
187
204
|
/** Start the browser download (default `true`); `false` just returns the text. */
|
|
188
205
|
download?: boolean;
|
|
189
206
|
}
|
|
@@ -498,11 +515,28 @@ declare class MkTable<T = Record<string, unknown>> {
|
|
|
498
515
|
expandAllRows(): void;
|
|
499
516
|
/** Collapse every parent row (tree mode). */
|
|
500
517
|
collapseAllRows(): void;
|
|
518
|
+
/**
|
|
519
|
+
* The rows and columns an export writes — exactly what {@link exportCsv}
|
|
520
|
+
* serialises, for other formats (XLSX, PDF, the clipboard, …): rows in
|
|
521
|
+
* display order with the current sort applied and tree children
|
|
522
|
+
* (`childrenKey`) flattened under their parent whether or not they are
|
|
523
|
+
* expanded, optionally only the selected ones; columns in the table's
|
|
524
|
+
* current order, restricted to `options.columns` when given, each carrying
|
|
525
|
+
* its header and `format` so what the user saw is what gets written.
|
|
526
|
+
*
|
|
527
|
+
* ```ts
|
|
528
|
+
* const { rows, columns } = table.getExportRows({ selectedOnly: true });
|
|
529
|
+
* const sheet = rows.map((row) =>
|
|
530
|
+
* Object.fromEntries(columns.map((c) => [c.header ?? c.key, c.format ? c.format(row[c.key], row) : row[c.key]])),
|
|
531
|
+
* );
|
|
532
|
+
* ```
|
|
533
|
+
*/
|
|
534
|
+
getExportRows(options?: MkTableExportRowsOptions): MkTableExportRows<T>;
|
|
501
535
|
/**
|
|
502
536
|
* The table's rows as CSV: current column order, column formatters applied,
|
|
503
537
|
* sorted the way they are shown, tree children flattened under their parent
|
|
504
538
|
* whether or not they are expanded. Downloads the file (default name
|
|
505
|
-
* `table.csv`) and returns the text.
|
|
539
|
+
* `table.csv`) and returns the text. Built on {@link getExportRows}.
|
|
506
540
|
*/
|
|
507
541
|
exportCsv(options?: MkTableExportOptions): string;
|
|
508
542
|
private setTreeExpanded;
|
|
@@ -876,4 +910,4 @@ declare class MkTableDataSource<T> {
|
|
|
876
910
|
}
|
|
877
911
|
|
|
878
912
|
export { MkSort, MkSortHeader, MkTable, MkTableCell, MkTableDataSource, MkTableRowDetail, mkDownloadText, mkExportCsv, mkToCsv };
|
|
879
|
-
export type { MkCellEdit, MkColumnResize, MkCsvColumn, MkCsvExportOptions, MkCsvOptions, MkDataFetcher, MkDataPage, MkDataRequest, MkGroupToggle, MkSortChange, MkSortDirection, MkSortState, MkSortable, MkTableAlign, MkTableCellContext, MkTableColumn, MkTableDataSourceOptions, MkTableDensity, MkTableExportOptions, MkTableGroup, MkTreeToggle };
|
|
913
|
+
export type { MkCellEdit, MkColumnResize, MkCsvColumn, MkCsvExportOptions, MkCsvOptions, MkDataFetcher, MkDataPage, MkDataRequest, MkGroupToggle, MkSortChange, MkSortDirection, MkSortState, MkSortable, MkTableAlign, MkTableCellContext, MkTableColumn, MkTableDataSourceOptions, MkTableDensity, MkTableExportOptions, MkTableExportRows, MkTableExportRowsOptions, MkTableGroup, MkTreeToggle };
|