@softwareone/spi-sv5-library 1.11.6 → 1.11.8
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/dist/Form/Form.svelte +1 -1
- package/dist/Table/ActionsColumn.svelte +76 -72
- package/dist/Table/ActionsColumn.svelte.d.ts +0 -2
- package/dist/Table/Body.svelte +22 -2
- package/dist/Table/Body.svelte.d.ts +1 -0
- package/dist/Table/Table.svelte +13 -4
- package/dist/Table/Table.svelte.d.ts +1 -1
- package/dist/Table/excel-setting.d.ts +1 -0
- package/dist/Table/util.js +2 -4
- package/dist/Waffle/WaffleItems.svelte +6 -10
- package/dist/Waffle/WaffleItems.svelte.d.ts +1 -1
- package/dist/Waffle/waffleState.svelte.d.ts +1 -1
- package/package.json +1 -1
package/dist/Form/Form.svelte
CHANGED
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
let isLoading = $state(false);
|
|
53
53
|
|
|
54
54
|
const { form, errors, isFormValid } = getFormContext<Schema>(contextName);
|
|
55
|
-
$form =
|
|
55
|
+
$form = $state.snapshot(initialData);
|
|
56
56
|
|
|
57
57
|
const onUpdated = () => {
|
|
58
58
|
isLoading = false;
|
|
@@ -1,59 +1,56 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Attachment } from 'svelte/attachments';
|
|
3
|
+
import { fade } from 'svelte/transition';
|
|
4
|
+
|
|
2
5
|
import type { Action } from './types.js';
|
|
3
6
|
|
|
4
7
|
interface Props {
|
|
5
8
|
actions: Action[];
|
|
6
|
-
isLastChild?: boolean;
|
|
7
|
-
isOnlyOneRow?: boolean;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
let { actions
|
|
11
|
+
let { actions }: Props = $props();
|
|
12
|
+
|
|
13
|
+
let container = $state<HTMLDivElement>()!;
|
|
14
|
+
let isOpen = $state(false);
|
|
11
15
|
|
|
12
|
-
const
|
|
16
|
+
const ICONS: Record<string, string> = {
|
|
13
17
|
Edit: 'edit',
|
|
14
18
|
Delete: 'delete'
|
|
15
19
|
};
|
|
16
20
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
const isSingleAction = $derived(actions.length === 1);
|
|
22
|
+
const dividerIndex = $derived(actions.findLastIndex((action) => !action.isMainAction));
|
|
23
|
+
|
|
24
|
+
const showDividerAfter = (index: number) =>
|
|
25
|
+
dividerIndex !== -1 && dividerIndex !== actions.length - 1 && dividerIndex === index;
|
|
26
|
+
|
|
27
|
+
const autoPosition: Attachment<HTMLElement> = (element: HTMLElement) => {
|
|
28
|
+
const updatePosition = () => {
|
|
29
|
+
const rect = container.getBoundingClientRect();
|
|
30
|
+
const showAbove = rect.bottom + element.offsetHeight > window.innerHeight;
|
|
31
|
+
|
|
32
|
+
const left = rect.left + rect.width / 2 - element.offsetWidth / 2;
|
|
33
|
+
const top = showAbove ? rect.top - element.offsetHeight + 14 : rect.bottom - 8;
|
|
34
|
+
|
|
35
|
+
element.style.setProperty('--menu-left', `${Math.max(0, left)}px`);
|
|
36
|
+
element.style.setProperty('--menu-top', `${top}px`);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
updatePosition();
|
|
40
|
+
window.addEventListener('scroll', updatePosition, true);
|
|
41
|
+
|
|
42
|
+
return () => window.removeEventListener('scroll', updatePosition, true);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const toggleActionsMenu = () => {
|
|
46
|
+
isOpen = !isOpen;
|
|
47
|
+
};
|
|
20
48
|
</script>
|
|
21
49
|
|
|
22
50
|
<div class="actions-column">
|
|
23
|
-
{#if
|
|
24
|
-
<div class="actions-group">
|
|
25
|
-
<span class="actions-trigger">...</span>
|
|
26
|
-
<div
|
|
27
|
-
class={[
|
|
28
|
-
'actions-menu',
|
|
29
|
-
isOnlyOneRow && 'actions-menu--only-row',
|
|
30
|
-
isLastChild && !isOnlyOneRow && 'actions-menu--last',
|
|
31
|
-
!isLastChild && !isOnlyOneRow && 'actions-menu--top'
|
|
32
|
-
]}
|
|
33
|
-
>
|
|
34
|
-
<ul class="actions-list">
|
|
35
|
-
{#each actions as action, index}
|
|
36
|
-
<li>
|
|
37
|
-
<button
|
|
38
|
-
type="button"
|
|
39
|
-
onclick={action.onClick}
|
|
40
|
-
class="action-button"
|
|
41
|
-
class:action-button--delete={action.isDelete && action.isEnabled}
|
|
42
|
-
disabled={!action.isEnabled}
|
|
43
|
-
>
|
|
44
|
-
<span>{action.name}</span>
|
|
45
|
-
</button>
|
|
46
|
-
</li>
|
|
47
|
-
{#if indexLastSecondaryAction !== -1 && indexLastSecondaryAction !== actions.length - 1 && indexLastSecondaryAction === index}
|
|
48
|
-
<hr class="action-divider" />
|
|
49
|
-
{/if}
|
|
50
|
-
{/each}
|
|
51
|
-
</ul>
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
{:else}
|
|
51
|
+
{#if isSingleAction}
|
|
55
52
|
{@const action = actions[0]}
|
|
56
|
-
{@const
|
|
53
|
+
{@const icon = ICONS[action.name]}
|
|
57
54
|
|
|
58
55
|
<button
|
|
59
56
|
type="button"
|
|
@@ -62,14 +59,45 @@
|
|
|
62
59
|
class:action-button--delete={action.isDelete && action.isEnabled}
|
|
63
60
|
disabled={!action.isEnabled}
|
|
64
61
|
>
|
|
65
|
-
{#if
|
|
66
|
-
<span class="material-icons-outlined">
|
|
67
|
-
{nameIcon}
|
|
68
|
-
</span>
|
|
62
|
+
{#if icon}
|
|
63
|
+
<span class="material-icons-outlined">{icon}</span>
|
|
69
64
|
{:else}
|
|
70
65
|
<span class:action-button--primary={action.isEnabled}>{action.name}</span>
|
|
71
66
|
{/if}
|
|
72
67
|
</button>
|
|
68
|
+
{:else}
|
|
69
|
+
<div
|
|
70
|
+
role="menu"
|
|
71
|
+
tabindex="-1"
|
|
72
|
+
class="actions-group"
|
|
73
|
+
bind:this={container}
|
|
74
|
+
onmouseenter={toggleActionsMenu}
|
|
75
|
+
onmouseleave={toggleActionsMenu}
|
|
76
|
+
>
|
|
77
|
+
<span class="actions-trigger">...</span>
|
|
78
|
+
{#if isOpen}
|
|
79
|
+
<div class="actions-menu" {@attach autoPosition} transition:fade={{ duration: 100 }}>
|
|
80
|
+
<ul class="actions-list">
|
|
81
|
+
{#each actions as action, index}
|
|
82
|
+
<li>
|
|
83
|
+
<button
|
|
84
|
+
type="button"
|
|
85
|
+
onclick={action.onClick}
|
|
86
|
+
class="action-button"
|
|
87
|
+
class:action-button--delete={action.isDelete && action.isEnabled}
|
|
88
|
+
disabled={!action.isEnabled}
|
|
89
|
+
>
|
|
90
|
+
<span>{action.name}</span>
|
|
91
|
+
</button>
|
|
92
|
+
</li>
|
|
93
|
+
{#if showDividerAfter(index)}
|
|
94
|
+
<hr class="action-divider" />
|
|
95
|
+
{/if}
|
|
96
|
+
{/each}
|
|
97
|
+
</ul>
|
|
98
|
+
</div>
|
|
99
|
+
{/if}
|
|
100
|
+
</div>
|
|
73
101
|
{/if}
|
|
74
102
|
</div>
|
|
75
103
|
|
|
@@ -99,7 +127,7 @@
|
|
|
99
127
|
}
|
|
100
128
|
|
|
101
129
|
.actions-group {
|
|
102
|
-
position:
|
|
130
|
+
position: relative;
|
|
103
131
|
}
|
|
104
132
|
|
|
105
133
|
.actions-trigger {
|
|
@@ -111,39 +139,15 @@
|
|
|
111
139
|
}
|
|
112
140
|
|
|
113
141
|
.actions-menu {
|
|
114
|
-
position:
|
|
142
|
+
position: fixed;
|
|
115
143
|
z-index: var(--z-index-menu);
|
|
116
144
|
width: 108px;
|
|
145
|
+
left: var(--menu-left);
|
|
146
|
+
top: var(--menu-top);
|
|
117
147
|
padding: var(--spacing-md) var(--spacing-lg);
|
|
118
148
|
background: var(--color-white);
|
|
119
149
|
border-radius: var(--radius-lg);
|
|
120
150
|
box-shadow: var(--shadow-menu);
|
|
121
|
-
visibility: hidden;
|
|
122
|
-
opacity: 0;
|
|
123
|
-
transition: var(--transition-standard);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
.actions-group:hover .actions-menu {
|
|
127
|
-
visibility: visible;
|
|
128
|
-
opacity: 1;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
.actions-menu--only-row {
|
|
132
|
-
right: 28px;
|
|
133
|
-
bottom: 16px;
|
|
134
|
-
transform: translateY(50%);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
.actions-menu--last {
|
|
138
|
-
bottom: 28px;
|
|
139
|
-
left: 50%;
|
|
140
|
-
transform: translateX(-50%);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
.actions-menu--top {
|
|
144
|
-
top: 32px;
|
|
145
|
-
left: 50%;
|
|
146
|
-
transform: translateX(-50%);
|
|
147
151
|
}
|
|
148
152
|
|
|
149
153
|
.actions-list {
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { Action } from './types.js';
|
|
2
2
|
interface Props {
|
|
3
3
|
actions: Action[];
|
|
4
|
-
isLastChild?: boolean;
|
|
5
|
-
isOnlyOneRow?: boolean;
|
|
6
4
|
}
|
|
7
5
|
declare const ActionsColumn: import("svelte").Component<Props, {}, "">;
|
|
8
6
|
type ActionsColumn = ReturnType<typeof ActionsColumn>;
|
package/dist/Table/Body.svelte
CHANGED
|
@@ -4,16 +4,32 @@
|
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
6
|
bodyRows: Row<T>[];
|
|
7
|
+
enableChecked?: boolean;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
let { bodyRows }: Props = $props();
|
|
10
|
+
let { bodyRows, enableChecked = false }: Props = $props();
|
|
11
|
+
|
|
12
|
+
const CLICKABLE_TAGS = ['td', 'span', 'p'];
|
|
13
|
+
|
|
14
|
+
const handleRowClick = (row: Row<T>, target: EventTarget | null) => {
|
|
15
|
+
const isHtmlElement = target instanceof HTMLElement;
|
|
16
|
+
const tagName = isHtmlElement ? target.tagName.toLocaleLowerCase() : '';
|
|
17
|
+
if (isHtmlElement && CLICKABLE_TAGS.includes(tagName)) {
|
|
18
|
+
row.toggleSelected();
|
|
19
|
+
}
|
|
20
|
+
};
|
|
10
21
|
</script>
|
|
11
22
|
|
|
12
23
|
<tbody class="table-body">
|
|
13
24
|
{#each bodyRows as row (row.id)}
|
|
14
25
|
<tr
|
|
15
26
|
animate:flip={{ duration: 500 }}
|
|
16
|
-
class={[
|
|
27
|
+
class={[
|
|
28
|
+
'table-row',
|
|
29
|
+
row.getIsSelected() && 'table-row--selected',
|
|
30
|
+
enableChecked && 'table-row--clickable'
|
|
31
|
+
]}
|
|
32
|
+
onclick={enableChecked ? (event) => handleRowClick(row, event.target) : undefined}
|
|
17
33
|
>
|
|
18
34
|
{#each row.getVisibleCells() as cell}
|
|
19
35
|
{@const alignColumn = cell.column.columnDef.meta?.alignColumn}
|
|
@@ -66,6 +82,10 @@
|
|
|
66
82
|
background: var(--color-row-selected);
|
|
67
83
|
}
|
|
68
84
|
|
|
85
|
+
.table-row--clickable {
|
|
86
|
+
cursor: pointer;
|
|
87
|
+
}
|
|
88
|
+
|
|
69
89
|
.table-cell {
|
|
70
90
|
max-width: 50px;
|
|
71
91
|
padding: var(--spacing-md) var(--spacing-lg);
|
package/dist/Table/Table.svelte
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
pagination?: Pagination;
|
|
49
49
|
excelSetting?: ExcelSetting;
|
|
50
50
|
header?: Snippet;
|
|
51
|
-
bulkActions?: Snippet<[selectedRows: T[]]>;
|
|
51
|
+
bulkActions?: Snippet<[selectedRows: T[], clearSelection: VoidFunction]>;
|
|
52
52
|
onpagechange?: (pageSize: number, pageNumber: number) => void;
|
|
53
53
|
onpagesizechange?: (pageSize: number) => void;
|
|
54
54
|
}
|
|
@@ -206,6 +206,10 @@
|
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
+
const clearSelection = () => {
|
|
210
|
+
rowSelection = {};
|
|
211
|
+
};
|
|
212
|
+
|
|
209
213
|
const changeFilters = (filters: Filter[]) => {
|
|
210
214
|
const searchParams = new URLSearchParams(page.url.searchParams);
|
|
211
215
|
searchParams.delete('filter');
|
|
@@ -271,8 +275,10 @@
|
|
|
271
275
|
<Button
|
|
272
276
|
type="button"
|
|
273
277
|
variant="secondary"
|
|
274
|
-
onclick={() => exportExcel(table, excelSetting)}
|
|
278
|
+
onclick={() => exportExcel(table, excelSetting)}
|
|
275
279
|
>
|
|
280
|
+
{excelSetting.label ?? 'Export'}
|
|
281
|
+
</Button>
|
|
276
282
|
{/if}
|
|
277
283
|
{@render header?.()}
|
|
278
284
|
</div>
|
|
@@ -286,7 +292,10 @@
|
|
|
286
292
|
</p>
|
|
287
293
|
{#if bulkActions}
|
|
288
294
|
<hr class="action-divider" />
|
|
289
|
-
{@render bulkActions?.(
|
|
295
|
+
{@render bulkActions?.(
|
|
296
|
+
selectedRows.map((row) => row.original),
|
|
297
|
+
clearSelection
|
|
298
|
+
)}
|
|
290
299
|
{/if}
|
|
291
300
|
</div>
|
|
292
301
|
{/if}
|
|
@@ -295,7 +304,7 @@
|
|
|
295
304
|
<table class="table-main">
|
|
296
305
|
<Header headerGroups={table.getHeaderGroups()} {enableColumnSearch} />
|
|
297
306
|
{#if hasData}
|
|
298
|
-
<Body bodyRows={table.getRowModel().rows} />
|
|
307
|
+
<Body bodyRows={table.getRowModel().rows} {enableChecked} />
|
|
299
308
|
{/if}
|
|
300
309
|
</table>
|
|
301
310
|
</article>
|
|
@@ -18,7 +18,7 @@ declare function $$render<T>(): {
|
|
|
18
18
|
pagination?: Pagination;
|
|
19
19
|
excelSetting?: ExcelSetting;
|
|
20
20
|
header?: Snippet;
|
|
21
|
-
bulkActions?: Snippet<[selectedRows: T[]]>;
|
|
21
|
+
bulkActions?: Snippet<[selectedRows: T[], clearSelection: VoidFunction]>;
|
|
22
22
|
onpagechange?: (pageSize: number, pageNumber: number) => void;
|
|
23
23
|
onpagesizechange?: (pageSize: number) => void;
|
|
24
24
|
};
|
package/dist/Table/util.js
CHANGED
|
@@ -43,10 +43,8 @@ export const createActionsColumn = (getActions) => {
|
|
|
43
43
|
columnWidth: '117px',
|
|
44
44
|
hideColumnFilter: true
|
|
45
45
|
},
|
|
46
|
-
cell: ({ row
|
|
47
|
-
actions: getActions(row)
|
|
48
|
-
isLastChild: table.getRowModel().rows.at(-1).index === row.index,
|
|
49
|
-
isOnlyOneRow: table.getRowModel().rows.length === 1
|
|
46
|
+
cell: ({ row }) => renderComponent(ActionsColumn, {
|
|
47
|
+
actions: getActions(row)
|
|
50
48
|
})
|
|
51
49
|
});
|
|
52
50
|
};
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
interface Props {
|
|
3
3
|
title: string;
|
|
4
|
-
|
|
4
|
+
iconUrl: string;
|
|
5
5
|
onclickwaffleitems: VoidFunction;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
let { title,
|
|
8
|
+
let { title, iconUrl, onclickwaffleitems }: Props = $props();
|
|
9
9
|
</script>
|
|
10
10
|
|
|
11
11
|
<button type="button" onclick={onclickwaffleitems} class="waffle-item-button">
|
|
12
|
-
<
|
|
13
|
-
{@html icon}
|
|
14
|
-
</figure>
|
|
15
|
-
|
|
12
|
+
<img src={iconUrl} alt="" aria-hidden="true" class="waffle-item-img" />
|
|
16
13
|
<h3 class="waffle-title">
|
|
17
14
|
{title}
|
|
18
15
|
</h3>
|
|
@@ -44,13 +41,12 @@
|
|
|
44
41
|
background: #eaecff;
|
|
45
42
|
}
|
|
46
43
|
|
|
47
|
-
.waffle-
|
|
44
|
+
.waffle-item-img {
|
|
48
45
|
width: 40px;
|
|
49
46
|
height: 40px;
|
|
50
47
|
margin-bottom: 12px;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
justify-content: center;
|
|
48
|
+
filter: invert(27%) sepia(99%) saturate(4729%) hue-rotate(240deg) brightness(101%)
|
|
49
|
+
contrast(106%);
|
|
54
50
|
}
|
|
55
51
|
|
|
56
52
|
.waffle-title {
|