5htp-core 0.4.9-97 → 0.4.9-98
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/package.json +1 -1
- package/src/client/assets/css/components/button.less +30 -14
- package/src/client/assets/css/theme.less +11 -4
- package/src/client/assets/css/utils/layouts.less +4 -1
- package/src/client/components/Select/ChoiceElement.tsx +21 -22
- package/src/client/components/Select/index.tsx +32 -43
- package/src/client/components/button.tsx +24 -16
- package/src/client/components/dropdown/index.tsx +1 -1
- package/src/client/components/input/Slider/index.tsx +0 -5
- package/src/client/components/inputv3/Checkbox/index.tsx +0 -6
- package/src/client/components/inputv3/Rte/index.tsx +0 -6
- package/src/client/components/inputv3/Rte/plugins/TableActionMenuPlugin/index.tsx +1 -1
- package/src/client/components/inputv3/Rte/ui/DropDown.tsx +1 -1
- package/src/client/components/inputv3/base.less +17 -28
- package/src/client/components/inputv3/base.tsx +7 -1
- package/src/client/components/inputv3/index.tsx +0 -6
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "5htp-core",
|
|
3
3
|
"description": "Convenient TypeScript framework designed for Performance and Productivity.",
|
|
4
|
-
"version": "0.4.9-
|
|
4
|
+
"version": "0.4.9-98",
|
|
5
5
|
"author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
|
|
6
6
|
"repository": "git://github.com/gaetanlegac/5htp-core.git",
|
|
7
7
|
"license": "MIT",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
|
|
12
12
|
// Layout
|
|
13
13
|
position: relative;
|
|
14
|
-
gap: @spacing;
|
|
15
|
-
min-width:
|
|
14
|
+
gap: @spacing / 2;
|
|
15
|
+
min-width: @sizeComponent; // Wdth should be < height
|
|
16
16
|
|
|
17
17
|
// Dimensions
|
|
18
18
|
font-size: 1em;
|
|
@@ -29,8 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
// Colors
|
|
31
31
|
// NOTE: transparent by default (menu items, etc..)
|
|
32
|
-
background:
|
|
33
|
-
color: var(--cTxtAccent);
|
|
32
|
+
background: var(--cBg);
|
|
34
33
|
|
|
35
34
|
// Hover
|
|
36
35
|
//transition: all .5s linear;
|
|
@@ -38,6 +37,7 @@
|
|
|
38
37
|
li:hover > & {
|
|
39
38
|
|
|
40
39
|
color: var(--cTxtImportant);
|
|
40
|
+
background: var(--cBgActive);
|
|
41
41
|
//transition: all .1s linear;
|
|
42
42
|
|
|
43
43
|
> i {
|
|
@@ -77,9 +77,14 @@
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
&.selected {
|
|
81
|
+
background: var(--cBgSelected);
|
|
82
|
+
color: #fff;
|
|
83
|
+
}
|
|
84
|
+
|
|
80
85
|
// Click
|
|
81
86
|
&.pressed {
|
|
82
|
-
|
|
87
|
+
background: var(--cBgPressed) !important;
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
&,
|
|
@@ -149,6 +154,11 @@
|
|
|
149
154
|
|
|
150
155
|
}
|
|
151
156
|
|
|
157
|
+
&:not(.bg) {
|
|
158
|
+
|
|
159
|
+
color: var(--cTxtAccent);
|
|
160
|
+
}
|
|
161
|
+
|
|
152
162
|
/*----------------------------------
|
|
153
163
|
- STATE
|
|
154
164
|
----------------------------------*/
|
|
@@ -231,7 +241,7 @@
|
|
|
231
241
|
// Give less imortance to buttons which are in lists
|
|
232
242
|
color: var(--cTxtBase);
|
|
233
243
|
box-shadow: none;
|
|
234
|
-
|
|
244
|
+
padding: 0 1em; // Row display = more condensed
|
|
235
245
|
|
|
236
246
|
&.active,
|
|
237
247
|
&:hover {
|
|
@@ -239,14 +249,6 @@
|
|
|
239
249
|
color: var(--cTxtImportant);
|
|
240
250
|
}
|
|
241
251
|
|
|
242
|
-
> .label {
|
|
243
|
-
// All the list items label must be aligned
|
|
244
|
-
justify-content: flex-start;
|
|
245
|
-
// Since they're all horizontally aligned,
|
|
246
|
-
// Label = max width, so icon right are also aligned to right
|
|
247
|
-
flex: 1;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
252
|
&.icon {
|
|
251
253
|
|
|
252
254
|
color: var(--cTxtDesc);
|
|
@@ -273,6 +275,20 @@
|
|
|
273
275
|
}
|
|
274
276
|
}
|
|
275
277
|
|
|
278
|
+
.col {
|
|
279
|
+
&.menu > .btn,
|
|
280
|
+
&.menu > li > .btn {
|
|
281
|
+
|
|
282
|
+
> .label {
|
|
283
|
+
// All the list items label must be aligned
|
|
284
|
+
justify-content: flex-start;
|
|
285
|
+
// Since they're all horizontally aligned,
|
|
286
|
+
// Label = max width, so icon right are also aligned to right
|
|
287
|
+
flex: 1;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
276
292
|
ul.col,
|
|
277
293
|
ul.row {
|
|
278
294
|
|
|
@@ -19,9 +19,7 @@
|
|
|
19
19
|
// Default theming for the children components
|
|
20
20
|
@{componentsSelector} {
|
|
21
21
|
// Don't apply the default theme to already themed components
|
|
22
|
-
|
|
23
|
-
.apply-theme-style( @componentsTheme, false, false );
|
|
24
|
-
}
|
|
22
|
+
.apply-theme-style( @componentsTheme, false, false );
|
|
25
23
|
}
|
|
26
24
|
}
|
|
27
25
|
}
|
|
@@ -35,15 +33,23 @@
|
|
|
35
33
|
@bgActive: if( (@theme[alpha]) or (alpha(@bg) < 1),
|
|
36
34
|
fadeout( @bg, 90%),
|
|
37
35
|
if( @isLight,
|
|
38
|
-
@bg - #
|
|
36
|
+
@bg - #0A0A0A,
|
|
39
37
|
@bg + #111,
|
|
40
38
|
)
|
|
41
39
|
);
|
|
40
|
+
@bgPressed: if( (@theme[alpha]) or (alpha(@bg) < 1),
|
|
41
|
+
fadeout( @bg, 80%),
|
|
42
|
+
if( @isLight,
|
|
43
|
+
@bg - #1A1A1A,
|
|
44
|
+
@bg + #222,
|
|
45
|
+
)
|
|
46
|
+
);
|
|
42
47
|
@fg: @theme[foreground];
|
|
43
48
|
|
|
44
49
|
// Background
|
|
45
50
|
--cBg: @bg;
|
|
46
51
|
--cBgActive: @bgActive;
|
|
52
|
+
--cBgPressed: @bgPressed;
|
|
47
53
|
& when (@apply = true) {
|
|
48
54
|
background: var(--cBg);
|
|
49
55
|
}
|
|
@@ -51,6 +57,7 @@
|
|
|
51
57
|
// Accent
|
|
52
58
|
& when (@theme[accent1]) {
|
|
53
59
|
--cTxtAccent: @theme[accent1];
|
|
60
|
+
--cBgSelected: @@theme[accent1];
|
|
54
61
|
}
|
|
55
62
|
& when (@theme[accent2]) {
|
|
56
63
|
--cTxtAccent2: @theme[accent2];
|
|
@@ -140,8 +140,11 @@
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
// Put this one at first because high possibilities we need to override
|
|
144
|
+
&.al-middle,
|
|
145
|
+
&.al-center { justify-content: center; }
|
|
146
|
+
|
|
143
147
|
&, &.al-top { justify-content: flex-start; }
|
|
144
|
-
&.al-middle, &.al-center { justify-content: center; }
|
|
145
148
|
&.al-bottom { justify-content: flex-end; }
|
|
146
149
|
|
|
147
150
|
&.al-left { align-items: flex-start; }
|
|
@@ -20,7 +20,7 @@ import type { Props } from '.';
|
|
|
20
20
|
/*----------------------------------
|
|
21
21
|
- COMPONENT
|
|
22
22
|
----------------------------------*/
|
|
23
|
-
export default ({ choice, currentList, onChange, multiple, includeCurrent, format = 'badge' }: {
|
|
23
|
+
export default ({ choice, currentList, onChange, multiple, required, includeCurrent, format = 'badge' }: {
|
|
24
24
|
choice: Choice,
|
|
25
25
|
currentList: Choice[],
|
|
26
26
|
includeCurrent?: boolean,
|
|
@@ -30,37 +30,36 @@ export default ({ choice, currentList, onChange, multiple, includeCurrent, forma
|
|
|
30
30
|
const isCurrent = currentList.some(c => c.value === choice.value);
|
|
31
31
|
if (isCurrent && !includeCurrent) return null;
|
|
32
32
|
|
|
33
|
-
const
|
|
33
|
+
const canUnselect = !required || currentList.length > 1;
|
|
34
|
+
|
|
35
|
+
const onClick = () => {
|
|
36
|
+
|
|
37
|
+
if (isCurrent && !canUnselect)
|
|
38
|
+
return;
|
|
39
|
+
|
|
40
|
+
onChange( current => multiple
|
|
41
|
+
? (isCurrent
|
|
42
|
+
? currentList.filter(item => item.value !== choice.value)
|
|
43
|
+
: [...(current || []), choice]
|
|
44
|
+
)
|
|
45
|
+
: isCurrent ? undefined : choice
|
|
46
|
+
);
|
|
47
|
+
}
|
|
34
48
|
|
|
35
49
|
return format === 'list' ? (
|
|
36
50
|
<li>
|
|
37
|
-
<Button
|
|
38
|
-
? (isCurrent
|
|
39
|
-
? currentList.filter(item => item.value !== choice.value)
|
|
40
|
-
: [...(current || []), choice]
|
|
41
|
-
)
|
|
42
|
-
: isCurrent ? undefined : choice
|
|
43
|
-
)}>
|
|
51
|
+
<Button selected={isCurrent} onClick={onClick}>
|
|
44
52
|
{choice.label}
|
|
45
53
|
</Button>
|
|
46
54
|
</li>
|
|
47
55
|
) : (
|
|
48
56
|
<li>
|
|
49
|
-
<Button type="secondary"
|
|
50
|
-
|
|
51
|
-
? currentList.filter(item => item.value !== choice.value)
|
|
52
|
-
: [...(current || []), choice]
|
|
53
|
-
)
|
|
54
|
-
: isCurrent ? undefined : choice
|
|
55
|
-
)}>
|
|
57
|
+
<Button type="secondary" selected={isCurrent} onClick={onClick}>
|
|
58
|
+
|
|
56
59
|
{choice.label}
|
|
57
60
|
|
|
58
|
-
{
|
|
59
|
-
<span class="badge xs clickable"
|
|
60
|
-
e.stopPropagation();
|
|
61
|
-
onChange( current => current.filter( c => c.value !== choice.value))
|
|
62
|
-
return false;
|
|
63
|
-
}}>
|
|
61
|
+
{(isCurrent && canUnselect) && (
|
|
62
|
+
<span class="badge xs clickable">
|
|
64
63
|
x
|
|
65
64
|
</span>
|
|
66
65
|
)}
|
|
@@ -165,6 +165,7 @@ export default (props: Props) => {
|
|
|
165
165
|
----------------------------------*/
|
|
166
166
|
|
|
167
167
|
const selectedItems = enableSearch ? currentList : []
|
|
168
|
+
const selectedItemsValue = selectedItems.map( c => c.value);
|
|
168
169
|
|
|
169
170
|
const Search = enableSearch && (
|
|
170
171
|
<Input
|
|
@@ -197,6 +198,7 @@ export default (props: Props) => {
|
|
|
197
198
|
currentList={currentList}
|
|
198
199
|
onChange={onChange}
|
|
199
200
|
multiple={multiple}
|
|
201
|
+
required={required}
|
|
200
202
|
includeCurrent
|
|
201
203
|
/>
|
|
202
204
|
))}
|
|
@@ -214,6 +216,7 @@ export default (props: Props) => {
|
|
|
214
216
|
currentList={currentList}
|
|
215
217
|
onChange={onChange}
|
|
216
218
|
multiple={multiple}
|
|
219
|
+
required={required}
|
|
217
220
|
includeCurrent
|
|
218
221
|
/>
|
|
219
222
|
))}
|
|
@@ -229,7 +232,7 @@ export default (props: Props) => {
|
|
|
229
232
|
)}
|
|
230
233
|
</div>
|
|
231
234
|
)} state={popoverState}>
|
|
232
|
-
<Button
|
|
235
|
+
<Button icon={icon} iconR="angle-down" {...otherProps}>
|
|
233
236
|
|
|
234
237
|
{currentList.length === 0 ? <>
|
|
235
238
|
{title}
|
|
@@ -239,51 +242,37 @@ export default (props: Props) => {
|
|
|
239
242
|
{currentList[0].label}
|
|
240
243
|
</>}
|
|
241
244
|
|
|
242
|
-
{errors?.length && (
|
|
243
|
-
<div class="bubble bg error bottom">
|
|
244
|
-
{errors.join('. ')}
|
|
245
|
-
</div>
|
|
246
|
-
)}
|
|
247
|
-
|
|
248
245
|
</Button>
|
|
249
246
|
</Popover>
|
|
250
247
|
) : (
|
|
251
|
-
<div class=
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
</ul>
|
|
280
|
-
|
|
281
|
-
</div>
|
|
282
|
-
{errors?.length && (
|
|
283
|
-
<div class="bubble bg error bottom">
|
|
284
|
-
{errors.join('. ')}
|
|
285
|
-
</div>
|
|
286
|
-
)}
|
|
248
|
+
<div class={className} onMouseDown={() => refInputSearch.current?.focus()}>
|
|
249
|
+
|
|
250
|
+
{Search}
|
|
251
|
+
|
|
252
|
+
<ul class="row al-left wrap sp-05 scrollable mgt-1" style={{
|
|
253
|
+
maxHeight: '30vh',
|
|
254
|
+
}}>
|
|
255
|
+
{selectedItems.map( choice => (
|
|
256
|
+
<ChoiceElement format='badge' choice={choice}
|
|
257
|
+
currentList={currentList}
|
|
258
|
+
onChange={onChange}
|
|
259
|
+
multiple={multiple}
|
|
260
|
+
required={required}
|
|
261
|
+
includeCurrent
|
|
262
|
+
/>
|
|
263
|
+
))}
|
|
264
|
+
|
|
265
|
+
{choices.map( choice => !selectedItemsValue.includes(choice.value) && (
|
|
266
|
+
<ChoiceElement format='badge' choice={choice}
|
|
267
|
+
currentList={currentList}
|
|
268
|
+
onChange={onChange}
|
|
269
|
+
multiple={multiple}
|
|
270
|
+
required={required}
|
|
271
|
+
includeCurrent
|
|
272
|
+
/>
|
|
273
|
+
))}
|
|
274
|
+
</ul>
|
|
275
|
+
|
|
287
276
|
</div>
|
|
288
277
|
)}
|
|
289
278
|
</InputWrapper>
|
|
@@ -35,6 +35,7 @@ export type Props = {
|
|
|
35
35
|
|
|
36
36
|
state?: [string, React.StateUpdater<string>],
|
|
37
37
|
active?: boolean,
|
|
38
|
+
selected?: boolean,
|
|
38
39
|
disabled?: boolean,
|
|
39
40
|
loading?: boolean,
|
|
40
41
|
autoFocus?: boolean,
|
|
@@ -92,6 +93,7 @@ export default ({
|
|
|
92
93
|
|
|
93
94
|
// Interactions
|
|
94
95
|
active,
|
|
96
|
+
selected,
|
|
95
97
|
state: stateUpdater,
|
|
96
98
|
disabled,
|
|
97
99
|
loading,
|
|
@@ -106,7 +108,8 @@ export default ({
|
|
|
106
108
|
}: Props) => {
|
|
107
109
|
|
|
108
110
|
const ctx = useContext();
|
|
109
|
-
let [
|
|
111
|
+
let [isSelected, setIsSelected] = React.useState(false);
|
|
112
|
+
let [isActive, setIsActive] = React.useState(false);
|
|
110
113
|
const [isLoading, setLoading] = React.useState(false);
|
|
111
114
|
|
|
112
115
|
if (isLoading || loading) {
|
|
@@ -118,29 +121,28 @@ export default ({
|
|
|
118
121
|
if (stateUpdater && id !== undefined) {
|
|
119
122
|
const [active, setActive] = stateUpdater;
|
|
120
123
|
if (id === active)
|
|
121
|
-
|
|
124
|
+
isSelected = true;
|
|
122
125
|
props.onClick = () => setActive(id);
|
|
123
126
|
}
|
|
124
127
|
|
|
125
128
|
// Shape classes
|
|
126
|
-
|
|
129
|
+
const classNames: string[] = ['btn'];
|
|
130
|
+
if (className)
|
|
131
|
+
classNames.push(className);
|
|
127
132
|
|
|
128
133
|
if (shape !== undefined) {
|
|
129
134
|
if (shape === 'tile')
|
|
130
|
-
|
|
135
|
+
classNames.push('col');
|
|
131
136
|
else
|
|
132
|
-
|
|
137
|
+
classNames.push(shape);
|
|
133
138
|
}
|
|
134
139
|
|
|
135
140
|
if (size !== undefined)
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (type !== undefined)
|
|
139
|
-
className += type === 'link' ? type : (' bg ' + type);
|
|
141
|
+
classNames.push(size);
|
|
140
142
|
|
|
141
143
|
if (icon) {
|
|
142
144
|
if (children === undefined)
|
|
143
|
-
|
|
145
|
+
classNames.push('icon');
|
|
144
146
|
}
|
|
145
147
|
|
|
146
148
|
// state classes
|
|
@@ -148,11 +150,17 @@ export default ({
|
|
|
148
150
|
props.onMouseDown = () => setMouseDown(true);
|
|
149
151
|
props.onMouseUp = () => setMouseDown(false);
|
|
150
152
|
props.onMouseLeave = () => setMouseDown(false);
|
|
151
|
-
if (isMouseDown)
|
|
152
|
-
className += ' pressed';
|
|
153
153
|
|
|
154
|
+
// Theming & state
|
|
155
|
+
if (isMouseDown)
|
|
156
|
+
classNames.push('pressed');
|
|
157
|
+
else if (selected || isSelected === true)
|
|
158
|
+
classNames.push('bg accent');
|
|
159
|
+
else if (type !== undefined)
|
|
160
|
+
classNames.push(type === 'link' ? type : (' bg ' + type));
|
|
161
|
+
|
|
154
162
|
if (active || isActive === true)
|
|
155
|
-
|
|
163
|
+
classNames.push('active');
|
|
156
164
|
|
|
157
165
|
// Icon
|
|
158
166
|
if (prefix === undefined && icon !== undefined)
|
|
@@ -180,12 +188,12 @@ export default ({
|
|
|
180
188
|
|
|
181
189
|
// Init
|
|
182
190
|
if (checkIfCurrentUrl(ctx.request.path))
|
|
183
|
-
|
|
191
|
+
setIsActive(true);
|
|
184
192
|
|
|
185
193
|
// On location change
|
|
186
194
|
return history?.listen(({ location }) => {
|
|
187
195
|
|
|
188
|
-
|
|
196
|
+
setIsActive( checkIfCurrentUrl(location.pathname) );
|
|
189
197
|
|
|
190
198
|
})
|
|
191
199
|
|
|
@@ -207,7 +215,7 @@ export default ({
|
|
|
207
215
|
}
|
|
208
216
|
|
|
209
217
|
let render: VNode = (
|
|
210
|
-
<Tag {...props} id={id} class={
|
|
218
|
+
<Tag {...props} id={id} class={classNames.join(' ')} disabled={disabled} ref={refElem} onClick={(e: MouseEvent) => {
|
|
211
219
|
|
|
212
220
|
// annulation si:
|
|
213
221
|
// - Pas clic gauche
|
|
@@ -53,7 +53,7 @@ export default (props: Props) => {
|
|
|
53
53
|
</div>
|
|
54
54
|
)} state={popoverState} {...(popover || {})}>
|
|
55
55
|
|
|
56
|
-
<Button {...buttonProps} iconR={<i src="
|
|
56
|
+
<Button {...buttonProps} iconR={<i src="angle-down" class="s" />}
|
|
57
57
|
refElem={refButton} children={label} />
|
|
58
58
|
|
|
59
59
|
</Popover>
|
|
@@ -27,33 +27,8 @@
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
.input {
|
|
31
|
-
&.text,
|
|
32
|
-
&.select {
|
|
33
|
-
|
|
34
|
-
background: var(--cBg);
|
|
35
|
-
border-radius: @radius;
|
|
36
|
-
|
|
37
|
-
> i {
|
|
38
|
-
color: var(--cTxtDesc);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Error bubble
|
|
43
|
-
position: relative;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
30
|
.input.select {
|
|
47
|
-
|
|
48
|
-
padding: 0;
|
|
49
|
-
|
|
50
|
-
.input.text {
|
|
51
|
-
border: none;
|
|
52
|
-
box-shadow: none;
|
|
53
|
-
padding: 0;
|
|
54
|
-
height: auto;
|
|
55
|
-
width: 150px;
|
|
56
|
-
}
|
|
31
|
+
|
|
57
32
|
}
|
|
58
33
|
|
|
59
34
|
.input.text {
|
|
@@ -68,9 +43,23 @@
|
|
|
68
43
|
// Since they are not supposed to be on the same row (mobile first design)
|
|
69
44
|
height: @hInput;
|
|
70
45
|
align-items: center;
|
|
46
|
+
|
|
47
|
+
background: var(--cBg);
|
|
48
|
+
border-radius: @radius;
|
|
49
|
+
transition: background .1s linear;
|
|
50
|
+
|
|
51
|
+
> i {
|
|
52
|
+
color: var(--cTxtDesc);
|
|
53
|
+
}
|
|
71
54
|
|
|
72
|
-
|
|
73
|
-
|
|
55
|
+
&:hover {
|
|
56
|
+
background: var(--cBgActive);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&.focus {
|
|
60
|
+
background: #fff;
|
|
61
|
+
box-shadow: 1px 3px 0 fade(#000,4%), 0 1px 2px 0 fade(#000,2%);
|
|
62
|
+
}
|
|
74
63
|
|
|
75
64
|
@gapAround: @spacing;
|
|
76
65
|
> .btn:first-child { margin-left: 0 - @gapAround / 2; }
|
|
@@ -96,7 +96,7 @@ export function useInput<TValue>(
|
|
|
96
96
|
/*----------------------------------
|
|
97
97
|
- COMPONENT
|
|
98
98
|
----------------------------------*/
|
|
99
|
-
export const InputWrapper = ({ children, wrapper = true, title, hint, required, className = '' }: InputBaseProps<unknown> & {
|
|
99
|
+
export const InputWrapper = ({ children, wrapper = true, title, hint, required, errors, className = '' }: InputBaseProps<unknown> & {
|
|
100
100
|
children: ComponentChild
|
|
101
101
|
}) => {
|
|
102
102
|
|
|
@@ -123,6 +123,12 @@ export const InputWrapper = ({ children, wrapper = true, title, hint, required,
|
|
|
123
123
|
{hint && <p class="hint">{hint}</p>}
|
|
124
124
|
|
|
125
125
|
{children}
|
|
126
|
+
|
|
127
|
+
{errors?.length && (
|
|
128
|
+
<div class="bubble bg error bottom">
|
|
129
|
+
{errors.join('. ')}
|
|
130
|
+
</div>
|
|
131
|
+
)}
|
|
126
132
|
|
|
127
133
|
</div>
|
|
128
134
|
)
|
|
@@ -200,12 +200,6 @@ export default (props: Props & InputBaseProps<string> & TInputElementProps) => {
|
|
|
200
200
|
</div>
|
|
201
201
|
|
|
202
202
|
{suffix}
|
|
203
|
-
|
|
204
|
-
{errors?.length && (
|
|
205
|
-
<div class="bubble bg error bottom">
|
|
206
|
-
{errors.join('. ')}
|
|
207
|
-
</div>
|
|
208
|
-
)}
|
|
209
203
|
|
|
210
204
|
</div>
|
|
211
205
|
</InputWrapper>
|