@dosgato/dialog 0.0.29 → 0.0.31

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,6 +1,6 @@
1
- <script>import { FORM_CONTEXT } from '@txstate-mws/svelte-forms';
1
+ <script>import { FORM_CONTEXT, FORM_INHERITED_PATH } from '@txstate-mws/svelte-forms';
2
2
  import { getContext } from 'svelte';
3
- import { randomid } from 'txstate-utils';
3
+ import { isNotBlank, randomid } from 'txstate-utils';
4
4
  import { Chooser, ChooserStore, CHOOSER_API_CONTEXT } from './chooser';
5
5
  import Details from './chooser/Details.svelte';
6
6
  import Thumbnail from './chooser/Thumbnail.svelte';
@@ -20,8 +20,12 @@ export let urlEntry = false;
20
20
  export let initialSource = undefined;
21
21
  export let initialPath = undefined;
22
22
  export let helptext = undefined;
23
+ // TODO: add a mime type acceptance prop, maybe a regex or function, to prevent users from
24
+ // choosing unacceptable mime types
23
25
  const formStore = getContext(FORM_CONTEXT);
24
- const value = formStore.getField(path);
26
+ const inheritedPath = getContext(FORM_INHERITED_PATH);
27
+ const finalPath = [inheritedPath, path].filter(isNotBlank).join('.');
28
+ const value = formStore.getField(finalPath);
25
29
  const chooserClient = getContext(CHOOSER_API_CONTEXT);
26
30
  const store = new ChooserStore(chooserClient);
27
31
  const descid = randomid();
@@ -43,19 +47,48 @@ function onChange(setVal) {
43
47
  }
44
48
  async function userUrlEntry() {
45
49
  const url = this.value;
50
+ store.clearPreview();
51
+ let found = false;
46
52
  if (chooserClient.findByUrl) {
47
53
  const item = await chooserClient.findByUrl(url);
48
- if (item)
49
- return store.setPreview(item);
54
+ if (item) {
55
+ found = true;
56
+ if ((item.type === 'page' && !pages) || // they typed the URL for a page but we don't allow pages right now
57
+ (item.type === 'folder' && !folders) || // they typed the URL for an asset folder but not allowed
58
+ (item.type === 'asset' && !assets) || // they typed the URL for an asset but not allowed
59
+ (item.type === 'asset' && !item.image && images) // they typed the URL for a non-image asset but we only want images
60
+ ) {
61
+ selectedAsset = {
62
+ type: 'raw',
63
+ id: undefined,
64
+ url
65
+ };
66
+ }
67
+ else {
68
+ selectedAsset = { ...item, url };
69
+ }
70
+ }
50
71
  }
51
- store.clearPreview();
52
- const newVal = chooserClient.urlToValue?.(url) ?? url;
53
- selectedAsset = {
54
- type: 'raw',
55
- id: newVal,
56
- url
57
- };
58
- formStore.setField(path, newVal);
72
+ if (!found) {
73
+ try {
74
+ const _ = new URL(url);
75
+ const newVal = chooserClient.urlToValue?.(url) ?? url;
76
+ selectedAsset = {
77
+ type: 'raw',
78
+ id: newVal,
79
+ url
80
+ };
81
+ }
82
+ catch (e) {
83
+ selectedAsset = {
84
+ type: 'raw',
85
+ id: undefined,
86
+ url
87
+ };
88
+ }
89
+ }
90
+ formStore.setField(finalPath, selectedAsset?.id);
91
+ formStore.dirtyField(finalPath);
59
92
  }
60
93
  let selectedAsset;
