@dosgato/dialog 0.0.47 → 0.0.49

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.
@@ -1,4 +1,4 @@
1
- <script>import { eq } from '@txstate-mws/svelte-components';
1
+ <script>import { eq, resize, ScreenReaderOnly } from '@txstate-mws/svelte-components';
2
2
  import { randomid } from 'txstate-utils';
3
3
  import { getContext } from 'svelte';
4
4
  import { DG_DIALOG_FIELD_MULTIPLE } from './FieldMultiple.svelte';
@@ -17,6 +17,14 @@ const dgMultipleContext = getContext(DG_DIALOG_FIELD_MULTIPLE);
17
17
  const helptextid = randomid();
18
18
  $: descids = getDescribedBy([helptext ? helptextid : undefined, dgMultipleContext?.helptextid]);
19
19
  let showhelp = false;
20
+ let helpelement;
21
+ let needsShowHelp = false;
22
+ function setNeedsShowHelp(..._) {
23
+ needsShowHelp = (helpelement?.getClientRects().length ?? 0) > 1;
24
+ if (!needsShowHelp)
25
+ showhelp = false;
26
+ }
27
+ $: setNeedsShowHelp(helpelement);
20
28
  </script>
21
29
 
22
30
  {#if conditional !== false}
@@ -29,7 +37,12 @@ let showhelp = false;
29
37
  <div class="dialog-field-content">
30
38
  {#if helptext}
31
39
  <!-- svelte-ignore a11y-click-events-have-key-events -->
32
- <div id={helptextid} class="dialog-field-help" class:expanded={showhelp} on:click={() => { showhelp = !showhelp }}>{helptext}</div>
40
+ <div use:resize={{ debounce: 10 }} on:resize={setNeedsShowHelp} id={helptextid} class="dialog-field-help" class:needsShowHelp class:expanded={showhelp} on:click={() => { if (needsShowHelp) showhelp = !showhelp }}>
41
+ <span bind:this={helpelement}>{helptext}</span>
42
+ {#if needsShowHelp}
43
+ <button type="button" class="dialog-field-help-expand">Show {#if showhelp}Less{:else}More{/if}<ScreenReaderOnly>, ignore this, the help text it controls will be read to you as input description</ScreenReaderOnly></button>
44
+ {/if}
45
+ </div>
33
46
  {/if}
34
47
  <slot {messagesid} helptextid={descids} />
35
48
  </div>
@@ -115,11 +128,33 @@ let showhelp = false;
115
128
  overflow: hidden;
116
129
  text-overflow: ellipsis;
117
130
  white-space: nowrap;
118
- cursor: help;
119
131
  }
120
132
  .dialog-field-help.expanded {
121
133
  white-space: normal;
122
134
  max-height: fit-content;
123
135
  }
136
+ .dialog-field-help.needsShowHelp {
137
+ padding-right: 6em;
138
+ cursor: help;
139
+ }
140
+ .dialog-field-help.expanded {
141
+ padding-right: 0;
142
+ }
143
+ .dialog-field-help:not(.expanded) .dialog-field-help-expand {
144
+ position: absolute;
145
+ top: 0;
146
+ right: 0.5em;
147
+ }
148
+ .dialog-field-help-expand {
149
+ background: none!important;
150
+ border: none;
151
+ padding: 0!important;
152
+ color: #069;
153
+ text-decoration: underline;
154
+ cursor: pointer;
155
+ }
156
+ .dialog-field-help-expand:hover {
157
+ text-decoration: none;
158
+ }
124
159
 
125
160
  </style>
@@ -91,28 +91,19 @@ onMount(async () => {
91
91
  <Tabs bind:store={tabStore} tabs={$sources.map(s => ({ name: s.name, title: s.label ?? s.name }))} />
92
92
  {/if}
93
93
  </header>
94
- <div class="dialog-chooser-body">
95
- <section class="dialog-chooser-chooser">
96
- {#if $store.initialized}
97
- <Tree headers={[
98
- { label: 'Path', id: 'name', grow: 4, icon: item => item.type === 'asset' ? iconForMime(item.mime) : (item.type === 'folder' ? (item.open ? folderNotchOpen : folderIcon) : applicationOutline), get: 'name' }
99
- ]} singleSelect store={treeStore} on:deselect={onDeselect} on:choose={onChoose} />
100
- {/if}
101
- </section>
102
- <section class="dialog-chooser-preview" tabindex="-1">
103
- {#if $preview}
104
- <Thumbnail item={$preview} larger />
105
- <Details item={$preview}>
106
- {#if $preview.type === 'folder'}
107
- <div class="folder-info">
108
- <dt>Contents:</dt>
109
- <dd>{$selected?.children?.length ?? 0} sub-items</dd>
110
- </div>
111
- {/if}
112
- </Details>
113
- {/if}
114
- </section>
115
- </div>
94
+ <section class="dialog-chooser-chooser">
95
+ {#if $store.initialized}
96
+ <Tree headers={[
97
+ { label: 'Path', id: 'name', grow: 4, icon: item => item.type === 'asset' ? iconForMime(item.mime) : (item.type === 'folder' ? (item.open ? folderNotchOpen : folderIcon) : applicationOutline), get: 'name' }
98
+ ]} singleSelect store={treeStore} on:deselect={onDeselect} on:choose={onChoose} />
99
+ {/if}
100
+ </section>
101
+ <section class="dialog-chooser-preview" tabindex="-1">
102
+ {#if $preview}
103
+ <Thumbnail item={$preview} larger />
104
+ <Details item={$preview} />
105
+ {/if}
106
+ </section>
116
107
  </section>
117
108
  </Dialog>
118
109
 
@@ -120,6 +111,7 @@ onMount(async () => {
120
111
  .dialog-chooser-window {
121
112
  position: relative;
122
113
  height: 80vh;
114
+ display: flex;
123
115
  flex-wrap: wrap;
124
116
  align-items: stretch;
125
117
  justify-content: flex-end;
@@ -128,10 +120,6 @@ onMount(async () => {
128
120
  .dialog-chooser-window * {
129
121
  box-sizing: border-box;
130
122
  }
131
-
132
- .dialog-chooser-body {
133
- display: flex;
134
- }
135
123
  .dialog-chooser-chooser {
136
124
  position: relative;
137
125
  width: 75%;
@@ -148,12 +136,6 @@ onMount(async () => {
148
136
  padding: 1em;
149
137
  overflow-y: auto;
150
138
  }
151
- .folder-info dt {
152
- font-weight: bold;
153
- }
154
- .folder-info dd {
155
- margin: 0;
156
- }
157
139
  header {
158
140
  position: relative;
159
141
  width: 100%;
@@ -18,7 +18,7 @@ export interface IAssetStore {
18
18
  activetype: ChooserType;
19
19
  activesource: number;
20
20
  initialized: boolean;
21
- preview?: AnyItem;
21
+ preview?: AnyUIItem;
22
22
  }
23
23
  export interface ChooserStoreOptions<F> {
24
24
  pages?: boolean;
@@ -44,11 +44,11 @@ export declare class ChooserStore<F = any> extends Store<IAssetStore> {
44
44
  setOptions(options: ChooserStoreOptions<F>): void;
45
45
  sources: import("@txstate-mws/svelte-store").DerivedStore<UISource[], IAssetStore>;
46
46
  source: import("@txstate-mws/svelte-store").DerivedStore<UISource | undefined, IAssetStore>;
47
- preview: import("@txstate-mws/svelte-store").DerivedStore<AnyItem | undefined, IAssetStore>;
47
+ preview: import("@txstate-mws/svelte-store").DerivedStore<AnyUIItem | undefined, IAssetStore>;
48
48
  getSource(state?: IAssetStore): UISource | undefined;
49
49
  getSourceIndex(name: string, state?: IAssetStore, type?: ChooserType): number;
50
50
  init(options: ChooserStoreOptions<F>): Promise<void>;
51
- setPreview(item?: AnyItem): void;
51
+ setPreview(item?: AnyUIItem): void;
52
52
  clearPreview(): void;
53
53
  setSource(name?: string, init?: boolean): void;
54
54
  }
@@ -24,7 +24,7 @@ export class ChooserStore extends Store {
24
24
  setOptions(options) {
25
25
  const userFilter = options.filter ?? nofilter;
26
26
  const filter = options.images
27
- ? (itm) => ((itm.type === 'asset' && !!itm.image) || itm.type === 'folder') && userFilter(itm)
27
+ ? async (itm) => ((itm.type === 'asset' && !!itm.image) || itm.type === 'folder') && await userFilter(itm)
28
28
  : userFilter;
29
29
  this.options = {
30
30
  ...options,
@@ -58,8 +58,10 @@ export class ChooserStore extends Store {
58
58
  this.update(v => ({ ...v, initialized: true }));
59
59
  }
60
60
  setPreview(item) {
61
- if (!item)
62
- return this.clearPreview();
61
+ if (!item) {
62
+ this.clearPreview();
63
+ return;
64
+ }
63
65
  if (item.type === 'folder' && !this.options.folders)
64
66
  return;
65
67
  this.update(v => ({ ...v, preview: item }));
@@ -15,7 +15,7 @@ export let item;
15
15
  </div>
16
16
  {/if}
17
17
  {#if item.type === 'asset'}
18
- <div class="asset-properties">
18
+ <div class="horizontal-group">
19
19
  {#if item.image}
20
20
  <div>
21
21
  <dt>Dimensions:</dt>
@@ -32,14 +32,18 @@ export let item;
32
32
  </div>
33
33
  </div>
34
34
  {:else if item.type === 'page' && item.title}
35
- <div>
36
- <dt>Title:</dt>
37
- <dd>{item.title}</dd>
38
- </div>
35
+ <dt>Title:</dt>
36
+ <dd>{item.title}</dd>
39
37
  {:else if item.type === 'folder'}
40
- <div>
41
- <dt>Path:</dt>
42
- <dd>{item.path}</dd>
38
+ <div class="horizontal-group">
39
+ <div>
40
+ <dt>Path:</dt>
41
+ <dd>{item.path}</dd>
42
+ </div>
43
+ <div>
44
+ <dt>Contents:</dt>
45
+ <dd>{item.children?.length ?? 0} sub-items</dd>
46
+ </div>
43
47
  </div>
44
48
  {/if}
45
49
  <slot />
@@ -60,14 +64,14 @@ export let item;
60
64
  .top-row {
61
65
  margin-bottom: 1em;
62
66
  }
63
- .asset-properties {
67
+ .horizontal-group {
64
68
  display: flex;
65
69
  justify-content: space-between;
66
70
  }
67
- :global([data-eq~="1400px"]) .asset-properties {
71
+ :global([data-eq~="1400px"]) .horizontal-group {
68
72
  flex-direction: column;
69
73
  }
70
- :global([data-eq~="1400px"]) .asset-properties div:not(:last-child){
74
+ :global([data-eq~="1400px"]) .horizontal-group div:not(:last-child){
71
75
  margin-bottom: 1em;
72
76
  }
73
77
 
@@ -1,9 +1,8 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
- import type { AnyItem } from './ChooserAPI';
3
- import { type RawURL } from './ChooserStore';
2
+ import { type AnyUIItem, type RawURL } from './ChooserStore';
4
3
  declare const __propDef: {
5
4
  props: {
6
- item: AnyItem | RawURL;
5
+ item: AnyUIItem | RawURL;
7
6
  };
8
7
  events: {
9
8
  [evt: string]: CustomEvent<any>;
@@ -95,17 +95,12 @@ function headerDragReset() {
95
95
  let mounted = false;
96
96
  onMount(async () => {
97
97
  document.addEventListener('dragend', onDragEnd);
98
- const saveFocusId = $store.focused?.id;
99
98
  headerSizes.set(calcHeaderSizes()); // seems to need a kick on first mount
100
99
  await new Promise(resolve => requestAnimationFrame(resolve));
101
100
  // need to wait long enough for headers to redraw before trying to mount the rows
102
101
  await new Promise(resolve => requestAnimationFrame(resolve));
103
102
  mounted = true;
104
103
  await store.refresh();
105
- if ($store.focused?.id && $store.focused.id === saveFocusId) {
106
- const el = document.getElementById(getHashId($store.focused.id));
107
- el?.scrollIntoView({ block: 'center' });
108
- }
109
104
  });
110
105
  onDestroy(() => {
111
106
  if (typeof document !== 'undefined')
@@ -3,7 +3,7 @@ import checkboxBlankOutline from '@iconify-icons/mdi/checkbox-blank-outline';
3
3
  import menuDown from '@iconify-icons/mdi/menu-down';
4
4
  import menuRight from '@iconify-icons/mdi/menu-right';
5
5
  import { modifierKey, ScreenReaderOnly } from '@txstate-mws/svelte-components';
6
- import { createEventDispatcher, getContext } from 'svelte';
6
+ import { createEventDispatcher, getContext, onMount } from 'svelte';
7
7
  import { isNotBlank, toArray } from 'txstate-utils';
8
8
  import { Icon } from '..';
9
9
  import { TREE_STORE_CONTEXT, getHashId } from './treestore';
@@ -243,6 +243,10 @@ function onDragLeaveAbove(e) {
243
243
  else
244
244
  dragOverAbove--;
245
245
  }
246
+ onMount(() => {
247
+ if ($focused && $focused.id === item.id)
248
+ nodeelement.scrollIntoView({ block: 'center' });
249
+ });
246
250
  $: if ($dragging) {
247
251
  dragOver = 0;
248
252
  dragOverAbove = 0;
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.47",
4
+ "version": "0.0.49",
5
5
  "scripts": {
6
6
  "prepublishOnly": "svelte-package",
7
7
  "dev": "vite dev --force",