ehscan-react-components 0.1.17 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # ehscan-react-components
2
2
 
3
+ - Button
4
+ - Window
5
+ - TextArea
6
+
3
7
  # Styling
4
8
 
5
9
  ## Base Button Variables
@@ -1,2 +1,3 @@
1
1
  export { Button } from './Button';
2
2
  export { Window } from './Window';
3
+ export { TextArea } from './TextArea';
@@ -1,5 +1,4 @@
1
- // export const ExtButton = () => {
2
- // return <Button />
3
- // }
1
+ // ehscan-react-components entries
4
2
  export { Button } from './Button';
5
3
  export { Window } from './Window';
4
+ export { TextArea } from './TextArea';
@@ -0,0 +1,14 @@
1
+ import './style/input.css';
2
+ interface Props {
3
+ id?: string;
4
+ tabIndex?: number;
5
+ editable?: boolean;
6
+ label?: string;
7
+ required?: boolean;
8
+ value: string;
9
+ onChange: (value: string) => void;
10
+ placeholder?: string;
11
+ maxLength?: number;
12
+ }
13
+ export declare const TextArea: React.FC<Props>;
14
+ export {};
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useLayoutEffect, useRef, useState, useCallback, useId } from "react";
3
+ import './style/input.css';
4
+ export const TextArea = ({ id, tabIndex, label, value, editable = true, required = false, onChange, placeholder, maxLength = 500, }) => {
5
+ const textareaRef = useRef(null);
6
+ const [charCount, setCharCount] = useState(value.length);
7
+ const generatedId = useId(); // unique fallback for aria linking
8
+ const textareaId = id || `textarea-${generatedId}`;
9
+ // 🔧 Resize and update char count whenever value changes
10
+ useLayoutEffect(() => {
11
+ setHeight();
12
+ setCharCount(value.length);
13
+ }, [value]);
14
+ const setHeight = () => {
15
+ const el = textareaRef.current;
16
+ if (!el)
17
+ return;
18
+ el.style.height = "auto";
19
+ el.style.height = `${Math.max(el.scrollHeight, 20)}px`;
20
+ };
21
+ const handleInputChange = useCallback((event) => {
22
+ const newValue = event.target.value;
23
+ onChange(newValue);
24
+ setCharCount(newValue.length);
25
+ }, [onChange]);
26
+ const handleFocus = useCallback(() => {
27
+ const el = textareaRef.current;
28
+ if (!el)
29
+ return;
30
+ requestAnimationFrame(() => {
31
+ el.focus({ preventScroll: true });
32
+ el.scrollIntoView({ behavior: "smooth", block: "center" });
33
+ });
34
+ setHeight();
35
+ }, []);
36
+ const clear = useCallback(() => {
37
+ onChange("");
38
+ setCharCount(0);
39
+ if (textareaRef.current) {
40
+ textareaRef.current.style.height = "auto";
41
+ }
42
+ }, [onChange]);
43
+ return (_jsxs("div", { className: "ext-textarea-wrapper", children: [label && (_jsxs("div", { className: "ext-textarea-label", children: [_jsxs("label", { className: "ext-textarea-label-title", htmlFor: textareaId, children: [label, " ", required && _jsx("span", { className: "required", children: "*" })] }), _jsxs("div", { className: "ext-textarea-label-btns", children: [editable && charCount > 0 && (_jsxs("div", { className: "form-container-count", children: [charCount, " / ", maxLength] })), editable && charCount > 0 && (_jsx("div", { className: "ext-textarea-svg-close", onClick: clear, "aria-label": `Clear ${label !== null && label !== void 0 ? label : "text area"}`, children: _jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("line", { x1: "8", y1: "8", x2: "16", y2: "16", stroke: "#333", "stroke-width": "2", "stroke-linecap": "round" }), _jsx("line", { x1: "16", y1: "8", x2: "8", y2: "16", stroke: "#333", "stroke-width": "2", "stroke-linecap": "round" })] }) }))] })] })), _jsx("div", { className: "ext-textarea-box", children: _jsx("textarea", { id: textareaId, tabIndex: tabIndex, ref: textareaRef, value: value !== null && value !== void 0 ? value : "", placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : "...", maxLength: maxLength, onChange: handleInputChange, onFocus: handleFocus, onBlur: setHeight, className: `ext-textarea${required && value === "" ? " highlight" : ""}`, rows: 1, spellCheck: false, readOnly: !editable, "aria-required": required, "aria-label": label }) })] }));
44
+ };
@@ -0,0 +1,169 @@
1
+ /* textarea */
2
+
3
+ .ext-textarea-wrapper {
4
+ position: relative;
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: 10px;
8
+ }
9
+
10
+ .ext-textarea-lable {
11
+ padding: 5px 0 0 10px;
12
+ display: flex;
13
+ flex-direction: row;
14
+ gap: 10px;
15
+ }
16
+
17
+ .ext-textarea-lable-title {
18
+ flex: 1;
19
+ }
20
+
21
+ .ext-textarea-lable-btn {
22
+ background-color: aquamarine;
23
+ display: flex;
24
+ gap: 10px;
25
+ }
26
+
27
+ .ext-textarea-box {
28
+ background-color: var(--ext-textarea-box-bck-color, lavender);
29
+ border-radius: 10px;
30
+ display: flex;
31
+ position: relative;
32
+ }
33
+
34
+ input,
35
+ textarea {
36
+ height: 100%;
37
+ font-family: Arial, sans-serif;
38
+ font-family: Inter, sans-serif;
39
+ font-style: normal;
40
+ font-weight: 400;
41
+ font-optical-sizing: auto;
42
+ -webkit-font-smoothing: antialiased;
43
+ text-rendering: optimizelegibility;
44
+ letter-spacing: 0.072px;
45
+ overflow: hidden;
46
+ }
47
+
48
+ input::placeholder,
49
+ textarea::placeholder {
50
+ color: red;
51
+ opacity: 1;
52
+ font-size: 12;
53
+ font-weight: 300;
54
+ padding: 0
55
+ }
56
+
57
+ input[type="text"],
58
+ input[type="email"],
59
+ textarea {
60
+ color: var(--input-clr);
61
+ text-align: var(--input-align);
62
+ background-color: var(--d-input-bck-clr);
63
+ outline: none;
64
+ border: none;
65
+ }
66
+
67
+ textarea {
68
+ resize: none;
69
+ overflow: hidden;
70
+ min-height: 30px;
71
+ }
72
+
73
+ input:-webkit-autofill,
74
+ input:-webkit-autofill:hover,
75
+ input:-webkit-autofill:focus,
76
+ input:-webkit-autofill:active {
77
+ -webkit-box-shadow: 0 0 0px 1000px transparent inset !important;
78
+ box-shadow: 0 0 0px 1000px transparent inset !important;
79
+ -webkit-text-fill-color: var(--input-clr);
80
+ background-clip: padding-box !important;
81
+ transition: background-color 9999s ease-in-out 0s;
82
+ }
83
+
84
+ /* 🌐 Wrapper */
85
+ .ext-textarea-wrapper {
86
+ display: flex;
87
+ flex-direction: column;
88
+ gap: 4px;
89
+ }
90
+
91
+ /* 🏷️ Label Area */
92
+ .ext-textarea-label {
93
+ display: flex;
94
+ justify-content: center;
95
+ align-items:center;
96
+ height: 22px;
97
+ }
98
+
99
+ /* 🏷️ Label Title */
100
+ .ext-textarea-label-title {
101
+ flex: 1;
102
+ color: darkblue;
103
+ font-weight: 800;
104
+ }
105
+
106
+ /* ⚙️ Label Controls (counter + clear) */
107
+ .ext-textarea-label-btns {
108
+ display: flex;
109
+ align-items: center;
110
+ gap: 8px;
111
+ }
112
+
113
+ /* 🔢 Character Count */
114
+ .form-container-count {
115
+ font-size: 0.85rem;
116
+ color: #666;
117
+ }
118
+
119
+ /* ❌ Clear Button */
120
+ .form-container-clear {
121
+ border: none;
122
+ background: none;
123
+ color: #007aff;
124
+ cursor: pointer;
125
+ font-size: 0.85rem;
126
+ }
127
+
128
+ /* ✏️ Textarea Box */
129
+ .ext-textarea-box {
130
+ width: 100%;
131
+ }
132
+
133
+ .ext-textarea {
134
+ font-size: var(--ext-textarea-input-txt-size, 14px);
135
+ border: none;
136
+ outline: none;
137
+ width: 100%;
138
+ font-weight: var(--ext-textarea-d-font-weight, 400);
139
+ display: grid;
140
+ justify-content: left;
141
+ align-items: center;
142
+ background-color: transparent;
143
+ color: var(--ext-textarea-input-clr, red);
144
+ box-sizing: border-box;
145
+ resize: none;
146
+ overflow: hidden;
147
+ padding: 10px;
148
+ line-height: 1.5;
149
+ }
150
+
151
+ /* Required Highlight */
152
+ .ext-textarea.highlight {
153
+ border-color: green;
154
+ border-width: 3px;
155
+ border-style: solid;
156
+ }
157
+
158
+ .ext-textarea-svg-close{
159
+ background-color: #007aff;
160
+ border-radius: 50px;
161
+ display: flex;
162
+ align-items: center;
163
+ justify-content: center;
164
+ }
165
+
166
+ .ext-textarea-svg-close:hover{
167
+ cursor: pointer;
168
+ background-color: aquamarine;
169
+ }
@@ -7,7 +7,6 @@
7
7
  --ext-window-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
