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.
- package/LICENSE +21 -0
- package/README.md +310 -0
- package/dist/components/secure-datetime/secure-datetime.css +263 -0
- package/dist/components/secure-datetime/secure-datetime.d.ts +124 -0
- package/dist/components/secure-datetime/secure-datetime.d.ts.map +1 -0
- package/dist/components/secure-datetime/secure-datetime.js +610 -0
- package/dist/components/secure-datetime/secure-datetime.js.map +1 -0
- package/dist/components/secure-file-upload/secure-file-upload.css +334 -0
- package/dist/components/secure-file-upload/secure-file-upload.d.ts +150 -0
- package/dist/components/secure-file-upload/secure-file-upload.d.ts.map +1 -0
- package/dist/components/secure-file-upload/secure-file-upload.js +911 -0
- package/dist/components/secure-file-upload/secure-file-upload.js.map +1 -0
- package/dist/components/secure-form/secure-form.css +62 -0
- package/dist/components/secure-form/secure-form.d.ts +128 -0
- package/dist/components/secure-form/secure-form.d.ts.map +1 -0
- package/dist/components/secure-form/secure-form.js +697 -0
- package/dist/components/secure-form/secure-form.js.map +1 -0
- package/dist/components/secure-input/secure-input.css +168 -0
- package/dist/components/secure-input/secure-input.d.ts +114 -0
- package/dist/components/secure-input/secure-input.d.ts.map +1 -0
- package/dist/components/secure-input/secure-input.js +785 -0
- package/dist/components/secure-input/secure-input.js.map +1 -0
- package/dist/components/secure-select/secure-select.css +195 -0
- package/dist/components/secure-select/secure-select.d.ts +149 -0
- package/dist/components/secure-select/secure-select.d.ts.map +1 -0
- package/dist/components/secure-select/secure-select.js +634 -0
- package/dist/components/secure-select/secure-select.js.map +1 -0
- package/dist/components/secure-submit-button/secure-submit-button.css +135 -0
- package/dist/components/secure-submit-button/secure-submit-button.d.ts +61 -0
- package/dist/components/secure-submit-button/secure-submit-button.d.ts.map +1 -0
- package/dist/components/secure-submit-button/secure-submit-button.js +399 -0
- package/dist/components/secure-submit-button/secure-submit-button.js.map +1 -0
- package/dist/components/secure-table/secure-table.css +341 -0
- package/dist/components/secure-table/secure-table.d.ts +64 -0
- package/dist/components/secure-table/secure-table.d.ts.map +1 -0
- package/dist/components/secure-table/secure-table.js +567 -0
- package/dist/components/secure-table/secure-table.js.map +1 -0
- package/dist/components/secure-textarea/secure-textarea.css +153 -0
- package/dist/components/secure-textarea/secure-textarea.d.ts +111 -0
- package/dist/components/secure-textarea/secure-textarea.d.ts.map +1 -0
- package/dist/components/secure-textarea/secure-textarea.js +477 -0
- package/dist/components/secure-textarea/secure-textarea.js.map +1 -0
- package/dist/core/base-component.d.ts +134 -0
- package/dist/core/base-component.d.ts.map +1 -0
- package/dist/core/base-component.js +303 -0
- package/dist/core/base-component.js.map +1 -0
- package/dist/core/base.css +37 -0
- package/dist/core/security-config.d.ts +89 -0
- package/dist/core/security-config.d.ts.map +1 -0
- package/dist/core/security-config.js +273 -0
- package/dist/core/security-config.js.map +1 -0
- package/dist/core/types.d.ts +212 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +7 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/package.json +89 -0
- package/dist/styles/tokens.css +257 -0
- package/package.json +118 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure Textarea Component Styles
|
|
3
|
+
* Uses design tokens for full customizability
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* Container */
|
|
7
|
+
.textarea-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
|
+
/* Textarea Wrapper */
|
|
42
|
+
.textarea-wrapper {
|
|
43
|
+
position: relative;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Textarea Field */
|
|
47
|
+
.textarea-field {
|
|
48
|
+
width: 100%;
|
|
49
|
+
min-height: var(--secure-ui-textarea-min-height);
|
|
50
|
+
padding: var(--secure-ui-textarea-padding);
|
|
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
|
+
resize: vertical;
|
|
63
|
+
box-sizing: border-box;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.textarea-field::placeholder {
|
|
67
|
+
color: var(--secure-ui-input-placeholder-color);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.textarea-field:hover:not(:disabled) {
|
|
71
|
+
border-color: var(--secure-ui-input-border-color-hover);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.textarea-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
|
+
.textarea-field.error {
|
|
81
|
+
border-color: var(--secure-ui-color-error);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.textarea-field.error:focus {
|
|
85
|
+
box-shadow: var(--secure-ui-shadow-focus-error);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.textarea-field:read-only:not(:disabled) {
|
|
89
|
+
background-color: var(--secure-ui-color-bg-secondary);
|
|
90
|
+
cursor: default;
|
|
91
|
+
resize: none;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.textarea-field:disabled {
|
|
95
|
+
background-color: var(--secure-ui-input-disabled-bg);
|
|
96
|
+
cursor: not-allowed;
|
|
97
|
+
opacity: var(--secure-ui-input-disabled-opacity);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
/* Character Count */
|
|
102
|
+
.char-count {
|
|
103
|
+
display: block;
|
|
104
|
+
margin-top: var(--secure-ui-space-1);
|
|
105
|
+
font-size: var(--secure-ui-font-size-xs);
|
|
106
|
+
color: var(--secure-ui-color-text-secondary);
|
|
107
|
+
text-align: right;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.char-count.warning {
|
|
111
|
+
color: var(--secure-ui-color-warning);
|
|
112
|
+
font-weight: var(--secure-ui-font-weight-medium);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Error Container */
|
|
116
|
+
.error-container {
|
|
117
|
+
margin-top: var(--secure-ui-form-error-margin-top);
|
|
118
|
+
font-size: var(--secure-ui-error-font-size);
|
|
119
|
+
color: var(--secure-ui-error-color);
|
|
120
|
+
line-height: var(--secure-ui-line-height-normal);
|
|
121
|
+
overflow: hidden;
|
|
122
|
+
max-height: 40px;
|
|
123
|
+
opacity: 1;
|
|
124
|
+
transform: translateY(0);
|
|
125
|
+
transition: opacity 0.2s ease-out, transform 0.2s ease-out, max-height 0.2s ease-out, margin-top 0.2s ease-out;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.error-container.hidden {
|
|
129
|
+
max-height: 0;
|
|
130
|
+
opacity: 0;
|
|
131
|
+
transform: translateY(-4px);
|
|
132
|
+
margin-top: 0;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@media (prefers-reduced-motion: reduce) {
|
|
136
|
+
.textarea-field,
|
|
137
|
+
.error-container {
|
|
138
|
+
transition: none !important;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* Security Tier Styles */
|
|
143
|
+
:host([security-tier="authenticated"]) .textarea-field {
|
|
144
|
+
border-color: var(--secure-ui-tier-authenticated);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
:host([security-tier="sensitive"]) .textarea-field {
|
|
148
|
+
border-color: var(--secure-ui-tier-sensitive);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
:host([security-tier="critical"]) .textarea-field {
|
|
152
|
+
border-color: var(--secure-ui-tier-critical);
|
|
153
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Secure Textarea Component
|
|
3
|
+
*
|
|
4
|
+
* A security-first textarea component that implements progressive enhancement,
|
|
5
|
+
* tier-based validation, character counting, and audit logging.
|
|
6
|
+
*
|
|
7
|
+
* Progressive Enhancement Strategy:
|
|
8
|
+
* 1. Without JavaScript: Falls back to native HTML5 textarea with attributes
|
|
9
|
+
* 2. With JavaScript: Enhances with real-time validation, character limits, rate limiting
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* <secure-textarea
|
|
13
|
+
* security-tier="sensitive"
|
|
14
|
+
* name="bio"
|
|
15
|
+
* label="Biography"
|
|
16
|
+
* rows="5"
|
|
17
|
+
* required
|
|
18
|
+
* ></secure-textarea>
|
|
19
|
+
*
|
|
20
|
+
* Security Features:
|
|
21
|
+
* - XSS prevention via sanitization
|
|
22
|
+
* - Character counting and limits based on security tier
|
|
23
|
+
* - Rate limiting for sensitive/critical tiers
|
|
24
|
+
* - Autocomplete control based on tier
|
|
25
|
+
* - Comprehensive audit logging
|
|
26
|
+
* - Visual security indicators
|
|
27
|
+
*
|
|
28
|
+
* @module secure-textarea
|
|
29
|
+
* @license MIT
|
|
30
|
+
*/
|
|
31
|
+
import { SecureBaseComponent } from '../../core/base-component.js';
|
|
32
|
+
/**
|
|
33
|
+
* Secure Textarea Web Component
|
|
34
|
+
*
|
|
35
|
+
* Provides a security-hardened textarea field with progressive enhancement.
|
|
36
|
+
* The component works as a standard form textarea without JavaScript and
|
|
37
|
+
* enhances with security features when JavaScript is available.
|
|
38
|
+
*
|
|
39
|
+
* @extends SecureBaseComponent
|
|
40
|
+
*/
|
|
41
|
+
export declare class SecureTextarea extends SecureBaseComponent {
|
|
42
|
+
#private;
|
|
43
|
+
/**
|
|
44
|
+
* Observed attributes for this component
|
|
45
|
+
*
|
|
46
|
+
* @static
|
|
47
|
+
*/
|
|
48
|
+
static get observedAttributes(): string[];
|
|
49
|
+
/**
|
|
50
|
+
* Constructor
|
|
51
|
+
*/
|
|
52
|
+
constructor();
|
|
53
|
+
/**
|
|
54
|
+
* Render the textarea component
|
|
55
|
+
*
|
|
56
|
+
* Security Note: We use a native <textarea> element wrapped in our web component
|
|
57
|
+
* to ensure progressive enhancement. The native textarea works without JavaScript,
|
|
58
|
+
* and we enhance it with security features when JS is available.
|
|
59
|
+
*
|
|
60
|
+
* @protected
|
|
61
|
+
*/
|
|
62
|
+
protected render(): DocumentFragment | HTMLElement | null;
|
|
63
|
+
/**
|
|
64
|
+
* Handle attribute changes
|
|
65
|
+
*
|
|
66
|
+
* @protected
|
|
67
|
+
*/
|
|
68
|
+
protected handleAttributeChange(name: string, _oldValue: string | null, newValue: string | null): void;
|
|
69
|
+
/**
|
|
70
|
+
* Get the current value
|
|
71
|
+
*
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
get value(): string;
|
|
75
|
+
/**
|
|
76
|
+
* Set the value
|
|
77
|
+
*
|
|
78
|
+
* @public
|
|
79
|
+
*/
|
|
80
|
+
set value(value: string);
|
|
81
|
+
/**
|
|
82
|
+
* Get the textarea name
|
|
83
|
+
*
|
|
84
|
+
* @public
|
|
85
|
+
*/
|
|
86
|
+
get name(): string;
|
|
87
|
+
/**
|
|
88
|
+
* Check if the textarea is valid
|
|
89
|
+
*
|
|
90
|
+
* @public
|
|
91
|
+
*/
|
|
92
|
+
get valid(): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Focus the textarea
|
|
95
|
+
*
|
|
96
|
+
* @public
|
|
97
|
+
*/
|
|
98
|
+
focus(): void;
|
|
99
|
+
/**
|
|
100
|
+
* Blur the textarea
|
|
101
|
+
*
|
|
102
|
+
* @public
|
|
103
|
+
*/
|
|
104
|
+
blur(): void;
|
|
105
|
+
/**
|
|
106
|
+
* Cleanup on disconnect
|
|
107
|
+
*/
|
|
108
|
+
disconnectedCallback(): void;
|
|
109
|
+
}
|
|
110
|
+
export default SecureTextarea;
|
|
111
|
+
//# sourceMappingURL=secure-textarea.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-textarea.d.ts","sourceRoot":"","sources":["../../../src/components/secure-textarea/secure-textarea.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;;;;;;;GAQG;AACH,qBAAa,cAAe,SAAQ,mBAAmB;;IA+BrD;;;;OAIG;IACH,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAcxC;IAED;;OAEG;;IAKH;;;;;;;;OAQG;IACH,SAAS,CAAC,MAAM,IAAI,gBAAgB,GAAG,WAAW,GAAG,IAAI;IA+TzD;;;;OAIG;IACH,SAAS,CAAC,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAmBtG;;;;OAIG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;;;OAIG;IACH,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAKtB;IAED;;;;OAIG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;OAIG;IACH,IAAI,KAAK,IAAI,OAAO,CAkBnB;IAED;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAMb;;;;OAIG;IACH,IAAI,IAAI,IAAI;IAMZ;;OAEG;IACH,oBAAoB,IAAI,IAAI;CAQ7B;AAKD,eAAe,cAAc,CAAC"}
|