@deepfuture/dui-components 0.0.1
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/accordion/accordion-context.d.ts +15 -0
- package/accordion/accordion-context.js +3 -0
- package/accordion/accordion-item.d.ts +22 -0
- package/accordion/accordion-item.js +254 -0
- package/accordion/accordion.d.ts +20 -0
- package/accordion/accordion.js +185 -0
- package/accordion/index.d.ts +3 -0
- package/accordion/index.js +2 -0
- package/accordion/register.d.ts +1 -0
- package/accordion/register.js +8 -0
- package/alert-dialog/alert-dialog-close.d.ts +15 -0
- package/alert-dialog/alert-dialog-close.js +35 -0
- package/alert-dialog/alert-dialog-context.d.ts +13 -0
- package/alert-dialog/alert-dialog-context.js +3 -0
- package/alert-dialog/alert-dialog-popup.d.ts +34 -0
- package/alert-dialog/alert-dialog-popup.js +260 -0
- package/alert-dialog/alert-dialog-trigger.d.ts +15 -0
- package/alert-dialog/alert-dialog-trigger.js +52 -0
- package/alert-dialog/alert-dialog.d.ts +30 -0
- package/alert-dialog/alert-dialog.js +97 -0
- package/alert-dialog/index.d.ts +6 -0
- package/alert-dialog/index.js +4 -0
- package/alert-dialog/register.d.ts +1 -0
- package/alert-dialog/register.js +16 -0
- package/all.d.ts +86 -0
- package/all.js +191 -0
- package/avatar/avatar.d.ts +41 -0
- package/avatar/avatar.js +188 -0
- package/avatar/index.d.ts +2 -0
- package/avatar/index.js +1 -0
- package/avatar/register.d.ts +1 -0
- package/avatar/register.js +4 -0
- package/badge/badge.d.ts +14 -0
- package/badge/badge.js +43 -0
- package/badge/index.d.ts +2 -0
- package/badge/index.js +1 -0
- package/badge/register.d.ts +1 -0
- package/badge/register.js +4 -0
- package/breadcrumb/breadcrumb-ellipsis.d.ts +14 -0
- package/breadcrumb/breadcrumb-ellipsis.js +39 -0
- package/breadcrumb/breadcrumb-item.d.ts +13 -0
- package/breadcrumb/breadcrumb-item.js +31 -0
- package/breadcrumb/breadcrumb-link.d.ts +14 -0
- package/breadcrumb/breadcrumb-link.js +32 -0
- package/breadcrumb/breadcrumb-page.d.ts +13 -0
- package/breadcrumb/breadcrumb-page.js +36 -0
- package/breadcrumb/breadcrumb-separator.d.ts +14 -0
- package/breadcrumb/breadcrumb-separator.js +36 -0
- package/breadcrumb/breadcrumb.d.ts +14 -0
- package/breadcrumb/breadcrumb.js +38 -0
- package/breadcrumb/index.d.ts +6 -0
- package/breadcrumb/index.js +6 -0
- package/breadcrumb/register.d.ts +1 -0
- package/breadcrumb/register.js +14 -0
- package/button/button.d.ts +38 -0
- package/button/button.js +143 -0
- package/button/index.d.ts +2 -0
- package/button/index.js +1 -0
- package/button/register.d.ts +1 -0
- package/button/register.js +4 -0
- package/calendar/calendar.d.ts +33 -0
- package/calendar/calendar.js +428 -0
- package/calendar/index.d.ts +1 -0
- package/calendar/index.js +1 -0
- package/calendar/register.d.ts +1 -0
- package/calendar/register.js +4 -0
- package/center/center.d.ts +14 -0
- package/center/center.js +37 -0
- package/center/index.d.ts +1 -0
- package/center/index.js +1 -0
- package/center/register.d.ts +1 -0
- package/center/register.js +4 -0
- package/checkbox/checkbox-group-context.d.ts +11 -0
- package/checkbox/checkbox-group-context.js +3 -0
- package/checkbox/checkbox-group.d.ts +34 -0
- package/checkbox/checkbox-group.js +128 -0
- package/checkbox/checkbox.d.ts +46 -0
- package/checkbox/checkbox.js +314 -0
- package/checkbox/index.d.ts +3 -0
- package/checkbox/index.js +2 -0
- package/checkbox/register.d.ts +1 -0
- package/checkbox/register.js +8 -0
- package/collapsible/collapsible.d.ts +22 -0
- package/collapsible/collapsible.js +227 -0
- package/collapsible/index.d.ts +1 -0
- package/collapsible/index.js +1 -0
- package/collapsible/register.d.ts +1 -0
- package/collapsible/register.js +4 -0
- package/combobox/combobox.d.ts +46 -0
- package/combobox/combobox.js +524 -0
- package/combobox/index.d.ts +2 -0
- package/combobox/index.js +1 -0
- package/combobox/register.d.ts +1 -0
- package/combobox/register.js +4 -0
- package/command/command-context.d.ts +30 -0
- package/command/command-context.js +3 -0
- package/command/command-empty.d.ts +10 -0
- package/command/command-empty.js +50 -0
- package/command/command-group.d.ts +15 -0
- package/command/command-group.js +79 -0
- package/command/command-input.d.ts +13 -0
- package/command/command-input.js +106 -0
- package/command/command-item.d.ts +20 -0
- package/command/command-item.js +175 -0
- package/command/command-list.d.ts +9 -0
- package/command/command-list.js +43 -0
- package/command/command-score.d.ts +6 -0
- package/command/command-score.js +31 -0
- package/command/command-separator.d.ts +7 -0
- package/command/command-separator.js +15 -0
- package/command/command-shortcut.d.ts +7 -0
- package/command/command-shortcut.js +16 -0
- package/command/command.d.ts +25 -0
- package/command/command.js +278 -0
- package/command/index.d.ts +10 -0
- package/command/index.js +9 -0
- package/command/register.d.ts +1 -0
- package/command/register.js +22 -0
- package/data-table/data-table.d.ts +59 -0
- package/data-table/data-table.js +416 -0
- package/data-table/index.d.ts +2 -0
- package/data-table/index.js +1 -0
- package/data-table/register.d.ts +1 -0
- package/data-table/register.js +4 -0
- package/dialog/dialog-close.d.ts +15 -0
- package/dialog/dialog-close.js +35 -0
- package/dialog/dialog-context.d.ts +13 -0
- package/dialog/dialog-context.js +3 -0
- package/dialog/dialog-popup.d.ts +36 -0
- package/dialog/dialog-popup.js +277 -0
- package/dialog/dialog-trigger.d.ts +15 -0
- package/dialog/dialog-trigger.js +52 -0
- package/dialog/dialog.d.ts +30 -0
- package/dialog/dialog.js +97 -0
- package/dialog/index.d.ts +6 -0
- package/dialog/index.js +4 -0
- package/dialog/register.d.ts +1 -0
- package/dialog/register.js +16 -0
- package/dropzone/dropzone.d.ts +74 -0
- package/dropzone/dropzone.js +357 -0
- package/dropzone/index.d.ts +2 -0
- package/dropzone/index.js +1 -0
- package/dropzone/register.d.ts +1 -0
- package/dropzone/register.js +4 -0
- package/field/field-context.d.ts +20 -0
- package/field/field-context.js +2 -0
- package/field/index.d.ts +2 -0
- package/field/index.js +1 -0
- package/global.d.ts +189 -0
- package/hstack/hstack.d.ts +25 -0
- package/hstack/hstack.js +141 -0
- package/hstack/index.d.ts +2 -0
- package/hstack/index.js +1 -0
- package/hstack/register.d.ts +1 -0
- package/hstack/register.js +4 -0
- package/icon/icon.d.ts +16 -0
- package/icon/icon.js +34 -0
- package/icon/index.d.ts +1 -0
- package/icon/index.js +1 -0
- package/icon/register.d.ts +1 -0
- package/icon/register.js +4 -0
- package/input/index.d.ts +1 -0
- package/input/index.js +1 -0
- package/input/input.d.ts +47 -0
- package/input/input.js +205 -0
- package/input/register.d.ts +1 -0
- package/input/register.js +4 -0
- package/link/index.d.ts +1 -0
- package/link/index.js +1 -0
- package/link/link.d.ts +27 -0
- package/link/link.js +57 -0
- package/link/register.d.ts +1 -0
- package/link/register.js +4 -0
- package/menu/index.d.ts +2 -0
- package/menu/index.js +2 -0
- package/menu/menu-item.d.ts +17 -0
- package/menu/menu-item.js +62 -0
- package/menu/menu.d.ts +15 -0
- package/menu/menu.js +228 -0
- package/menu/register.d.ts +1 -0
- package/menu/register.js +8 -0
- package/menubar/index.d.ts +2 -0
- package/menubar/index.js +1 -0
- package/menubar/menubar-context.d.ts +9 -0
- package/menubar/menubar-context.js +2 -0
- package/menubar/menubar.d.ts +19 -0
- package/menubar/menubar.js +130 -0
- package/menubar/register.d.ts +1 -0
- package/menubar/register.js +4 -0
- package/number-field/index.d.ts +1 -0
- package/number-field/index.js +1 -0
- package/number-field/number-field.d.ts +34 -0
- package/number-field/number-field.js +326 -0
- package/number-field/register.d.ts +1 -0
- package/number-field/register.js +4 -0
- package/package.json +217 -0
- package/page-inset/index.d.ts +1 -0
- package/page-inset/index.js +1 -0
- package/page-inset/page-inset.d.ts +28 -0
- package/page-inset/page-inset.js +103 -0
- package/page-inset/register.d.ts +1 -0
- package/page-inset/register.js +4 -0
- package/popover/index.d.ts +6 -0
- package/popover/index.js +4 -0
- package/popover/popover-close.d.ts +13 -0
- package/popover/popover-close.js +33 -0
- package/popover/popover-context.d.ts +17 -0
- package/popover/popover-context.js +3 -0
- package/popover/popover-popup.d.ts +20 -0
- package/popover/popover-popup.js +176 -0
- package/popover/popover-trigger.d.ts +13 -0
- package/popover/popover-trigger.js +57 -0
- package/popover/popover.d.ts +30 -0
- package/popover/popover.js +140 -0
- package/popover/register.d.ts +1 -0
- package/popover/register.js +16 -0
- package/portal/index.d.ts +2 -0
- package/portal/index.js +1 -0
- package/portal/portal.d.ts +29 -0
- package/portal/portal.js +115 -0
- package/portal/register.d.ts +1 -0
- package/portal/register.js +4 -0
- package/preview-card/index.d.ts +5 -0
- package/preview-card/index.js +3 -0
- package/preview-card/preview-card-context.d.ts +16 -0
- package/preview-card/preview-card-context.js +3 -0
- package/preview-card/preview-card-popup.d.ts +16 -0
- package/preview-card/preview-card-popup.js +167 -0
- package/preview-card/preview-card-trigger.d.ts +13 -0
- package/preview-card/preview-card-trigger.js +75 -0
- package/preview-card/preview-card.d.ts +34 -0
- package/preview-card/preview-card.js +164 -0
- package/preview-card/register.d.ts +1 -0
- package/preview-card/register.js +12 -0
- package/progress/index.d.ts +1 -0
- package/progress/index.js +1 -0
- package/progress/progress.d.ts +19 -0
- package/progress/progress.js +94 -0
- package/progress/register.d.ts +1 -0
- package/progress/register.js +4 -0
- package/radio/index.d.ts +3 -0
- package/radio/index.js +2 -0
- package/radio/radio-group-context.d.ts +11 -0
- package/radio/radio-group-context.js +2 -0
- package/radio/radio-group.d.ts +37 -0
- package/radio/radio-group.js +135 -0
- package/radio/radio.d.ts +27 -0
- package/radio/radio.js +204 -0
- package/radio/register.d.ts +1 -0
- package/radio/register.js +8 -0
- package/scroll-area/index.d.ts +1 -0
- package/scroll-area/index.js +1 -0
- package/scroll-area/register.d.ts +1 -0
- package/scroll-area/register.js +4 -0
- package/scroll-area/scroll-area.d.ts +38 -0
- package/scroll-area/scroll-area.js +453 -0
- package/select/index.d.ts +2 -0
- package/select/index.js +1 -0
- package/select/register.d.ts +1 -0
- package/select/register.js +4 -0
- package/select/select.d.ts +36 -0
- package/select/select.js +404 -0
- package/separator/index.d.ts +1 -0
- package/separator/index.js +1 -0
- package/separator/register.d.ts +1 -0
- package/separator/register.js +4 -0
- package/separator/separator.d.ts +12 -0
- package/separator/separator.js +50 -0
- package/sidebar/index.d.ts +16 -0
- package/sidebar/index.js +13 -0
- package/sidebar/register.d.ts +1 -0
- package/sidebar/register.js +52 -0
- package/sidebar/sidebar-content.d.ts +14 -0
- package/sidebar/sidebar-content.js +30 -0
- package/sidebar/sidebar-context.d.ts +15 -0
- package/sidebar/sidebar-context.js +3 -0
- package/sidebar/sidebar-footer.d.ts +12 -0
- package/sidebar/sidebar-footer.js +21 -0
- package/sidebar/sidebar-group-label.d.ts +17 -0
- package/sidebar/sidebar-group-label.js +49 -0
- package/sidebar/sidebar-group.d.ts +15 -0
- package/sidebar/sidebar-group.js +29 -0
- package/sidebar/sidebar-header.d.ts +12 -0
- package/sidebar/sidebar-header.js +21 -0
- package/sidebar/sidebar-inset.d.ts +15 -0
- package/sidebar/sidebar-inset.js +29 -0
- package/sidebar/sidebar-menu-button.d.ts +31 -0
- package/sidebar/sidebar-menu-button.js +201 -0
- package/sidebar/sidebar-menu-item.d.ts +12 -0
- package/sidebar/sidebar-menu-item.js +20 -0
- package/sidebar/sidebar-menu.d.ts +14 -0
- package/sidebar/sidebar-menu.js +30 -0
- package/sidebar/sidebar-provider.d.ts +34 -0
- package/sidebar/sidebar-provider.js +157 -0
- package/sidebar/sidebar-separator.d.ts +12 -0
- package/sidebar/sidebar-separator.js +24 -0
- package/sidebar/sidebar-trigger.d.ts +16 -0
- package/sidebar/sidebar-trigger.js +50 -0
- package/sidebar/sidebar.d.ts +21 -0
- package/sidebar/sidebar.js +228 -0
- package/slider/index.d.ts +1 -0
- package/slider/index.js +1 -0
- package/slider/register.d.ts +1 -0
- package/slider/register.js +4 -0
- package/slider/slider.d.ts +37 -0
- package/slider/slider.js +268 -0
- package/spinner/index.d.ts +1 -0
- package/spinner/index.js +1 -0
- package/spinner/register.d.ts +1 -0
- package/spinner/register.js +4 -0
- package/spinner/spinner.d.ts +18 -0
- package/spinner/spinner.js +138 -0
- package/switch/index.d.ts +1 -0
- package/switch/index.js +1 -0
- package/switch/register.d.ts +1 -0
- package/switch/register.js +4 -0
- package/switch/switch.d.ts +29 -0
- package/switch/switch.js +201 -0
- package/tabs/index.d.ts +6 -0
- package/tabs/index.js +5 -0
- package/tabs/register.d.ts +1 -0
- package/tabs/register.js +10 -0
- package/tabs/tab.d.ts +16 -0
- package/tabs/tab.js +98 -0
- package/tabs/tabs-context.d.ts +8 -0
- package/tabs/tabs-context.js +2 -0
- package/tabs/tabs-indicator.d.ts +11 -0
- package/tabs/tabs-indicator.js +27 -0
- package/tabs/tabs-list.d.ts +17 -0
- package/tabs/tabs-list.js +85 -0
- package/tabs/tabs-panel.d.ts +18 -0
- package/tabs/tabs-panel.js +85 -0
- package/tabs/tabs.d.ts +24 -0
- package/tabs/tabs.js +111 -0
- package/textarea/index.d.ts +2 -0
- package/textarea/index.js +1 -0
- package/textarea/register.d.ts +1 -0
- package/textarea/register.js +4 -0
- package/textarea/textarea.d.ts +37 -0
- package/textarea/textarea.js +170 -0
- package/toggle/index.d.ts +3 -0
- package/toggle/index.js +2 -0
- package/toggle/register.d.ts +1 -0
- package/toggle/register.js +8 -0
- package/toggle/toggle-group-context.d.ts +9 -0
- package/toggle/toggle-group-context.js +2 -0
- package/toggle/toggle-group.d.ts +27 -0
- package/toggle/toggle-group.js +163 -0
- package/toggle/toggle.d.ts +25 -0
- package/toggle/toggle.js +124 -0
- package/toolbar/index.d.ts +1 -0
- package/toolbar/index.js +1 -0
- package/toolbar/register.d.ts +1 -0
- package/toolbar/register.js +4 -0
- package/toolbar/toolbar.d.ts +15 -0
- package/toolbar/toolbar.js +89 -0
- package/tooltip/index.d.ts +5 -0
- package/tooltip/index.js +3 -0
- package/tooltip/register.d.ts +1 -0
- package/tooltip/register.js +12 -0
- package/tooltip/tooltip-context.d.ts +17 -0
- package/tooltip/tooltip-context.js +3 -0
- package/tooltip/tooltip-popup.d.ts +16 -0
- package/tooltip/tooltip-popup.js +162 -0
- package/tooltip/tooltip-trigger.d.ts +15 -0
- package/tooltip/tooltip-trigger.js +110 -0
- package/tooltip/tooltip.d.ts +36 -0
- package/tooltip/tooltip.js +176 -0
- package/trunc/index.d.ts +1 -0
- package/trunc/index.js +1 -0
- package/trunc/register.d.ts +1 -0
- package/trunc/register.js +4 -0
- package/trunc/trunc.d.ts +19 -0
- package/trunc/trunc.js +68 -0
- package/vstack/index.d.ts +1 -0
- package/vstack/index.js +1 -0
- package/vstack/register.d.ts +1 -0
- package/vstack/register.js +4 -0
- package/vstack/vstack.d.ts +17 -0
- package/vstack/vstack.js +83 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
/** Ported from original DUI: deep-future-app/app/client/components/dui/data-table */
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
import { css, html, LitElement, nothing } from "lit";
|
|
9
|
+
import { property } from "lit/decorators.js";
|
|
10
|
+
import { repeat } from "lit/directives/repeat.js";
|
|
11
|
+
import { styleMap } from "lit/directives/style-map.js";
|
|
12
|
+
import { base } from "@deepfuture/dui-core/base";
|
|
13
|
+
import { customEvent } from "@deepfuture/dui-core/event";
|
|
14
|
+
// ── Events ─────────────────────────────────────────────────────────────
|
|
15
|
+
export const sortChangeEvent = customEvent("sort-change", {
|
|
16
|
+
bubbles: true,
|
|
17
|
+
composed: true,
|
|
18
|
+
});
|
|
19
|
+
export const pageChangeEvent = customEvent("page-change", {
|
|
20
|
+
bubbles: true,
|
|
21
|
+
composed: true,
|
|
22
|
+
});
|
|
23
|
+
// ── Inline SVG sort icons ──────────────────────────────────────────────
|
|
24
|
+
const chevronUpDown = html `<svg
|
|
25
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
26
|
+
width="100%"
|
|
27
|
+
height="100%"
|
|
28
|
+
viewBox="0 0 24 24"
|
|
29
|
+
fill="none"
|
|
30
|
+
stroke="currentColor"
|
|
31
|
+
stroke-width="2"
|
|
32
|
+
stroke-linecap="round"
|
|
33
|
+
stroke-linejoin="round"
|
|
34
|
+
>
|
|
35
|
+
<path d="m7 15 5 5 5-5" />
|
|
36
|
+
<path d="m7 9 5-5 5 5" />
|
|
37
|
+
</svg>`;
|
|
38
|
+
const chevronUp = html `<svg
|
|
39
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
40
|
+
width="100%"
|
|
41
|
+
height="100%"
|
|
42
|
+
viewBox="0 0 24 24"
|
|
43
|
+
fill="none"
|
|
44
|
+
stroke="currentColor"
|
|
45
|
+
stroke-width="2"
|
|
46
|
+
stroke-linecap="round"
|
|
47
|
+
stroke-linejoin="round"
|
|
48
|
+
>
|
|
49
|
+
<path d="m18 15-6-6-6 6" />
|
|
50
|
+
</svg>`;
|
|
51
|
+
const chevronDown = html `<svg
|
|
52
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
53
|
+
width="100%"
|
|
54
|
+
height="100%"
|
|
55
|
+
viewBox="0 0 24 24"
|
|
56
|
+
fill="none"
|
|
57
|
+
stroke="currentColor"
|
|
58
|
+
stroke-width="2"
|
|
59
|
+
stroke-linecap="round"
|
|
60
|
+
stroke-linejoin="round"
|
|
61
|
+
>
|
|
62
|
+
<path d="m6 9 6 6 6-6" />
|
|
63
|
+
</svg>`;
|
|
64
|
+
// ── Pure helpers ────────────────────────────────────────────────────────
|
|
65
|
+
function compareValues(a, b) {
|
|
66
|
+
if (a == null && b == null)
|
|
67
|
+
return 0;
|
|
68
|
+
if (a == null)
|
|
69
|
+
return -1;
|
|
70
|
+
if (b == null)
|
|
71
|
+
return 1;
|
|
72
|
+
if (typeof a === "number" && typeof b === "number")
|
|
73
|
+
return a - b;
|
|
74
|
+
if (typeof a === "string" && typeof b === "string")
|
|
75
|
+
return a.localeCompare(b);
|
|
76
|
+
if (a instanceof Date && b instanceof Date)
|
|
77
|
+
return a.getTime() - b.getTime();
|
|
78
|
+
return String(a).localeCompare(String(b));
|
|
79
|
+
}
|
|
80
|
+
function sortData(data, sort) {
|
|
81
|
+
if (!sort)
|
|
82
|
+
return [...data];
|
|
83
|
+
const { column, direction } = sort;
|
|
84
|
+
const multiplier = direction === "asc" ? 1 : -1;
|
|
85
|
+
return [...data].sort((a, b) => multiplier * compareValues(a[column], b[column]));
|
|
86
|
+
}
|
|
87
|
+
function paginateData(data, page, pageSize) {
|
|
88
|
+
const start = (page - 1) * pageSize;
|
|
89
|
+
return data.slice(start, start + pageSize);
|
|
90
|
+
}
|
|
91
|
+
// ── Styles ─────────────────────────────────────────────────────────────
|
|
92
|
+
const hostStyles = css `
|
|
93
|
+
:host {
|
|
94
|
+
display: block;
|
|
95
|
+
}
|
|
96
|
+
`;
|
|
97
|
+
const componentStyles = css `
|
|
98
|
+
.DataTable {
|
|
99
|
+
display: flex;
|
|
100
|
+
flex-direction: column;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.TableWindow {
|
|
104
|
+
overflow: auto;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
table {
|
|
108
|
+
border-collapse: collapse;
|
|
109
|
+
min-width: 100%;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
thead {
|
|
113
|
+
position: sticky;
|
|
114
|
+
top: 0;
|
|
115
|
+
z-index: 1;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
th {
|
|
119
|
+
text-align: left;
|
|
120
|
+
white-space: nowrap;
|
|
121
|
+
user-select: none;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
th[aria-sort] {
|
|
125
|
+
cursor: pointer;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.HeaderContent {
|
|
129
|
+
display: inline-flex;
|
|
130
|
+
align-items: center;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.SortIcon {
|
|
134
|
+
display: inline-flex;
|
|
135
|
+
flex-shrink: 0;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
tbody tr {
|
|
139
|
+
transition-property: background, filter, transform;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.Pagination {
|
|
143
|
+
display: flex;
|
|
144
|
+
align-items: center;
|
|
145
|
+
justify-content: space-between;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.PageInfo {
|
|
149
|
+
display: flex;
|
|
150
|
+
align-items: center;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.PageControls {
|
|
154
|
+
display: flex;
|
|
155
|
+
align-items: center;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.PageButton {
|
|
159
|
+
display: inline-flex;
|
|
160
|
+
align-items: center;
|
|
161
|
+
justify-content: center;
|
|
162
|
+
cursor: pointer;
|
|
163
|
+
border: none;
|
|
164
|
+
background: transparent;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.PageButton:disabled {
|
|
168
|
+
cursor: not-allowed;
|
|
169
|
+
}
|
|
170
|
+
`;
|
|
171
|
+
// ── Component ──────────────────────────────────────────────────────────
|
|
172
|
+
/**
|
|
173
|
+
* `<dui-data-table>` — A sortable, paginated data table.
|
|
174
|
+
*
|
|
175
|
+
* Accepts column definitions and row data, with optional sorting and
|
|
176
|
+
* pagination. Cells can be customized via column `render` functions.
|
|
177
|
+
*
|
|
178
|
+
* @fires sort-change - Fired when a sortable column header is clicked. Detail: SortState
|
|
179
|
+
* @fires page-change - Fired when the page changes. Detail: PageState
|
|
180
|
+
*/
|
|
181
|
+
export class DuiDataTable extends LitElement {
|
|
182
|
+
static { this.tagName = "dui-data-table"; }
|
|
183
|
+
static { this.styles = [base, hostStyles, componentStyles]; }
|
|
184
|
+
#columns_accessor_storage = [];
|
|
185
|
+
/** Column definitions describing each visible column. */
|
|
186
|
+
get columns() { return this.#columns_accessor_storage; }
|
|
187
|
+
set columns(value) { this.#columns_accessor_storage = value; }
|
|
188
|
+
#data_accessor_storage = [];
|
|
189
|
+
/** The full data array. Sorting and pagination are applied internally. */
|
|
190
|
+
get data() { return this.#data_accessor_storage; }
|
|
191
|
+
set data(value) { this.#data_accessor_storage = value; }
|
|
192
|
+
#pageSize_accessor_storage = 10;
|
|
193
|
+
/** Number of rows per page. Set to 0 to disable pagination. */
|
|
194
|
+
get pageSize() { return this.#pageSize_accessor_storage; }
|
|
195
|
+
set pageSize(value) { this.#pageSize_accessor_storage = value; }
|
|
196
|
+
#rowKey_accessor_storage = undefined;
|
|
197
|
+
/** Key function to derive a unique identifier from each row. */
|
|
198
|
+
get rowKey() { return this.#rowKey_accessor_storage; }
|
|
199
|
+
set rowKey(value) { this.#rowKey_accessor_storage = value; }
|
|
200
|
+
#emptyText_accessor_storage = "No results.";
|
|
201
|
+
/** Text shown when the data array is empty. */
|
|
202
|
+
get emptyText() { return this.#emptyText_accessor_storage; }
|
|
203
|
+
set emptyText(value) { this.#emptyText_accessor_storage = value; }
|
|
204
|
+
#sort_accessor_storage = null;
|
|
205
|
+
get #sort() { return this.#sort_accessor_storage; }
|
|
206
|
+
set #sort(value) { this.#sort_accessor_storage = value; }
|
|
207
|
+
#page_accessor_storage = 1;
|
|
208
|
+
get #page() { return this.#page_accessor_storage; }
|
|
209
|
+
set #page(value) { this.#page_accessor_storage = value; }
|
|
210
|
+
#displayRows_accessor_storage = [];
|
|
211
|
+
get #displayRows() { return this.#displayRows_accessor_storage; }
|
|
212
|
+
set #displayRows(value) { this.#displayRows_accessor_storage = value; }
|
|
213
|
+
// ── Lifecycle ──────────────────────────────────────────────────────
|
|
214
|
+
willUpdate(changed) {
|
|
215
|
+
// Recompute display rows when data, sort, page, or pageSize change.
|
|
216
|
+
if (changed.has("data") ||
|
|
217
|
+
changed.has("pageSize") ||
|
|
218
|
+
changed.has("#sort") ||
|
|
219
|
+
changed.has("#page")) {
|
|
220
|
+
// Reset page when data changes.
|
|
221
|
+
if (changed.has("data")) {
|
|
222
|
+
this.#page = 1;
|
|
223
|
+
}
|
|
224
|
+
const sorted = sortData(this.data, this.#sort);
|
|
225
|
+
if (this.pageSize > 0) {
|
|
226
|
+
this.#displayRows = paginateData(sorted, this.#page, this.pageSize);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
this.#displayRows = sorted;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// ── Computed ───────────────────────────────────────────────────────
|
|
234
|
+
get #totalPages() {
|
|
235
|
+
if (this.pageSize <= 0)
|
|
236
|
+
return 1;
|
|
237
|
+
return Math.max(1, Math.ceil(this.data.length / this.pageSize));
|
|
238
|
+
}
|
|
239
|
+
get #pageState() {
|
|
240
|
+
return {
|
|
241
|
+
page: this.#page,
|
|
242
|
+
pageSize: this.pageSize,
|
|
243
|
+
totalRows: this.data.length,
|
|
244
|
+
totalPages: this.#totalPages,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
// ── Sort handling ─────────────────────────────────────────────────
|
|
248
|
+
#handleSort(column) {
|
|
249
|
+
if (this.#sort?.column === column) {
|
|
250
|
+
if (this.#sort.direction === "asc") {
|
|
251
|
+
this.#sort = { column, direction: "desc" };
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
// desc → clear
|
|
255
|
+
this.#sort = null;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
this.#sort = { column, direction: "asc" };
|
|
260
|
+
}
|
|
261
|
+
this.#page = 1;
|
|
262
|
+
this.dispatchEvent(sortChangeEvent(this.#sort));
|
|
263
|
+
}
|
|
264
|
+
// ── Pagination handling ───────────────────────────────────────────
|
|
265
|
+
#goToPage(page) {
|
|
266
|
+
this.#page = Math.max(1, Math.min(page, this.#totalPages));
|
|
267
|
+
this.dispatchEvent(pageChangeEvent(this.#pageState));
|
|
268
|
+
}
|
|
269
|
+
// ── Render ────────────────────────────────────────────────────────
|
|
270
|
+
#renderSortIcon(column) {
|
|
271
|
+
if (!column.sortable)
|
|
272
|
+
return nothing;
|
|
273
|
+
if (this.#sort?.column === column.key) {
|
|
274
|
+
return html `<span class="SortIcon"
|
|
275
|
+
>${this.#sort.direction === "asc" ? chevronUp : chevronDown}</span
|
|
276
|
+
>`;
|
|
277
|
+
}
|
|
278
|
+
return html `<span class="SortIcon">${chevronUpDown}</span>`;
|
|
279
|
+
}
|
|
280
|
+
#renderHeader() {
|
|
281
|
+
return html `
|
|
282
|
+
<thead>
|
|
283
|
+
<tr>
|
|
284
|
+
${this.columns.map((col) => {
|
|
285
|
+
const style = col.width ? { width: col.width } : {};
|
|
286
|
+
const sortAttr = col.sortable
|
|
287
|
+
? this.#sort?.column === col.key
|
|
288
|
+
? this.#sort.direction === "asc"
|
|
289
|
+
? "ascending"
|
|
290
|
+
: "descending"
|
|
291
|
+
: "none"
|
|
292
|
+
: undefined;
|
|
293
|
+
return html `
|
|
294
|
+
<th
|
|
295
|
+
style=${styleMap(style)}
|
|
296
|
+
aria-sort=${sortAttr ?? nothing}
|
|
297
|
+
@click=${col.sortable
|
|
298
|
+
? () => this.#handleSort(col.key)
|
|
299
|
+
: nothing}
|
|
300
|
+
>
|
|
301
|
+
<span class="HeaderContent">
|
|
302
|
+
${col.header} ${this.#renderSortIcon(col)}
|
|
303
|
+
</span>
|
|
304
|
+
</th>
|
|
305
|
+
`;
|
|
306
|
+
})}
|
|
307
|
+
</tr>
|
|
308
|
+
</thead>
|
|
309
|
+
`;
|
|
310
|
+
}
|
|
311
|
+
#renderBody() {
|
|
312
|
+
if (this.#displayRows.length === 0) {
|
|
313
|
+
return html `
|
|
314
|
+
<tbody>
|
|
315
|
+
<tr class="EmptyRow">
|
|
316
|
+
<td colspan=${this.columns.length}>${this.emptyText}</td>
|
|
317
|
+
</tr>
|
|
318
|
+
</tbody>
|
|
319
|
+
`;
|
|
320
|
+
}
|
|
321
|
+
const keyFn = this.rowKey
|
|
322
|
+
? (row, index) => this.rowKey(row)
|
|
323
|
+
: (_row, index) => index;
|
|
324
|
+
return html `
|
|
325
|
+
<tbody>
|
|
326
|
+
${repeat(this.#displayRows, keyFn, (row) => html `
|
|
327
|
+
<tr>
|
|
328
|
+
${this.columns.map((col) => {
|
|
329
|
+
const value = row[col.key];
|
|
330
|
+
const content = col.render
|
|
331
|
+
? col.render(value, row)
|
|
332
|
+
: (value ?? "");
|
|
333
|
+
return html `<td>${content}</td>`;
|
|
334
|
+
})}
|
|
335
|
+
</tr>
|
|
336
|
+
`)}
|
|
337
|
+
</tbody>
|
|
338
|
+
`;
|
|
339
|
+
}
|
|
340
|
+
#renderPagination() {
|
|
341
|
+
if (this.pageSize <= 0 || this.data.length === 0)
|
|
342
|
+
return nothing;
|
|
343
|
+
const start = (this.#page - 1) * this.pageSize + 1;
|
|
344
|
+
const end = Math.min(this.#page * this.pageSize, this.data.length);
|
|
345
|
+
const isFirst = this.#page === 1;
|
|
346
|
+
const isLast = this.#page === this.#totalPages;
|
|
347
|
+
return html `
|
|
348
|
+
<div class="Pagination" part="pagination">
|
|
349
|
+
<div class="PageInfo">
|
|
350
|
+
<span>${start}-${end} of ${this.data.length}</span>
|
|
351
|
+
</div>
|
|
352
|
+
<div class="PageControls">
|
|
353
|
+
<button
|
|
354
|
+
class="PageButton"
|
|
355
|
+
?disabled=${isFirst}
|
|
356
|
+
@click=${() => this.#goToPage(1)}
|
|
357
|
+
aria-label="First page"
|
|
358
|
+
>
|
|
359
|
+
<dui-icon style="--icon-size: var(--font-size-sm)"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m11 17-5-5 5-5"/><path d="m18 17-5-5 5-5"/></svg></dui-icon>
|
|
360
|
+
</button>
|
|
361
|
+
<button
|
|
362
|
+
class="PageButton"
|
|
363
|
+
?disabled=${isFirst}
|
|
364
|
+
@click=${() => this.#goToPage(this.#page - 1)}
|
|
365
|
+
aria-label="Previous page"
|
|
366
|
+
>
|
|
367
|
+
<dui-icon style="--icon-size: var(--font-size-sm)"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg></dui-icon>
|
|
368
|
+
</button>
|
|
369
|
+
<button
|
|
370
|
+
class="PageButton"
|
|
371
|
+
?disabled=${isLast}
|
|
372
|
+
@click=${() => this.#goToPage(this.#page + 1)}
|
|
373
|
+
aria-label="Next page"
|
|
374
|
+
>
|
|
375
|
+
<dui-icon style="--icon-size: var(--font-size-sm)"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></dui-icon>
|
|
376
|
+
</button>
|
|
377
|
+
<button
|
|
378
|
+
class="PageButton"
|
|
379
|
+
?disabled=${isLast}
|
|
380
|
+
@click=${() => this.#goToPage(this.#totalPages)}
|
|
381
|
+
aria-label="Last page"
|
|
382
|
+
>
|
|
383
|
+
<dui-icon style="--icon-size: var(--font-size-sm)"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 17 5-5-5-5"/><path d="m13 17 5-5-5-5"/></svg></dui-icon>
|
|
384
|
+
</button>
|
|
385
|
+
</div>
|
|
386
|
+
</div>
|
|
387
|
+
`;
|
|
388
|
+
}
|
|
389
|
+
render() {
|
|
390
|
+
return html `
|
|
391
|
+
<div class="DataTable" part="root">
|
|
392
|
+
<div class="TableWindow" part="table-window">
|
|
393
|
+
<table part="table">
|
|
394
|
+
${this.#renderHeader()} ${this.#renderBody()}
|
|
395
|
+
</table>
|
|
396
|
+
</div>
|
|
397
|
+
${this.#renderPagination()}
|
|
398
|
+
</div>
|
|
399
|
+
`;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
__decorate([
|
|
403
|
+
property({ attribute: false })
|
|
404
|
+
], DuiDataTable.prototype, "columns", null);
|
|
405
|
+
__decorate([
|
|
406
|
+
property({ attribute: false })
|
|
407
|
+
], DuiDataTable.prototype, "data", null);
|
|
408
|
+
__decorate([
|
|
409
|
+
property({ type: Number, attribute: "page-size" })
|
|
410
|
+
], DuiDataTable.prototype, "pageSize", null);
|
|
411
|
+
__decorate([
|
|
412
|
+
property({ attribute: false })
|
|
413
|
+
], DuiDataTable.prototype, "rowKey", null);
|
|
414
|
+
__decorate([
|
|
415
|
+
property({ attribute: "empty-text" })
|
|
416
|
+
], DuiDataTable.prototype, "emptyText", null);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DuiDataTable } from "./data-table.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Ported from original DUI: deep-future-app/app/client/components/dui/dialog */
|
|
2
|
+
import { LitElement, type TemplateResult } from "lit";
|
|
3
|
+
/**
|
|
4
|
+
* `<dui-dialog-close>` — A close button wrapper for the dialog.
|
|
5
|
+
*
|
|
6
|
+
* Wraps slotted content and closes the dialog on click.
|
|
7
|
+
*
|
|
8
|
+
* @slot - Content that closes the dialog (usually a button).
|
|
9
|
+
*/
|
|
10
|
+
export declare class DuiDialogClose extends LitElement {
|
|
11
|
+
#private;
|
|
12
|
+
static tagName: "dui-dialog-close";
|
|
13
|
+
static styles: import("lit").CSSResult[];
|
|
14
|
+
render(): TemplateResult;
|
|
15
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Ported from original DUI: deep-future-app/app/client/components/dui/dialog */
|
|
2
|
+
import { css, html, LitElement } from "lit";
|
|
3
|
+
import { ContextConsumer } from "@lit/context";
|
|
4
|
+
import { base } from "@deepfuture/dui-core/base";
|
|
5
|
+
import { dialogContext } from "./dialog-context.js";
|
|
6
|
+
const hostStyles = css `
|
|
7
|
+
:host {
|
|
8
|
+
display: contents;
|
|
9
|
+
}
|
|
10
|
+
`;
|
|
11
|
+
/**
|
|
12
|
+
* `<dui-dialog-close>` — A close button wrapper for the dialog.
|
|
13
|
+
*
|
|
14
|
+
* Wraps slotted content and closes the dialog on click.
|
|
15
|
+
*
|
|
16
|
+
* @slot - Content that closes the dialog (usually a button).
|
|
17
|
+
*/
|
|
18
|
+
export class DuiDialogClose extends LitElement {
|
|
19
|
+
static { this.tagName = "dui-dialog-close"; }
|
|
20
|
+
static { this.styles = [base, hostStyles]; }
|
|
21
|
+
#ctx = new ContextConsumer(this, {
|
|
22
|
+
context: dialogContext,
|
|
23
|
+
subscribe: true,
|
|
24
|
+
});
|
|
25
|
+
#handleClick = () => {
|
|
26
|
+
this.#ctx.value?.closeDialog();
|
|
27
|
+
};
|
|
28
|
+
render() {
|
|
29
|
+
return html `
|
|
30
|
+
<span @click="${this.#handleClick}">
|
|
31
|
+
<slot></slot>
|
|
32
|
+
</span>
|
|
33
|
+
`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Ported from original DUI: deep-future-app/app/client/components/dui/dialog */
|
|
2
|
+
export type DialogContext = {
|
|
3
|
+
readonly open: boolean;
|
|
4
|
+
readonly dialogId: string;
|
|
5
|
+
readonly triggerId: string;
|
|
6
|
+
readonly titleId: string;
|
|
7
|
+
readonly descriptionId: string;
|
|
8
|
+
readonly openDialog: () => void;
|
|
9
|
+
readonly closeDialog: () => void;
|
|
10
|
+
};
|
|
11
|
+
export declare const dialogContext: {
|
|
12
|
+
__context__: DialogContext;
|
|
13
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Ported from original DUI: deep-future-app/app/client/components/dui/dialog */
|
|
2
|
+
import { LitElement, type PropertyValues, type TemplateResult } from "lit";
|
|
3
|
+
/**
|
|
4
|
+
* `<dui-dialog-popup>` — The popup overlay for the dialog.
|
|
5
|
+
*
|
|
6
|
+
* Renders a backdrop and a centered dialog popup with focus trapping.
|
|
7
|
+
* Handles open/close animations via `data-starting-style` / `data-ending-style`.
|
|
8
|
+
* Closes on backdrop click (unlike `<dui-alert-dialog-popup>`).
|
|
9
|
+
*
|
|
10
|
+
* Title and description are provided via named slots and rendered as
|
|
11
|
+
* semantic `<h2>` and `<p>` elements with ARIA linkage.
|
|
12
|
+
*
|
|
13
|
+
* @slot title - Title text for the dialog (rendered as `<h2>`).
|
|
14
|
+
* @slot description - Description text for the dialog (rendered as `<p>`).
|
|
15
|
+
* @slot - Default slot for dialog content (actions, form fields, etc.).
|
|
16
|
+
* @csspart backdrop - The overlay backdrop behind the dialog.
|
|
17
|
+
* @csspart popup - The dialog popup container.
|
|
18
|
+
* @csspart title - The heading element wrapping the title slot.
|
|
19
|
+
* @csspart description - The paragraph element wrapping the description slot.
|
|
20
|
+
*/
|
|
21
|
+
export declare class DuiDialogPopup extends LitElement {
|
|
22
|
+
#private;
|
|
23
|
+
static tagName: "dui-dialog-popup";
|
|
24
|
+
static styles: import("lit").CSSResult[];
|
|
25
|
+
/** Keep the popup in the DOM when closed. */
|
|
26
|
+
accessor keepMounted: boolean;
|
|
27
|
+
/** CSS selector within the popup to focus when the dialog opens. */
|
|
28
|
+
accessor initialFocus: string | undefined;
|
|
29
|
+
/** CSS selector in the document to focus when the dialog closes. */
|
|
30
|
+
accessor finalFocus: string | undefined;
|
|
31
|
+
/** Width of the popup (CSS value, e.g. "32rem" or "600px"). Defaults to 24rem. */
|
|
32
|
+
accessor width: string | undefined;
|
|
33
|
+
updated(): void;
|
|
34
|
+
willUpdate(changed: PropertyValues): void;
|
|
35
|
+
render(): TemplateResult;
|
|
36
|
+
}
|