@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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @hashrytech/quick-components-kit
2
2
 
3
+ ## 0.19.8
4
+
5
+ ### Patch Changes
6
+
7
+ - add: Adding pattern to TextInput
8
+
9
+ ## 0.19.7
10
+
11
+ ### Patch Changes
12
+
13
+ - add: Adding text area component
14
+
3
15
  ## 0.19.6
4
16
 
5
17
  ### Patch Changes
@@ -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, HTMLAttributes } from 'svelte/elements';
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
- error?: string;
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
- error,
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}
@@ -38,6 +38,7 @@ export type TextInputProps = {
38
38
  size?: TextInputSize;
39
39
  disabled?: boolean;
40
40
  required?: boolean;
41
+ pattern?: string;
41
42
  error?: string;
42
43
  labelClass?: ClassNameValue;
43
44
  firstDivClass?: ClassNameValue;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './components/text-input/index.js';
2
+ export * from './components/text-area/index.js';
2
3
  export * from './components/button/index.js';
3
4
  export * from './components/link-button/index.js';
4
5
  export * from './components/hamburger-menu/index.js';
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';
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/hashrytech/quick-components-kit.git"
7
7
  },
8
- "version": "0.19.6",
8
+ "version": "0.19.8",
9
9
  "license": "MIT",
10
10
  "author": "Hashry Tech",
11
11
  "files": [