@maihcx/super-date 0.3.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 maihcx
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,191 @@
1
+ # SuperDate
2
+
3
+ TypeScript date/time input enhancer. Replaces the native browser date-picker chrome with a fully custom, format-aware overlay — while still delegating the actual popup to the OS so you never re-implement a calendar or clock widget.
4
+
5
+ Supports `input[type="date"]`, `input[type="time"]`, and `input[type="datetime-local"]`.
6
+
7
+ ## Features
8
+
9
+ | Feature | Detail |
10
+ |---|---|
11
+ | **3 input types** | `date`, `time`, and `datetime-local` all supported |
12
+ | **Auto-observe** | `SuperDate.bind('.selector')` watches the DOM via `MutationObserver` — inputs added later are automatically enhanced |
13
+ | **Custom format** | Global default or per-element via `data-date-format`, `data-time-format`, `data-date-time-delimiter` |
14
+ | **Keyboard editing** | `↑ ↓` step values, `← →` move segments, `0–9` type digits, auto-advance on completion |
15
+ | **Copy / Paste** | Parses pasted text against configured format + common fallbacks |
16
+ | **Native picker** | Calendar / clock icon opens the OS picker; `input.value` stays as ISO string |
17
+ | **Zero dependencies** | Plain TypeScript, no runtime deps |
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ npm install superdate # if published
23
+ # or copy dist/ into your project
24
+ ```
25
+
26
+ ## Build
27
+
28
+ ```bash
29
+ npm install
30
+ npm run build
31
+ ```
32
+
33
+ Outputs:
34
+
35
+ | File | Format |
36
+ |---|---|
37
+ | `dist/super-date.esm.js` | ES Module |
38
+ | `dist/super-date.esm.min.js` | ES Module (minified) |
39
+ | `dist/super-date.umd.js` | UMD (browser global `SuperDate`) |
40
+ | `dist/super-date.min.js` | UMD (minified) |
41
+
42
+ ## Usage
43
+
44
+ ### Via `<script>` tag
45
+
46
+ ```html
47
+ <link rel="stylesheet" href="dist/super-date.min.css" />
48
+ <script src="dist/super-date.umd.js"></script>
49
+ <script>
50
+ SuperDate.bind('.sd', { format: 'dd/MM/yyyy' });
51
+ </script>
52
+ ```
53
+
54
+ ### ES Module
55
+
56
+ ```js
57
+ import SuperDate from './dist/super-date.esm.js';
58
+ SuperDate.bind('.sd', { format: 'dd/MM/yyyy' });
59
+ ```
60
+
61
+ ### TypeScript / bundler
62
+
63
+ ```ts
64
+ import SuperDate from 'superdate';
65
+ SuperDate.bind('.sd');
66
+ ```
67
+
68
+ ## API
69
+
70
+ ### `SuperDate.bind(selector, options?)`
71
+
72
+ Enhances all current **and future** `<input type="date">`, `<input type="time">`, and `<input type="datetime-local">` elements matching `selector`.
73
+
74
+ ```ts
75
+ SuperDate.bind('.sd', {
76
+ format: 'dd/MM/yyyy', // date display format
77
+ timeFormat: 'HH:mm', // time display format
78
+ dateTimeDelimiter: ' ', // separator between date and time parts
79
+ locale: 'vi-VN', // locale (reserved for future i18n)
80
+ });
81
+ ```
82
+
83
+ Returns `this` for chaining.
84
+
85
+ ### `SuperDate.init(el, options?)`
86
+
87
+ Manually enhance a single element. Returns the `SuperDateInstance`.
88
+
89
+ ```ts
90
+ const el = document.querySelector('#my-input') as HTMLInputElement;
91
+ SuperDate.init(el, { format: 'yyyy/MM/dd' });
92
+ ```
93
+
94
+ ### `SuperDate.destroy(el)`
95
+
96
+ Remove the overlay and restore the original native input.
97
+
98
+ ## Options
99
+
100
+ | Option | Type | Default | Description |
101
+ |---|---|---|---|
102
+ | `format` | `string` | `'dd/MM/yyyy'` | Display format for `date` and the date part of `datetime-local` inputs |
103
+ | `timeFormat` | `string` | `'HH:mm'` | Display format for `time` and the time part of `datetime-local` inputs |
104
+ | `dateTimeDelimiter` | `string` | `' '` | String inserted between date and time parts in `datetime-local` inputs |
105
+ | `locale` | `string` | `navigator.language` | Locale (reserved) |
106
+
107
+ ## Per-element overrides (data attributes)
108
+
109
+ ```html
110
+ <!-- date -->
111
+ <input type="date" data-date-format="yyyy/MM/dd" />
112
+
113
+ <!-- time -->
114
+ <input type="time" data-time-format="HH:mm:ss" />
115
+
116
+ <!-- datetime-local — all three can be combined -->
117
+ <input type="datetime-local"
118
+ data-date-format="dd/MM/yyyy"
119
+ data-time-format="HH:mm:ss"
120
+ data-date-time-delimiter=" | " />
121
+ ```
122
+
123
+ Per-element attributes always take priority over `bind()` options.
124
+
125
+ ## Supported tokens
126
+
127
+ ### Date tokens
128
+
129
+ | Token | Description | Example |
130
+ |---|---|---|
131
+ | `yyyy` | 4-digit year | `2025` |
132
+ | `yy` | 2-digit year | `25` |
133
+ | `MM` | Month, zero-padded | `03` |
134
+ | `M` | Month, no padding | `3` |
135
+ | `dd` | Day, zero-padded | `07` |
136
+ | `d` | Day, no padding | `7` |
137
+
138
+ ### Time tokens
139
+
140
+ | Token | Description | Example |
141
+ |---|---|---|
142
+ | `HH` | Hours 24h, zero-padded | `09`, `23` |
143
+ | `H` | Hours 24h, no padding | `9`, `23` |
144
+ | `hh` | Hours 12h, zero-padded | `09`, `11` |
145
+ | `h` | Hours 12h, no padding | `9`, `11` |
146
+ | `mm` | Minutes, zero-padded | `05`, `59` |
147
+ | `ss` | Seconds, zero-padded | `00`, `59` |
148
+
149
+ > **Note:** `MM` = months (uppercase), `mm` = minutes (lowercase).
150
+
151
+ ## CSS variables
152
+
153
+ Override the overlay appearance per-element or globally:
154
+
155
+ ```css
156
+ .superdate-overlay {
157
+ --superdate-active-bg: #2563eb; /* active segment background */
158
+ --superdate-active-color: #fff; /* active segment text */
159
+ --superdate-placeholder-color: #9ca3af; /* empty segment placeholder */
160
+ --superdate-sep-color: inherit; /* separator / literal color */
161
+ }
162
+ ```
163
+
164
+ ## Keyboard shortcuts
165
+
166
+ | Key | Action |
167
+ |---|---|
168
+ | `0–9` | Type digit into active segment, auto-advance when full |
169
+ | `↑` / `↓` | Increment / decrement active segment value |
170
+ | `←` / `→` | Move to previous / next segment |
171
+ | `Tab` / `Shift+Tab` | Move to next / previous segment |
172
+ | `Backspace` | Erase last typed digit in buffer |
173
+ | `Escape` | Deactivate / clear selection |
174
+ | `Ctrl+A` | Select all segments |
175
+ | `Ctrl+C` | Copy selected segments as formatted text |
176
+ | Click & drag | Multi-segment selection |
177
+ | Double-click | Select all segments |
178
+
179
+ ## Input value
180
+
181
+ The underlying `input.value` always stays in native ISO format — SuperDate only changes the **visual overlay**:
182
+
183
+ | Input type | `input.value` format |
184
+ |---|---|
185
+ | `date` | `yyyy-MM-dd` |
186
+ | `time` | `HH:mm:ss` |
187
+ | `datetime-local` | `yyyy-MM-ddTHH:mm:ss` |
188
+
189
+ ## License
190
+
191
+ MIT
@@ -0,0 +1,86 @@
1
+ input.superdate-input::-webkit-datetime-edit,
2
+ input.superdate-input::-webkit-inner-spin-button,
3
+ input.superdate-input::-webkit-clear-button,
4
+ input.superdate-input::-webkit-calendar-picker-indicator {
5
+ display: none !important;
6
+ opacity: 0 !important;
7
+ width: 0 !important;
8
+ }
9
+ input.superdate-input {
10
+ caret-color: transparent;
11
+ color: transparent !important;
12
+ position: relative;
13
+ }
14
+
15
+ /* Overlay wrapper */
16
+ .superdate-wrapper {
17
+ position: relative;
18
+ display: inline-block;
19
+ width: fit-content;
20
+ }
21
+
22
+ /* The visible overlay */
23
+ .superdate-overlay {
24
+ position: absolute;
25
+ inset: 0;
26
+ display: flex;
27
+ align-items: center;
28
+ padding: 0 8px;
29
+ pointer-events: none;
30
+ font: inherit;
31
+ letter-spacing: inherit;
32
+ white-space: nowrap;
33
+ overflow: hidden;
34
+ box-sizing: border-box;
35
+ gap: 0;
36
+ /* prevent browser text selection interfering with drag */
37
+ user-select: none;
38
+ -webkit-user-select: none;
39
+ }
40
+
41
+ .superdate-seg {
42
+ position: relative;
43
+ display: inline-block;
44
+ border-radius: 2px;
45
+ transition: background 0.1s;
46
+ white-space: pre;
47
+ }
48
+
49
+ .superdate-seg[data-token] {
50
+ pointer-events: auto;
51
+ cursor: text;
52
+ min-width: 1ch;
53
+ text-align: center;
54
+ }
55
+
56
+ /* Single-seg focus OR multi-seg drag selection — same colour, same class */
57
+ .superdate-seg[data-token].active {
58
+ background: var(--superdate-active-bg, #2563eb);
59
+ color: var(--superdate-active-color, #fff);
60
+ border-radius: 3px;
61
+ }
62
+
63
+ .superdate-seg[data-token].empty {
64
+ color: var(--superdate-placeholder-color, #9ca3af);
65
+ }
66
+
67
+ .superdate-seg:not([data-token]) {
68
+ color: var(--superdate-sep-color, inherit);
69
+ pointer-events: none;
70
+ }
71
+
72
+ /* Calendar icon area */
73
+ .superdate-icon {
74
+ pointer-events: auto;
75
+ cursor: pointer;
76
+ display: flex;
77
+ align-items: center;
78
+ margin-left: auto;
79
+ padding-left: 6px;
80
+ opacity: 0.5;
81
+ transition: opacity 0.15s;
82
+ flex-shrink: 0;
83
+ }
84
+ .superdate-icon:hover { opacity: 1; }
85
+
86
+ /*# sourceMappingURL=super-date.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["index.css"],"names":[],"mappings":"AAAA;;;;EAIE,wBAAwB;EACxB,qBAAqB;EACrB,mBAAmB;AACrB;AACA;EACE,wBAAwB;EACxB,6BAA6B;EAC7B,kBAAkB;AACpB;;AAEA,oBAAoB;AACpB;EACE,kBAAkB;EAClB,qBAAqB;EACrB,kBAAkB;AACpB;;AAEA,wBAAwB;AACxB;EACE,kBAAkB;EAClB,QAAQ;EACR,aAAa;EACb,mBAAmB;EACnB,cAAc;EACd,oBAAoB;EACpB,aAAa;EACb,uBAAuB;EACvB,mBAAmB;EACnB,gBAAgB;EAChB,sBAAsB;EACtB,MAAM;EACN,yDAAyD;EACzD,iBAAiB;EACjB,yBAAyB;AAC3B;;AAEA;EACE,kBAAkB;EAClB,qBAAqB;EACrB,kBAAkB;EAClB,2BAA2B;EAC3B,gBAAgB;AAClB;;AAEA;EACE,oBAAoB;EACpB,YAAY;EACZ,cAAc;EACd,kBAAkB;AACpB;;AAEA,2EAA2E;AAC3E;EACE,+CAA+C;EAC/C,0CAA0C;EAC1C,kBAAkB;AACpB;;AAEA;EACE,kDAAkD;AACpD;;AAEA;EACE,0CAA0C;EAC1C,oBAAoB;AACtB;;AAEA,uBAAuB;AACvB;EACE,oBAAoB;EACpB,eAAe;EACf,aAAa;EACb,mBAAmB;EACnB,iBAAiB;EACjB,iBAAiB;EACjB,YAAY;EACZ,yBAAyB;EACzB,cAAc;AAChB;AACA,wBAAwB,UAAU,EAAE","file":"super-date.css","sourcesContent":["input.superdate-input::-webkit-datetime-edit,\ninput.superdate-input::-webkit-inner-spin-button,\ninput.superdate-input::-webkit-clear-button,\ninput.superdate-input::-webkit-calendar-picker-indicator {\n display: none !important;\n opacity: 0 !important;\n width: 0 !important;\n}\ninput.superdate-input {\n caret-color: transparent;\n color: transparent !important;\n position: relative;\n}\n\n/* Overlay wrapper */\n.superdate-wrapper {\n position: relative;\n display: inline-block;\n width: fit-content;\n}\n\n/* The visible overlay */\n.superdate-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n padding: 0 8px;\n pointer-events: none;\n font: inherit;\n letter-spacing: inherit;\n white-space: nowrap;\n overflow: hidden;\n box-sizing: border-box;\n gap: 0;\n /* prevent browser text selection interfering with drag */\n user-select: none;\n -webkit-user-select: none;\n}\n\n.superdate-seg {\n position: relative;\n display: inline-block;\n border-radius: 2px;\n transition: background 0.1s;\n white-space: pre;\n}\n\n.superdate-seg[data-token] {\n pointer-events: auto;\n cursor: text;\n min-width: 1ch;\n text-align: center;\n}\n\n/* Single-seg focus OR multi-seg drag selection — same colour, same class */\n.superdate-seg[data-token].active {\n background: var(--superdate-active-bg, #2563eb);\n color: var(--superdate-active-color, #fff);\n border-radius: 3px;\n}\n\n.superdate-seg[data-token].empty {\n color: var(--superdate-placeholder-color, #9ca3af);\n}\n\n.superdate-seg:not([data-token]) {\n color: var(--superdate-sep-color, inherit);\n pointer-events: none;\n}\n\n/* Calendar icon area */\n.superdate-icon {\n pointer-events: auto;\n cursor: pointer;\n display: flex;\n align-items: center;\n margin-left: auto;\n padding-left: 6px;\n opacity: 0.5;\n transition: opacity 0.15s;\n flex-shrink: 0;\n}\n.superdate-icon:hover { opacity: 1; }\n"]}