@mesgflow/ui-kit 0.6.0 → 0.8.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 +56 -5
- package/fesm2022/mesgflow-ui-kit-accordion.mjs +9 -8
- package/fesm2022/mesgflow-ui-kit-accordion.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-agenda.mjs +208 -0
- package/fesm2022/mesgflow-ui-kit-agenda.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-alert.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-aspect-ratio.mjs +37 -0
- package/fesm2022/mesgflow-ui-kit-aspect-ratio.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-avatar-group.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-avatar.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-badge.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-banner.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-blocks.mjs +207 -0
- package/fesm2022/mesgflow-ui-kit-blocks.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-box-input.mjs +4 -4
- package/fesm2022/mesgflow-ui-kit-box-input.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-brand.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-breadcrumb.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-button-group.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-button.mjs +190 -244
- package/fesm2022/mesgflow-ui-kit-button.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-card.mjs +48 -27
- package/fesm2022/mesgflow-ui-kit-card.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-carousel.mjs +308 -0
- package/fesm2022/mesgflow-ui-kit-carousel.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-chart.mjs +12 -12
- package/fesm2022/mesgflow-ui-kit-checkbox.mjs +18 -23
- package/fesm2022/mesgflow-ui-kit-checkbox.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-chip.mjs +5 -5
- package/fesm2022/mesgflow-ui-kit-chip.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-code-block.mjs +11 -7
- package/fesm2022/mesgflow-ui-kit-code-block.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-collapsible.mjs +9 -9
- package/fesm2022/mesgflow-ui-kit-color-picker.mjs +9 -7
- package/fesm2022/mesgflow-ui-kit-color-picker.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-combobox.mjs +147 -67
- package/fesm2022/mesgflow-ui-kit-combobox.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-command.mjs +15 -16
- package/fesm2022/mesgflow-ui-kit-command.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-context-menu.mjs +7 -9
- package/fesm2022/mesgflow-ui-kit-context-menu.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-copy-button.mjs +6 -6
- package/fesm2022/mesgflow-ui-kit-core.mjs +446 -128
- package/fesm2022/mesgflow-ui-kit-core.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-countdown.mjs +149 -0
- package/fesm2022/mesgflow-ui-kit-countdown.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-date-picker.mjs +140 -19
- package/fesm2022/mesgflow-ui-kit-date-picker.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-description-list.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-dialog.mjs +310 -64
- package/fesm2022/mesgflow-ui-kit-dialog.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-divider.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-drawer.mjs +109 -0
- package/fesm2022/mesgflow-ui-kit-drawer.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-dropzone.mjs +6 -6
- package/fesm2022/mesgflow-ui-kit-dropzone.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-empty-state.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-field.mjs +55 -14
- package/fesm2022/mesgflow-ui-kit-field.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-file-upload.mjs +356 -0
- package/fesm2022/mesgflow-ui-kit-file-upload.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-hover-card.mjs +6 -6
- package/fesm2022/mesgflow-ui-kit-i18n-tr.mjs +135 -0
- package/fesm2022/mesgflow-ui-kit-i18n-tr.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-icon.mjs +8 -3
- package/fesm2022/mesgflow-ui-kit-icon.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-icons-lucide.mjs +371 -0
- package/fesm2022/mesgflow-ui-kit-icons-lucide.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-inline-edit.mjs +279 -0
- package/fesm2022/mesgflow-ui-kit-inline-edit.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-input.mjs +162 -19
- package/fesm2022/mesgflow-ui-kit-input.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-kbd.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-lightbox.mjs +299 -0
- package/fesm2022/mesgflow-ui-kit-lightbox.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-link.mjs +5 -5
- package/fesm2022/mesgflow-ui-kit-link.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-listbox.mjs +151 -0
- package/fesm2022/mesgflow-ui-kit-listbox.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-mention.mjs +283 -0
- package/fesm2022/mesgflow-ui-kit-mention.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-menu.mjs +178 -14
- package/fesm2022/mesgflow-ui-kit-menu.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-nav-menu.mjs +276 -0
- package/fesm2022/mesgflow-ui-kit-nav-menu.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-notification-center.mjs +281 -0
- package/fesm2022/mesgflow-ui-kit-notification-center.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-number-input.mjs +9 -6
- package/fesm2022/mesgflow-ui-kit-number-input.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-otp-input.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-page-header.mjs +6 -6
- package/fesm2022/mesgflow-ui-kit-pagination.mjs +7 -6
- package/fesm2022/mesgflow-ui-kit-pagination.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-password-input.mjs +38 -68
- package/fesm2022/mesgflow-ui-kit-password-input.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-popover.mjs +12 -52
- package/fesm2022/mesgflow-ui-kit-popover.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-progress.mjs +164 -23
- package/fesm2022/mesgflow-ui-kit-progress.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-qr-code.mjs +766 -0
- package/fesm2022/mesgflow-ui-kit-qr-code.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-radio.mjs +10 -12
- package/fesm2022/mesgflow-ui-kit-radio.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-rating.mjs +4 -4
- package/fesm2022/mesgflow-ui-kit-rating.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-scroll-area.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-search-input.mjs +11 -7
- package/fesm2022/mesgflow-ui-kit-search-input.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-segmented-control.mjs +15 -11
- package/fesm2022/mesgflow-ui-kit-segmented-control.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-select.mjs +6 -5
- package/fesm2022/mesgflow-ui-kit-select.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-sidebar.mjs +24 -21
- package/fesm2022/mesgflow-ui-kit-sidebar.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-skeleton.mjs +6 -5
- package/fesm2022/mesgflow-ui-kit-skeleton.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-slider.mjs +253 -6
- package/fesm2022/mesgflow-ui-kit-slider.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-sortable.mjs +526 -0
- package/fesm2022/mesgflow-ui-kit-sortable.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-spinner.mjs +44 -15
- package/fesm2022/mesgflow-ui-kit-spinner.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-split-button.mjs +205 -0
- package/fesm2022/mesgflow-ui-kit-split-button.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-splitter.mjs +213 -6
- package/fesm2022/mesgflow-ui-kit-splitter.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-stat-tile.mjs +13 -6
- package/fesm2022/mesgflow-ui-kit-stat-tile.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-stepper.mjs +171 -64
- package/fesm2022/mesgflow-ui-kit-stepper.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-switch.mjs +4 -4
- package/fesm2022/mesgflow-ui-kit-switch.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-table.mjs +34 -28
- package/fesm2022/mesgflow-ui-kit-table.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-tabs.mjs +421 -180
- package/fesm2022/mesgflow-ui-kit-tabs.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-tag-input.mjs +9 -4
- package/fesm2022/mesgflow-ui-kit-tag-input.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-theme-switcher.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-theming.mjs +7 -7
- package/fesm2022/mesgflow-ui-kit-theming.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-time-picker.mjs +6 -6
- package/fesm2022/mesgflow-ui-kit-time-picker.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-timeline.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-toast.mjs +118 -35
- package/fesm2022/mesgflow-ui-kit-toast.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-toggle.mjs +12 -11
- package/fesm2022/mesgflow-ui-kit-toggle.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-toolbar.mjs +13 -11
- package/fesm2022/mesgflow-ui-kit-toolbar.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-tooltip.mjs +76 -53
- package/fesm2022/mesgflow-ui-kit-tooltip.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-tour.mjs +17 -29
- package/fesm2022/mesgflow-ui-kit-tour.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-transfer-list.mjs +288 -0
- package/fesm2022/mesgflow-ui-kit-transfer-list.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-tree-select.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-tree.mjs +4 -4
- package/fesm2022/mesgflow-ui-kit-tree.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-virtual-list.mjs +109 -0
- package/fesm2022/mesgflow-ui-kit-virtual-list.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit.mjs +93 -12836
- package/fesm2022/mesgflow-ui-kit.mjs.map +1 -1
- package/package.json +91 -3
- package/schematics/collection.json +10 -0
- package/schematics/migration.json +10 -0
- package/schematics/migrations/v0-7.cjs +70 -0
- package/schematics/ng-add/index.cjs +234 -0
- package/schematics/ng-add/schema.json +43 -0
- package/tokens/color.css +96 -0
- package/tokens/controls.css +145 -0
- package/tokens/elevation.css +62 -6
- package/tokens/motion.css +304 -66
- package/tokens/radius.css +14 -0
- package/tokens.css +1 -0
- package/tokens.json +1583 -0
- package/types/mesgflow-ui-kit-agenda.d.ts +49 -0
- package/types/mesgflow-ui-kit-aspect-ratio.d.ts +18 -0
- package/types/mesgflow-ui-kit-blocks.d.ts +128 -0
- package/types/mesgflow-ui-kit-button.d.ts +23 -38
- package/types/mesgflow-ui-kit-card.d.ts +26 -16
- package/types/mesgflow-ui-kit-carousel.d.ts +51 -0
- package/types/mesgflow-ui-kit-checkbox.d.ts +8 -5
- package/types/mesgflow-ui-kit-code-block.d.ts +4 -1
- package/types/mesgflow-ui-kit-combobox.d.ts +47 -22
- package/types/mesgflow-ui-kit-command.d.ts +2 -2
- package/types/mesgflow-ui-kit-core.d.ts +279 -21
- package/types/mesgflow-ui-kit-countdown.d.ts +47 -0
- package/types/mesgflow-ui-kit-date-picker.d.ts +31 -1
- package/types/mesgflow-ui-kit-dialog.d.ts +122 -14
- package/types/mesgflow-ui-kit-drawer.d.ts +45 -0
- package/types/mesgflow-ui-kit-field.d.ts +17 -8
- package/types/mesgflow-ui-kit-file-upload.d.ts +64 -0
- package/types/mesgflow-ui-kit-hover-card.d.ts +2 -2
- package/types/mesgflow-ui-kit-icons-lucide.d.ts +27 -0
- package/types/mesgflow-ui-kit-inline-edit.d.ts +42 -0
- package/types/mesgflow-ui-kit-input.d.ts +64 -2
- package/types/mesgflow-ui-kit-lightbox.d.ts +54 -0
- package/types/mesgflow-ui-kit-listbox.d.ts +30 -0
- package/types/mesgflow-ui-kit-mention.d.ts +59 -0
- package/types/mesgflow-ui-kit-menu.d.ts +41 -2
- package/types/mesgflow-ui-kit-nav-menu.d.ts +58 -0
- package/types/mesgflow-ui-kit-notification-center.d.ts +41 -0
- package/types/mesgflow-ui-kit-number-input.d.ts +3 -1
- package/types/mesgflow-ui-kit-password-input.d.ts +35 -5
- package/types/mesgflow-ui-kit-popover.d.ts +13 -5
- package/types/mesgflow-ui-kit-progress.d.ts +33 -12
- package/types/mesgflow-ui-kit-qr-code.d.ts +160 -0
- package/types/mesgflow-ui-kit-radio.d.ts +2 -2
- package/types/mesgflow-ui-kit-search-input.d.ts +3 -1
- package/types/mesgflow-ui-kit-segmented-control.d.ts +4 -0
- package/types/mesgflow-ui-kit-sidebar.d.ts +1 -1
- package/types/mesgflow-ui-kit-slider.d.ts +60 -1
- package/types/mesgflow-ui-kit-sortable.d.ts +103 -0
- package/types/mesgflow-ui-kit-spinner.d.ts +5 -8
- package/types/mesgflow-ui-kit-split-button.d.ts +47 -0
- package/types/mesgflow-ui-kit-splitter.d.ts +64 -1
- package/types/mesgflow-ui-kit-stat-tile.d.ts +3 -0
- package/types/mesgflow-ui-kit-stepper.d.ts +54 -32
- package/types/mesgflow-ui-kit-table.d.ts +2 -0
- package/types/mesgflow-ui-kit-tabs.d.ts +193 -93
- package/types/mesgflow-ui-kit-tag-input.d.ts +3 -1
- package/types/mesgflow-ui-kit-toast.d.ts +48 -22
- package/types/mesgflow-ui-kit-tooltip.d.ts +15 -12
- package/types/mesgflow-ui-kit-transfer-list.d.ts +34 -0
- package/types/mesgflow-ui-kit-virtual-list.d.ts +35 -0
- package/types/mesgflow-ui-kit.d.ts +88 -5444
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
import { LiveAnnouncer } from '@angular/cdk/a11y';
|
|
2
|
+
import { CdkDropList, CdkDrag, CdkDragHandle, CdkDragPlaceholder, CdkDropListGroup } from '@angular/cdk/drag-drop';
|
|
3
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
4
|
+
import * as i0 from '@angular/core';
|
|
5
|
+
import { model, input, booleanAttribute, output, contentChild, TemplateRef, inject, signal, ElementRef, Component } from '@angular/core';
|
|
6
|
+
import { MF_SORTABLE_LABELS, nextId } from '@mesgflow/ui-kit/core';
|
|
7
|
+
import { Icon } from '@mesgflow/ui-kit/icon';
|
|
8
|
+
|
|
9
|
+
/** `'{item} moved to {position}'` gibi şablonları doldurur. */
|
|
10
|
+
function fillTemplate(template, values) {
|
|
11
|
+
return template.replace(/\{(\w+)\}/g, (_, key) => String(values[key] ?? ''));
|
|
12
|
+
}
|
|
13
|
+
/** Diziden bir öğeyi taşır — yeni dizi döner (orijinal değişmez). */
|
|
14
|
+
function moveItem(list, from, to) {
|
|
15
|
+
const next = [...list];
|
|
16
|
+
const [item] = next.splice(from, 1);
|
|
17
|
+
next.splice(Math.max(0, Math.min(next.length, to)), 0, item);
|
|
18
|
+
return next;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* `<mf-sortable-list [(items)]="tasks" [itemLabel]="labelOf">
|
|
23
|
+
* <ng-template let-task>{{ task.title }}</ng-template>
|
|
24
|
+
* </mf-sortable-list>`
|
|
25
|
+
*
|
|
26
|
+
* Sürükle-bırak ile yeniden sıralanan liste — CDK drag-drop üstüne ERİŞİLEBİLİR
|
|
27
|
+
* klavye modu eklenir (CDK'da yok): tutamaca odaklan → Boşluk/Enter ile al →
|
|
28
|
+
* ↑/↓ taşı → Boşluk/Enter bırak · Escape geri al. Her adım `LiveAnnouncer`
|
|
29
|
+
* ile duyurulur (WCAG 2.1.1 — sürükle-bırakın klavye eşdeğeri).
|
|
30
|
+
*
|
|
31
|
+
* `itemLabel`: duyurular ve tutamaç adı için öğenin okunur adı.
|
|
32
|
+
*/
|
|
33
|
+
class SortableList {
|
|
34
|
+
items = model.required(/* @ts-ignore */
|
|
35
|
+
...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
36
|
+
/** Duyurular ve tutamaç adı için okunur ad. */
|
|
37
|
+
itemLabel = input((item) => String(item), /* @ts-ignore */
|
|
38
|
+
...(ngDevMode ? [{ debugName: "itemLabel" }] : /* istanbul ignore next */ []));
|
|
39
|
+
trackBy = input((_, i) => i, /* @ts-ignore */
|
|
40
|
+
...(ngDevMode ? [{ debugName: "trackBy" }] : /* istanbul ignore next */ []));
|
|
41
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
42
|
+
ariaLabel = input('', /* @ts-ignore */
|
|
43
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
44
|
+
moved = output();
|
|
45
|
+
template = contentChild((TemplateRef), /* @ts-ignore */
|
|
46
|
+
...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
|
|
47
|
+
labels = inject(MF_SORTABLE_LABELS);
|
|
48
|
+
hintId = nextId('mf-sortable-hint');
|
|
49
|
+
grabbed = signal(null, /* @ts-ignore */
|
|
50
|
+
...(ngDevMode ? [{ debugName: "grabbed" }] : /* istanbul ignore next */ []));
|
|
51
|
+
announcer = inject(LiveAnnouncer);
|
|
52
|
+
host = inject(ElementRef);
|
|
53
|
+
grabStart = 0;
|
|
54
|
+
handleLabel(item) {
|
|
55
|
+
return fillTemplate(this.labels().dragHandle, { item: this.itemLabel()(item) });
|
|
56
|
+
}
|
|
57
|
+
onDrop(event) {
|
|
58
|
+
if (event.previousIndex === event.currentIndex)
|
|
59
|
+
return;
|
|
60
|
+
this.commit(event.previousIndex, event.currentIndex);
|
|
61
|
+
}
|
|
62
|
+
onKeydown(event, index) {
|
|
63
|
+
const grabbed = this.grabbed();
|
|
64
|
+
const total = this.items().length;
|
|
65
|
+
const say = (template, position) => this.announcer.announce(fillTemplate(template, {
|
|
66
|
+
item: this.itemLabel()(this.items()[position]),
|
|
67
|
+
position: position + 1,
|
|
68
|
+
total,
|
|
69
|
+
}));
|
|
70
|
+
if (event.key === ' ' || event.key === 'Enter') {
|
|
71
|
+
event.preventDefault();
|
|
72
|
+
if (grabbed === null) {
|
|
73
|
+
this.grabStart = index;
|
|
74
|
+
this.grabbed.set(index);
|
|
75
|
+
say(this.labels().grabbed, index);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
this.grabbed.set(null);
|
|
79
|
+
say(this.labels().dropped, grabbed);
|
|
80
|
+
if (grabbed !== this.grabStart)
|
|
81
|
+
this.moved.emit({ previousIndex: this.grabStart, currentIndex: grabbed });
|
|
82
|
+
}
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (grabbed === null)
|
|
86
|
+
return;
|
|
87
|
+
if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
|
|
88
|
+
event.preventDefault();
|
|
89
|
+
const target = grabbed + (event.key === 'ArrowUp' ? -1 : 1);
|
|
90
|
+
if (target < 0 || target >= total)
|
|
91
|
+
return;
|
|
92
|
+
this.items.set(moveItem(this.items(), grabbed, target));
|
|
93
|
+
this.grabbed.set(target);
|
|
94
|
+
say(this.labels().moved, target);
|
|
95
|
+
this.refocus(target);
|
|
96
|
+
}
|
|
97
|
+
else if (event.key === 'Escape') {
|
|
98
|
+
event.preventDefault();
|
|
99
|
+
this.items.set(moveItem(this.items(), grabbed, this.grabStart));
|
|
100
|
+
this.grabbed.set(null);
|
|
101
|
+
say(this.labels().cancelled, this.grabStart);
|
|
102
|
+
this.refocus(this.grabStart);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
cancelOnBlur() {
|
|
106
|
+
// Odak başka yere giderse (Tab) taşıma bitmiş sayılır — yerinde bırakılır.
|
|
107
|
+
queueMicrotask(() => {
|
|
108
|
+
const active = document.activeElement;
|
|
109
|
+
if (!this.host.nativeElement.contains(active))
|
|
110
|
+
this.grabbed.set(null);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
commit(from, to) {
|
|
114
|
+
this.items.set(moveItem(this.items(), from, to));
|
|
115
|
+
this.moved.emit({ previousIndex: from, currentIndex: to });
|
|
116
|
+
}
|
|
117
|
+
/** Taşıma sonrası `@for` DOM'u yeniden sıraladığında odağı taşınan tutamakta tut. */
|
|
118
|
+
refocus(index) {
|
|
119
|
+
queueMicrotask(() => {
|
|
120
|
+
const handles = this.host.nativeElement.querySelectorAll('[cdkDragHandle], .cdk-drag-handle');
|
|
121
|
+
handles[index]?.focus();
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SortableList, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
125
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: SortableList, isStandalone: true, selector: "mf-sortable-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, itemLabel: { classPropertyName: "itemLabel", publicName: "itemLabel", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { items: "itemsChange", moved: "moved" }, host: { classAttribute: "block" }, queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], exportAs: ["mfSortableList"], ngImport: i0, template: `
|
|
126
|
+
<p [id]="hintId" class="sr-only">{{ labels().instructions }}</p>
|
|
127
|
+
<ul
|
|
128
|
+
cdkDropList
|
|
129
|
+
[cdkDropListData]="items()"
|
|
130
|
+
[cdkDropListDisabled]="disabled()"
|
|
131
|
+
(cdkDropListDropped)="onDrop($event)"
|
|
132
|
+
class="m-0 flex list-none flex-col gap-1.5 p-0"
|
|
133
|
+
[attr.aria-label]="ariaLabel() || null"
|
|
134
|
+
>
|
|
135
|
+
@for (item of items(); track trackBy()(item, $index); let i = $index) {
|
|
136
|
+
<li
|
|
137
|
+
cdkDrag
|
|
138
|
+
[cdkDragData]="item"
|
|
139
|
+
class="group/sortable flex items-center gap-2 rounded-lg border border-hairline bg-surface p-2 ps-1 transition-[box-shadow,border-color,translate] duration-fast ease-emphasis"
|
|
140
|
+
[class.border-accent]="grabbed() === i"
|
|
141
|
+
[class.shadow-2]="grabbed() === i"
|
|
142
|
+
[class.-translate-y-px]="grabbed() === i"
|
|
143
|
+
>
|
|
144
|
+
<button
|
|
145
|
+
type="button"
|
|
146
|
+
cdkDragHandle
|
|
147
|
+
class="flex h-7 w-6 shrink-0 cursor-grab items-center justify-center rounded-sm text-fg-subtle outline-none transition-colors hover:bg-state-hover hover:text-fg focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-focus-ring active:cursor-grabbing"
|
|
148
|
+
[attr.aria-label]="handleLabel(item)"
|
|
149
|
+
[attr.aria-describedby]="hintId"
|
|
150
|
+
[attr.aria-pressed]="grabbed() === i"
|
|
151
|
+
[disabled]="disabled()"
|
|
152
|
+
(keydown)="onKeydown($event, i)"
|
|
153
|
+
(blur)="cancelOnBlur()"
|
|
154
|
+
>
|
|
155
|
+
<span mfIcon [size]="16">drag_indicator</span>
|
|
156
|
+
</button>
|
|
157
|
+
<div class="min-w-0 flex-1">
|
|
158
|
+
<ng-container
|
|
159
|
+
[ngTemplateOutlet]="template() ?? null"
|
|
160
|
+
[ngTemplateOutletContext]="{ $implicit: item, index: i }"
|
|
161
|
+
/>
|
|
162
|
+
</div>
|
|
163
|
+
<div
|
|
164
|
+
*cdkDragPlaceholder
|
|
165
|
+
class="h-11 rounded-lg border-2 border-dashed border-accent/40 bg-primary-tint"
|
|
166
|
+
></div>
|
|
167
|
+
</li>
|
|
168
|
+
}
|
|
169
|
+
</ul>
|
|
170
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: Icon, selector: "span[mfIcon]", inputs: ["size", "filled"] }] });
|
|
171
|
+
}
|
|
172
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SortableList, decorators: [{
|
|
173
|
+
type: Component,
|
|
174
|
+
args: [{
|
|
175
|
+
selector: 'mf-sortable-list',
|
|
176
|
+
exportAs: 'mfSortableList',
|
|
177
|
+
imports: [CdkDropList, CdkDrag, CdkDragHandle, CdkDragPlaceholder, NgTemplateOutlet, Icon],
|
|
178
|
+
host: { class: 'block' },
|
|
179
|
+
template: `
|
|
180
|
+
<p [id]="hintId" class="sr-only">{{ labels().instructions }}</p>
|
|
181
|
+
<ul
|
|
182
|
+
cdkDropList
|
|
183
|
+
[cdkDropListData]="items()"
|
|
184
|
+
[cdkDropListDisabled]="disabled()"
|
|
185
|
+
(cdkDropListDropped)="onDrop($event)"
|
|
186
|
+
class="m-0 flex list-none flex-col gap-1.5 p-0"
|
|
187
|
+
[attr.aria-label]="ariaLabel() || null"
|
|
188
|
+
>
|
|
189
|
+
@for (item of items(); track trackBy()(item, $index); let i = $index) {
|
|
190
|
+
<li
|
|
191
|
+
cdkDrag
|
|
192
|
+
[cdkDragData]="item"
|
|
193
|
+
class="group/sortable flex items-center gap-2 rounded-lg border border-hairline bg-surface p-2 ps-1 transition-[box-shadow,border-color,translate] duration-fast ease-emphasis"
|
|
194
|
+
[class.border-accent]="grabbed() === i"
|
|
195
|
+
[class.shadow-2]="grabbed() === i"
|
|
196
|
+
[class.-translate-y-px]="grabbed() === i"
|
|
197
|
+
>
|
|
198
|
+
<button
|
|
199
|
+
type="button"
|
|
200
|
+
cdkDragHandle
|
|
201
|
+
class="flex h-7 w-6 shrink-0 cursor-grab items-center justify-center rounded-sm text-fg-subtle outline-none transition-colors hover:bg-state-hover hover:text-fg focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-focus-ring active:cursor-grabbing"
|
|
202
|
+
[attr.aria-label]="handleLabel(item)"
|
|
203
|
+
[attr.aria-describedby]="hintId"
|
|
204
|
+
[attr.aria-pressed]="grabbed() === i"
|
|
205
|
+
[disabled]="disabled()"
|
|
206
|
+
(keydown)="onKeydown($event, i)"
|
|
207
|
+
(blur)="cancelOnBlur()"
|
|
208
|
+
>
|
|
209
|
+
<span mfIcon [size]="16">drag_indicator</span>
|
|
210
|
+
</button>
|
|
211
|
+
<div class="min-w-0 flex-1">
|
|
212
|
+
<ng-container
|
|
213
|
+
[ngTemplateOutlet]="template() ?? null"
|
|
214
|
+
[ngTemplateOutletContext]="{ $implicit: item, index: i }"
|
|
215
|
+
/>
|
|
216
|
+
</div>
|
|
217
|
+
<div
|
|
218
|
+
*cdkDragPlaceholder
|
|
219
|
+
class="h-11 rounded-lg border-2 border-dashed border-accent/40 bg-primary-tint"
|
|
220
|
+
></div>
|
|
221
|
+
</li>
|
|
222
|
+
}
|
|
223
|
+
</ul>
|
|
224
|
+
`,
|
|
225
|
+
}]
|
|
226
|
+
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }, { type: i0.Output, args: ["itemsChange"] }], itemLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemLabel", required: false }] }], trackBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackBy", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], moved: [{ type: i0.Output, args: ["moved"] }], template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
227
|
+
|
|
228
|
+
const DOT = {
|
|
229
|
+
neutral: 'bg-fg-subtle',
|
|
230
|
+
primary: 'bg-accent',
|
|
231
|
+
success: 'bg-success',
|
|
232
|
+
warning: 'bg-warning',
|
|
233
|
+
danger: 'bg-danger',
|
|
234
|
+
info: 'bg-info',
|
|
235
|
+
help: 'bg-help',
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* `<mf-kanban [(columns)]="board" [itemLabel]="titleOf" (moved)="save($event)">
|
|
239
|
+
* <ng-template let-card>…kart içeriği…</ng-template>
|
|
240
|
+
* </mf-kanban>`
|
|
241
|
+
*
|
|
242
|
+
* Sütunlar arası sürükle-bırak (CDK `cdkDropListGroup`) + klavye modu:
|
|
243
|
+
* karta odaklan → Boşluk/Enter al → ↑/↓ sütun içinde, ←/→ sütunlar arası →
|
|
244
|
+
* Boşluk/Enter bırak · Escape geri al. Her adım ekran okuyucuya duyurulur.
|
|
245
|
+
* Sütunlar yatay kaydırılır (mobilde de kullanılabilir).
|
|
246
|
+
*/
|
|
247
|
+
class Kanban {
|
|
248
|
+
columns = model.required(/* @ts-ignore */
|
|
249
|
+
...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
250
|
+
itemLabel = input((item) => String(item), /* @ts-ignore */
|
|
251
|
+
...(ngDevMode ? [{ debugName: "itemLabel" }] : /* istanbul ignore next */ []));
|
|
252
|
+
ariaLabel = input('', /* @ts-ignore */
|
|
253
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
254
|
+
moved = output();
|
|
255
|
+
template = contentChild((TemplateRef), /* @ts-ignore */
|
|
256
|
+
...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
|
|
257
|
+
labels = inject(MF_SORTABLE_LABELS);
|
|
258
|
+
hintId = nextId('mf-kanban');
|
|
259
|
+
grabbed = signal(null, /* @ts-ignore */
|
|
260
|
+
...(ngDevMode ? [{ debugName: "grabbed" }] : /* istanbul ignore next */ []));
|
|
261
|
+
grabOrigin = null;
|
|
262
|
+
announcer = inject(LiveAnnouncer);
|
|
263
|
+
host = inject(ElementRef);
|
|
264
|
+
dot(column) {
|
|
265
|
+
return DOT[column.tone ?? 'neutral'];
|
|
266
|
+
}
|
|
267
|
+
isGrabbed(c, i) {
|
|
268
|
+
const g = this.grabbed();
|
|
269
|
+
return !!g && g.c === c && g.i === i;
|
|
270
|
+
}
|
|
271
|
+
onDrop(event) {
|
|
272
|
+
const from = this.columns().findIndex((col) => col.id === event.previousContainer.data);
|
|
273
|
+
const to = this.columns().findIndex((col) => col.id === event.container.data);
|
|
274
|
+
if (from < 0 || to < 0)
|
|
275
|
+
return;
|
|
276
|
+
if (from === to && event.previousIndex === event.currentIndex)
|
|
277
|
+
return;
|
|
278
|
+
this.move({ c: from, i: event.previousIndex }, { c: to, i: event.currentIndex });
|
|
279
|
+
}
|
|
280
|
+
onKeydown(event, c, i) {
|
|
281
|
+
const g = this.grabbed();
|
|
282
|
+
if (event.key === ' ' || event.key === 'Enter') {
|
|
283
|
+
event.preventDefault();
|
|
284
|
+
if (!g) {
|
|
285
|
+
this.grabOrigin = { c, i };
|
|
286
|
+
this.grabbed.set({ c, i });
|
|
287
|
+
this.say(this.labels().grabbed, { c, i });
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
this.grabbed.set(null);
|
|
291
|
+
this.say(this.labels().dropped, g);
|
|
292
|
+
const item = this.columns()[g.c].items[g.i];
|
|
293
|
+
const origin = this.grabOrigin;
|
|
294
|
+
if (origin.c !== g.c || origin.i !== g.i) {
|
|
295
|
+
this.moved.emit({
|
|
296
|
+
item,
|
|
297
|
+
from: this.columns()[origin.c].id,
|
|
298
|
+
to: this.columns()[g.c].id,
|
|
299
|
+
index: g.i,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
if (!g)
|
|
306
|
+
return;
|
|
307
|
+
const cols = this.columns();
|
|
308
|
+
let target = null;
|
|
309
|
+
if (event.key === 'ArrowUp' && g.i > 0)
|
|
310
|
+
target = { c: g.c, i: g.i - 1 };
|
|
311
|
+
else if (event.key === 'ArrowDown' && g.i < cols[g.c].items.length - 1)
|
|
312
|
+
target = { c: g.c, i: g.i + 1 };
|
|
313
|
+
else if (event.key === 'ArrowLeft' && g.c > 0)
|
|
314
|
+
target = { c: g.c - 1, i: Math.min(g.i, cols[g.c - 1].items.length) };
|
|
315
|
+
else if (event.key === 'ArrowRight' && g.c < cols.length - 1)
|
|
316
|
+
target = { c: g.c + 1, i: Math.min(g.i, cols[g.c + 1].items.length) };
|
|
317
|
+
else if (event.key === 'Escape' && this.grabOrigin) {
|
|
318
|
+
event.preventDefault();
|
|
319
|
+
this.transfer(g, this.grabOrigin);
|
|
320
|
+
this.grabbed.set(null);
|
|
321
|
+
this.say(this.labels().cancelled, this.grabOrigin);
|
|
322
|
+
this.focusCard(this.grabOrigin);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if (!target)
|
|
326
|
+
return;
|
|
327
|
+
event.preventDefault();
|
|
328
|
+
this.transfer(g, target);
|
|
329
|
+
this.grabbed.set(target);
|
|
330
|
+
this.say(target.c === g.c ? this.labels().moved : this.labels().movedToColumn, target);
|
|
331
|
+
this.focusCard(target);
|
|
332
|
+
}
|
|
333
|
+
move(from, to) {
|
|
334
|
+
const item = this.columns()[from.c].items[from.i];
|
|
335
|
+
this.transfer(from, to);
|
|
336
|
+
this.moved.emit({
|
|
337
|
+
item,
|
|
338
|
+
from: this.columns()[from.c].id,
|
|
339
|
+
to: this.columns()[to.c].id,
|
|
340
|
+
index: to.i,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
transfer(from, to) {
|
|
344
|
+
this.columns.update((cols) => {
|
|
345
|
+
const next = cols.map((col) => ({ ...col, items: [...col.items] }));
|
|
346
|
+
if (from.c === to.c) {
|
|
347
|
+
next[from.c].items = moveItem(next[from.c].items, from.i, to.i);
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
const [item] = next[from.c].items.splice(from.i, 1);
|
|
351
|
+
next[to.c].items.splice(to.i, 0, item);
|
|
352
|
+
}
|
|
353
|
+
return next;
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
say(template, at) {
|
|
357
|
+
const col = this.columns()[at.c];
|
|
358
|
+
this.announcer.announce(fillTemplate(template, {
|
|
359
|
+
item: this.itemLabel()(col.items[at.i]),
|
|
360
|
+
position: at.i + 1,
|
|
361
|
+
total: col.items.length,
|
|
362
|
+
column: col.title,
|
|
363
|
+
}));
|
|
364
|
+
}
|
|
365
|
+
focusCard(at) {
|
|
366
|
+
queueMicrotask(() => {
|
|
367
|
+
const list = this.host.nativeElement.querySelector(`#${CSS.escape(this.hintId + '-list-' + at.c)}`);
|
|
368
|
+
list?.querySelectorAll('[role=button]')[at.i]?.focus();
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: Kanban, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
372
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: Kanban, isStandalone: true, selector: "mf-kanban", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, itemLabel: { classPropertyName: "itemLabel", publicName: "itemLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { columns: "columnsChange", moved: "moved" }, host: { classAttribute: "block" }, queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], exportAs: ["mfKanban"], ngImport: i0, template: `
|
|
373
|
+
<p [id]="hintId" class="sr-only">{{ labels().instructions }}</p>
|
|
374
|
+
<div
|
|
375
|
+
cdkDropListGroup
|
|
376
|
+
class="flex gap-4 overflow-x-auto pb-2"
|
|
377
|
+
[attr.aria-label]="ariaLabel() || null"
|
|
378
|
+
role="group"
|
|
379
|
+
>
|
|
380
|
+
@for (column of columns(); track column.id; let c = $index) {
|
|
381
|
+
<section
|
|
382
|
+
class="flex w-72 shrink-0 flex-col rounded-xl border border-hairline bg-surface-sunken"
|
|
383
|
+
[attr.aria-labelledby]="hintId + '-col-' + c"
|
|
384
|
+
>
|
|
385
|
+
<header class="flex items-center gap-2 px-3 pt-3 pb-2">
|
|
386
|
+
<span class="h-2 w-2 rounded-full" [class]="dot(column)"></span>
|
|
387
|
+
<h3 [id]="hintId + '-col-' + c" class="flex-1 truncate text-sm font-semibold text-fg">
|
|
388
|
+
{{ column.title }}
|
|
389
|
+
</h3>
|
|
390
|
+
<span
|
|
391
|
+
class="rounded-full px-2 py-0.5 text-xs font-medium tabular-nums"
|
|
392
|
+
[class]="
|
|
393
|
+
column.limit && column.items.length > column.limit
|
|
394
|
+
? 'bg-warning-tint text-warning-tint-fg'
|
|
395
|
+
: 'bg-state-selected text-fg-muted'
|
|
396
|
+
"
|
|
397
|
+
>{{ column.items.length }}{{ column.limit ? ' / ' + column.limit : '' }}</span
|
|
398
|
+
>
|
|
399
|
+
</header>
|
|
400
|
+
<ul
|
|
401
|
+
cdkDropList
|
|
402
|
+
[id]="hintId + '-list-' + c"
|
|
403
|
+
[cdkDropListData]="column.id"
|
|
404
|
+
(cdkDropListDropped)="onDrop($event)"
|
|
405
|
+
class="m-0 flex min-h-24 flex-1 list-none flex-col gap-2 p-2 pt-0"
|
|
406
|
+
>
|
|
407
|
+
@for (item of column.items; track $index; let i = $index) {
|
|
408
|
+
<li
|
|
409
|
+
cdkDrag
|
|
410
|
+
[cdkDragData]="item"
|
|
411
|
+
class="cursor-grab rounded-lg active:cursor-grabbing"
|
|
412
|
+
>
|
|
413
|
+
<div
|
|
414
|
+
tabindex="0"
|
|
415
|
+
role="button"
|
|
416
|
+
[attr.aria-roledescription]="labels().card"
|
|
417
|
+
[attr.aria-describedby]="hintId"
|
|
418
|
+
[attr.aria-pressed]="isGrabbed(c, i)"
|
|
419
|
+
[attr.aria-label]="itemLabel()(item)"
|
|
420
|
+
(keydown)="onKeydown($event, c, i)"
|
|
421
|
+
class="rounded-lg border border-hairline bg-surface p-3 text-sm shadow-highlight outline-none transition-[box-shadow,border-color,translate] duration-fast ease-emphasis hover:border-border focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring"
|
|
422
|
+
[class.border-accent]="isGrabbed(c, i)"
|
|
423
|
+
[class.shadow-2]="isGrabbed(c, i)"
|
|
424
|
+
>
|
|
425
|
+
<ng-container
|
|
426
|
+
[ngTemplateOutlet]="template() ?? null"
|
|
427
|
+
[ngTemplateOutletContext]="{ $implicit: item, column: column.id }"
|
|
428
|
+
/>
|
|
429
|
+
</div>
|
|
430
|
+
<div
|
|
431
|
+
*cdkDragPlaceholder
|
|
432
|
+
class="h-16 rounded-lg border-2 border-dashed border-accent/40 bg-primary-tint"
|
|
433
|
+
></div>
|
|
434
|
+
</li>
|
|
435
|
+
}
|
|
436
|
+
</ul>
|
|
437
|
+
</section>
|
|
438
|
+
}
|
|
439
|
+
</div>
|
|
440
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
441
|
+
}
|
|
442
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: Kanban, decorators: [{
|
|
443
|
+
type: Component,
|
|
444
|
+
args: [{
|
|
445
|
+
selector: 'mf-kanban',
|
|
446
|
+
exportAs: 'mfKanban',
|
|
447
|
+
imports: [CdkDropListGroup, CdkDropList, CdkDrag, CdkDragPlaceholder, NgTemplateOutlet],
|
|
448
|
+
host: { class: 'block' },
|
|
449
|
+
template: `
|
|
450
|
+
<p [id]="hintId" class="sr-only">{{ labels().instructions }}</p>
|
|
451
|
+
<div
|
|
452
|
+
cdkDropListGroup
|
|
453
|
+
class="flex gap-4 overflow-x-auto pb-2"
|
|
454
|
+
[attr.aria-label]="ariaLabel() || null"
|
|
455
|
+
role="group"
|
|
456
|
+
>
|
|
457
|
+
@for (column of columns(); track column.id; let c = $index) {
|
|
458
|
+
<section
|
|
459
|
+
class="flex w-72 shrink-0 flex-col rounded-xl border border-hairline bg-surface-sunken"
|
|
460
|
+
[attr.aria-labelledby]="hintId + '-col-' + c"
|
|
461
|
+
>
|
|
462
|
+
<header class="flex items-center gap-2 px-3 pt-3 pb-2">
|
|
463
|
+
<span class="h-2 w-2 rounded-full" [class]="dot(column)"></span>
|
|
464
|
+
<h3 [id]="hintId + '-col-' + c" class="flex-1 truncate text-sm font-semibold text-fg">
|
|
465
|
+
{{ column.title }}
|
|
466
|
+
</h3>
|
|
467
|
+
<span
|
|
468
|
+
class="rounded-full px-2 py-0.5 text-xs font-medium tabular-nums"
|
|
469
|
+
[class]="
|
|
470
|
+
column.limit && column.items.length > column.limit
|
|
471
|
+
? 'bg-warning-tint text-warning-tint-fg'
|
|
472
|
+
: 'bg-state-selected text-fg-muted'
|
|
473
|
+
"
|
|
474
|
+
>{{ column.items.length }}{{ column.limit ? ' / ' + column.limit : '' }}</span
|
|
475
|
+
>
|
|
476
|
+
</header>
|
|
477
|
+
<ul
|
|
478
|
+
cdkDropList
|
|
479
|
+
[id]="hintId + '-list-' + c"
|
|
480
|
+
[cdkDropListData]="column.id"
|
|
481
|
+
(cdkDropListDropped)="onDrop($event)"
|
|
482
|
+
class="m-0 flex min-h-24 flex-1 list-none flex-col gap-2 p-2 pt-0"
|
|
483
|
+
>
|
|
484
|
+
@for (item of column.items; track $index; let i = $index) {
|
|
485
|
+
<li
|
|
486
|
+
cdkDrag
|
|
487
|
+
[cdkDragData]="item"
|
|
488
|
+
class="cursor-grab rounded-lg active:cursor-grabbing"
|
|
489
|
+
>
|
|
490
|
+
<div
|
|
491
|
+
tabindex="0"
|
|
492
|
+
role="button"
|
|
493
|
+
[attr.aria-roledescription]="labels().card"
|
|
494
|
+
[attr.aria-describedby]="hintId"
|
|
495
|
+
[attr.aria-pressed]="isGrabbed(c, i)"
|
|
496
|
+
[attr.aria-label]="itemLabel()(item)"
|
|
497
|
+
(keydown)="onKeydown($event, c, i)"
|
|
498
|
+
class="rounded-lg border border-hairline bg-surface p-3 text-sm shadow-highlight outline-none transition-[box-shadow,border-color,translate] duration-fast ease-emphasis hover:border-border focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring"
|
|
499
|
+
[class.border-accent]="isGrabbed(c, i)"
|
|
500
|
+
[class.shadow-2]="isGrabbed(c, i)"
|
|
501
|
+
>
|
|
502
|
+
<ng-container
|
|
503
|
+
[ngTemplateOutlet]="template() ?? null"
|
|
504
|
+
[ngTemplateOutletContext]="{ $implicit: item, column: column.id }"
|
|
505
|
+
/>
|
|
506
|
+
</div>
|
|
507
|
+
<div
|
|
508
|
+
*cdkDragPlaceholder
|
|
509
|
+
class="h-16 rounded-lg border-2 border-dashed border-accent/40 bg-primary-tint"
|
|
510
|
+
></div>
|
|
511
|
+
</li>
|
|
512
|
+
}
|
|
513
|
+
</ul>
|
|
514
|
+
</section>
|
|
515
|
+
}
|
|
516
|
+
</div>
|
|
517
|
+
`,
|
|
518
|
+
}]
|
|
519
|
+
}], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }, { type: i0.Output, args: ["columnsChange"] }], itemLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemLabel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], moved: [{ type: i0.Output, args: ["moved"] }], template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Generated bundle index. Do not edit.
|
|
523
|
+
*/
|
|
524
|
+
|
|
525
|
+
export { Kanban, SortableList, fillTemplate, moveItem };
|
|
526
|
+
//# sourceMappingURL=mesgflow-ui-kit-sortable.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mesgflow-ui-kit-sortable.mjs","sources":["../../../projects/ui-kit/sortable/announcer.ts","../../../projects/ui-kit/sortable/sortable-list.ts","../../../projects/ui-kit/sortable/kanban.ts","../../../projects/ui-kit/sortable/mesgflow-ui-kit-sortable.ts"],"sourcesContent":["/** `'{item} moved to {position}'` gibi şablonları doldurur. */\r\nexport function fillTemplate(template: string, values: Record<string, string | number>): string {\r\n return template.replace(/\\{(\\w+)\\}/g, (_, key: string) => String(values[key] ?? ''));\r\n}\r\n\r\n/** Diziden bir öğeyi taşır — yeni dizi döner (orijinal değişmez). */\r\nexport function moveItem<T>(list: readonly T[], from: number, to: number): T[] {\r\n const next = [...list];\r\n const [item] = next.splice(from, 1);\r\n next.splice(Math.max(0, Math.min(next.length, to)), 0, item!);\r\n return next;\r\n}\r\n","import { LiveAnnouncer } from '@angular/cdk/a11y';\r\nimport {\r\n CdkDrag,\r\n CdkDragHandle,\r\n CdkDragPlaceholder,\r\n CdkDropList,\r\n type CdkDragDrop,\r\n} from '@angular/cdk/drag-drop';\r\nimport { NgTemplateOutlet } from '@angular/common';\r\nimport {\r\n Component,\r\n ElementRef,\r\n TemplateRef,\r\n booleanAttribute,\r\n contentChild,\r\n inject,\r\n input,\r\n model,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport { MF_SORTABLE_LABELS, nextId } from '@mesgflow/ui-kit/core';\r\nimport { Icon } from '@mesgflow/ui-kit/icon';\r\nimport { fillTemplate, moveItem } from './announcer';\r\n\r\nexport interface SortableMove {\r\n previousIndex: number;\r\n currentIndex: number;\r\n}\r\n\r\n/**\r\n * `<mf-sortable-list [(items)]=\"tasks\" [itemLabel]=\"labelOf\">\r\n * <ng-template let-task>{{ task.title }}</ng-template>\r\n * </mf-sortable-list>`\r\n *\r\n * Sürükle-bırak ile yeniden sıralanan liste — CDK drag-drop üstüne ERİŞİLEBİLİR\r\n * klavye modu eklenir (CDK'da yok): tutamaca odaklan → Boşluk/Enter ile al →\r\n * ↑/↓ taşı → Boşluk/Enter bırak · Escape geri al. Her adım `LiveAnnouncer`\r\n * ile duyurulur (WCAG 2.1.1 — sürükle-bırakın klavye eşdeğeri).\r\n *\r\n * `itemLabel`: duyurular ve tutamaç adı için öğenin okunur adı.\r\n */\r\n@Component({\r\n selector: 'mf-sortable-list',\r\n exportAs: 'mfSortableList',\r\n imports: [CdkDropList, CdkDrag, CdkDragHandle, CdkDragPlaceholder, NgTemplateOutlet, Icon],\r\n host: { class: 'block' },\r\n template: `\r\n <p [id]=\"hintId\" class=\"sr-only\">{{ labels().instructions }}</p>\r\n <ul\r\n cdkDropList\r\n [cdkDropListData]=\"items()\"\r\n [cdkDropListDisabled]=\"disabled()\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"m-0 flex list-none flex-col gap-1.5 p-0\"\r\n [attr.aria-label]=\"ariaLabel() || null\"\r\n >\r\n @for (item of items(); track trackBy()(item, $index); let i = $index) {\r\n <li\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n class=\"group/sortable flex items-center gap-2 rounded-lg border border-hairline bg-surface p-2 ps-1 transition-[box-shadow,border-color,translate] duration-fast ease-emphasis\"\r\n [class.border-accent]=\"grabbed() === i\"\r\n [class.shadow-2]=\"grabbed() === i\"\r\n [class.-translate-y-px]=\"grabbed() === i\"\r\n >\r\n <button\r\n type=\"button\"\r\n cdkDragHandle\r\n class=\"flex h-7 w-6 shrink-0 cursor-grab items-center justify-center rounded-sm text-fg-subtle outline-none transition-colors hover:bg-state-hover hover:text-fg focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-focus-ring active:cursor-grabbing\"\r\n [attr.aria-label]=\"handleLabel(item)\"\r\n [attr.aria-describedby]=\"hintId\"\r\n [attr.aria-pressed]=\"grabbed() === i\"\r\n [disabled]=\"disabled()\"\r\n (keydown)=\"onKeydown($event, i)\"\r\n (blur)=\"cancelOnBlur()\"\r\n >\r\n <span mfIcon [size]=\"16\">drag_indicator</span>\r\n </button>\r\n <div class=\"min-w-0 flex-1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"template() ?? null\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item, index: i }\"\r\n />\r\n </div>\r\n <div\r\n *cdkDragPlaceholder\r\n class=\"h-11 rounded-lg border-2 border-dashed border-accent/40 bg-primary-tint\"\r\n ></div>\r\n </li>\r\n }\r\n </ul>\r\n `,\r\n})\r\nexport class SortableList<T> {\r\n readonly items = model.required<T[]>();\r\n /** Duyurular ve tutamaç adı için okunur ad. */\r\n readonly itemLabel = input<(item: T) => string>((item) => String(item));\r\n readonly trackBy = input<(item: T, index: number) => unknown>((_, i) => i);\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n readonly ariaLabel = input('');\r\n\r\n readonly moved = output<SortableMove>();\r\n\r\n protected readonly template = contentChild(TemplateRef<{ $implicit: T; index: number }>);\r\n protected readonly labels = inject(MF_SORTABLE_LABELS);\r\n protected readonly hintId = nextId('mf-sortable-hint');\r\n protected readonly grabbed = signal<number | null>(null);\r\n\r\n private readonly announcer = inject(LiveAnnouncer);\r\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\r\n private grabStart = 0;\r\n\r\n protected handleLabel(item: T): string {\r\n return fillTemplate(this.labels().dragHandle, { item: this.itemLabel()(item) });\r\n }\r\n\r\n protected onDrop(event: CdkDragDrop<T[]>): void {\r\n if (event.previousIndex === event.currentIndex) return;\r\n this.commit(event.previousIndex, event.currentIndex);\r\n }\r\n\r\n protected onKeydown(event: KeyboardEvent, index: number): void {\r\n const grabbed = this.grabbed();\r\n const total = this.items().length;\r\n const say = (template: string, position: number) =>\r\n this.announcer.announce(\r\n fillTemplate(template, {\r\n item: this.itemLabel()(this.items()[position]!),\r\n position: position + 1,\r\n total,\r\n }),\r\n );\r\n\r\n if (event.key === ' ' || event.key === 'Enter') {\r\n event.preventDefault();\r\n if (grabbed === null) {\r\n this.grabStart = index;\r\n this.grabbed.set(index);\r\n say(this.labels().grabbed, index);\r\n } else {\r\n this.grabbed.set(null);\r\n say(this.labels().dropped, grabbed);\r\n if (grabbed !== this.grabStart)\r\n this.moved.emit({ previousIndex: this.grabStart, currentIndex: grabbed });\r\n }\r\n return;\r\n }\r\n if (grabbed === null) return;\r\n if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {\r\n event.preventDefault();\r\n const target = grabbed + (event.key === 'ArrowUp' ? -1 : 1);\r\n if (target < 0 || target >= total) return;\r\n this.items.set(moveItem(this.items(), grabbed, target));\r\n this.grabbed.set(target);\r\n say(this.labels().moved, target);\r\n this.refocus(target);\r\n } else if (event.key === 'Escape') {\r\n event.preventDefault();\r\n this.items.set(moveItem(this.items(), grabbed, this.grabStart));\r\n this.grabbed.set(null);\r\n say(this.labels().cancelled, this.grabStart);\r\n this.refocus(this.grabStart);\r\n }\r\n }\r\n\r\n protected cancelOnBlur(): void {\r\n // Odak başka yere giderse (Tab) taşıma bitmiş sayılır — yerinde bırakılır.\r\n queueMicrotask(() => {\r\n const active = document.activeElement;\r\n if (!this.host.nativeElement.contains(active)) this.grabbed.set(null);\r\n });\r\n }\r\n\r\n private commit(from: number, to: number): void {\r\n this.items.set(moveItem(this.items(), from, to));\r\n this.moved.emit({ previousIndex: from, currentIndex: to });\r\n }\r\n\r\n /** Taşıma sonrası `@for` DOM'u yeniden sıraladığında odağı taşınan tutamakta tut. */\r\n private refocus(index: number): void {\r\n queueMicrotask(() => {\r\n const handles = this.host.nativeElement.querySelectorAll<HTMLElement>(\r\n '[cdkDragHandle], .cdk-drag-handle',\r\n );\r\n handles[index]?.focus();\r\n });\r\n }\r\n}\r\n","import { LiveAnnouncer } from '@angular/cdk/a11y';\r\nimport {\r\n CdkDrag,\r\n CdkDragPlaceholder,\r\n CdkDropList,\r\n CdkDropListGroup,\r\n type CdkDragDrop,\r\n} from '@angular/cdk/drag-drop';\r\nimport { NgTemplateOutlet } from '@angular/common';\r\nimport {\r\n Component,\r\n ElementRef,\r\n TemplateRef,\r\n contentChild,\r\n inject,\r\n input,\r\n model,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport { MF_SORTABLE_LABELS, nextId } from '@mesgflow/ui-kit/core';\r\nimport { fillTemplate, moveItem } from './announcer';\r\n\r\nexport interface KanbanColumn<T> {\r\n id: string;\r\n title: string;\r\n items: T[];\r\n /** Sütun başlığındaki nokta rengi. */\r\n tone?: 'neutral' | 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'help';\r\n /** WIP sınırı — aşılınca sayaç uyarı tonuna döner. */\r\n limit?: number;\r\n}\r\n\r\nexport interface KanbanMove<T> {\r\n item: T;\r\n from: string;\r\n to: string;\r\n index: number;\r\n}\r\n\r\nconst DOT: Record<NonNullable<KanbanColumn<unknown>['tone']>, string> = {\r\n neutral: 'bg-fg-subtle',\r\n primary: 'bg-accent',\r\n success: 'bg-success',\r\n warning: 'bg-warning',\r\n danger: 'bg-danger',\r\n info: 'bg-info',\r\n help: 'bg-help',\r\n};\r\n\r\n/**\r\n * `<mf-kanban [(columns)]=\"board\" [itemLabel]=\"titleOf\" (moved)=\"save($event)\">\r\n * <ng-template let-card>…kart içeriği…</ng-template>\r\n * </mf-kanban>`\r\n *\r\n * Sütunlar arası sürükle-bırak (CDK `cdkDropListGroup`) + klavye modu:\r\n * karta odaklan → Boşluk/Enter al → ↑/↓ sütun içinde, ←/→ sütunlar arası →\r\n * Boşluk/Enter bırak · Escape geri al. Her adım ekran okuyucuya duyurulur.\r\n * Sütunlar yatay kaydırılır (mobilde de kullanılabilir).\r\n */\r\n@Component({\r\n selector: 'mf-kanban',\r\n exportAs: 'mfKanban',\r\n imports: [CdkDropListGroup, CdkDropList, CdkDrag, CdkDragPlaceholder, NgTemplateOutlet],\r\n host: { class: 'block' },\r\n template: `\r\n <p [id]=\"hintId\" class=\"sr-only\">{{ labels().instructions }}</p>\r\n <div\r\n cdkDropListGroup\r\n class=\"flex gap-4 overflow-x-auto pb-2\"\r\n [attr.aria-label]=\"ariaLabel() || null\"\r\n role=\"group\"\r\n >\r\n @for (column of columns(); track column.id; let c = $index) {\r\n <section\r\n class=\"flex w-72 shrink-0 flex-col rounded-xl border border-hairline bg-surface-sunken\"\r\n [attr.aria-labelledby]=\"hintId + '-col-' + c\"\r\n >\r\n <header class=\"flex items-center gap-2 px-3 pt-3 pb-2\">\r\n <span class=\"h-2 w-2 rounded-full\" [class]=\"dot(column)\"></span>\r\n <h3 [id]=\"hintId + '-col-' + c\" class=\"flex-1 truncate text-sm font-semibold text-fg\">\r\n {{ column.title }}\r\n </h3>\r\n <span\r\n class=\"rounded-full px-2 py-0.5 text-xs font-medium tabular-nums\"\r\n [class]=\"\r\n column.limit && column.items.length > column.limit\r\n ? 'bg-warning-tint text-warning-tint-fg'\r\n : 'bg-state-selected text-fg-muted'\r\n \"\r\n >{{ column.items.length }}{{ column.limit ? ' / ' + column.limit : '' }}</span\r\n >\r\n </header>\r\n <ul\r\n cdkDropList\r\n [id]=\"hintId + '-list-' + c\"\r\n [cdkDropListData]=\"column.id\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"m-0 flex min-h-24 flex-1 list-none flex-col gap-2 p-2 pt-0\"\r\n >\r\n @for (item of column.items; track $index; let i = $index) {\r\n <li\r\n cdkDrag\r\n [cdkDragData]=\"item\"\r\n class=\"cursor-grab rounded-lg active:cursor-grabbing\"\r\n >\r\n <div\r\n tabindex=\"0\"\r\n role=\"button\"\r\n [attr.aria-roledescription]=\"labels().card\"\r\n [attr.aria-describedby]=\"hintId\"\r\n [attr.aria-pressed]=\"isGrabbed(c, i)\"\r\n [attr.aria-label]=\"itemLabel()(item)\"\r\n (keydown)=\"onKeydown($event, c, i)\"\r\n class=\"rounded-lg border border-hairline bg-surface p-3 text-sm shadow-highlight outline-none transition-[box-shadow,border-color,translate] duration-fast ease-emphasis hover:border-border focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring\"\r\n [class.border-accent]=\"isGrabbed(c, i)\"\r\n [class.shadow-2]=\"isGrabbed(c, i)\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"template() ?? null\"\r\n [ngTemplateOutletContext]=\"{ $implicit: item, column: column.id }\"\r\n />\r\n </div>\r\n <div\r\n *cdkDragPlaceholder\r\n class=\"h-16 rounded-lg border-2 border-dashed border-accent/40 bg-primary-tint\"\r\n ></div>\r\n </li>\r\n }\r\n </ul>\r\n </section>\r\n }\r\n </div>\r\n `,\r\n})\r\nexport class Kanban<T> {\r\n readonly columns = model.required<KanbanColumn<T>[]>();\r\n readonly itemLabel = input<(item: T) => string>((item) => String(item));\r\n readonly ariaLabel = input('');\r\n readonly moved = output<KanbanMove<T>>();\r\n\r\n protected readonly template = contentChild(TemplateRef<{ $implicit: T; column: string }>);\r\n protected readonly labels = inject(MF_SORTABLE_LABELS);\r\n protected readonly hintId = nextId('mf-kanban');\r\n private readonly grabbed = signal<{ c: number; i: number } | null>(null);\r\n private grabOrigin: { c: number; i: number } | null = null;\r\n\r\n private readonly announcer = inject(LiveAnnouncer);\r\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\r\n\r\n protected dot(column: KanbanColumn<T>): string {\r\n return DOT[column.tone ?? 'neutral'];\r\n }\r\n\r\n protected isGrabbed(c: number, i: number): boolean {\r\n const g = this.grabbed();\r\n return !!g && g.c === c && g.i === i;\r\n }\r\n\r\n protected onDrop(event: CdkDragDrop<string>): void {\r\n const from = this.columns().findIndex((col) => col.id === event.previousContainer.data);\r\n const to = this.columns().findIndex((col) => col.id === event.container.data);\r\n if (from < 0 || to < 0) return;\r\n if (from === to && event.previousIndex === event.currentIndex) return;\r\n this.move({ c: from, i: event.previousIndex }, { c: to, i: event.currentIndex });\r\n }\r\n\r\n protected onKeydown(event: KeyboardEvent, c: number, i: number): void {\r\n const g = this.grabbed();\r\n if (event.key === ' ' || event.key === 'Enter') {\r\n event.preventDefault();\r\n if (!g) {\r\n this.grabOrigin = { c, i };\r\n this.grabbed.set({ c, i });\r\n this.say(this.labels().grabbed, { c, i });\r\n } else {\r\n this.grabbed.set(null);\r\n this.say(this.labels().dropped, g);\r\n const item = this.columns()[g.c]!.items[g.i]!;\r\n const origin = this.grabOrigin!;\r\n if (origin.c !== g.c || origin.i !== g.i) {\r\n this.moved.emit({\r\n item,\r\n from: this.columns()[origin.c]!.id,\r\n to: this.columns()[g.c]!.id,\r\n index: g.i,\r\n });\r\n }\r\n }\r\n return;\r\n }\r\n if (!g) return;\r\n const cols = this.columns();\r\n let target: { c: number; i: number } | null = null;\r\n if (event.key === 'ArrowUp' && g.i > 0) target = { c: g.c, i: g.i - 1 };\r\n else if (event.key === 'ArrowDown' && g.i < cols[g.c]!.items.length - 1)\r\n target = { c: g.c, i: g.i + 1 };\r\n else if (event.key === 'ArrowLeft' && g.c > 0)\r\n target = { c: g.c - 1, i: Math.min(g.i, cols[g.c - 1]!.items.length) };\r\n else if (event.key === 'ArrowRight' && g.c < cols.length - 1)\r\n target = { c: g.c + 1, i: Math.min(g.i, cols[g.c + 1]!.items.length) };\r\n else if (event.key === 'Escape' && this.grabOrigin) {\r\n event.preventDefault();\r\n this.transfer(g, this.grabOrigin);\r\n this.grabbed.set(null);\r\n this.say(this.labels().cancelled, this.grabOrigin);\r\n this.focusCard(this.grabOrigin);\r\n return;\r\n }\r\n if (!target) return;\r\n event.preventDefault();\r\n this.transfer(g, target);\r\n this.grabbed.set(target);\r\n this.say(target.c === g.c ? this.labels().moved : this.labels().movedToColumn, target);\r\n this.focusCard(target);\r\n }\r\n\r\n private move(from: { c: number; i: number }, to: { c: number; i: number }): void {\r\n const item = this.columns()[from.c]!.items[from.i]!;\r\n this.transfer(from, to);\r\n this.moved.emit({\r\n item,\r\n from: this.columns()[from.c]!.id,\r\n to: this.columns()[to.c]!.id,\r\n index: to.i,\r\n });\r\n }\r\n\r\n private transfer(from: { c: number; i: number }, to: { c: number; i: number }): void {\r\n this.columns.update((cols) => {\r\n const next = cols.map((col) => ({ ...col, items: [...col.items] }));\r\n if (from.c === to.c) {\r\n next[from.c]!.items = moveItem(next[from.c]!.items, from.i, to.i);\r\n } else {\r\n const [item] = next[from.c]!.items.splice(from.i, 1);\r\n next[to.c]!.items.splice(to.i, 0, item!);\r\n }\r\n return next;\r\n });\r\n }\r\n\r\n private say(template: string, at: { c: number; i: number }): void {\r\n const col = this.columns()[at.c]!;\r\n this.announcer.announce(\r\n fillTemplate(template, {\r\n item: this.itemLabel()(col.items[at.i]!),\r\n position: at.i + 1,\r\n total: col.items.length,\r\n column: col.title,\r\n }),\r\n );\r\n }\r\n\r\n private focusCard(at: { c: number; i: number }): void {\r\n queueMicrotask(() => {\r\n const list = this.host.nativeElement.querySelector(\r\n `#${CSS.escape(this.hintId + '-list-' + at.c)}`,\r\n );\r\n list?.querySelectorAll<HTMLElement>('[role=button]')[at.i]?.focus();\r\n });\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|