@t007/input 0.0.23 → 0.0.24
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/README.md +64 -2
- package/dist/index.css +6 -4
- package/dist/index.d.ts +20 -51
- package/dist/index.global.js +141 -155
- package/dist/index.js +96 -124
- package/dist/react.d.ts +139 -0
- package/dist/react.js +255 -0
- package/package.json +22 -2
package/README.md
CHANGED
|
@@ -65,6 +65,13 @@ Beautiful floating labels with native error state handling.
|
|
|
65
65
|
- **Horizontal Scroll Assist**: Built-in helper for long error messages overflowing the container.
|
|
66
66
|
- **Tree-Shakeable**: Import only the utilities you need.
|
|
67
67
|
|
|
68
|
+
### Vanilla Perks & Hooks
|
|
69
|
+
|
|
70
|
+
- **`form.onSubmit`**: Optional callback on a form that runs instead of `form.submit()` when provided, allowing custom JS submission flows.
|
|
71
|
+
- **`form.validateOnServer`**: Async hook; if defined the form will await its result before proceeding. Returning `false` prevents submission and shows a global error.
|
|
72
|
+
- **`form.validateOnClient`**: Reference to the internal client-side validation function, allowing you to trigger validation manually or integrate it into custom UI flows.
|
|
73
|
+
- **`form.toggleGlobalError(bool)`**: Programmatic API to display a form-level error state and shake all fields, used internally if `form.validateOnServer` returns false.
|
|
74
|
+
|
|
68
75
|
---
|
|
69
76
|
|
|
70
77
|
## Tech Stack
|
|
@@ -122,6 +129,25 @@ myForm.appendChild(emailInput);
|
|
|
122
129
|
handleFormValidation(myForm);
|
|
123
130
|
```
|
|
124
131
|
|
|
132
|
+
### React
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import { Input, WordsInput, useFormManager } from "@t007/input/react";
|
|
136
|
+
|
|
137
|
+
export function SignupForm() {
|
|
138
|
+
const formRef = useRef<HTMLFormElement>(null); // use in a non-form setup or for manual `validate` triggers
|
|
139
|
+
const { handleSubmit, validate, fireInput } = useFormManager((e) => console.log("submitted"), formRef); // first in line to replace browser behaviour effectively
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<form noValidate className="t007-input-form" onSubmit={handleSubmit} ref={formRef}>
|
|
143
|
+
<Input type="email" label="Email" required helperText={{ typeMismatch: "Enter a valid email." }} />
|
|
144
|
+
<WordsInput type="textarea" label="Bio" maxCount={120} />
|
|
145
|
+
<button type="submit">Submit</button>
|
|
146
|
+
</form>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
125
151
|
### CDN / Browser (Global)
|
|
126
152
|
|
|
127
153
|
When loaded via a `<script>` tag, the library automatically scans the DOM for forms with the class `.t007-input-form` and initializes them.
|
|
@@ -190,7 +216,7 @@ The core object injected into the global namespace containing utility functions
|
|
|
190
216
|
|
|
191
217
|
### File Validation
|
|
192
218
|
|
|
193
|
-
The library extends native file inputs with custom attributes for strict size enforcement
|
|
219
|
+
The library extends native file inputs with custom attributes for strict size enforcement, and the same validation logic is available directly through `t007.FM.getFilesHelper(files, opts)`:
|
|
194
220
|
|
|
195
221
|
```javascript
|
|
196
222
|
const fileUploader = field({
|
|
@@ -204,6 +230,23 @@ const fileUploader = field({
|
|
|
204
230
|
});
|
|
205
231
|
```
|
|
206
232
|
|
|
233
|
+
To use the helper directly, map the same fields into `getFilesHelper` and feed the returned message into your own resolver or `helperText` path:
|
|
234
|
+
|
|
235
|
+
```javascript
|
|
236
|
+
const { violation, message } = t007.FM.getFilesHelper(input.files, {
|
|
237
|
+
accept: input.accept, // -> typeMismatch
|
|
238
|
+
multiple: input.multiple, // respects file count limits
|
|
239
|
+
maxSize: input.maxSize, // -> rangeOverflow
|
|
240
|
+
minSize: input.minSize, // -> rangeUnderflow
|
|
241
|
+
maxTotalSize: input.maxTotalSize, // -> rangeOverflow
|
|
242
|
+
minTotalSize: input.minTotalSize, // -> rangeUnderflow
|
|
243
|
+
maxLength: input.maxLength, // -> tooLong
|
|
244
|
+
minLength: input.minLength, // -> tooShort
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
if (message) input.setCustomValidity(message);
|
|
248
|
+
```
|
|
249
|
+
|
|
207
250
|
### Password Management
|
|
208
251
|
|
|
209
252
|
Setting an input's custom attribute to `password` or `confirm_password` automatically links their validation states.
|
|
@@ -216,13 +259,15 @@ field({ type: 'password', custom: 'password', label: 'Password' });
|
|
|
216
259
|
field({ type: 'password', custom: 'confirm_password', label: 'Confirm Password' });
|
|
217
260
|
```
|
|
218
261
|
|
|
262
|
+
There's other custom features like `onward_date`, `past_date`.
|
|
263
|
+
|
|
219
264
|
-----
|
|
220
265
|
|
|
221
266
|
## Customization
|
|
222
267
|
|
|
223
268
|
You can deeply customize the look and feel by overriding the built-in CSS variables or targeting the specific classes.
|
|
224
269
|
|
|
225
|
-
###
|
|
270
|
+
### CSS Selectors & Variables
|
|
226
271
|
|
|
227
272
|
- `.t007-input`: The actual `<input>` element.
|
|
228
273
|
- `.t007-input-floating-label`: The label text.
|
|
@@ -230,6 +275,23 @@ You can deeply customize the look and feel by overriding the built-in CSS variab
|
|
|
230
275
|
- `[data-error]`: Attribute added dynamically on validation failure.
|
|
231
276
|
- `.t007-input-password-strength-meter`: The container for the 4 strength bars.
|
|
232
277
|
|
|
278
|
+
#### Override Starter
|
|
279
|
+
|
|
280
|
+
```css
|
|
281
|
+
.t007-input-field {
|
|
282
|
+
--t007-input-color: var(--app-theme-color);
|
|
283
|
+
/* ...check source code for all variables... */
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
#### Specificity Note
|
|
288
|
+
|
|
289
|
+
- Start with `:root` for shared input tokens.
|
|
290
|
+
- If a token does not apply, override directly on `.t007-input-field`.
|
|
291
|
+
- For precise control, target element selectors like `.t007-input`, `.t007-input-floating-label`, and `.t007-input-outline`.
|
|
292
|
+
- For strong app themes (e.g. `html[data-theme="dark"]`), use equal/stronger selectors like `html[data-theme="dark"] .t007-input-field`.
|
|
293
|
+
- Check source code for more details.
|
|
294
|
+
|
|
233
295
|
-----
|
|
234
296
|
|
|
235
297
|
## Author
|
package/dist/index.css
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
--t007-input-width: 100%;
|
|
6
6
|
--t007-input-height: 3rem;
|
|
7
7
|
--t007-input-font-size: 1rem;
|
|
8
|
-
--t007-input-floating-label-scale: 0.
|
|
8
|
+
--t007-input-floating-label-scale: 0.85;
|
|
9
9
|
--t007-input-border-width: 1px;
|
|
10
10
|
--t007-input-focused-border-width: 2px;
|
|
11
11
|
--t007-input-border-style: solid;
|
|
@@ -58,9 +58,9 @@
|
|
|
58
58
|
--t007-input-icon-stroke: unset;
|
|
59
59
|
--t007-input-padding: calc(var(--t007-input-height) / 4);
|
|
60
60
|
--t007-input-floating-label-font-size: calc(var(--t007-input-font-size) * var(--t007-input-floating-label-scale));
|
|
61
|
-
--t007-input-helper-font-size: calc(var(--t007-input-font-size) *
|
|
61
|
+
--t007-input-helper-font-size: calc(var(--t007-input-font-size) * var(--t007-input-floating-label-scale));
|
|
62
62
|
--t007-input-border-radius: calc(var(--t007-input-height) / 12);
|
|
63
|
-
--t007-input-p-meter-font-size: calc(var(--t007-input-font-size) *
|
|
63
|
+
--t007-input-p-meter-font-size: calc(var(--t007-input-font-size) * var(--t007-input-floating-label-scale));
|
|
64
64
|
--t007-input-p-meter-gap: calc(var(--t007-input-font-size) * 0.25);
|
|
65
65
|
--t007-input-p-meter-height: calc(var(--t007-input-font-size) * 0.25);
|
|
66
66
|
--t007-input-checkbox-font-size: calc(var(--t007-input-font-size) * 0.9);
|
|
@@ -275,7 +275,9 @@
|
|
|
275
275
|
.t007-input-floating-label {
|
|
276
276
|
position: relative;
|
|
277
277
|
top: calc(var(--t007-input-height) / 2);
|
|
278
|
-
display:
|
|
278
|
+
display: flex;
|
|
279
|
+
align-items: center;
|
|
280
|
+
gap: calc(var(--t007-input-font-size) / 3);
|
|
279
281
|
max-width: 100%;
|
|
280
282
|
transform: translateY(-50%);
|
|
281
283
|
color: var(--t007-input-current-label-color);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,52 +1,24 @@
|
|
|
1
1
|
import "@t007/utils";
|
|
2
|
+
import { BaseProps, CheckboxInputAddon, DateInputAddon, FileInputAddon, SelectElementAddon } from "../react";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
export interface FieldOptions extends Partial<
|
|
5
|
-
Omit<HTMLInputElement, "type" | "className" | "children">
|
|
6
|
-
> {
|
|
7
|
-
/** Wrap the field in its own container. */
|
|
8
|
-
isWrapper?: boolean;
|
|
4
|
+
interface BaseOptions extends Omit<BaseProps, "error"> {
|
|
9
5
|
/** Visible label text. */
|
|
10
6
|
label?: string;
|
|
11
|
-
/** Input type to render. */
|
|
12
|
-
type?: string;
|
|
13
|
-
/** Placeholder text. */
|
|
14
|
-
placeholder?: string;
|
|
15
|
-
/** Custom CSS class or class list. */
|
|
16
|
-
custom?: string;
|
|
17
|
-
/** Minimum value length or count. */
|
|
18
|
-
minSize?: number;
|
|
19
|
-
/** Maximum value length or count. */
|
|
20
|
-
maxSize?: number;
|
|
21
|
-
/** Minimum total size allowed across the field value. */
|
|
22
|
-
minTotalSize?: number;
|
|
23
|
-
/** Maximum total size allowed across the field value. */
|
|
24
|
-
maxTotalSize?: number;
|
|
25
|
-
/** Options used by select-like fields. */
|
|
26
|
-
options?: Array<string | { value: string; option: string }>;
|
|
27
|
-
/** Whether the checkbox is partially selected. */
|
|
28
|
-
indeterminate?: boolean;
|
|
29
|
-
/** Show the password visibility toggler. */
|
|
30
|
-
eyeToggler?: boolean;
|
|
31
|
-
/** Enable the password strength meter. */
|
|
32
|
-
passwordMeter?: boolean;
|
|
33
|
-
/** Helper text shown under the field. */
|
|
34
|
-
helperText?: false | Record<string, string>;
|
|
35
|
-
/** Class applied to the root field element. */
|
|
36
|
-
className?: string;
|
|
37
|
-
/** Class applied to the inner field control. */
|
|
38
|
-
fieldClassName?: string;
|
|
39
7
|
/** Optional child element rendered inside the field wrapper. */
|
|
40
8
|
children?: HTMLElement;
|
|
41
|
-
/** End icon rendered inside the field control. */
|
|
42
|
-
endIcon?: string;
|
|
43
|
-
/** Native icon rendered by the browser control. */
|
|
44
|
-
nativeIcon?: string;
|
|
45
|
-
/** Icon shown when the password is visible. */
|
|
46
|
-
passwordVisibleIcon?: string;
|
|
47
|
-
/** Icon shown when the password is hidden. */
|
|
48
|
-
passwordHiddenIcon?: string;
|
|
49
9
|
}
|
|
10
|
+
type InputAttrs = Partial<Omit<HTMLInputElement, "type" | "children">>;
|
|
11
|
+
type SelectAttrs = Partial<Omit<HTMLSelectElement, "type" | "children">>;
|
|
12
|
+
type TextareaAttrs = Partial<Omit<HTMLTextAreaElement, "type" | "children">>;
|
|
13
|
+
type PasswordFieldOptions = BaseOptions & InputAttrs & Omit<FileInputAddon, "passwordVisibleIcon" | "passwordHiddenIcon"> & { passwordVisibleIcon?: HTMLElement; passwordHiddenIcon?: HTMLElement };
|
|
14
|
+
type FileFieldOptions = BaseOptions & InputAttrs & FileInputAddon;
|
|
15
|
+
type CheckboxFieldOptions = BaseOptions & InputAttrs & CheckboxInputAddon;
|
|
16
|
+
type DateFieldOptions = BaseOptions & InputAttrs & DateInputAddon;
|
|
17
|
+
type GenericFieldOptions = BaseOptions & InputAttrs & { type?: Exclude<HTMLInputElement["type"], "password" | "file" | "checkbox" | NativeType> };
|
|
18
|
+
type TextareaFieldOptions = BaseOptions & TextareaAttrs & { type: "textarea" };
|
|
19
|
+
type SelectFieldOptions = BaseOptions & SelectAttrs & SelectElementAddon;
|
|
20
|
+
/** Configuration accepted by the field() helper. */
|
|
21
|
+
export type FieldOptions = PasswordFieldOptions | FileFieldOptions | CheckboxFieldOptions | DateFieldOptions | GenericFieldOptions | TextareaFieldOptions | SelectFieldOptions;
|
|
50
22
|
|
|
51
23
|
/** Form-level manager used to build and validate inputs. */
|
|
52
24
|
export interface FormManager {
|
|
@@ -63,10 +35,7 @@ export interface FormManager {
|
|
|
63
35
|
* @param opts Validation options.
|
|
64
36
|
* @returns Violation information and user-facing message.
|
|
65
37
|
*/
|
|
66
|
-
getFilesHelper(
|
|
67
|
-
files: FileList | File[],
|
|
68
|
-
opts: any,
|
|
69
|
-
): { violation: string | null; message: string };
|
|
38
|
+
getFilesHelper(files: FileList | File[], opts: any): { violation: string | null; message: string };
|
|
70
39
|
/** Format a file size for display.
|
|
71
40
|
* @param size Size in bytes.
|
|
72
41
|
* @param decimals Decimal precision.
|
|
@@ -135,13 +104,13 @@ declare global {
|
|
|
135
104
|
handleFormValidation?: T007Namespace["handleFormValidation"];
|
|
136
105
|
}
|
|
137
106
|
interface HTMLFormElement {
|
|
138
|
-
/** Client-side submit hook. */
|
|
139
|
-
onSubmit?(): void;
|
|
140
|
-
/** Check validation on the client. */
|
|
107
|
+
/** Vanilla-only Client-side submit hook. Use instead of `onsubmit` to escape browser behavior. */
|
|
108
|
+
onSubmit?(e: Event): void;
|
|
109
|
+
/** Vanilla-only Check validation on the client. Reference to internals for manual use. */
|
|
141
110
|
validateOnClient?(): boolean;
|
|
142
|
-
/** Check validation on the server. */
|
|
111
|
+
/** Vanilla-only Check validation on the server. Assign custom server-side validation logic. */
|
|
143
112
|
validateOnServer?(): Promise<boolean>;
|
|
144
|
-
/** Toggle the global error state. */
|
|
113
|
+
/** Vanilla-only Toggle the global error state. Reference to internals for manual use. */
|
|
145
114
|
toggleGlobalError?(bool: boolean): void;
|
|
146
115
|
}
|
|
147
116
|
}
|