@marianmeres/stuic 1.19.0 → 1.21.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/actions/autogrow.d.ts +8 -0
- package/dist/actions/autogrow.js +22 -0
- package/dist/actions/tooltip/tooltip.d.ts +2 -1
- package/dist/actions/tooltip/tooltip.js +3 -0
- package/dist/actions/trim.d.ts +4 -0
- package/dist/actions/trim.js +18 -0
- package/dist/actions/validate.d.ts +22 -0
- package/dist/actions/validate.js +80 -0
- package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte +463 -0
- package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte.d.ts +104 -0
- package/dist/components/AlertConfirmPrompt/acp-icons.d.ts +7 -0
- package/dist/components/AlertConfirmPrompt/acp-icons.js +134 -0
- package/dist/components/AlertConfirmPrompt/alert-confirm-prompt.d.ts +55 -0
- package/dist/components/AlertConfirmPrompt/alert-confirm-prompt.js +126 -0
- package/dist/components/Button/Button.svelte +18 -9
- package/dist/components/Button/Button.svelte.d.ts +1 -1
- package/dist/components/Input/Field.svelte +179 -0
- package/dist/components/Input/Field.svelte.d.ts +63 -0
- package/dist/components/Input/FieldCheckbox.svelte +102 -0
- package/dist/components/Input/FieldCheckbox.svelte.d.ts +34 -0
- package/dist/components/Input/FieldRadios.svelte +51 -0
- package/dist/components/Input/FieldRadios.svelte.d.ts +31 -0
- package/dist/components/Input/FieldSelect.svelte +125 -0
- package/dist/components/Input/FieldSelect.svelte.d.ts +47 -0
- package/dist/components/Input/Fieldset.svelte +27 -0
- package/dist/components/Input/Fieldset.svelte.d.ts +20 -0
- package/dist/components/Input/XFieldRadioInternal.svelte +102 -0
- package/dist/components/Input/XFieldRadioInternal.svelte.d.ts +33 -0
- package/dist/components/Switch/Switch.svelte.d.ts +1 -1
- package/dist/components/Thc/Thc.svelte +15 -0
- package/dist/components/Thc/Thc.svelte.d.ts +28 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +13 -0
- package/package.json +3 -2
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function increaseHeightToScrollHeight(el: HTMLElement, max?: number, min?: number): void;
|
|
2
|
+
export declare function autogrow(el: HTMLTextAreaElement, options?: Partial<{
|
|
3
|
+
max: number;
|
|
4
|
+
min: number;
|
|
5
|
+
allowed: boolean;
|
|
6
|
+
}> | null): {
|
|
7
|
+
destroy: () => void;
|
|
8
|
+
} | undefined;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// actual worker
|
|
2
|
+
export function increaseHeightToScrollHeight(el, max = 0, min = 16) {
|
|
3
|
+
//
|
|
4
|
+
let h = max ? Math.min(max, el.scrollHeight) : el.scrollHeight;
|
|
5
|
+
h = Math.max(min, h);
|
|
6
|
+
// only increase size
|
|
7
|
+
if (el.getBoundingClientRect().height < h) {
|
|
8
|
+
el.style.height = `${h}px`;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
// action wrap
|
|
12
|
+
export function autogrow(el, options = null) {
|
|
13
|
+
const { max, min, allowed } = { max: 250, min: 64, allowed: true, ...(options || {}) };
|
|
14
|
+
if (!allowed)
|
|
15
|
+
return;
|
|
16
|
+
const _doGrow = () => increaseHeightToScrollHeight(el, max, min);
|
|
17
|
+
_doGrow(); // resize asap (on mount) as well...
|
|
18
|
+
el.addEventListener('input', _doGrow);
|
|
19
|
+
return {
|
|
20
|
+
destroy: () => el.removeEventListener('input', _doGrow),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -16,6 +16,7 @@ export declare class PopoverConfig {
|
|
|
16
16
|
static defaultOptions: Partial<TooltipOptions>;
|
|
17
17
|
}
|
|
18
18
|
export type TooltipLogger = (...args: any[]) => void;
|
|
19
|
+
export type TooltipTrigger = 'hover' | 'focus' | 'click';
|
|
19
20
|
export interface TooltipOptions {
|
|
20
21
|
content: string;
|
|
21
22
|
popover: HTMLElement | null;
|
|
@@ -24,7 +25,7 @@ export interface TooltipOptions {
|
|
|
24
25
|
delay: number;
|
|
25
26
|
class: string;
|
|
26
27
|
arrowClass: string;
|
|
27
|
-
triggers:
|
|
28
|
+
triggers: TooltipTrigger[];
|
|
28
29
|
logger?: TooltipLogger;
|
|
29
30
|
boundaryRoot?: HTMLElement;
|
|
30
31
|
arrowSize: number;
|
|
@@ -195,6 +195,9 @@ export function tooltip(node, initialOptions = {}) {
|
|
|
195
195
|
};
|
|
196
196
|
//
|
|
197
197
|
const destroy = () => {
|
|
198
|
+
// for obscure cases, where parent node might have be removed from DOM
|
|
199
|
+
// before the planned show/hide happens
|
|
200
|
+
_resetDelayTimer();
|
|
198
201
|
if (!div && !arrow && !opts.popover && !storeGet(_isOn))
|
|
199
202
|
return;
|
|
200
203
|
_log('destroy');
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const trim = (el, enabled = true) => {
|
|
2
|
+
const trim = (e) => {
|
|
3
|
+
if (enabled && typeof el.value === 'string') {
|
|
4
|
+
el.value = el.value.trim();
|
|
5
|
+
}
|
|
6
|
+
};
|
|
7
|
+
el.addEventListener('change', trim);
|
|
8
|
+
return {
|
|
9
|
+
update(enabledFlag) {
|
|
10
|
+
if (enabledFlag !== undefined) {
|
|
11
|
+
enabled = !!enabled;
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
destroy() {
|
|
15
|
+
el.removeEventListener('change', trim);
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ValidationResult {
|
|
2
|
+
validity: ValidityState;
|
|
3
|
+
reasons: (keyof ValidityStateFlags)[];
|
|
4
|
+
valid: boolean;
|
|
5
|
+
message: string;
|
|
6
|
+
}
|
|
7
|
+
type ReasonTranslate = (reason: keyof ValidityStateFlags, value: any, fallback: string) => string;
|
|
8
|
+
export interface ValidateOptions {
|
|
9
|
+
context?: Record<string, any>;
|
|
10
|
+
customValidator?: (value: any, context: Record<string, any> | undefined, el: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement) => string | undefined;
|
|
11
|
+
on?: 'input' | 'change';
|
|
12
|
+
setValidationResult?: (res: ValidationResult) => void;
|
|
13
|
+
t?: false | ReasonTranslate;
|
|
14
|
+
}
|
|
15
|
+
export declare const validate: {
|
|
16
|
+
(el: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement, options: undefined | ValidateOptions): {
|
|
17
|
+
update(newOptions: undefined | ValidateOptions): void;
|
|
18
|
+
destroy(): void;
|
|
19
|
+
};
|
|
20
|
+
t: null;
|
|
21
|
+
};
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export const validate = (el, options) => {
|
|
2
|
+
let _doValidate = !!options;
|
|
3
|
+
let context = options?.context;
|
|
4
|
+
let customValidator = options?.customValidator;
|
|
5
|
+
let onEventName = options?.on || 'change';
|
|
6
|
+
const t = (reason, value, fallback) => {
|
|
7
|
+
if (!reason || options?.t === false)
|
|
8
|
+
return fallback;
|
|
9
|
+
// local t (if any)
|
|
10
|
+
if (typeof options?.t === 'function')
|
|
11
|
+
return options.t(reason, value, fallback);
|
|
12
|
+
// global t (if any)
|
|
13
|
+
if (typeof validate.t === 'function')
|
|
14
|
+
return validate.t(reason, value, fallback);
|
|
15
|
+
//
|
|
16
|
+
return fallback;
|
|
17
|
+
};
|
|
18
|
+
const doValidate = (event) => {
|
|
19
|
+
if (!_doValidate)
|
|
20
|
+
return;
|
|
21
|
+
el.checkValidity();
|
|
22
|
+
if (typeof customValidator === 'function') {
|
|
23
|
+
el.setCustomValidity(customValidator(el.value, context, el) || '');
|
|
24
|
+
}
|
|
25
|
+
// toto trigerne bubble
|
|
26
|
+
// el.reportValidity();
|
|
27
|
+
const validityState = el.validity;
|
|
28
|
+
// prettier-ignore
|
|
29
|
+
const reasons = [
|
|
30
|
+
'badInput', 'customError', 'patternMismatch', 'rangeOverflow', 'rangeUnderflow',
|
|
31
|
+
'stepMismatch', 'tooLong', 'tooShort', 'typeMismatch', 'valueMissing'
|
|
32
|
+
].reduce((m, k) => {
|
|
33
|
+
if (validityState[k])
|
|
34
|
+
m.push(k);
|
|
35
|
+
return m;
|
|
36
|
+
}, []);
|
|
37
|
+
if (typeof options?.setValidationResult === 'function') {
|
|
38
|
+
options.setValidationResult({
|
|
39
|
+
validity: validityState,
|
|
40
|
+
reasons,
|
|
41
|
+
valid: validityState?.valid,
|
|
42
|
+
// use translate fn for first reason (if fn provided and allowed),
|
|
43
|
+
// otherwise fallback to native msg
|
|
44
|
+
message: t(reasons?.[0], el.value, el.validationMessage),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
el.addEventListener(onEventName, doValidate);
|
|
49
|
+
//
|
|
50
|
+
let _touchCount = 0;
|
|
51
|
+
const onFocus = (e) => _touchCount++;
|
|
52
|
+
el.addEventListener('focus', onFocus);
|
|
53
|
+
// also validate on first blur
|
|
54
|
+
const onBlur = (e) => _touchCount === 1 && doValidate(e);
|
|
55
|
+
el.addEventListener('blur', onBlur);
|
|
56
|
+
//
|
|
57
|
+
// const onChange = (e) => doValidate(e);
|
|
58
|
+
// el.addEventListener('change', onChange);
|
|
59
|
+
//
|
|
60
|
+
// const onInput = (e) => _touchCount > 1 && doValidate(e);
|
|
61
|
+
// el.addEventListener('input', onInput);
|
|
62
|
+
//
|
|
63
|
+
return {
|
|
64
|
+
update(newOptions) {
|
|
65
|
+
_doValidate = !!newOptions;
|
|
66
|
+
// allow only context to update
|
|
67
|
+
context = newOptions?.context;
|
|
68
|
+
},
|
|
69
|
+
destroy() {
|
|
70
|
+
el.removeEventListener(onEventName, doValidate);
|
|
71
|
+
el.removeEventListener('focus', onFocus);
|
|
72
|
+
el.removeEventListener('blur', onBlur);
|
|
73
|
+
// el.removeEventListener('change', onChange);
|
|
74
|
+
// el.removeEventListener('input', onInput);
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
// ReasonTranslate
|
|
79
|
+
const t = null;
|
|
80
|
+
validate.t = t;
|
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
<script context="module">import { onMount } from "svelte";
|
|
2
|
+
import { Button, focusTrap } from "../../index.js";
|
|
3
|
+
import Thc from "../Thc/Thc.svelte";
|
|
4
|
+
import {
|
|
5
|
+
AlertConfirmPromptType
|
|
6
|
+
} from "./alert-confirm-prompt.js";
|
|
7
|
+
import { twMerge } from "tailwind-merge";
|
|
8
|
+
import { Field } from "../../index.js";
|
|
9
|
+
import { acpDefaultIcons } from "./acp-icons.js";
|
|
10
|
+
import { createClog } from "@marianmeres/clog";
|
|
11
|
+
export class AlertConfirmPromptConfig {
|
|
12
|
+
// sane defaults which perhaps should stay untouched
|
|
13
|
+
static preset = {
|
|
14
|
+
dialog: `
|
|
15
|
+
relative
|
|
16
|
+
w-full sm:max-w-xl
|
|
17
|
+
mx-auto
|
|
18
|
+
p-5 sm:p-6
|
|
19
|
+
bg-white text-black
|
|
20
|
+
dark:bg-black dark:text-white
|
|
21
|
+
rounded-lg
|
|
22
|
+
transition-all
|
|
23
|
+
shadow-xl
|
|
24
|
+
focus-within:outline-0 focus-within:ring-0
|
|
25
|
+
`.trim(),
|
|
26
|
+
icon: `
|
|
27
|
+
size-12 sm:size-10
|
|
28
|
+
mt-1 mb-4 sm:my-0
|
|
29
|
+
mx-auto
|
|
30
|
+
flex flex-shrink-0 items-center justify-center
|
|
31
|
+
rounded-full
|
|
32
|
+
bg-neutral-100 text-black/50
|
|
33
|
+
`.trim(),
|
|
34
|
+
contentBlock: `
|
|
35
|
+
mt-3 sm:ml-4 sm:mt-0 sm:flex-1
|
|
36
|
+
`.trim(),
|
|
37
|
+
title: `
|
|
38
|
+
text-center sm:text-left
|
|
39
|
+
text-base font-semibold leading-6 text-black/90
|
|
40
|
+
`.trim(),
|
|
41
|
+
content: `
|
|
42
|
+
mt-2 mx-3 sm:mx-0
|
|
43
|
+
text-center sm:text-left
|
|
44
|
+
text-sm text-black/75
|
|
45
|
+
`.trim(),
|
|
46
|
+
inputBox: `
|
|
47
|
+
mt-3
|
|
48
|
+
`.trim(),
|
|
49
|
+
inputField: `
|
|
50
|
+
m-0
|
|
51
|
+
`.trim(),
|
|
52
|
+
menu: `
|
|
53
|
+
mt-6
|
|
54
|
+
sm:flex sm:space-x-4 justify-end
|
|
55
|
+
space-y-3 sm:space-y-0
|
|
56
|
+
`.trim(),
|
|
57
|
+
menuLi: `
|
|
58
|
+
flex-1 sm:flex-none w-full sm:w-auto sm:inline-block
|
|
59
|
+
`.trim(),
|
|
60
|
+
button: `
|
|
61
|
+
w-full min-w-24 text-center inline-block
|
|
62
|
+
`.trim(),
|
|
63
|
+
spinnerBox: `
|
|
64
|
+
absolute inset-0 flex justify-center items-center
|
|
65
|
+
rounded-lg
|
|
66
|
+
bg-white/50
|
|
67
|
+
`.trim()
|
|
68
|
+
};
|
|
69
|
+
// main userland configuration
|
|
70
|
+
static classDialog = "";
|
|
71
|
+
static classIcon = "";
|
|
72
|
+
static classTitle = "";
|
|
73
|
+
static classContentBlock = "";
|
|
74
|
+
static classContent = "";
|
|
75
|
+
static classInputBox = "";
|
|
76
|
+
static classInputField = "";
|
|
77
|
+
static classMenu = "";
|
|
78
|
+
static classMenuLi = "";
|
|
79
|
+
static classButton = "";
|
|
80
|
+
static classSpinnerBox = "";
|
|
81
|
+
// 'info' | 'success' | 'warn' | 'error'
|
|
82
|
+
// userlang variant fine tuning
|
|
83
|
+
static variant = {
|
|
84
|
+
info: {
|
|
85
|
+
dialog: "",
|
|
86
|
+
icon: "",
|
|
87
|
+
contentBlock: "",
|
|
88
|
+
title: "",
|
|
89
|
+
content: "",
|
|
90
|
+
inputBox: "",
|
|
91
|
+
inputField: "",
|
|
92
|
+
menu: "",
|
|
93
|
+
menuLi: "",
|
|
94
|
+
button: "",
|
|
95
|
+
spinnerBox: ""
|
|
96
|
+
},
|
|
97
|
+
success: {
|
|
98
|
+
dialog: "",
|
|
99
|
+
icon: "",
|
|
100
|
+
contentBlock: "",
|
|
101
|
+
title: "",
|
|
102
|
+
content: "",
|
|
103
|
+
inputBox: "",
|
|
104
|
+
inputField: "",
|
|
105
|
+
menu: "",
|
|
106
|
+
menuLi: "",
|
|
107
|
+
button: "",
|
|
108
|
+
spinnerBox: ""
|
|
109
|
+
},
|
|
110
|
+
warn: {
|
|
111
|
+
dialog: "",
|
|
112
|
+
icon: "",
|
|
113
|
+
contentBlock: "",
|
|
114
|
+
title: "",
|
|
115
|
+
content: "",
|
|
116
|
+
inputBox: "",
|
|
117
|
+
inputField: "",
|
|
118
|
+
menu: "",
|
|
119
|
+
menuLi: "",
|
|
120
|
+
button: "",
|
|
121
|
+
spinnerBox: ""
|
|
122
|
+
},
|
|
123
|
+
error: {
|
|
124
|
+
dialog: "",
|
|
125
|
+
icon: "",
|
|
126
|
+
contentBlock: "",
|
|
127
|
+
title: "",
|
|
128
|
+
content: "",
|
|
129
|
+
inputBox: "",
|
|
130
|
+
inputField: "",
|
|
131
|
+
menu: "",
|
|
132
|
+
menuLi: "",
|
|
133
|
+
button: "",
|
|
134
|
+
spinnerBox: ""
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
static iconFn = {
|
|
138
|
+
info: void 0,
|
|
139
|
+
success: void 0,
|
|
140
|
+
warn: void 0,
|
|
141
|
+
error: void 0,
|
|
142
|
+
spinner: void 0
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const _isFn = (v) => typeof v === "function";
|
|
146
|
+
const { ALERT, CONFIRM, PROMPT } = AlertConfirmPromptType;
|
|
147
|
+
</script>
|
|
148
|
+
|
|
149
|
+
<script>const clog = createClog("AlertConfirmPrompt");
|
|
150
|
+
export let acp;
|
|
151
|
+
$:
|
|
152
|
+
dialog = $acp[0];
|
|
153
|
+
let _dialogEl;
|
|
154
|
+
let value = null;
|
|
155
|
+
let isPending = false;
|
|
156
|
+
$:
|
|
157
|
+
if (dialog?.type === PROMPT) {
|
|
158
|
+
if (value === null)
|
|
159
|
+
value = dialog.value;
|
|
160
|
+
} else {
|
|
161
|
+
value = null;
|
|
162
|
+
}
|
|
163
|
+
$:
|
|
164
|
+
if (dialog && _dialogEl)
|
|
165
|
+
!_dialogEl.hasAttribute("open") && _dialogEl.showModal();
|
|
166
|
+
$:
|
|
167
|
+
if (!dialog && _dialogEl)
|
|
168
|
+
_dialogEl.close("cleanup");
|
|
169
|
+
const onKeyDown = (e) => {
|
|
170
|
+
if (!dialog)
|
|
171
|
+
return;
|
|
172
|
+
if (e.key === "Escape") {
|
|
173
|
+
e.stopPropagation();
|
|
174
|
+
if (!isPending)
|
|
175
|
+
return acp.escape();
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
onMount(() => {
|
|
179
|
+
_dialogEl.addEventListener("close", async () => {
|
|
180
|
+
if (_dialogEl.returnValue === "") {
|
|
181
|
+
acp.escape();
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
_dialogEl.addEventListener("cancel", (event) => event.preventDefault());
|
|
185
|
+
document.addEventListener("keydown", onKeyDown, true);
|
|
186
|
+
return () => document.removeEventListener("keydown", onKeyDown, true);
|
|
187
|
+
});
|
|
188
|
+
$:
|
|
189
|
+
_dialogClass = twMerge(`
|
|
190
|
+
${AlertConfirmPromptConfig.preset.dialog}
|
|
191
|
+
${AlertConfirmPromptConfig.classDialog}
|
|
192
|
+
${dialog?.class?.dialog || ""}
|
|
193
|
+
${AlertConfirmPromptConfig.variant?.[dialog?.variant]?.dialog || ""}
|
|
194
|
+
`);
|
|
195
|
+
$:
|
|
196
|
+
_iconClass = twMerge(`
|
|
197
|
+
${AlertConfirmPromptConfig.preset.icon}
|
|
198
|
+
${AlertConfirmPromptConfig.classIcon}
|
|
199
|
+
${dialog?.class?.icon || ""}
|
|
200
|
+
${AlertConfirmPromptConfig.variant?.[dialog?.variant]?.icon || ""}
|
|
201
|
+
`);
|
|
202
|
+
$:
|
|
203
|
+
_contentBlockClass = twMerge(`
|
|
204
|
+
${AlertConfirmPromptConfig.preset.contentBlock}
|
|
205
|
+
${AlertConfirmPromptConfig.classContentBlock}
|
|
206
|
+
${dialog?.class?.contentBlock || ""}
|
|
207
|
+
${AlertConfirmPromptConfig.variant?.[dialog?.variant]?.contentBlock || ""}
|
|
208
|
+
`);
|
|
209
|
+
$:
|
|
210
|
+
_titleClass = twMerge(`
|
|
211
|
+
${AlertConfirmPromptConfig.preset.title}
|
|
212
|
+
${AlertConfirmPromptConfig.classTitle}
|
|
213
|
+
${dialog?.class?.title || ""}
|
|
214
|
+
${AlertConfirmPromptConfig.variant?.[dialog?.variant]?.title || ""}
|
|
215
|
+
`);
|
|
216
|
+
$:
|
|
217
|
+
_contentClass = twMerge(`
|
|
218
|
+
${AlertConfirmPromptConfig.preset.content}
|
|
219
|
+
${AlertConfirmPromptConfig.classContent}
|
|
220
|
+
${dialog?.class?.content || ""}
|
|
221
|
+
${AlertConfirmPromptConfig.variant?.[dialog?.variant]?.content || ""}
|
|
222
|
+
`);
|
|
223
|
+
$:
|
|
224
|
+
_inputBoxClass = twMerge(`
|
|
225
|
+
${AlertConfirmPromptConfig.preset.inputBox}
|
|
226
|
+
${AlertConfirmPromptConfig.classInputBox}
|
|
227
|
+
${dialog?.class?.inputBox || ""}
|
|
228
|
+
${AlertConfirmPromptConfig.variant?.[dialog?.variant]?.inputBox || ""}
|
|
229
|
+
`);
|
|
230
|
+
$:
|
|
231
|
+
_inputFieldClass = twMerge(`
|
|
232
|
+
${AlertConfirmPromptConfig.preset.inputField}
|
|
233
|
+
${AlertConfirmPromptConfig.classInputField}
|
|
234
|
+
${dialog?.class?.inputField || ""}
|
|
235
|
+
${AlertConfirmPromptConfig.variant?.[dialog?.variant]?.inputField || ""}
|
|
236
|
+
`);
|
|
237
|
+
$:
|
|
238
|
+
_menuClass = twMerge(`
|
|
239
|
+
${AlertConfirmPromptConfig.preset.menu}
|
|
240
|
+
${AlertConfirmPromptConfig.classMenu}
|
|
241
|
+
${dialog?.class?.menu || ""}
|
|
242
|
+
${AlertConfirmPromptConfig.variant?.[dialog?.variant]?.menu || ""}
|
|
243
|
+
`);
|
|
244
|
+
$:
|
|
245
|
+
_menuLiClass = twMerge(`
|
|
246
|
+
${AlertConfirmPromptConfig.preset.menuLi}
|
|
247
|
+
${AlertConfirmPromptConfig.classMenuLi}
|
|
248
|
+
${dialog?.class?.menuLi || ""}
|
|
249
|
+
${AlertConfirmPromptConfig.variant?.[dialog?.variant]?.menuLi || ""}
|
|
250
|
+
`);
|
|
251
|
+
$:
|
|
252
|
+
_buttonClass = twMerge(`
|
|
253
|
+
${AlertConfirmPromptConfig.preset.button}
|
|
254
|
+
${AlertConfirmPromptConfig.classButton}
|
|
255
|
+
${dialog?.class?.button || ""}
|
|
256
|
+
${AlertConfirmPromptConfig.variant?.[dialog?.variant]?.button || ""}
|
|
257
|
+
`);
|
|
258
|
+
$:
|
|
259
|
+
_spinnerBoxClass = twMerge(`
|
|
260
|
+
${AlertConfirmPromptConfig.preset.spinnerBox}
|
|
261
|
+
${AlertConfirmPromptConfig.classSpinnerBox}
|
|
262
|
+
${dialog?.class?.spinnerBox || ""}
|
|
263
|
+
${AlertConfirmPromptConfig.variant?.[dialog?.variant]?.spinnerBox || ""}
|
|
264
|
+
`);
|
|
265
|
+
let iconFn = false;
|
|
266
|
+
$:
|
|
267
|
+
if (dialog?.iconFn === true) {
|
|
268
|
+
iconFn = // either runtime config
|
|
269
|
+
AlertConfirmPromptConfig.iconFn[dialog?.variant] || // or fixed default
|
|
270
|
+
acpDefaultIcons[dialog?.variant];
|
|
271
|
+
} else if (dialog?.iconFn) {
|
|
272
|
+
iconFn = dialog.iconFn;
|
|
273
|
+
} else {
|
|
274
|
+
iconFn = false;
|
|
275
|
+
}
|
|
276
|
+
$:
|
|
277
|
+
clog(dialog);
|
|
278
|
+
</script>
|
|
279
|
+
|
|
280
|
+
<dialog
|
|
281
|
+
bind:this={_dialogEl}
|
|
282
|
+
data-acp-type={dialog?.type}
|
|
283
|
+
data-acp-variant={dialog?.variant}
|
|
284
|
+
data-acp-is-pending={isPending}
|
|
285
|
+
class="bg-transparent w-full focus-within:outline-0 focus-within:ring-0"
|
|
286
|
+
tabindex="-1"
|
|
287
|
+
>
|
|
288
|
+
{#if dialog}
|
|
289
|
+
<!--since we're not using the native form submit, the <form> is not necessary-->
|
|
290
|
+
<form
|
|
291
|
+
method="dialog"
|
|
292
|
+
use:focusTrap={{ autoFocusFirst: false }}
|
|
293
|
+
tabindex="-1"
|
|
294
|
+
data-acp-type={dialog?.type}
|
|
295
|
+
data-acp-variant={dialog?.variant}
|
|
296
|
+
data-acp-is-pending={isPending}
|
|
297
|
+
class={_dialogClass}
|
|
298
|
+
>
|
|
299
|
+
<!-- this sm:flex is not configurable -->
|
|
300
|
+
<div class="sm:flex sm:items-start">
|
|
301
|
+
{#if _isFn(iconFn)}
|
|
302
|
+
<div
|
|
303
|
+
class={_iconClass}
|
|
304
|
+
data-acp-type={dialog?.type}
|
|
305
|
+
data-acp-variant={dialog?.variant}
|
|
306
|
+
data-acp-is-pending={isPending}
|
|
307
|
+
>
|
|
308
|
+
{@html iconFn()}
|
|
309
|
+
</div>
|
|
310
|
+
{/if}
|
|
311
|
+
<div class={_contentBlockClass}>
|
|
312
|
+
<h1
|
|
313
|
+
class={_titleClass}
|
|
314
|
+
data-acp-type={dialog?.type}
|
|
315
|
+
data-acp-variant={dialog?.variant}
|
|
316
|
+
data-acp-is-pending={isPending}
|
|
317
|
+
>
|
|
318
|
+
<Thc thc={dialog.title} />
|
|
319
|
+
</h1>
|
|
320
|
+
{#if dialog.content}
|
|
321
|
+
<div
|
|
322
|
+
class={_contentClass}
|
|
323
|
+
data-acp-type={dialog?.type}
|
|
324
|
+
data-acp-variant={dialog?.variant}
|
|
325
|
+
data-acp-is-pending={isPending}
|
|
326
|
+
>
|
|
327
|
+
<Thc thc={dialog.content} />
|
|
328
|
+
</div>
|
|
329
|
+
{/if}
|
|
330
|
+
{#if dialog.type === PROMPT}
|
|
331
|
+
<div
|
|
332
|
+
class={_inputBoxClass}
|
|
333
|
+
data-acp-type={dialog?.type}
|
|
334
|
+
data-acp-variant={dialog?.variant}
|
|
335
|
+
data-acp-is-pending={isPending}
|
|
336
|
+
>
|
|
337
|
+
<Field
|
|
338
|
+
class={_inputFieldClass}
|
|
339
|
+
bind:value
|
|
340
|
+
data-acp-type={dialog?.type}
|
|
341
|
+
data-acp-variant={dialog?.variant}
|
|
342
|
+
data-acp-is-pending={isPending}
|
|
343
|
+
on:input_mounted={({ detail }) => detail.focus()}
|
|
344
|
+
size="sm"
|
|
345
|
+
/>
|
|
346
|
+
</div>
|
|
347
|
+
{/if}
|
|
348
|
+
</div>
|
|
349
|
+
</div>
|
|
350
|
+
<menu
|
|
351
|
+
class={_menuClass}
|
|
352
|
+
data-acp-type={dialog?.type}
|
|
353
|
+
data-acp-variant={dialog?.variant}
|
|
354
|
+
data-acp-is-pending={isPending}
|
|
355
|
+
>
|
|
356
|
+
{#if dialog.type !== ALERT}
|
|
357
|
+
<li
|
|
358
|
+
class={_menuLiClass}
|
|
359
|
+
data-acp-dialog-type={dialog?.type}
|
|
360
|
+
data-acp-variant={dialog?.variant}
|
|
361
|
+
data-acp-is-pending={isPending}
|
|
362
|
+
>
|
|
363
|
+
<Button
|
|
364
|
+
class={_buttonClass}
|
|
365
|
+
on:click={async (e) => {
|
|
366
|
+
e.preventDefault();
|
|
367
|
+
isPending = true;
|
|
368
|
+
await Promise.resolve(dialog.onCancel(false));
|
|
369
|
+
isPending = false;
|
|
370
|
+
value = null;
|
|
371
|
+
}}
|
|
372
|
+
type="reset"
|
|
373
|
+
data-acp-button-type="cancel"
|
|
374
|
+
data-acp-dialog-type={dialog?.type}
|
|
375
|
+
data-acp-variant={dialog?.variant}
|
|
376
|
+
data-acp-is-pending={isPending}
|
|
377
|
+
disabled={isPending}
|
|
378
|
+
>
|
|
379
|
+
<Thc thc={dialog.labelCancel} />
|
|
380
|
+
</Button>
|
|
381
|
+
</li>
|
|
382
|
+
{/if}
|
|
383
|
+
{#if dialog.labelCustom && _isFn(dialog.onCustom)}
|
|
384
|
+
<li
|
|
385
|
+
class={_menuLiClass}
|
|
386
|
+
data-acp-dialog-type={dialog?.type}
|
|
387
|
+
data-acp-variant={dialog?.variant}
|
|
388
|
+
data-acp-is-pending={isPending}
|
|
389
|
+
>
|
|
390
|
+
<Button
|
|
391
|
+
class={_buttonClass}
|
|
392
|
+
on:click={async (e) => {
|
|
393
|
+
e.preventDefault();
|
|
394
|
+
isPending = true;
|
|
395
|
+
await Promise.resolve(dialog.onCustom(value));
|
|
396
|
+
isPending = false;
|
|
397
|
+
value = null;
|
|
398
|
+
}}
|
|
399
|
+
type="button"
|
|
400
|
+
data-acp-button-type="custom"
|
|
401
|
+
data-acp-dialog-type={dialog?.type}
|
|
402
|
+
data-acp-variant={dialog?.variant}
|
|
403
|
+
data-acp-is-pending={isPending}
|
|
404
|
+
disabled={isPending}
|
|
405
|
+
>
|
|
406
|
+
<Thc thc={dialog.labelCustom} />
|
|
407
|
+
</Button>
|
|
408
|
+
</li>
|
|
409
|
+
{/if}
|
|
410
|
+
<li
|
|
411
|
+
class={_menuLiClass}
|
|
412
|
+
data-acp-type={dialog?.type}
|
|
413
|
+
data-acp-variant={dialog?.variant}
|
|
414
|
+
data-acp-is-pending={isPending}
|
|
415
|
+
>
|
|
416
|
+
<Button
|
|
417
|
+
class={_buttonClass}
|
|
418
|
+
type="submit"
|
|
419
|
+
value="OK"
|
|
420
|
+
data-acp-button-type="ok"
|
|
421
|
+
data-acp-dialog-type={dialog?.type}
|
|
422
|
+
data-acp-variant={dialog?.variant}
|
|
423
|
+
data-acp-is-pending={isPending}
|
|
424
|
+
on:click={async (e) => {
|
|
425
|
+
e.preventDefault();
|
|
426
|
+
isPending = true;
|
|
427
|
+
await Promise.resolve(dialog.onOk(dialog.type === PROMPT ? value : true));
|
|
428
|
+
isPending = false;
|
|
429
|
+
value = null;
|
|
430
|
+
}}
|
|
431
|
+
disabled={isPending}
|
|
432
|
+
variant="primary"
|
|
433
|
+
>
|
|
434
|
+
<Thc thc={dialog.labelOk} />
|
|
435
|
+
</Button>
|
|
436
|
+
</li>
|
|
437
|
+
</menu>
|
|
438
|
+
{#if isPending}
|
|
439
|
+
<div
|
|
440
|
+
class={_spinnerBoxClass}
|
|
441
|
+
data-acp-type={dialog?.type}
|
|
442
|
+
data-acp-variant={dialog?.variant}
|
|
443
|
+
>
|
|
444
|
+
<div class="rotating-cw">
|
|
445
|
+
{@html acpDefaultIcons.spinner()}
|
|
446
|
+
</div>
|
|
447
|
+
</div>
|
|
448
|
+
{/if}
|
|
449
|
+
</form>
|
|
450
|
+
{/if}
|
|
451
|
+
</dialog>
|
|
452
|
+
|
|
453
|
+
<style>@keyframes -global-rotating-cw {
|
|
454
|
+
from {
|
|
455
|
+
transform: rotate(0deg);
|
|
456
|
+
}
|
|
457
|
+
to {
|
|
458
|
+
transform: rotate(360deg);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
.rotating-cw {
|
|
462
|
+
animation: rotating-cw 0.6s linear infinite;
|
|
463
|
+
}</style>
|