@ainias42/react-bootstrap-mobile 0.2.12 → 0.2.14
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/bin/release.sh +0 -1
- package/bin/updateCopies.js +1 -0
- package/bootstrapReactMobile.ts +1 -0
- package/dist/bootstrapReactMobile.d.ts +1 -0
- package/dist/bootstrapReactMobile.js +3295 -18691
- package/dist/bootstrapReactMobile.js.map +1 -1
- package/dist/src/Components/FormElements/Button/Button.d.ts +2 -1
- package/dist/src/Components/FormElements/ColorInput/ColorInput.d.ts +3 -3
- package/dist/src/Components/FormElements/ColorInput/sharedSelectedColor.d.ts +1 -1
- package/dist/src/Components/FormElements/Controller/useYupResolver.d.ts +11 -0
- package/dist/src/Components/FormElements/SearchSelectInput/SearchSelectInput.d.ts +8 -1
- package/dist/src/Components/FormElements/Slider/Slider.d.ts +2 -1
- package/dist/src/Components/FormElements/Switch/Switch.d.ts +4 -1
- package/dist/src/Components/SpoilerList/Spoiler/Spoiler.d.ts +2 -1
- package/package.json +4 -3
- package/src/Components/Clickable/Clickable.tsx +1 -1
- package/src/Components/Dialog/ButtonDialog.tsx +0 -2
- package/src/Components/Dialog/DialogBackground.tsx +1 -1
- package/src/Components/Dialog/DialogContext.ts +1 -1
- package/src/Components/Dialog/dialogBackground.scss +1 -0
- package/src/Components/FormElements/Button/Button.tsx +11 -3
- package/src/Components/FormElements/ColorInput/ColorInput.tsx +22 -37
- package/src/Components/FormElements/ColorInput/colorInput.scss +39 -0
- package/src/Components/FormElements/ColorInput/sharedSelectedColor.ts +33 -4
- package/src/Components/FormElements/Controller/FileInputController.tsx +2 -2
- package/src/Components/FormElements/Controller/HookForm.tsx +1 -1
- package/src/Components/FormElements/Controller/useYupResolver.ts +53 -0
- package/src/Components/FormElements/FormError.tsx +1 -1
- package/src/Components/FormElements/Input/FileInput/MultipleFileInput.tsx +0 -1
- package/src/Components/FormElements/SearchSelectInput/SearchSelectInput.tsx +161 -129
- package/src/Components/FormElements/SearchSelectInput/seachSelectInput.scss +6 -1
- package/src/Components/FormElements/Select/Select.tsx +1 -1
- package/src/Components/FormElements/Slider/Slider.tsx +9 -1
- package/src/Components/FormElements/Switch/Switch.tsx +26 -14
- package/src/Components/FormElements/Switch/switch.scss +18 -16
- package/src/Components/FullScreen/FullScreen.tsx +5 -7
- package/src/Components/Hooks/useComposedRef.ts +1 -1
- package/src/Components/Hooks/useDelayedEffect.ts +4 -3
- package/src/Components/Hooks/useRerender.ts +1 -1
- package/src/Components/Icon/Icon.tsx +0 -1
- package/src/Components/List/InfiniteList.tsx +3 -4
- package/src/Components/List/List.tsx +0 -2
- package/src/Components/SpoilerList/Spoiler/Spoiler.tsx +24 -18
- package/src/scss/_default.scss +14 -12
|
@@ -2,7 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import { OptionalListener } from '../../Hooks/useListener';
|
|
3
3
|
import { SelectOption } from '../Select/Select';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
|
-
import { ChangeEventHandler, KeyboardEvent, useCallback, useMemo, useRef, useState } from 'react';
|
|
5
|
+
import { ChangeEventHandler, KeyboardEvent, ReactNode, useCallback, useMemo, useRef, useState } from 'react';
|
|
6
6
|
import { ArrayHelper } from '@ainias42/js-helper';
|
|
7
7
|
import { RbmComponentProps } from '../../RbmComponentProps';
|
|
8
8
|
import { withMemo } from '../../../helper/withMemo';
|
|
@@ -22,147 +22,179 @@ export type SearchSelectInputProps<OnChangeData> = RbmComponentProps<
|
|
|
22
22
|
options: SelectOption[];
|
|
23
23
|
onChangeValue?: (newValues: string[]) => void;
|
|
24
24
|
values: string[];
|
|
25
|
+
renderSelectableOptions?: (option: SelectOption, isActive: boolean, index: number, activeIndex: number) => ReactNode,
|
|
26
|
+
renderSelectedOption?: (option: SelectOption) => ReactNode,
|
|
27
|
+
showSelectedOptions?: boolean;
|
|
28
|
+
closeOnSelect?: boolean;
|
|
29
|
+
enableSearch?: boolean;
|
|
30
|
+
allowDeselect?: boolean;
|
|
25
31
|
} & OptionalListener<'onChange', OnChangeData>
|
|
26
32
|
>;
|
|
27
33
|
|
|
28
34
|
export const SearchSelectInput = withMemo(function SearchSelectInput<OnChangeData>({
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
setSelectedIndex(0);
|
|
74
|
-
}, []);
|
|
75
|
-
const onFocus = useCallback(() => updateSuggestionPosition(), [updateSuggestionPosition]);
|
|
76
|
-
|
|
77
|
-
const toggleOption = useCallback(
|
|
78
|
-
(_: any, value: string) => {
|
|
79
|
-
const newValues = [...values];
|
|
80
|
-
const index = values.indexOf(value);
|
|
81
|
-
if (index === -1) {
|
|
82
|
-
newValues.push(value);
|
|
83
|
-
} else {
|
|
84
|
-
newValues.splice(index, 1);
|
|
35
|
+
label,
|
|
36
|
+
options,
|
|
37
|
+
values,
|
|
38
|
+
onChangeValue,
|
|
39
|
+
className,
|
|
40
|
+
renderSelectableOptions,
|
|
41
|
+
renderSelectedOption,
|
|
42
|
+
showSelectedOptions = false,
|
|
43
|
+
closeOnSelect = false,
|
|
44
|
+
enableSearch = true,
|
|
45
|
+
allowDeselect = true,
|
|
46
|
+
style,
|
|
47
|
+
}: SearchSelectInputProps<OnChangeData>) {
|
|
48
|
+
// Variables
|
|
49
|
+
const indexedOptions = useMemo(() => ArrayHelper.arrayToObject(options, (opt) => opt.value), [options]);
|
|
50
|
+
|
|
51
|
+
// Refs
|
|
52
|
+
const containerRef = useRef<HTMLLabelElement>(null);
|
|
53
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
54
|
+
const window = useWindow();
|
|
55
|
+
|
|
56
|
+
// States
|
|
57
|
+
const [searchText, setSearchText] = useState('');
|
|
58
|
+
const [suggestionsPosition, setSuggestionsPosition] = useState<
|
|
59
|
+
{ top: number; left: number; right: number } | undefined
|
|
60
|
+
>(undefined);
|
|
61
|
+
|
|
62
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
63
|
+
|
|
64
|
+
const selectableOptions = useMemo(() => {
|
|
65
|
+
if (!suggestionsPosition) {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
return options.filter(
|
|
69
|
+
(option) => (showSelectedOptions || !values.includes(option.value)) && (!enableSearch || option.label.toLowerCase().includes(searchText.toLowerCase()))
|
|
70
|
+
);
|
|
71
|
+
}, [suggestionsPosition, options, showSelectedOptions, values, enableSearch, searchText]);
|
|
72
|
+
|
|
73
|
+
// Selectors
|
|
74
|
+
|
|
75
|
+
// Callbacks
|
|
76
|
+
const updateSuggestionPosition = useCallback(() => {
|
|
77
|
+
if (!containerRef.current) {
|
|
78
|
+
return;
|
|
85
79
|
}
|
|
86
|
-
|
|
80
|
+
const {left, right, bottom: top} = containerRef.current.getBoundingClientRect();
|
|
81
|
+
setSuggestionsPosition({top, left, right: (window?.innerWidth ?? 0) - right});
|
|
82
|
+
}, [window?.innerWidth]);
|
|
83
|
+
|
|
84
|
+
const onChange = useCallback<ChangeEventHandler<HTMLInputElement>>((ev) => {
|
|
85
|
+
if (!enableSearch){
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
setSearchText(ev.target.value);
|
|
87
89
|
setSelectedIndex(0);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
toggleOption(undefined, selectableOptions[selectedIndex].value);
|
|
90
|
+
}, [enableSearch]);
|
|
91
|
+
const onFocus = useCallback(() => updateSuggestionPosition(), [updateSuggestionPosition]);
|
|
92
|
+
|
|
93
|
+
const toggleOption = useCallback(
|
|
94
|
+
(_: any, value: string) => {
|
|
95
|
+
const newValues = [...values];
|
|
96
|
+
const index = values.indexOf(value);
|
|
97
|
+
if (index === -1) {
|
|
98
|
+
newValues.push(value);
|
|
99
|
+
} else {
|
|
100
|
+
newValues.splice(index, 1);
|
|
100
101
|
}
|
|
101
|
-
|
|
102
|
-
setSelectedIndex(
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
setSearchText('');
|
|
103
|
+
setSelectedIndex(0);
|
|
104
|
+
onChangeValue?.(newValues);
|
|
105
|
+
if (closeOnSelect) {
|
|
106
|
+
if (containerRef.current?.contains(document.activeElement)) {
|
|
107
|
+
inputRef.current?.focus();
|
|
108
|
+
requestAnimationFrame(() => {
|
|
109
|
+
inputRef.current?.blur();
|
|
110
|
+
});
|
|
105
111
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
[closeOnSelect, onChangeValue, values]
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
const onKeyPress = useCallback(
|
|
118
|
+
(e: KeyboardEvent<HTMLInputElement>) => {
|
|
119
|
+
if (e.key === 'Enter' && !e.defaultPrevented) {
|
|
120
|
+
if (selectedIndex < selectableOptions.length) {
|
|
121
|
+
toggleOption(undefined, selectableOptions[selectedIndex].value);
|
|
112
122
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
123
|
+
} else if (e.key === 'ArrowDown') {
|
|
124
|
+
setSelectedIndex((old) => {
|
|
125
|
+
if (old + 1 >= selectableOptions.length) {
|
|
126
|
+
return 0;
|
|
127
|
+
}
|
|
128
|
+
return old + 1;
|
|
129
|
+
});
|
|
130
|
+
} else if (e.key === 'ArrowUp') {
|
|
131
|
+
setSelectedIndex((old) => {
|
|
132
|
+
if (old - 1 < 0) {
|
|
133
|
+
return Math.max(selectableOptions.length - 1, 0);
|
|
134
|
+
}
|
|
135
|
+
return old - 1;
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
[toggleOption, selectableOptions, selectedIndex]
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
// Effects
|
|
119
143
|
|
|
120
|
-
|
|
144
|
+
// Other
|
|
121
145
|
|
|
122
|
-
|
|
146
|
+
// Render Functions
|
|
147
|
+
const renderOption = (value: string) => {
|
|
148
|
+
const option = indexedOptions[value];
|
|
149
|
+
if (!option) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
123
152
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
153
|
+
const element = renderSelectedOption?.(option) ?? <InlineBlock className={styles.tag}>
|
|
154
|
+
<Text size={TEXT_SIZE.xSmall}>{indexedOptions[value]?.label}</Text>
|
|
155
|
+
</InlineBlock>;
|
|
156
|
+
|
|
157
|
+
const onClickProps = allowDeselect ? {onClick: toggleOption, onClickData: value} : {};
|
|
158
|
+
|
|
159
|
+
return (
|
|
160
|
+
<Clickable {...onClickProps} key={option.key} __allowChildren="all">
|
|
161
|
+
{element}
|
|
162
|
+
</Clickable>
|
|
163
|
+
);
|
|
164
|
+
};
|
|
165
|
+
const renderSelectableOption = (opt: SelectOption, index: number) => {
|
|
166
|
+
const isActive = index === selectedIndex;
|
|
167
|
+
const element = renderSelectableOptions?.(opt, isActive, index, selectedIndex) ?? (
|
|
168
|
+
<Block className={classNames(styles.selectableOption, {[styles.active]: index === selectedIndex})}>
|
|
169
|
+
<Text>{opt.label}</Text>
|
|
170
|
+
</Block>);
|
|
171
|
+
|
|
172
|
+
return <Clickable onClick={toggleOption} onClickData={opt.value} key={opt.key} __allowChildren="all">
|
|
173
|
+
{element}
|
|
174
|
+
</Clickable>;
|
|
175
|
+
};
|
|
129
176
|
|
|
130
177
|
return (
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
178
|
+
// eslint-disable-next-line jsx-a11y/label-has-associated-control
|
|
179
|
+
<label className={classNames(styles.input, className)} style={style} ref={containerRef}>
|
|
180
|
+
{label ? <span className={styles.label}>{label}</span> : null}
|
|
181
|
+
<Flex className={styles.inputContainer} horizontal={true}>
|
|
182
|
+
<InlineBlock>{values.map(renderOption)}</InlineBlock>
|
|
183
|
+
<Grow __allowChildren="html">
|
|
184
|
+
<input
|
|
185
|
+
ref={inputRef}
|
|
186
|
+
className={classNames(styles.text, {[styles.disabled]: !enableSearch})}
|
|
187
|
+
value={searchText}
|
|
188
|
+
onChange={onChange}
|
|
189
|
+
onKeyDown={onKeyPress}
|
|
190
|
+
onFocus={onFocus}
|
|
191
|
+
/>
|
|
192
|
+
</Grow>
|
|
193
|
+
</Flex>
|
|
194
|
+
<InlineBlock className={styles.selectableOptionContainer} style={suggestionsPosition}>
|
|
195
|
+
{selectableOptions.map(renderSelectableOption)}
|
|
134
196
|
</InlineBlock>
|
|
135
|
-
</
|
|
197
|
+
</label>
|
|
136
198
|
);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
<Clickable onClick={toggleOption} onClickData={opt.value} key={opt.key}>
|
|
140
|
-
<Block className={classNames(styles.selectableOption, { [styles.active]: index === selectedIndex })}>
|
|
141
|
-
<Text>{opt.label}</Text>
|
|
142
|
-
</Block>
|
|
143
|
-
</Clickable>
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
return (
|
|
147
|
-
// eslint-disable-next-line jsx-a11y/label-has-associated-control
|
|
148
|
-
<label className={classNames(styles.input, className)} style={style} ref={containerRef}>
|
|
149
|
-
{label ? <span className={styles.label}>{label}</span> : null}
|
|
150
|
-
<Flex className={styles.inputContainer} horizontal={true}>
|
|
151
|
-
<InlineBlock>{values.map(renderOption)}</InlineBlock>
|
|
152
|
-
<Grow __allowChildren="html">
|
|
153
|
-
<input
|
|
154
|
-
className={styles.text}
|
|
155
|
-
value={searchText}
|
|
156
|
-
onChange={onChange}
|
|
157
|
-
onKeyDown={onKeyPress}
|
|
158
|
-
onFocus={onFocus}
|
|
159
|
-
/>
|
|
160
|
-
</Grow>
|
|
161
|
-
</Flex>
|
|
162
|
-
<InlineBlock className={styles.selectableOptionContainer} style={suggestionsPosition}>
|
|
163
|
-
{selectableOptions.map(renderSelectableOption)}
|
|
164
|
-
</InlineBlock>
|
|
165
|
-
</label>
|
|
166
|
-
);
|
|
167
|
-
},
|
|
168
|
-
styles);
|
|
199
|
+
},
|
|
200
|
+
styles);
|
|
@@ -34,10 +34,15 @@
|
|
|
34
34
|
|
|
35
35
|
.label {
|
|
36
36
|
display: block;
|
|
37
|
-
font-weight: bold;
|
|
37
|
+
font-weight: var(--label-font-weight, bold);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
.text {
|
|
41
|
+
&.disabled {
|
|
42
|
+
caret-color: transparent;
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
}
|
|
45
|
+
|
|
41
46
|
width: 100%;
|
|
42
47
|
background-color: transparent;
|
|
43
48
|
border: 0;
|
|
@@ -14,6 +14,7 @@ export type SliderProps<OnChangeData, OnChangeValueData, OnChangeDoneData> = Rbm
|
|
|
14
14
|
Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>,
|
|
15
15
|
{
|
|
16
16
|
value?: number;
|
|
17
|
+
stopPropagation?: boolean;
|
|
17
18
|
} & OptionalListener<'onChange', OnChangeData> &
|
|
18
19
|
OptionalListener<'onChangeValue', OnChangeValueData, number> &
|
|
19
20
|
OptionalListener<'onChangeDone', OnChangeDoneData>
|
|
@@ -23,6 +24,7 @@ export type SliderProps<OnChangeData, OnChangeValueData, OnChangeDoneData> = Rbm
|
|
|
23
24
|
export const Slider = withMemo(function Slider<OnChangeData, OnChangeValueData, OnChangeDoneData>({
|
|
24
25
|
className,
|
|
25
26
|
style,
|
|
27
|
+
stopPropagation = true,
|
|
26
28
|
...props
|
|
27
29
|
}: SliderProps<OnChangeData, OnChangeValueData, OnChangeDoneData>) {
|
|
28
30
|
// Variables
|
|
@@ -57,6 +59,12 @@ export const Slider = withMemo(function Slider<OnChangeData, OnChangeValueData,
|
|
|
57
59
|
[onChange, onChangeValue]
|
|
58
60
|
);
|
|
59
61
|
|
|
62
|
+
const checkStopPropagation = useCallback((ev: React.MouseEvent) => {
|
|
63
|
+
if (stopPropagation) {
|
|
64
|
+
ev.stopPropagation();
|
|
65
|
+
}
|
|
66
|
+
}, [stopPropagation]);
|
|
67
|
+
|
|
60
68
|
// Effects
|
|
61
69
|
const innerRef = useOnChangeDone(onChangeDone) as MutableRefObject<HTMLInputElement|null>;
|
|
62
70
|
|
|
@@ -66,7 +74,7 @@ export const Slider = withMemo(function Slider<OnChangeData, OnChangeValueData,
|
|
|
66
74
|
|
|
67
75
|
return (
|
|
68
76
|
// eslint-disable-next-line jsx-a11y/label-has-associated-control
|
|
69
|
-
<label className={classNames(styles.slider, className)} style={style}>
|
|
77
|
+
<label className={classNames(styles.slider, className)} style={style} onClick={checkStopPropagation}>
|
|
70
78
|
<input
|
|
71
79
|
type="range"
|
|
72
80
|
{...otherPropsWithoutData}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { ChangeEventHandler, InputHTMLAttributes, useCallback } from 'react';
|
|
2
|
+
import { ChangeEventHandler, InputHTMLAttributes, MouseEvent, useCallback } from 'react';
|
|
3
3
|
import { RbmComponentProps } from '../../RbmComponentProps';
|
|
4
4
|
import { Override } from '../../../TypeHelpers';
|
|
5
5
|
import classNames from 'classnames';
|
|
6
|
-
|
|
7
6
|
import styles from './switch.scss';
|
|
8
7
|
import { withMemo } from '../../../helper/withMemo';
|
|
9
8
|
import { OptionalListener, useListenerWithExtractedProps } from "../../Hooks/useListener";
|
|
@@ -19,6 +18,9 @@ export type SwitchProps<OnChangeCheckedData> = RbmComponentProps<
|
|
|
19
18
|
isLabelBeforeSwitch?: boolean;
|
|
20
19
|
isDual?: boolean;
|
|
21
20
|
error?: string;
|
|
21
|
+
classNameLabel?: string;
|
|
22
|
+
classNamePreLabel?: string;
|
|
23
|
+
stopPropagation?: boolean;
|
|
22
24
|
} & OptionalListener<"onChangeChecked", OnChangeCheckedData, boolean>
|
|
23
25
|
>
|
|
24
26
|
>;
|
|
@@ -29,8 +31,11 @@ export const Switch = withMemo(function Switch<OnChangeCheckedData>({
|
|
|
29
31
|
preLabel = '',
|
|
30
32
|
isLabelBeforeSwitch = false,
|
|
31
33
|
isDual = undefined,
|
|
34
|
+
stopPropagation = true,
|
|
32
35
|
id,
|
|
33
36
|
className,
|
|
37
|
+
classNamePreLabel,
|
|
38
|
+
classNameLabel,
|
|
34
39
|
style,
|
|
35
40
|
error,
|
|
36
41
|
onChange,
|
|
@@ -53,6 +58,14 @@ export const Switch = withMemo(function Switch<OnChangeCheckedData>({
|
|
|
53
58
|
[onChange, onChangeChecked]
|
|
54
59
|
);
|
|
55
60
|
|
|
61
|
+
const checkStopPropagation = useCallback((ev: MouseEvent) => {
|
|
62
|
+
if (stopPropagation) {
|
|
63
|
+
console.log("LOG-d stopPropagation inside checkStopPropagation", ev);
|
|
64
|
+
ev.stopPropagation();
|
|
65
|
+
ev.nativeEvent.stopPropagation();
|
|
66
|
+
}
|
|
67
|
+
}, [stopPropagation]);
|
|
68
|
+
|
|
56
69
|
// Effects
|
|
57
70
|
|
|
58
71
|
// Other
|
|
@@ -71,17 +84,16 @@ export const Switch = withMemo(function Switch<OnChangeCheckedData>({
|
|
|
71
84
|
isDual = true;
|
|
72
85
|
}
|
|
73
86
|
return (
|
|
74
|
-
<span className={classNames(styles.switch, {[styles.dual]: isDual}, className)} style={style}>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
);
|
|
87
|
+
<span className={classNames(styles.switch, {[styles.dual]: isDual}, className)} style={style} onClick={checkStopPropagation}>
|
|
88
|
+
<label htmlFor={id} key={id}>
|
|
89
|
+
<span className={classNames(styles.label, classNamePreLabel)}>{preLabel}</span>
|
|
90
|
+
<input {...otherProps} type="checkbox" id={id} onChange={realOnChange}/>
|
|
91
|
+
<div className={styles.toggle}>
|
|
92
|
+
<span className={styles.handle}/>
|
|
93
|
+
</div>
|
|
94
|
+
<span className={classNames(styles.label, classNameLabel)}>{label}</span>
|
|
95
|
+
<FormError error={error}/>
|
|
96
|
+
</label>
|
|
97
|
+
</span>);
|
|
86
98
|
},
|
|
87
99
|
styles);
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
.toggle {
|
|
27
|
+
flex-shrink: 0;
|
|
27
28
|
width: 40px;
|
|
28
29
|
display: inline-block;
|
|
29
30
|
position: relative;
|
|
@@ -33,6 +34,7 @@
|
|
|
33
34
|
border-radius: 30px;
|
|
34
35
|
|
|
35
36
|
.handle {
|
|
37
|
+
left: var(--switch-handle-offset, 0);
|
|
36
38
|
transition-property: all;
|
|
37
39
|
transition-duration: 0.35s;
|
|
38
40
|
transition-timing-function: cubic-bezier(.59, .01, .5, .99);
|
|
@@ -60,14 +62,14 @@
|
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
@include design($material) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
//box-shadow: none;
|
|
65
|
+
--switch-handle-checked-offset: 18px;
|
|
66
|
+
--switch-handle-offset: 0px;
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
input:checked + .toggle {
|
|
69
|
+
--switch-handle-offset: var(--switch-handle-checked-offset);
|
|
70
|
+
|
|
71
|
+
.handle {
|
|
72
|
+
@extend %dual-handle-material;
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
75
|
|
|
@@ -82,7 +84,6 @@
|
|
|
82
84
|
width: 22px;
|
|
83
85
|
height: 22px;
|
|
84
86
|
background-color: #f1f1f1;
|
|
85
|
-
left: 0;
|
|
86
87
|
box-shadow: 0 4px 5px 0 rgb(0 0 0 / 14%), 0 1px 10px 0 rgb(0 0 0 / 12%), 0 2px 4px -1px rgb(0 0 0 / 40%);
|
|
87
88
|
|
|
88
89
|
&:before {
|
|
@@ -101,15 +102,17 @@
|
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
@include design($flat) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
@extend %dual-toggle-flat;
|
|
105
|
+
--switch-handle-offset: 2px;
|
|
106
|
+
--switch-handle-checked-offset: 19px;
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
input:checked + .toggle {
|
|
109
|
+
@extend %dual-toggle-flat;
|
|
110
|
+
--switch-handle-offset: var(--switch-handle-checked-offset);
|
|
111
|
+
|
|
112
|
+
.handle {
|
|
113
|
+
@extend %dual-handle-flat;
|
|
112
114
|
}
|
|
115
|
+
|
|
113
116
|
}
|
|
114
117
|
|
|
115
118
|
.toggle {
|
|
@@ -122,7 +125,6 @@
|
|
|
122
125
|
height: 19px;
|
|
123
126
|
width: 19px;
|
|
124
127
|
background-color: #ffffff;
|
|
125
|
-
left: 2px;
|
|
126
128
|
top: 2px;
|
|
127
129
|
box-shadow: 0 0 1px 0 rgb(0 0 0 / 25%), 0 3px 2px rgb(0 0 0 / 25%);
|
|
128
130
|
}
|
|
@@ -53,7 +53,7 @@ export const FullScreen = withMemo(function FullScreen<AsTag extends keyof JSX.I
|
|
|
53
53
|
} else {
|
|
54
54
|
containerRef.current?.requestFullscreen();
|
|
55
55
|
}
|
|
56
|
-
}, [
|
|
56
|
+
}, []);
|
|
57
57
|
|
|
58
58
|
// Effects
|
|
59
59
|
useEffect(() => {
|
|
@@ -71,28 +71,26 @@ export const FullScreen = withMemo(function FullScreen<AsTag extends keyof JSX.I
|
|
|
71
71
|
|
|
72
72
|
useEffect(() => {
|
|
73
73
|
if (!containerRef.current) {
|
|
74
|
-
return;
|
|
74
|
+
return undefined;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
const container = containerRef.current;
|
|
78
78
|
const listener = () => {
|
|
79
|
-
// @ts-
|
|
79
|
+
// @ts-expect-error the typing is not completely correct
|
|
80
80
|
const fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement;
|
|
81
81
|
if (fullscreenElement === container) {
|
|
82
|
-
console.log("LOG-d enter fullscreen")
|
|
83
82
|
onEnterFullscreen?.();
|
|
84
83
|
} else {
|
|
85
|
-
console.log("LOG-d leave fullscreen")
|
|
86
84
|
onLeaveFullscreen?.();
|
|
87
85
|
}
|
|
88
|
-
}
|
|
86
|
+
};
|
|
89
87
|
container.addEventListener('fullscreenchange', listener);
|
|
90
88
|
container.addEventListener('webkitfullscreenchange', listener);
|
|
91
89
|
|
|
92
90
|
return () => {
|
|
93
91
|
container.removeEventListener('fullscreenchange', listener);
|
|
94
92
|
container.removeEventListener('webkitfullscreenchange', listener);
|
|
95
|
-
}
|
|
93
|
+
};
|
|
96
94
|
}, [onEnterFullscreen, onLeaveFullscreen]);
|
|
97
95
|
|
|
98
96
|
// Other
|
|
@@ -3,12 +3,13 @@ import { useEffect } from "react";
|
|
|
3
3
|
export function useDelayedEffect(effect: () => void|(() => void), dependencies: any[], delay = 100){
|
|
4
4
|
useEffect(() => {
|
|
5
5
|
let cleanup: (() => void)|void | undefined;
|
|
6
|
-
|
|
6
|
+
const timeout = setTimeout(() => {
|
|
7
7
|
cleanup = effect();
|
|
8
8
|
}, delay);
|
|
9
9
|
return () => {
|
|
10
10
|
clearTimeout(timeout);
|
|
11
|
-
cleanup?.()
|
|
11
|
+
cleanup?.();
|
|
12
12
|
};
|
|
13
|
-
|
|
13
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
14
|
+
}, [delay, ...dependencies]);
|
|
14
15
|
}
|
|
@@ -6,7 +6,6 @@ import {IconProp} from '@fortawesome/fontawesome-svg-core';
|
|
|
6
6
|
import {withMemo} from '../../helper/withMemo';
|
|
7
7
|
import {IconDefinition} from '@fortawesome/free-regular-svg-icons';
|
|
8
8
|
import classNames from "classnames";
|
|
9
|
-
|
|
10
9
|
import styles from "./icon.scss";
|
|
11
10
|
|
|
12
11
|
export type IconSource = IconProp | string | IconDefinition;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useCallback, useState } from 'react';
|
|
2
2
|
import InfiniteLoader from "react-window-infinite-loader";
|
|
3
|
-
import { RbmComponentProps } from "../RbmComponentProps";
|
|
4
3
|
import { List, ListProps } from "./List";
|
|
5
4
|
import { withMemo } from "../../helper/withMemo";
|
|
6
5
|
|
|
@@ -34,12 +33,12 @@ export const InfiniteList = withMemo(function InfiniteList<ItemType>({
|
|
|
34
33
|
if (!isPageLoading) {
|
|
35
34
|
setIsPageLoading(true);
|
|
36
35
|
try {
|
|
37
|
-
loadNextPage()
|
|
36
|
+
loadNextPage();
|
|
38
37
|
} finally {
|
|
39
38
|
setIsPageLoading(false);
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
|
-
}, [isPageLoading, loadNextPage])
|
|
41
|
+
}, [isPageLoading, loadNextPage]);
|
|
43
42
|
|
|
44
43
|
// Effects
|
|
45
44
|
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { ComponentType, CSSProperties, ForwardedRef, ReactElement, ReactNode, useCallback, useState } from 'react';
|
|
3
3
|
import { RbmComponentProps } from '../RbmComponentProps';
|
|
4
|
-
|
|
5
4
|
import styles from './list.scss';
|
|
6
|
-
import { withMemo } from '../../helper/withMemo';
|
|
7
5
|
import { FixedSizeList, FixedSizeListProps, ListChildComponentProps } from 'react-window';
|
|
8
6
|
import AutoSizer from 'react-virtualized-auto-sizer';
|
|
9
7
|
import { SizeCalculator, SizeCalculatorProps } from '../SizeCalculator/SizeCalculator';
|