61
94
  async function updateSelected(..._) {
@@ -73,8 +106,8 @@ $: updateSelected($value);
73
106
  </div>
74
107
  {/if}
75
108
  <div class="dialog-chooser-entry">
76
- {#if urlEntry && !folders && selectedAsset?.type !== 'folder'}
77
- <input type="text" value={selectedAsset?.url ?? ''} on:change={userUrlEntry}>
109
+ {#if urlEntry}
110
+ <input type="text" value={selectedAsset?.url ?? ''} on:change={userUrlEntry} on:keyup={userUrlEntry}>
78
111
  {/if}
79
112
  <button type="button" on:click={show} aria-describedby={getDescribedBy([descid, messagesid, helptextid])}>Select {#if value}New{/if} {#if assets && pages}Link Target{:else if images}Image{:else if assets}Asset{:else}Page{/if}</button>
80
113
  </div>
@@ -1,7 +1,8 @@
1
1
  <script>import { passActions } from '@txstate-mws/svelte-components';
2
- import { nullableSerialize, nullableDeserialize, FORM_CONTEXT, FormStore } from '@txstate-mws/svelte-forms';
2
+ import { nullableSerialize, nullableDeserialize, FORM_CONTEXT, FormStore, FORM_INHERITED_PATH } from '@txstate-mws/svelte-forms';
3
3
  import CodeFlask from 'codeflask';
4
4
  import { getContext, onMount } from 'svelte';
5
+ import { isNotBlank } from 'txstate-utils';
5
6
  import { getDescribedBy, FieldStandard } from './';
6
7
  let className = '';
7
8
  export { className as class };
@@ -10,7 +11,7 @@ export let path;
10
11
  export let label = '';
11
12
  export let notNull = false;
12
13
  export let defaultValue = notNull ? '' : undefined;
13
- export let rows = undefined;
14
+ export let rows = 8;
14
15
  export let conditional = undefined;
15
16
  export let required = false;
16
17
  export let use = [];
@@ -18,13 +19,13 @@ export let inputelement = undefined;
18
19
  export let helptext = undefined;
19
20
  export let language;
20
21
  const store = getContext(FORM_CONTEXT);
21
- const value = store.getField(path);
22
+ const inheritedPath = getContext(FORM_INHERITED_PATH);
23
+ const finalPath = [inheritedPath, path].filter(isNotBlank).join('.');
24
+ const value = store.getField(finalPath);
22
25
  let editorelement;
23
26
  let flask;
24
- let codeValue = '';
25
27
  onMount(() => {
26
28
  flask = new CodeFlask(editorelement, { language, lineNumbers: true, areaId: id });
27
- flask.onUpdate(code => { codeValue = code; });
28
29
  inputelement = editorelement.querySelector(`#${id}`);
29
30
  if (className)
30
31
  inputelement.classList.add(...className.split(' '));
@@ -60,6 +61,7 @@ function updateValidState(invalidIn, messagesIdIn) {
60
61
 
61
62
  <style>
62
63
  div {
64
+ position: relative;
63
65
  overflow: hidden;
64
66
  resize: vertical;
65
67
  }
@@ -8,7 +8,7 @@ declare const __propDef: {
8
8
  label?: string;
9
9
  notNull?: boolean;
10
10
  defaultValue?: any;
11
- rows?: number | undefined;
11
+ rows?: number;
12
12
  conditional?: boolean | undefined;
13
13
  required?: boolean;
14
14
  use?: HTMLActionEntry[];
@@ -10,7 +10,7 @@ declare const __propDef: {
10
10
  disabled?: boolean;
11
11
  choices: {
12
12
  label?: string;
13
- value: string;
13
+ value: any;
14
14
  disabled?: boolean;
15
15
  }[];
16
16
  defaultValue?: any;
@@ -30,11 +30,28 @@ interface Item {
30
30
  path: string;
31
31
  name: string;
32
32
  source: string;
33
+ /**
34
+ * Identifier for the urlEntry input
35
+ *
36
+ * When urlEntry prop is true, the user gets a text field where they can freely
37
+ * enter a string to identify the object being chosen. This value will be
38
+ * placed in that field when they use the chooser.
39
+ *
40
+ * It should be reversible with the `findByUrl` function provided by your chooser
41
+ * client, but note that the `findByUrl` function can accept multiple URLs that
42
+ * all point to the same resource. If the user types anything that can identify
43
+ * a resource, the resource will show up in the "Details" area, but the URL the user
44
+ * typed will NOT change to the one provided by this property. We try not
45
+ * to rewrite values in the form fields where possible, because it can disrupt the
46
+ * user's interaction.
47
+ */
48
+ url: string;
33
49
  }
34
50
  export interface Folder extends Item {
35
51
  type: 'folder';
36
52
  hasChildren: boolean;
37
53
  acceptsUpload: boolean;
54
+ url: string;
38
55
  }
39
56
  export interface Page extends Item {
40
57
  type: 'page';
@@ -4,11 +4,13 @@ export let item;
4
4
 
5
5
  <ul class="dialog-chooser-info" aria-live="polite">
6
6
  {#if item.type !== 'raw'}
7
- <li>{item.name}</li>
7
+ <li>{item.path}</li>
8
+ {:else if item.id}
9
+ <li>External Link<br>{item.url}</li>
8
10
  {/if}
9
11
  {#if item.type === 'asset' && item.image}
10
12
  <li>{item.image.width}x{item.image.height}</li>
11
- {:else if item.type === 'page'}
13
+ {:else if item.type === 'page' && item.title}
12
14
  <li>{item.title}</li>
13
15
  {:else if item.type === 'folder'}
14
16
  <li>{item.path}</li>
@@ -14,7 +14,7 @@ export let item;
14
14
  {/if}
15
15
  {:else if item.type === 'folder'}
16
16
  <Icon icon={folderOutline} width='5em' />
17
- {:else}
17
+ {:else if item.id}
18
18
  <Icon icon={fileLinkOutline} width='5em' />
19
19
  {/if}
20
20
  </div>
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.29",
4
+ "version": "0.0.31",
5
5
  "dependencies": {
6
6
  "@txstate-mws/svelte-components": "^1.3.5",
7
7
  "@txstate-mws/svelte-forms": "^1.2.1",