@warkypublic/svelix 0.1.46 → 0.1.47

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.
Files changed (97) hide show
  1. package/README.md +93 -33
  2. package/dist/components/BetterMenu/BetterMenu.svelte +21 -37
  3. package/dist/components/BetterMenu/BetterMenuAsyncButton.svelte +21 -31
  4. package/dist/components/BetterMenu/BetterMenuPreview.svelte +27 -29
  5. package/dist/components/BetterMenu/MenuRenderer.svelte +40 -51
  6. package/dist/components/Boxer/Boxer.svelte +488 -602
  7. package/dist/components/Boxer/BoxerTarget.svelte +6 -46
  8. package/dist/components/Boxer/BoxerTarget.svelte.d.ts +1 -0
  9. package/dist/components/Boxer/types.d.ts +0 -1
  10. package/dist/components/Button.svelte +19 -43
  11. package/dist/components/ButtonPreview.svelte +2 -11
  12. package/dist/components/CardGrid/CardGrid.svelte +443 -614
  13. package/dist/components/CardGrid/CardGridFilterPanel.svelte +111 -90
  14. package/dist/components/CardGrid/DefaultCard.svelte +80 -96
  15. package/dist/components/CardGrid/ImageCardStory.svelte +87 -36
  16. package/dist/components/ContentEditor/CollaboraInsertTextDemo.svelte +5 -10
  17. package/dist/components/ContentEditor/ContentEditor.svelte +24 -50
  18. package/dist/components/ContentEditor/subcomponents/AudioPlayer.svelte +17 -17
  19. package/dist/components/ContentEditor/subcomponents/CollaboraEditor.svelte +244 -309
  20. package/dist/components/ContentEditor/subcomponents/EmailViewer.svelte +2 -3
  21. package/dist/components/ContentEditor/subcomponents/ImageViewer.svelte +14 -15
  22. package/dist/components/ContentEditor/subcomponents/MarkdownViewer.svelte +74 -90
  23. package/dist/components/ContentEditor/subcomponents/MonacoEditor.svelte +75 -103
  24. package/dist/components/ContentEditor/subcomponents/Office365Editor.svelte +234 -297
  25. package/dist/components/ContentEditor/subcomponents/PdfViewer.svelte +14 -20
  26. package/dist/components/ContentEditor/subcomponents/TextEditor.svelte +122 -150
  27. package/dist/components/ContentEditor/subcomponents/UnknownFile.svelte +105 -126
  28. package/dist/components/ContentEditor/subcomponents/VideoPlayer.svelte +17 -17
  29. package/dist/components/ContentEditor/subcomponents/ZipViewer.svelte +2 -3
  30. package/dist/components/ErrorBoundary/ErrorBoundary.svelte +41 -58
  31. package/dist/components/ErrorBoundary/ErrorBoundaryPreview.svelte +8 -16
  32. package/dist/components/Former/Former.svelte +306 -424
  33. package/dist/components/Former/FormerButtonArea.svelte +17 -68
  34. package/dist/components/Former/FormerDrawer.svelte +26 -78
  35. package/dist/components/Former/FormerDrawerPreview.svelte +99 -89
  36. package/dist/components/Former/FormerModal.svelte +24 -70
  37. package/dist/components/Former/FormerModalPreview.svelte +99 -89
  38. package/dist/components/Former/FormerPreview.svelte +76 -78
  39. package/dist/components/Former/FormerRestApiPreview.svelte +55 -48
  40. package/dist/components/FormerControllers/ButtonCtrl.svelte +13 -44
  41. package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrl.svelte +280 -445
  42. package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrlCalendar.svelte +95 -136
  43. package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrlPickerPanel.svelte +3 -62
  44. package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrlTimeFields.svelte +143 -217
  45. package/dist/components/FormerControllers/IconButtonCtrl.svelte +13 -42
  46. package/dist/components/FormerControllers/InlineWrapper.svelte +12 -41
  47. package/dist/components/FormerControllers/InlineWrapperPreview.svelte +4 -26
  48. package/dist/components/FormerControllers/NativeSelectCtrl.svelte +3 -29
  49. package/dist/components/FormerControllers/NumberInputCtrl.svelte +9 -35
  50. package/dist/components/FormerControllers/PasswordInputCtrl.svelte +4 -23
  51. package/dist/components/FormerControllers/SwitchCtrl.svelte +3 -20
  52. package/dist/components/FormerControllers/TextAreaCtrl.svelte +3 -24
  53. package/dist/components/FormerControllers/TextInputCtrl.svelte +3 -24
  54. package/dist/components/GlobalStateStore/GlobalStateStoreProvider.svelte +73 -120
  55. package/dist/components/Gridler/components/Gridler.svelte +338 -442
  56. package/dist/components/Gridler/components/GridlerCanvas.svelte +720 -1115
  57. package/dist/components/Gridler/components/GridlerEditor.svelte +2 -15
  58. package/dist/components/Gridler/components/GridlerFull.svelte +520 -841
  59. package/dist/components/Gridler/components/GridlerFull.svelte.d.ts +1 -1
  60. package/dist/components/Gridler/components/GridlerFullWithFormerPreview.svelte +194 -147
  61. package/dist/components/Gridler/components/GridlerSearch.svelte +7 -16
  62. package/dist/components/Gridler/components/GridlerSearchToggle.svelte +7 -19
  63. package/dist/components/Gridler/types.d.ts +1 -1
  64. package/dist/components/Icons/IconAdd.svelte +1 -3
  65. package/dist/components/Icons/IconAlertCircle.svelte +1 -3
  66. package/dist/components/Icons/IconAlertTriangle.svelte +1 -3
  67. package/dist/components/Icons/IconCamera.svelte +1 -3
  68. package/dist/components/Icons/IconClose.svelte +1 -3
  69. package/dist/components/Icons/IconEdit.svelte +1 -3
  70. package/dist/components/Icons/IconFilter.svelte +1 -3
  71. package/dist/components/Icons/IconSearch.svelte +1 -3
  72. package/dist/components/Icons/IconSort.svelte +1 -3
  73. package/dist/components/Icons/IconTrash.svelte +1 -3
  74. package/dist/components/Portal/Portal.svelte +14 -38
  75. package/dist/components/Screenshot/Screenshot.svelte +7 -13
  76. package/dist/components/Svark/Svark.svelte +680 -852
  77. package/dist/components/Svark/SvarkContextMenu.svelte +44 -63
  78. package/dist/components/Svark/SvarkInfiniteLoader.svelte +2 -6
  79. package/dist/components/Svark/SvarkPager.svelte +2 -28
  80. package/dist/components/Svark/SvarkSelectionDemo.svelte +4 -8
  81. package/dist/components/Svark/SvarkTopBar.svelte +9 -74
  82. package/dist/components/SvarkGrid/SvarkGrid.svelte +877 -1123
  83. package/dist/components/SvarkGrid/components/SvarkColumnFilterForm.svelte +45 -58
  84. package/dist/components/SvarkGrid/components/SvarkContextMenu.svelte +44 -63
  85. package/dist/components/SvarkGrid/components/SvarkHeaderFilterCell.svelte +41 -75
  86. package/dist/components/SvarkGrid/components/SvarkInfiniteLoader.svelte +2 -6
  87. package/dist/components/SvarkGrid/components/SvarkPager.svelte +2 -28
  88. package/dist/components/SvarkGrid/components/SvarkSearchPopover.svelte +8 -16
  89. package/dist/components/SvarkGrid/components/SvarkTopBar.svelte +6 -62
  90. package/dist/components/SvarkGrid/internal/SvarkGridView.svelte +345 -507
  91. package/dist/components/VTree/VTree.svelte +349 -431
  92. package/dist/components/VTree/VTreeContextMenu.svelte +21 -33
  93. package/dist/components/VTree/VTreeEventsDemo.svelte +48 -58
  94. package/dist/components/VTree/VTreeRow.svelte +13 -65
  95. package/dist/components/VTree/VTreeSearch.svelte +6 -13
  96. package/dist/components/VTree/VTreeVirtualViewport.svelte +37 -106
  97. package/package.json +30 -29
