@marianmeres/stuic 1.20.0 → 1.22.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/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 +465 -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 +19 -10
- 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,104 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import { createAlertConfirmPromptStore } from '../../index.js';
|
|
3
|
+
export declare class AlertConfirmPromptConfig {
|
|
4
|
+
static preset: {
|
|
5
|
+
dialog: string;
|
|
6
|
+
icon: string;
|
|
7
|
+
contentBlock: string;
|
|
8
|
+
title: string;
|
|
9
|
+
content: string;
|
|
10
|
+
inputBox: string;
|
|
11
|
+
inputField: string;
|
|
12
|
+
menu: string;
|
|
13
|
+
menuLi: string;
|
|
14
|
+
button: string;
|
|
15
|
+
spinnerBox: string;
|
|
16
|
+
};
|
|
17
|
+
static classDialog: string;
|
|
18
|
+
static classIcon: string;
|
|
19
|
+
static classTitle: string;
|
|
20
|
+
static classContentBlock: string;
|
|
21
|
+
static classContent: string;
|
|
22
|
+
static classInputBox: string;
|
|
23
|
+
static classInputField: string;
|
|
24
|
+
static classMenu: string;
|
|
25
|
+
static classMenuLi: string;
|
|
26
|
+
static classButton: string;
|
|
27
|
+
static classSpinnerBox: string;
|
|
28
|
+
static variant: {
|
|
29
|
+
info: {
|
|
30
|
+
dialog: string;
|
|
31
|
+
icon: string;
|
|
32
|
+
contentBlock: string;
|
|
33
|
+
title: string;
|
|
34
|
+
content: string;
|
|
35
|
+
inputBox: string;
|
|
36
|
+
inputField: string;
|
|
37
|
+
menu: string;
|
|
38
|
+
menuLi: string;
|
|
39
|
+
button: string;
|
|
40
|
+
spinnerBox: string;
|
|
41
|
+
};
|
|
42
|
+
success: {
|
|
43
|
+
dialog: string;
|
|
44
|
+
icon: string;
|
|
45
|
+
contentBlock: string;
|
|
46
|
+
title: string;
|
|
47
|
+
content: string;
|
|
48
|
+
inputBox: string;
|
|
49
|
+
inputField: string;
|
|
50
|
+
menu: string;
|
|
51
|
+
menuLi: string;
|
|
52
|
+
button: string;
|
|
53
|
+
spinnerBox: string;
|
|
54
|
+
};
|
|
55
|
+
warn: {
|
|
56
|
+
dialog: string;
|
|
57
|
+
icon: string;
|
|
58
|
+
contentBlock: string;
|
|
59
|
+
title: string;
|
|
60
|
+
content: string;
|
|
61
|
+
inputBox: string;
|
|
62
|
+
inputField: string;
|
|
63
|
+
menu: string;
|
|
64
|
+
menuLi: string;
|
|
65
|
+
button: string;
|
|
66
|
+
spinnerBox: string;
|
|
67
|
+
};
|
|
68
|
+
error: {
|
|
69
|
+
dialog: string;
|
|
70
|
+
icon: string;
|
|
71
|
+
contentBlock: string;
|
|
72
|
+
title: string;
|
|
73
|
+
content: string;
|
|
74
|
+
inputBox: string;
|
|
75
|
+
inputField: string;
|
|
76
|
+
menu: string;
|
|
77
|
+
menuLi: string;
|
|
78
|
+
button: string;
|
|
79
|
+
spinnerBox: string;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
static iconFn: {
|
|
83
|
+
info: undefined;
|
|
84
|
+
success: undefined;
|
|
85
|
+
warn: undefined;
|
|
86
|
+
error: undefined;
|
|
87
|
+
spinner: undefined;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
declare const __propDef: {
|
|
91
|
+
props: {
|
|
92
|
+
acp: ReturnType<typeof createAlertConfirmPromptStore>;
|
|
93
|
+
};
|
|
94
|
+
events: {
|
|
95
|
+
[evt: string]: CustomEvent<any>;
|
|
96
|
+
};
|
|
97
|
+
slots: {};
|
|
98
|
+
};
|
|
99
|
+
export type AlertConfirmPromptProps = typeof __propDef.props;
|
|
100
|
+
export type AlertConfirmPromptEvents = typeof __propDef.events;
|
|
101
|
+
export type AlertConfirmPromptSlots = typeof __propDef.slots;
|
|
102
|
+
export default class AlertConfirmPrompt extends SvelteComponent<AlertConfirmPromptProps, AlertConfirmPromptEvents, AlertConfirmPromptSlots> {
|
|
103
|
+
}
|
|
104
|
+
export {};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// taken from @marianmeres/icons-fns
|
|
2
|
+
function iconFeatherAlertCircle(props) {
|
|
3
|
+
// Backward compatible signature support: fn(cls, size, style)
|
|
4
|
+
if (props === null || props === undefined)
|
|
5
|
+
props = {};
|
|
6
|
+
if (typeof props !== 'object')
|
|
7
|
+
props = { class: props || '' };
|
|
8
|
+
if (arguments.length > 1)
|
|
9
|
+
props.size ??= arguments[1];
|
|
10
|
+
if (arguments.length > 2)
|
|
11
|
+
props.style ??= arguments[2];
|
|
12
|
+
//
|
|
13
|
+
const { size, class: cls, style, strokeWidth } = props;
|
|
14
|
+
let attrs = Object.entries(props)
|
|
15
|
+
.filter(([k, v]) => !/^class|size|style|strokeWidth$/.test(k))
|
|
16
|
+
.reduce((m, [k, v]) => [...m, `${k}="${v}"`], [])
|
|
17
|
+
.join(' ');
|
|
18
|
+
return `<svg ${style ? `style="${style}" ` : ''}${cls ? `class="${cls}" ` : ''}width="${size || 24}" height="${size || 24}" stroke-width="${strokeWidth ?? 2}" ${attrs ? `${attrs} ` : ''}viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>`;
|
|
19
|
+
}
|
|
20
|
+
function iconFeatherCheckCircle(props) {
|
|
21
|
+
// Backward compatible signature support: fn(cls, size, style)
|
|
22
|
+
if (props === null || props === undefined)
|
|
23
|
+
props = {};
|
|
24
|
+
if (typeof props !== 'object')
|
|
25
|
+
props = { class: props || '' };
|
|
26
|
+
if (arguments.length > 1)
|
|
27
|
+
props.size ??= arguments[1];
|
|
28
|
+
if (arguments.length > 2)
|
|
29
|
+
props.style ??= arguments[2];
|
|
30
|
+
//
|
|
31
|
+
const { size, class: cls, style, strokeWidth } = props;
|
|
32
|
+
let attrs = Object.entries(props)
|
|
33
|
+
.filter(([k, v]) => !/^class|size|style|strokeWidth$/.test(k))
|
|
34
|
+
.reduce((m, [k, v]) => [...m, `${k}="${v}"`], [])
|
|
35
|
+
.join(' ');
|
|
36
|
+
return `<svg ${style ? `style="${style}" ` : ''}${cls ? `class="${cls}" ` : ''}width="${size || 24}" height="${size || 24}" stroke-width="${strokeWidth ?? 2}" ${attrs ? `${attrs} ` : ''}viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>`;
|
|
37
|
+
}
|
|
38
|
+
function iconFeatherHelpCircle(props) {
|
|
39
|
+
// Backward compatible signature support: fn(cls, size, style)
|
|
40
|
+
if (props === null || props === undefined)
|
|
41
|
+
props = {};
|
|
42
|
+
if (typeof props !== 'object')
|
|
43
|
+
props = { class: props || '' };
|
|
44
|
+
if (arguments.length > 1)
|
|
45
|
+
props.size ??= arguments[1];
|
|
46
|
+
if (arguments.length > 2)
|
|
47
|
+
props.style ??= arguments[2];
|
|
48
|
+
//
|
|
49
|
+
const { size, class: cls, style, strokeWidth } = props;
|
|
50
|
+
let attrs = Object.entries(props)
|
|
51
|
+
.filter(([k, v]) => !/^class|size|style|strokeWidth$/.test(k))
|
|
52
|
+
.reduce((m, [k, v]) => [...m, `${k}="${v}"`], [])
|
|
53
|
+
.join(' ');
|
|
54
|
+
return `<svg ${style ? `style="${style}" ` : ''}${cls ? `class="${cls}" ` : ''}width="${size || 24}" height="${size || 24}" stroke-width="${strokeWidth ?? 2}" ${attrs ? `${attrs} ` : ''}viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>`;
|
|
55
|
+
}
|
|
56
|
+
function iconFeatherXCircle(props) {
|
|
57
|
+
// Backward compatible signature support: fn(cls, size, style)
|
|
58
|
+
if (props === null || props === undefined)
|
|
59
|
+
props = {};
|
|
60
|
+
if (typeof props !== 'object')
|
|
61
|
+
props = { class: props || '' };
|
|
62
|
+
if (arguments.length > 1)
|
|
63
|
+
props.size ??= arguments[1];
|
|
64
|
+
if (arguments.length > 2)
|
|
65
|
+
props.style ??= arguments[2];
|
|
66
|
+
//
|
|
67
|
+
const { size, class: cls, style, strokeWidth } = props;
|
|
68
|
+
let attrs = Object.entries(props)
|
|
69
|
+
.filter(([k, v]) => !/^class|size|style|strokeWidth$/.test(k))
|
|
70
|
+
.reduce((m, [k, v]) => [...m, `${k}="${v}"`], [])
|
|
71
|
+
.join(' ');
|
|
72
|
+
return `<svg ${style ? `style="${style}" ` : ''}${cls ? `class="${cls}" ` : ''}width="${size || 24}" height="${size || 24}" stroke-width="${strokeWidth ?? 2}" ${attrs ? `${attrs} ` : ''}viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg>`;
|
|
73
|
+
}
|
|
74
|
+
function iconFeatherXOctagon(props) {
|
|
75
|
+
// Backward compatible signature support: fn(cls, size, style)
|
|
76
|
+
if (props === null || props === undefined)
|
|
77
|
+
props = {};
|
|
78
|
+
if (typeof props !== 'object')
|
|
79
|
+
props = { class: props || '' };
|
|
80
|
+
if (arguments.length > 1)
|
|
81
|
+
props.size ??= arguments[1];
|
|
82
|
+
if (arguments.length > 2)
|
|
83
|
+
props.style ??= arguments[2];
|
|
84
|
+
//
|
|
85
|
+
const { size, class: cls, style, strokeWidth } = props;
|
|
86
|
+
let attrs = Object.entries(props)
|
|
87
|
+
.filter(([k, v]) => !/^class|size|style|strokeWidth$/.test(k))
|
|
88
|
+
.reduce((m, [k, v]) => [...m, `${k}="${v}"`], [])
|
|
89
|
+
.join(' ');
|
|
90
|
+
return `<svg ${style ? `style="${style}" ` : ''}${cls ? `class="${cls}" ` : ''}width="${size || 24}" height="${size || 24}" stroke-width="${strokeWidth ?? 2}" ${attrs ? `${attrs} ` : ''}viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg>`;
|
|
91
|
+
}
|
|
92
|
+
function iconFeatherInfo(props) {
|
|
93
|
+
// Backward compatible signature support: fn(cls, size, style)
|
|
94
|
+
if (props === null || props === undefined)
|
|
95
|
+
props = {};
|
|
96
|
+
if (typeof props !== 'object')
|
|
97
|
+
props = { class: props || '' };
|
|
98
|
+
if (arguments.length > 1)
|
|
99
|
+
props.size ??= arguments[1];
|
|
100
|
+
if (arguments.length > 2)
|
|
101
|
+
props.style ??= arguments[2];
|
|
102
|
+
//
|
|
103
|
+
const { size, class: cls, style, strokeWidth } = props;
|
|
104
|
+
let attrs = Object.entries(props)
|
|
105
|
+
.filter(([k, v]) => !/^class|size|style|strokeWidth$/.test(k))
|
|
106
|
+
.reduce((m, [k, v]) => [...m, `${k}="${v}"`], [])
|
|
107
|
+
.join(' ');
|
|
108
|
+
return `<svg ${style ? `style="${style}" ` : ''}${cls ? `class="${cls}" ` : ''}width="${size || 24}" height="${size || 24}" stroke-width="${strokeWidth ?? 2}" ${attrs ? `${attrs} ` : ''}viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>`;
|
|
109
|
+
}
|
|
110
|
+
function iconFeatherRotateCw(props) {
|
|
111
|
+
// Backward compatible signature support: fn(cls, size, style)
|
|
112
|
+
if (props === null || props === undefined)
|
|
113
|
+
props = {};
|
|
114
|
+
if (typeof props !== 'object')
|
|
115
|
+
props = { class: props || '' };
|
|
116
|
+
if (arguments.length > 1)
|
|
117
|
+
props.size ??= arguments[1];
|
|
118
|
+
if (arguments.length > 2)
|
|
119
|
+
props.style ??= arguments[2];
|
|
120
|
+
//
|
|
121
|
+
const { size, class: cls, style, strokeWidth } = props;
|
|
122
|
+
let attrs = Object.entries(props)
|
|
123
|
+
.filter(([k, v]) => !/^class|size|style|strokeWidth$/.test(k))
|
|
124
|
+
.reduce((m, [k, v]) => [...m, `${k}="${v}"`], [])
|
|
125
|
+
.join(' ');
|
|
126
|
+
return `<svg ${style ? `style="${style}" ` : ''}${cls ? `class="${cls}" ` : ''}width="${size || 24}" height="${size || 24}" stroke-width="${strokeWidth ?? 2}" ${attrs ? `${attrs} ` : ''}viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path></svg>`;
|
|
127
|
+
}
|
|
128
|
+
export const acpDefaultIcons = {
|
|
129
|
+
info: () => iconFeatherInfo({}),
|
|
130
|
+
success: () => iconFeatherCheckCircle({}),
|
|
131
|
+
warn: () => iconFeatherAlertCircle({}),
|
|
132
|
+
error: () => iconFeatherXOctagon({}),
|
|
133
|
+
spinner: () => iconFeatherRotateCw({ size: 32, class: 'opacity-75', strokeWidth: 1.5 }),
|
|
134
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { THC } from '../Thc/Thc.svelte';
|
|
2
|
+
export declare enum AlertConfirmPromptType {
|
|
3
|
+
ALERT = "alert",
|
|
4
|
+
CONFIRM = "confirm",
|
|
5
|
+
PROMPT = "prompt"
|
|
6
|
+
}
|
|
7
|
+
export type AlertConfirmPromptVariant = 'info' | 'success' | 'warn' | 'error';
|
|
8
|
+
type FnOnOK = (value: any) => any;
|
|
9
|
+
type FnOnCancel = (value: false) => any;
|
|
10
|
+
type FnOnEscape = () => undefined;
|
|
11
|
+
type FnOnCustom = (value: any) => any;
|
|
12
|
+
interface Dialog extends Record<string, any> {
|
|
13
|
+
type: AlertConfirmPromptType.ALERT | AlertConfirmPromptType.CONFIRM | AlertConfirmPromptType.PROMPT;
|
|
14
|
+
title: THC;
|
|
15
|
+
content: THC;
|
|
16
|
+
value: any;
|
|
17
|
+
labelOk: THC;
|
|
18
|
+
onOk: FnOnOK;
|
|
19
|
+
labelCancel: THC;
|
|
20
|
+
onCancel: FnOnCancel;
|
|
21
|
+
onEscape: FnOnEscape;
|
|
22
|
+
labelCustom?: THC;
|
|
23
|
+
onCustom?: FnOnCustom;
|
|
24
|
+
variant: AlertConfirmPromptVariant;
|
|
25
|
+
iconFn: (() => string) | boolean;
|
|
26
|
+
class?: Partial<{
|
|
27
|
+
dialog: string;
|
|
28
|
+
icon: string;
|
|
29
|
+
contentBlock: string;
|
|
30
|
+
title: string;
|
|
31
|
+
content: string;
|
|
32
|
+
inputBox: string;
|
|
33
|
+
inputField: string;
|
|
34
|
+
menu: string;
|
|
35
|
+
menuLi: string;
|
|
36
|
+
button: string;
|
|
37
|
+
spinnerBox: string;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
export declare const createAlertConfirmPromptStore: () => {
|
|
41
|
+
subscribe: (cb: import("@marianmeres/store").Subscribe<Dialog[]>) => import("@marianmeres/store").Unsubscribe;
|
|
42
|
+
get: () => Dialog[];
|
|
43
|
+
push: (o: Partial<Dialog>) => void;
|
|
44
|
+
shift: () => void;
|
|
45
|
+
reset: (stack?: Dialog[]) => void;
|
|
46
|
+
escape: () => void;
|
|
47
|
+
close: () => void;
|
|
48
|
+
alert: (o?: Partial<Dialog> | string) => void;
|
|
49
|
+
confirm: (onOk: FnOnOK, o?: Partial<Dialog>) => void;
|
|
50
|
+
prompt: (onOk: FnOnOK, o?: Partial<Dialog>) => void;
|
|
51
|
+
};
|
|
52
|
+
export declare const createAlert: (acp: ReturnType<typeof createAlertConfirmPromptStore>) => (message: string, o?: Partial<Dialog>) => Promise<unknown>;
|
|
53
|
+
export declare const createConfirm: (acp: ReturnType<typeof createAlertConfirmPromptStore>) => (message: string, o?: Partial<Dialog>) => Promise<unknown>;
|
|
54
|
+
export declare const createPrompt: (acp: ReturnType<typeof createAlertConfirmPromptStore>) => (message: string, defaultValue?: string, o?: Partial<Dialog>) => Promise<unknown>;
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { createStore } from '@marianmeres/store';
|
|
2
|
+
import { createClog } from '@marianmeres/clog';
|
|
3
|
+
const clog = createClog('alert-confirm-prompt');
|
|
4
|
+
export var AlertConfirmPromptType;
|
|
5
|
+
(function (AlertConfirmPromptType) {
|
|
6
|
+
AlertConfirmPromptType["ALERT"] = "alert";
|
|
7
|
+
AlertConfirmPromptType["CONFIRM"] = "confirm";
|
|
8
|
+
AlertConfirmPromptType["PROMPT"] = "prompt";
|
|
9
|
+
})(AlertConfirmPromptType || (AlertConfirmPromptType = {}));
|
|
10
|
+
const isFn = (v) => typeof v === 'function';
|
|
11
|
+
const ucf = (s) => `${s}`[0].toUpperCase() + `${s}`.slice(1);
|
|
12
|
+
export const createAlertConfirmPromptStore = () => {
|
|
13
|
+
// fifo
|
|
14
|
+
const _stack = createStore([]);
|
|
15
|
+
// defaults
|
|
16
|
+
const labelOk = 'OK';
|
|
17
|
+
const labelCancel = 'Cancel';
|
|
18
|
+
// optional 3rd button label
|
|
19
|
+
const labelCustom = undefined;
|
|
20
|
+
const push = (o) => {
|
|
21
|
+
if (!isFn(o.onOk))
|
|
22
|
+
o.onOk = shift;
|
|
23
|
+
if (!isFn(o.onCancel))
|
|
24
|
+
o.onCancel = shift;
|
|
25
|
+
if (!isFn(o.onEscape))
|
|
26
|
+
o.onEscape = () => undefined;
|
|
27
|
+
if (o.labelOk === undefined)
|
|
28
|
+
o.labelOk = labelOk;
|
|
29
|
+
if (o.labelCancel === undefined)
|
|
30
|
+
o.labelCancel = labelCancel;
|
|
31
|
+
if (o.title === undefined)
|
|
32
|
+
o.title = ucf(o.type);
|
|
33
|
+
// variant defaults to info
|
|
34
|
+
if (!['info', 'success', 'warn', 'error'].includes(o?.variant)) {
|
|
35
|
+
o.variant = 'info';
|
|
36
|
+
}
|
|
37
|
+
if (o.iconFn === undefined)
|
|
38
|
+
o.iconFn = true; // will use default
|
|
39
|
+
// 3rd label may stay undefined
|
|
40
|
+
if (!isFn(o.onCustom))
|
|
41
|
+
o.onCustom = () => undefined;
|
|
42
|
+
//
|
|
43
|
+
_stack.update((old) => [...old, o]);
|
|
44
|
+
};
|
|
45
|
+
const shift = () => _stack.update((old) => {
|
|
46
|
+
old.shift();
|
|
47
|
+
return [...old];
|
|
48
|
+
});
|
|
49
|
+
const reset = (stack = []) => _stack.set(stack);
|
|
50
|
+
const escape = () => {
|
|
51
|
+
if (_stack.get().length)
|
|
52
|
+
_stack.get()[0].onEscape();
|
|
53
|
+
shift();
|
|
54
|
+
};
|
|
55
|
+
return {
|
|
56
|
+
subscribe: _stack.subscribe,
|
|
57
|
+
get: _stack.get,
|
|
58
|
+
push,
|
|
59
|
+
shift,
|
|
60
|
+
reset,
|
|
61
|
+
escape,
|
|
62
|
+
// human alias
|
|
63
|
+
close: shift,
|
|
64
|
+
// sugar below
|
|
65
|
+
//
|
|
66
|
+
alert: (o) => {
|
|
67
|
+
if (typeof o === 'string')
|
|
68
|
+
o = { title: o };
|
|
69
|
+
push({ ...(o || {}), type: AlertConfirmPromptType.ALERT });
|
|
70
|
+
},
|
|
71
|
+
//
|
|
72
|
+
confirm: (onOk, o) => push({ onOk, value: false, ...o, type: AlertConfirmPromptType.CONFIRM }),
|
|
73
|
+
//
|
|
74
|
+
prompt: (onOk, o) => push({ onOk, value: '', ...o, type: AlertConfirmPromptType.PROMPT }),
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
// sugar helpers to patch the native window.alert/confirm/prompt
|
|
78
|
+
export const createAlert = (acp) =>
|
|
79
|
+
// allowing to add the custom param outside of the native signature
|
|
80
|
+
(message, o) => new Promise((resolve) => acp.alert({
|
|
81
|
+
onOk: () => {
|
|
82
|
+
acp.close();
|
|
83
|
+
resolve(undefined);
|
|
84
|
+
},
|
|
85
|
+
content: message,
|
|
86
|
+
onEscape: () => {
|
|
87
|
+
acp.close();
|
|
88
|
+
resolve(undefined);
|
|
89
|
+
},
|
|
90
|
+
...(o || {}),
|
|
91
|
+
}));
|
|
92
|
+
export const createConfirm = (acp) =>
|
|
93
|
+
// allowing to add the custom param outside of the native signature
|
|
94
|
+
(message, o) => new Promise((resolve) => acp.confirm(() => {
|
|
95
|
+
acp.close();
|
|
96
|
+
resolve(true);
|
|
97
|
+
}, {
|
|
98
|
+
content: message,
|
|
99
|
+
onCancel: () => {
|
|
100
|
+
acp.close();
|
|
101
|
+
resolve(false);
|
|
102
|
+
},
|
|
103
|
+
onEscape: () => {
|
|
104
|
+
acp.close();
|
|
105
|
+
resolve(false);
|
|
106
|
+
},
|
|
107
|
+
...(o || {}),
|
|
108
|
+
}));
|
|
109
|
+
export const createPrompt = (acp) =>
|
|
110
|
+
// allowing to add the custom param outside of the native signature
|
|
111
|
+
(message, defaultValue = '', o) => new Promise((resolve) => acp.prompt((value) => {
|
|
112
|
+
acp.close();
|
|
113
|
+
resolve(value);
|
|
114
|
+
}, {
|
|
115
|
+
content: message,
|
|
116
|
+
value: defaultValue,
|
|
117
|
+
onCancel: () => {
|
|
118
|
+
acp.close();
|
|
119
|
+
resolve(null);
|
|
120
|
+
},
|
|
121
|
+
onEscape: () => {
|
|
122
|
+
acp.close();
|
|
123
|
+
resolve(null);
|
|
124
|
+
},
|
|
125
|
+
...(o || {}),
|
|
126
|
+
}));
|
|
@@ -48,7 +48,16 @@ export class ButtonConfig {
|
|
|
48
48
|
};
|
|
49
49
|
static class = "";
|
|
50
50
|
// to be defined at consumer level...
|
|
51
|
-
static variant = {
|
|
51
|
+
static variant = {
|
|
52
|
+
// primary: `
|
|
53
|
+
// bg-[rgb(var(--primary))] text-[rgb(var(--on-primary))]
|
|
54
|
+
// dark:bg-[rgb(var(--primary-dark))] dark:text-[rgb(var(--on-primary-dark))]
|
|
55
|
+
// `.trim(),
|
|
56
|
+
primary: `
|
|
57
|
+
bg-primary text-on-primary
|
|
58
|
+
dark:bg-primary-dark dark:text-on-primary-dark
|
|
59
|
+
`.trim()
|
|
60
|
+
};
|
|
52
61
|
}
|
|
53
62
|
</script>
|
|
54
63
|
|
|
@@ -85,7 +94,7 @@ $:
|
|
|
85
94
|
variant && `${variant || ""}`.split(" ").reduce((m, v) => {
|
|
86
95
|
m += ButtonConfig.variant?.[v] + " ";
|
|
87
96
|
return m;
|
|
88
|
-
}, ""),
|
|
97
|
+
}, " "),
|
|
89
98
|
//
|
|
90
99
|
square && ButtonConfig.presetSquare,
|
|
91
100
|
//
|
|
@@ -99,10 +108,10 @@ $:
|
|
|
99
108
|
class={buttonClass}
|
|
100
109
|
{...$$restProps}
|
|
101
110
|
role="button"
|
|
102
|
-
data-size={size}
|
|
103
|
-
data-shadow={shadow}
|
|
104
|
-
data-rounded={rounded}
|
|
105
|
-
data-variant={variant}
|
|
111
|
+
data-button-size={size}
|
|
112
|
+
data-button-shadow={shadow}
|
|
113
|
+
data-button-rounded={rounded}
|
|
114
|
+
data-button-variant={variant}
|
|
106
115
|
on:click
|
|
107
116
|
on:change
|
|
108
117
|
on:keydown
|
|
@@ -121,10 +130,10 @@ $:
|
|
|
121
130
|
{disabled}
|
|
122
131
|
class={buttonClass}
|
|
123
132
|
{value}
|
|
124
|
-
data-size={size}
|
|
125
|
-
data-shadow={shadow}
|
|
126
|
-
data-rounded={rounded}
|
|
127
|
-
data-variant={variant}
|
|
133
|
+
data-button-size={size}
|
|
134
|
+
data-button-shadow={shadow}
|
|
135
|
+
data-button-rounded={rounded}
|
|
136
|
+
data-button-variant={variant}
|
|
128
137
|
{...$$restProps}
|
|
129
138
|
on:click
|
|
130
139
|
on:change
|
|
@@ -50,7 +50,7 @@ declare const __propDef: {
|
|
|
50
50
|
square?: boolean | undefined;
|
|
51
51
|
disabled?: boolean | undefined;
|
|
52
52
|
value?: string | undefined;
|
|
53
|
-
size?: "
|
|
53
|
+
size?: "sm" | "md" | "lg" | "xs" | "xl" | undefined;
|
|
54
54
|
};
|
|
55
55
|
events: {
|
|
56
56
|
click: MouseEvent;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
<script>import { slide } from "svelte/transition";
|
|
2
|
+
import { twMerge } from "tailwind-merge";
|
|
3
|
+
import {
|
|
4
|
+
autogrow,
|
|
5
|
+
getId,
|
|
6
|
+
trim,
|
|
7
|
+
validate as validateAction
|
|
8
|
+
} from "../../index.js";
|
|
9
|
+
import { createEventDispatcher } from "svelte";
|
|
10
|
+
const dispatch = createEventDispatcher();
|
|
11
|
+
const setType = (el, t) => el.type = t;
|
|
12
|
+
const inputSizePreset = {
|
|
13
|
+
sm: "text-sm placeholder:text-sm",
|
|
14
|
+
md: "text-base placeholder:text-base",
|
|
15
|
+
lg: "text-lg placeholder:text-lg"
|
|
16
|
+
};
|
|
17
|
+
const labelSizePreset = {
|
|
18
|
+
sm: "text-sm",
|
|
19
|
+
md: "text-base",
|
|
20
|
+
lg: "text-base font-bold"
|
|
21
|
+
};
|
|
22
|
+
let _class = "";
|
|
23
|
+
export { _class as class };
|
|
24
|
+
export let labelClass = "";
|
|
25
|
+
export let wrapClass = "";
|
|
26
|
+
export let textareaClass = "";
|
|
27
|
+
export let invalidClass = "border-primary";
|
|
28
|
+
export let size = "md";
|
|
29
|
+
export let id = getId();
|
|
30
|
+
export let value;
|
|
31
|
+
export let label = "";
|
|
32
|
+
export let type = "text";
|
|
33
|
+
export let name = "";
|
|
34
|
+
export let tabindex = 0;
|
|
35
|
+
export let description = "";
|
|
36
|
+
export let descriptionClass = "";
|
|
37
|
+
export let disabled = false;
|
|
38
|
+
export let readonly = false;
|
|
39
|
+
export let required = false;
|
|
40
|
+
export let placeholder = void 0;
|
|
41
|
+
export let autocomplete = void 0;
|
|
42
|
+
export let minlength = void 0;
|
|
43
|
+
export let maxlength = void 0;
|
|
44
|
+
export let min = void 0;
|
|
45
|
+
export let max = void 0;
|
|
46
|
+
export let pattern = void 0;
|
|
47
|
+
export let step = void 0;
|
|
48
|
+
export let useTrim = true;
|
|
49
|
+
export let textareaAutoEnlarge = true;
|
|
50
|
+
export let validationMessageClass = "";
|
|
51
|
+
export let validate = void 0;
|
|
52
|
+
let validation;
|
|
53
|
+
const setValidationResult = (res) => validation = res;
|
|
54
|
+
let _inputEl;
|
|
55
|
+
$:
|
|
56
|
+
if (_inputEl)
|
|
57
|
+
dispatch("input_mounted", _inputEl);
|
|
58
|
+
$:
|
|
59
|
+
inputClass = twMerge(`
|
|
60
|
+
form-input
|
|
61
|
+
rounded-md border-0 w-full flex-1
|
|
62
|
+
bg-transparent
|
|
63
|
+
tracking-tight
|
|
64
|
+
focus:outline-0 focus-visible:ring-0
|
|
65
|
+
placeholder:text-black/35 placeholder:tracking-tight
|
|
66
|
+
${inputSizePreset[size]}
|
|
67
|
+
`);
|
|
68
|
+
</script>
|
|
69
|
+
|
|
70
|
+
<div class={twMerge(`mb-4 ${_class}`)}>
|
|
71
|
+
<div class="flex items-end px-2 mb-1">
|
|
72
|
+
{#if label || $$slots.label}
|
|
73
|
+
<label
|
|
74
|
+
for={id}
|
|
75
|
+
class={twMerge(`
|
|
76
|
+
block flex-1
|
|
77
|
+
${required ? "after:content-['*'] after:opacity-30 after:pl-1" : ''}
|
|
78
|
+
${labelSizePreset[size]}
|
|
79
|
+
${labelClass}
|
|
80
|
+
`)}
|
|
81
|
+
class:required
|
|
82
|
+
>
|
|
83
|
+
{#if $$slots.label}
|
|
84
|
+
<slot name="label" />
|
|
85
|
+
{:else}
|
|
86
|
+
{@html label}
|
|
87
|
+
{/if}
|
|
88
|
+
</label>
|
|
89
|
+
{/if}
|
|
90
|
+
<slot name="right_of_label" />
|
|
91
|
+
</div>
|
|
92
|
+
<div
|
|
93
|
+
class={twMerge(`
|
|
94
|
+
rounded-md border border-gray-300
|
|
95
|
+
bg-gray-100
|
|
96
|
+
focus-within:border-primary
|
|
97
|
+
focus-within:ring-4
|
|
98
|
+
focus-within:ring-primary
|
|
99
|
+
focus-within:ring-opacity-20
|
|
100
|
+
${wrapClass}
|
|
101
|
+
${validation && !validation.valid ? invalidClass : ''}
|
|
102
|
+
`)}
|
|
103
|
+
class:cursor-not-allowed={disabled}
|
|
104
|
+
class:opacity-50={disabled}
|
|
105
|
+
>
|
|
106
|
+
<div class="flex items-center">
|
|
107
|
+
<slot name="input_before" {id} />
|
|
108
|
+
{#if type === 'textarea'}
|
|
109
|
+
<textarea
|
|
110
|
+
bind:value
|
|
111
|
+
bind:this={_inputEl}
|
|
112
|
+
{id}
|
|
113
|
+
class={twMerge(`${inputClass} min-h-16 ${textareaClass}`)}
|
|
114
|
+
class:cursor-not-allowed={disabled}
|
|
115
|
+
{name}
|
|
116
|
+
{disabled}
|
|
117
|
+
{readonly}
|
|
118
|
+
{required}
|
|
119
|
+
{tabindex}
|
|
120
|
+
use:trim={useTrim}
|
|
121
|
+
use:validateAction={validate
|
|
122
|
+
? { ...(validate === true ? {} : validate), setValidationResult }
|
|
123
|
+
: undefined}
|
|
124
|
+
use:autogrow={{ allowed: textareaAutoEnlarge }}
|
|
125
|
+
{...$$restProps}
|
|
126
|
+
></textarea>
|
|
127
|
+
{:else}
|
|
128
|
+
<input
|
|
129
|
+
bind:value
|
|
130
|
+
bind:this={_inputEl}
|
|
131
|
+
use:setType={type}
|
|
132
|
+
{id}
|
|
133
|
+
class={inputClass}
|
|
134
|
+
class:cursor-not-allowed={disabled}
|
|
135
|
+
{name}
|
|
136
|
+
{placeholder}
|
|
137
|
+
{disabled}
|
|
138
|
+
{readonly}
|
|
139
|
+
{required}
|
|
140
|
+
{autocomplete}
|
|
141
|
+
{tabindex}
|
|
142
|
+
{minlength}
|
|
143
|
+
{maxlength}
|
|
144
|
+
{min}
|
|
145
|
+
{max}
|
|
146
|
+
{pattern}
|
|
147
|
+
{step}
|
|
148
|
+
use:trim={useTrim}
|
|
149
|
+
use:validateAction={validate
|
|
150
|
+
? { ...(validate === true ? {} : validate), setValidationResult }
|
|
151
|
+
: undefined}
|
|
152
|
+
{...$$restProps}
|
|
153
|
+
/>
|
|
154
|
+
{/if}
|
|
155
|
+
<slot name="input_after" {id} />
|
|
156
|
+
</div>
|
|
157
|
+
<slot name="input_below" {id} />
|
|
158
|
+
</div>
|
|
159
|
+
{#if validation && !validation?.valid}
|
|
160
|
+
<div
|
|
161
|
+
transition:slide={{ duration: 150 }}
|
|
162
|
+
class={twMerge(
|
|
163
|
+
`mt-1 text-xs text-primary px-2 tracking-tight ${validationMessageClass}`
|
|
164
|
+
)}
|
|
165
|
+
>
|
|
166
|
+
{@html validation.message}
|
|
167
|
+
</div>
|
|
168
|
+
{/if}
|
|
169
|
+
{#if description}
|
|
170
|
+
<div class={twMerge(`mx-2 mt-1 text-sm opacity-50 ${descriptionClass}`)}>
|
|
171
|
+
{@html description}
|
|
172
|
+
</div>
|
|
173
|
+
{/if}
|
|
174
|
+
{#if $$slots.below}
|
|
175
|
+
<div class="mx-2 mt-1">
|
|
176
|
+
<slot name="below" {id} />
|
|
177
|
+
</div>
|
|
178
|
+
{/if}
|
|
179
|
+
</div>
|