8
8
  --ext-window-opacity: 0;
9
9
  --ext-window-transition: opacity 0.4s ease-in-out; */
10
-
11
10
  background-color: var(--ext-window-bck-color, white);
12
11
  position: absolute;
13
12
  width: var(--ext-window-width, 400px);
@@ -25,37 +24,17 @@
25
24
 
26
25
  /* Header */
27
26
  .ext-window-header {
28
- --ext-window-header-bck-color: var(--ext-window-bck-color, white);
29
27
  border-radius: var(--ext-window-border-radius, 12px) var(--ext-window-border-radius, 12px) 0 0;
30
- background-color: var(--ext-window-header-bck-color);
28
+ background-color: var(--ext-window-header-bck-color, transparent);
31
29
  height: var(--ext-window-header-height, 50px);
32
30
  cursor: pointer;
33
- }
34
-
35
- .ext-window-header-title {
36
- flex: 1;
37
31
  display: flex;
38
- align-items: center;
39
- line-height: 1.4;
40
- padding: 5px 0 2px 0;
41
- cursor: move;
42
- }
43
-
44
- .ext-window-header-close {
45
- display: flex;
46
- align-items: center;
47
- justify-content: center;
48
- background-color: var(--ext-window-close-bck, aqua);
49
- width: 40px;
50
- height: 40px;
51
- border-radius: var(--ext-window-border-radius, 12px);
52
- cursor: pointer;
53
32
  }
54
33
 
55
34
  /* Body */
56
35
  .ext-window-body {
57
36
  background-color: var(--ext-window-body-bck, transparent);
58
- min-height: var(--ext-window-min-height, 300px);
37
+ min-height: var(--ext-window-min-height, 200px);
59
38
  overflow: auto;
60
39
  }
61
40
 
@@ -63,12 +42,12 @@
63
42
  .ext-window-footer {
64
43
  background-color: var(--ext-window-footer-bck, transparent);
65
44
  height: var(--ext-window-footer-height, 50px);
66
-
45
+ border-radius: 0 0 var(--ext-window-border-radius, 12px) var(--ext-window-border-radius, 12px);
67
46
  }
68
47
 
69
48
  /* Scrollbars for WebKit */
70
49
  ._ewb::-webkit-scrollbar {
71
- width: 0;
50
+ width: 6px;
72
51
  background-color: var(--ext-window-bck-color, white);
73
52
  }
74
53
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ehscan-react-components",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "components",
5
5
  "main": "dist/Components.js",
6
6
  "types": "dist/Components.d.ts",