@dosgato/dialog 0.0.80 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,8 @@
3
3
  <script>import arrowLeftLight from '@iconify-icons/ph/arrow-left-light';
4
4
  import arrowRightLight from '@iconify-icons/ph/arrow-right-light';
5
5
  import xLight from '@iconify-icons/ph/x-light';
6
+ import arrowsOutSimple from '@iconify-icons/ph/arrows-out-simple';
7
+ import arrowsInSimple from '@iconify-icons/ph/arrows-in-simple';
6
8
  import { eq, Modal, ScreenReaderOnly } from '@txstate-mws/svelte-components';
7
9
  import { createEventDispatcher, setContext } from 'svelte';
8
10
  import { isNotBlank, randomid } from 'txstate-utils';
@@ -16,6 +18,7 @@ export let cancelText = undefined;
16
18
  export let continueText = 'Ok';
17
19
  export let continueIcon = undefined;
18
20
  export let escapable = isNotBlank(cancelText);
21
+ export let expandable = false;
19
22
  export let disabled = false;
20
23
  export let ignoreTabs = false;
21
24
  export let labelid = randomid();
@@ -27,6 +30,7 @@ let nextTitle;
27
30
  let hasRequired = false;
28
31
  let onPrev;
29
32
  let onNext;
33
+ let expanded = false;
30
34
  function onTabChange() {
31
35
  ({ hasTabs, prevTitle, nextTitle, hasRequired, onPrev, onNext } = ctx);
32
36
  }
