@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/Container.svelte
CHANGED
|
@@ -47,6 +47,7 @@ $: setNeedsShowHelp(helpelement);
|
|
|
47
47
|
<div class="dialog-field-content">
|
|
48
48
|
{#if helptext}
|
|
49
49
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
50
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
50
51
|
<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 }}>
|
|
51
52
|
<span bind:this={helpelement}>{@html helptext}</span>
|
|
52
53
|
{#if needsShowHelp}
|
|
@@ -69,6 +70,7 @@ $: setNeedsShowHelp(helpelement);
|
|
|
69
70
|
.dialog-field-container[data-related~="1"] {
|
|
70
71
|
padding-top: 0;
|
|
71
72
|
padding-left: calc(var(--dialog-container-padding, 1em) + var(--dialog-related-padding, 1em));
|
|
73
|
+
margin-top: -0.5em;
|
|
72
74
|
}
|
|
73
75
|
.dialog-field-container[data-related~="2"] {
|
|
74
76
|
padding-left: calc(var(--dialog-container-padding, 1em) + (2 * var(--dialog-related-padding, 1em)));
|
package/dist/Dialog.svelte
CHANGED
package/dist/FieldChoices.svelte
CHANGED
|
@@ -69,7 +69,7 @@ onMount(reactToChoices);
|
|
|
69
69
|
<div class="dialog-choices {className}" class:valid class:invalid>
|
|
70
70
|
{#each choices as choice, idx (choice.value)}
|
|
71
71
|
{@const checkid = `${path}.${idx}`}
|
|
72
|
-
{@const included = value
|
|
72
|
+
{@const included = value?.includes(choice.value)}
|
|
73
73
|
{@const label = choice.label || (typeof choice.value === 'string' ? choice.value : '')}
|
|
74
74
|
<label for={checkid} style:width style:order={orders[idx]}>
|
|
75
75
|
<Checkbox id={checkid} name={checkid} value={included} descid={getDescribedBy([descid, messagesid, helptextid, extradescid])} disabled={choice.disabled} onChange={() => onChangeCheckbox(setVal, choice, included)} {onBlur} />
|
|
@@ -66,7 +66,7 @@ async function userUrlEntryDebounced() {
|
|
|
66
66
|
store.clearPreview();
|
|
67
67
|
if (isBlank(url)) {
|
|
68
68
|
selectedAsset = undefined;
|
|
69
|
-
formStore.setField(finalPath, undefined);
|
|
69
|
+
void formStore.setField(finalPath, undefined);
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
72
|
let found = false;
|
|
@@ -117,7 +117,7 @@ async function userUrlEntryDebounced() {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
formStore.setField(finalPath, selectedAsset?.id);
|
|
120
|
+
void formStore.setField(finalPath, selectedAsset?.id);
|
|
121
121
|
formStore.dirtyField(finalPath);
|
|
122
122
|
}
|
|
123
123
|
const urlToValueCache = {};
|
|
@@ -159,7 +159,7 @@ async function updateSelected(..._) {
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
|
-
$: updateSelected($value);
|
|
162
|
+
$: void updateSelected($value);
|
|
163
163
|
</script>
|
|
164
164
|
|
|
165
165
|
<FieldStandard bind:id {path} {descid} {label} {defaultValue} {conditional} {required} {related} {helptext} let:value let:messagesid let:helptextid let:valid let:invalid let:id let:onBlur let:setVal>
|
|
@@ -243,6 +243,11 @@ $: updateSelected($value);
|
|
|
243
243
|
align-items: flex-start;
|
|
244
244
|
margin-top: 0.2em;
|
|
245
245
|
}
|
|
246
|
+
.dialog-chooser-entry > button {
|
|
247
|
+
border-radius: 0.25em;
|
|
248
|
+
border: 1px solid #808080;
|
|
249
|
+
color: black;
|
|
250
|
+
}
|
|
246
251
|
.dialog-chooser-entry-input {
|
|
247
252
|
position: relative;
|
|
248
253
|
flex-grow: 1;
|
|
@@ -261,6 +266,7 @@ $: updateSelected($value);
|
|
|
261
266
|
transform: translateY(-50%);
|
|
262
267
|
cursor: pointer;
|
|
263
268
|
line-height: 1;
|
|
269
|
+
color: black;
|
|
264
270
|
}
|
|
265
271
|
:global([data-eq~="400px"] .dialog-chooser-container .dialog-chooser-thumbnail img) {
|
|
266
272
|
object-position: left;
|
|
@@ -15,8 +15,24 @@ export let required = false;
|
|
|
15
15
|
export let related = 0;
|
|
16
16
|
export let extradescid = undefined;
|
|
17
17
|
export let helptext = undefined;
|
|
18
|
+
export let inputelement = undefined;
|
|
19
|
+
let showBadInputMessage = false;
|
|
20
|
+
function wrapOnBlur(onBlur) {
|
|
21
|
+
const date = new Date(inputelement.value);
|
|
22
|
+
showBadInputMessage = inputelement.validity.badInput || !(date instanceof Date && !isNaN(date.valueOf()));
|
|
23
|
+
onBlur();
|
|
24
|
+
}
|
|
18
25
|
</script>
|
|
19
26
|
|
|
20
27
|
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext} serialize={datetimeSerialize} deserialize={datetimeDeserialize} let:value let:valid let:invalid let:id let:onBlur let:onChange let:helptextid let:messagesid>
|
|
21
|
-
|
|
28
|
+
{#if showBadInputMessage}<div class="bad-input-warning" aria-live='polite'>{`Field ${label}`} must include both a date and time</div>{/if}
|
|
29
|
+
<Input bind:inputelement={inputelement} type="datetime-local" name={path} {value} {id} class="dialog-input {className}" onBlur={() => { wrapOnBlur(onBlur) }} {onChange} {valid} {invalid} {min} {max} {step} {extradescid} {messagesid} {helptextid}/>
|
|
22
30
|
</FieldStandard>
|
|
31
|
+
|
|
32
|
+
<style>
|
|
33
|
+
.bad-input-warning {
|
|
34
|
+
margin-bottom: 0.3em;
|
|
35
|
+
color: var(--dg-danger-bg, #9a3332);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
</style>
|
|
@@ -62,7 +62,7 @@ function valueToSelectedChoices(value) {
|
|
|
62
62
|
return ret;
|
|
63
63
|
}
|
|
64
64
|
function getAvailable(value) {
|
|
65
|
-
return choices.filter(choice => value.
|
|
65
|
+
return choices.filter(choice => !value.includes(choice.value));
|
|
66
66
|
}
|
|
67
67
|
function onkeydown(value, setVal) {
|
|
68
68
|
return (e) => {
|
|
@@ -85,6 +85,7 @@ function onkeydown(value, setVal) {
|
|
|
85
85
|
</script>
|
|
86
86
|
|
|
87
87
|
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {descid} {related} {helptext} let:value let:valid let:invalid let:id let:onBlur let:setVal let:helptextid let:messagesid serialize={arraySerialize}>
|
|
88
|
+
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
|
88
89
|
<div {id} role="group" class="dual-list-container" on:keydown={onkeydown(value, setVal)}>
|
|
89
90
|
<ScreenReaderOnly>
|
|
90
91
|
<span aria-live="polite">{instructions}</span>
|
package/dist/FieldHidden.svelte
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script>import { Field, nullableSerialize, nullableDeserialize,
|
|
1
|
+
<script>import { Field, nullableSerialize, nullableDeserialize, FORM_CONTEXT, FORM_INHERITED_PATH } from '@txstate-mws/svelte-forms';
|
|
2
2
|
import { getContext } from 'svelte';
|
|
3
3
|
import { isNotBlank } from 'txstate-utils';
|
|
4
4
|
export let id = undefined;
|
|
@@ -11,7 +11,7 @@ export let conditional = undefined;
|
|
|
11
11
|
const store = getContext(FORM_CONTEXT);
|
|
12
12
|
const inheritedPath = getContext(FORM_INHERITED_PATH);
|
|
13
13
|
const finalPath = [inheritedPath, path].filter(isNotBlank).join('.');
|
|
14
|
-
$: store.setField(finalPath, value);
|
|
14
|
+
$: void store.setField(finalPath, value);
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
17
|
<Field {path} {conditional} {boolean} {number} serialize={!notNull ? nullableSerialize : undefined} deserialize={!notNull ? nullableDeserialize : undefined} let:value>
|
package/dist/FieldSelect.svelte
CHANGED
package/dist/Form.svelte
CHANGED
package/dist/Listbox.svelte
CHANGED
|
@@ -26,7 +26,7 @@ async function reactToItems(..._) {
|
|
|
26
26
|
if (listboxElement)
|
|
27
27
|
listboxElement.removeAttribute('aria-activedescendant');
|
|
28
28
|
}
|
|
29
|
-
$: reactToItems(items);
|
|
29
|
+
$: void reactToItems(items);
|
|
30
30
|
const selectItem = (item, index) => (e) => {
|
|
31
31
|
e.stopPropagation();
|
|
32
32
|
e.preventDefault();
|
package/dist/MaxLength.svelte
CHANGED
package/dist/Tab.svelte
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>import { derivedStore } from '@txstate-mws/svelte-store';
|
|
2
2
|
import { getContext } from 'svelte';
|
|
3
3
|
import Icon from './Icon.svelte';
|
|
4
|
-
import {
|
|
4
|
+
import { TAB_CONTEXT } from './TabStore';
|
|
5
5
|
export let name;
|
|
6
6
|
const { store, onClick, onKeyDown, tabelements } = getContext(TAB_CONTEXT);
|
|
7
7
|
const accordion = store.accordion();
|
package/dist/Tabs.svelte
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
<script>import { modifierKey, resize, offset } from '@txstate-mws/svelte-components';
|
|
1
|
+
<script>import { modifierKey, resize, offset, PopupMenu } from '@txstate-mws/svelte-components';
|
|
2
2
|
import { Store } from '@txstate-mws/svelte-store';
|
|
3
|
-
import { getContext, onMount, setContext } from 'svelte';
|
|
3
|
+
import { getContext, onMount, setContext, tick } from 'svelte';
|
|
4
4
|
import { roundTo } from 'txstate-utils';
|
|
5
5
|
import { DIALOG_TABS_CONTEXT } from './Dialog.svelte';
|
|
6
6
|
import Icon from './Icon.svelte';
|
|
7
7
|
import { TabStore, TAB_CONTEXT } from './TabStore';
|
|
8
|
+
import caretRightFill from '@iconify-icons/ph/caret-right-fill';
|
|
8
9
|
export let tabs;
|
|
9
10
|
export let active = undefined;
|
|
10
11
|
export let store = new TabStore(tabs, active);
|
|
@@ -13,7 +14,9 @@ export let accordionOnMobile = true;
|
|
|
13
14
|
$: store.update(v => ({ ...v, tabs, accordionOnMobile }));
|
|
14
15
|
const activeStore = new Store({});
|
|
15
16
|
const tabelements = [];
|
|
17
|
+
let tabOverflowButton;
|
|
16
18
|
let activeelement;
|
|
19
|
+
let hiddenTabs = [];
|
|
17
20
|
setContext(TAB_CONTEXT, { store, onClick, onKeyDown, tabelements });
|
|
18
21
|
const dialogContext = (disableDialogControl ? undefined : getContext(DIALOG_TABS_CONTEXT)) ?? { change: () => { } };
|
|
19
22
|
dialogContext.onNext = () => { store.right(); };
|
|
@@ -47,18 +50,22 @@ function onKeyDown(idx) {
|
|
|
47
50
|
}
|
|
48
51
|
else if (e.key === 'ArrowLeft' && $store.current > 0) {
|
|
49
52
|
store.left();
|
|
53
|
+
await tick();
|
|
50
54
|
tabelements[$store.current].focus();
|
|
51
55
|
}
|
|
52
56
|
else if (e.key === 'ArrowRight' && $store.current < $store.tabs.length - 1) {
|
|
53
57
|
store.right();
|
|
58
|
+
await tick();
|
|
54
59
|
tabelements[$store.current].focus();
|
|
55
60
|
}
|
|
56
61
|
else if (e.key === 'Home' && $store.current > 0) {
|
|
57
62
|
store.home();
|
|
63
|
+
await tick();
|
|
58
64
|
tabelements[$store.current].focus();
|
|
59
65
|
}
|
|
60
66
|
else if (e.key === 'End' && $store.current < $store.tabs.length - 1) {
|
|
61
67
|
store.end();
|
|
68
|
+
await tick();
|
|
62
69
|
tabelements[$store.current].focus();
|
|
63
70
|
}
|
|
64
71
|
};
|
|
@@ -66,6 +73,17 @@ function onKeyDown(idx) {
|
|
|
66
73
|
function isActive(idx, activeidx) {
|
|
67
74
|
return idx === (activeidx ?? 0);
|
|
68
75
|
}
|
|
76
|
+
function onOverflowChange(e) {
|
|
77
|
+
store.activateName(e.detail.value);
|
|
78
|
+
}
|
|
79
|
+
function tabIsHidden(index) {
|
|
80
|
+
if (!wrapping)
|
|
81
|
+
return false;
|
|
82
|
+
const left = Math.max($currentIdx - cols + 1, 0);
|
|
83
|
+
const right = Math.min(left + cols - 1);
|
|
84
|
+
// return (index !== $currentIdx && index >= cols) || (index === cols - 1 && $currentIdx > cols - 1)
|
|
85
|
+
return (index !== $currentIdx) && ((index < left) || (index > right));
|
|
86
|
+
}
|
|
69
87
|
const activeOversize = 2;
|
|
70
88
|
async function reactToCurrent(..._) {
|
|
71
89
|
if (!activeelement)
|
|
@@ -80,9 +98,10 @@ async function reactToCurrent(..._) {
|
|
|
80
98
|
const width = span.offsetWidth + (activeOversize * 2);
|
|
81
99
|
activeelement.style.transform = `translateX(${left}px)`;
|
|
82
100
|
activeelement.style.width = `${width}px`;
|
|
101
|
+
hiddenTabs = $store.tabs.filter((tab, idx) => { return tabIsHidden(idx); });
|
|
83
102
|
}
|
|
84
103
|
$: active = $currentName;
|
|
85
|
-
$: reactToCurrent($activeStore);
|
|
104
|
+
$: void reactToCurrent($activeStore);
|
|
86
105
|
onMount(reactToCurrent);
|
|
87
106
|
</script>
|
|
88
107
|
|
|
@@ -92,9 +111,13 @@ onMount(reactToCurrent);
|
|
|
92
111
|
<ul use:resize={{ store }} class="tabs-buttons" role="tablist">
|
|
93
112
|
{#each $store.tabs as tab, idx (tab.name)}
|
|
94
113
|
{@const active = isActive(idx, $store.current)}
|
|
95
|
-
{@const left = idx
|
|
96
|
-
<li bind:this={tabelements[idx]} use:offset={{ store: active ? activeStore : undefined }} id={$store.tabids[tab.name]} class="tabs-tab" class:left class:wrapping class:active style:font-size="{scalefactor}em" style:line-height={1.2 / scalefactor} aria-selected={active} aria-controls={$store.panelids[tab.name]} role="tab" tabindex={active ? 0 : -1} on:click={onClick(idx)} on:keydown={onKeyDown(idx)}><span><Icon icon={tab.icon} inline />{tab.title}</span></li>
|
|
114
|
+
{@const left = idx === 0}
|
|
115
|
+
<li bind:this={tabelements[idx]} use:offset={{ store: active ? activeStore : undefined }} id={$store.tabids[tab.name]} class="tabs-tab" class:left class:wrapping class:active class:hidden={tabIsHidden(idx)} style:font-size="{scalefactor}em" style:line-height={1.2 / scalefactor} aria-selected={active} aria-controls={$store.panelids[tab.name]} role="tab" tabindex={active ? 0 : -1} on:click={onClick(idx)} on:keydown={onKeyDown(idx)}><span><Icon icon={tab.icon} inline />{tab.title}</span></li>
|
|
97
116
|
{/each}
|
|
117
|
+
{#if cols < $store.tabs.length}
|
|
118
|
+
<li class="overflow" role="presentation"><button bind:this={tabOverflowButton} type="button" tabindex="-1"><Icon icon={caretRightFill} hiddenLabel="More Tabs Menu" inline /></button></li>
|
|
119
|
+
<PopupMenu buttonelement={tabOverflowButton} items={hiddenTabs.map(t => ({ value: t.name }))} on:change={onOverflowChange}/>
|
|
120
|
+
{/if}
|
|
98
121
|
</ul>
|
|
99
122
|
<div bind:this={activeelement} class="tabs-active"></div>
|
|
100
123
|
<slot current={$store.current} />
|
|
@@ -135,6 +158,22 @@ onMount(reactToCurrent);
|
|
|
135
158
|
font-weight: 500;
|
|
136
159
|
color: var(--tabs-text, #363534)
|
|
137
160
|
}
|
|
161
|
+
:global(.tabs-tab.hidden) {
|
|
162
|
+
display: none;
|
|
163
|
+
}
|
|
164
|
+
li.overflow {
|
|
165
|
+
min-width: 2em;
|
|
166
|
+
display: flex;
|
|
167
|
+
align-items: center;
|
|
168
|
+
background-color: transparent !important;
|
|
169
|
+
padding: 0;
|
|
170
|
+
}
|
|
171
|
+
li.overflow button {
|
|
172
|
+
background: none;
|
|
173
|
+
cursor: pointer;
|
|
174
|
+
border: 0;
|
|
175
|
+
color: black;
|
|
176
|
+
}
|
|
138
177
|
li:not(.left) {
|
|
139
178
|
margin-left: -1px;
|
|
140
179
|
}
|
|
@@ -158,20 +197,4 @@ onMount(reactToCurrent);
|
|
|
158
197
|
border-radius: 2px;
|
|
159
198
|
}
|
|
160
199
|
|
|
161
|
-
/* .tabs-active {
|
|
162
|
-
background: var(--dg-tabs-active, var(--dg-button-bg, #501214));
|
|
163
|
-
height: 3px;
|
|
164
|
-
border-radius: 2px;
|
|
165
|
-
overflow: hidden;
|
|
166
|
-
width: 0px;
|
|
167
|
-
margin-top: calc(-1 * var(--tabs-padding-vert, 0.7em));
|
|
168
|
-
margin-bottom: var(--tabs-padding-vert, 0.7em);
|
|
169
|
-
transition: 0.2s transform;
|
|
170
|
-
}
|
|
171
|
-
@media (prefers-reduced-motion) {
|
|
172
|
-
.tabs-active {
|
|
173
|
-
transition: none;
|
|
174
|
-
}
|
|
175
|
-
} */
|
|
176
|
-
|
|
177
200
|
</style>
|
|
@@ -33,7 +33,7 @@ onMount(reactToOptions);
|
|
|
33
33
|
</script>
|
|
34
34
|
|
|
35
35
|
<FieldStandard bind:id descid={groupid} {path} {label} {required} {defaultValue} {conditional} {helptext} let:value let:valid let:invalid let:onBlur let:onChange let:messagesid let:helptextid let:setVal>
|
|
36
|
-
{@const _ = updateValue(value, setVal)}
|
|
36
|
+
{@const _ = void updateValue(value, setVal)}
|
|
37
37
|
<div class="container-query-wrapper">
|
|
38
38
|
<div class="color-container {className}" role="radiogroup" aria-labelledby={groupid} class:invalid class:valid>
|
|
39
39
|
{#if addAllOption}
|
|
@@ -112,6 +112,7 @@ let focusWithin = false;
|
|
|
112
112
|
{@const _ = init(value, setVal)}
|
|
113
113
|
{#if isNotBlank(imageSrc)}
|
|
114
114
|
<div on:focusin={() => { focusWithin = true }} on:focusout={() => { focusWithin = false }}>
|
|
115
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
115
116
|
<div bind:this={container} use:resize on:resize={() => updateRect()} class="crop-image-container" on:mousedown={onMouseDown} on:touchstart={onMouseDown} on:touchmove={onMouseMove} style:cursor={$store.cursor}>
|
|
116
117
|
<img class="crop-image" src={imageSrc} alt="" />
|
|
117
118
|
{#if $selection && $outputPct}
|
|
@@ -119,6 +120,7 @@ let focusWithin = false;
|
|
|
119
120
|
<img class='crop-image clipped' src={imageSrc} alt="" style:clip-path="polygon({$outputPct.left}% {$outputPct.top}%, {100 - $outputPct.right}% {$outputPct.top}%, {100 - $outputPct.right}% {100 - $outputPct.bottom}%, {$outputPct.left}% {100 - $outputPct.bottom}%, {$outputPct.left}% {$outputPct.top}%)" />
|
|
120
121
|
</div>
|
|
121
122
|
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
123
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
122
124
|
<div class='selectionHilite' {id} tabindex="0" on:keydown={onKeyDown('move')}
|
|
123
125
|
aria-labelledby={descid}
|
|
124
126
|
aria-describedby="{movedescid} {helptextid ?? ''}"
|
|
@@ -132,24 +134,28 @@ let focusWithin = false;
|
|
|
132
134
|
<ScreenReaderOnly arialive="polite">top left x y coordinate is ({Math.round($selection.left)}, {Math.round($selection.top)}) bottom right x y coordinate is ({Math.round($selection.right)}, {Math.round($selection.bottom)})</ScreenReaderOnly>
|
|
133
135
|
<ScreenReaderOnly arialive="polite">crop area is {Math.round($store.width)} pixels wide by {Math.round($store.height)} pixels tall</ScreenReaderOnly>
|
|
134
136
|
{/if}
|
|
137
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
135
138
|
<div class='selectionCorner tl'
|
|
136
139
|
tabindex="0"
|
|
137
140
|
on:keydown={onKeyDown('tl')}
|
|
138
141
|
>
|
|
139
142
|
<ScreenReaderOnly>arrows adjust crop size, bottom right is fixed, hold shift and/or cmd/alt for bigger steps</ScreenReaderOnly>
|
|
140
143
|
</div>
|
|
144
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
141
145
|
<div class='selectionCorner tr'
|
|
142
146
|
tabindex="0"
|
|
143
147
|
on:keydown={onKeyDown('tr')}
|
|
144
148
|
>
|
|
145
149
|
<ScreenReaderOnly>arrows adjust crop size, bottom left is fixed, hold shift and/or cmd/alt for bigger steps</ScreenReaderOnly>
|
|
146
150
|
</div>
|
|
151
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
147
152
|
<div class='selectionCorner bl'
|
|
148
153
|
tabindex="0"
|
|
149
154
|
on:keydown={onKeyDown('bl')}
|
|
150
155
|
>
|
|
151
156
|
<ScreenReaderOnly>arrows adjust crop size, top right is fixed, hold shift and/or cmd/alt for bigger steps</ScreenReaderOnly>
|
|
152
157
|
</div>
|
|
158
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
153
159
|
<div class='selectionCorner br'
|
|
154
160
|
tabindex="0"
|
|
155
161
|
on:keydown={onKeyDown('br')}
|
|
@@ -18,7 +18,7 @@ let selected = defaultValue;
|
|
|
18
18
|
const iconToPrefix = {};
|
|
19
19
|
const categoriesToIcons = keyby(IconCategories, 'key');
|
|
20
20
|
for (const icon of FontAwesomeIcons) {
|
|
21
|
-
iconToPrefix[icon.class] = icon.free.
|
|
21
|
+
iconToPrefix[icon.class] = icon.free.includes('brands') ? 'fab' : 'fas';
|
|
22
22
|
}
|
|
23
23
|
const iconElements = [];
|
|
24
24
|
let visibleIcons = FontAwesomeIcons;
|
|
@@ -104,8 +104,8 @@ function onKeyDown(e) {
|
|
|
104
104
|
</script>
|
|
105
105
|
|
|
106
106
|
<FieldStandard bind:id {path} {descid} {label} {required} {defaultValue} {conditional} {helptext} let:value let:valid let:invalid let:id let:onBlur let:setVal let:messagesid let:helptextid>
|
|
107
|
-
<Icon icon={`${value.prefix === 'fab' ? '
|
|
108
|
-
<button type="button" id="btnSelectIcon" on:click={() => { modalOpen = true }} aria-describedby={getDescribedBy([descid, messagesid, helptextid])}>Select New Icon</button>
|
|
107
|
+
<Icon icon={`${value.prefix === 'fab' ? 'fa6-brands' : 'fa6-solid'}:${value.icon?.slice(3) ?? 'graduation-cap'}`}/>
|
|
108
|
+
<button type="button" id="btnSelectIcon" class="select-icon" on:click={() => { modalOpen = true }} aria-describedby={getDescribedBy([descid, messagesid, helptextid])}>Select New Icon</button>
|
|
109
109
|
{#if modalOpen}
|
|
110
110
|
<Modal>
|
|
111
111
|
<section>
|
|
@@ -130,8 +130,9 @@ function onKeyDown(e) {
|
|
|
130
130
|
<ScreenReaderOnly><legend class="sr-only">Icons</legend></ScreenReaderOnly>
|
|
131
131
|
<div class="icon-picker-items" role="radiogroup">
|
|
132
132
|
{#each visibleIcons as icon, idx (icon.class)}
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
|
|
134
|
+
<div bind:this={iconElements[idx]} id={icon.class} class="icon-picker-item" role="radio" aria-checked={icon.class === selected.icon} tabindex={icon.class === selected.icon ? 0 : -1} data-index={idx} on:click={() => onSelectIcon(icon.class)} on:keydown={onKeyDown}>
|
|
135
|
+
<Icon icon={`${iconToPrefix[icon.class] === 'fab' ? 'fa6-brands' : 'fa6-solid'}:${icon.class.slice(3)}`}/>
|
|
135
136
|
<ScreenReaderOnly>{icon.label}</ScreenReaderOnly>
|
|
136
137
|
</div>
|
|
137
138
|
{:else}
|
|
@@ -153,6 +154,11 @@ function onKeyDown(e) {
|
|
|
153
154
|
|
|
154
155
|
|
|
155
156
|
<style>
|
|
157
|
+
.select-icon {
|
|
158
|
+
border-radius: 0.25em;
|
|
159
|
+
border: 1px solid #808080;
|
|
160
|
+
color: black;
|
|
161
|
+
}
|
|
156
162
|
section {
|
|
157
163
|
position: relative;
|
|
158
164
|
background-color: #f4f4f4;
|