@jsenv/navi 0.1.0 → 0.2.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/dist/jsenv_navi.js +8413 -3793
- package/package.json +4 -3
- package/src/components/action_execution/form_context.js +1 -4
- package/src/components/action_execution/use_action.js +2 -2
- package/src/components/demos/0_button_demo.html +149 -68
- package/src/components/demos/1_checkbox_demo.html +122 -2
- package/src/components/demos/2_input_textual_demo.html +44 -55
- package/src/components/demos/3_radio_demo.html +811 -157
- package/src/components/demos/action/0_button_demo.html +6 -4
- package/src/components/demos/action/1_input_text_demo.html +19 -25
- package/src/components/field/button.jsx +174 -71
- package/src/components/field/custom_field.js +106 -0
- package/src/components/field/field_css.js +51 -85
- package/src/components/field/form.jsx +9 -4
- package/src/components/field/input_checkbox.jsx +170 -99
- package/src/components/field/input_radio.jsx +179 -153
- package/src/components/field/input_textual.jsx +103 -6
- package/src/components/field/label.jsx +15 -3
- package/src/components/field/navi_css_vars.js +8 -0
- package/src/components/loader/loader_background.jsx +41 -14
- package/src/validation/constraints/readonly_constraint.js +5 -0
- package/src/validation/validation_message.js +78 -70
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/navi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Library of components including navigation to create frontend applications",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"email": "dmaillard06@gmail.com"
|
|
14
14
|
},
|
|
15
15
|
"sideEffects": [
|
|
16
|
-
"./dist/jsenv_navi.js"
|
|
16
|
+
"./dist/jsenv_navi.js",
|
|
17
|
+
"./src/components/field/field_css.js"
|
|
17
18
|
],
|
|
18
19
|
"type": "module",
|
|
19
20
|
"exports": {
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
"prepublishOnly": "npm run build"
|
|
34
35
|
},
|
|
35
36
|
"dependencies": {
|
|
36
|
-
"@jsenv/dom": "0.
|
|
37
|
+
"@jsenv/dom": "0.3.0",
|
|
37
38
|
"@jsenv/humanize": "1.6.0"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { createContext } from "preact";
|
|
2
|
-
import { useContext } from "preact/hooks";
|
|
3
2
|
|
|
4
3
|
export const FormContext = createContext();
|
|
5
4
|
|
|
6
|
-
export const
|
|
7
|
-
return useContext(FormContext);
|
|
8
|
-
};
|
|
5
|
+
export const FormActionContext = createContext();
|
|
@@ -29,7 +29,7 @@ export const useActionBoundToOneArrayParam = (
|
|
|
29
29
|
fallbackValue,
|
|
30
30
|
defaultValue,
|
|
31
31
|
) => {
|
|
32
|
-
const [boundAction, value, setValue
|
|
32
|
+
const [boundAction, value, setValue] = useActionBoundToOneParam(
|
|
33
33
|
action,
|
|
34
34
|
name,
|
|
35
35
|
externalValue,
|
|
@@ -45,7 +45,7 @@ export const useActionBoundToOneArrayParam = (
|
|
|
45
45
|
setValue(removeFromArray(valueArray, valueToRemove));
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
const result = [boundAction, value, setValue
|
|
48
|
+
const result = [boundAction, value, setValue];
|
|
49
49
|
result.add = add;
|
|
50
50
|
result.remove = remove;
|
|
51
51
|
return result;
|
|
@@ -7,72 +7,72 @@
|
|
|
7
7
|
<title>Button Demo</title>
|
|
8
8
|
<style>
|
|
9
9
|
body {
|
|
10
|
-
font-family:
|
|
11
|
-
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
12
10
|
max-width: 1400px;
|
|
11
|
+
min-height: 100vh;
|
|
13
12
|
margin: 0 auto;
|
|
14
13
|
padding: 20px;
|
|
14
|
+
font-family:
|
|
15
|
+
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
15
16
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
16
|
-
min-height: 100vh;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
h1 {
|
|
20
|
-
text-align: center;
|
|
21
|
-
color: white;
|
|
22
20
|
margin-bottom: 30px;
|
|
21
|
+
color: white;
|
|
23
22
|
font-size: 2.5rem;
|
|
23
|
+
text-align: center;
|
|
24
24
|
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
.demo-grid {
|
|
28
28
|
display: grid;
|
|
29
|
+
margin-bottom: 30px;
|
|
29
30
|
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
|
30
31
|
gap: 20px;
|
|
31
|
-
margin-bottom: 30px;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
.demo-card {
|
|
35
|
+
padding: 25px;
|
|
35
36
|
background: white;
|
|
37
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
36
38
|
border-radius: 12px;
|
|
37
|
-
padding: 25px;
|
|
38
39
|
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
|
39
|
-
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
40
40
|
transition:
|
|
41
41
|
transform 0.2s ease,
|
|
42
42
|
box-shadow 0.2s ease;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
.demo-card:hover {
|
|
46
|
-
transform: translateY(-2px);
|
|
47
46
|
box-shadow: 0 12px 35px rgba(0, 0, 0, 0.2);
|
|
47
|
+
transform: translateY(-2px);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
.demo-title {
|
|
51
|
-
|
|
51
|
+
display: flex;
|
|
52
52
|
margin: 0 0 20px 0;
|
|
53
|
-
font-size: 1.3rem;
|
|
54
|
-
font-weight: 600;
|
|
55
|
-
border-bottom: 3px solid #667eea;
|
|
56
53
|
padding-bottom: 10px;
|
|
57
|
-
display: flex;
|
|
58
54
|
align-items: center;
|
|
59
55
|
gap: 10px;
|
|
56
|
+
color: #2c3e50;
|
|
57
|
+
font-weight: 600;
|
|
58
|
+
font-size: 1.3rem;
|
|
59
|
+
border-bottom: 3px solid #667eea;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
.demo-title::before {
|
|
63
|
-
content: "🔘";
|
|
64
63
|
font-size: 1.2rem;
|
|
64
|
+
content: "🔘";
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
.button-row {
|
|
68
68
|
display: flex;
|
|
69
|
-
align-items: center;
|
|
70
|
-
gap: 15px;
|
|
71
69
|
margin: 15px 0;
|
|
72
70
|
padding: 12px;
|
|
71
|
+
align-items: center;
|
|
72
|
+
gap: 15px;
|
|
73
73
|
background: #f8f9fa;
|
|
74
|
-
border-radius: 8px;
|
|
75
74
|
border: 1px solid #e9ecef;
|
|
75
|
+
border-radius: 8px;
|
|
76
76
|
transition: background 0.2s ease;
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -82,49 +82,49 @@
|
|
|
82
82
|
|
|
83
83
|
.button-container {
|
|
84
84
|
display: flex;
|
|
85
|
+
min-width: 0;
|
|
86
|
+
flex: 1;
|
|
85
87
|
align-items: center;
|
|
86
88
|
gap: 10px;
|
|
87
|
-
flex: 1;
|
|
88
|
-
min-width: 0;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
.toggle-button {
|
|
92
92
|
padding: 8px 16px;
|
|
93
|
-
|
|
93
|
+
flex-shrink: 0;
|
|
94
94
|
color: white;
|
|
95
|
+
font-weight: 500;
|
|
96
|
+
font-size: 0.9rem;
|
|
97
|
+
white-space: nowrap;
|
|
98
|
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
|
95
99
|
border: none;
|
|
96
100
|
border-radius: 6px;
|
|
97
|
-
cursor: pointer;
|
|
98
|
-
font-size: 0.9rem;
|
|
99
|
-
font-weight: 500;
|
|
100
|
-
transition: all 0.2s ease;
|
|
101
101
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
transition: all 0.2s ease;
|
|
103
|
+
cursor: pointer;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
.toggle-button:hover {
|
|
107
107
|
background: linear-gradient(45deg, #5a6fd8, #6b3fa0);
|
|
108
|
-
transform: translateY(-1px);
|
|
109
108
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
|
109
|
+
transform: translateY(-1px);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
.comparison {
|
|
113
113
|
display: flex;
|
|
114
|
-
flex-direction: column;
|
|
115
|
-
gap: 8px;
|
|
116
114
|
margin-top: 15px;
|
|
117
115
|
padding: 12px;
|
|
116
|
+
flex-direction: column;
|
|
117
|
+
gap: 8px;
|
|
118
118
|
background: #fff3cd;
|
|
119
|
-
border-radius: 6px;
|
|
120
119
|
border-left: 4px solid #ffc107;
|
|
120
|
+
border-radius: 6px;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
.comparison-label {
|
|
124
|
-
|
|
124
|
+
margin-bottom: 5px;
|
|
125
125
|
color: #856404;
|
|
126
126
|
font-weight: 500;
|
|
127
|
-
|
|
127
|
+
font-size: 0.85rem;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
.native-examples {
|
|
@@ -134,15 +134,15 @@
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
.native-examples button {
|
|
137
|
-
align-self: flex-start;
|
|
138
137
|
padding: 8px 16px;
|
|
138
|
+
align-self: flex-start;
|
|
139
139
|
font-size: 0.9rem;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
.prop-control-demo {
|
|
143
143
|
grid-column: 1 / -1;
|
|
144
|
-
background: linear-gradient(45deg, #ff6b6b 0%, #feca57 100%);
|
|
145
144
|
color: white;
|
|
145
|
+
background: linear-gradient(45deg, #ff6b6b 0%, #feca57 100%);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
.prop-control-demo .demo-title {
|
|
@@ -155,17 +155,17 @@
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
.prop-controls {
|
|
158
|
-
margin-bottom: 25px;
|
|
159
158
|
display: grid;
|
|
159
|
+
margin-bottom: 25px;
|
|
160
160
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
161
161
|
gap: 15px;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
.prop-select-group {
|
|
165
|
-
background: rgba(255, 255, 255, 0.1);
|
|
166
165
|
padding: 15px;
|
|
167
|
-
|
|
166
|
+
background: rgba(255, 255, 255, 0.1);
|
|
168
167
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
168
|
+
border-radius: 8px;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
.prop-select-label {
|
|
@@ -178,65 +178,65 @@
|
|
|
178
178
|
.prop-select {
|
|
179
179
|
width: 100%;
|
|
180
180
|
padding: 8px 12px;
|
|
181
|
-
border: none;
|
|
182
|
-
border-radius: 6px;
|
|
183
|
-
background: white;
|
|
184
181
|
color: #333;
|
|
185
182
|
font-size: 0.9rem;
|
|
186
|
-
|
|
183
|
+
background: white;
|
|
184
|
+
border: none;
|
|
185
|
+
border-radius: 6px;
|
|
187
186
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
187
|
+
cursor: pointer;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
.state-controls {
|
|
191
|
-
|
|
191
|
+
margin-bottom: 20px;
|
|
192
192
|
padding: 15px;
|
|
193
|
-
|
|
193
|
+
background: rgba(255, 255, 255, 0.1);
|
|
194
194
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
195
|
-
|
|
195
|
+
border-radius: 8px;
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
.state-controls h4 {
|
|
199
199
|
margin: 0 0 15px 0;
|
|
200
|
-
font-size: 1rem;
|
|
201
200
|
color: white;
|
|
201
|
+
font-size: 1rem;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
.control-row {
|
|
205
205
|
display: flex;
|
|
206
|
-
gap: 15px;
|
|
207
|
-
flex-wrap: wrap;
|
|
208
206
|
margin-bottom: 10px;
|
|
207
|
+
flex-wrap: wrap;
|
|
208
|
+
gap: 15px;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
.control-group {
|
|
212
212
|
display: flex;
|
|
213
|
+
min-width: 100px;
|
|
214
|
+
padding: 12px;
|
|
213
215
|
flex-direction: column;
|
|
214
216
|
align-items: center;
|
|
215
217
|
gap: 8px;
|
|
216
218
|
background: rgba(255, 255, 255, 0.05);
|
|
217
|
-
padding: 12px;
|
|
218
|
-
border-radius: 8px;
|
|
219
219
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
220
|
-
|
|
220
|
+
border-radius: 8px;
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
.control-toggle {
|
|
224
|
+
min-width: 80px;
|
|
224
225
|
padding: 8px 16px;
|
|
225
|
-
border: 2px solid rgba(255, 255, 255, 0.3);
|
|
226
|
-
background: rgba(255, 255, 255, 0.1);
|
|
227
226
|
color: white;
|
|
228
|
-
border-radius: 6px;
|
|
229
|
-
cursor: pointer;
|
|
230
|
-
font-size: 0.85rem;
|
|
231
227
|
font-weight: 500;
|
|
232
|
-
|
|
233
|
-
min-width: 80px;
|
|
228
|
+
font-size: 0.85rem;
|
|
234
229
|
text-align: center;
|
|
230
|
+
background: rgba(255, 255, 255, 0.1);
|
|
231
|
+
border: 2px solid rgba(255, 255, 255, 0.3);
|
|
232
|
+
border-radius: 6px;
|
|
233
|
+
transition: all 0.2s ease;
|
|
234
|
+
cursor: pointer;
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
.control-toggle.active {
|
|
238
|
-
background: rgba(255, 255, 255, 0.9);
|
|
239
238
|
color: #333;
|
|
239
|
+
background: rgba(255, 255, 255, 0.9);
|
|
240
240
|
border-color: white;
|
|
241
241
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
|
242
242
|
}
|
|
@@ -251,36 +251,36 @@
|
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
.control-label {
|
|
254
|
-
font-size: 0.9rem;
|
|
255
|
-
color: white;
|
|
256
254
|
margin: 0;
|
|
255
|
+
color: white;
|
|
256
|
+
font-size: 0.9rem;
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
.button-test-grid {
|
|
260
260
|
display: grid;
|
|
261
|
+
padding: 20px;
|
|
261
262
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
262
263
|
gap: 15px;
|
|
263
264
|
background: rgba(255, 255, 255, 0.1);
|
|
264
|
-
padding: 20px;
|
|
265
|
-
border-radius: 8px;
|
|
266
265
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
266
|
+
border-radius: 8px;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
.button-test-item {
|
|
270
270
|
display: flex;
|
|
271
|
+
padding: 15px;
|
|
271
272
|
flex-direction: column;
|
|
272
273
|
align-items: center;
|
|
273
274
|
gap: 10px;
|
|
274
|
-
|
|
275
|
+
text-align: center;
|
|
275
276
|
background: rgba(255, 255, 255, 0.05);
|
|
276
277
|
border-radius: 6px;
|
|
277
|
-
text-align: center;
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
.button-label {
|
|
281
|
-
font-size: 0.9rem;
|
|
282
|
-
color: white;
|
|
283
281
|
margin-bottom: 8px;
|
|
282
|
+
color: white;
|
|
283
|
+
font-size: 0.9rem;
|
|
284
284
|
}
|
|
285
285
|
|
|
286
286
|
@media (max-width: 768px) {
|
|
@@ -320,6 +320,7 @@
|
|
|
320
320
|
<ReadOnlyDemo />
|
|
321
321
|
<DisabledDemo />
|
|
322
322
|
<SizeVariationsDemo />
|
|
323
|
+
<DiscreteDemo />
|
|
323
324
|
<PropControlDemo />
|
|
324
325
|
</div>
|
|
325
326
|
);
|
|
@@ -448,7 +449,11 @@
|
|
|
448
449
|
<div className="button-container">
|
|
449
450
|
<Button
|
|
450
451
|
loading={loading}
|
|
451
|
-
style={{
|
|
452
|
+
style={{
|
|
453
|
+
"--border-width": "8px",
|
|
454
|
+
"--padding-x": "12px",
|
|
455
|
+
"--padding-y": "24px",
|
|
456
|
+
}}
|
|
452
457
|
>
|
|
453
458
|
Thick Border Button
|
|
454
459
|
</Button>
|
|
@@ -474,6 +479,82 @@
|
|
|
474
479
|
);
|
|
475
480
|
};
|
|
476
481
|
|
|
482
|
+
// eslint-disable-next-line no-unused-vars
|
|
483
|
+
const DiscreteDemo = () => {
|
|
484
|
+
const [loading, setLoading] = useState(false);
|
|
485
|
+
|
|
486
|
+
return (
|
|
487
|
+
<div className="demo-card">
|
|
488
|
+
<h3 className="demo-title">Discrete Buttons</h3>
|
|
489
|
+
|
|
490
|
+
<div className="button-row">
|
|
491
|
+
<div className="button-container">
|
|
492
|
+
<Button discrete loading={loading}>
|
|
493
|
+
Discrete Button
|
|
494
|
+
</Button>
|
|
495
|
+
<span style={{ fontSize: "0.9rem", color: "#666" }}>
|
|
496
|
+
Subtle, minimal styling
|
|
497
|
+
</span>
|
|
498
|
+
</div>
|
|
499
|
+
<button
|
|
500
|
+
className="toggle-button"
|
|
501
|
+
onClick={() => setLoading(!loading)}
|
|
502
|
+
>
|
|
503
|
+
{loading ? "Stop Loading" : "Start Loading"}
|
|
504
|
+
</button>
|
|
505
|
+
</div>
|
|
506
|
+
|
|
507
|
+
<div className="button-row">
|
|
508
|
+
<div className="button-container">
|
|
509
|
+
<Button discrete disabled>
|
|
510
|
+
Disabled Discrete
|
|
511
|
+
</Button>
|
|
512
|
+
<span style={{ fontSize: "0.9rem", color: "#666" }}>
|
|
513
|
+
Disabled state
|
|
514
|
+
</span>
|
|
515
|
+
</div>
|
|
516
|
+
</div>
|
|
517
|
+
|
|
518
|
+
<div className="button-row">
|
|
519
|
+
<div className="button-container">
|
|
520
|
+
<Button discrete readOnly>
|
|
521
|
+
Read-Only Discrete
|
|
522
|
+
</Button>
|
|
523
|
+
<span style={{ fontSize: "0.9rem", color: "#666" }}>
|
|
524
|
+
Read-only state
|
|
525
|
+
</span>
|
|
526
|
+
</div>
|
|
527
|
+
</div>
|
|
528
|
+
|
|
529
|
+
<div className="comparison">
|
|
530
|
+
<span className="comparison-label">Comparison:</span>
|
|
531
|
+
<div
|
|
532
|
+
style={{
|
|
533
|
+
display: "flex",
|
|
534
|
+
gap: "15px",
|
|
535
|
+
alignItems: "center",
|
|
536
|
+
marginTop: "10px",
|
|
537
|
+
}}
|
|
538
|
+
>
|
|
539
|
+
<Button appearance="default" loading={loading}>
|
|
540
|
+
Regular Button
|
|
541
|
+
</Button>
|
|
542
|
+
<Button appearance="default" discrete loading={loading}>
|
|
543
|
+
Discrete Button
|
|
544
|
+
</Button>
|
|
545
|
+
</div>
|
|
546
|
+
<div className="native-examples">
|
|
547
|
+
<small style={{ color: "#666" }}>
|
|
548
|
+
Discrete buttons have minimal styling and blend better with
|
|
549
|
+
content. They're perfect for secondary actions or when you
|
|
550
|
+
want less visual emphasis.
|
|
551
|
+
</small>
|
|
552
|
+
</div>
|
|
553
|
+
</div>
|
|
554
|
+
</div>
|
|
555
|
+
);
|
|
556
|
+
};
|
|
557
|
+
|
|
477
558
|
// eslint-disable-next-line no-unused-vars
|
|
478
559
|
const PropControlDemo = () => {
|
|
479
560
|
const [loading, setLoading] = useState(false);
|
|
@@ -281,6 +281,55 @@
|
|
|
281
281
|
font-size: 0.95rem;
|
|
282
282
|
}
|
|
283
283
|
|
|
284
|
+
/* Custom styles override section */
|
|
285
|
+
.my_styles .navi_checkbox {
|
|
286
|
+
--accent-color: green;
|
|
287
|
+
--width: 20px;
|
|
288
|
+
--height: 20px;
|
|
289
|
+
}
|
|
290
|
+
.my_styles .navi_checkbox[data-hover] {
|
|
291
|
+
--accent-color: yellow;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.custom-styles-demo {
|
|
295
|
+
margin-top: 30px;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.custom-styles-test {
|
|
299
|
+
background: rgba(255, 255, 255, 0.1);
|
|
300
|
+
padding: 20px;
|
|
301
|
+
border-radius: 8px;
|
|
302
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
303
|
+
margin: 15px 0;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.custom-styles-test h4 {
|
|
307
|
+
margin-top: 0;
|
|
308
|
+
color: #2c3e50;
|
|
309
|
+
font-size: 1.1rem;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.custom-styles-comparison {
|
|
313
|
+
display: grid;
|
|
314
|
+
grid-template-columns: 1fr 1fr;
|
|
315
|
+
gap: 20px;
|
|
316
|
+
margin-top: 15px;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.comparison-item {
|
|
320
|
+
background: rgba(255, 255, 255, 0.05);
|
|
321
|
+
padding: 15px;
|
|
322
|
+
border-radius: 6px;
|
|
323
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.comparison-item h5 {
|
|
327
|
+
margin-top: 0;
|
|
328
|
+
margin-bottom: 10px;
|
|
329
|
+
color: #34495e;
|
|
330
|
+
font-size: 0.9rem;
|
|
331
|
+
}
|
|
332
|
+
|
|
284
333
|
@media (max-width: 768px) {
|
|
285
334
|
.demo-grid {
|
|
286
335
|
grid-template-columns: 1fr;
|
|
@@ -320,6 +369,7 @@
|
|
|
320
369
|
<ReadOnlyDemo />
|
|
321
370
|
<DisabledDemo />
|
|
322
371
|
<PropControlDemo />
|
|
372
|
+
<CustomStylesDemo />
|
|
323
373
|
</div>
|
|
324
374
|
);
|
|
325
375
|
};
|
|
@@ -493,7 +543,7 @@
|
|
|
493
543
|
const [isLoading, setIsLoading] = useState(false);
|
|
494
544
|
|
|
495
545
|
const colorOptions = [
|
|
496
|
-
{ name: "Default (blue)", value:
|
|
546
|
+
{ name: "Default (blue)", value: "default" },
|
|
497
547
|
{ name: "Orange", value: "#ff8c00" },
|
|
498
548
|
{ name: "Green", value: "#28a745" },
|
|
499
549
|
{ name: "Purple", value: "#6f42c1" },
|
|
@@ -511,7 +561,11 @@
|
|
|
511
561
|
<label className="color-select-label">Accent Color:</label>
|
|
512
562
|
<select
|
|
513
563
|
value={accentColor}
|
|
514
|
-
onChange={(e) =>
|
|
564
|
+
onChange={(e) => {
|
|
565
|
+
setAccentColor(
|
|
566
|
+
e.target.value === "default" ? undefined : e.target.value,
|
|
567
|
+
);
|
|
568
|
+
}}
|
|
515
569
|
className="color-select"
|
|
516
570
|
>
|
|
517
571
|
{colorOptions.map(({ name, value }) => (
|
|
@@ -628,6 +682,72 @@
|
|
|
628
682
|
);
|
|
629
683
|
};
|
|
630
684
|
|
|
685
|
+
// eslint-disable-next-line no-unused-vars
|
|
686
|
+
const CustomStylesDemo = () => {
|
|
687
|
+
return (
|
|
688
|
+
<div className="custom-styles-demo">
|
|
689
|
+
<h2 style={{ color: "#2c3e50", marginBottom: "20px" }}>
|
|
690
|
+
Ability to Override with Custom Styles
|
|
691
|
+
</h2>
|
|
692
|
+
|
|
693
|
+
<div className="custom-styles-test">
|
|
694
|
+
<h4>Accent Color Override Test</h4>
|
|
695
|
+
<p>
|
|
696
|
+
Testing if CSS <code>accent-color</code> property can override
|
|
697
|
+
the component's styling:
|
|
698
|
+
</p>
|
|
699
|
+
|
|
700
|
+
<div className="custom-styles-comparison">
|
|
701
|
+
<div className="comparison-item">
|
|
702
|
+
<h5>Default Checkbox</h5>
|
|
703
|
+
<Label className="checkbox-label">
|
|
704
|
+
<Input
|
|
705
|
+
type="checkbox"
|
|
706
|
+
name="default-checkbox"
|
|
707
|
+
defaultChecked={true}
|
|
708
|
+
/>
|
|
709
|
+
Default styling
|
|
710
|
+
</Label>
|
|
711
|
+
</div>
|
|
712
|
+
|
|
713
|
+
<div className="comparison-item my_styles">
|
|
714
|
+
<h5>Custom Styled Checkbox (.my_styles)</h5>
|
|
715
|
+
<Label className="checkbox-label">
|
|
716
|
+
<Input
|
|
717
|
+
type="checkbox"
|
|
718
|
+
name="custom-styled-checkbox"
|
|
719
|
+
defaultChecked={true}
|
|
720
|
+
/>
|
|
721
|
+
Should be green accent
|
|
722
|
+
</Label>
|
|
723
|
+
</div>
|
|
724
|
+
</div>
|
|
725
|
+
|
|
726
|
+
<div
|
|
727
|
+
style={{
|
|
728
|
+
marginTop: "15px",
|
|
729
|
+
padding: "10px",
|
|
730
|
+
background: "rgba(255,255,255,0.1)",
|
|
731
|
+
borderRadius: "4px",
|
|
732
|
+
}}
|
|
733
|
+
>
|
|
734
|
+
<p
|
|
735
|
+
style={{
|
|
736
|
+
marginTop: "10px",
|
|
737
|
+
fontSize: "0.9em",
|
|
738
|
+
color: "#666",
|
|
739
|
+
}}
|
|
740
|
+
>
|
|
741
|
+
If the custom styling works, the checkbox on the right should
|
|
742
|
+
have a green accent color instead of the component's default
|
|
743
|
+
accent color.
|
|
744
|
+
</p>
|
|
745
|
+
</div>
|
|
746
|
+
</div>
|
|
747
|
+
</div>
|
|
748
|
+
);
|
|
749
|
+
};
|
|
750
|
+
|
|
631
751
|
render(<App />, document.querySelector("#root"));
|
|
632
752
|
</script>
|
|
633
753
|
</body>
|