@ibobbyts/svelte-ui-utils 0.2.12 → 0.2.13
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 +97 -1
- package/dist/dialog/ConfirmDialog.svelte +2 -0
- package/dist/dialog/ConfirmDialog.svelte.d.ts +1 -0
- package/dist/dialog/ConfirmDialog.svelte.d.ts.map +1 -1
- package/dist/dialog/CsvUploadDialog.svelte +2 -0
- package/dist/dialog/CsvUploadDialog.svelte.d.ts +1 -0
- package/dist/dialog/CsvUploadDialog.svelte.d.ts.map +1 -1
- package/dist/dialog/Dialog.svelte +3 -0
- package/dist/dialog/Dialog.svelte.d.ts +1 -0
- package/dist/dialog/Dialog.svelte.d.ts.map +1 -1
- package/dist/dialog/ImagePreviewDialog.svelte +2 -0
- package/dist/dialog/ImagePreviewDialog.svelte.d.ts +1 -0
- package/dist/dialog/ImagePreviewDialog.svelte.d.ts.map +1 -1
- package/dist/dialog/InputDialog.svelte +2 -0
- package/dist/dialog/InputDialog.svelte.d.ts +1 -0
- package/dist/dialog/InputDialog.svelte.d.ts.map +1 -1
- package/dist/dialog/PasswordCopyDialog.svelte +2 -0
- package/dist/dialog/PasswordCopyDialog.svelte.d.ts +1 -0
- package/dist/dialog/PasswordCopyDialog.svelte.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/ordered-list/OrderedListEditor.svelte +60 -0
- package/dist/ordered-list/OrderedListEditor.svelte.d.ts +23 -0
- package/dist/ordered-list/OrderedListEditor.svelte.d.ts.map +1 -0
- package/dist/ordered-list/index.d.ts +3 -0
- package/dist/ordered-list/index.d.ts.map +1 -0
- package/dist/ordered-list/index.js +1 -0
- package/dist/sortable-list/SortableList.svelte +167 -0
- package/dist/sortable-list/SortableList.svelte.d.ts +38 -0
- package/dist/sortable-list/SortableList.svelte.d.ts.map +1 -0
- package/dist/sortable-list/index.d.ts +3 -0
- package/dist/sortable-list/index.d.ts.map +1 -0
- package/dist/sortable-list/index.js +1 -0
- package/dist/sortable-list/types.d.ts +23 -0
- package/dist/sortable-list/types.d.ts.map +1 -0
- package/dist/sortable-list/types.js +1 -0
- package/dist/sortable-table/SortableTable.svelte +118 -0
- package/dist/sortable-table/SortableTable.svelte.d.ts +41 -0
- package/dist/sortable-table/SortableTable.svelte.d.ts.map +1 -0
- package/dist/sortable-table/SortableTableEnhanced.svelte +128 -0
- package/dist/sortable-table/SortableTableEnhanced.svelte.d.ts +44 -0
- package/dist/sortable-table/SortableTableEnhanced.svelte.d.ts.map +1 -0
- package/dist/sortable-table/index.d.ts +4 -0
- package/dist/sortable-table/index.d.ts.map +1 -0
- package/dist/sortable-table/index.js +2 -0
- package/dist/sortable-table/types.d.ts +16 -0
- package/dist/sortable-table/types.d.ts.map +1 -0
- package/dist/sortable-table/types.js +1 -0
- package/dist/style.css +2 -2
- package/package.json +16 -1
package/README.md
CHANGED
|
@@ -170,6 +170,98 @@ In multiselect mode, the text input remains a search query. Selecting an item
|
|
|
170
170
|
adds or removes it from `selectedItems`, clears the query, and emits both
|
|
171
171
|
`onChange` and `onSelectedItemsChange`.
|
|
172
172
|
|
|
173
|
+
## SortableList
|
|
174
|
+
|
|
175
|
+
`SortableList` provides controlled vertical HTML5 drag-and-drop ordering. Each
|
|
176
|
+
item has a string `id` (and may contain any additional fields); `getId` can
|
|
177
|
+
project a different string key while retaining that typed item contract. The
|
|
178
|
+
caller owns the item array and receives the reordered array through
|
|
179
|
+
`onReorder`. Use the third snippet argument to attach drag bindings to a
|
|
180
|
+
dedicated handle. `listTag` and `itemTag` can be changed when the list must
|
|
181
|
+
render valid table markup such as direct `<tr>` children under `<tbody>`.
|
|
182
|
+
|
|
183
|
+
```svelte
|
|
184
|
+
<script lang="ts">
|
|
185
|
+
import { SortableList } from '@ibobbyts/svelte-ui-utils/sortable-list';
|
|
186
|
+
|
|
187
|
+
let items = [{ id: 'a', label: 'First' }, { id: 'b', label: 'Second' }];
|
|
188
|
+
</script>
|
|
189
|
+
|
|
190
|
+
<SortableList {items} onReorder={(next) => (items = next)}>
|
|
191
|
+
{#snippet children(item, _index, handle)}
|
|
192
|
+
<div {...handle} aria-label={`Drag ${item.label}`}>⠿</div>
|
|
193
|
+
<span>{item.label}</span>
|
|
194
|
+
{/snippet}
|
|
195
|
+
</SortableList>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Dragging over the target item's upper or lower half displays a before/after
|
|
199
|
+
insertion indicator. Dropping on the same item or while `disabled={true}` is a
|
|
200
|
+
no-op. The component does not persist order or perform rollback; those remain
|
|
201
|
+
the responsibility of the controlled parent.
|
|
202
|
+
|
|
203
|
+
## OrderedListEditor
|
|
204
|
+
|
|
205
|
+
`OrderedListEditor` is the shared editor for ordered fields. It renders the
|
|
206
|
+
provided content first, an optional current/select action next, and a trash-icon
|
|
207
|
+
remove action at the far right. Reorder arrows are intentionally not rendered;
|
|
208
|
+
use `SortableList` when drag-and-drop ordering is needed. Set
|
|
209
|
+
`allowRemoveLast={true}` when an empty list is valid.
|
|
210
|
+
|
|
211
|
+
```svelte
|
|
212
|
+
<script lang="ts">
|
|
213
|
+
import { OrderedListEditor } from '@ibobbyts/svelte-ui-utils/ordered-list';
|
|
214
|
+
</script>
|
|
215
|
+
|
|
216
|
+
<OrderedListEditor items={rows} onremove={(id) => remove(id)}>
|
|
217
|
+
{#snippet children(item)}
|
|
218
|
+
<input value={item.value ?? ''} />
|
|
219
|
+
{/snippet}
|
|
220
|
+
</OrderedListEditor>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## SortableTable
|
|
224
|
+
|
|
225
|
+
`SortableTable` is the table-level ordering primitive. It owns the table rows,
|
|
226
|
+
the left drag-handle column, and the right trash-icon delete column. Callers
|
|
227
|
+
provide only the header cells and the middle row cells through snippets.
|
|
228
|
+
Use `getDragLabel(item, index)` and `getRemoveLabel(item, index)` when the
|
|
229
|
+
controls need caller-owned accessible labels. Each label is applied to both
|
|
230
|
+
`aria-label` and `title`; defaults remain `Drag ${getId(item)}` and
|
|
231
|
+
`Remove ${getId(item)}`.
|
|
232
|
+
|
|
233
|
+
```svelte
|
|
234
|
+
<SortableTable items={rows} onReorder={reorder} onRemove={remove}>
|
|
235
|
+
{#snippet header()}<th>Name</th><th>Protocol</th>{/snippet}
|
|
236
|
+
{#snippet children(row)}<td>{row.name}</td><td>{row.protocol}</td>{/snippet}
|
|
237
|
+
</SortableTable>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
`SortableTableEnhanced` composes the same table and adds a controlled current
|
|
241
|
+
radio immediately after each drag handle. `currentId` is read-only input;
|
|
242
|
+
`onCurrentChange` asks the caller to persist a new current item. Use
|
|
243
|
+
`getCurrentDisabled` for per-row eligibility and `getRowColorPreset` to select
|
|
244
|
+
the package-owned `red`, `yellow`, or `green` background. The presets include
|
|
245
|
+
light and dark defaults and expose `--suu-sortable-table-row-*-light` and
|
|
246
|
+
`--suu-sortable-table-row-*-dark` override variables.
|
|
247
|
+
|
|
248
|
+
```svelte
|
|
249
|
+
<SortableTableEnhanced
|
|
250
|
+
items={rows}
|
|
251
|
+
currentId={currentRowId}
|
|
252
|
+
getDragLabel={(row) => `Reorder ${row.name}`}
|
|
253
|
+
getRemoveLabel={(row) => `Remove ${row.name}`}
|
|
254
|
+
onCurrentChange={(row) => selectCurrent(row.id)}
|
|
255
|
+
getCurrentDisabled={(row) => row.exhausted}
|
|
256
|
+
getRowColorPreset={(row) => row.exhausted ? 'red' : row.cooling ? 'yellow' : 'green'}
|
|
257
|
+
onReorder={reorder}
|
|
258
|
+
onRemove={remove}
|
|
259
|
+
>
|
|
260
|
+
{#snippet header()}<th>Name</th><th>Protocol</th>{/snippet}
|
|
261
|
+
{#snippet children(row)}<td>{row.name}</td><td>{row.protocol}</td>{/snippet}
|
|
262
|
+
</SortableTableEnhanced>
|
|
263
|
+
```
|
|
264
|
+
|
|
173
265
|
## Dialogs
|
|
174
266
|
|
|
175
267
|
```svelte
|
|
@@ -189,6 +281,7 @@ adds or removes it from `selectedItems`, clears the query, and emits both
|
|
|
189
281
|
open={dialogOpen}
|
|
190
282
|
title="Edit record"
|
|
191
283
|
description="Update the shared fields."
|
|
284
|
+
padding="12px 16px"
|
|
192
285
|
closeLabel="Close dialog"
|
|
193
286
|
blurBackdrop={true}
|
|
194
287
|
showCountdown={true}
|
|
@@ -245,7 +338,10 @@ from the close button, backdrop, or Escape key when dismissible; it does not
|
|
|
245
338
|
mutate `open` internally. Set `dimBackdrop={false}` to disable background
|
|
246
339
|
darkening, `blurBackdrop={true}` to blur content behind the dialog, and
|
|
247
340
|
`showCountdown={true}` with `countdownDurationMs` to show a toast-style top
|
|
248
|
-
countdown bar.
|
|
341
|
+
countdown bar. The optional `padding` prop accepts a CSS padding shorthand and
|
|
342
|
+
applies it consistently to the dialog header, body, and footer. The default
|
|
343
|
+
section-specific spacing is preserved when `padding` is omitted, and the same
|
|
344
|
+
prop is available on all dialog wrapper components.
|
|
249
345
|
|
|
250
346
|
## Dropdown
|
|
251
347
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
export let closeLabel = 'Close dialog';
|
|
13
13
|
export let intent: ConfirmDialogIntent = 'default';
|
|
14
14
|
export let size: DialogSize = 'sm';
|
|
15
|
+
export let padding: string | undefined = undefined;
|
|
15
16
|
export let confirmDisabled = false;
|
|
16
17
|
export let cancelDisabled = false;
|
|
17
18
|
export let dismissible = true;
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
{title}
|
|
48
49
|
{closeLabel}
|
|
49
50
|
{size}
|
|
51
|
+
{padding}
|
|
50
52
|
{dismissible}
|
|
51
53
|
{closeOnBackdrop}
|
|
52
54
|
{closeOnEscape}
|
|
@@ -26,6 +26,7 @@ declare const ConfirmDialog: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_P
|
|
|
26
26
|
closeLabel?: string;
|
|
27
27
|
intent?: ConfirmDialogIntent;
|
|
28
28
|
size?: DialogSize;
|
|
29
|
+
padding?: string | undefined;
|
|
29
30
|
confirmDisabled?: boolean;
|
|
30
31
|
cancelDisabled?: boolean;
|
|
31
32
|
dismissible?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfirmDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/ConfirmDialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"ConfirmDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/ConfirmDialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAkElE,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AACD,KAAK,gCAAgC,CAAC,KAAK,EAAE,KAAK,IAAI,KAAK,GACvD,CAAC,KAAK,SAAS;IAAE,OAAO,EAAE,GAAG,CAAA;CAAE,GACzB,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GACnC,GAAG,GACH;IAAE,QAAQ,CAAC,EAAE,GAAG,CAAA;CAAE,GAClB,EAAE,CAAC,CAAC;AAId,QAAA,MAAM,aAAa;;;;;;;aAfwyB,mBAAmB;WAAS,UAAU;cAAY,MAAM,GAAG,SAAS;;;;;;;;sBAA8R,MAAM,GAAG,MAAM;;;;;gBAAkL,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS;eAAa,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;cAAY,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;;;;;;;cAev2C,CAAC;AACvF,KAAK,aAAa,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AAC1D,eAAe,aAAa,CAAC"}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
export let description = '';
|
|
10
10
|
export let closeLabel = 'Close dialog';
|
|
11
11
|
export let size: DialogSize = 'lg';
|
|
12
|
+
export let padding: string | undefined = undefined;
|
|
12
13
|
export let dismissible = true;
|
|
13
14
|
export let closeOnBackdrop = true;
|
|
14
15
|
export let closeOnEscape = true;
|
|
@@ -103,6 +104,7 @@
|
|
|
103
104
|
{description}
|
|
104
105
|
{closeLabel}
|
|
105
106
|
{size}
|
|
107
|
+
{padding}
|
|
106
108
|
{dismissible}
|
|
107
109
|
{closeOnBackdrop}
|
|
108
110
|
{closeOnEscape}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CsvUploadDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/CsvUploadDialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"CsvUploadDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/CsvUploadDialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA8K7C,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAUD,QAAA,MAAM,eAAe;;;;;WAfmhC,UAAU;cAAY,MAAM,GAAG,SAAS;;;;;;sBAA4M,MAAM,GAAG,MAAM;;kBAAoD,MAAM,GAAG,SAAS;2BAAyB,MAAM,GAAG,SAAS;;;;;;;;mBAAqS,MAAM,EAAE;;;;;;;eAAiP,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS;eAAa,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;cAAY,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;mBAAiB,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS;;;;;;;;;cAergE,CAAC;AACzF,KAAK,eAAe,GAAG,YAAY,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,eAAe,eAAe,CAAC"}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
export let description = '';
|
|
10
10
|
export let closeLabel = 'Close dialog';
|
|
11
11
|
export let size: DialogSize = 'md';
|
|
12
|
+
export let padding: string | undefined = undefined;
|
|
12
13
|
export let dismissible = true;
|
|
13
14
|
export let showCloseButton = true;
|
|
14
15
|
export let closeOnBackdrop = true;
|
|
@@ -35,6 +36,7 @@
|
|
|
35
36
|
describedBy ?? (description ? descriptionId : undefined);
|
|
36
37
|
$: backdropStyle =
|
|
37
38
|
`--suu-dialog-backdrop-opacity: ${backdropOpacity}; --suu-dialog-backdrop-blur: ${backdropBlur};`;
|
|
39
|
+
$: dialogStyle = padding ? `--suu-dialog-padding: ${padding};` : '';
|
|
38
40
|
$: countdownStyle = `--suu-dialog-countdown-duration: ${Math.max(0, countdownDurationMs)}ms;`;
|
|
39
41
|
$: if (open && !wasOpen) {
|
|
40
42
|
wasOpen = true;
|
|
@@ -99,6 +101,7 @@
|
|
|
99
101
|
<div
|
|
100
102
|
bind:this={dialogElement}
|
|
101
103
|
class={`suu-dialog suu-dialog--${size}`}
|
|
104
|
+
style={dialogStyle}
|
|
102
105
|
role="dialog"
|
|
103
106
|
aria-modal="true"
|
|
104
107
|
aria-labelledby={resolvedLabelledBy}
|
|
@@ -23,6 +23,7 @@ declare const Dialog: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWit
|
|
|
23
23
|
description?: string;
|
|
24
24
|
closeLabel?: string;
|
|
25
25
|
size?: DialogSize;
|
|
26
|
+
padding?: string | undefined;
|
|
26
27
|
dismissible?: boolean;
|
|
27
28
|
showCloseButton?: boolean;
|
|
28
29
|
closeOnBackdrop?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/Dialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"Dialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/Dialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAsI7C,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AACD,KAAK,gCAAgC,CAAC,KAAK,EAAE,KAAK,IAAI,KAAK,GACvD,CAAC,KAAK,SAAS;IAAE,OAAO,EAAE,GAAG,CAAA;CAAE,GACzB,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GACnC,GAAG,GACH;IAAE,QAAQ,CAAC,EAAE,GAAG,CAAA;CAAE,GAClB,EAAE,CAAC,CAAC;AAId,QAAA,MAAM,MAAM;;;;;WAfqpB,UAAU;cAAY,MAAM,GAAG,SAAS;;;;;;;sBAAsP,MAAM,GAAG,MAAM;;;;;iBAAmL,MAAM,GAAG,SAAS;kBAAgB,MAAM,GAAG,SAAS;cAAY,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;;;;;;;;;cAexnC,CAAC;AAChF,KAAK,MAAM,GAAG,YAAY,CAAC,OAAO,MAAM,CAAC,CAAC;AAC5C,eAAe,MAAM,CAAC"}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
export let closeLabel = 'Close dialog';
|
|
13
13
|
export let downloadLabel = 'Download';
|
|
14
14
|
export let size: DialogSize = 'lg';
|
|
15
|
+
export let padding: string | undefined = undefined;
|
|
15
16
|
export let dismissible = true;
|
|
16
17
|
export let closeOnBackdrop = true;
|
|
17
18
|
export let closeOnEscape = true;
|
|
@@ -45,6 +46,7 @@
|
|
|
45
46
|
title={resolvedTitle}
|
|
46
47
|
{closeLabel}
|
|
47
48
|
{size}
|
|
49
|
+
{padding}
|
|
48
50
|
{dismissible}
|
|
49
51
|
{closeOnBackdrop}
|
|
50
52
|
{closeOnEscape}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImagePreviewDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/ImagePreviewDialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"ImagePreviewDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/ImagePreviewDialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA+D7C,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,kBAAkB;;;;;;;;WAV2mB,UAAU;cAAY,MAAM,GAAG,SAAS;;;;;;sBAA4M,MAAM,GAAG,MAAM;;;cAAoF,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;;;kBAU34B,CAAC;AACtF,KAAK,kBAAkB,GAAG,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACpE,eAAe,kBAAkB,CAAC"}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
export let cancelLabel = 'Cancel';
|
|
17
17
|
export let closeLabel = 'Close dialog';
|
|
18
18
|
export let size: DialogSize = 'sm';
|
|
19
|
+
export let padding: string | undefined = undefined;
|
|
19
20
|
export let confirmDisabled = false;
|
|
20
21
|
export let cancelDisabled = false;
|
|
21
22
|
export let dismissible = true;
|
|
@@ -81,6 +82,7 @@
|
|
|
81
82
|
{title}
|
|
82
83
|
{closeLabel}
|
|
83
84
|
{size}
|
|
85
|
+
{padding}
|
|
84
86
|
{dismissible}
|
|
85
87
|
{closeOnBackdrop}
|
|
86
88
|
{closeOnEscape}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/InputDialog.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"InputDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/InputDialog.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA0G9D,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,WAAW;;;;;gBAVsuB,eAAe;;;;;;WAAiL,UAAU;cAAY,MAAM,GAAG,SAAS;;;;;;;;sBAA8R,MAAM,GAAG,MAAM;;;gBAAgF,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS;eAAa,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;cAAY,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;;;kBAU13C,CAAC;AAC/E,KAAK,WAAW,GAAG,YAAY,CAAC,OAAO,WAAW,CAAC,CAAC;AACtD,eAAe,WAAW,CAAC"}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
export let doneLabel = 'Done';
|
|
15
15
|
export let closeLabel = 'Close dialog';
|
|
16
16
|
export let size: DialogSize = 'sm';
|
|
17
|
+
export let padding: string | undefined = undefined;
|
|
17
18
|
export let dismissible = true;
|
|
18
19
|
export let closeOnBackdrop = true;
|
|
19
20
|
export let closeOnEscape = true;
|
|
@@ -53,6 +54,7 @@
|
|
|
53
54
|
{title}
|
|
54
55
|
{closeLabel}
|
|
55
56
|
{size}
|
|
57
|
+
{padding}
|
|
56
58
|
{dismissible}
|
|
57
59
|
{closeOnBackdrop}
|
|
58
60
|
{closeOnEscape}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordCopyDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/PasswordCopyDialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"PasswordCopyDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/PasswordCopyDialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA+E7C,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,kBAAkB;;;;;;;;;;WAV6sB,UAAU;cAAY,MAAM,GAAG,SAAS;;;;;;sBAA4M,MAAM,GAAG,MAAM;;cAAgD,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;aAAW,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS;;;kBAU5/B,CAAC;AACtF,KAAK,kBAAkB,GAAG,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACpE,eAAe,kBAAkB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ export * from './dropdown/index.js';
|
|
|
3
3
|
export * from './dropdown-search/index.js';
|
|
4
4
|
export * from './dialog/index.js';
|
|
5
5
|
export * from './data-table/index.js';
|
|
6
|
+
export * from './sortable-list/index.js';
|
|
7
|
+
export * from './ordered-list/index.js';
|
|
8
|
+
export * from './sortable-table/index.js';
|
|
6
9
|
export { getUiMessages, resolveUiLanguage, uiLanguages } from './i18n.js';
|
|
7
10
|
export type { UiLanguage, UiMessages } from './i18n.js';
|
|
8
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC1E,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC1E,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,4 +3,7 @@ export * from './dropdown/index.js';
|
|
|
3
3
|
export * from './dropdown-search/index.js';
|
|
4
4
|
export * from './dialog/index.js';
|
|
5
5
|
export * from './data-table/index.js';
|
|
6
|
+
export * from './sortable-list/index.js';
|
|
7
|
+
export * from './ordered-list/index.js';
|
|
8
|
+
export * from './sortable-table/index.js';
|
|
6
9
|
export { getUiMessages, resolveUiLanguage, uiLanguages } from './i18n.js';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
export type OrderedListItem = { id: string; value?: string; current?: boolean; status?: string };
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
items,
|
|
8
|
+
disabled = false,
|
|
9
|
+
compact = false,
|
|
10
|
+
allowRemoveLast = false,
|
|
11
|
+
renderId,
|
|
12
|
+
onremove,
|
|
13
|
+
oncurrent,
|
|
14
|
+
currentLabel,
|
|
15
|
+
removeLabel,
|
|
16
|
+
children
|
|
17
|
+
}: {
|
|
18
|
+
items: OrderedListItem[];
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
compact?: boolean;
|
|
21
|
+
allowRemoveLast?: boolean;
|
|
22
|
+
renderId?: string;
|
|
23
|
+
onremove?: (id: string) => void;
|
|
24
|
+
oncurrent?: (id: string) => void;
|
|
25
|
+
currentLabel?: (item: OrderedListItem) => string;
|
|
26
|
+
removeLabel?: (item: OrderedListItem) => string;
|
|
27
|
+
children?: Snippet<[OrderedListItem, number]>;
|
|
28
|
+
} = $props();
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<div class:compact class="suu-ordered-list-editor">
|
|
32
|
+
{#each items as item, index}
|
|
33
|
+
{#if renderId === undefined || renderId === item.id}
|
|
34
|
+
<div class="suu-ordered-list-editor__row" data-ordered-id={item.id}>
|
|
35
|
+
{#if children}{@render children(item, index)}{/if}
|
|
36
|
+
{#if oncurrent}
|
|
37
|
+
<button type="button" class="suu-ordered-list-editor__current" disabled={disabled || item.current} aria-label={currentLabel?.(item) ?? `Select ${item.id}`} onclick={() => oncurrent?.(item.id)}>{item.current ? 'Current' : 'Select'}</button>
|
|
38
|
+
{/if}
|
|
39
|
+
{#if onremove}
|
|
40
|
+
<button type="button" class="suu-ordered-list-editor__remove" disabled={disabled || (!allowRemoveLast && items.length === 1)} aria-label={removeLabel?.(item) ?? `Remove ${item.id}`} title={removeLabel?.(item) ?? `Remove ${item.id}`} onclick={() => onremove?.(item.id)}>
|
|
41
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 3h6l1 2h4v2H4V5h4l1-2Zm-2 6h2v9H7V9Zm4 0h2v9h-2V9Zm4 0h2v9h-2V9ZM6 21V8h12v13H6Z" fill="currentColor"/></svg>
|
|
42
|
+
</button>
|
|
43
|
+
{/if}
|
|
44
|
+
</div>
|
|
45
|
+
{/if}
|
|
46
|
+
{/each}
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<style>
|
|
50
|
+
.suu-ordered-list-editor { display: grid; gap: 5px; }
|
|
51
|
+
.suu-ordered-list-editor__row { display: flex; align-items: center; gap: 6px; min-width: 0; }
|
|
52
|
+
.suu-ordered-list-editor__row :global(input) { min-width: 0; flex: 1; }
|
|
53
|
+
.suu-ordered-list-editor__row :global(label) { display: flex; align-items: center; gap: 4px; white-space: nowrap; font-size: 11px; }
|
|
54
|
+
.suu-ordered-list-editor__row :global(label input) { flex: 0; }
|
|
55
|
+
.compact .suu-ordered-list-editor__row { gap: 3px; }
|
|
56
|
+
.suu-ordered-list-editor__current { margin-left: auto; }
|
|
57
|
+
.suu-ordered-list-editor__remove { display: inline-grid; place-items: center; width: 30px; height: 30px; padding: 6px; border: 1px solid transparent; border-radius: 6px; background: transparent; color: #dc2626; cursor: pointer; }
|
|
58
|
+
.suu-ordered-list-editor__remove svg { width: 16px; height: 16px; }
|
|
59
|
+
.suu-ordered-list-editor__remove:disabled { cursor: default; opacity: .35; }
|
|
60
|
+
</style>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
export type OrderedListItem = {
|
|
3
|
+
id: string;
|
|
4
|
+
value?: string;
|
|
5
|
+
current?: boolean;
|
|
6
|
+
status?: string;
|
|
7
|
+
};
|
|
8
|
+
type $$ComponentProps = {
|
|
9
|
+
items: OrderedListItem[];
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
compact?: boolean;
|
|
12
|
+
allowRemoveLast?: boolean;
|
|
13
|
+
renderId?: string;
|
|
14
|
+
onremove?: (id: string) => void;
|
|
15
|
+
oncurrent?: (id: string) => void;
|
|
16
|
+
currentLabel?: (item: OrderedListItem) => string;
|
|
17
|
+
removeLabel?: (item: OrderedListItem) => string;
|
|
18
|
+
children?: Snippet<[OrderedListItem, number]>;
|
|
19
|
+
};
|
|
20
|
+
declare const OrderedListEditor: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
21
|
+
type OrderedListEditor = ReturnType<typeof OrderedListEditor>;
|
|
22
|
+
export default OrderedListEditor;
|
|
23
|
+
//# sourceMappingURL=OrderedListEditor.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrderedListEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/ordered-list/OrderedListEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGpC,MAAM,MAAM,eAAe,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAClG,KAAK,gBAAgB,GAAI;IACtB,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,MAAM,CAAC;IACjD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,MAAM,CAAC;IAChD,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;CAC/C,CAAC;AAyCJ,QAAA,MAAM,iBAAiB,sDAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/ordered-list/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,YAAY,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as OrderedListEditor } from './OrderedListEditor.svelte';
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
<script lang="ts" generics="Item extends SortableListItem">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type {
|
|
4
|
+
SortableListChildren,
|
|
5
|
+
SortableListDropPosition,
|
|
6
|
+
SortableListItem,
|
|
7
|
+
SortableListItemClassGetter,
|
|
8
|
+
SortableListReorderHandler
|
|
9
|
+
} from './types.js';
|
|
10
|
+
|
|
11
|
+
type DropIndicator = { targetId: string; position: SortableListDropPosition };
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
items = [],
|
|
15
|
+
getId = (item: Item) => item.id,
|
|
16
|
+
disabled = false,
|
|
17
|
+
listTag = 'div',
|
|
18
|
+
itemTag = 'div',
|
|
19
|
+
listClass = '',
|
|
20
|
+
itemClass,
|
|
21
|
+
listRole = 'list',
|
|
22
|
+
itemRole = 'listitem',
|
|
23
|
+
onReorder,
|
|
24
|
+
children
|
|
25
|
+
}: {
|
|
26
|
+
items?: Item[];
|
|
27
|
+
getId?: (item: Item) => string;
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
listTag?: string;
|
|
30
|
+
itemTag?: string;
|
|
31
|
+
listClass?: string;
|
|
32
|
+
itemClass?: string | SortableListItemClassGetter<Item>;
|
|
33
|
+
listRole?: string | undefined;
|
|
34
|
+
itemRole?: string | undefined;
|
|
35
|
+
onReorder?: SortableListReorderHandler<Item>;
|
|
36
|
+
children: SortableListChildren<Item>;
|
|
37
|
+
} = $props();
|
|
38
|
+
|
|
39
|
+
let draggedId = $state<string | null>(null);
|
|
40
|
+
let dropIndicator = $state<DropIndicator | null>(null);
|
|
41
|
+
|
|
42
|
+
function finishDrag(): void {
|
|
43
|
+
draggedId = null;
|
|
44
|
+
dropIndicator = null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function startDrag(event: DragEvent, id: string): void {
|
|
48
|
+
if (disabled) {
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
draggedId = id;
|
|
53
|
+
dropIndicator = null;
|
|
54
|
+
if (event.dataTransfer) {
|
|
55
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
56
|
+
event.dataTransfer.setData('text/plain', id);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function dropPosition(event: DragEvent): SortableListDropPosition {
|
|
61
|
+
const bounds = (event.currentTarget as HTMLElement).getBoundingClientRect();
|
|
62
|
+
const pointerY = Number.isFinite(event.clientY) ? event.clientY : bounds.top;
|
|
63
|
+
return pointerY < bounds.top + bounds.height / 2 ? 'before' : 'after';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function updateDropIndicator(event: DragEvent, targetId: string): void {
|
|
67
|
+
if (disabled || !draggedId || draggedId === targetId) return;
|
|
68
|
+
event.preventDefault();
|
|
69
|
+
if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';
|
|
70
|
+
dropIndicator = { targetId, position: dropPosition(event) };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function updateListDropIndicator(event: DragEvent): void {
|
|
74
|
+
if (disabled || event.target !== event.currentTarget || !draggedId || !items.length) return;
|
|
75
|
+
const lastId = getId(items[items.length - 1]);
|
|
76
|
+
if (draggedId === lastId) return;
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';
|
|
79
|
+
dropIndicator = { targetId: lastId, position: 'after' };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function reorder(sourceId: string, targetId: string, position: SortableListDropPosition): void {
|
|
83
|
+
if (disabled || sourceId === targetId) return;
|
|
84
|
+
const sourceIndex = items.findIndex((item) => getId(item) === sourceId);
|
|
85
|
+
if (sourceIndex < 0 || !items.some((item) => getId(item) === targetId)) return;
|
|
86
|
+
const next = [...items];
|
|
87
|
+
const [source] = next.splice(sourceIndex, 1);
|
|
88
|
+
if (!source) return;
|
|
89
|
+
const targetIndex = next.findIndex((item) => getId(item) === targetId);
|
|
90
|
+
next.splice(targetIndex + (position === 'after' ? 1 : 0), 0, source);
|
|
91
|
+
void onReorder?.(next, { sourceId, targetId, position });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function dropItem(event: DragEvent, targetId: string): void {
|
|
95
|
+
event.preventDefault();
|
|
96
|
+
const sourceId = draggedId;
|
|
97
|
+
const position = dropIndicator?.targetId === targetId
|
|
98
|
+
? dropIndicator.position
|
|
99
|
+
: dropPosition(event);
|
|
100
|
+
finishDrag();
|
|
101
|
+
if (sourceId) reorder(sourceId, targetId, position);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function itemClasses(item: Item, index: number): string {
|
|
105
|
+
const custom = typeof itemClass === 'function' ? itemClass(item, index) : itemClass;
|
|
106
|
+
return [
|
|
107
|
+
'suu-sortable-list__item',
|
|
108
|
+
custom,
|
|
109
|
+
draggedId === getId(item) ? 'suu-sortable-list__item--dragging' : '',
|
|
110
|
+
dropIndicator?.targetId === getId(item) && dropIndicator.position === 'before'
|
|
111
|
+
? 'suu-sortable-list__item--drop-before' : '',
|
|
112
|
+
dropIndicator?.targetId === getId(item) && dropIndicator.position === 'after'
|
|
113
|
+
? 'suu-sortable-list__item--drop-after' : ''
|
|
114
|
+
].filter(Boolean).join(' ');
|
|
115
|
+
}
|
|
116
|
+
</script>
|
|
117
|
+
|
|
118
|
+
<svelte:element
|
|
119
|
+
this={listTag}
|
|
120
|
+
class={`suu-sortable-list ${listClass}`.trim()}
|
|
121
|
+
role={listRole}
|
|
122
|
+
ondragover={updateListDropIndicator}
|
|
123
|
+
ondrop={(event) => {
|
|
124
|
+
if (event.target !== event.currentTarget || !items.length) return;
|
|
125
|
+
dropItem(event, getId(items[items.length - 1]));
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
{#each items as item, index (getId(item))}
|
|
129
|
+
{@const id = getId(item)}
|
|
130
|
+
{@const handleProps = {
|
|
131
|
+
draggable: !disabled,
|
|
132
|
+
ondragstart: (event: DragEvent) => startDrag(event, id),
|
|
133
|
+
ondragend: finishDrag
|
|
134
|
+
}}
|
|
135
|
+
<svelte:element
|
|
136
|
+
this={itemTag}
|
|
137
|
+
class={itemClasses(item, index)}
|
|
138
|
+
role={itemRole}
|
|
139
|
+
data-sortable-id={id}
|
|
140
|
+
ondragover={(event) => updateDropIndicator(event, id)}
|
|
141
|
+
ondrop={(event) => dropItem(event, id)}
|
|
142
|
+
>
|
|
143
|
+
{@render children(item, index, handleProps)}
|
|
144
|
+
</svelte:element>
|
|
145
|
+
{/each}
|
|
146
|
+
</svelte:element>
|
|
147
|
+
|
|
148
|
+
<style>
|
|
149
|
+
.suu-sortable-list { position: relative; }
|
|
150
|
+
.suu-sortable-list__item { position: relative; }
|
|
151
|
+
.suu-sortable-list__item--dragging { opacity: 0.55; }
|
|
152
|
+
.suu-sortable-list__item--drop-before::before,
|
|
153
|
+
.suu-sortable-list__item--drop-after::after {
|
|
154
|
+
position: absolute;
|
|
155
|
+
right: 0;
|
|
156
|
+
left: 0;
|
|
157
|
+
z-index: 2;
|
|
158
|
+
height: 3px;
|
|
159
|
+
border-radius: 999px;
|
|
160
|
+
background: var(--suu-color-accent, #2563eb);
|
|
161
|
+
box-shadow: 0 0 8px color-mix(in srgb, var(--suu-color-accent, #2563eb) 65%, transparent);
|
|
162
|
+
content: '';
|
|
163
|
+
pointer-events: none;
|
|
164
|
+
}
|
|
165
|
+
.suu-sortable-list__item--drop-before::before { top: -7px; }
|
|
166
|
+
.suu-sortable-list__item--drop-after::after { bottom: -7px; }
|
|
167
|
+
</style>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { SortableListChildren, SortableListItem, SortableListItemClassGetter, SortableListReorderHandler } from './types.js';
|
|
2
|
+
declare function $$render<Item extends SortableListItem>(): {
|
|
3
|
+
props: {
|
|
4
|
+
items?: Item[];
|
|
5
|
+
getId?: (item: Item) => string;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
listTag?: string;
|
|
8
|
+
itemTag?: string;
|
|
9
|
+
listClass?: string;
|
|
10
|
+
itemClass?: string | SortableListItemClassGetter<Item>;
|
|
11
|
+
listRole?: string | undefined;
|
|
12
|
+
itemRole?: string | undefined;
|
|
13
|
+
onReorder?: SortableListReorderHandler<Item>;
|
|
14
|
+
children: SortableListChildren<Item>;
|
|
15
|
+
};
|
|
16
|
+
exports: {};
|
|
17
|
+
bindings: "";
|
|
18
|
+
slots: {};
|
|
19
|
+
events: {};
|
|
20
|
+
};
|
|
21
|
+
declare class __sveltets_Render<Item extends SortableListItem> {
|
|
22
|
+
props(): ReturnType<typeof $$render<Item>>['props'];
|
|
23
|
+
events(): ReturnType<typeof $$render<Item>>['events'];
|
|
24
|
+
slots(): ReturnType<typeof $$render<Item>>['slots'];
|
|
25
|
+
bindings(): "";
|
|
26
|
+
exports(): {};
|
|
27
|
+
}
|
|
28
|
+
interface $$IsomorphicComponent {
|
|
29
|
+
new <Item extends SortableListItem>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<Item>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<Item>['props']>, ReturnType<__sveltets_Render<Item>['events']>, ReturnType<__sveltets_Render<Item>['slots']>> & {
|
|
30
|
+
$$bindings?: ReturnType<__sveltets_Render<Item>['bindings']>;
|
|
31
|
+
} & ReturnType<__sveltets_Render<Item>['exports']>;
|
|
32
|
+
<Item extends SortableListItem>(internal: unknown, props: ReturnType<__sveltets_Render<Item>['props']> & {}): ReturnType<__sveltets_Render<Item>['exports']>;
|
|
33
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
34
|
+
}
|
|
35
|
+
declare const SortableList: $$IsomorphicComponent;
|
|
36
|
+
type SortableList<Item extends SortableListItem> = InstanceType<typeof SortableList<Item>>;
|
|
37
|
+
export default SortableList;
|
|
38
|
+
//# sourceMappingURL=SortableList.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SortableList.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/sortable-list/SortableList.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACR,oBAAoB,EAEpB,gBAAgB,EAChB,2BAA2B,EAC3B,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AACtB,iBAAS,QAAQ,CAAC,IAAI,SAAS,gBAAgB;;gBAMnC,IAAI,EAAE;gBACN,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM;mBACnB,OAAO;kBACR,MAAM;kBACN,MAAM;oBACJ,MAAM;oBACN,MAAM,GAAG,2BAA2B,CAAC,IAAI,CAAC;mBAC3C,MAAM,GAAG,SAAS;mBAClB,MAAM,GAAG,SAAS;oBACjB,0BAA0B,CAAC,IAAI,CAAC;kBAClC,oBAAoB,CAAC,IAAI,CAAC;;;;;;EAoHiF;AACzH,cAAM,iBAAiB,CAAC,IAAI,SAAS,gBAAgB;IACjD,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IACnD,MAAM,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;IACrD,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IACnD,QAAQ;IACR,OAAO;CACV;AAED,UAAU,qBAAqB;IAC3B,KAAK,IAAI,SAAS,gBAAgB,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;KAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC1a,CAAC,IAAI,SAAS,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC7J,YAAY,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;CACjE;AACD,QAAA,MAAM,YAAY,EAAE,qBAAmC,CAAC;AACtC,KAAK,YAAY,CAAC,IAAI,SAAS,gBAAgB,IAAI,YAAY,CAAC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;AAC7F,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { default as SortableList } from './SortableList.svelte';
|
|
2
|
+
export type { SortableListChildren, SortableListDropPosition, SortableListHandleProps, SortableListItem, SortableListItemClassGetter, SortableListReorderDetail, SortableListReorderHandler } from './types.js';
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/sortable-list/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,YAAY,EACV,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,EACvB,gBAAgB,EAChB,2BAA2B,EAC3B,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as SortableList } from './SortableList.svelte';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
export type SortableListItem = {
|
|
3
|
+
id: string;
|
|
4
|
+
};
|
|
5
|
+
export type SortableListDropPosition = 'before' | 'after';
|
|
6
|
+
export type SortableListHandleProps = {
|
|
7
|
+
draggable: boolean;
|
|
8
|
+
ondragstart: (event: DragEvent) => void;
|
|
9
|
+
ondragend: () => void;
|
|
10
|
+
};
|
|
11
|
+
export type SortableListReorderDetail = {
|
|
12
|
+
sourceId: string;
|
|
13
|
+
targetId: string;
|
|
14
|
+
position: SortableListDropPosition;
|
|
15
|
+
};
|
|
16
|
+
export type SortableListReorderHandler<Item extends SortableListItem> = (items: Item[], detail: SortableListReorderDetail) => void | Promise<void>;
|
|
17
|
+
export type SortableListItemClassGetter<Item extends SortableListItem> = (item: Item, index: number) => string | undefined | null;
|
|
18
|
+
export type SortableListChildren<Item extends SortableListItem> = Snippet<[
|
|
19
|
+
Item,
|
|
20
|
+
number,
|
|
21
|
+
SortableListHandleProps
|
|
22
|
+
]>;
|
|
23
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/sortable-list/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,MAAM,gBAAgB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAC9C,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1D,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACxC,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,wBAAwB,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,0BAA0B,CAAC,IAAI,SAAS,gBAAgB,IAAI,CACtE,KAAK,EAAE,IAAI,EAAE,EACb,MAAM,EAAE,yBAAyB,KAC9B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,MAAM,2BAA2B,CAAC,IAAI,SAAS,gBAAgB,IAAI,CACvE,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,KACV,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;AAE/B,MAAM,MAAM,oBAAoB,CAAC,IAAI,SAAS,gBAAgB,IAAI,OAAO,CAAC;IACxE,IAAI;IACJ,MAAM;IACN,uBAAuB;CACxB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
<script lang="ts" generics="Item extends SortableTableItem">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { SortableListDropPosition } from '../sortable-list/types.js';
|
|
4
|
+
import type { SortableTableItem, SortableTableReorderDetail } from './types.js';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
items = [],
|
|
8
|
+
getId = (item: Item) => item.id,
|
|
9
|
+
disabled = false,
|
|
10
|
+
allowRemoveLast = false,
|
|
11
|
+
tableClass = '',
|
|
12
|
+
getRowClass,
|
|
13
|
+
getDragLabel = (item: Item) => `Drag ${getId(item)}`,
|
|
14
|
+
getRemoveLabel = (item: Item) => `Remove ${getId(item)}`,
|
|
15
|
+
onReorder,
|
|
16
|
+
onRemove,
|
|
17
|
+
dragAccessory,
|
|
18
|
+
header,
|
|
19
|
+
children
|
|
20
|
+
}: {
|
|
21
|
+
items?: Item[];
|
|
22
|
+
getId?: (item: Item) => string;
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
allowRemoveLast?: boolean;
|
|
25
|
+
tableClass?: string;
|
|
26
|
+
getRowClass?: (item: Item, index: number) => string | undefined | null;
|
|
27
|
+
getDragLabel?: (item: Item, index: number) => string;
|
|
28
|
+
getRemoveLabel?: (item: Item, index: number) => string;
|
|
29
|
+
onReorder?: (items: Item[], detail: SortableTableReorderDetail) => void;
|
|
30
|
+
onRemove?: (item: Item) => void;
|
|
31
|
+
dragAccessory?: Snippet<[Item, number]>;
|
|
32
|
+
header: Snippet;
|
|
33
|
+
children: Snippet<[Item, number]>;
|
|
34
|
+
} = $props();
|
|
35
|
+
|
|
36
|
+
let draggingId = $state<string | null>(null);
|
|
37
|
+
let indicator = $state<{ id: string; position: SortableListDropPosition } | null>(null);
|
|
38
|
+
|
|
39
|
+
function finishDrag(): void { draggingId = null; indicator = null; }
|
|
40
|
+
function startDrag(event: DragEvent, id: string): void {
|
|
41
|
+
if (disabled) { event.preventDefault(); return; }
|
|
42
|
+
draggingId = id;
|
|
43
|
+
indicator = null;
|
|
44
|
+
if (event.dataTransfer) {
|
|
45
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
46
|
+
event.dataTransfer.setData('text/plain', id);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function position(event: DragEvent): SortableListDropPosition {
|
|
50
|
+
const bounds = (event.currentTarget as HTMLElement).getBoundingClientRect();
|
|
51
|
+
return event.clientY < bounds.top + bounds.height / 2 ? 'before' : 'after';
|
|
52
|
+
}
|
|
53
|
+
function dragOver(event: DragEvent, id: string): void {
|
|
54
|
+
if (disabled || !draggingId || draggingId === id) return;
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
indicator = { id, position: position(event) };
|
|
57
|
+
}
|
|
58
|
+
function drop(event: DragEvent, targetId: string): void {
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
const sourceId = draggingId;
|
|
61
|
+
const targetPosition = indicator?.id === targetId ? indicator.position : position(event);
|
|
62
|
+
finishDrag();
|
|
63
|
+
if (!sourceId || sourceId === targetId || disabled) return;
|
|
64
|
+
const sourceIndex = items.findIndex((item) => getId(item) === sourceId);
|
|
65
|
+
if (sourceIndex < 0) return;
|
|
66
|
+
const next = [...items];
|
|
67
|
+
const [source] = next.splice(sourceIndex, 1);
|
|
68
|
+
if (!source) return;
|
|
69
|
+
const targetIndex = next.findIndex((item) => getId(item) === targetId);
|
|
70
|
+
if (targetIndex < 0) return;
|
|
71
|
+
next.splice(targetIndex + (targetPosition === 'after' ? 1 : 0), 0, source);
|
|
72
|
+
void onReorder?.(next, { sourceId, targetId, position: targetPosition });
|
|
73
|
+
}
|
|
74
|
+
function rowClass(item: Item, index: number): string {
|
|
75
|
+
return ['suu-sortable-table__row', getRowClass?.(item, index), draggingId === getId(item) ? 'suu-sortable-table__row--dragging' : '', indicator?.id === getId(item) ? `suu-sortable-table__row--drop-${indicator.position}` : ''].filter(Boolean).join(' ');
|
|
76
|
+
}
|
|
77
|
+
</script>
|
|
78
|
+
|
|
79
|
+
<table class={`suu-sortable-table ${tableClass}`.trim()}>
|
|
80
|
+
<thead><tr><th class="suu-sortable-table__drag-column" aria-hidden="true"></th>{@render header()}<th class="suu-sortable-table__remove-column" aria-hidden="true"></th></tr></thead>
|
|
81
|
+
<tbody>
|
|
82
|
+
{#each items as item, index (getId(item))}
|
|
83
|
+
{@const id = getId(item)}
|
|
84
|
+
{@const dragLabel = getDragLabel(item, index)}
|
|
85
|
+
{@const removeLabel = getRemoveLabel(item, index)}
|
|
86
|
+
<tr class={rowClass(item, index)} data-sortable-id={id} ondragover={(event) => dragOver(event, id)} ondrop={(event) => drop(event, id)}>
|
|
87
|
+
<td class="suu-sortable-table__drag-cell">
|
|
88
|
+
<button type="button" class="suu-sortable-table__drag-handle" disabled={disabled} draggable={!disabled} aria-label={dragLabel} title={dragLabel} ondragstart={(event) => startDrag(event, id)} ondragend={finishDrag}>⋮⋮</button>
|
|
89
|
+
{#if dragAccessory}{@render dragAccessory(item, index)}{/if}
|
|
90
|
+
</td>
|
|
91
|
+
{@render children(item, index)}
|
|
92
|
+
<td class="suu-sortable-table__remove-cell">
|
|
93
|
+
{#if onRemove}
|
|
94
|
+
<button type="button" class="suu-sortable-table__remove" disabled={disabled || (!allowRemoveLast && items.length === 1)} aria-label={removeLabel} title={removeLabel} onclick={() => onRemove?.(item)}>
|
|
95
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 3h6l1 2h4v2H4V5h4l1-2Zm-2 6h2v9H7V9Zm4 0h2v9h-2V9Zm4 0h2v9h-2V9ZM6 21V8h12v13H6Z" fill="currentColor"/></svg>
|
|
96
|
+
</button>
|
|
97
|
+
{/if}
|
|
98
|
+
</td>
|
|
99
|
+
</tr>
|
|
100
|
+
{/each}
|
|
101
|
+
</tbody>
|
|
102
|
+
</table>
|
|
103
|
+
|
|
104
|
+
<style>
|
|
105
|
+
.suu-sortable-table { width: 100%; border-collapse: collapse; }
|
|
106
|
+
.suu-sortable-table__drag-column, .suu-sortable-table__remove-column { width: 38px; }
|
|
107
|
+
.suu-sortable-table__drag-cell, .suu-sortable-table__remove-cell { width: 38px; padding: 6px; text-align: center; vertical-align: middle; }
|
|
108
|
+
.suu-sortable-table__drag-handle, .suu-sortable-table__remove { display: inline-grid; place-items: center; border: 0; background: transparent; cursor: grab; color: var(--suu-color-text-dim, #6b7280); padding: 4px; font: inherit; }
|
|
109
|
+
.suu-sortable-table__remove { width: 30px; height: 30px; cursor: pointer; color: var(--suu-color-danger, #dc2626); }
|
|
110
|
+
.suu-sortable-table__remove svg { width: 16px; height: 16px; }
|
|
111
|
+
.suu-sortable-table__drag-handle:active { cursor: grabbing; }
|
|
112
|
+
.suu-sortable-table__drag-handle:disabled, .suu-sortable-table__remove:disabled { cursor: default; opacity: .35; }
|
|
113
|
+
.suu-sortable-table__row { position: relative; border-bottom: 1px solid var(--suu-color-border, #d1d5db); }
|
|
114
|
+
.suu-sortable-table :global(td) { border-bottom: 0; }
|
|
115
|
+
.suu-sortable-table__row--dragging { opacity: .55; }
|
|
116
|
+
.suu-sortable-table__row--drop-before :global(td) { box-shadow: inset 0 3px 0 var(--suu-color-accent, #2563eb); }
|
|
117
|
+
.suu-sortable-table__row--drop-after :global(td) { box-shadow: inset 0 -3px 0 var(--suu-color-accent, #2563eb); }
|
|
118
|
+
</style>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { SortableTableItem, SortableTableReorderDetail } from './types.js';
|
|
3
|
+
declare function $$render<Item extends SortableTableItem>(): {
|
|
4
|
+
props: {
|
|
5
|
+
items?: Item[];
|
|
6
|
+
getId?: (item: Item) => string;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
allowRemoveLast?: boolean;
|
|
9
|
+
tableClass?: string;
|
|
10
|
+
getRowClass?: (item: Item, index: number) => string | undefined | null;
|
|
11
|
+
getDragLabel?: (item: Item, index: number) => string;
|
|
12
|
+
getRemoveLabel?: (item: Item, index: number) => string;
|
|
13
|
+
onReorder?: (items: Item[], detail: SortableTableReorderDetail) => void;
|
|
14
|
+
onRemove?: (item: Item) => void;
|
|
15
|
+
dragAccessory?: Snippet<[Item, number]>;
|
|
16
|
+
header: Snippet;
|
|
17
|
+
children: Snippet<[Item, number]>;
|
|
18
|
+
};
|
|
19
|
+
exports: {};
|
|
20
|
+
bindings: "";
|
|
21
|
+
slots: {};
|
|
22
|
+
events: {};
|
|
23
|
+
};
|
|
24
|
+
declare class __sveltets_Render<Item extends SortableTableItem> {
|
|
25
|
+
props(): ReturnType<typeof $$render<Item>>['props'];
|
|
26
|
+
events(): ReturnType<typeof $$render<Item>>['events'];
|
|
27
|
+
slots(): ReturnType<typeof $$render<Item>>['slots'];
|
|
28
|
+
bindings(): "";
|
|
29
|
+
exports(): {};
|
|
30
|
+
}
|
|
31
|
+
interface $$IsomorphicComponent {
|
|
32
|
+
new <Item extends SortableTableItem>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<Item>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<Item>['props']>, ReturnType<__sveltets_Render<Item>['events']>, ReturnType<__sveltets_Render<Item>['slots']>> & {
|
|
33
|
+
$$bindings?: ReturnType<__sveltets_Render<Item>['bindings']>;
|
|
34
|
+
} & ReturnType<__sveltets_Render<Item>['exports']>;
|
|
35
|
+
<Item extends SortableTableItem>(internal: unknown, props: ReturnType<__sveltets_Render<Item>['props']> & {}): ReturnType<__sveltets_Render<Item>['exports']>;
|
|
36
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
37
|
+
}
|
|
38
|
+
declare const SortableTable: $$IsomorphicComponent;
|
|
39
|
+
type SortableTable<Item extends SortableTableItem> = InstanceType<typeof SortableTable<Item>>;
|
|
40
|
+
export default SortableTable;
|
|
41
|
+
//# sourceMappingURL=SortableTable.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SortableTable.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/sortable-table/SortableTable.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAChF,iBAAS,QAAQ,CAAC,IAAI,SAAS,iBAAiB;;gBAKpC,IAAI,EAAE;gBACN,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM;mBACnB,OAAO;0BACA,OAAO;qBACZ,MAAM;sBACL,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,IAAI;uBACvD,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM;yBACnC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM;oBAC1C,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,0BAA0B,KAAK,IAAI;mBAC5D,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI;wBACf,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC/B,OAAO;kBACL,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;;;;;;EA0FoF;AACzH,cAAM,iBAAiB,CAAC,IAAI,SAAS,iBAAiB;IAClD,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IACnD,MAAM,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;IACrD,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IACnD,QAAQ;IACR,OAAO;CACV;AAED,UAAU,qBAAqB;IAC3B,KAAK,IAAI,SAAS,iBAAiB,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;KAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3a,CAAC,IAAI,SAAS,iBAAiB,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9J,YAAY,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;CACjE;AACD,QAAA,MAAM,aAAa,EAAE,qBAAmC,CAAC;AACvC,KAAK,aAAa,CAAC,IAAI,SAAS,iBAAiB,IAAI,YAAY,CAAC,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;AAChG,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
<script lang="ts" generics="Item extends SortableTableItem">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import SortableTable from './SortableTable.svelte';
|
|
4
|
+
import type {
|
|
5
|
+
SortableTableItem,
|
|
6
|
+
SortableTableReorderDetail,
|
|
7
|
+
SortableTableRowColorPreset
|
|
8
|
+
} from './types.js';
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
items = [],
|
|
12
|
+
getId = (item: Item) => item.id,
|
|
13
|
+
disabled = false,
|
|
14
|
+
allowRemoveLast = false,
|
|
15
|
+
tableClass = '',
|
|
16
|
+
currentId = null,
|
|
17
|
+
getCurrentDisabled = () => false,
|
|
18
|
+
getCurrentLabel = (item: Item) => `Set ${getId(item)} as current`,
|
|
19
|
+
getRowColorPreset = () => null,
|
|
20
|
+
getDragLabel,
|
|
21
|
+
getRemoveLabel,
|
|
22
|
+
onReorder,
|
|
23
|
+
onRemove,
|
|
24
|
+
onCurrentChange,
|
|
25
|
+
header,
|
|
26
|
+
children
|
|
27
|
+
}: {
|
|
28
|
+
items?: Item[];
|
|
29
|
+
getId?: (item: Item) => string;
|
|
30
|
+
disabled?: boolean;
|
|
31
|
+
allowRemoveLast?: boolean;
|
|
32
|
+
tableClass?: string;
|
|
33
|
+
currentId?: string | null;
|
|
34
|
+
getCurrentDisabled?: (item: Item, index: number) => boolean;
|
|
35
|
+
getCurrentLabel?: (item: Item, index: number) => string;
|
|
36
|
+
getRowColorPreset?: (item: Item, index: number) => SortableTableRowColorPreset | undefined | null;
|
|
37
|
+
getDragLabel?: (item: Item, index: number) => string;
|
|
38
|
+
getRemoveLabel?: (item: Item, index: number) => string;
|
|
39
|
+
onReorder?: (items: Item[], detail: SortableTableReorderDetail) => void;
|
|
40
|
+
onRemove?: (item: Item) => void;
|
|
41
|
+
onCurrentChange?: (item: Item) => void | Promise<void>;
|
|
42
|
+
header: Snippet;
|
|
43
|
+
children: Snippet<[Item, number]>;
|
|
44
|
+
} = $props();
|
|
45
|
+
|
|
46
|
+
const instanceId = $props.id();
|
|
47
|
+
const radioName = `suu-sortable-table-current-${instanceId}`;
|
|
48
|
+
|
|
49
|
+
function rowClass(item: Item, index: number): string | undefined {
|
|
50
|
+
const preset = getRowColorPreset(item, index);
|
|
51
|
+
return preset ? `suu-sortable-table-enhanced__row--${preset}` : undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function selectCurrent(item: Item): void {
|
|
55
|
+
void onCurrentChange?.(item);
|
|
56
|
+
}
|
|
57
|
+
</script>
|
|
58
|
+
|
|
59
|
+
{#snippet currentControl(item: Item, index: number)}
|
|
60
|
+
<input
|
|
61
|
+
type="radio"
|
|
62
|
+
class="suu-sortable-table-enhanced__current"
|
|
63
|
+
name={radioName}
|
|
64
|
+
value={getId(item)}
|
|
65
|
+
checked={currentId === getId(item)}
|
|
66
|
+
disabled={disabled || !onCurrentChange || getCurrentDisabled(item, index)}
|
|
67
|
+
aria-label={getCurrentLabel(item, index)}
|
|
68
|
+
onchange={() => selectCurrent(item)}
|
|
69
|
+
/>
|
|
70
|
+
{/snippet}
|
|
71
|
+
|
|
72
|
+
<SortableTable
|
|
73
|
+
{items}
|
|
74
|
+
{getId}
|
|
75
|
+
{disabled}
|
|
76
|
+
{allowRemoveLast}
|
|
77
|
+
tableClass={`suu-sortable-table-enhanced ${tableClass}`.trim()}
|
|
78
|
+
getRowClass={rowClass}
|
|
79
|
+
{getDragLabel}
|
|
80
|
+
{getRemoveLabel}
|
|
81
|
+
{onReorder}
|
|
82
|
+
{onRemove}
|
|
83
|
+
dragAccessory={currentControl}
|
|
84
|
+
{header}
|
|
85
|
+
{children}
|
|
86
|
+
/>
|
|
87
|
+
|
|
88
|
+
<style>
|
|
89
|
+
:global(.suu-sortable-table-enhanced .suu-sortable-table__drag-column),
|
|
90
|
+
:global(.suu-sortable-table-enhanced .suu-sortable-table__drag-cell) {
|
|
91
|
+
width: 68px;
|
|
92
|
+
}
|
|
93
|
+
:global(.suu-sortable-table-enhanced .suu-sortable-table__drag-cell) {
|
|
94
|
+
white-space: nowrap;
|
|
95
|
+
}
|
|
96
|
+
.suu-sortable-table-enhanced__current {
|
|
97
|
+
width: 16px;
|
|
98
|
+
height: 16px;
|
|
99
|
+
margin: 0 0 0 6px;
|
|
100
|
+
accent-color: var(--suu-color-accent, #2563eb);
|
|
101
|
+
vertical-align: middle;
|
|
102
|
+
cursor: pointer;
|
|
103
|
+
}
|
|
104
|
+
.suu-sortable-table-enhanced__current:disabled {
|
|
105
|
+
cursor: default;
|
|
106
|
+
opacity: .45;
|
|
107
|
+
}
|
|
108
|
+
:global(.suu-sortable-table-enhanced__row--red > td) {
|
|
109
|
+
background-color: var(--suu-sortable-table-row-red-light, rgba(207, 34, 46, .08));
|
|
110
|
+
}
|
|
111
|
+
:global(.suu-sortable-table-enhanced__row--yellow > td) {
|
|
112
|
+
background-color: var(--suu-sortable-table-row-yellow-light, rgba(191, 135, 0, .09));
|
|
113
|
+
}
|
|
114
|
+
:global(.suu-sortable-table-enhanced__row--green > td) {
|
|
115
|
+
background-color: var(--suu-sortable-table-row-green-light, rgba(26, 127, 55, .08));
|
|
116
|
+
}
|
|
117
|
+
@media (prefers-color-scheme: dark) {
|
|
118
|
+
:global(.suu-sortable-table-enhanced__row--red > td) {
|
|
119
|
+
background-color: var(--suu-sortable-table-row-red-dark, var(--suu-sortable-table-row-red-light, rgba(239, 68, 68, .14)));
|
|
120
|
+
}
|
|
121
|
+
:global(.suu-sortable-table-enhanced__row--yellow > td) {
|
|
122
|
+
background-color: var(--suu-sortable-table-row-yellow-dark, var(--suu-sortable-table-row-yellow-light, rgba(245, 158, 11, .14)));
|
|
123
|
+
}
|
|
124
|
+
:global(.suu-sortable-table-enhanced__row--green > td) {
|
|
125
|
+
background-color: var(--suu-sortable-table-row-green-dark, var(--suu-sortable-table-row-green-light, rgba(34, 197, 94, .13)));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
</style>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { SortableTableItem, SortableTableReorderDetail, SortableTableRowColorPreset } from './types.js';
|
|
3
|
+
declare function $$render<Item extends SortableTableItem>(): {
|
|
4
|
+
props: {
|
|
5
|
+
items?: Item[];
|
|
6
|
+
getId?: (item: Item) => string;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
allowRemoveLast?: boolean;
|
|
9
|
+
tableClass?: string;
|
|
10
|
+
currentId?: string | null;
|
|
11
|
+
getCurrentDisabled?: (item: Item, index: number) => boolean;
|
|
12
|
+
getCurrentLabel?: (item: Item, index: number) => string;
|
|
13
|
+
getRowColorPreset?: (item: Item, index: number) => SortableTableRowColorPreset | undefined | null;
|
|
14
|
+
getDragLabel?: (item: Item, index: number) => string;
|
|
15
|
+
getRemoveLabel?: (item: Item, index: number) => string;
|
|
16
|
+
onReorder?: (items: Item[], detail: SortableTableReorderDetail) => void;
|
|
17
|
+
onRemove?: (item: Item) => void;
|
|
18
|
+
onCurrentChange?: (item: Item) => void | Promise<void>;
|
|
19
|
+
header: Snippet;
|
|
20
|
+
children: Snippet<[Item, number]>;
|
|
21
|
+
};
|
|
22
|
+
exports: {};
|
|
23
|
+
bindings: "";
|
|
24
|
+
slots: {};
|
|
25
|
+
events: {};
|
|
26
|
+
};
|
|
27
|
+
declare class __sveltets_Render<Item extends SortableTableItem> {
|
|
28
|
+
props(): ReturnType<typeof $$render<Item>>['props'];
|
|
29
|
+
events(): ReturnType<typeof $$render<Item>>['events'];
|
|
30
|
+
slots(): ReturnType<typeof $$render<Item>>['slots'];
|
|
31
|
+
bindings(): "";
|
|
32
|
+
exports(): {};
|
|
33
|
+
}
|
|
34
|
+
interface $$IsomorphicComponent {
|
|
35
|
+
new <Item extends SortableTableItem>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<Item>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<Item>['props']>, ReturnType<__sveltets_Render<Item>['events']>, ReturnType<__sveltets_Render<Item>['slots']>> & {
|
|
36
|
+
$$bindings?: ReturnType<__sveltets_Render<Item>['bindings']>;
|
|
37
|
+
} & ReturnType<__sveltets_Render<Item>['exports']>;
|
|
38
|
+
<Item extends SortableTableItem>(internal: unknown, props: ReturnType<__sveltets_Render<Item>['props']> & {}): ReturnType<__sveltets_Render<Item>['exports']>;
|
|
39
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
40
|
+
}
|
|
41
|
+
declare const SortableTableEnhanced: $$IsomorphicComponent;
|
|
42
|
+
type SortableTableEnhanced<Item extends SortableTableItem> = InstanceType<typeof SortableTableEnhanced<Item>>;
|
|
43
|
+
export default SortableTableEnhanced;
|
|
44
|
+
//# sourceMappingURL=SortableTableEnhanced.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SortableTableEnhanced.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/sortable-table/SortableTableEnhanced.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EACR,iBAAiB,EACjB,0BAA0B,EAC1B,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AACtB,iBAAS,QAAQ,CAAC,IAAI,SAAS,iBAAiB;;gBAOpC,IAAI,EAAE;gBACN,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM;mBACnB,OAAO;0BACA,OAAO;qBACZ,MAAM;oBACP,MAAM,GAAG,IAAI;6BACJ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO;0BACzC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM;4BACnC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,2BAA2B,GAAG,SAAS,GAAG,IAAI;uBAClF,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM;yBACnC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM;oBAC1C,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,0BAA0B,KAAK,IAAI;mBAC5D,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI;0BACb,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBAC9C,OAAO;kBACL,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;;;;;;EA0CoF;AACzH,cAAM,iBAAiB,CAAC,IAAI,SAAS,iBAAiB;IAClD,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IACnD,MAAM,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;IACrD,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IACnD,QAAQ;IACR,OAAO;CACV;AAED,UAAU,qBAAqB;IAC3B,KAAK,IAAI,SAAS,iBAAiB,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;KAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3a,CAAC,IAAI,SAAS,iBAAiB,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9J,YAAY,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;CACjE;AACD,QAAA,MAAM,qBAAqB,EAAE,qBAAmC,CAAC;AAC/C,KAAK,qBAAqB,CAAC,IAAI,SAAS,iBAAiB,IAAI,YAAY,CAAC,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;AAChH,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { default as SortableTable } from './SortableTable.svelte';
|
|
2
|
+
export { default as SortableTableEnhanced } from './SortableTableEnhanced.svelte';
|
|
3
|
+
export type { SortableTableHandle, SortableTableItem, SortableTableReorderDetail, SortableTableRowClassGetter, SortableTableRowColorPreset, SortableTableRowColorPresetGetter } from './types.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/sortable-table/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAClF,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,0BAA0B,EAC1B,2BAA2B,EAC3B,2BAA2B,EAC3B,iCAAiC,EAClC,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SortableListDropPosition, SortableListItem } from '../sortable-list/types.js';
|
|
2
|
+
export type SortableTableItem = SortableListItem;
|
|
3
|
+
export type SortableTableReorderDetail = {
|
|
4
|
+
sourceId: string;
|
|
5
|
+
targetId: string;
|
|
6
|
+
position: SortableListDropPosition;
|
|
7
|
+
};
|
|
8
|
+
export type SortableTableHandle = {
|
|
9
|
+
draggable: boolean;
|
|
10
|
+
ondragstart: (event: DragEvent) => void;
|
|
11
|
+
ondragend: () => void;
|
|
12
|
+
};
|
|
13
|
+
export type SortableTableRowClassGetter<Item extends SortableTableItem> = (item: Item, index: number) => string | undefined | null;
|
|
14
|
+
export type SortableTableRowColorPreset = 'red' | 'yellow' | 'green';
|
|
15
|
+
export type SortableTableRowColorPresetGetter<Item extends SortableTableItem> = (item: Item, index: number) => SortableTableRowColorPreset | undefined | null;
|
|
16
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/sortable-table/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE5F,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AACjD,MAAM,MAAM,0BAA0B,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,wBAAwB,CAAA;CAAE,CAAC;AACpH,MAAM,MAAM,mBAAmB,GAAG;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC;AACzH,MAAM,MAAM,2BAA2B,CAAC,IAAI,SAAS,iBAAiB,IAAI,CACxE,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,KACV,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;AAC/B,MAAM,MAAM,2BAA2B,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;AACrE,MAAM,MAAM,iCAAiC,CAAC,IAAI,SAAS,iBAAiB,IAAI,CAC9E,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,KACV,2BAA2B,GAAG,SAAS,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/style.css
CHANGED
|
@@ -1326,7 +1326,7 @@
|
|
|
1326
1326
|
display: flex;
|
|
1327
1327
|
gap: 12px;
|
|
1328
1328
|
align-items: center;
|
|
1329
|
-
padding: 16px 18px;
|
|
1329
|
+
padding: var(--suu-dialog-padding, 16px 18px);
|
|
1330
1330
|
}
|
|
1331
1331
|
|
|
1332
1332
|
.suu-dialog__header {
|
|
@@ -1385,7 +1385,7 @@
|
|
|
1385
1385
|
.suu-dialog__body {
|
|
1386
1386
|
min-height: 0;
|
|
1387
1387
|
overflow: auto;
|
|
1388
|
-
padding: 18px;
|
|
1388
|
+
padding: var(--suu-dialog-padding, 18px);
|
|
1389
1389
|
}
|
|
1390
1390
|
|
|
1391
1391
|
.suu-dialog__footer {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ibobbyts/svelte-ui-utils",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"description": "Reusable Svelte 5 UI utilities for dialogs, toast notifications, dropdown search, and data tables.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -62,6 +62,21 @@
|
|
|
62
62
|
"svelte": "./dist/pagination/index.js",
|
|
63
63
|
"default": "./dist/pagination/index.js"
|
|
64
64
|
},
|
|
65
|
+
"./sortable-list": {
|
|
66
|
+
"types": "./dist/sortable-list/index.d.ts",
|
|
67
|
+
"svelte": "./dist/sortable-list/index.js",
|
|
68
|
+
"default": "./dist/sortable-list/index.js"
|
|
69
|
+
},
|
|
70
|
+
"./ordered-list": {
|
|
71
|
+
"types": "./dist/ordered-list/index.d.ts",
|
|
72
|
+
"svelte": "./dist/ordered-list/index.js",
|
|
73
|
+
"default": "./dist/ordered-list/index.js"
|
|
74
|
+
},
|
|
75
|
+
"./sortable-table": {
|
|
76
|
+
"types": "./dist/sortable-table/index.d.ts",
|
|
77
|
+
"svelte": "./dist/sortable-table/index.js",
|
|
78
|
+
"default": "./dist/sortable-table/index.js"
|
|
79
|
+
},
|
|
65
80
|
"./style.css": "./dist/style.css"
|
|
66
81
|
},
|
|
67
82
|
"publishConfig": {
|