@marianmeres/stuic 1.113.0 → 1.114.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.
|
@@ -74,7 +74,8 @@ export class FieldConfig {
|
|
|
74
74
|
}
|
|
75
75
|
</script>
|
|
76
76
|
|
|
77
|
-
<script>
|
|
77
|
+
<script>import PinInput from "./PinInput.svelte";
|
|
78
|
+
const clog = createClog("Field");
|
|
78
79
|
const dispatch = createEventDispatcher();
|
|
79
80
|
const setType = (el, t) => el.type = t;
|
|
80
81
|
let _class = {};
|
|
@@ -217,6 +218,37 @@ $:
|
|
|
217
218
|
on:mouseenter
|
|
218
219
|
on:mouseleave
|
|
219
220
|
{...$$restProps}
|
|
221
|
+
></textarea>
|
|
222
|
+
{:else if type === 'pin'}
|
|
223
|
+
<PinInput
|
|
224
|
+
bind:value
|
|
225
|
+
inputClass={_inputClass}
|
|
226
|
+
on:input_mounted
|
|
227
|
+
{id}
|
|
228
|
+
{name}
|
|
229
|
+
{disabled}
|
|
230
|
+
{readonly}
|
|
231
|
+
{required}
|
|
232
|
+
{autofocus}
|
|
233
|
+
{tabindex}
|
|
234
|
+
{placeholder}
|
|
235
|
+
{pattern}
|
|
236
|
+
{setValidationResult}
|
|
237
|
+
bind:validate
|
|
238
|
+
on:blur
|
|
239
|
+
on:change
|
|
240
|
+
on:click
|
|
241
|
+
on:focus
|
|
242
|
+
on:input
|
|
243
|
+
on:keydown
|
|
244
|
+
on:keyup
|
|
245
|
+
on:touchstart
|
|
246
|
+
on:touchend
|
|
247
|
+
on:touchmove
|
|
248
|
+
on:touchcancel
|
|
249
|
+
on:mouseenter
|
|
250
|
+
on:mouseleave
|
|
251
|
+
{...$$restProps}
|
|
220
252
|
/>
|
|
221
253
|
{:else}
|
|
222
254
|
<input
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
<script>import { createClog } from "@marianmeres/clog";
|
|
2
|
+
import { iconBsEye } from "@marianmeres/icons-fns/bootstrap/iconBsEye.js";
|
|
3
|
+
import { iconBsEyeSlash } from "@marianmeres/icons-fns/bootstrap/iconBsEyeSlash.js";
|
|
4
|
+
import { createEventDispatcher } from "svelte";
|
|
5
|
+
import { twMerge } from "tailwind-merge";
|
|
6
|
+
import { trim } from "../../actions/trim.js";
|
|
7
|
+
import { validate as validateAction } from "../../actions/validate.js";
|
|
8
|
+
import { getId } from "../../utils/get-id.js";
|
|
9
|
+
import { iconBsX } from "@marianmeres/icons-fns/bootstrap/iconBsX.js";
|
|
10
|
+
const dispatch = createEventDispatcher();
|
|
11
|
+
const clog = createClog("PinInput");
|
|
12
|
+
export let tabindex = 0;
|
|
13
|
+
export let id = getId();
|
|
14
|
+
export let name;
|
|
15
|
+
export let value;
|
|
16
|
+
export let inputClass;
|
|
17
|
+
export let placeholder;
|
|
18
|
+
export let length = 4;
|
|
19
|
+
export let pattern = void 0;
|
|
20
|
+
export let autofocus = void 0;
|
|
21
|
+
export let disabled = false;
|
|
22
|
+
export let readonly = false;
|
|
23
|
+
export let required = false;
|
|
24
|
+
export let validate = void 0;
|
|
25
|
+
export let setValidationResult;
|
|
26
|
+
export let masked = false;
|
|
27
|
+
let _unmasked = false;
|
|
28
|
+
export let showX = false;
|
|
29
|
+
export let pinCellClass = "";
|
|
30
|
+
let _inputEl;
|
|
31
|
+
$:
|
|
32
|
+
if (_inputEl)
|
|
33
|
+
dispatch("input_mounted", _inputEl);
|
|
34
|
+
$:
|
|
35
|
+
if (length < 2)
|
|
36
|
+
length = 2;
|
|
37
|
+
$:
|
|
38
|
+
if (length > 12)
|
|
39
|
+
length = 12;
|
|
40
|
+
$:
|
|
41
|
+
if (value.length > length)
|
|
42
|
+
value = value.slice(0, length);
|
|
43
|
+
$:
|
|
44
|
+
_chars = value.split("").slice(0, length).map((c) => {
|
|
45
|
+
return masked && !_unmasked ? "*" : c;
|
|
46
|
+
});
|
|
47
|
+
$:
|
|
48
|
+
_cells = new Array(length);
|
|
49
|
+
let w = 0;
|
|
50
|
+
const gridCols = [
|
|
51
|
+
"grid-cols-2",
|
|
52
|
+
"grid-cols-3",
|
|
53
|
+
"grid-cols-4",
|
|
54
|
+
"grid-cols-5",
|
|
55
|
+
"grid-cols-6",
|
|
56
|
+
"grid-cols-7",
|
|
57
|
+
"grid-cols-8",
|
|
58
|
+
"grid-cols-9",
|
|
59
|
+
"grid-cols-10",
|
|
60
|
+
"grid-cols-11",
|
|
61
|
+
"grid-cols-12"
|
|
62
|
+
];
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<div class="relative w-full">
|
|
66
|
+
<div class="absolute inset-0 grid {gridCols[length - 2]} pointer-events-none p-1 gap-1">
|
|
67
|
+
{#each _cells as c, idx (idx)}
|
|
68
|
+
<div
|
|
69
|
+
class={twMerge(
|
|
70
|
+
'flex items-center justify-center rounded bg-black/10 font-mono',
|
|
71
|
+
pinCellClass
|
|
72
|
+
)}
|
|
73
|
+
>
|
|
74
|
+
{#if _chars[idx]}
|
|
75
|
+
<span class="">{_chars[idx] || ''}</span>
|
|
76
|
+
{:else if !_chars.length}
|
|
77
|
+
<span class="opacity-25">{placeholder?.[idx] || ''}</span>
|
|
78
|
+
{/if}
|
|
79
|
+
</div>
|
|
80
|
+
{/each}
|
|
81
|
+
</div>
|
|
82
|
+
<div class="aboslute inset-0" bind:clientWidth={w}>
|
|
83
|
+
<input
|
|
84
|
+
bind:value
|
|
85
|
+
bind:this={_inputEl}
|
|
86
|
+
{id}
|
|
87
|
+
type="text"
|
|
88
|
+
spellcheck="false"
|
|
89
|
+
class={twMerge('caret-black', inputClass, `font-mono text-transparent`)}
|
|
90
|
+
class:cursor-not-allowed={disabled}
|
|
91
|
+
style="
|
|
92
|
+
padding-left: {100 / length / 2}%;
|
|
93
|
+
padding-right: {100 / length / 2}%;
|
|
94
|
+
letter-spacing: calc({w / length}px - 1ch);
|
|
95
|
+
"
|
|
96
|
+
{name}
|
|
97
|
+
minlength={length}
|
|
98
|
+
maxlength={length}
|
|
99
|
+
{disabled}
|
|
100
|
+
{readonly}
|
|
101
|
+
{required}
|
|
102
|
+
{autofocus}
|
|
103
|
+
{tabindex}
|
|
104
|
+
{pattern}
|
|
105
|
+
use:trim
|
|
106
|
+
use:validateAction={validate
|
|
107
|
+
? { ...(validate === true ? {} : validate), setValidationResult }
|
|
108
|
+
: undefined}
|
|
109
|
+
on:blur
|
|
110
|
+
on:change
|
|
111
|
+
on:click
|
|
112
|
+
on:focus
|
|
113
|
+
on:input
|
|
114
|
+
on:keydown
|
|
115
|
+
on:keyup
|
|
116
|
+
on:touchstart|passive
|
|
117
|
+
on:touchend|passive
|
|
118
|
+
on:touchmove|passive
|
|
119
|
+
on:touchcancel
|
|
120
|
+
on:mouseenter
|
|
121
|
+
on:mouseleave
|
|
122
|
+
{...$$restProps}
|
|
123
|
+
/>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
{#if showX || masked}
|
|
127
|
+
<div class="flex items-center justify-center mr-1">
|
|
128
|
+
{#if showX}
|
|
129
|
+
<button type="button" class="p-2" on:click={() => (value = '')}>
|
|
130
|
+
{@html iconBsX()}
|
|
131
|
+
</button>
|
|
132
|
+
{/if}
|
|
133
|
+
{#if masked}
|
|
134
|
+
<button
|
|
135
|
+
type="button"
|
|
136
|
+
class="p-2 focus:outline-0"
|
|
137
|
+
on:click={() => (_unmasked = !_unmasked)}
|
|
138
|
+
>
|
|
139
|
+
{#if _unmasked}
|
|
140
|
+
{@html iconBsEye()}
|
|
141
|
+
{:else}
|
|
142
|
+
{@html iconBsEyeSlash()}
|
|
143
|
+
{/if}
|
|
144
|
+
</button>
|
|
145
|
+
{/if}
|
|
146
|
+
</div>
|
|
147
|
+
{/if}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { ValidateOptions } from '../../actions/validate.js';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
[x: string]: any;
|
|
6
|
+
tabindex?: number | undefined;
|
|
7
|
+
id?: string | undefined;
|
|
8
|
+
name: string;
|
|
9
|
+
value: string;
|
|
10
|
+
inputClass: string;
|
|
11
|
+
placeholder: string | undefined;
|
|
12
|
+
length?: number | undefined;
|
|
13
|
+
pattern?: string | undefined;
|
|
14
|
+
autofocus?: true | undefined;
|
|
15
|
+
disabled?: boolean | undefined;
|
|
16
|
+
readonly?: boolean | undefined;
|
|
17
|
+
required?: boolean | undefined;
|
|
18
|
+
validate?: ValidateOptions | true | undefined;
|
|
19
|
+
setValidationResult: any;
|
|
20
|
+
masked?: boolean | undefined;
|
|
21
|
+
showX?: boolean | undefined;
|
|
22
|
+
pinCellClass?: string | undefined;
|
|
23
|
+
};
|
|
24
|
+
events: {
|
|
25
|
+
blur: FocusEvent;
|
|
26
|
+
change: Event;
|
|
27
|
+
click: MouseEvent;
|
|
28
|
+
focus: FocusEvent;
|
|
29
|
+
input: Event;
|
|
30
|
+
keydown: KeyboardEvent;
|
|
31
|
+
keyup: KeyboardEvent;
|
|
32
|
+
touchstart: TouchEvent;
|
|
33
|
+
touchend: TouchEvent;
|
|
34
|
+
touchmove: TouchEvent;
|
|
35
|
+
touchcancel: TouchEvent;
|
|
36
|
+
mouseenter: MouseEvent;
|
|
37
|
+
mouseleave: MouseEvent;
|
|
38
|
+
input_mounted: CustomEvent<any>;
|
|
39
|
+
} & {
|
|
40
|
+
[evt: string]: CustomEvent<any>;
|
|
41
|
+
};
|
|
42
|
+
slots: {};
|
|
43
|
+
exports?: undefined;
|
|
44
|
+
bindings?: undefined;
|
|
45
|
+
};
|
|
46
|
+
export type PinInputProps = typeof __propDef.props;
|
|
47
|
+
export type PinInputEvents = typeof __propDef.events;
|
|
48
|
+
export type PinInputSlots = typeof __propDef.slots;
|
|
49
|
+
export default class PinInput extends SvelteComponent<PinInputProps, PinInputEvents, PinInputSlots> {
|
|
50
|
+
}
|
|
51
|
+
export {};
|