@dosgato/dialog 1.1.6 → 1.1.8
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/Button.svelte +1 -1
- package/dist/FieldChooserLink.svelte +1 -1
- package/dist/Icon.svelte +42 -2
- package/dist/InlineMessage.svelte +30 -1
- package/dist/chooser/Chooser.svelte +11 -1
- package/dist/chooser/ChooserAPI.d.ts +5 -0
- package/dist/cropper/FieldCropper.svelte +10 -1
- package/package.json +2 -2
package/dist/Button.svelte
CHANGED
|
@@ -12,7 +12,7 @@ let className = undefined;
|
|
|
12
12
|
export { className as class };
|
|
13
13
|
</script>
|
|
14
14
|
|
|
15
|
-
<button {disabled} bind:this={element} {type} class="reset {className ?? ''}" class:cancel class:destructive class:secondary class:compact aria-describedby={describedby} on:click><Icon {icon} width="1.3em" /><span><slot /></span></button>
|
|
15
|
+
<button {disabled} bind:this={element} {type} class="reset {className ?? ''}" class:cancel class:destructive class:secondary class:compact aria-describedby={describedby} on:click><Icon {icon} width="1.3em" inline /><span><slot /></span></button>
|
|
16
16
|
|
|
17
17
|
<style>
|
|
18
18
|
button.reset {
|
|
@@ -170,7 +170,7 @@ $: void updateSelected($value);
|
|
|
170
170
|
<Details item={selectedAsset} singleLine />
|
|
171
171
|
{#if !urlEntry}
|
|
172
172
|
<button type="button" on:click={show} aria-describedby={getDescribedBy([descid, messagesid, helptextid, extradescid])}>
|
|
173
|
-
<Icon icon={arrowClockwiseFill} /> Replace
|
|
173
|
+
<Icon icon={arrowClockwiseFill} inline /> Replace
|
|
174
174
|
</button>
|
|
175
175
|
<button type="button" on:click={() => { selectedAsset = undefined; setVal(undefined) }} aria-describedby={getDescribedBy([descid, messagesid, helptextid, extradescid])}>
|
|
176
176
|
<Icon icon={deleteOutline} inline /> Remove
|
package/dist/Icon.svelte
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
implementation of icons that adds a hidden label that can be read by screen readers. Useful for situations where aria-label
|
|
4
4
|
isn't supported, to provide in kind icon support, while still making use of aria attributes regardless of support.
|
|
5
5
|
-->
|
|
6
|
-
<script>import
|
|
6
|
+
<script>import { randomid } from 'txstate-utils';
|
|
7
7
|
import Tooltip from './Tooltip.svelte';
|
|
8
8
|
export let icon;
|
|
9
9
|
/** Label used in a `<ScreenReaderOnly>`. */
|
|
@@ -12,13 +12,53 @@ export let inline = false;
|
|
|
12
12
|
export let width = undefined;
|
|
13
13
|
export let height = undefined;
|
|
14
14
|
export let tooltip = undefined;
|
|
15
|
+
function replaceIDs(body) {
|
|
16
|
+
const matches = body.matchAll(/\sid="(\S+)"/g);
|
|
17
|
+
const ids = Array.from(matches).map(m => m[1]);
|
|
18
|
+
if (!ids.length)
|
|
19
|
+
return body;
|
|
20
|
+
// Replace with unique ids
|
|
21
|
+
ids.forEach((id) => {
|
|
22
|
+
const escapedID = id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
23
|
+
body = body.replace(
|
|
24
|
+
// Allowed characters before id: [#;"]
|
|
25
|
+
// Allowed characters after id: [)"], .[a-z]
|
|
26
|
+
new RegExp('([#;"])(' + escapedID + ')([")]|\\.[a-z])', 'g'), '$1' + randomid() + '$3');
|
|
27
|
+
});
|
|
28
|
+
return body;
|
|
29
|
+
}
|
|
30
|
+
const fixedSVG = new Map();
|
|
31
|
+
function svgBody(icon) {
|
|
32
|
+
if (!fixedSVG.has(icon))
|
|
33
|
+
fixedSVG.set(icon, replaceIDs(icon.body));
|
|
34
|
+
return fixedSVG.get(icon);
|
|
35
|
+
}
|
|
15
36
|
// If neither is defined, set both to 1em
|
|
16
37
|
if (!width && !height)
|
|
17
38
|
width = height = '1em';
|
|
39
|
+
height ??= width;
|
|
18
40
|
</script>
|
|
19
41
|
|
|
20
42
|
{#if icon}
|
|
21
43
|
<Tooltip tip={tooltip} top>
|
|
22
|
-
<
|
|
44
|
+
<svg role="img" viewBox="{icon.left ?? 0} {icon.top ?? 0} {icon.width ?? 256} {icon.height ?? 256}" class:vFlip={icon.vFlip} class:hFlip={icon.hFlip} class:inline {width} {height} aria-hidden={!hiddenLabel} aria-label={hiddenLabel} xmlns="http://www.w3.org/2000/svg">
|
|
45
|
+
{@html svgBody(icon)}
|
|
46
|
+
</svg>
|
|
23
47
|
</Tooltip>
|
|
24
48
|
{/if}
|
|
49
|
+
|
|
50
|
+
<style>
|
|
51
|
+
svg.inline {
|
|
52
|
+
vertical-align: -0.125em;
|
|
53
|
+
}
|
|
54
|
+
svg.vFlip {
|
|
55
|
+
transform: scale(1, -1);
|
|
56
|
+
}
|
|
57
|
+
svg.hFlip {
|
|
58
|
+
transform: scale(-1, 1);
|
|
59
|
+
}
|
|
60
|
+
svg.hFlip.vFlip {
|
|
61
|
+
transform: scale(-1, -1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
</style>
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import checkCircleOutline from '@iconify-icons/mdi/check-circle-outline.js';
|
|
6
6
|
import informationOutline from '@iconify-icons/mdi/information-outline.js';
|
|
7
7
|
import closeOctagonOutline from '@iconify-icons/mdi/close-octagon-outline.js';
|
|
8
|
+
import { htmlEncode } from 'txstate-utils';
|
|
8
9
|
import Icon from './Icon.svelte';
|
|
9
10
|
export let message;
|
|
10
11
|
const icons = {
|
|
@@ -24,9 +25,34 @@ const ariaLables = {
|
|
|
24
25
|
}
|
|
25
26
|
$: hiddenLabel = ariaLables[message.type] ?? 'Error'
|
|
26
27
|
*/
|
|
28
|
+
function addMarkup(msg) {
|
|
29
|
+
const lines = msg.split(/\r?\n/);
|
|
30
|
+
const output = [];
|
|
31
|
+
for (const line of lines) {
|
|
32
|
+
const splitLinks = line.split(/((?:\[[^\]]+\])?\([^)]+\))/);
|
|
33
|
+
const replaced = [];
|
|
34
|
+
for (const segment of splitLinks) {
|
|
35
|
+
const m = segment.match(/(?:\[([^\]]+)\])?\(([^)]+)\)/);
|
|
36
|
+
if (m) {
|
|
37
|
+
try {
|
|
38
|
+
const url = new URL(m[2]);
|
|
39
|
+
replaced.push('<a href="' + htmlEncode(url.toString()) + '" target="_blank">' + htmlEncode(m[1] || m[2]) + '</a>');
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
replaced.push(htmlEncode(m[0]));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
replaced.push(htmlEncode(segment));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
output.push(replaced.join(''));
|
|
50
|
+
}
|
|
51
|
+
return output.join('<br>');
|
|
52
|
+
}
|
|
27
53
|
</script>
|
|
28
54
|
|
|
29
|
-
<div class={message.type}><Icon width='1.5em' {icon} hiddenLabel='Error' /><span>{message.message}</span></div>
|
|
55
|
+
<div class={message.type}><Icon width='1.5em' {icon} inline hiddenLabel='Error' /><span>{@html addMarkup(message.message)}</span></div>
|
|
30
56
|
|
|
31
57
|
<style>
|
|
32
58
|
div {
|
|
@@ -52,5 +78,8 @@ $: hiddenLabel = ariaLables[message.type] ?? 'Error'
|
|
|
52
78
|
background-color: #218739;
|
|
53
79
|
color: white;
|
|
54
80
|
}
|
|
81
|
+
div :global(a) {
|
|
82
|
+
color: inherit;
|
|
83
|
+
}
|
|
55
84
|
|
|
56
85
|
</style>
|
|
@@ -84,6 +84,16 @@ onMount(async () => {
|
|
|
84
84
|
});
|
|
85
85
|
const previewId = randomid();
|
|
86
86
|
let thumbnailExpanded = false;
|
|
87
|
+
function iconForItem(item) {
|
|
88
|
+
if (item.icon) {
|
|
89
|
+
return item.icon;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
return {
|
|
93
|
+
icon: item.type === 'asset' ? iconForMime(item.mime) : (item.type === 'folder' ? (item.open ? folderNotchOpen : folderIcon) : browserIcon)
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
87
97
|
</script>
|
|
88
98
|
|
|
89
99
|
<Dialog size="xl" ignoreTabs title={label} on:escape continueText="Choose" disabled={!$preview && required} cancelText="Cancel">
|
|
@@ -96,7 +106,7 @@ let thumbnailExpanded = false;
|
|
|
96
106
|
<section class="dialog-chooser-chooser">
|
|
97
107
|
{#if $store.initialized}
|
|
98
108
|
<Tree headers={[
|
|
99
|
-
{ label: 'Path', id: 'name', grow: 4, icon: item => (
|
|
109
|
+
{ label: 'Path', id: 'name', grow: 4, icon: item => iconForItem(item), get: 'name' }
|
|
100
110
|
]} singleSelect store={treeStore} on:deselect={onDeselect} on:choose={onChoose} />
|
|
101
111
|
{/if}
|
|
102
112
|
</section>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IconifyIcon } from '@iconify/svelte';
|
|
1
2
|
export declare const CHOOSER_API_CONTEXT: {};
|
|
2
3
|
export type ChooserType = 'asset' | 'page';
|
|
3
4
|
export type AnyItem = Asset | Folder | Page;
|
|
@@ -76,6 +77,10 @@ interface Item {
|
|
|
76
77
|
* user's interaction.
|
|
77
78
|
*/
|
|
78
79
|
url: string;
|
|
80
|
+
icon?: {
|
|
81
|
+
icon: IconifyIcon;
|
|
82
|
+
label?: string;
|
|
83
|
+
};
|
|
79
84
|
}
|
|
80
85
|
export interface Folder extends Item {
|
|
81
86
|
type: 'folder';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script>import { resize, ScreenReaderOnly } from '@txstate-mws/svelte-components';
|
|
2
|
+
import { onMount } from 'svelte';
|
|
2
3
|
import { isNotBlank, randomid } from 'txstate-utils';
|
|
3
4
|
import FieldStandard from '../FieldStandard.svelte';
|
|
4
5
|
import { CropperStore } from './cropper';
|
|
@@ -20,7 +21,11 @@ function init(spValue, spSetVal) {
|
|
|
20
21
|
value = spValue;
|
|
21
22
|
}
|
|
22
23
|
$: store.setOutput(value);
|
|
23
|
-
|
|
24
|
+
function reactToOutput(...args) {
|
|
25
|
+
if (mounted)
|
|
26
|
+
setVal?.($output);
|
|
27
|
+
}
|
|
28
|
+
$: reactToOutput($output);
|
|
24
29
|
let rect;
|
|
25
30
|
function updateRect(..._) {
|
|
26
31
|
if (!container)
|
|
@@ -101,6 +106,10 @@ function onKeyDown(type) {
|
|
|
101
106
|
}
|
|
102
107
|
};
|
|
103
108
|
}
|
|
109
|
+
let mounted = false;
|
|
110
|
+
onMount(() => {
|
|
111
|
+
mounted = true;
|
|
112
|
+
});
|
|
104
113
|
$: updateRect(container);
|
|
105
114
|
const descid = randomid();
|
|
106
115
|
const movedescid = randomid();
|
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.1.
|
|
4
|
+
"version": "1.1.8",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"prepublishOnly": "svelte-package",
|
|
7
7
|
"dev": "vite dev --force",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@codemirror/lang-javascript": "^6.1.7",
|
|
24
24
|
"@codemirror/lang-css": "^6.2.1",
|
|
25
25
|
"@codemirror/lang-html": "^6.4.3",
|
|
26
|
-
"@iconify/svelte": "^3.
|
|
26
|
+
"@iconify/svelte": "^3.1.6",
|
|
27
27
|
"@iconify-icons/mdi": "^1.2.22",
|
|
28
28
|
"@iconify-icons/ph": "^1.2.2",
|
|
29
29
|
"@txstate-mws/svelte-components": "^1.5.5",
|