@@ -35,15 +39,20 @@ $: describedby = [title ? labelid : undefined, descid].filter(isNotBlank).join('
35
39
  </script>
36
40
 
37
41
  <Modal {escapable} {initialfocus} hidefocus={false} includeselector=".ck-body-wrapper" on:escape>
38
- <section class="{size}" use:eq>
42
+ <section class="{expanded ? 'xl' : size}" use:eq>
39
43
  {#if title || icon}
40
44
  <header id={labelid}>
41
45
  <Icon width="1.4em" {icon} inline />{title}
42
46
  </header>
43
47
  {/if}
44
- {#if escapable}
45
- <button type="button" class="escape" on:click={() => dispatch('escape')}><Icon icon={xLight} width="2em" hiddenLabel="Close Dialog" /></button>
46
- {/if}
48
+ <div class="header-buttons">
49
+ {#if expandable && size !== 'xl'}
50
+ <button type="button" class="expand" on:click={() => { expanded = !expanded } }><Icon icon={expanded ? arrowsInSimple : arrowsOutSimple} width="2em" hiddenLabel={`${expanded ? 'Contract' : 'Expand'} dialog`}/></button>
51
+ {/if}
52
+ {#if escapable}
53
+ <button type="button" class="escape" on:click={() => dispatch('escape')}><Icon icon={xLight} width="2em" hiddenLabel="Close Dialog" /></button>
54
+ {/if}
55
+ </div>
47
56
  <div id={descid} class="dialog-content">
48
57
  <slot></slot>
49
58
  </div>
@@ -146,11 +155,12 @@ $: describedby = [title ? labelid : undefined, descid].filter(isNotBlank).join('
146
155
  footer.actions :global(.prev) {
147
156
  margin-right: auto;
148
157
  }
149
-
150
- .escape {
158
+ .header-buttons {
151
159
  position: absolute;
152
160
  top: 0.1em;
153
161
  right: 0;
162
+ }
163
+ .header-buttons button {
154
164
  border: 0;
155
165
  background: none;
156
166
  cursor: pointer;
@@ -20,6 +20,7 @@ declare const __propDef: {
20
20
  continueText?: string | undefined;
21
21
  continueIcon?: IconifyIcon | undefined;
22
22
  escapable?: boolean | undefined;
23
+ expandable?: boolean | undefined;
23
24
  disabled?: boolean | undefined;
24
25
  ignoreTabs?: boolean | undefined;
25
26
  labelid?: string | undefined;
@@ -146,8 +146,13 @@ async function updateSelected(..._) {
146
146
  selectedAsset = { type: 'raw', id: $value, url: cleanedUrlFromValue };
147
147
  }
148
148
  }
149
- if (selectedAsset)
149
+ if (selectedAsset) {
150
150
  urlToValueCache[selectedAsset.url] = $value;
151
+ if (selectedAsset.type !== 'raw' && selectedAsset.type !== 'broken') {
152
+ initialPath = selectedAsset.path ?? initialPath;
153
+ initialSource = selectedAsset.source ?? initialSource;
154
+ }
155
+ }
151
156
  }
152
157
  catch (e) {
153
158
  console.error(e);
@@ -21,7 +21,7 @@ async function onSubmit() {
21
21
  setContext(CHOOSER_API_CONTEXT, chooserClient);
22
22
  </script>
23
23
 
24
- <Dialog continueText="Save" continueIcon={contentSave} cancelText="Cancel" on:escape on:continue={onSubmit} {title} {icon} {size} escapable={false}>
24
+ <Dialog continueText="Save" continueIcon={contentSave} cancelText="Cancel" on:escape on:continue={onSubmit} {title} {icon} {size} escapable={false} expandable>
25
25
  <Form bind:store {submit} {validate} {chooserClient} {autocomplete} {name} {preload} on:saved let:messages let:allMessages let:showingInlineErrors let:saved let:valid let:invalid let:validating let:submitting let:data>
26
26
  <slot {messages} {allMessages} {saved} {validating} {submitting} {valid} {invalid} {data} {showingInlineErrors} />
27
27
  </Form>
package/dist/Icon.svelte CHANGED
@@ -4,22 +4,21 @@
4
4
  isn't supported, to provide in kind icon support, while still making use of aria attributes regardless of support.
5
5
  -->
6
6
  <script>import Icon from '@iconify/svelte/dist/OfflineIcon.svelte';
7
- import { ScreenReaderOnly } from '@txstate-mws/svelte-components';
8
7
  import Tooltip from './Tooltip.svelte';
9
8
  export let icon;
10
9
  /** Label used in a `<ScreenReaderOnly>`. */
11
10
  export let hiddenLabel = undefined;
12
11
  export let inline = false;
13
- export let width = '1em';
14
- export let height = width;
12
+ export let width = undefined;
13
+ export let height = undefined;
15
14
  export let tooltip = undefined;
15
+ // If neither is defined, set both to 1em
16
+ if (!width && !height)
17
+ width = height = '1em';
16
18
  </script>
17
19
 
18
20
  {#if icon}
19
21
  <Tooltip tip={tooltip} top>
20
- <Icon {icon} {inline} {width} {height} aria-hidden={!hiddenLabel} />
22
+ <Icon {icon} {inline} {width} {height} aria-hidden={!hiddenLabel} aria-label={hiddenLabel}/>
21
23
  </Tooltip>
22
- {#if hiddenLabel}
23
- <ScreenReaderOnly>{hiddenLabel}</ScreenReaderOnly>
24
- {/if}
25
24
  {/if}
@@ -35,11 +35,19 @@ export let singleLine = false;
35
35
  <dt>File Size:</dt>
36
36
  <dd>{bytesToHuman(item.bytes)}</dd>
37
37
  </div>
38
+ <div>
39
+ <dt>Path:</dt>
40
+ <dd>{item.path}</dd>
41
+ </div>
38
42
  {:else if item.type === 'page' && item.title}
39
43
  <div>
40
44
  <dt>Title:</dt>
41
45
  <dd>{item.title}</dd>
42
46
  </div>
47
+ <div>
48
+ <dt>Path:</dt>
49
+ <dd>{item.path}</dd>
50
+ </div>
43
51
  {:else if item.type === 'folder'}
44
52
  <div>
45
53
  <dt>Path:</dt>
@@ -7,6 +7,7 @@ import TreeNode from './TreeNode.svelte';
7
7
  import { getHashId, transformSearchable, TreeStore, TREE_STORE_CONTEXT } from './treestore';
8
8
  export let headers;
9
9
  export let searchable = undefined;
10
+ export let filterable = searchable;
10
11
  export let filter = '';
11
12
  export let nodeClass = undefined;
12
13
  export let singleSelect = undefined;
@@ -27,6 +28,8 @@ export let dropEffect = undefined;
27
28
  export let store = new TreeStore(fetchChildren, { copyHandler, dragEligible, dropEffect, moveHandler });
28
29
  if (searchable)
29
30
  store.searchableFn = transformSearchable(searchable);
31
+ if (filterable)
32
+ store.filterableFn = transformSearchable(filterable);
30
33
  setContext(TREE_STORE_CONTEXT, store);
31
34
  const { filteredRootItems, headerOverride } = store;
32
35
  let checkboxelement;
@@ -80,41 +83,41 @@ function onKeyUp(e) {
80
83
  search = '';
81
84
  }
82
85
  }
83
- let dragheaderid;
84
- let dragheaderidx;
85
- let dragtarget;
86
+ let dragtargetid;
87
+ let rightoftargetid;
86
88
  let widthStart;
89
+ let width2Start;
87
90
  let mouseStart;
88
91
  function headerDragStart(header, idx) {
89
92
  return (e) => {
90
93
  if (!enableResize)
91
94
  return;
92
- dragtarget = headerelements[idx];
93
- if (!dragtarget.isConnected)
94
- dragtarget = undefined;
95
+ const dragtarget = headerelements[idx];
96
+ const rightoftarget = headerelements.find((e, i) => i > idx && e.isConnected);
97
+ if (!dragtarget?.isConnected || !rightoftarget)
98
+ dragtargetid = undefined;
95
99
  else {
96
100
  e.preventDefault();
97
- dragheaderid = header.id;
98
- dragheaderidx = idx;
101
+ dragtargetid = header.id;
102
+ rightoftargetid = rightoftarget.getAttribute('id') ?? undefined;
99
103
  widthStart = dragtarget.clientWidth;
100
- mouseStart = e instanceof TouchEvent ? e.touches[0].screenX : e.screenX;
104
+ width2Start = rightoftarget.clientWidth;
105
+ mouseStart = 'touches' in e ? e.touches[0].screenX : e.screenX;
101
106
  }
102
107
  };
103
108
  }
104
109
  function headerDrag(e) {
105
- if (e instanceof TouchEvent && e.touches.length > 1)
110
+ if ('touches' in e && e.touches?.length > 1)
106
111
  return;
107
- if (dragheaderid && dragheaderidx != null && dragtarget?.isConnected) {
108
- for (let i = 0; i < dragheaderidx; i++) {
109
- store.setHeaderOverride(headers[i].id, $headerSizes[i]);
110
- }
111
- const screenX = e instanceof TouchEvent ? e.touches[0].screenX : e.screenX;
112
- store.setHeaderOverride(dragheaderid, `${widthStart - (mouseStart - screenX)}px`);
112
+ if (dragtargetid && rightoftargetid) {
113
+ const screenX = 'touches' in e ? e.touches[0].screenX : e.screenX;
114
+ store.setHeaderOverride(dragtargetid, `${widthStart - (mouseStart - screenX)}px`);
115
+ store.setHeaderOverride(rightoftargetid, `${width2Start + (mouseStart - screenX)}px`);
113
116
  }
114
117
  }
115
118
  function headerDragEnd() {
116
- dragtarget = undefined;
117
- dragheaderid = undefined;
119
+ dragtargetid = undefined;
120
+ rightoftargetid = undefined;
118
121
  }
119
122
  function headerDragReset() {
120
123
  store.resetHeaderOverride();
@@ -152,16 +155,16 @@ $: myRootItems = $store?.rootItems?.filter(r => myRootItemIds.has(r.id)) ?? [];
152
155
 
153
156
  <svelte:window on:mouseup={headerDragEnd} />
154
157
 
155
- <div class="tree-header" class:resizing={!!dragheaderid} use:resize={{ store: treeWidth }} aria-hidden="true" on:mouseup={headerDragEnd} on:touchend={headerDragEnd} on:mousemove={dragheaderid ? headerDrag : undefined} on:touchmove={dragheaderid ? headerDrag : undefined}>
158
+ <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}>
156
159
  <div class="checkbox" bind:this={checkboxelement}>&nbsp;</div>
157
160
  {#each headers as header, i (header.label)}
158
161
  <div bind:this={headerelements[i]} id={header.id} class="tree-header-cell {header.id}" style:width={$headerOverride[header.id] ?? $headerSizes?.[i]} style:padding-left={i === 0 ? '1.4em' : undefined}>{header.label}{#if i === 0 && $store.loading}<LoadIcon />{/if}{#if i === 0 && isNotBlank(search)}&nbsp;(searching: {search}){/if}</div>
159
- {#if enableResize && i !== headers.length - 1}<div class="tree-separator" on:mousedown={headerDragStart(header, i)} on:touchstart={headerDragStart(header, i)} on:dblclick={headerDragReset}>&nbsp;</div>{/if}
162
+ {#if enableResize && i !== headers.length - 1}<div class="tree-separator {header.id}" on:mousedown={headerDragStart(header, i)} on:touchstart={headerDragStart(header, i)} on:dblclick={headerDragReset}>&nbsp;</div>{/if}
160
163
  {/each}
161
164
  </div>
162
165
  {#if mounted && myRootItems?.length}
163
166
  <!-- svelte-ignore a11y-no-noninteractive-element-to-interactive-role -->
164
- <ul bind:this={store.treeElement} role="tree" class:resizing={!!dragheaderid} on:mousemove={dragheaderid ? headerDrag : undefined} on:touchmove={dragheaderid ? headerDrag : undefined} on:mouseup={headerDragEnd} on:touchend={headerDragEnd} on:keyup={onKeyUp}>
167
+ <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}>
165
168
  {#each myRootItems as item, i (item.id)}
166
169
  <TreeNode
167
170
  {item}
@@ -5,6 +5,7 @@ declare class __sveltets_Render<T extends TreeItemFromDB> {
5
5
  props(): {
6
6
  headers: TreeHeader<T>[];
7
7
  searchable?: SearchableType<T>;
8
+ filterable?: SearchableType<T>;
8
9
  filter?: string | undefined;
9
10
  nodeClass?: ((itm: T) => string) | undefined;
10
11
  singleSelect?: boolean | undefined;
@@ -71,6 +71,7 @@ export declare class TreeStore<T extends TreeItemFromDB> extends ActiveStore<ITr
71
71
  dragEligibleHandler?: DragEligibleFn<T>;
72
72
  dropEffectHandler?: DropEffectFn<T>;
73
73
  searchableFn?: SearchableFn<T>;
74
+ filterableFn?: SearchableFn<T>;
74
75
  singleSelect?: boolean;
75
76
  private refreshPromise?;
76
77
  constructor(fetchChildren: FetchChildrenFn<T>, { moveHandler, copyHandler, dragEligible, dropEffect, searchableFn, singleSelect }?: {
@@ -8,15 +8,15 @@ export class TreeStore extends ActiveStore {
8
8
  rootItems = derivedStore(this, 'rootItems');
9
9
  filterTerm = new Store('');
10
10
  filteredRootItems = derived([this.rootItems, this.filterTerm], ([rootItems, filter]) => {
11
- if (!this.searchableFn || !rootItems?.length || isBlank(filter))
11
+ if (!this.filterableFn || !rootItems?.length || isBlank(filter))
12
12
  return new Set(this.value.rootItems?.map(r => r.id));
13
13
  const ret = new Set();
14
14
  const newselected = [];
15
15
  let foundfocus = false;
16
16
  for (const itm of this.value.rootItems ?? []) {
17
17
  let found = false;
18
- for (const val of this.searchableFn(itm)) {
19
- if (val.toLocaleLowerCase().startsWith(filter))
18
+ for (const val of this.filterableFn(itm)) {
19
+ if (val.toLocaleLowerCase().includes(filter))
20
20
  found = true;
21
21
  }
22
22
  if (found) {
@@ -44,6 +44,7 @@ export class TreeStore extends ActiveStore {
44
44
  dragEligibleHandler;
45
45
  dropEffectHandler;
46
46
  searchableFn;
47
+ filterableFn;
47
48
  singleSelect;
48
49
  refreshPromise;
49
50
  constructor(fetchChildren, { moveHandler, copyHandler, dragEligible, dropEffect, searchableFn, singleSelect } = {}) {
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": "0.0.80",
4
+ "version": "1.0.1",
5
5
  "scripts": {
6
6
  "prepublishOnly": "svelte-package",
7
7
  "dev": "vite dev --force",