@t007/input 0.0.4 → 0.0.6

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 OLUWATOBILOBA OKETADE
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,241 @@
1
+ # @t007/input
2
+
3
+ > An advanced, highly customizable, and fully automated vanilla JavaScript form management system. Features floating labels, automatic validation, mutation observing, and native file-size enforcement.
4
+
5
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
+ [![NPM Version](https://img.shields.io/npm/v/@t007/input.svg)](https://www.npmjs.com/package/@t007/input)
7
+
8
+ [Live Demo](https://tobi007-del.github.io/t007-tools/packages/input/src/index.html) | [Report Bug](https://github.com/Tobi007-del/t007-tools/issues)
9
+
10
+ ---
11
+
12
+ ## Table of contents
13
+
14
+ - [@t007/input](#t007input)
15
+ - [Table of contents](#table-of-contents)
16
+ - [Overview](#overview)
17
+ - [Demo \& Screenshots](#demo--screenshots)
18
+ - [Features](#features)
19
+ - [Tech Stack](#tech-stack)
20
+ - [Getting Started](#getting-started)
21
+ - [Usage](#usage)
22
+ - [API Reference](#api-reference)
23
+ - [Advanced Usage](#advanced-usage)
24
+ - [Customization](#customization)
25
+ - [Author](#author)
26
+ - [Acknowledgments](#acknowledgments)
27
+
28
+ ---
29
+
30
+ ## Overview
31
+
32
+ **@t007/input** is a powerful Form Manager (FM) designed to take the pain out of HTML5 forms. It automatically handles floating labels, injects custom icons, tracks password strength, and strictly enforces validation rules (including deep file-size and mime-type checks) without requiring a massive framework.
33
+
34
+ ### Why @t007/input?
35
+
36
+ - ✅ **DOM Mutation Auto-Tracking:** Automatically initializes new inputs added to the DOM dynamically.
37
+ - ✅ **Advanced File Validation:** Built-in checks for `maxSize`, `minSize`, `maxTotalSize`, and specific MIME types.
38
+ - ✅ **Intelligent Password UX:** Ships with a built-in password strength meter, confirm-password matching, and toggleable visibility icons.
39
+ - ✅ **Zero Frameworks:** Pure vanilla JS. Drop it into React, Vue, or a static HTML site.
40
+ - ✅ **Global Injection:** Automatically attaches to `window.field` and `window.handleFormValidation` for instant legacy integration.
41
+
42
+ ---
43
+
44
+ ## Demo & Screenshots
45
+
46
+ ### Standard Input Fields
47
+ Beautiful floating labels with native error state handling.
48
+ <img src="https://raw.githubusercontent.com/Tobi007-del/t007-tools/refs/heads/main/assets/images/input_library_desktop_preview.png" alt="Desktop Preview" width="600" />
49
+
50
+ ### Mobile & Responsive State
51
+ <img src="https://raw.githubusercontent.com/Tobi007-del/t007-tools/refs/heads/main/assets/images/input_library_mobile_preview.png" alt="Mobile Preview" width="300" />
52
+
53
+ ### Form Validation in Action
54
+ <img src="https://raw.githubusercontent.com/Tobi007-del/t007-tools/refs/heads/main/assets/images/input_library_sample_1.png" alt="Validation Example 1" width="600" />
55
+ <img src="https://raw.githubusercontent.com/Tobi007-del/t007-tools/refs/heads/main/assets/images/input_library_sample_2.png" alt="Validation Example 2" width="600" />
56
+
57
+ ---
58
+
59
+ ## Features
60
+
61
+ - **Programmatic Field Generation**: Create complex DOM inputs (with icons, meters, and helpers) via a single JS object.
62
+ - **Client & Server Sync**: Supports `form.validateOnServer()` hooks before allowing submission.
63
+ - **Automatic Error Shaking**: Visual feedback (shake animation) on invalid focus-out or submit.
64
+ - **Horizontal Scroll Assist**: Built-in helper for long error messages overflowing the container.
65
+ - **Tree-Shakeable**: Import only the utilities you need.
66
+
67
+ ---
68
+
69
+ ## Tech Stack
70
+
71
+ ### Built with
72
+
73
+ - Vanilla JavaScript (ES6+)
74
+ - HTML5 Form Validation API
75
+ - MutationObserver API
76
+ - Bundled via `tsup` (ESM, CJS, IIFE outputs)
77
+
78
+ ---
79
+
80
+ ## Getting Started
81
+
82
+ ### Installation
83
+
84
+ Install via your preferred package manager:
85
+
86
+ ```bash
87
+ npm install @t007/input
88
+ # or
89
+ yarn add @t007/input
90
+ # or
91
+ pnpm add @t007/input
92
+ ````
93
+
94
+ -----
95
+
96
+ ## Usage
97
+
98
+ ### Modern Bundlers (ESM)
99
+
100
+ ```javascript
101
+ import '@t007/input/style.css';
102
+ import { field, handleFormValidation, formManager } from '@t007/input'; // also attached to window.t007
103
+
104
+ // 1. Create a complex input field programmatically
105
+ const emailInput = field({
106
+ type: 'email',
107
+ label: 'Email Address',
108
+ placeholder: 'Enter your email',
109
+ required: true,
110
+ helperText: {
111
+ info: "We'll never share your email.",
112
+ typeMismatch: "Please enter a valid email address."
113
+ }
114
+ });
115
+
116
+ // 2. Append to a form
117
+ const myForm = document.querySelector('.t007-input-form');
118
+ myForm.appendChild(emailInput);
119
+
120
+ // 3. Initialize the validation engine
121
+ handleFormValidation(myForm);
122
+ ```
123
+
124
+ ### CDN / Browser (Global)
125
+
126
+ When loaded via a `<script>` tag, the library automatically scans the DOM for forms with the class `.t007-input-form` and initializes them.
127
+
128
+ ```html
129
+ <!DOCTYPE html>
130
+ <html>
131
+ <head>
132
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@t007/input@latest/dist/index.min.css">
133
+ </head>
134
+ <body>
135
+
136
+ <form class="t007-input-form" novalidate>
137
+ <div class="t007-input-field">
138
+ <label class="t007-input-wrapper">
139
+ <span class="t007-input-outline">
140
+ <span class="t007-input-outline-leading"></span>
141
+ <span class="t007-input-outline-notch">
142
+ <span class="t007-input-floating-label">Username</span>
143
+ </span>
144
+ <span class="t007-input-outline-trailing"></span>
145
+ </span>
146
+ <input type="text" class="t007-input" required minlength="3">
147
+ </label>
148
+ </div>
149
+ <button type="submit">Submit</button>
150
+ </form>
151
+
152
+ <script src="https://cdn.jsdelivr.net/npm/@t007/input@latest"></script>
153
+ </body>
154
+ </html>
155
+ ```
156
+
157
+ -----
158
+
159
+ ## API Reference
160
+
161
+ ### `field(config)`
162
+
163
+ Programmatically generates the complex DOM structure required for the floating labels, icons, and error states.
164
+
165
+ - **`config.type`** *(String)*: Standard HTML input type, or `"select"`, `"textarea"`.
166
+ - **`config.label`** *(String)*: The floating label text.
167
+ - **`config.placeholder`** *(String)*: Standard placeholder.
168
+ - **`config.options`** *(Array)*: Used only when `type="select"`. Array of strings or `{value, option}` objects.
169
+ - **`config.helperText`** *(Object | Boolean)*: Maps native HTML5 validity states to custom error messages.
170
+ - `info`: Default helper text.
171
+ - `valueMissing`: Shown when `required` fails.
172
+ - `typeMismatch`: Shown when email/url format fails.
173
+ - *(Set to `false` to disable the helper line entirely).*
174
+ - **`config.passwordMeter`** *(Boolean)*: Enables the 4-tier password strength bar.
175
+ - **`config.eyeToggler`** *(Boolean)*: Enables the show/hide password icons.
176
+ - **`...otherProps`**: Any standard HTML attributes (`required`, `minlength`, `disabled`) are passed directly to the input.
177
+
178
+ ### `handleFormValidation(formElement)`
179
+
180
+ Attaches the event listeners to a specific form, preventing default submission if inputs are invalid, and triggering the `.t007-input-shake` animations on errors.
181
+
182
+ ### `The Form Manager (t007.FM)`
183
+
184
+ The core object injected into the global namespace containing utility functions like `togglePasswordType`, `getFilesHelper`, and `observeDOMForFields()`.
185
+
186
+ -----
187
+
188
+ ## Advanced Usage
189
+
190
+ ### File Validation
191
+
192
+ The library extends native file inputs with custom attributes for strict size enforcement:
193
+
194
+ ```javascript
195
+ const fileUploader = field({
196
+ type: 'file',
197
+ label: 'Upload Avatar',
198
+ accept: 'image/png, image/jpeg',
199
+ multiple: true,
200
+ maxSize: 5000000, // 5MB max per file
201
+ maxTotalSize: 15000000, // 15MB max total upload
202
+ maxLength: 3 // Max 3 files allowed
203
+ });
204
+ ```
205
+
206
+ ### Password Management
207
+
208
+ Setting an input's custom attribute to `password` or `confirm_password` automatically links their validation states.
209
+
210
+ ```javascript
211
+ // Master password
212
+ field({ type: 'password', custom: 'password', label: 'Password' });
213
+
214
+ // Confirmation (Automatically errors if it doesn't match the master)
215
+ field({ type: 'password', custom: 'confirm_password', label: 'Confirm Password' });
216
+ ```
217
+
218
+ -----
219
+
220
+ ## Customization
221
+
222
+ You can deeply customize the look and feel by overriding the built-in CSS variables or targeting the specific classes.
223
+
224
+ ### Important Selectors
225
+
226
+ - `.t007-input`: The actual `<input>` element.
227
+ - `.t007-input-floating-label`: The label text.
228
+ - `.t007-input-outline`: The border wrapper holding the label.
229
+ - `[data-error]`: Attribute added dynamically on validation failure.
230
+ - `.t007-input-password-strength-meter`: The container for the 4 strength bars.
231
+
232
+ -----
233
+
234
+ ## Author
235
+
236
+ - Developer - [Oketade Oluwatobiloba (Tobi007-del)](https://github.com/Tobi007-del)
237
+ - Project - [t007-tools](https://github.com/Tobi007-del/t007-tools)
238
+
239
+ ## Acknowledgments
240
+
241
+ Built to provide a robust, dependency-free form validation engine that rivals heavyweight frontend frameworks. Part of the `@t007` utility ecosystem.
@@ -1,3 +1,4 @@
1
+ /* src/css/index.css */
1
2
  :where(:root) {
2
3
  --t007-input-dark-error-color: #f44336;
3
4
  --t007-input-font-family: inherit;
@@ -20,39 +21,32 @@
20
21
  --t007-input-ripple-size: 250%;
21
22
  --t007-input-ripple-color: rgb(from var(--t007-input-checkbox-checked-background) r g b/0.15);
22
23
  }
23
-
24
- /* general input state variables */
25
24
  :where(:root, .t007-input-field) {
26
25
  --t007-input-color: black;
27
- /* borders */
28
26
  --t007-input-base-color: rgb(from var(--t007-input-color) r g b / 0.45);
29
27
  --t007-input-hover-color: rgb(from var(--t007-input-color) r g b / 1);
30
28
  --t007-input-focused-color: rgb(from var(--t007-input-color) r g b / 1);
31
29
  --t007-input-filled-color: var(--t007-input-base-color);
32
30
  --t007-input-error-color: #d32f2f;
33
31
  --t007-input-disabled-color: gray;
34
- /* label */
35
32
  --t007-input-base-label-color: rgb(from var(--t007-input-base-color) r g b / 0.95);
36
33
  --t007-input-hover-label-color: var(--t007-input-base-label-color);
37
34
  --t007-input-focused-label-color: var(--t007-input-focused-color);
38
35
  --t007-input-filled-label-color: var(--t007-input-base-label-color);
39
36
  --t007-input-error-label-color: var(--t007-input-error-color);
40
37
  --t007-input-disabled-label-color: var(--t007-input-disabled-color);
41
- /* value */
42
38
  --t007-input-base-value-color: rgb(from var(--t007-input-color) r g b / 1);
43
39
  --t007-input-hover-value-color: var(--t007-input-base-value-color);
44
40
  --t007-input-focused-value-color: var(--t007-input-base-value-color);
45
41
  --t007-input-filled-value-color: var(--t007-input-base-value-color);
46
42
  --t007-input-error-value-color: var(--t007-input-base-value-color);
47
43
  --t007-input-disabled-value-color: var(--t007-input-disabled-color);
48
- /* helper */
49
44
  --t007-input-base-helper-color: rgb(from var(--t007-input-color) r g b / 0.8);
50
45
  --t007-input-hover-helper-color: var(--t007-input-base-helper-color);
51
46
  --t007-input-focused-helper-color: rgb(from var(--t007-input-color) r g b / 0.9);
52
47
  --t007-input-filled-helper-color: var(--t007-input-filled-color);
53
48
  --t007-input-error-helper-color: var(--t007-input-error-color);
54
49
  --t007-input-disabled-helper-color: var(--t007-input-disabled-color);
55
- /* background */
56
50
  --t007-input-base-background-color: transparent;
57
51
  --t007-input-hover-background-color: var(--t007-input-base-background-color);
58
52
  --t007-input-focused-background-color: var(--t007-input-base-background-color);
@@ -60,10 +54,8 @@
60
54
  --t007-input-error-background-color: var(--t007-input-base-background-color);
61
55
  --t007-input-disabled-background-color: var(--t007-input-base-background-color);
62
56
  --t007-input-autofill-background-color: var(--t007-input-base-background-color);
63
- /* icon */
64
57
  --t007-input-icon-fill: var(--t007-input-color);
65
58
  --t007-input-icon-stroke: unset;
66
- /* derived */
67
59
  --t007-input-padding: calc(var(--t007-input-height) / 4);
68
60
  --t007-input-floating-label-font-size: calc(var(--t007-input-font-size) * var(--t007-input-floating-label-scale));
69
61
  --t007-input-helper-font-size: calc(var(--t007-input-font-size) * 0.7);
@@ -78,8 +70,6 @@
78
70
  --t007-input-radio-gap: calc(var(--t007-input-font-size) * 0.5);
79
71
  --t007-input-radio-size: calc(var(--t007-input-font-size) * 0.85);
80
72
  }
81
-
82
- /* checkbox input state variables */
83
73
  :where(:root) {
84
74
  --t007-input-checkmark-color: white;
85
75
  --t007-input-checkmark-width: 2px;
@@ -90,8 +80,6 @@
90
80
  --t007-input-checkbox-border-width: 1px;
91
81
  --t007-input-checkbox-border-radius: 0.2rem;
92
82
  }
93
-
94
- /* radio input state variables */
95
83
  :where(:root) {
96
84
  --t007-input-radio-color: dodgerblue;
97
85
  --t007-input-radio-background: whitesmoke;
@@ -100,25 +88,35 @@
100
88
  --t007-input-radio-checked-background: whitesmoke;
101
89
  --t007-input-radio-border-width: 1px;
102
90
  }
103
-
104
91
  .t007-input-field,
105
- .t007-input-field *[class^="t007-input"],
106
- .t007-input-field *[class^="t007-input"]::after,
107
- .t007-input-field *[class^="t007-input"]::before {
92
+ .t007-input-field *[class^=t007-input],
93
+ .t007-input-field *[class^=t007-input]::after,
94
+ .t007-input-field *[class^=t007-input]::before {
108
95
  box-sizing: border-box;
109
96
  font-family: var(--t007-input-font-family);
110
- transition-property: transform, filter, background-color, color, border, right, left, top, bottom, width, height, font-size, scale;
97
+ transition-property:
98
+ transform,
99
+ filter,
100
+ background-color,
101
+ color,
102
+ border,
103
+ right,
104
+ left,
105
+ top,
106
+ bottom,
107
+ width,
108
+ height,
109
+ font-size,
110
+ scale;
111
111
  transition-duration: 150ms;
112
112
  transition-timing-function: ease;
113
113
  }
114
-
115
114
  :where(.t007-input-field) *,
116
115
  :where(.t007-input-field) *::after,
117
116
  :where(.t007-input-field) *::before {
118
117
  padding: 0;
119
118
  margin: 0;
120
119
  }
121
-
122
120
  .t007-input-field {
123
121
  --t007-input-current-color: var(--t007-input-base-color);
124
122
  --t007-input-current-label-color: var(--t007-input-base-label-color);
@@ -131,17 +129,15 @@
131
129
  isolation: isolate;
132
130
  -webkit-font-smoothing: antialiased;
133
131
  }
134
-
135
- .t007-input-field:where(.t007-input-is-wrapper):where(:has([contenteditable="true"]:not(:empty)):not(:has([contenteditable="true"] > br:only-child)):not(:has([contenteditable="true"] > :only-child > br:only-child))),
136
- .t007-input-field:where(.t007-input-is-wrapper):where(:has([data-wrapper-filled], [contenteditable="true"][data-filled])),
137
- .t007-input-field:where(:has(.t007-input:is([data-filled], :-webkit-autofill, :not(:placeholder-shown):where(:not(select):not([type="date"]):not([type="time"]):not([type="datetime-local"]):not([type="month"]):not([type="week"]):not([type="color"]):not([type="range"]):not([type="file"]))))) {
132
+ .t007-input-field:where(.t007-input-is-wrapper):where(:has([contenteditable=true]:not(:empty)):not(:has([contenteditable=true] > br:only-child)):not(:has([contenteditable=true] > :only-child > br:only-child))),
133
+ .t007-input-field:where(.t007-input-is-wrapper):where(:has([data-wrapper-filled], [contenteditable=true][data-filled])),
134
+ .t007-input-field:where(:has(.t007-input:is([data-filled], :-webkit-autofill, :not(:placeholder-shown):where(:not(select):not([type=date]):not([type=time]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=color]):not([type=range]):not([type=file]))))) {
138
135
  --t007-input-current-color: var(--t007-input-filled-color);
139
136
  --t007-input-current-label-color: var(--t007-input-filled-label-color);
140
137
  --t007-input-current-value-color: var(--t007-input-filled-value-color);
141
138
  --t007-input-current-helper-color: var(--t007-input-filled-helper-color);
142
139
  --t007-input-current-background-color: var(--t007-input-filled-background-color);
143
140
  }
144
-
145
141
  .t007-input-field:where(:hover) {
146
142
  --t007-input-current-color: var(--t007-input-hover-color);
147
143
  --t007-input-current-label-color: var(--t007-input-hover-label-color);
@@ -149,8 +145,7 @@
149
145
  --t007-input-current-helper-color: var(--t007-input-hover-helper-color);
150
146
  --t007-input-current-background-color: var(--t007-input-hover-background-color);
151
147
  }
152
-
153
- .t007-input-field:where(.t007-input-is-wrapper):where(:has([data-wrapper-focused], [contenteditable="true"]:focus)),
148
+ .t007-input-field:where(.t007-input-is-wrapper):where(:has([data-wrapper-focused], [contenteditable=true]:focus)),
154
149
  .t007-input-field:where(:has(.t007-input:focus)) {
155
150
  --t007-input-current-color: var(--t007-input-focused-color);
156
151
  --t007-input-current-label-color: var(--t007-input-focused-label-color);
@@ -158,8 +153,7 @@
158
153
  --t007-input-current-helper-color: var(--t007-input-focused-helper-color);
159
154
  --t007-input-current-background-color: var(--t007-input-focused-background-color);
160
155
  }
161
-
162
- .t007-input-field:where(.t007-input-is-wrapper):where(:has([data-wrapper-error], [contenteditable="true"][data-error])),
156
+ .t007-input-field:where(.t007-input-is-wrapper):where(:has([data-wrapper-error], [contenteditable=true][data-error])),
163
157
  .t007-input-field:where(:has(.t007-input[data-error])) {
164
158
  --t007-input-current-color: var(--t007-input-error-color);
165
159
  --t007-input-current-label-color: var(--t007-input-error-label-color);
@@ -167,7 +161,6 @@
167
161
  --t007-input-current-helper-color: var(--t007-input-error-helper-color);
168
162
  --t007-input-current-background-color: var(--t007-input-error-background-color);
169
163
  }
170
-
171
164
  .t007-input-field:has(.t007-input:disabled) {
172
165
  --t007-input-current-color: var(--t007-input-disabled-color);
173
166
  --t007-input-current-label-color: var(--t007-input-disabled-label-color);
@@ -177,19 +170,15 @@
177
170
  opacity: var(--t007-input-disabled-opacity);
178
171
  cursor: not-allowed;
179
172
  }
180
-
181
173
  .t007-input-field:has(.t007-input:-webkit-autofill) {
182
174
  --t007-input-current-background-color: var(--t007-input-autofill-background-color);
183
175
  }
184
-
185
- .t007-input-field:where(.t007-input-no-helper:has(.t007-input[type="checkbox"], .t007-input[type="radio"])) {
176
+ .t007-input-field:where(.t007-input-no-helper:has(.t007-input[type=checkbox], .t007-input[type=radio])) {
186
177
  display: contents;
187
178
  }
188
-
189
179
  .t007-input-field:has(.t007-input[hidden]) {
190
180
  display: none;
191
181
  }
192
-
193
182
  .t007-input-wrapper {
194
183
  position: relative;
195
184
  width: 100%;
@@ -199,24 +188,19 @@
199
188
  padding: var(--t007-input-padding);
200
189
  border-radius: var(--t007-input-border-radius);
201
190
  }
202
-
203
191
  .t007-input-field.t007-input-is-wrapper .t007-input-wrapper {
204
192
  min-height: fit-content;
205
193
  padding: var(--t007-input-border-width);
206
194
  }
207
-
208
195
  .t007-input-wrapper:has(textarea) {
209
196
  min-height: fit-content;
210
197
  }
211
-
212
198
  .t007-input-wrapper:has(.t007-input-icon) {
213
199
  padding-right: 0;
214
200
  }
215
-
216
201
  .t007-input-field.t007-input-icon-override .t007-input-wrapper {
217
202
  padding-right: 12px;
218
203
  }
219
-
220
204
  .t007-input-outline {
221
205
  position: absolute;
222
206
  inset: 0;
@@ -228,7 +212,6 @@
228
212
  text-align: left;
229
213
  border-radius: inherit;
230
214
  }
231
-
232
215
  .t007-input-outline > * {
233
216
  height: 100%;
234
217
  background-color: var(--t007-input-current-background-color);
@@ -237,13 +220,11 @@
237
220
  border-style: var(--t007-input-border-style);
238
221
  pointer-events: none;
239
222
  }
240
-
241
- .t007-input-field.t007-input-is-wrapper:has([data-wrapper-focused], [contenteditable="true"]:focus) .t007-input-outline > *,
223
+ .t007-input-field.t007-input-is-wrapper:has([data-wrapper-focused], [contenteditable=true]:focus) .t007-input-outline > *,
242
224
  .t007-input-field:has(.t007-input:focus) .t007-input-outline > * {
243
225
  border-width: var(--t007-input-focused-border-width);
244
226
  border-style: var(--t007-input-focused-border-style);
245
227
  }
246
-
247
228
  .t007-input-outline-leading {
248
229
  width: max(0.75rem, var(--t007-input-border-radius));
249
230
  border-top-left-radius: inherit;
@@ -252,7 +233,6 @@
252
233
  border-bottom-right-radius: 0;
253
234
  border-right: none !important;
254
235
  }
255
-
256
236
  .t007-input-outline-trailing {
257
237
  flex: 1;
258
238
  min-width: var(--t007-input-border-radius);
@@ -262,7 +242,6 @@
262
242
  border-bottom-right-radius: inherit;
263
243
  border-left: none !important;
264
244
  }
265
-
266
245
  .t007-input-outline-notch {
267
246
  flex: 0 0 auto;
268
247
  position: relative;
@@ -270,19 +249,29 @@
270
249
  max-width: calc(100% - 0.75rem);
271
250
  border-left: none !important;
272
251
  border-right: none !important;
273
- transition-property: border-bottom, transform, filter, background-color, color, right, left, top, bottom, width, height, font-size, scale;
252
+ transition-property:
253
+ border-bottom,
254
+ transform,
255
+ filter,
256
+ background-color,
257
+ color,
258
+ right,
259
+ left,
260
+ top,
261
+ bottom,
262
+ width,
263
+ height,
264
+ font-size,
265
+ scale;
274
266
  }
275
-
276
267
  .t007-input-field:has(.t007-input-icon) .t007-input-outline-notch {
277
268
  max-width: calc(100% - 3.75rem);
278
269
  }
279
-
280
270
  .t007-input-field.t007-input-is-wrapper .t007-input-outline-notch,
281
- .t007-input-field:has(.t007-input:is([data-filled], :focus, :-webkit-autofill, :not(:placeholder-shown):where(:not(select):not([type="date"]):not([type="time"]):not([type="datetime-local"]):not([type="month"]):not([type="week"]):not([type="color"]):not([type="range"]):not([type="file"])))) .t007-input-outline-notch,
282
- .t007-input-field:has(.t007-input:is(select, :not([placeholder=""]), [type="date"], [type="time"], [type="datetime-local"], [type="month"], [type="week"], [type="color"], [type="range"], [type="file"])) .t007-input-outline-notch {
271
+ .t007-input-field:has(.t007-input:is([data-filled], :focus, :-webkit-autofill, :not(:placeholder-shown):where(:not(select):not([type=date]):not([type=time]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=color]):not([type=range]):not([type=file])))) .t007-input-outline-notch,
272
+ .t007-input-field:has(.t007-input:is(select, :not([placeholder=""]), [type=date], [type=time], [type=datetime-local], [type=month], [type=week], [type=color], [type=range], [type=file])) .t007-input-outline-notch {
283
273
  border-top: none !important;
284
274
  }
285
-
286
275
  .t007-input-floating-label {
287
276
  position: relative;
288
277
  top: calc(var(--t007-input-height) / 2);
@@ -300,27 +289,23 @@
300
289
  white-space: nowrap;
301
290
  will-change: transform;
302
291
  }
303
-
304
292
  .t007-input-floating-label:not(:empty) {
305
293
  margin-inline: 0.25rem;
306
294
  }
307
-
308
295
  .t007-input-field.t007-input-is-wrapper .t007-input-floating-label,
309
- .t007-input-field:has(.t007-input:is([data-filled], :focus, :-webkit-autofill, :not(:placeholder-shown):where(:not(select):not([type="date"]):not([type="time"]):not([type="datetime-local"]):not([type="month"]):not([type="week"]):not([type="color"]):not([type="range"]):not([type="file"])))) .t007-input-floating-label,
310
- .t007-input-field:has(.t007-input:is(select, :not([placeholder=""]), [type="date"], [type="time"], [type="datetime-local"], [type="month"], [type="week"], [type="color"], [type="range"], [type="file"])) .t007-input-floating-label {
296
+ .t007-input-field:has(.t007-input:is([data-filled], :focus, :-webkit-autofill, :not(:placeholder-shown):where(:not(select):not([type=date]):not([type=time]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=color]):not([type=range]):not([type=file])))) .t007-input-floating-label,
297
+ .t007-input-field:has(.t007-input:is(select, :not([placeholder=""]), [type=date], [type=time], [type=datetime-local], [type=month], [type=week], [type=color], [type=range], [type=file])) .t007-input-floating-label {
311
298
  transform: translateY(calc(-1 * ((var(--t007-input-height) / 2) + (var(--t007-input-font-size) / 2))));
312
299
  font-size: var(--t007-input-floating-label-font-size);
313
300
  opacity: 1;
314
301
  right: auto;
315
302
  max-width: 133%;
316
303
  }
317
-
318
304
  .t007-input-field.t007-input-is-wrapper .t007-input-floating-label.t007-input-shake,
319
- .t007-input-field:has(.t007-input:is([data-filled], :focus, :-webkit-autofill, :not(:placeholder-shown):where(:not(select):not([type="date"]):not([type="time"]):not([type="datetime-local"]):not([type="month"]):not([type="week"]):not([type="color"]):not([type="range"]):not([type="file"])))) .t007-input-floating-label.t007-input-shake,
320
- .t007-input-field:has(.t007-input:is(select, :not([placeholder=""]), [type="date"], [type="time"], [type="datetime-local"], [type="month"], [type="week"], [type="color"], [type="range"], [type="file"])) .t007-input-floating-label.t007-input-shake {
305
+ .t007-input-field:has(.t007-input:is([data-filled], :focus, :-webkit-autofill, :not(:placeholder-shown):where(:not(select):not([type=date]):not([type=time]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=color]):not([type=range]):not([type=file])))) .t007-input-floating-label.t007-input-shake,
306
+ .t007-input-field:has(.t007-input:is(select, :not([placeholder=""]), [type=date], [type=time], [type=datetime-local], [type=month], [type=week], [type=color], [type=range], [type=file])) .t007-input-floating-label.t007-input-shake {
321
307
  transform: translateY(calc(-1 * ((var(--t007-input-height) / 2) + (var(--t007-input-font-size) / 2)))) translateX(0.25rem);
322
308
  }
323
-
324
309
  .t007-input {
325
310
  border: none;
326
311
  background: none;
@@ -336,49 +321,39 @@
336
321
  font-family: inherit;
337
322
  outline: none !important;
338
323
  }
339
-
340
- .t007-input[type="file"] {
324
+ .t007-input[type=file] {
341
325
  height: unset;
342
326
  }
343
-
344
- .t007-input:is([type="checkbox"], [type="radio"]) {
327
+ .t007-input:is([type=checkbox], [type=radio]) {
345
328
  opacity: 0;
346
329
  position: absolute;
347
330
  pointer-events: none;
348
331
  }
349
-
350
332
  .t007-input:not(select) {
351
333
  appearance: none;
352
334
  }
353
-
354
335
  .t007-input:where(textarea) {
355
336
  min-height: 100%;
356
337
  height: auto;
357
338
  resize: none;
358
339
  }
359
-
360
340
  :where(select.t007-input::picker(select)) {
361
341
  color: black;
362
342
  }
363
-
364
343
  .t007-input::placeholder {
365
344
  color: currentColor;
366
345
  opacity: 0.55;
367
346
  }
368
-
369
- .t007-input-field:has(.t007-input[type="file"]) {
370
- /* computed values for the selector button */
347
+ .t007-input-field:has(.t007-input[type=file]) {
371
348
  --t007-input-sb-active-margin: calc((var(--t007-input-floating-label-font-size) * 1.3) / 2);
372
349
  --t007-input-sb-padding-inline: calc(var(--t007-input-font-size) / 3.5);
373
350
  --t007-input-sb-padding-block: calc(((var(--t007-input-height) / 2) - ((var(--t007-input-font-size) / 1.25) / 2)) - ((var(--t007-input-floating-label-font-size) * 1.3) / 2) - 1px);
374
351
  }
375
-
376
- .t007-input-wrapper:has(.t007-input[type="file"]) {
352
+ .t007-input-wrapper:has(.t007-input[type=file]) {
377
353
  padding-block: var(--t007-input-sb-active-margin);
378
354
  padding-left: var(--t007-input-sb-active-margin);
379
355
  }
380
-
381
- :where(.t007-input[type="file"])::file-selector-button {
356
+ :where(.t007-input[type=file])::file-selector-button {
382
357
  font-family: inherit;
383
358
  font-weight: bold;
384
359
  font-size: calc(var(--t007-input-font-size) / 1.25);
@@ -394,16 +369,13 @@
394
369
  cursor: pointer;
395
370
  transition: filter 200ms ease;
396
371
  }
397
-
398
- :where(.t007-input[type="file"])::file-selector-button:where(:active) {
372
+ :where(.t007-input[type=file])::file-selector-button:where(:active) {
399
373
  border-width: 1px;
400
374
  }
401
-
402
- :where(.t007-input[type="file"])::file-selector-button:where(:hover, :focus-visible) {
375
+ :where(.t007-input[type=file])::file-selector-button:where(:hover, :focus-visible) {
403
376
  filter: brightness(80%);
404
377
  }
405
-
406
- :where(.t007-input[type="file"].t007-input-image-selected)::file-selector-button {
378
+ :where(.t007-input[type=file].t007-input-image-selected)::file-selector-button {
407
379
  background:
408
380
  center/contain no-repeat var(--t007-input-image-src),
409
381
  linear-gradient(black, black),
@@ -412,16 +384,13 @@
412
384
  padding-block: var(--t007-input-sb-padding-block);
413
385
  border: none;
414
386
  }
415
-
416
387
  .t007-input:-webkit-autofill {
417
388
  transition: background-color 50000000s ease-in-out 0s !important;
418
389
  -webkit-text-fill-color: var(--t007-input-current-value-color) !important;
419
390
  }
420
-
421
391
  .t007-input-field.t007-input-icon-override input::-webkit-calendar-picker-indicator {
422
392
  opacity: 0;
423
393
  }
424
-
425
394
  .t007-input-icon {
426
395
  background: none;
427
396
  border: none;
@@ -434,43 +403,35 @@
434
403
  justify-content: center;
435
404
  pointer-events: none;
436
405
  }
437
-
438
406
  .t007-input-icon:is(.t007-input-password-hidden-icon, .t007-input-password-visible-icon) {
439
407
  pointer-events: all;
440
408
  }
441
-
442
409
  .t007-input-icon:hover {
443
410
  background-color: rgba(0, 0, 0, 0.02);
444
411
  }
445
-
446
412
  .t007-input-field.t007-input-icon-override .t007-input-icon {
447
413
  position: absolute;
448
414
  right: 0;
449
415
  }
450
-
451
416
  .t007-input-field.t007-input-icon-override svg,
452
417
  .t007-input-icon svg {
453
418
  width: var(--t007-input-icon-width);
454
419
  height: var(--t007-input-icon-height);
455
420
  }
456
-
457
421
  .t007-input-icon svg path {
458
422
  fill: var(--t007-input-icon-fill);
459
423
  stroke: var(--t007-input-icon-stroke);
460
424
  }
461
-
462
- .t007-input-field:has(input[type="password"]) .t007-input-password-visible-icon,
463
- .t007-input-field:has(input[type="text"]) .t007-input-password-hidden-icon {
425
+ .t007-input-field:has(input[type=password]) .t007-input-password-visible-icon,
426
+ .t007-input-field:has(input[type=text]) .t007-input-password-hidden-icon {
464
427
  display: none;
465
428
  }
466
-
467
429
  .t007-input-helper-line {
468
430
  position: relative;
469
431
  margin-inline: 1rem;
470
432
  height: calc(var(--t007-input-helper-font-size) * 1.4);
471
433
  color: var(--t007-input-current-helper-color);
472
434
  }
473
-
474
435
  .t007-input-helper-text-wrapper {
475
436
  position: relative;
476
437
  width: 100%;
@@ -479,31 +440,31 @@
479
440
  overflow-y: hidden;
480
441
  scrollbar-width: none;
481
442
  }
482
-
483
443
  .t007-input-helper-text-wrapper::-webkit-scrollbar {
484
444
  display: none;
485
445
  }
486
-
487
446
  .t007-input-scroll-assist {
488
447
  position: absolute;
489
448
  top: 1px;
490
449
  min-width: 2rem;
491
450
  height: 100%;
492
451
  opacity: 0.075;
493
- background: linear-gradient(var(--gradient-dir), transparent 0, currentColor 30%, transparent);
452
+ background:
453
+ linear-gradient(
454
+ var(--gradient-dir),
455
+ transparent 0,
456
+ currentColor 30%,
457
+ transparent);
494
458
  z-index: 2;
495
459
  }
496
-
497
- .t007-input-scroll-assist[data-scroll-direction="left"] {
460
+ .t007-input-scroll-assist[data-scroll-direction=left] {
498
461
  left: -0.25rem;
499
462
  --gradient-dir: to right;
500
463
  }
501
-
502
- .t007-input-scroll-assist[data-scroll-direction="right"] {
464
+ .t007-input-scroll-assist[data-scroll-direction=right] {
503
465
  right: -0.25rem;
504
466
  --gradient-dir: to left;
505
467
  }
506
-
507
468
  .t007-input-helper-text {
508
469
  position: absolute;
509
470
  top: 2px;
@@ -512,39 +473,31 @@
512
473
  line-height: 1.2;
513
474
  white-space: nowrap;
514
475
  }
515
-
516
- .t007-input-helper-text[data-violation="none"],
476
+ .t007-input-helper-text[data-violation=none],
517
477
  .t007-input-helper-text.t007-input-show {
518
478
  opacity: 1;
519
479
  }
520
-
521
- .t007-input-helper-line:has(.t007-input-show) [data-violation="none"],
522
- .t007-input-helper-line:not(:has(.t007-input-show, [data-violation="none"])) .t007-input-scroll-assist {
480
+ .t007-input-helper-line:has(.t007-input-show) [data-violation=none],
481
+ .t007-input-helper-line:not(:has(.t007-input-show, [data-violation=none])) .t007-input-scroll-assist {
523
482
  opacity: 0;
524
483
  }
525
-
526
484
  .t007-input-password-meter {
527
485
  --t007-input-p-meter-current-color: var(--t007-input-p-meter-color-weak);
528
486
  display: none;
529
487
  margin-top: 0.75rem;
530
488
  }
531
-
532
- .t007-input-field:has(.t007-input:is([type="password"], [type="text"]):is([data-filled], :-webkit-autofill, :not(:placeholder-shown))) .t007-input-password-meter {
489
+ .t007-input-field:has(.t007-input:is([type=password], [type=text]):is([data-filled], :-webkit-autofill, :not(:placeholder-shown))) .t007-input-password-meter {
533
490
  display: block;
534
491
  }
535
-
536
492
  .t007-input-password-meter[data-strength-level="2"] {
537
493
  --t007-input-p-meter-current-color: var(--t007-input-p-meter-color-fair);
538
494
  }
539
-
540
495
  .t007-input-password-meter[data-strength-level="3"] {
541
496
  --t007-input-p-meter-current-color: var(--t007-input-p-meter-color-strong);
542
497
  }
543
-
544
498
  .t007-input-password-meter[data-strength-level="4"] {
545
499
  --t007-input-p-meter-current-color: var(--t007-input-p-meter-color-very-strong);
546
500
  }
547
-
548
501
  .t007-input-password-meter::after {
549
502
  content: "";
550
503
  position: relative;
@@ -556,123 +509,98 @@
556
509
  color: var(--t007-input-p-meter-current-color);
557
510
  line-height: normal;
558
511
  }
559
-
560
512
  .t007-input-password-meter[data-strength-level="1"]::after {
561
513
  content: "Weak";
562
514
  }
563
-
564
515
  .t007-input-password-meter[data-strength-level="2"]::after {
565
516
  content: "Fair";
566
517
  }
567
-
568
518
  .t007-input-password-meter[data-strength-level="3"]::after {
569
519
  content: "Strong";
570
520
  }
571
-
572
521
  .t007-input-password-meter[data-strength-level="4"]::after {
573
522
  content: "Very Strong";
574
523
  }
575
-
576
524
  .t007-input-password-strength-meter {
577
525
  display: flex;
578
526
  }
579
-
580
527
  .t007-input-password-strength-meter > div {
581
528
  flex: 1;
582
529
  margin-right: var(--t007-input-p-meter-gap);
583
530
  height: var(--t007-input-p-meter-height);
584
531
  border-radius: var(--t007-input-p-meter-border-radius);
585
532
  }
586
-
587
533
  .t007-input-password-meter[data-strength-level="1"] .t007-input-p-weak,
588
534
  .t007-input-password-meter[data-strength-level="2"] :is(.t007-input-p-weak, .t007-input-p-fair),
589
535
  .t007-input-password-meter[data-strength-level="3"] :is(.t007-input-p-weak, .t007-input-p-fair, .t007-input-p-strong),
590
536
  .t007-input-password-meter[data-strength-level="4"] :is(.t007-input-p-weak, .t007-input-p-fair, .t007-input-p-strong, .t007-input-p-very-strong) {
591
537
  background-color: var(--t007-input-p-meter-current-color);
592
538
  }
593
-
594
539
  .t007-input-checkbox-wrapper,
595
540
  .t007-input-radio-wrapper {
596
541
  position: relative;
597
542
  display: inline-flex;
598
543
  align-items: center;
599
544
  }
600
-
601
545
  .t007-input-checkbox-wrapper {
602
546
  font-size: var(--t007-input-checkbox-font-size);
603
547
  }
604
-
605
548
  .t007-input-radio-wrapper {
606
549
  font-size: var(--t007-input-radio-font-size);
607
550
  }
608
-
609
551
  .t007-input-checkbox-label,
610
552
  .t007-input-radio-label {
611
553
  color: var(--t007-input-current-label-color);
612
554
  }
613
-
614
555
  .t007-input-checkbox-label:not(:empty) {
615
556
  margin-left: var(--t007-input-checkbox-gap);
616
557
  }
617
-
618
558
  .t007-input-radio-label:not(:empty) {
619
559
  margin-left: var(--t007-input-radio-gap);
620
560
  }
621
-
622
561
  :is(.t007-input-checkbox-wrapper, .t007-input-radio-wrapper):hover {
623
562
  filter: brightness(95%);
624
563
  }
625
-
626
564
  .t007-input-checkbox-box,
627
565
  .t007-input-radio-box {
628
566
  position: relative;
629
567
  border-style: solid;
630
568
  }
631
-
632
569
  .t007-input-checkbox-box {
633
570
  width: var(--t007-input-checkbox-size);
634
571
  height: var(--t007-input-checkbox-size);
635
572
  border-width: var(--t007-input-checkbox-border-width);
636
573
  }
637
-
638
574
  .t007-input-radio-box {
639
575
  width: var(--t007-input-radio-size);
640
576
  height: var(--t007-input-radio-size);
641
577
  border-width: var(--t007-input-radio-border-width);
642
578
  }
643
-
644
579
  .t007-input-checkbox-box {
645
580
  background: var(--t007-input-checkbox-background);
646
581
  border-color: var(--t007-input-checkbox-border-color);
647
582
  }
648
-
649
583
  .t007-input-radio-box {
650
584
  background: var(--t007-input-radio-background);
651
585
  border-color: var(--t007-input-radio-border-color);
652
586
  }
653
-
654
587
  .t007-input-checkbox-box {
655
588
  border-radius: var(--t007-input-checkbox-border-radius);
656
589
  }
657
-
658
590
  .t007-input-radio-box {
659
591
  border-radius: 50%;
660
592
  }
661
-
662
- .t007-input-field:has(.t007-input[type="checkbox"]:checked) .t007-input-checkbox-box {
593
+ .t007-input-field:has(.t007-input[type=checkbox]:checked) .t007-input-checkbox-box {
663
594
  background: var(--t007-input-checkbox-checked-background);
664
595
  border-color: var(--t007-input-checkbox-checked-border-color);
665
596
  }
666
-
667
- .t007-input-field:has(.t007-input[type="radio"]:checked) .t007-input-radio-box {
597
+ .t007-input-field:has(.t007-input[type=radio]:checked) .t007-input-radio-box {
668
598
  background: var(--t007-input-radio-checked-background);
669
599
  border-color: var(--t007-input-radio-checked-border-color);
670
600
  }
671
-
672
- .t007-input-field:has(.t007-input:is([type="checkbox"], [type="radio"])[data-error]) :is(.t007-input-checkbox-box, .t007-input-radio-box) {
601
+ .t007-input-field:has(.t007-input:is([type=checkbox], [type=radio])[data-error]) :is(.t007-input-checkbox-box, .t007-input-radio-box) {
673
602
  border-color: var(--t007-input-error-color);
674
603
  }
675
-
676
604
  .t007-input-checkbox-tag,
677
605
  .t007-input-radio-tag {
678
606
  content: "";
@@ -682,7 +610,6 @@
682
610
  left: 2.6%;
683
611
  margin: auto;
684
612
  }
685
-
686
613
  .t007-input-checkbox-tag {
687
614
  top: -14.25%;
688
615
  width: 35%;
@@ -691,7 +618,6 @@
691
618
  border-width: 0 var(--t007-input-checkmark-width) var(--t007-input-checkmark-width) 0;
692
619
  transform: rotate(45deg);
693
620
  }
694
-
695
621
  .t007-input-field.t007-input-indeterminate .t007-input-checkbox-tag {
696
622
  top: 50%;
697
623
  left: 50.5%;
@@ -702,7 +628,6 @@
702
628
  background-color: var(--t007-input-checkmark-color);
703
629
  border: none;
704
630
  }
705
-
706
631
  .t007-input-radio-tag {
707
632
  width: 70%;
708
633
  height: 72.5%;
@@ -712,21 +637,16 @@
712
637
  scale: 0;
713
638
  transition-timing-function: cubic-bezier(0.34, 1.64, 0.64, 1);
714
639
  }
715
-
716
- .t007-input-field:has(.t007-input:is([type="radio"], [type="checkbox"]):checked) :is(.t007-input-checkbox-tag, .t007-input-radio-tag) {
640
+ .t007-input-field:has(.t007-input:is([type=radio], [type=checkbox]):checked) :is(.t007-input-checkbox-tag, .t007-input-radio-tag) {
717
641
  opacity: 1;
718
642
  scale: 1;
719
643
  }
720
-
721
- /* Base styles to enable pointer effects */
722
644
  :where(.t007-input-rippler),
723
645
  .t007-input-checkbox-box,
724
646
  .t007-input-radio-box {
725
647
  position: relative;
726
648
  outline: none !important;
727
649
  }
728
-
729
- /* Pulse bubble effect on click */
730
650
  .t007-input-rippler::before,
731
651
  .t007-input-checkbox-box::before,
732
652
  .t007-input-radio-box::before {
@@ -739,27 +659,27 @@
739
659
  background: var(--t007-input-ripple-color);
740
660
  border-radius: 50%;
741
661
  transform: translate(-50%, -50%);
742
- transition-property: width, height, opacity;
662
+ transition-property:
663
+ width,
664
+ height,
665
+ opacity;
743
666
  transition-duration: 300ms;
744
667
  transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);
745
668
  opacity: 0;
746
669
  pointer-events: none;
747
670
  }
748
-
749
671
  .t007-input-rippler:is(:hover, :focus-visible, :has(:focus-visible), :has(~ :focus-visible))::before,
750
- .t007-input-field:is(:hover, :has(.t007-input[type="checkbox"]:focus-visible)) .t007-input-checkbox-box::before,
751
- .t007-input-field:is(:hover, :has(.t007-input[type="radio"]:focus-visible)) .t007-input-radio-box::before {
672
+ .t007-input-field:is(:hover, :has(.t007-input[type=checkbox]:focus-visible)) .t007-input-checkbox-box::before,
673
+ .t007-input-field:is(:hover, :has(.t007-input[type=radio]:focus-visible)) .t007-input-radio-box::before {
752
674
  width: var(--t007-input-ripple-size);
753
675
  height: var(--t007-input-ripple-size);
754
676
  opacity: 1;
755
677
  }
756
-
757
678
  .t007-input-rippler:is(:checked, :has(:checked), :has(~ :checked))::before,
758
- .t007-input-field:has(.t007-input[type="checkbox"]:checked) .t007-input-checkbox-box::before,
759
- .t007-input-field:has(.t007-input[type="radio"]:checked) .t007-input-radio-box::before {
679
+ .t007-input-field:has(.t007-input[type=checkbox]:checked) .t007-input-checkbox-box::before,
680
+ .t007-input-field:has(.t007-input[type=radio]:checked) .t007-input-radio-box::before {
760
681
  animation: t007-ripple-pulse 350ms ease-out;
761
682
  }
762
-
763
683
  @keyframes t007-ripple-pulse {
764
684
  0% {
765
685
  width: 0;
@@ -25,8 +25,11 @@
25
25
  for (const k of Object.keys(styles)) if (styles[k] !== void 0) el.style[k] = styles[k];
26
26
  }
27
27
  }
28
- function loadResource(src, type = "style", { module, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, attempts = 3, retryKey = false } = {}, w = window) {
28
+ var VIRTUAL_RESOURCE = /* @__PURE__ */ Symbol.for("T007_VIRTUAL_RESOURCE");
29
+ function loadResource(req, type = "style", { module, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, attempts = 3, retryKey = false } = {}, w = window) {
29
30
  w.t007._resourceCache ??= {};
31
+ if (req === VIRTUAL_RESOURCE || "symbol" === typeof req) return Promise.resolve();
32
+ const src = req;
30
33
  if (w.t007._resourceCache[src]) return w.t007._resourceCache[src];
31
34
  const existing = type === "script" ? Array.prototype.find.call(w.document.scripts, (s) => isSameURL(s.src, src)) : type === "style" ? Array.prototype.find.call(w.document.styleSheets, (s) => isSameURL(s.href, src)) : null;
32
35
  if (existing) return w.t007._resourceCache[src] = Promise.resolve(existing);
@@ -123,12 +126,13 @@
123
126
  }
124
127
  if (typeof window !== "undefined") {
125
128
  window.t007 ??= {};
129
+ t007.VIRTUAL_RESOURCE = VIRTUAL_RESOURCE;
126
130
  window.T007_TOAST_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest`;
127
131
  window.T007_INPUT_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest`;
128
132
  window.T007_DIALOG_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest`;
129
- window.T007_TOAST_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest/style.css`;
130
- window.T007_INPUT_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest/style.css`;
131
- window.T007_DIALOG_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest/style.css`;
133
+ window.T007_TOAST_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest/dist/index.min.css`;
134
+ window.T007_INPUT_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest/dist/index.min.css`;
135
+ window.T007_DIALOG_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest/dist/index.min.css`;
132
136
  }
133
137
 
134
138
  // src/index.js
@@ -23,8 +23,11 @@ function assignEl(el, props, dataset, styles) {
23
23
  for (const k of Object.keys(styles)) if (styles[k] !== void 0) el.style[k] = styles[k];
24
24
  }
25
25
  }
26
- function loadResource(src, type = "style", { module, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, attempts = 3, retryKey = false } = {}, w = window) {
26
+ var VIRTUAL_RESOURCE = /* @__PURE__ */ Symbol.for("T007_VIRTUAL_RESOURCE");
27
+ function loadResource(req, type = "style", { module, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, attempts = 3, retryKey = false } = {}, w = window) {
27
28
  w.t007._resourceCache ??= {};
29
+ if (req === VIRTUAL_RESOURCE || "symbol" === typeof req) return Promise.resolve();
30
+ const src = req;
28
31
  if (w.t007._resourceCache[src]) return w.t007._resourceCache[src];
29
32
  const existing = type === "script" ? Array.prototype.find.call(w.document.scripts, (s) => isSameURL(s.src, src)) : type === "style" ? Array.prototype.find.call(w.document.styleSheets, (s) => isSameURL(s.href, src)) : null;
30
33
  if (existing) return w.t007._resourceCache[src] = Promise.resolve(existing);
@@ -121,12 +124,13 @@ function initScrollAssist(el, { pxPerSecond = 80, assistClassName = "tmg-video-c
121
124
  }
122
125
  if (typeof window !== "undefined") {
123
126
  window.t007 ??= {};
127
+ t007.VIRTUAL_RESOURCE = VIRTUAL_RESOURCE;
124
128
  window.T007_TOAST_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest`;
125
129
  window.T007_INPUT_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest`;
126
130
  window.T007_DIALOG_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest`;
127
- window.T007_TOAST_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest/style.css`;
128
- window.T007_INPUT_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest/style.css`;
129
- window.T007_DIALOG_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest/style.css`;
131
+ window.T007_TOAST_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest/dist/index.min.css`;
132
+ window.T007_INPUT_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest/dist/index.min.css`;
133
+ window.T007_DIALOG_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest/dist/index.min.css`;
130
134
  }
131
135
 
132
136
  // src/index.js
package/package.json CHANGED
@@ -1,56 +1,59 @@
1
1
  {
2
2
  "name": "@t007/input",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "A lightweight, pure JS input system.",
5
5
  "author": "Oketade Oluwatobiloba <tobioketade007@gmail.com>",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "git+https://github.com/tobi007-del/t007-tools.git",
9
+ "url": "git+https://github.com/Tobi007-del/t007-tools.git",
10
10
  "directory": "packages/input"
11
11
  },
12
- "homepage": "https://github.com/tobi007-del/t007-tools/tree/main/packages/input#readme",
12
+ "homepage": "https://github.com/Tobi007-del/t007-tools/tree/main/packages/input#readme",
13
13
  "bugs": {
14
- "url": "https://github.com/tobi007-del/t007-tools/issues"
14
+ "url": "https://github.com/Tobi007-del/t007-tools/issues"
15
15
  },
16
16
  "type": "module",
17
17
  "main": "./dist/index.js",
18
18
  "module": "./dist/index.js",
19
19
  "unpkg": "./dist/index.global.js",
20
20
  "jsdelivr": "./dist/index.global.js",
21
- "types": "./src/ts/types/index.d.ts",
22
- "style": "./src/css/index.css",
21
+ "types": "./dist/index.d.ts",
22
+ "style": "./dist/index.css",
23
23
  "sideEffects": [
24
24
  "*.css"
25
25
  ],
26
26
  "exports": {
27
27
  ".": {
28
- "types": "./src/ts/types/index.d.ts",
28
+ "types": "./dist/index.d.ts",
29
29
  "import": "./dist/index.js",
30
30
  "default": "./dist/index.js"
31
31
  },
32
32
  "./standalone": "./dist/standalone.js",
33
33
  "./global": "./dist/index.global.js",
34
- "./style.css": "./src/css/index.css"
34
+ "./style.css": "./dist/index.css"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public"
35
38
  },
36
39
  "scripts": {
37
- "build": "tsup --config ../../tsup.config.ts"
40
+ "build": "tsup --config ../../tsup.config.ts",
41
+ "prepublishOnly": "shx cp ../../LICENSE ."
38
42
  },
39
43
  "files": [
40
- "dist",
41
- "./src/ts/types/index.d.ts",
42
- "./src/css/index.css"
44
+ "dist"
43
45
  ],
44
46
  "keywords": [
47
+ "t007",
48
+ "ecosystem",
49
+ "ui",
50
+ "vanilla-js",
45
51
  "input",
46
52
  "form",
47
53
  "form-validation",
48
54
  "form-manager",
49
55
  "file-upload",
50
56
  "password-meter",
51
- "t007",
52
- "ui",
53
- "vanilla-js",
54
57
  "monkey-patch"
55
58
  ],
56
59
  "dependencies": {
File without changes