@warkypublic/svelix 0.1.46 → 0.2.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/README.md +93 -33
- package/dist/components/BetterMenu/BetterMenu.svelte +21 -37
- package/dist/components/BetterMenu/BetterMenuAsyncButton.svelte +21 -31
- package/dist/components/BetterMenu/BetterMenuPreview.svelte +27 -29
- package/dist/components/BetterMenu/MenuRenderer.svelte +40 -51
- package/dist/components/Boxer/Boxer.svelte +492 -602
- package/dist/components/Boxer/BoxerTarget.svelte +6 -46
- package/dist/components/Boxer/BoxerTarget.svelte.d.ts +1 -0
- package/dist/components/Boxer/types.d.ts +0 -1
- package/dist/components/Button.svelte +19 -43
- package/dist/components/ButtonPreview.svelte +2 -11
- package/dist/components/CardGrid/CardGrid.svelte +489 -614
- package/dist/components/CardGrid/CardGrid.svelte.d.ts +4 -0
- package/dist/components/CardGrid/CardGridFilterPanel.svelte +111 -90
- package/dist/components/CardGrid/DefaultCard.svelte +86 -97
- package/dist/components/CardGrid/DefaultCard.svelte.d.ts +1 -0
- package/dist/components/CardGrid/ImageCardStory.svelte +87 -36
- package/dist/components/CardGrid/cardGrid.d.ts +24 -0
- package/dist/components/CardGrid/cardGrid.js +20 -0
- package/dist/components/ContentEditor/CollaboraInsertTextDemo.svelte +5 -10
- package/dist/components/ContentEditor/ContentEditor.svelte +24 -50
- package/dist/components/ContentEditor/subcomponents/AudioPlayer.svelte +17 -17
- package/dist/components/ContentEditor/subcomponents/CollaboraEditor.svelte +244 -309
- package/dist/components/ContentEditor/subcomponents/EmailViewer.svelte +2 -3
- package/dist/components/ContentEditor/subcomponents/ImageViewer.svelte +14 -15
- package/dist/components/ContentEditor/subcomponents/MarkdownViewer.svelte +74 -90
- package/dist/components/ContentEditor/subcomponents/MonacoEditor.svelte +75 -103
- package/dist/components/ContentEditor/subcomponents/Office365Editor.svelte +234 -297
- package/dist/components/ContentEditor/subcomponents/PdfViewer.svelte +14 -20
- package/dist/components/ContentEditor/subcomponents/TextEditor.svelte +122 -150
- package/dist/components/ContentEditor/subcomponents/UnknownFile.svelte +105 -126
- package/dist/components/ContentEditor/subcomponents/VideoPlayer.svelte +17 -17
- package/dist/components/ContentEditor/subcomponents/ZipViewer.svelte +2 -3
- package/dist/components/ErrorBoundary/ErrorBoundary.svelte +41 -58
- package/dist/components/ErrorBoundary/ErrorBoundaryPreview.svelte +8 -16
- package/dist/components/Former/Former.svelte +306 -424
- package/dist/components/Former/FormerButtonArea.svelte +17 -68
- package/dist/components/Former/FormerDrawer.svelte +16 -80
- package/dist/components/Former/FormerDrawerPreview.svelte +99 -89
- package/dist/components/Former/FormerModal.svelte +16 -74
- package/dist/components/Former/FormerModalPreview.svelte +99 -89
- package/dist/components/Former/FormerPreview.svelte +76 -78
- package/dist/components/Former/FormerRestApiPreview.svelte +55 -48
- package/dist/components/Former/formerOverlayHelpers.svelte.d.ts +11 -0
- package/dist/components/Former/formerOverlayHelpers.svelte.js +38 -0
- package/dist/components/Former/index.d.ts +1 -0
- package/dist/components/Former/index.js +1 -0
- package/dist/components/FormerControllers/ButtonCtrl.svelte +13 -49
- package/dist/components/FormerControllers/CtrlFieldShell.svelte +15 -0
- package/dist/components/FormerControllers/CtrlFieldShell.svelte.d.ts +12 -0
- package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrl.svelte +285 -457
- package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrlCalendar.svelte +95 -136
- package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrlPickerPanel.svelte +3 -62
- package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrlTimeFields.svelte +143 -217
- package/dist/components/FormerControllers/IconButtonCtrl.svelte +13 -47
- package/dist/components/FormerControllers/InlineWrapper.svelte +12 -41
- package/dist/components/FormerControllers/InlineWrapperPreview.svelte +4 -26
- package/dist/components/FormerControllers/NativeSelectCtrl.svelte +7 -39
- package/dist/components/FormerControllers/NumberInputCtrl.svelte +21 -43
- package/dist/components/FormerControllers/PasswordInputCtrl.svelte +8 -33
- package/dist/components/FormerControllers/SwitchCtrl.svelte +4 -20
- package/dist/components/FormerControllers/TextAreaCtrl.svelte +7 -34
- package/dist/components/FormerControllers/TextInputCtrl.svelte +7 -34
- package/dist/components/FormerControllers/ctrlLoading.svelte.d.ts +8 -0
- package/dist/components/FormerControllers/ctrlLoading.svelte.js +43 -0
- package/dist/components/FormerControllers/index.d.ts +2 -0
- package/dist/components/FormerControllers/index.js +2 -0
- package/dist/components/FormerControllers/utils.d.ts +1 -0
- package/dist/components/FormerControllers/utils.js +3 -0
- package/dist/components/GlobalStateStore/GlobalStateStoreProvider.svelte +73 -120
- package/dist/components/Gridler/components/Gridler.svelte +344 -442
- package/dist/components/Gridler/components/GridlerCanvas.svelte +720 -1115
- package/dist/components/Gridler/components/GridlerEditor.svelte +2 -15
- package/dist/components/Gridler/components/GridlerFull.svelte +521 -841
- package/dist/components/Gridler/components/GridlerFull.svelte.d.ts +1 -1
- package/dist/components/Gridler/components/GridlerFullWithFormerPreview.svelte +194 -147
- package/dist/components/Gridler/components/GridlerSearch.svelte +7 -16
- package/dist/components/Gridler/components/GridlerSearchToggle.svelte +7 -19
- package/dist/components/Gridler/types.d.ts +1 -1
- package/dist/components/Gridler/utils/serverPaging.d.ts +1 -0
- package/dist/components/Gridler/utils/serverPaging.js +7 -0
- package/dist/components/Icons/IconAdd.svelte +1 -3
- package/dist/components/Icons/IconAlertCircle.svelte +1 -3
- package/dist/components/Icons/IconAlertTriangle.svelte +1 -3
- package/dist/components/Icons/IconCamera.svelte +1 -3
- package/dist/components/Icons/IconClose.svelte +1 -3
- package/dist/components/Icons/IconEdit.svelte +1 -3
- package/dist/components/Icons/IconFilter.svelte +1 -3
- package/dist/components/Icons/IconSearch.svelte +1 -3
- package/dist/components/Icons/IconSort.svelte +1 -3
- package/dist/components/Icons/IconTrash.svelte +1 -3
- package/dist/components/Portal/Portal.svelte +14 -38
- package/dist/components/Screenshot/Screenshot.svelte +7 -13
- package/dist/components/Svark/Svark.svelte +680 -852
- package/dist/components/Svark/SvarkContextMenu.svelte +44 -63
- package/dist/components/Svark/SvarkInfiniteLoader.svelte +2 -6
- package/dist/components/Svark/SvarkPager.svelte +2 -28
- package/dist/components/Svark/SvarkSelectionDemo.svelte +4 -8
- package/dist/components/Svark/SvarkTopBar.svelte +9 -74
- package/dist/components/SvarkGrid/SvarkGrid.svelte +877 -1123
- package/dist/components/SvarkGrid/components/SvarkColumnFilterForm.svelte +45 -58
- package/dist/components/SvarkGrid/components/SvarkContextMenu.svelte +44 -63
- package/dist/components/SvarkGrid/components/SvarkHeaderFilterCell.svelte +41 -75
- package/dist/components/SvarkGrid/components/SvarkInfiniteLoader.svelte +2 -6
- package/dist/components/SvarkGrid/components/SvarkPager.svelte +2 -28
- package/dist/components/SvarkGrid/components/SvarkSearchPopover.svelte +8 -16
- package/dist/components/SvarkGrid/components/SvarkTopBar.svelte +6 -62
- package/dist/components/SvarkGrid/internal/SvarkGridView.svelte +345 -507
- package/dist/components/VTree/VTree.svelte +454 -431
- package/dist/components/VTree/VTree.utils.d.ts +23 -0
- package/dist/components/VTree/VTree.utils.js +73 -0
- package/dist/components/VTree/VTreeContextMenu.svelte +21 -33
- package/dist/components/VTree/VTreeControlledSelectionDemo.svelte +20 -0
- package/dist/components/VTree/VTreeControlledSelectionDemo.svelte.d.ts +18 -0
- package/dist/components/VTree/VTreeCustomizationDemo.svelte +23 -0
- package/dist/components/VTree/VTreeCustomizationDemo.svelte.d.ts +18 -0
- package/dist/components/VTree/VTreeEventsDemo.svelte +48 -58
- package/dist/components/VTree/VTreeInteractionDemo.svelte +29 -0
- package/dist/components/VTree/VTreeInteractionDemo.svelte.d.ts +18 -0
- package/dist/components/VTree/VTreeMultiSelectDemo.svelte +27 -0
- package/dist/components/VTree/VTreeMultiSelectDemo.svelte.d.ts +18 -0
- package/dist/components/VTree/VTreeRow.svelte +77 -115
- package/dist/components/VTree/VTreeRow.svelte.d.ts +34 -18
- package/dist/components/VTree/VTreeSearch.svelte +6 -13
- package/dist/components/VTree/VTreeVirtualViewport.svelte +54 -143
- package/dist/components/VTree/VTreeVirtualViewport.svelte.d.ts +35 -18
- package/dist/components/VTree/types.d.ts +39 -1
- package/llm/COMPONENT_GUIDE.md +25 -0
- package/package.json +51 -50
|
@@ -53,8 +53,12 @@ interface Props {
|
|
|
53
53
|
onLoadError?: (error: string) => void;
|
|
54
54
|
class?: string;
|
|
55
55
|
toolbarEnd?: Snippet;
|
|
56
|
+
animate?: boolean;
|
|
57
|
+
density?: 'compact' | 'default' | 'comfortable' | 'spacious';
|
|
58
|
+
expand?: 'none' | 'medium' | 'large';
|
|
56
59
|
}
|
|
57
60
|
declare const CardGrid: import("svelte").Component<Props, {
|
|
61
|
+
selectItem: (uniqueIDValue: string) => boolean;
|
|
58
62
|
refresh: () => void;
|
|
59
63
|
}, "loading" | "total">;
|
|
60
64
|
type CardGrid = ReturnType<typeof CardGrid>;
|
|
@@ -1,96 +1,117 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
1
|
+
<script lang="ts">const { columns, filters, onApply, onCancel } = $props();
|
|
2
|
+
const ALL_OPERATORS = [
|
|
3
|
+
{
|
|
4
|
+
value: "contains",
|
|
5
|
+
label: "Contains"
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
value: "equals",
|
|
9
|
+
label: "Equals"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
value: "notEquals",
|
|
13
|
+
label: "Not equals"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
value: "startsWith",
|
|
17
|
+
label: "Starts with"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
value: "endsWith",
|
|
21
|
+
label: "Ends with"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
value: "greaterThan",
|
|
25
|
+
label: ">"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
value: "greaterThanOrEqual",
|
|
29
|
+
label: ">="
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
value: "lessThan",
|
|
33
|
+
label: "<"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
value: "lessThanOrEqual",
|
|
37
|
+
label: "<="
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
value: "between",
|
|
41
|
+
label: "Between"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
value: "notBetween",
|
|
45
|
+
label: "Not between"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
value: "in",
|
|
49
|
+
label: "In (comma-sep)"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
value: "notIn",
|
|
53
|
+
label: "Not in"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
value: "isNull",
|
|
57
|
+
label: "Is empty"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
value: "isNotNull",
|
|
61
|
+
label: "Is not empty"
|
|
41
62
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
next[row.colId] = entry;
|
|
63
|
+
];
|
|
64
|
+
const filterableColumns = $derived(columns.filter((c) => !c.disableFilter));
|
|
65
|
+
function filtersToRows(f) {
|
|
66
|
+
return Object.entries(f).map(([colId, entry]) => ({
|
|
67
|
+
colId,
|
|
68
|
+
op: entry.op ?? "contains",
|
|
69
|
+
value: entry.value ?? "",
|
|
70
|
+
value2: entry.value2 ?? ""
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
let rows = $state([]);
|
|
74
|
+
$effect(() => {
|
|
75
|
+
rows = filtersToRows(filters);
|
|
76
|
+
});
|
|
77
|
+
function addRow() {
|
|
78
|
+
const firstCol = filterableColumns[0];
|
|
79
|
+
if (!firstCol) return;
|
|
80
|
+
rows = [...rows, {
|
|
81
|
+
colId: firstCol.id,
|
|
82
|
+
op: "contains",
|
|
83
|
+
value: "",
|
|
84
|
+
value2: ""
|
|
85
|
+
}];
|
|
86
|
+
}
|
|
87
|
+
function removeRow(index) {
|
|
88
|
+
rows = rows.filter((_, i) => i !== index);
|
|
89
|
+
}
|
|
90
|
+
function apply() {
|
|
91
|
+
const next = {};
|
|
92
|
+
for (const row of rows) {
|
|
93
|
+
if (!row.colId) continue;
|
|
94
|
+
const needsValue = row.op !== "isNull" && row.op !== "isNotNull";
|
|
95
|
+
if (needsValue && !row.value) continue;
|
|
96
|
+
const col = columns.find((c) => c.id === row.colId);
|
|
97
|
+
const entry = {
|
|
98
|
+
value: row.value,
|
|
99
|
+
op: row.op,
|
|
100
|
+
...col?.dataKey ? { dataKey: col.dataKey } : {}
|
|
101
|
+
};
|
|
102
|
+
if ((row.op === "between" || row.op === "notBetween") && row.value2) {
|
|
103
|
+
entry.value2 = row.value2;
|
|
84
104
|
}
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function clear() {
|
|
89
|
-
onApply({});
|
|
105
|
+
next[row.colId] = entry;
|
|
90
106
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
107
|
+
onApply(next);
|
|
108
|
+
}
|
|
109
|
+
function clear() {
|
|
110
|
+
onApply({});
|
|
111
|
+
}
|
|
112
|
+
const needsValue = (op) => op !== "isNull" && op !== "isNotNull";
|
|
113
|
+
const needsValue2 = (op) => op === "between" || op === "notBetween";
|
|
114
|
+
export {};
|
|
94
115
|
</script>
|
|
95
116
|
|
|
96
117
|
<div class="fp-panel">
|
|
@@ -1,106 +1,90 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
<script lang="ts">const { record, columns, selected, focused, expanded } = $props();
|
|
2
|
+
// First column → title, second → subtitle, rest → detail rows
|
|
3
|
+
const titleCol = $derived(columns[0]);
|
|
4
|
+
const subtitleCol = $derived(columns.length > 1 ? columns[1] : undefined);
|
|
5
|
+
const detailCols = $derived(columns.slice(subtitleCol ? 2 : 1));
|
|
6
|
+
function getVal(key, row) {
|
|
7
|
+
const parts = key.split(".");
|
|
8
|
+
let val = row;
|
|
9
|
+
for (const part of parts) {
|
|
10
|
+
if (val == null || typeof val !== "object") return undefined;
|
|
11
|
+
val = val[part];
|
|
9
12
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
val = (val as Record<string, unknown>)[part];
|
|
13
|
+
return val;
|
|
14
|
+
}
|
|
15
|
+
function formatVal(val, col) {
|
|
16
|
+
if (val == null || val === "") return "—";
|
|
17
|
+
switch (col.format) {
|
|
18
|
+
case "currency": {
|
|
19
|
+
const n = Number(val);
|
|
20
|
+
if (!isNaN(n)) return new Intl.NumberFormat(undefined, {
|
|
21
|
+
style: "currency",
|
|
22
|
+
currency: "ZAR",
|
|
23
|
+
maximumFractionDigits: 0
|
|
24
|
+
}).format(n);
|
|
25
|
+
break;
|
|
24
26
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
break;
|
|
45
|
-
}
|
|
46
|
-
case 'percentage': {
|
|
47
|
-
const n = Number(val);
|
|
48
|
-
if (!isNaN(n)) return `${(n * 100).toFixed(1)}%`;
|
|
49
|
-
break;
|
|
50
|
-
}
|
|
51
|
-
case 'date': {
|
|
52
|
-
const d = val instanceof Date ? val : new Date(String(val));
|
|
53
|
-
if (!isNaN(d.getTime())) return d.toLocaleDateString();
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
case 'datetime': {
|
|
57
|
-
const d = val instanceof Date ? val : new Date(String(val));
|
|
58
|
-
if (!isNaN(d.getTime())) return d.toLocaleString();
|
|
59
|
-
break;
|
|
60
|
-
}
|
|
27
|
+
case "number": {
|
|
28
|
+
const n = Number(val);
|
|
29
|
+
if (!isNaN(n)) return n.toLocaleString();
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
case "percentage": {
|
|
33
|
+
const n = Number(val);
|
|
34
|
+
if (!isNaN(n)) return `${(n * 100).toFixed(1)}%`;
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
case "date": {
|
|
38
|
+
const d = val instanceof Date ? val : new Date(String(val));
|
|
39
|
+
if (!isNaN(d.getTime())) return d.toLocaleDateString();
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
case "datetime": {
|
|
43
|
+
const d = val instanceof Date ? val : new Date(String(val));
|
|
44
|
+
if (!isNaN(d.getTime())) return d.toLocaleString();
|
|
45
|
+
break;
|
|
61
46
|
}
|
|
62
|
-
return String(val);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Status chip logic — keyed on common English status words
|
|
66
|
-
const STATUS_MAP: Record<string, 'success' | 'warning' | 'error' | 'neutral'> = {
|
|
67
|
-
active: 'success',
|
|
68
|
-
enabled: 'success',
|
|
69
|
-
approved: 'success',
|
|
70
|
-
confirmed: 'success',
|
|
71
|
-
completed: 'success',
|
|
72
|
-
done: 'success',
|
|
73
|
-
live: 'success',
|
|
74
|
-
pending: 'warning',
|
|
75
|
-
review: 'warning',
|
|
76
|
-
draft: 'warning',
|
|
77
|
-
in_progress: 'warning',
|
|
78
|
-
processing: 'warning',
|
|
79
|
-
queued: 'warning',
|
|
80
|
-
inactive: 'error',
|
|
81
|
-
disabled: 'error',
|
|
82
|
-
cancelled: 'error',
|
|
83
|
-
rejected: 'error',
|
|
84
|
-
failed: 'error',
|
|
85
|
-
error: 'error',
|
|
86
|
-
blocked: 'error',
|
|
87
|
-
archived: 'neutral',
|
|
88
|
-
closed: 'neutral',
|
|
89
|
-
deprecated: 'neutral',
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
function isStatusCol(col: CardGridColumn): boolean {
|
|
93
|
-
const id = col.id.toLowerCase();
|
|
94
|
-
return id.includes('status') || id.includes('state') || id === 'type';
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function statusVariant(val: unknown): 'success' | 'warning' | 'error' | 'neutral' | null {
|
|
98
|
-
if (val == null) return null;
|
|
99
|
-
return STATUS_MAP[String(val).toLowerCase().replace(/[\s-]/g, '_')] ?? null;
|
|
100
47
|
}
|
|
48
|
+
return String(val);
|
|
49
|
+
}
|
|
50
|
+
// Status chip logic — keyed on common English status words
|
|
51
|
+
const STATUS_MAP = {
|
|
52
|
+
active: "success",
|
|
53
|
+
enabled: "success",
|
|
54
|
+
approved: "success",
|
|
55
|
+
confirmed: "success",
|
|
56
|
+
completed: "success",
|
|
57
|
+
done: "success",
|
|
58
|
+
live: "success",
|
|
59
|
+
pending: "warning",
|
|
60
|
+
review: "warning",
|
|
61
|
+
draft: "warning",
|
|
62
|
+
in_progress: "warning",
|
|
63
|
+
processing: "warning",
|
|
64
|
+
queued: "warning",
|
|
65
|
+
inactive: "error",
|
|
66
|
+
disabled: "error",
|
|
67
|
+
cancelled: "error",
|
|
68
|
+
rejected: "error",
|
|
69
|
+
failed: "error",
|
|
70
|
+
error: "error",
|
|
71
|
+
blocked: "error",
|
|
72
|
+
archived: "neutral",
|
|
73
|
+
closed: "neutral",
|
|
74
|
+
deprecated: "neutral"
|
|
75
|
+
};
|
|
76
|
+
function isStatusCol(col) {
|
|
77
|
+
const id = col.id.toLowerCase();
|
|
78
|
+
return id.includes("status") || id.includes("state") || id === "type";
|
|
79
|
+
}
|
|
80
|
+
function statusVariant(val) {
|
|
81
|
+
if (val == null) return null;
|
|
82
|
+
return STATUS_MAP[String(val).toLowerCase().replace(/[\s-]/g, "_")] ?? null;
|
|
83
|
+
}
|
|
84
|
+
export {};
|
|
101
85
|
</script>
|
|
102
86
|
|
|
103
|
-
<article class="dc-card" class:dc-selected={selected} class:dc-focused={focused}>
|
|
87
|
+
<article class="dc-card" class:dc-selected={selected} class:dc-focused={focused} class:dc-expanded={expanded}>
|
|
104
88
|
<!-- Header -->
|
|
105
89
|
{#if titleCol}
|
|
106
90
|
{@const titleKey = titleCol.dataKey ?? titleCol.id}
|
|
@@ -148,6 +132,11 @@
|
|
|
148
132
|
flex-direction: column;
|
|
149
133
|
}
|
|
150
134
|
|
|
135
|
+
/* Expanded mode — merges front + back columns */
|
|
136
|
+
.dc-expanded {
|
|
137
|
+
--cg-colspan: span 2;
|
|
138
|
+
}
|
|
139
|
+
|
|
151
140
|
/* ── Header ───────────────────────────────────────────────────────── */
|
|
152
141
|
|
|
153
142
|
.dc-header {
|
|
@@ -1,39 +1,90 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
1
|
+
<script lang="ts">import CardGrid from "./CardGrid.svelte";
|
|
2
|
+
const columns = [
|
|
3
|
+
{
|
|
4
|
+
id: "id",
|
|
5
|
+
title: "ID",
|
|
6
|
+
disableSearch: true,
|
|
7
|
+
disableFilter: true
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
id: "title",
|
|
11
|
+
title: "Title"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: "photographer",
|
|
15
|
+
title: "Photographer"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "category",
|
|
19
|
+
title: "Category"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "likes",
|
|
23
|
+
title: "Likes",
|
|
24
|
+
format: "number"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "views",
|
|
28
|
+
title: "Views",
|
|
29
|
+
format: "number"
|
|
30
|
+
}
|
|
31
|
+
];
|
|
32
|
+
const sortOptions = [
|
|
33
|
+
{
|
|
34
|
+
columnId: "title",
|
|
35
|
+
label: "Title"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
columnId: "photographer",
|
|
39
|
+
label: "Photographer"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
columnId: "likes",
|
|
43
|
+
label: "Likes"
|
|
44
|
+
}
|
|
45
|
+
];
|
|
46
|
+
const CATEGORIES = [
|
|
47
|
+
"Architecture",
|
|
48
|
+
"Nature",
|
|
49
|
+
"People",
|
|
50
|
+
"Travel",
|
|
51
|
+
"Abstract",
|
|
52
|
+
"Animals"
|
|
53
|
+
];
|
|
54
|
+
const PHOTOGRAPHERS = [
|
|
55
|
+
"Alice Monroe",
|
|
56
|
+
"Ben Carter",
|
|
57
|
+
"Cara Lee",
|
|
58
|
+
"Daniel Park",
|
|
59
|
+
"Emma Rios",
|
|
60
|
+
"Felix Braun"
|
|
61
|
+
];
|
|
62
|
+
const TITLES = [
|
|
63
|
+
"Golden Hour",
|
|
64
|
+
"Morning Mist",
|
|
65
|
+
"Urban Jungle",
|
|
66
|
+
"Still Waters",
|
|
67
|
+
"First Light",
|
|
68
|
+
"Hidden Path",
|
|
69
|
+
"City Pulse",
|
|
70
|
+
"Wild Plains",
|
|
71
|
+
"Quiet Corner",
|
|
72
|
+
"Storm Front",
|
|
73
|
+
"Desert Bloom",
|
|
74
|
+
"Arctic Echo",
|
|
75
|
+
"Neon Drift",
|
|
76
|
+
"Forest Floor",
|
|
77
|
+
"Tidal Wave"
|
|
78
|
+
];
|
|
79
|
+
const data = Array.from({ length: 60 }, (_, i) => ({
|
|
80
|
+
id: i + 1,
|
|
81
|
+
title: `${TITLES[i % TITLES.length]} ${Math.floor(i / TITLES.length) || ""}`.trim(),
|
|
82
|
+
photographer: PHOTOGRAPHERS[i % PHOTOGRAPHERS.length],
|
|
83
|
+
category: CATEGORIES[i % CATEGORIES.length],
|
|
84
|
+
likes: Math.floor(Math.random() * 4800 + 200),
|
|
85
|
+
views: Math.floor(Math.random() * 48e3 + 2e3),
|
|
86
|
+
imageUrl: `https://picsum.photos/seed/${i + 1}/400/260`
|
|
87
|
+
}));
|
|
37
88
|
</script>
|
|
38
89
|
|
|
39
90
|
<!-- cardMaxFrontColumns=3 splits: front=[id,title,photographer], back=[category,likes,views] -->
|
|
@@ -31,3 +31,27 @@ export declare function rangeSelect(allItems: Record<string, unknown>[], anchorI
|
|
|
31
31
|
export declare function isItemSelected(selectedItems: Record<string, unknown>[], item: Record<string, unknown>, uniqueID: string): boolean;
|
|
32
32
|
/** Compute how many cards fit in a row given container width, min card width, and gap. */
|
|
33
33
|
export declare function computeColumnsInRow(containerWidth: number, cardMinWidth: number, gap: number): number;
|
|
34
|
+
/** Density mode for the card grid. */
|
|
35
|
+
export type CardGridDensity = 'compact' | 'default' | 'comfortable';
|
|
36
|
+
/** Expand mode for the card grid. */
|
|
37
|
+
export type CardGridExpand = 'none' | 'medium' | 'large';
|
|
38
|
+
/** Extended props interface including animation, density and expand controls. */
|
|
39
|
+
export interface CardGridAnimationProps {
|
|
40
|
+
/** Enable staggered entry/exit animations on cards (default true). */
|
|
41
|
+
animate?: boolean;
|
|
42
|
+
/** Duration of card entrance transitions in ms (default 200). */
|
|
43
|
+
animateDuration?: number;
|
|
44
|
+
}
|
|
45
|
+
/** Extended props interface including animation, density and expand controls. */
|
|
46
|
+
export interface CardGridDensityProps {
|
|
47
|
+
/** Density mode: compact(default), comfortable. Overrides cardMinWidth/gap when set. */
|
|
48
|
+
density?: CardGridDensity;
|
|
49
|
+
/** Expand mode: none, medium, large. Controls how much space each card occupies. */
|
|
50
|
+
expand?: CardGridExpand;
|
|
51
|
+
}
|
|
52
|
+
/** Build virtual rows from flat displayData, packing columnsInRow items per row. */
|
|
53
|
+
export declare function buildVirtualRows(displayData: Record<string, unknown>[], columnsInRow: number): Record<string, unknown>[][];
|
|
54
|
+
/** Match a search string against any hotfield column value. */
|
|
55
|
+
export declare function typeaheadMatch(searchValue: string, item: Record<string, unknown>, hotfields?: string[]): boolean;
|
|
56
|
+
export interface ExtendedCardGridProps extends CardGridAnimationProps, CardGridDensityProps {
|
|
57
|
+
}
|
|
@@ -19,3 +19,23 @@ export function isItemSelected(selectedItems, item, uniqueID) {
|
|
|
19
19
|
export function computeColumnsInRow(containerWidth, cardMinWidth, gap) {
|
|
20
20
|
return Math.max(1, Math.floor((containerWidth + gap) / (cardMinWidth + gap)));
|
|
21
21
|
}
|
|
22
|
+
/** Build virtual rows from flat displayData, packing columnsInRow items per row. */
|
|
23
|
+
export function buildVirtualRows(displayData, columnsInRow) {
|
|
24
|
+
const cols = Math.max(1, columnsInRow);
|
|
25
|
+
const rows = [];
|
|
26
|
+
for (let i = 0; i < displayData.length; i += cols) {
|
|
27
|
+
rows.push(displayData.slice(i, i + cols));
|
|
28
|
+
}
|
|
29
|
+
return rows;
|
|
30
|
+
}
|
|
31
|
+
/** Match a search string against any hotfield column value. */
|
|
32
|
+
export function typeaheadMatch(searchValue, item, hotfields) {
|
|
33
|
+
if (!searchValue)
|
|
34
|
+
return true;
|
|
35
|
+
const lower = searchValue.toLowerCase();
|
|
36
|
+
if (hotfields && hotfields.length > 0) {
|
|
37
|
+
return Object.entries(item).some(([k, v]) => hotfields.some((f) => k === f || k.endsWith(`.${f}`)) &&
|
|
38
|
+
String(v ?? '').toLowerCase().includes(lower));
|
|
39
|
+
}
|
|
40
|
+
return Object.values(item).some((v) => String(v ?? '').toLowerCase().includes(lower));
|
|
41
|
+
}
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
$props();
|
|
7
|
-
|
|
8
|
-
let insertText = $state<((text: string) => void) | undefined>();
|
|
9
|
-
let insertHtml = $state<((html: string) => void) | undefined>();
|
|
10
|
-
let inputText = $state("Hello from Storybook!");
|
|
1
|
+
<script lang="ts">import ContentEditor from "./ContentEditor.svelte";
|
|
2
|
+
let { value, filename, wopiUrl, discoverUrl, adminKey, userid, username } = $props();
|
|
3
|
+
let insertText = $state();
|
|
4
|
+
let insertHtml = $state();
|
|
5
|
+
let inputText = $state("Hello from Storybook!");
|
|
11
6
|
</script>
|
|
12
7
|
|
|
13
8
|
<div style="display:flex;flex-direction:column;height:100vh;">
|