@@ -1,96 +1,117 @@
1
- <script lang="ts">
2
- import type { CardGridColumn } from './cardGrid.js';
3
- import type { GridColumnFilters } from '../Types/generic_grid.js';
4
-
5
- interface Props {
6
- columns: CardGridColumn[];
7
- filters: GridColumnFilters;
8
- onApply: (filters: GridColumnFilters) => void;
9
- onCancel: () => void;
10
- }
11
-
12
- const { columns, filters, onApply, onCancel }: Props = $props();
13
-
14
- type Op = NonNullable<GridColumnFilters[string]['op']>;
15
-
16
- const ALL_OPERATORS: { value: Op; label: string }[] = [
17
- { value: 'contains', label: 'Contains' },
18
- { value: 'equals', label: 'Equals' },
19
- { value: 'notEquals', label: 'Not equals' },
20
- { value: 'startsWith', label: 'Starts with' },
21
- { value: 'endsWith', label: 'Ends with' },
22
- { value: 'greaterThan', label: '>' },
23
- { value: 'greaterThanOrEqual', label: '>=' },
24
- { value: 'lessThan', label: '<' },
25
- { value: 'lessThanOrEqual', label: '<=' },
26
- { value: 'between', label: 'Between' },
27
- { value: 'notBetween', label: 'Not between' },
28
- { value: 'in', label: 'In (comma-sep)' },
29
- { value: 'notIn', label: 'Not in' },
30
- { value: 'isNull', label: 'Is empty' },
31
- { value: 'isNotNull', label: 'Is not empty' },
32
- ];
33
-
34
- const filterableColumns = $derived(columns.filter((c) => !c.disableFilter));
35
-
36
- interface FilterRow {
37
- colId: string;
38
- op: Op;
39
- value: string;
40
- value2: string;
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
- function filtersToRows(f: GridColumnFilters): FilterRow[] {
44
- return Object.entries(f).map(([colId, entry]) => ({
45
- colId,
46
- op: entry.op ?? 'contains',
47
- value: entry.value ?? '',
48
- value2: entry.value2 ?? '',
49
- }));
50
- }
51
-
52
- let rows = $state<FilterRow[]>([]);
53
-
54
- $effect(() => {
55
- rows = filtersToRows(filters);
56
- });
57
-
58
- function addRow() {
59
- const firstCol = filterableColumns[0];
60
- if (!firstCol) return;
61
- rows = [...rows, { colId: firstCol.id, op: 'contains', value: '', value2: '' }];
62
- }
63
-
64
- function removeRow(index: number) {
65
- rows = rows.filter((_, i) => i !== index);
66
- }
67
-
68
- function apply() {
69
- const next: GridColumnFilters = {};
70
- for (const row of rows) {
71
- if (!row.colId) continue;
72
- const needsValue = row.op !== 'isNull' && row.op !== 'isNotNull';
73
- if (needsValue && !row.value) continue;
74
- const col = columns.find((c) => c.id === row.colId);
75
- const entry: GridColumnFilters[string] = {
76
- value: row.value,
77
- op: row.op,
78
- ...(col?.dataKey ? { dataKey: col.dataKey } : {}),
79
- };
80
- if ((row.op === 'between' || row.op === 'notBetween') && row.value2) {
81
- entry.value2 = row.value2;
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
- onApply(next);
86
- }
87
-
88
- function clear() {
89
- onApply({});
105
+ next[row.colId] = entry;
90
106
  }
91
-
92
- const needsValue = (op: Op) => op !== 'isNull' && op !== 'isNotNull';
93
- const needsValue2 = (op: Op) => op === 'between' || op === 'notBetween';
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,103 +1,87 @@
1
- <script lang="ts">
2
- import type { CardGridColumn } from './cardGrid.js';
3
-
4
- interface Props {
5
- record: Record<string, unknown>;
6
- columns: CardGridColumn[];
7
- selected: boolean;
8
- focused: boolean;
1
+ <script lang="ts">const { record, columns, selected, focused } = $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
- const { record, columns, selected, focused }: Props = $props();
12
-
13
- // First column title, second subtitle, rest → detail rows
14
- const titleCol = $derived(columns[0]);
15
- const subtitleCol = $derived(columns.length > 1 ? columns[1] : undefined);
16
- const detailCols = $derived(columns.slice(subtitleCol ? 2 : 1));
17
-
18
- function getVal(key: string, row: Record<string, unknown>): unknown {
19
- const parts = key.split('.');
20
- let val: unknown = row;
21
- for (const part of parts) {
22
- if (val == null || typeof val !== 'object') return undefined;
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
- return val;
26
- }
27
-
28
- function formatVal(val: unknown, col: CardGridColumn): string {
29
- if (val == null || val === '') return '—';
30
- switch (col.format) {
31
- case 'currency': {
32
- const n = Number(val);
33
- if (!isNaN(n))
34
- return new Intl.NumberFormat(undefined, {
35
- style: 'currency',
36
- currency: 'ZAR',
37
- maximumFractionDigits: 0,
38
- }).format(n);
39
- break;
40
- }
41
- case 'number': {
42
- const n = Number(val);
43
- if (!isNaN(n)) return n.toLocaleString();
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
87
  <article class="dc-card" class:dc-selected={selected} class:dc-focused={focused}>
@@ -1,39 +1,90 @@
1
- <script lang="ts">
2
- import CardGrid from './CardGrid.svelte';
3
- import type { CardGridColumn, CardSortOption } from './cardGrid.js';
4
-
5
- const columns: CardGridColumn[] = [
6
- { id: 'id', title: 'ID', disableSearch: true, disableFilter: true },
7
- { id: 'title', title: 'Title' },
8
- { id: 'photographer', title: 'Photographer' },
9
- { id: 'category', title: 'Category' },
10
- { id: 'likes', title: 'Likes', format: 'number' },
11
- { id: 'views', title: 'Views', format: 'number' },
12
- ];
13
-
14
- const sortOptions: CardSortOption[] = [
15
- { columnId: 'title', label: 'Title' },
16
- { columnId: 'photographer', label: 'Photographer' },
17
- { columnId: 'likes', label: 'Likes' },
18
- ];
19
-
20
- const CATEGORIES = ['Architecture', 'Nature', 'People', 'Travel', 'Abstract', 'Animals'];
21
- const PHOTOGRAPHERS = ['Alice Monroe', 'Ben Carter', 'Cara Lee', 'Daniel Park', 'Emma Rios', 'Felix Braun'];
22
- const TITLES = [
23
- 'Golden Hour', 'Morning Mist', 'Urban Jungle', 'Still Waters', 'First Light',
24
- 'Hidden Path', 'City Pulse', 'Wild Plains', 'Quiet Corner', 'Storm Front',
25
- 'Desert Bloom', 'Arctic Echo', 'Neon Drift', 'Forest Floor', 'Tidal Wave',
26
- ];
27
-
28
- const data = Array.from({ length: 60 }, (_, i) => ({
29
- id: i + 1,
30
- title: `${TITLES[i % TITLES.length]} ${Math.floor(i / TITLES.length) || ''}`.trim(),
31
- photographer: PHOTOGRAPHERS[i % PHOTOGRAPHERS.length],
32
- category: CATEGORIES[i % CATEGORIES.length],
33
- likes: Math.floor(Math.random() * 4800 + 200),
34
- views: Math.floor(Math.random() * 48000 + 2000),
35
- imageUrl: `https://picsum.photos/seed/${i + 1}/400/260`,
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] -->
@@ -1,13 +1,8 @@
1
- <script lang="ts">
2
- import type { ContentEditorProps } from "./types.js";
3
- import ContentEditor from "./ContentEditor.svelte";
4
-
5
- let { value, filename, wopiUrl, discoverUrl, adminKey, userid, username }: ContentEditorProps =
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;">
@@ -1,53 +1,27 @@
1
- <script lang="ts">
2
- import type { ContentEditorProps } from "./types.js";
3
- import { getEditorType } from "./utils.js";
4
- import MonacoEditor from "./subcomponents/MonacoEditor.svelte";
5
- import ImageViewer from "./subcomponents/ImageViewer.svelte";
6
- import AudioPlayer from "./subcomponents/AudioPlayer.svelte";
7
- import VideoPlayer from "./subcomponents/VideoPlayer.svelte";
8
- import TextEditor from "./subcomponents/TextEditor.svelte";
9
- import MarkdownViewer from "./subcomponents/MarkdownViewer.svelte";
10
- import PdfViewer from "./subcomponents/PdfViewer.svelte";
11
- import EmailViewer from "./subcomponents/EmailViewer.svelte";
12
- import ZipViewer from "./subcomponents/ZipViewer.svelte";
13
- import CollaboraEditor from "./subcomponents/CollaboraEditor.svelte";
14
- import Office365Editor from "./subcomponents/Office365Editor.svelte";
15
- import UnknownFile from "./subcomponents/UnknownFile.svelte";
16
-
17
- let {
18
- value,
19
- filename,
20
- contentType,
21
- mode = "value",
22
- hideHeader = false,
23
- theme,
24
- colorScheme = "auto",
25
- readonly = false,
26
- onChange,
27
- onSave,
28
- onUpload,
29
- insertText = $bindable(),
30
- insertHtml = $bindable(),
31
- wopiUrl,
32
- discoverUrl,
33
- adminKey,
34
- userid,
35
- username,
36
- viewtype,
37
- officeSuite = "collabora",
38
- officeOnlineUrl,
39
- }: ContentEditorProps = $props();
40
-
41
- const editorType = $derived(getEditorType({ filename, contentType }));
42
- const forcedColorScheme = $derived(colorScheme === "auto" ? undefined : colorScheme);
43
-
44
- $effect(() => {
45
- if (mode === "filepointer") {
46
- console.warn(
47
- '[ContentEditor] mode="filepointer" is not yet implemented; falling back to value mode.',
48
- );
49
- }
50
- });
1
+ <script lang="ts">import { getEditorType } from "./utils.js";
2
+ import MonacoEditor from "./subcomponents/MonacoEditor.svelte";
3
+ import ImageViewer from "./subcomponents/ImageViewer.svelte";
4
+ import AudioPlayer from "./subcomponents/AudioPlayer.svelte";
5
+ import VideoPlayer from "./subcomponents/VideoPlayer.svelte";
6
+ import TextEditor from "./subcomponents/TextEditor.svelte";
7
+ import MarkdownViewer from "./subcomponents/MarkdownViewer.svelte";
8
+ import PdfViewer from "./subcomponents/PdfViewer.svelte";
9
+ import EmailViewer from "./subcomponents/EmailViewer.svelte";
10
+ import ZipViewer from "./subcomponents/ZipViewer.svelte";
11
+ import CollaboraEditor from "./subcomponents/CollaboraEditor.svelte";
12
+ import Office365Editor from "./subcomponents/Office365Editor.svelte";
13
+ import UnknownFile from "./subcomponents/UnknownFile.svelte";
14
+ let { value, filename, contentType, mode = "value", hideHeader = false, theme, colorScheme = "auto", readonly = false, onChange, onSave, onUpload, insertText = $bindable(), insertHtml = $bindable(), wopiUrl, discoverUrl, adminKey, userid, username, viewtype, officeSuite = "collabora", officeOnlineUrl } = $props();
15
+ const editorType = $derived(getEditorType({
16
+ filename,
17
+ contentType
18
+ }));
19
+ const forcedColorScheme = $derived(colorScheme === "auto" ? undefined : colorScheme);
20
+ $effect(() => {
21
+ if (mode === "filepointer") {
22
+ console.warn("[ContentEditor] mode=\"filepointer\" is not yet implemented; falling back to value mode.");
23
+ }
24
+ });
51
25
  </script>
52
26
 
53
27
  <div
@@ -1,20 +1,20 @@
1
- <script lang="ts">
2
- import type { AudioPlayerProps } from '../types.js';
3
- import IconAlertCircle from '../../Icons/IconAlertCircle.svelte';
4
- let { value, filename }: AudioPlayerProps = $props();
5
-
6
- let src = $state('');
7
- let srcType = $state<string | undefined>(undefined);
8
- let err = $state<string | null>(null);
9
-
10
- $effect(() => {
11
- if (!value) { src = ''; srcType = undefined; return; }
12
- err = null;
13
- const url = URL.createObjectURL(value);
14
- src = url;
15
- srcType = value.type || undefined;
16
- return () => URL.revokeObjectURL(url);
17
- });
1
+ <script lang="ts">import IconAlertCircle from "../../Icons/IconAlertCircle.svelte";
2
+ let { value, filename } = $props();
3
+ let src = $state("");
4
+ let srcType = $state(undefined);
5
+ let err = $state(null);
6
+ $effect(() => {
7
+ if (!value) {
8
+ src = "";
9
+ srcType = undefined;
10
+ return;
11
+ }
12
+ err = null;
13
+ const url = URL.createObjectURL(value);
14
+ src = url;
15
+ srcType = value.type || undefined;
16
+ return () => URL.revokeObjectURL(url);
17
+ });
18
18
  </script>
19
19
 
20
20
  <div class="flex h-full w-full flex-col items-center justify-center gap-4 p-6">