secure-ui-components 0.1.0-beta.1

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.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +310 -0
  3. package/dist/components/secure-datetime/secure-datetime.css +263 -0
  4. package/dist/components/secure-datetime/secure-datetime.d.ts +124 -0
  5. package/dist/components/secure-datetime/secure-datetime.d.ts.map +1 -0
  6. package/dist/components/secure-datetime/secure-datetime.js +610 -0
  7. package/dist/components/secure-datetime/secure-datetime.js.map +1 -0
  8. package/dist/components/secure-file-upload/secure-file-upload.css +334 -0
  9. package/dist/components/secure-file-upload/secure-file-upload.d.ts +150 -0
  10. package/dist/components/secure-file-upload/secure-file-upload.d.ts.map +1 -0
  11. package/dist/components/secure-file-upload/secure-file-upload.js +911 -0
  12. package/dist/components/secure-file-upload/secure-file-upload.js.map +1 -0
  13. package/dist/components/secure-form/secure-form.css +62 -0
  14. package/dist/components/secure-form/secure-form.d.ts +128 -0
  15. package/dist/components/secure-form/secure-form.d.ts.map +1 -0
  16. package/dist/components/secure-form/secure-form.js +697 -0
  17. package/dist/components/secure-form/secure-form.js.map +1 -0
  18. package/dist/components/secure-input/secure-input.css +168 -0
  19. package/dist/components/secure-input/secure-input.d.ts +114 -0
  20. package/dist/components/secure-input/secure-input.d.ts.map +1 -0
  21. package/dist/components/secure-input/secure-input.js +785 -0
  22. package/dist/components/secure-input/secure-input.js.map +1 -0
  23. package/dist/components/secure-select/secure-select.css +195 -0
  24. package/dist/components/secure-select/secure-select.d.ts +149 -0
  25. package/dist/components/secure-select/secure-select.d.ts.map +1 -0
  26. package/dist/components/secure-select/secure-select.js +634 -0
  27. package/dist/components/secure-select/secure-select.js.map +1 -0
  28. package/dist/components/secure-submit-button/secure-submit-button.css +135 -0
  29. package/dist/components/secure-submit-button/secure-submit-button.d.ts +61 -0
  30. package/dist/components/secure-submit-button/secure-submit-button.d.ts.map +1 -0
  31. package/dist/components/secure-submit-button/secure-submit-button.js +399 -0
  32. package/dist/components/secure-submit-button/secure-submit-button.js.map +1 -0
  33. package/dist/components/secure-table/secure-table.css +341 -0
  34. package/dist/components/secure-table/secure-table.d.ts +64 -0
  35. package/dist/components/secure-table/secure-table.d.ts.map +1 -0
  36. package/dist/components/secure-table/secure-table.js +567 -0
  37. package/dist/components/secure-table/secure-table.js.map +1 -0
  38. package/dist/components/secure-textarea/secure-textarea.css +153 -0
  39. package/dist/components/secure-textarea/secure-textarea.d.ts +111 -0
  40. package/dist/components/secure-textarea/secure-textarea.d.ts.map +1 -0
  41. package/dist/components/secure-textarea/secure-textarea.js +477 -0
  42. package/dist/components/secure-textarea/secure-textarea.js.map +1 -0
  43. package/dist/core/base-component.d.ts +134 -0
  44. package/dist/core/base-component.d.ts.map +1 -0
  45. package/dist/core/base-component.js +303 -0
  46. package/dist/core/base-component.js.map +1 -0
  47. package/dist/core/base.css +37 -0
  48. package/dist/core/security-config.d.ts +89 -0
  49. package/dist/core/security-config.d.ts.map +1 -0
  50. package/dist/core/security-config.js +273 -0
  51. package/dist/core/security-config.js.map +1 -0
  52. package/dist/core/types.d.ts +212 -0
  53. package/dist/core/types.d.ts.map +1 -0
  54. package/dist/core/types.js +7 -0
  55. package/dist/core/types.js.map +1 -0
  56. package/dist/index.d.ts +18 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +19 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/package.json +89 -0
  61. package/dist/styles/tokens.css +257 -0
  62. package/package.json +118 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Secure-UI Contributors
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,310 @@
1
+ # secure-ui-components
2
+
3
+ Security-first web component library with zero dependencies.
4
+
5
+ **[Live Demo](https://barryprender.github.io/Secure-UI/)** — Try all components in your browser.
6
+
7
+ ## 🔒 Features
8
+
9
+ - **8 Secure Components**: Input, Textarea, Select, Form, File Upload, DateTime, Table, Submit Button
10
+ - **4-Tier Security System**: PUBLIC, AUTHENTICATED, SENSITIVE, CRITICAL
11
+ - **Progressive Enhancement**: Works without JavaScript
12
+ - **Zero Dependencies**: Pure TypeScript, no runtime dependencies
13
+ - **Fully Customizable**: CSS Design Tokens + CSS Parts API
14
+ - **SSR Friendly**: Components render meaningful markup without JavaScript
15
+ - **Comprehensive Testing**: Unit tests and security tests included
16
+
17
+ ## 📦 Installation
18
+
19
+ ```bash
20
+ npm install secure-ui-components
21
+ ```
22
+
23
+ ## 🚀 Quick Start
24
+
25
+ ### Bundler (Vite, Webpack, Rollup, etc.)
26
+
27
+ Import the components you need — each import auto-registers its custom element:
28
+
29
+ ```js
30
+ import 'secure-ui-components/secure-input';
31
+ import 'secure-ui-components/secure-form';
32
+ ```
33
+
34
+ Then use them in your HTML:
35
+
36
+ ```html
37
+ <secure-input
38
+ label="Email Address"
39
+ name="email"
40
+ type="email"
41
+ required
42
+ security-tier="authenticated"
43
+ ></secure-input>
44
+ ```
45
+
46
+ ### CDN / Vanilla HTML (no bundler)
47
+
48
+ ```html
49
+ <!DOCTYPE html>
50
+ <html>
51
+ <head>
52
+ <link rel="stylesheet" href="https://unpkg.com/secure-ui-components/dist/styles/tokens.css">
53
+ </head>
54
+ <body>
55
+ <secure-input
56
+ label="Email Address"
57
+ name="email"
58
+ type="email"
59
+ required
60
+ security-tier="authenticated"
61
+ ></secure-input>
62
+
63
+ <script type="module">
64
+ import 'https://unpkg.com/secure-ui-components/dist/index.js';
65
+ </script>
66
+ </body>
67
+ </html>
68
+ ```
69
+
70
+ ## 🧩 Available Components
71
+
72
+ ### SecureInput
73
+ Text input with security features and validation.
74
+
75
+ ```html
76
+ <secure-input
77
+ label="Password"
78
+ name="password"
79
+ type="password"
80
+ required
81
+ security-tier="critical"
82
+ ></secure-input>
83
+ ```
84
+
85
+ ### SecureTextarea
86
+ Multi-line text input with character counting.
87
+
88
+ ```html
89
+ <secure-textarea
90
+ label="Description"
91
+ name="description"
92
+ rows="5"
93
+ maxlength="500"
94
+ ></secure-textarea>
95
+ ```
96
+
97
+ ### SecureSelect
98
+ Dropdown select with XSS prevention.
99
+
100
+ ```html
101
+ <secure-select
102
+ label="Country"
103
+ name="country"
104
+ required
105
+ >
106
+ <option value="us">United States</option>
107
+ <option value="uk">United Kingdom</option>
108
+ </secure-select>
109
+ ```
110
+
111
+ ### SecureForm
112
+ Form container with CSRF protection.
113
+
114
+ ```html
115
+ <secure-form
116
+ action="/api/submit"
117
+ method="post"
118
+ csrf-token="your-token"
119
+ security-tier="sensitive"
120
+ >
121
+ <!-- Your form fields here -->
122
+ </secure-form>
123
+ ```
124
+
125
+ ### SecureFileUpload
126
+ File upload with drag-drop and validation.
127
+
128
+ ```html
129
+ <secure-file-upload
130
+ label="Upload Document"
131
+ name="document"
132
+ accept="image/*,.pdf"
133
+ max-size="5242880"
134
+ ></secure-file-upload>
135
+ ```
136
+
137
+ ### SecureDateTime
138
+ Date and time picker with range validation.
139
+
140
+ ```html
141
+ <secure-datetime
142
+ label="Birth Date"
143
+ name="birthdate"
144
+ type="date"
145
+ min="1900-01-01"
146
+ max="2025-12-31"
147
+ ></secure-datetime>
148
+ ```
149
+
150
+ ### SecureSubmitButton
151
+ Accessible submit button with loading state and security integration.
152
+
153
+ ```html
154
+ <secure-submit-button label="Submit"></secure-submit-button>
155
+ ```
156
+
157
+ ### SecureTable
158
+ Data table with sorting, filtering, and pagination.
159
+
160
+ ```javascript
161
+ const table = document.querySelector('secure-table');
162
+ table.data = [
163
+ { id: 1, name: 'John', email: 'john@example.com' },
164
+ { id: 2, name: 'Jane', email: 'jane@example.com' }
165
+ ];
166
+ table.columns = [
167
+ { key: 'id', label: 'ID', sortable: true },
168
+ { key: 'name', label: 'Name', sortable: true, filterable: true },
169
+ { key: 'email', label: 'Email', sortable: true, tier: 'sensitive' }
170
+ ];
171
+ ```
172
+
173
+ ## 🎨 Customization
174
+
175
+ ### Using Design Tokens
176
+
177
+ ```css
178
+ :root {
179
+ /* Override global colors */
180
+ --secure-ui-color-primary: #your-brand-color;
181
+ --secure-ui-input-border-radius: 8px;
182
+ --secure-ui-font-family-base: 'Your Font', sans-serif;
183
+ }
184
+ ```
185
+
186
+ ### Using CSS Parts API
187
+
188
+ ```css
189
+ /* Style internal elements */
190
+ secure-input::part(label) {
191
+ font-weight: 700;
192
+ text-transform: uppercase;
193
+ }
194
+
195
+ secure-input::part(input) {
196
+ font-family: monospace;
197
+ }
198
+
199
+ secure-input::part(error) {
200
+ background: #ffe0e0;
201
+ padding: 0.5rem;
202
+ }
203
+ ```
204
+
205
+ See the [Customization Guide](https://github.com/Barryprender/Secure-UI/blob/main/secure-ui-components/docs/customization.md) for a complete styling guide with examples.
206
+
207
+ ## 🔐 Security Tiers
208
+
209
+ ```html
210
+ <!-- PUBLIC: Basic validation -->
211
+ <secure-input security-tier="public"></secure-input>
212
+
213
+ <!-- AUTHENTICATED: Enhanced validation, detailed logging -->
214
+ <secure-input security-tier="authenticated"></secure-input>
215
+
216
+ <!-- SENSITIVE: Strict validation, autocomplete disabled -->
217
+ <secure-input security-tier="sensitive"></secure-input>
218
+
219
+ <!-- CRITICAL: Maximum security, masking, rate limiting -->
220
+ <secure-input security-tier="critical" type="password"></secure-input>
221
+ ```
222
+
223
+ ## 🧪 Testing
224
+
225
+ All components include comprehensive tests:
226
+
227
+ ```bash
228
+ # Run all tests
229
+ npm test
230
+
231
+ # Run tests in watch mode
232
+ npm run test:watch
233
+
234
+ # Run tests with coverage report
235
+ npm run test:coverage
236
+ ```
237
+
238
+ ## 📖 Documentation
239
+
240
+ - [Customization Guide](https://github.com/Barryprender/Secure-UI/blob/main/secure-ui-components/docs/customization.md) - Complete styling guide
241
+ - [Architecture](https://github.com/Barryprender/Secure-UI/blob/main/secure-ui-components/docs/ARCHITECTURE.md) - Technical architecture details
242
+
243
+ ## 📝 API Reference
244
+
245
+ ### Common Attributes
246
+
247
+ All components support:
248
+
249
+ | Attribute | Type | Description |
250
+ |-----------|------|-------------|
251
+ | `label` | `string` | Visible field label |
252
+ | `name` | `string` | Form field name |
253
+ | `required` | `boolean` | Mark field as required |
254
+ | `disabled` | `boolean` | Disable the field |
255
+ | `readonly` | `boolean` | Make the field read-only |
256
+ | `security-tier` | `string` | Security level: `public`, `authenticated`, `sensitive`, `critical` (default: `critical`) |
257
+
258
+ ### Common Properties / Methods
259
+
260
+ ```js
261
+ const el = document.querySelector('secure-input');
262
+
263
+ el.value // get current value (unmasked)
264
+ el.value = 'foo' // set value programmatically
265
+ el.valid // boolean — passes all validation rules
266
+ el.name // field name string
267
+ el.getAuditLog() // returns array of security audit log entries
268
+ ```
269
+
270
+ `secure-file-upload` also exposes:
271
+
272
+ ```js
273
+ el.files // FileList | null
274
+ el.clear() // clear selected files
275
+ el.hasScanHook // boolean
276
+ el.scanning // boolean — true while scan hook is running
277
+ el.setScanHook(async (file) => { return { valid: true } })
278
+ ```
279
+
280
+ ### Common Events
281
+
282
+ | Event | Fired by | Detail |
283
+ |-------|----------|--------|
284
+ | `secure-input` | `secure-input` | `{ name, value, masked, tier }` |
285
+ | `secure-textarea` | `secure-textarea` | `{ name, value, tier }` |
286
+ | `secure-select` | `secure-select` | `{ name, value, tier }` |
287
+ | `secure-datetime` | `secure-datetime` | `{ name, value, type, tier }` |
288
+ | `secure-file-upload` | `secure-file-upload` | `{ name, files, tier }` |
289
+ | `secure-form-submit` | `secure-form` | `{ formData, formElement, preventDefault }` |
290
+ | `secure-form-success` | `secure-form` | `{ formData, response }` |
291
+ | `secure-audit` | all components | `{ event, tier, timestamp, … }` |
292
+ | `table-action` | `secure-table` | `{ action, row }` |
293
+
294
+ ## 🤝 Contributing
295
+
296
+ Contributions are welcome! Please see the main repository for guidelines.
297
+
298
+ ## 📄 License
299
+
300
+ MIT License - see LICENSE file for details.
301
+
302
+ ## 🔗 Links
303
+
304
+ - [GitHub Repository](https://github.com/Barryprender/Secure-UI)
305
+ - [Live Demo](https://barryprender.github.io/Secure-UI/)
306
+
307
+ ## 🆘 Support
308
+
309
+ - [Issue Tracker](https://github.com/Barryprender/Secure-UI/issues)
310
+ - [Discussions](https://github.com/Barryprender/Secure-UI/discussions)
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Secure DateTime Component Styles
3
+ * Uses design tokens for full customizability
4
+ */
5
+
6
+ /* Container */
7
+ .datetime-container {
8
+ margin-bottom: var(--secure-ui-form-gap);
9
+ font-family: var(--secure-ui-font-family-base);
10
+ }
11
+
12
+ /* Label */
13
+ label {
14
+ display: block;
15
+ margin-bottom: var(--secure-ui-form-label-margin-bottom);
16
+ font-size: var(--secure-ui-label-font-size);
17
+ font-weight: var(--secure-ui-label-font-weight);
18
+ color: var(--secure-ui-label-color);
19
+ }
20
+
21
+ .label-suffix {
22
+ font-weight: var(--secure-ui-font-weight-normal);
23
+ color: var(--secure-ui-color-text-secondary);
24
+ font-size: var(--secure-ui-font-size-xs);
25
+ margin-left: var(--secure-ui-space-1);
26
+ }
27
+
28
+ .security-badge {
29
+ display: inline-block;
30
+ padding: var(--secure-ui-badge-padding);
31
+ margin-left: var(--secure-ui-space-2);
32
+ font-size: var(--secure-ui-badge-font-size);
33
+ font-weight: var(--secure-ui-font-weight-semibold);
34
+ border-radius: var(--secure-ui-badge-border-radius);
35
+ text-transform: uppercase;
36
+ background-color: var(--secure-ui-color-bg-tertiary);
37
+ color: var(--secure-ui-color-text-secondary);
38
+ border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border);
39
+ }
40
+
41
+ /* Datetime Wrapper */
42
+ .input-wrapper {
43
+ position: relative;
44
+ }
45
+
46
+ /* Datetime Input */
47
+ .datetime-field {
48
+ width: 100%;
49
+ height: var(--secure-ui-input-height);
50
+ padding: var(--secure-ui-input-padding-y) var(--secure-ui-input-padding-x);
51
+
52
+ font-family: var(--secure-ui-font-family-base);
53
+ font-size: var(--secure-ui-input-font-size);
54
+ line-height: var(--secure-ui-line-height-normal);
55
+ color: var(--secure-ui-input-text-color);
56
+
57
+ background-color: var(--secure-ui-input-bg);
58
+ border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color);
59
+ border-radius: var(--secure-ui-input-border-radius);
60
+
61
+ transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out);
62
+ cursor: pointer;
63
+ box-sizing: border-box;
64
+ }
65
+
66
+ .datetime-field::placeholder {
67
+ color: var(--secure-ui-input-placeholder-color);
68
+ }
69
+
70
+ .datetime-field:hover:not(:disabled):not([readonly]) {
71
+ border-color: var(--secure-ui-input-border-color-hover);
72
+ }
73
+
74
+ .datetime-field:focus {
75
+ outline: none;
76
+ border-color: var(--secure-ui-input-border-color-focus);
77
+ box-shadow: var(--secure-ui-shadow-focus);
78
+ }
79
+
80
+ .datetime-field.error {
81
+ border-color: var(--secure-ui-color-error);
82
+ }
83
+
84
+ .datetime-field.error:focus {
85
+ box-shadow: var(--secure-ui-shadow-focus-error);
86
+ }
87
+
88
+ .datetime-field:disabled {
89
+ background-color: var(--secure-ui-input-disabled-bg);
90
+ cursor: not-allowed;
91
+ opacity: var(--secure-ui-input-disabled-opacity);
92
+ }
93
+
94
+ .datetime-field[readonly] {
95
+ background-color: var(--secure-ui-color-bg-secondary);
96
+ cursor: default;
97
+ }
98
+
99
+ /* Calendar Icon Indicator
100
+ CSS alt-text syntax (content: 'emoji' / '') marks the pseudo-element as
101
+ presentational (no accessible name) in browsers that support it (Chrome 94+,
102
+ Firefox 92+, Safari 15.4+). This prevents screen readers from reading out
103
+ the verbose Unicode emoji name. */
104
+ .input-wrapper::after {
105
+ content: '📅' / '';
106
+ position: absolute;
107
+ right: var(--secure-ui-space-3);
108
+ top: 50%;
109
+ transform: translateY(-50%);
110
+ pointer-events: none;
111
+ font-size: var(--secure-ui-font-size-lg);
112
+ color: var(--secure-ui-color-text-secondary);
113
+ }
114
+
115
+ .input-wrapper[data-type="time"]::after {
116
+ content: '🕐' / '';
117
+ }
118
+
119
+ .input-wrapper[data-type="datetime-local"]::after {
120
+ content: '📅' / '';
121
+ }
122
+
123
+ .input-wrapper[data-type="month"]::after {
124
+ content: '📆' / '';
125
+ }
126
+
127
+ .input-wrapper[data-type="week"]::after {
128
+ content: '📅' / '';
129
+ }
130
+
131
+ .input-wrapper .timezone-display {
132
+ position: absolute;
133
+ right: 0;
134
+ bottom: -1.25rem;
135
+ }
136
+
137
+ /* Range Display */
138
+ .range-display {
139
+ display: none;
140
+ margin-top: var(--secure-ui-space-2);
141
+ padding: var(--secure-ui-space-2) var(--secure-ui-space-3);
142
+ background-color: var(--secure-ui-color-bg-secondary);
143
+ border-radius: var(--secure-ui-border-radius-sm);
144
+ font-size: var(--secure-ui-font-size-xs);
145
+ color: var(--secure-ui-color-text-secondary);
146
+ }
147
+
148
+ .range-display.visible {
149
+ display: block;
150
+ }
151
+
152
+ .range-item {
153
+ margin-bottom: var(--secure-ui-space-1);
154
+ }
155
+
156
+ .range-item:last-child {
157
+ margin-bottom: 0;
158
+ }
159
+
160
+ .range-label {
161
+ font-weight: var(--secure-ui-font-weight-medium);
162
+ margin-right: var(--secure-ui-space-1);
163
+ }
164
+
165
+ /* Helper Text */
166
+ .helper-text {
167
+ margin-top: var(--secure-ui-space-2);
168
+ font-size: var(--secure-ui-font-size-xs);
169
+ color: var(--secure-ui-color-text-secondary);
170
+ line-height: var(--secure-ui-line-height-normal);
171
+ }
172
+
173
+ /* Error Container */
174
+ .error-container {
175
+ position: absolute;
176
+ margin-top: var(--secure-ui-form-error-margin-top);
177
+ font-size: var(--secure-ui-error-font-size);
178
+ color: var(--secure-ui-error-color);
179
+ line-height: var(--secure-ui-line-height-normal);
180
+ overflow: hidden;
181
+ max-height: 40px;
182
+ opacity: 1;
183
+ transform: translateY(0);
184
+ transition: opacity 0.2s ease-out, transform 0.2s ease-out, max-height 0.2s ease-out, margin-top 0.2s ease-out;
185
+ }
186
+
187
+ .error-container.hidden {
188
+ max-height: 0;
189
+ opacity: 0;
190
+ transform: translateY(-4px);
191
+ margin-top: 0;
192
+ }
193
+
194
+ @media (prefers-reduced-motion: reduce) {
195
+ .datetime-field,
196
+ .error-container {
197
+ transition: none !important;
198
+ }
199
+ }
200
+
201
+ /* Security Tier Styles */
202
+ /* :host([security-tier="authenticated"]) .datetime-field {
203
+ border-color: var(--secure-ui-tier-authenticated);
204
+ }
205
+
206
+ :host([security-tier="sensitive"]) .datetime-field {
207
+ border-color: var(--secure-ui-tier-sensitive);
208
+ }
209
+
210
+ :host([security-tier="critical"]) .datetime-field {
211
+ border-color: var(--secure-ui-tier-critical);
212
+ } */
213
+
214
+ /* Browser-specific Adjustments */
215
+ /* Chrome/Safari date picker styling */
216
+ .datetime-field::-webkit-calendar-picker-indicator {
217
+ display: inline-block;
218
+ cursor: pointer;
219
+ opacity: 1;
220
+ padding: 4px;
221
+ margin-left: 4px;
222
+ }
223
+
224
+ .datetime-field:disabled::-webkit-calendar-picker-indicator {
225
+ cursor: not-allowed;
226
+ opacity: 0.3;
227
+ }
228
+
229
+ /* Inner spin button in Chrome/Safari */
230
+ .datetime-field::-webkit-inner-spin-button {
231
+ height: auto;
232
+ opacity: 0.6;
233
+ cursor: pointer;
234
+ }
235
+
236
+ /* Validation States */
237
+ .datetime-field:valid:not(:placeholder-shown):not(:focus) {
238
+ border-color: var(--secure-ui-color-success);
239
+ }
240
+
241
+ .datetime-field:invalid:not(:placeholder-shown):not(:focus) {
242
+ border-color: var(--secure-ui-color-error);
243
+ }
244
+
245
+ /* Focus Within Container */
246
+ .datetime-container:focus-within label {
247
+ color: var(--secure-ui-color-primary);
248
+ }
249
+
250
+ /* Disabled State */
251
+ .datetime-container.disabled {
252
+ opacity: var(--secure-ui-input-disabled-opacity);
253
+ }
254
+
255
+ .datetime-container.disabled label {
256
+ color: var(--secure-ui-color-text-disabled);
257
+ }
258
+
259
+ /* Required Indicator */
260
+ label .required {
261
+ color: var(--secure-ui-color-error);
262
+ margin-left: var(--secure-ui-space-1);
263
+ }
@@ -0,0 +1,124 @@
1
+ /**
2
+ * @fileoverview Secure Date/Time Picker Component
3
+ *
4
+ * A security-first date/time picker component that implements progressive enhancement,
5
+ * validation, and audit logging.
6
+ *
7
+ * Progressive Enhancement Strategy:
8
+ * 1. Without JavaScript: Falls back to native HTML5 date/time inputs
9
+ * 2. With JavaScript: Enhances with validation, range limits, audit logging
10
+ *
11
+ * Usage:
12
+ * <secure-datetime
13
+ * security-tier="authenticated"
14
+ * name="appointment"
15
+ * label="Appointment Date"
16
+ * type="datetime-local"
17
+ * min="2024-01-01T00:00"
18
+ * max="2024-12-31T23:59"
19
+ * required
20
+ * ></secure-datetime>
21
+ *
22
+ * Security Features:
23
+ * - Input sanitization and validation
24
+ * - Date range enforcement
25
+ * - Rate limiting for sensitive/critical tiers
26
+ * - Comprehensive audit logging
27
+ * - Timezone awareness
28
+ * - Format validation
29
+ *
30
+ * @module secure-datetime
31
+ * @license MIT
32
+ */
33
+ import { SecureBaseComponent } from '../../core/base-component.js';
34
+ /**
35
+ * Secure DateTime Web Component
36
+ *
37
+ * Provides a security-hardened date/time picker with progressive enhancement.
38
+ * The component works as a standard HTML5 date/time input without JavaScript and
39
+ * enhances with security features when JavaScript is available.
40
+ *
41
+ * @extends SecureBaseComponent
42
+ */
43
+ export declare class SecureDateTime extends SecureBaseComponent {
44
+ #private;
45
+ /**
46
+ * Observed attributes for this component
47
+ *
48
+ * @static
49
+ */
50
+ static get observedAttributes(): string[];
51
+ /**
52
+ * Constructor
53
+ */
54
+ constructor();
55
+ /**
56
+ * Render the datetime component
57
+ *
58
+ * Security Note: We use native HTML5 date/time inputs wrapped in our web component
59
+ * to ensure progressive enhancement and browser-native date validation.
60
+ *
61
+ * @protected
62
+ */
63
+ protected render(): DocumentFragment | HTMLElement | null;
64
+ /**
65
+ * Handle attribute changes
66
+ *
67
+ * @protected
68
+ */
69
+ protected handleAttributeChange(name: string, _oldValue: string | null, newValue: string | null): void;
70
+ /**
71
+ * Get the current value
72
+ *
73
+ * @public
74
+ */
75
+ get value(): string;
76
+ /**
77
+ * Set the value
78
+ *
79
+ * @public
80
+ */
81
+ set value(value: string);
82
+ /**
83
+ * Get the input name
84
+ *
85
+ * @public
86
+ */
87
+ get name(): string;
88
+ /**
89
+ * Get value as Date object
90
+ *
91
+ * @public
92
+ */
93
+ getValueAsDate(): Date | null;
94
+ /**
95
+ * Set value from Date object
96
+ *
97
+ * @public
98
+ */
99
+ setValueFromDate(date: Date): void;
100
+ /**
101
+ * Check if the datetime is valid
102
+ *
103
+ * @public
104
+ */
105
+ get valid(): boolean;
106
+ /**
107
+ * Focus the input
108
+ *
109
+ * @public
110
+ */
111
+ focus(): void;
112
+ /**
113
+ * Blur the input
114
+ *
115
+ * @public
116
+ */
117
+ blur(): void;
118
+ /**
119
+ * Cleanup on disconnect
120
+ */
121
+ disconnectedCallback(): void;
122
+ }
123
+ export default SecureDateTime;
124
+ //# sourceMappingURL=secure-datetime.d.ts.map