@hashrytech/quick-components-kit 0.19.6 → 0.19.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/CHANGELOG.md +12 -0
- package/dist/components/text-area/TextArea.svelte +136 -0
- package/dist/components/text-area/TextArea.svelte.d.ts +56 -0
- package/dist/components/text-area/index.d.ts +1 -0
- package/dist/components/text-area/index.js +1 -0
- package/dist/components/text-input/TextInput.svelte +6 -10
- package/dist/components/text-input/TextInput.svelte.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { FullAutoFill } from 'svelte/elements';
|
|
4
|
+
import type { ClassNameValue } from 'tailwind-merge';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Predefined size classes for the TextArea input.
|
|
8
|
+
* - "sm": h-[2.05rem] text-sm placeholder:text-sm
|
|
9
|
+
* - "md": h-[2.375rem] text-sm placeholder:text-sm
|
|
10
|
+
* - "lg": h-[2.8rem] text-lg placeholder:text-lg
|
|
11
|
+
*/
|
|
12
|
+
export type TextAreaSize = "sm" | "md" | "lg";
|
|
13
|
+
export type TextInputType = "text" | "password" | "number" | "email" | "tel" | "url" | "search";
|
|
14
|
+
export type InputMode = "none" | "text" | "decimal" | "numeric" | "tel" | "search" | "email" | "url";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Props for the TextBox component.
|
|
18
|
+
*
|
|
19
|
+
* @prop {string} id - The unique ID of the input field.
|
|
20
|
+
* @prop {string} [name] - The name attribute for form submission.
|
|
21
|
+
* @prop {string} [value] - The bound value of the input.
|
|
22
|
+
* @prop {string} [placeholder] - Placeholder text.
|
|
23
|
+
* @prop {string} [labelText] - Optional label text.
|
|
24
|
+
* @prop {TextInputSize} [size] - Size variant ("sm", "md", "lg") with predefined Tailwind styles.
|
|
25
|
+
* - "sm": h-[2.05rem] text-sm placeholder:text-sm
|
|
26
|
+
* - "md": h-[2.375rem] text-sm placeholder:text-sm
|
|
27
|
+
* - "lg": h-[2.8rem] text-lg placeholder:text-lg
|
|
28
|
+
* @prop {() => void} [onchange] - Event handler for change events.
|
|
29
|
+
* @prop {() => void} [onmouseup] - Event handler for mouseup events.
|
|
30
|
+
* @prop {Snippet} [label] - Custom label snippet.
|
|
31
|
+
* @prop {Snippet} [class] - Css classes for the input element.
|
|
32
|
+
*/
|
|
33
|
+
export type TextInputProps = {
|
|
34
|
+
id: string;
|
|
35
|
+
name?: string;
|
|
36
|
+
value?: string|number;
|
|
37
|
+
placeholder?: string;
|
|
38
|
+
labelText?: string;
|
|
39
|
+
labelPosition?: "top" | "left" | "right" | "bottom";
|
|
40
|
+
size?: TextAreaSize;
|
|
41
|
+
disabled?: boolean;
|
|
42
|
+
required?: boolean;
|
|
43
|
+
error?: string;
|
|
44
|
+
labelClass?: ClassNameValue;
|
|
45
|
+
firstDivClass?: ClassNameValue;
|
|
46
|
+
secondDivClass?: ClassNameValue;
|
|
47
|
+
autocomplete?: FullAutoFill | null;
|
|
48
|
+
minlength?: number;
|
|
49
|
+
maxlength?: number;
|
|
50
|
+
debounceDelay?: number;
|
|
51
|
+
onInput?: (value: string|number) => void;
|
|
52
|
+
onchange?: (event: Event) => void;
|
|
53
|
+
onmouseup?: () => void;
|
|
54
|
+
label?: Snippet;
|
|
55
|
+
class?: ClassNameValue;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<script lang="ts">
|
|
62
|
+
import { twMerge } from 'tailwind-merge';
|
|
63
|
+
|
|
64
|
+
let {
|
|
65
|
+
id,
|
|
66
|
+
name="",
|
|
67
|
+
value=$bindable(""),
|
|
68
|
+
placeholder="",
|
|
69
|
+
labelText="",
|
|
70
|
+
labelClass,
|
|
71
|
+
labelPosition="top",
|
|
72
|
+
size="md",
|
|
73
|
+
disabled=false,
|
|
74
|
+
required=false,
|
|
75
|
+
error,
|
|
76
|
+
firstDivClass,
|
|
77
|
+
secondDivClass,
|
|
78
|
+
autocomplete,
|
|
79
|
+
minlength,
|
|
80
|
+
maxlength,
|
|
81
|
+
debounceDelay=300, //ms
|
|
82
|
+
onchange,
|
|
83
|
+
onInput,
|
|
84
|
+
onmouseup,
|
|
85
|
+
label,
|
|
86
|
+
...restProps}: TextInputProps = $props();
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Predefined size classes for the TextBox input.
|
|
90
|
+
* - "sm": h-[2.05rem] text-sm placeholder:text-sm
|
|
91
|
+
* - "md": h-[2.375rem] text-sm placeholder:text-sm
|
|
92
|
+
* - "lg": h-[2.8rem] text-lg placeholder:text-lg
|
|
93
|
+
*/
|
|
94
|
+
let sizeStyle: Record<TextAreaSize, string> = {
|
|
95
|
+
sm: "text-sm placeholder:text-sm px-2.5",
|
|
96
|
+
md: "text-sm placeholder:text-sm px-2.5",
|
|
97
|
+
lg: "text-base placeholder:text-base px-3"
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const directionClass = {
|
|
101
|
+
top: "flex-col gap-1",
|
|
102
|
+
bottom: "flex-col-reverse gap-1",
|
|
103
|
+
left: "flex-row items-center gap-2",
|
|
104
|
+
right: "flex-row-reverse items-center gap-2",
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// --- Debounce logic ---
|
|
108
|
+
let localValue = value; // local for immediate typing
|
|
109
|
+
let debounceTimer: ReturnType<typeof setTimeout>;
|
|
110
|
+
|
|
111
|
+
function handleInput(e: Event) {
|
|
112
|
+
localValue = (e.target as HTMLInputElement).value;
|
|
113
|
+
clearTimeout(debounceTimer);
|
|
114
|
+
debounceTimer = setTimeout(() => {
|
|
115
|
+
value = localValue; // sync to bound value after delay
|
|
116
|
+
onInput?.(value); // call handler if provided
|
|
117
|
+
}, debounceDelay);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
</script>
|
|
121
|
+
|
|
122
|
+
<div class={twMerge("", firstDivClass)}>
|
|
123
|
+
<div class={twMerge("flex rounded-primary", directionClass[labelPosition] ?? directionClass.top, secondDivClass)}>
|
|
124
|
+
{#if label}{@render label()}{/if}
|
|
125
|
+
{#if !label && labelText}<label for={id} class={twMerge("text-sm font-medium text-primary-label-text ml-1", labelClass)}>{labelText}</label>{/if}
|
|
126
|
+
|
|
127
|
+
<textarea {disabled} {required} {id} name={name ? name: id} {placeholder} {onmouseup} bind:value {autocomplete} {minlength} {maxlength} oninput={handleInput}
|
|
128
|
+
class={twMerge("placeholder:text-neutral-600/50 h-full w-full rounded-primary border border-primary-input-border focus-within:ring focus-within:border-primary-focus focus-within:ring-primary-focus disabled:bg-neutral-300/30 disabled:border-neutral-300/30", sizeStyle[size], restProps.class)}>
|
|
129
|
+
</textarea>
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
{#if error}
|
|
133
|
+
<p class="text-sm text-red-500 mt-0.5 bg-red-100/30 px-2 rounded-primary">{error}</p>
|
|
134
|
+
{/if}
|
|
135
|
+
|
|
136
|
+
</div>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { FullAutoFill } from 'svelte/elements';
|
|
3
|
+
import type { ClassNameValue } from 'tailwind-merge';
|
|
4
|
+
/**
|
|
5
|
+
* Predefined size classes for the TextArea input.
|
|
6
|
+
* - "sm": h-[2.05rem] text-sm placeholder:text-sm
|
|
7
|
+
* - "md": h-[2.375rem] text-sm placeholder:text-sm
|
|
8
|
+
* - "lg": h-[2.8rem] text-lg placeholder:text-lg
|
|
9
|
+
*/
|
|
10
|
+
export type TextAreaSize = "sm" | "md" | "lg";
|
|
11
|
+
export type TextInputType = "text" | "password" | "number" | "email" | "tel" | "url" | "search";
|
|
12
|
+
export type InputMode = "none" | "text" | "decimal" | "numeric" | "tel" | "search" | "email" | "url";
|
|
13
|
+
/**
|
|
14
|
+
* Props for the TextBox component.
|
|
15
|
+
*
|
|
16
|
+
* @prop {string} id - The unique ID of the input field.
|
|
17
|
+
* @prop {string} [name] - The name attribute for form submission.
|
|
18
|
+
* @prop {string} [value] - The bound value of the input.
|
|
19
|
+
* @prop {string} [placeholder] - Placeholder text.
|
|
20
|
+
* @prop {string} [labelText] - Optional label text.
|
|
21
|
+
* @prop {TextInputSize} [size] - Size variant ("sm", "md", "lg") with predefined Tailwind styles.
|
|
22
|
+
* - "sm": h-[2.05rem] text-sm placeholder:text-sm
|
|
23
|
+
* - "md": h-[2.375rem] text-sm placeholder:text-sm
|
|
24
|
+
* - "lg": h-[2.8rem] text-lg placeholder:text-lg
|
|
25
|
+
* @prop {() => void} [onchange] - Event handler for change events.
|
|
26
|
+
* @prop {() => void} [onmouseup] - Event handler for mouseup events.
|
|
27
|
+
* @prop {Snippet} [label] - Custom label snippet.
|
|
28
|
+
* @prop {Snippet} [class] - Css classes for the input element.
|
|
29
|
+
*/
|
|
30
|
+
export type TextInputProps = {
|
|
31
|
+
id: string;
|
|
32
|
+
name?: string;
|
|
33
|
+
value?: string | number;
|
|
34
|
+
placeholder?: string;
|
|
35
|
+
labelText?: string;
|
|
36
|
+
labelPosition?: "top" | "left" | "right" | "bottom";
|
|
37
|
+
size?: TextAreaSize;
|
|
38
|
+
disabled?: boolean;
|
|
39
|
+
required?: boolean;
|
|
40
|
+
error?: string;
|
|
41
|
+
labelClass?: ClassNameValue;
|
|
42
|
+
firstDivClass?: ClassNameValue;
|
|
43
|
+
secondDivClass?: ClassNameValue;
|
|
44
|
+
autocomplete?: FullAutoFill | null;
|
|
45
|
+
minlength?: number;
|
|
46
|
+
maxlength?: number;
|
|
47
|
+
debounceDelay?: number;
|
|
48
|
+
onInput?: (value: string | number) => void;
|
|
49
|
+
onchange?: (event: Event) => void;
|
|
50
|
+
onmouseup?: () => void;
|
|
51
|
+
label?: Snippet;
|
|
52
|
+
class?: ClassNameValue;
|
|
53
|
+
};
|
|
54
|
+
declare const TextArea: import("svelte").Component<TextInputProps, {}, "value">;
|
|
55
|
+
type TextArea = ReturnType<typeof TextArea>;
|
|
56
|
+
export default TextArea;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as TextArea } from './TextArea.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as TextArea } from './TextArea.svelte';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { FullAutoFill
|
|
3
|
+
import type { FullAutoFill } from 'svelte/elements';
|
|
4
4
|
import type { ClassNameValue } from 'tailwind-merge';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
size?: TextInputSize;
|
|
42
42
|
disabled?: boolean;
|
|
43
43
|
required?: boolean;
|
|
44
|
-
|
|
44
|
+
pattern?: string;
|
|
45
|
+
error?: string;
|
|
45
46
|
labelClass?: ClassNameValue;
|
|
46
47
|
firstDivClass?: ClassNameValue;
|
|
47
48
|
secondDivClass?: ClassNameValue;
|
|
@@ -78,7 +79,8 @@
|
|
|
78
79
|
size="md",
|
|
79
80
|
disabled=false,
|
|
80
81
|
required=false,
|
|
81
|
-
|
|
82
|
+
pattern,
|
|
83
|
+
error,
|
|
82
84
|
firstDivClass,
|
|
83
85
|
secondDivClass,
|
|
84
86
|
thirdDivClass,
|
|
@@ -107,12 +109,6 @@
|
|
|
107
109
|
lg: "text-base placeholder:text-base px-3"
|
|
108
110
|
};
|
|
109
111
|
|
|
110
|
-
let iconStyle: Record<TextInputSize, string> = {
|
|
111
|
-
sm: "pl-2.5",
|
|
112
|
-
md: "px-2.5",
|
|
113
|
-
lg: "text-base placeholder:text-base px-3"
|
|
114
|
-
};
|
|
115
|
-
|
|
116
112
|
let textBoxStyle: Record<TextInputSize, string> = {
|
|
117
113
|
sm: "h-[2.05rem]",
|
|
118
114
|
md: "h-[2.375rem]",
|
|
@@ -153,7 +149,7 @@
|
|
|
153
149
|
|
|
154
150
|
{#if leftIcon}<div class="h-full flex flex-col items-center justify-center {size == 'lg' ? 'pl-3' : 'pl-2.5'}">{@render leftIcon()}</div>{/if}
|
|
155
151
|
|
|
156
|
-
<input {disabled} {required} {type} {id} name={name ? name: id} {placeholder} {onmouseup} bind:value {autocomplete} {inputmode} {min} {max} oninput={handleInput}
|
|
152
|
+
<input {disabled} {required} {type} {id} name={name ? name: id} {placeholder} {pattern} {onmouseup} bind:value {autocomplete} {inputmode} {min} {max} oninput={handleInput}
|
|
157
153
|
class={twMerge("border-0 focus:border-0 focus:ring-0 active:border-0 outline-none p-0 bg-transparent placeholder:text-neutral-600/50 h-full w-full rounded-primary", sizeStyle[size], restProps.class)} />
|
|
158
154
|
|
|
159
155
|
{#if rightIcon}<div class="h-full flex flex-col items-center justify-center {size == 'lg' ? 'pr-3' : 'pr-2.5'}">{@render rightIcon()}</div>{/if}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Reexport your entry components here
|
|
2
2
|
// lib/index.js
|
|
3
3
|
export * from './components/text-input/index.js';
|
|
4
|
+
export * from './components/text-area/index.js';
|
|
4
5
|
export * from './components/button/index.js';
|
|
5
6
|
export * from './components/link-button/index.js';
|
|
6
7
|
export * from './components/hamburger-menu/index.js';
|