@dosgato/dialog 1.0.7 → 1.1.0
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/Container.svelte +2 -0
- package/dist/Dialog.svelte +4 -0
- package/dist/FieldChoices.svelte +1 -1
- package/dist/FieldChooserLink.svelte +9 -3
- package/dist/FieldDateTime.svelte +17 -1
- package/dist/FieldDateTime.svelte.d.ts +1 -0
- package/dist/FieldDualListbox.svelte +2 -1
- package/dist/FieldHidden.svelte +2 -2
- package/dist/FieldMultiple.svelte +4 -0
- package/dist/FieldSelect.svelte +7 -0
- package/dist/Form.svelte +1 -1
- package/dist/Listbox.svelte +1 -1
- package/dist/MaxLength.svelte +1 -1
- package/dist/Tab.svelte +1 -1
- package/dist/Tabs.svelte +44 -21
- package/dist/chooser/ChooserPreview.svelte +1 -1
- package/dist/colorpicker/FieldColorPicker.svelte +1 -1
- package/dist/cropper/FieldCropper.svelte +6 -0
- package/dist/iconpicker/FieldIconPicker.svelte +11 -5
- package/dist/iconpicker/iconpicker.js +21403 -14036
- package/dist/tree/Tree.svelte +70 -13
- package/dist/tree/Tree.svelte.d.ts +1 -0
- package/dist/tree/TreeNode.svelte +11 -8
- package/dist/tree/treestore.d.ts +1 -0
- package/package.json +4 -4
package/dist/tree/Tree.svelte
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
<script>import {
|
|
1
|
+
<script>import { Icon } from '..';
|
|
2
|
+
import { resize, PopupMenu } from '@txstate-mws/svelte-components';
|
|
2
3
|
import { derivedStore, Store } from '@txstate-mws/svelte-store';
|
|
3
|
-
import { afterUpdate, beforeUpdate, onDestroy, onMount, setContext } from 'svelte';
|
|
4
|
+
import { afterUpdate, beforeUpdate, onDestroy, onMount, setContext, tick } from 'svelte';
|
|
5
|
+
import dotsIcon from '@iconify-icons/ph/dots-three-outline-vertical-fill';
|
|
4
6
|
import { isNotBlank } from 'txstate-utils';
|
|
5
7
|
import LoadIcon from './LoadIcon.svelte';
|
|
6
8
|
import TreeNode from './TreeNode.svelte';
|
|
@@ -12,6 +14,7 @@ export let filter = '';
|
|
|
12
14
|
export let nodeClass = undefined;
|
|
13
15
|
export let singleSelect = undefined;
|
|
14
16
|
export let enableResize = false;
|
|
17
|
+
export let minColumnSize = 100;
|
|
15
18
|
/**
|
|
16
19
|
* this `itemType` prop is here for typescript only
|
|
17
20
|
*
|
|
@@ -35,21 +38,52 @@ const { filteredRootItems, headerOverride } = store;
|
|
|
35
38
|
let checkboxelement;
|
|
36
39
|
const headerelements = [];
|
|
37
40
|
const treeWidth = new Store({});
|
|
41
|
+
let numShownColumns = headers.length;
|
|
42
|
+
let numNeverHidden = headers.filter(h => h.neverHide).length;
|
|
43
|
+
// Need to keep track of which headers are shown or hidden and which is selected
|
|
44
|
+
let shownHeaders = headers;
|
|
45
|
+
let hiddenHeaders = [];
|
|
46
|
+
let selectedHeader = undefined;
|
|
47
|
+
function updateShownHeaders() {
|
|
48
|
+
numShownColumns = Math.min(headers.length, Math.floor(($treeWidth.clientWidth ?? 1024) / minColumnSize));
|
|
49
|
+
if (numShownColumns < headers.length) {
|
|
50
|
+
shownHeaders = [];
|
|
51
|
+
hiddenHeaders = [];
|
|
52
|
+
let available = (selectedHeader ? numShownColumns - 1 : numShownColumns) - numNeverHidden;
|
|
53
|
+
if (selectedHeader?.neverHide)
|
|
54
|
+
available++;
|
|
55
|
+
for (let i = 0; i < headers.length; i++) {
|
|
56
|
+
if (available > 0 || headers[i].neverHide || headers[i].id === selectedHeader?.id) {
|
|
57
|
+
shownHeaders.push(headers[i]);
|
|
58
|
+
if (headers[i].id !== selectedHeader?.id && !headers[i].neverHide)
|
|
59
|
+
available--;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
hiddenHeaders.push(headers[i]);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
shownHeaders = headers;
|
|
68
|
+
hiddenHeaders = [];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
38
71
|
function calcHeaderSizes() {
|
|
72
|
+
updateShownHeaders();
|
|
39
73
|
const headerSizes = [];
|
|
40
74
|
let totalFixed = checkboxelement?.offsetWidth ?? 0;
|
|
41
|
-
for (let i = 0; i <
|
|
42
|
-
const header =
|
|
75
|
+
for (let i = 0; i < shownHeaders.length; i++) {
|
|
76
|
+
const header = shownHeaders[i];
|
|
43
77
|
if (header.fixed || $headerOverride[header.id]) {
|
|
44
|
-
headerSizes[i] = $headerOverride[header.id] ?? header.fixed;
|
|
78
|
+
headerSizes[i] = $headerOverride[header.id] ?? (header.fixed ? (hiddenHeaders.length && i === shownHeaders.length - 1 ? `calc(${header.fixed} + 1em)` : header.fixed) : undefined);
|
|
45
79
|
totalFixed += headerelements[i]?.offsetWidth ?? 0;
|
|
46
80
|
}
|
|
47
81
|
}
|
|
48
82
|
const remainingWidth = ($treeWidth.clientWidth ?? 1024) - totalFixed;
|
|
49
|
-
const growHeaders =
|
|
83
|
+
const growHeaders = shownHeaders.filter((h, i) => !h.fixed && !$headerOverride[h.id]);
|
|
50
84
|
const totalGrowShares = growHeaders.reduce((sum, h) => sum + (h.grow ?? 1), 0);
|
|
51
|
-
for (let i = 0; i <
|
|
52
|
-
const header =
|
|
85
|
+
for (let i = 0; i < shownHeaders.length; i++) {
|
|
86
|
+
const header = shownHeaders[i];
|
|
53
87
|
if (!header.fixed && !$headerOverride[header.id] && headerelements[i]?.offsetWidth) {
|
|
54
88
|
headerSizes[i] = `${remainingWidth * (header.grow ?? 1) / totalGrowShares}px`;
|
|
55
89
|
}
|
|
@@ -151,24 +185,42 @@ afterUpdate(() => {
|
|
|
151
185
|
});
|
|
152
186
|
$: myRootItemIds = $store && $filteredRootItems;
|
|
153
187
|
$: myRootItems = $store?.rootItems?.filter(r => myRootItemIds.has(r.id)) ?? [];
|
|
188
|
+
async function selectHeader(selected) {
|
|
189
|
+
selectedHeader = headers.find(h => h.id === selected.value);
|
|
190
|
+
updateShownHeaders();
|
|
191
|
+
headerSizes.set([]);
|
|
192
|
+
store.resetHeaderOverride();
|
|
193
|
+
await tick();
|
|
194
|
+
headerSizes.set(calcHeaderSizes());
|
|
195
|
+
}
|
|
154
196
|
</script>
|
|
155
197
|
|
|
156
198
|
<svelte:window on:mouseup={headerDragEnd} />
|
|
157
|
-
|
|
158
199
|
<div class="tree-header" class:resizing={!!dragtargetid} use:resize={{ store: treeWidth }} aria-hidden="true" on:mouseup={headerDragEnd} on:touchend={headerDragEnd} on:mousemove={dragtargetid ? headerDrag : undefined} on:touchmove={dragtargetid ? headerDrag : undefined}>
|
|
159
200
|
<div class="checkbox" bind:this={checkboxelement}> </div>
|
|
160
|
-
{#each
|
|
161
|
-
|
|
162
|
-
|
|
201
|
+
{#each shownHeaders as header, i (header.label)}
|
|
202
|
+
{@const hasDropdown = hiddenHeaders.length && i === shownHeaders.length - 1}
|
|
203
|
+
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
204
|
+
<div bind:this={headerelements[i]} id={header.id} class="tree-header-cell {header.id}" class:column-dropdown={hasDropdown} style:width={$headerOverride[header.id] ?? $headerSizes?.[i]} style:padding-left={i === 0 ? '1.4em' : undefined} tabindex={hasDropdown ? 0 : undefined}>{header.label}{#if i === 0 && $store.loading}
|
|
205
|
+
<LoadIcon />{/if}{#if i === 0 && isNotBlank(search)} (searching: {search}){/if}
|
|
206
|
+
{#if hasDropdown}
|
|
207
|
+
<Icon icon={dotsIcon} inline hiddenLabel="Show more columns"/>
|
|
208
|
+
{/if}
|
|
209
|
+
</div>
|
|
210
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
211
|
+
{#if enableResize && i !== shownHeaders.length - 1}<div class="tree-separator {header.id}" on:mousedown={headerDragStart(header, i)} on:touchstart={headerDragStart(header, i)} on:dblclick={headerDragReset}> </div>{/if}
|
|
163
212
|
{/each}
|
|
164
213
|
</div>
|
|
214
|
+
{#if hiddenHeaders.length > 0}
|
|
215
|
+
<PopupMenu items={hiddenHeaders.map(h => ({ value: h.id, label: h.label }))} buttonelement={headerelements[shownHeaders.length-1]} on:change={e => {selectHeader(e.detail)}}/>
|
|
216
|
+
{/if}
|
|
165
217
|
{#if mounted && myRootItems?.length}
|
|
166
218
|
<!-- svelte-ignore a11y-no-noninteractive-element-to-interactive-role -->
|
|
167
219
|
<ul bind:this={store.treeElement} role="tree" class:resizing={!!dragtargetid} on:mousemove={dragtargetid ? headerDrag : undefined} on:touchmove={dragtargetid ? headerDrag : undefined} on:mouseup={headerDragEnd} on:touchend={headerDragEnd} on:keyup={onKeyUp}>
|
|
168
220
|
{#each myRootItems as item, i (item.id)}
|
|
169
221
|
<TreeNode
|
|
170
222
|
{item}
|
|
171
|
-
{
|
|
223
|
+
headers={shownHeaders}
|
|
172
224
|
{headerSizes}
|
|
173
225
|
{nodeClass}
|
|
174
226
|
posinset={i + 1}
|
|
@@ -217,6 +269,11 @@ $: myRootItems = $store?.rootItems?.filter(r => myRootItemIds.has(r.id)) ?? [];
|
|
|
217
269
|
height: 100%;
|
|
218
270
|
background-color: var(--tree-head-text, white);
|
|
219
271
|
}
|
|
272
|
+
:global(.column-dropdown) {
|
|
273
|
+
display: flex;
|
|
274
|
+
gap: 0.5em;
|
|
275
|
+
justify-content: space-between;
|
|
276
|
+
}
|
|
220
277
|
:global([data-eq~="650px"]) .tree-header {
|
|
221
278
|
font-size: 0.8em;
|
|
222
279
|
}
|
|
@@ -10,6 +10,7 @@ declare class __sveltets_Render<T extends TreeItemFromDB> {
|
|
|
10
10
|
nodeClass?: ((itm: T) => string) | undefined;
|
|
11
11
|
singleSelect?: boolean | undefined;
|
|
12
12
|
enableResize?: boolean | undefined;
|
|
13
|
+
minColumnSize?: number | undefined;
|
|
13
14
|
/**
|
|
14
15
|
* this `itemType` prop is here for typescript only
|
|
15
16
|
*
|
|
@@ -41,7 +41,7 @@ function onKeyDown(e) {
|
|
|
41
41
|
store.copy();
|
|
42
42
|
}
|
|
43
43
|
else if (e.key === 'v') {
|
|
44
|
-
store.paste();
|
|
44
|
+
void store.paste();
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
else if (e.key === 'Escape') {
|
|
@@ -77,7 +77,7 @@ function onKeyDown(e) {
|
|
|
77
77
|
store.focus(child);
|
|
78
78
|
}
|
|
79
79
|
else {
|
|
80
|
-
store.open(item);
|
|
80
|
+
void store.open(item);
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
else if (e.key === 'ArrowLeft') {
|
|
@@ -158,7 +158,7 @@ function onClick(e) {
|
|
|
158
158
|
if (item.open && wasFocused && !item.loading)
|
|
159
159
|
store.close(item);
|
|
160
160
|
else if (!item.open)
|
|
161
|
-
store.open(item);
|
|
161
|
+
void store.open(item);
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
function onCheckClick(e) {
|
|
@@ -207,15 +207,15 @@ function onDragOverAbove(e) {
|
|
|
207
207
|
}
|
|
208
208
|
let dragOver = 0;
|
|
209
209
|
let dragOverAbove = 0;
|
|
210
|
-
function onDrop(e) {
|
|
210
|
+
async function onDrop(e) {
|
|
211
211
|
e.preventDefault();
|
|
212
212
|
dragOver = 0;
|
|
213
|
-
return store.drop(item, false, e.dataTransfer.dropEffect === 'copy');
|
|
213
|
+
return await store.drop(item, false, e.dataTransfer.dropEffect === 'copy');
|
|
214
214
|
}
|
|
215
|
-
function onDropAbove(e) {
|
|
215
|
+
async function onDropAbove(e) {
|
|
216
216
|
e.preventDefault();
|
|
217
217
|
dragOverAbove = 0;
|
|
218
|
-
return store.drop(item, true, e.dataTransfer.dropEffect === 'copy');
|
|
218
|
+
return await store.drop(item, true, e.dataTransfer.dropEffect === 'copy');
|
|
219
219
|
}
|
|
220
220
|
function onDragEnter(e) {
|
|
221
221
|
if (!dropZone)
|
|
@@ -244,7 +244,7 @@ function onDragLeaveAbove(e) {
|
|
|
244
244
|
dragOverAbove--;
|
|
245
245
|
}
|
|
246
246
|
let display = $focused && $focused.id === item.id;
|
|
247
|
-
onMount(
|
|
247
|
+
onMount(() => {
|
|
248
248
|
if ($focused && $focused.id === item.id)
|
|
249
249
|
nodeelement.scrollIntoView({ block: 'center' });
|
|
250
250
|
nodeelement.addEventListener('lazy', () => { display = true; });
|
|
@@ -258,6 +258,7 @@ $: if ($dragging) {
|
|
|
258
258
|
</script>
|
|
259
259
|
<li role="presentation">
|
|
260
260
|
{#if dropAbove}
|
|
261
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
261
262
|
<div class="drop-above"
|
|
262
263
|
class:dragOverAbove
|
|
263
264
|
on:dragenter={onDragEnterAbove}
|
|
@@ -298,6 +299,7 @@ $: if ($dragging) {
|
|
|
298
299
|
{#if display}
|
|
299
300
|
<!-- keyboard users have modifier keys, they don't ever focus the checkbox -->
|
|
300
301
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
302
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
301
303
|
<div class="checkbox" on:click={onCheckClick}>
|
|
302
304
|
<Icon icon={isSelected ? checkboxOutline : checkboxBlankOutline } width="1.15em" inline />
|
|
303
305
|
</div>
|
|
@@ -310,6 +312,7 @@ $: if ($dragging) {
|
|
|
310
312
|
>
|
|
311
313
|
{#if i === 0 && item.hasChildren}
|
|
312
314
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
315
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
313
316
|
<span class="arrow" on:click={onClick}><Icon icon={item.open ? menuDown : menuRight} width="1.5em" inline /></span>
|
|
314
317
|
{/if}
|
|
315
318
|
<TreeCell {header} {item} />
|
package/dist/tree/treestore.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ export interface TreeHeader<T extends TreeItemFromDB> {
|
|
|
51
51
|
render?: (item: TypedTreeItem<T>) => string;
|
|
52
52
|
component?: SvelteComponent;
|
|
53
53
|
class?: (item: TypedTreeItem<T>) => string | string[];
|
|
54
|
+
neverHide?: boolean;
|
|
54
55
|
}
|
|
55
56
|
export declare class TreeStore<T extends TreeItemFromDB> extends ActiveStore<ITreeStore<T>> {
|
|
56
57
|
#private;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dosgato/dialog",
|
|
3
3
|
"description": "A component library for building forms that edit a JSON document.",
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"prepublishOnly": "svelte-package",
|
|
7
7
|
"dev": "vite dev --force",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@codemirror/lang-javascript": "^6.1.7",
|
|
24
|
-
"@codemirror/lang-css": "^6.2.
|
|
24
|
+
"@codemirror/lang-css": "^6.2.1",
|
|
25
25
|
"@codemirror/lang-html": "^6.4.3",
|
|
26
26
|
"@iconify/svelte": "^3.0.0",
|
|
27
27
|
"@iconify-icons/mdi": "^1.2.22",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"@sveltejs/adapter-auto": "^2.0.0",
|
|
36
36
|
"@sveltejs/kit": "^1.0.1",
|
|
37
37
|
"@sveltejs/package": "^2.0.1",
|
|
38
|
-
"eslint-config-standard-with-typescript": "^
|
|
39
|
-
"eslint-plugin-
|
|
38
|
+
"eslint-config-standard-with-typescript": "^39.0.0",
|
|
39
|
+
"eslint-plugin-svelte": "^2.0.0",
|
|
40
40
|
"svelte-check": "^3.0.1",
|
|
41
41
|
"svelte-preprocess": "^5.0.0",
|
|
42
42
|
"svelte2tsx": "^0.6.0",
|