@ainias42/react-bootstrap-mobile 0.2.4 → 0.2.6

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.
Files changed (31) hide show
  1. package/bin/updateCopies.js +1 -1
  2. package/bootstrapReactMobile.ts +4 -0
  3. package/dist/bootstrapReactMobile.d.ts +4 -0
  4. package/dist/bootstrapReactMobile.js +751 -589
  5. package/dist/bootstrapReactMobile.js.map +1 -1
  6. package/dist/src/Components/FormElements/CheckBox/Checkbox.d.ts +2 -1
  7. package/dist/src/Components/FormElements/ColorInput/ColorInput.d.ts +2 -1
  8. package/dist/src/Components/FormElements/Controller/ColorInputController.d.ts +3 -0
  9. package/dist/src/Components/FormElements/Controller/FileInputController.d.ts +8 -0
  10. package/dist/src/Components/FormElements/FormError.d.ts +5 -0
  11. package/dist/src/Components/FormElements/Input/FileInput/FileInput.d.ts +1 -1
  12. package/dist/src/Components/FormElements/Input/FileInput/FileType.d.ts +2 -2
  13. package/dist/src/Components/FormElements/Switch/Switch.d.ts +2 -1
  14. package/dist/src/Components/Hooks/useDelayedEffect.d.ts +1 -0
  15. package/package.json +1 -1
  16. package/src/Components/Card/card.scss +2 -2
  17. package/src/Components/FormElements/CheckBox/Checkbox.tsx +4 -0
  18. package/src/Components/FormElements/ColorInput/ColorInput.tsx +15 -10
  19. package/src/Components/FormElements/Controller/ColorInputController.ts +4 -0
  20. package/src/Components/FormElements/Controller/FileInputController.tsx +42 -0
  21. package/src/Components/FormElements/Controller/MultipleFileInputController.ts +1 -0
  22. package/src/Components/FormElements/Controller/withHookController.tsx +6 -4
  23. package/src/Components/FormElements/FormError.tsx +29 -0
  24. package/src/Components/FormElements/Input/FileInput/FileInput.tsx +3 -2
  25. package/src/Components/FormElements/Input/FileInput/FileType.ts +1 -1
  26. package/src/Components/FormElements/Input/FileInput/MultipleFileInput.tsx +13 -9
  27. package/src/Components/FormElements/Input/Input.tsx +2 -4
  28. package/src/Components/FormElements/Input/input.scss +2 -2
  29. package/src/Components/FormElements/Switch/Switch.tsx +47 -43
  30. package/src/Components/FormElements/formError.scss +4 -0
  31. package/src/Components/Hooks/useDelayedEffect.ts +14 -0
@@ -7,7 +7,8 @@ export type CheckboxProps<OnChangeData, OnChangeCheckedData> = RbmComponentProps
7
7
  label?: string;
8
8
  children?: string;
9
9
  isLabelBeforeCheckbox?: boolean;
10
+ error?: string;
10
11
  } & OptionalListener<'onChange', OnChangeData> & OptionalListener<'onChangeChecked', OnChangeCheckedData, boolean>>>;
11
- declare function Checkbox<OnChangeData, OnChangeCheckedData>({ children, label, isLabelBeforeCheckbox, id, className, style, ...props }: CheckboxProps<OnChangeData, OnChangeCheckedData>): React.JSX.Element;
12
+ declare function Checkbox<OnChangeData, OnChangeCheckedData>({ children, label, isLabelBeforeCheckbox, id, className, error, style, ...props }: CheckboxProps<OnChangeData, OnChangeCheckedData>): React.JSX.Element;
12
13
  declare const tmp: typeof Checkbox;
13
14
  export { tmp as Checkbox };
@@ -12,7 +12,8 @@ export type ColorInputProps<OnChangeData> = {
12
12
  presetColors?: string[];
13
13
  sharedColorKey?: string;
14
14
  disabled?: boolean;
15
+ error?: string;
15
16
  } & OptionalListener<'onChange', OnChangeData>;
16
- declare function ColorInput<OnChangeData>({ defaultValue, value, label, onChangeColor, onChangeColorComplete, onOpen, onClose, disableAlpha, presetColors, sharedColorKey, disabled, ...otherProps }: ColorInputProps<OnChangeData>): React.JSX.Element;
17
+ declare function ColorInput<OnChangeData>({ defaultValue, value, label, onChangeColor, onChangeColorComplete, onOpen, onClose, disableAlpha, presetColors, error, sharedColorKey, disabled, ...otherProps }: ColorInputProps<OnChangeData>): React.JSX.Element;
17
18
  declare const ColorInputMemo: typeof ColorInput;
18
19
  export { ColorInputMemo as ColorInput };
@@ -0,0 +1,3 @@
1
+ export declare const ColorInputController: import("../../../helper/withForwardRef").RefComponent<Omit<import("../ColorInput/ColorInput").ColorInputProps<unknown>, "value" | "ref" | "onBlur" | "name" | "onChangeColor"> & {
2
+ name: string;
3
+ }, never>;
@@ -0,0 +1,8 @@
1
+ import { FileInputProps } from "../Input/FileInput/FileInput";
2
+ import React from "react";
3
+ import { FieldPath, FieldValues } from "react-hook-form";
4
+ type Props<Values extends FieldValues, Name extends FieldPath<Values> = FieldPath<Values>> = Omit<FileInputProps<unknown>, 'name' | 'onBlur' | 'ref' | 'value' | "__allowChildren" | "children" | "onChangeFile" | "error"> & {
5
+ name: Name;
6
+ };
7
+ export declare const FileInputController: <Values extends FieldValues, Name extends FieldPath<Values> = FieldPath<Values>>({ name, ...otherProps }: Props<Values, Name>) => React.JSX.Element;
8
+ export {};
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ export type FormErrorProps = {
3
+ error?: string;
4
+ };
5
+ export declare const FormError: ({ error }: FormErrorProps) => React.JSX.Element | null;
@@ -6,7 +6,7 @@ import { FileType } from "./FileType";
6
6
  import { MultipleFileInputProps } from "./MultipleFileInput";
7
7
  export type FileInputProps<OnChangeFileData> = RbmComponentProps<Override<Omit<MultipleFileInputProps<unknown>, "onChangeFiles" | "maxFiles" | "onChangeFilesData" | "mimeTypes" | "showDeleteButton">, {
8
8
  value?: FileType;
9
- mimeType?: string;
9
+ mimeType?: string | string[];
10
10
  required?: boolean;
11
11
  "data-test-id"?: string;
12
12
  } & Listener<'onChangeFile', OnChangeFileData, FileType | undefined>>>;
@@ -1,7 +1,7 @@
1
1
  export type FileType = {
2
2
  name: string;
3
- data: string;
4
- mimeType: string;
3
+ src: string;
4
+ type: string;
5
5
  uploaded?: boolean;
6
6
  blob?: Blob;
7
7
  };
@@ -9,5 +9,6 @@ export type SwitchProps<OnChangeCheckedData> = RbmComponentProps<Override<InputH
9
9
  children?: string;
10
10
  isLabelBeforeSwitch?: boolean;
11
11
  isDual?: boolean;
12
+ error?: string;
12
13
  } & OptionalListener<"onChangeChecked", OnChangeCheckedData, boolean>>>;
13
- export declare const Switch: <OnChangeCheckedData>({ children, label, preLabel, isLabelBeforeSwitch, isDual, id, className, style, onChange, ...props }: SwitchProps<OnChangeCheckedData>) => React.JSX.Element;
14
+ export declare const Switch: <OnChangeCheckedData>({ children, label, preLabel, isLabelBeforeSwitch, isDual, id, className, style, error, onChange, ...props }: SwitchProps<OnChangeCheckedData>) => React.JSX.Element;
@@ -0,0 +1 @@
1
+ export declare function useDelayedEffect(effect: () => (() => void | void), dependencies: any[], delay?: number): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainias42/react-bootstrap-mobile",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Mobile React Components using Bootstrap",
5
5
  "main": "dist/bootstrapReactMobile",
6
6
  "scripts": {
@@ -51,7 +51,7 @@ $marginCard: 8px;
51
51
 
52
52
  .content {
53
53
  color: #000000;
54
- color: rgba(0, 0, 0, 0.54);
54
+ color: var(--card-text-color, rgba(0, 0, 0, 0.54));
55
55
  }
56
56
 
57
57
  .title {
@@ -65,7 +65,7 @@ $marginCard: 8px;
65
65
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 12%);
66
66
 
67
67
  .content {
68
- color: #030303;
68
+ color: var(--card-text-color, #030303);
69
69
  }
70
70
 
71
71
  .title {
@@ -6,6 +6,7 @@ import { withMemo } from '../../../helper/withMemo';
6
6
  import classNames from 'classnames';
7
7
  import { Override } from '@ainias42/js-helper';
8
8
  import { OptionalListener, useListenerWithExtractedProps } from '../../Hooks/useListener';
9
+ import { FormError } from "../FormError";
9
10
 
10
11
  export type CheckboxProps<OnChangeData, OnChangeCheckedData> = RbmComponentProps<
11
12
  Override<
@@ -14,6 +15,7 @@ export type CheckboxProps<OnChangeData, OnChangeCheckedData> = RbmComponentProps
14
15
  label?: string;
15
16
  children?: string;
16
17
  isLabelBeforeCheckbox?: boolean;
18
+ error?: string;
17
19
  } & OptionalListener<'onChange', OnChangeData> &
18
20
  OptionalListener<'onChangeChecked', OnChangeCheckedData, boolean>
19
21
  >
@@ -25,6 +27,7 @@ function Checkbox<OnChangeData, OnChangeCheckedData>({
25
27
  isLabelBeforeCheckbox = false,
26
28
  id,
27
29
  className,
30
+ error,
28
31
  style,
29
32
  ...props
30
33
  }: CheckboxProps<OnChangeData, OnChangeCheckedData>) {
@@ -80,6 +83,7 @@ function Checkbox<OnChangeData, OnChangeCheckedData>({
80
83
  />
81
84
  <span className={styles.checkmark} />
82
85
  <span className={styles.label}>{label}</span>
86
+ <FormError error={error} />
83
87
  </label>
84
88
  </span>
85
89
  );
@@ -1,13 +1,13 @@
1
1
  import * as React from 'react';
2
- import {useCallback, useRef, useState, MouseEvent} from 'react';
3
- import {Color, ColorChangeHandler, ColorResult, SketchPicker} from 'react-color';
4
- import {OptionalListener, useListener} from '../../Hooks/useListener';
5
- import {withMemo} from '../../../helper/withMemo';
6
-
2
+ import { useCallback, useRef, useState, MouseEvent } from 'react';
3
+ import { Color, ColorChangeHandler, ColorResult, SketchPicker } from 'react-color';
4
+ import { OptionalListener, useListener } from '../../Hooks/useListener';
5
+ import { withMemo } from '../../../helper/withMemo';
7
6
  import styles from './colorInput.scss';
8
- import {useSharedSelectedColor} from './sharedSelectedColor';
9
- import {Menu} from "../../Menu/Menu";
7
+ import { useSharedSelectedColor } from './sharedSelectedColor';
8
+ import { Menu } from "../../Menu/Menu";
10
9
  import { useClientLayoutEffect } from "../../Hooks/useClientLayoutEffect";
10
+ import { FormError } from "../FormError";
11
11
 
12
12
  export type ColorInputProps<OnChangeData> = {
13
13
  defaultValue?: string;
@@ -21,6 +21,7 @@ export type ColorInputProps<OnChangeData> = {
21
21
  presetColors?: string[];
22
22
  sharedColorKey?: string;
23
23
  disabled?: boolean
24
+ error?: string;
24
25
  } & OptionalListener<'onChange', OnChangeData>;
25
26
 
26
27
  function convertToHex(color: { r: number; g: number; b: number; a?: number }, disableAlpha?: boolean) {
@@ -45,8 +46,9 @@ function ColorInput<OnChangeData>({
45
46
  onClose,
46
47
  disableAlpha,
47
48
  presetColors,
49
+ error,
48
50
  sharedColorKey = "default",
49
- disabled,
51
+ disabled,
50
52
  ...otherProps
51
53
  }: ColorInputProps<OnChangeData>) {
52
54
  // Variables
@@ -101,7 +103,7 @@ function ColorInput<OnChangeData>({
101
103
 
102
104
  const openElement = useCallback(
103
105
  (e: MouseEvent) => {
104
- if (disabled){
106
+ if (disabled) {
105
107
  return;
106
108
  }
107
109
 
@@ -133,6 +135,7 @@ function ColorInput<OnChangeData>({
133
135
 
134
136
  // Render Functions
135
137
  return (
138
+ <>
136
139
  <span className={styles.colorInput}>
137
140
  <Menu x={position.x} y={position.y} isOpen={realIsOpen} onClose={onMenuClose}>
138
141
  <SketchPicker
@@ -148,9 +151,11 @@ function ColorInput<OnChangeData>({
148
151
  </span>
149
152
  <span onClick={openElement} style={{backgroundColor: colVal}} className={styles.preview}/>
150
153
  </span>
154
+ <FormError error={error}/>
155
+ </>
151
156
  );
152
157
  }
153
158
 
154
159
  // Need ColorInputMemo for autocompletion of phpstorm
155
160
  const ColorInputMemo = withMemo(ColorInput, styles);
156
- export {ColorInputMemo as ColorInput};
161
+ export { ColorInputMemo as ColorInput };
@@ -0,0 +1,4 @@
1
+ import { withHookController } from "./withHookController";
2
+ import { ColorInput } from "../ColorInput/ColorInput";
3
+
4
+ export const ColorInputController = withHookController(ColorInput, "onChangeColor");
@@ -0,0 +1,42 @@
1
+ import { FileInput, FileInputProps } from "../Input/FileInput/FileInput";
2
+ import React, { useCallback } from "react";
3
+ import { FieldPath, FieldValues, useController, useFormContext, useFormState } from "react-hook-form";
4
+ import { FileType } from "../Input/FileInput/FileType";
5
+ import { withMemo } from "../../../helper/withMemo";
6
+
7
+
8
+ type Props<Values extends FieldValues, Name extends FieldPath<Values> = FieldPath<Values>> = Omit<
9
+ FileInputProps<unknown>,
10
+ 'name' | 'onBlur' | 'ref' | 'value' | "__allowChildren" | "children"|"onChangeFile"|"error"
11
+ > & { name: Name };
12
+
13
+ export const FileInputController = withMemo(function FileInputController<Values extends FieldValues, Name extends FieldPath<Values> = FieldPath<Values>>(
14
+ {name, ...otherProps}: Props<Values, Name>,
15
+ ) {
16
+ const {field, fieldState} = useController({name});
17
+ const {errors} = useFormState();
18
+
19
+ const {clearErrors} = useFormContext();
20
+ const errorMessage = fieldState.error?.message ?? errors[`${name}.src`]?.message as string|undefined ?? errors[`${name}.name`]?.message as string|undefined ?? errors[`${name}.type`]?.message as string|undefined;
21
+
22
+ const internalOnChange = useCallback(
23
+ (arg: FileType | undefined) => {
24
+ clearErrors(name);
25
+ clearErrors(`${name}.name`);
26
+ clearErrors(`${name}.src`);
27
+ clearErrors(`${name}.type`);
28
+ field.onChange(arg);
29
+ },
30
+ [clearErrors, field, name]
31
+ );
32
+
33
+ return (
34
+ <FileInput
35
+ {...otherProps}
36
+ {...field}
37
+ onChangeFile={internalOnChange}
38
+ value={field.value}
39
+ error={errorMessage}
40
+ />
41
+ );
42
+ });
@@ -1,4 +1,5 @@
1
1
  import { MultipleFileInput } from "../Input/FileInput/MultipleFileInput";
2
2
  import { withHookController } from "./withHookController";
3
3
 
4
+ // TODO Error handling(?)
4
5
  export const MultipleFileInputController = withHookController(MultipleFileInput, 'onChangeFiles');
@@ -25,20 +25,22 @@ export function withHookController<C extends ComponentType<any>, OnChangeProp ex
25
25
 
26
26
  const internalOnChange = useCallback(
27
27
  (arg: any) => {
28
- clearErrors(name);
29
- field.onChange(arg);
28
+ clearErrors(name);
29
+ field.onChange(arg);
30
30
  },
31
31
  [clearErrors, field, name]
32
32
  );
33
33
  const onChangeProps = {
34
34
  [onChangeProp]: internalOnChange
35
- }
35
+ };
36
36
 
37
37
  return (
38
38
  // @ts-expect-error Because of the prop spreading, typescript is really confused here
39
39
  <Comp
40
40
  {...otherProps}
41
- {...field}
41
+ name={field.name}
42
+ onBlur={field.onBlur}
43
+ disabled={field.disabled}
42
44
  {...onChangeProps}
43
45
  value={field.value ?? emptyValue}
44
46
  checked={field.value ?? emptyValue}
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { withMemo } from "../../helper/withMemo";
3
+ import styles from "./formError.scss";
4
+ import { Text } from "../Text/Text";
5
+ import { Block } from "../Layout/Block";
6
+
7
+ export type FormErrorProps = {error?: string};
8
+
9
+ export const FormError = withMemo(function FormError({error}: FormErrorProps) {
10
+ // Refs
11
+
12
+ // States/Variables/Selectors
13
+
14
+ // Dispatch
15
+
16
+ // Callbacks
17
+
18
+ // Effects
19
+
20
+ // Other
21
+
22
+ // RenderFunctions
23
+
24
+ if (!error){
25
+ return null;
26
+ }
27
+
28
+ return <Block className={styles.error}><Text>{error}</Text></Block>
29
+ }, styles);
@@ -13,7 +13,7 @@ export type FileInputProps<OnChangeFileData> = RbmComponentProps<
13
13
  Override<
14
14
  Omit<MultipleFileInputProps<unknown>, "onChangeFiles" | "maxFiles" | "onChangeFilesData" | "mimeTypes" | "showDeleteButton">, {
15
15
  value?: FileType,
16
- mimeType?: string,
16
+ mimeType?: string | string[],
17
17
  required?: boolean,
18
18
  "data-test-id"?: string;
19
19
  } & Listener<'onChangeFile', OnChangeFileData, FileType | undefined>>
@@ -30,7 +30,7 @@ export const FileInput = withMemo(function FileInput<OnChangeData>({
30
30
  // Refs
31
31
 
32
32
  // States
33
- const mimeTypes = useMemo(() => (mimeType ? [mimeType] : undefined), [mimeType]);
33
+ const mimeTypes = useMemo(() => (mimeType ? (Array.isArray(mimeType) ? mimeType : [mimeType]) : undefined), [mimeType]);
34
34
  const innerValue = useMemo(() => value ? [value] : [], [value]);
35
35
 
36
36
  // Selectors
@@ -39,6 +39,7 @@ export const FileInput = withMemo(function FileInput<OnChangeData>({
39
39
  const [onChangeFile, multipleFileInputProps] = useListenerWithExtractedProps<"onChangeFile", OnChangeData>("onChangeFile", otherProps);
40
40
  const onChangeFiles = useCallback((files: FileType[]) => {
41
41
  if (!required || files[0]) {
42
+ console.log("LOG-d onChangeFile", files[0]);
42
43
  onChangeFile(files[0]);
43
44
  }
44
45
  }, [onChangeFile, required]);
@@ -1 +1 @@
1
- export type FileType = { name: string; data: string; mimeType: string; uploaded?: boolean; blob?: Blob };
1
+ export type FileType = { name: string; src: string; type: string; uploaded?: boolean; blob?: Blob };
@@ -17,6 +17,7 @@ import { Clickable } from '../../../Clickable/Clickable';
17
17
  import { Inline } from '../../../Layout/Inline';
18
18
  import { FileType } from "./FileType";
19
19
  import { InlineBlock } from "../../../Layout/InlineBlock";
20
+ import { FormError } from "../../FormError";
20
21
 
21
22
 
22
23
  export type MultipleFileInputProps<OnChangeFilesData> = RbmComponentProps<
@@ -64,7 +65,6 @@ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeDa
64
65
 
65
66
  // Callbacks
66
67
 
67
-
68
68
  const checkMimeType = useCallback(
69
69
  (fileType: string) => {
70
70
  return mimeTypes.some((type) => {
@@ -116,8 +116,8 @@ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeDa
116
116
  const newUrls = await getBase64(newFiles);
117
117
  const newValue = newFiles.map((file, fileIndex) => ({
118
118
  name: file.name,
119
- data: newUrls[fileIndex],
120
- mimeType: file.type,
119
+ src: newUrls[fileIndex],
120
+ type: file.type,
121
121
  blob: file,
122
122
  }));
123
123
 
@@ -200,13 +200,13 @@ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeDa
200
200
 
201
201
  // Render Functions
202
202
  const renderFile = (file: FileType) => {
203
- if (file.mimeType.startsWith('image/')) {
203
+ if (file.type.startsWith('image/')) {
204
204
  return (
205
205
  <Image
206
- key={file.data}
207
- src={file.data}
206
+ key={file.src}
207
+ src={file.src}
208
208
  alt={file.name}
209
- className={classNames(styles.previewImage, file.data)}
209
+ className={classNames(styles.previewImage)}
210
210
  />
211
211
  );
212
212
  }
@@ -218,6 +218,10 @@ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeDa
218
218
  );
219
219
  };
220
220
 
221
+ if (error){
222
+ console.log("LOG-d error inside MultipleFileInput:", error);
223
+ }
224
+
221
225
  return (
222
226
  <span
223
227
  className={classNames(styles.fileInput, className)}
@@ -240,7 +244,7 @@ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeDa
240
244
  </Flex>
241
245
  <Flex horizontal={true} className={styles.previewContainer}>
242
246
  {value?.map((file, index) => {
243
- return <Grow className={styles.preview} center={true} key={file.data}>
247
+ return <Grow className={styles.preview} center={true} key={file.src}>
244
248
  <Clickable
245
249
  onDrop={onDrop}
246
250
  onDragOver={onDragOver}
@@ -282,7 +286,7 @@ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeDa
282
286
  </Clickable>
283
287
  </Grow>
284
288
  </Flex>
285
- {error && <InlineBlock className={styles.error}><Text>{error}</Text></InlineBlock>}
289
+ <FormError error={error}/>
286
290
  </span>
287
291
  );
288
292
  },
@@ -11,15 +11,13 @@ import { RbmComponentProps } from '../../RbmComponentProps';
11
11
  import { Override } from '../../../TypeHelpers';
12
12
  import { OptionalListener, useListenerWithExtractedProps } from '../../Hooks/useListener';
13
13
  import { withForwardRef } from '../../../helper/withForwardRef';
14
-
15
14
  import styles from './input.scss';
16
15
  import classNames from 'classnames';
17
16
  import { useComposedRef } from '../../Hooks/useComposedRef';
18
17
  import { useOnChangeDone } from '../hooks/useOnChangeDone';
19
- import { InlineBlock } from "../../Layout/InlineBlock";
20
- import { Text } from "../../Text/Text";
21
18
  import { useSendFormContext } from "../Controller/SendFormContext";
22
19
  import { useDebounced } from "../../Hooks/useDebounced";
20
+ import { FormError } from "../FormError";
23
21
 
24
22
  export type InputProps<OnChangeData, OnBlurData, OnChangeDoneData> = RbmComponentProps<
25
23
  Override<
@@ -196,7 +194,7 @@ export const Input = withForwardRef(function Input<OnChangeData, OnBlurData, OnC
196
194
  onChange={onChange}
197
195
  onKeyDown={realOnKeyDown}
198
196
  />
199
- {error && <InlineBlock className={styles.error}><Text>{error}</Text></InlineBlock>}
197
+ <FormError error={error}/>
200
198
  </label>
201
199
  );
202
200
  },
@@ -34,7 +34,7 @@
34
34
  font-size: 1rem;
35
35
 
36
36
  @include design($material) {
37
- color: #212121;
37
+ color: var(--input-text-color, #212121);
38
38
  background-image: linear-gradient(to top, transparent 1px, #afafaf 1px);
39
39
  background-size: 100% 2px;
40
40
  background-repeat: no-repeat;
@@ -53,7 +53,7 @@
53
53
  }
54
54
 
55
55
  @include design($flat) {
56
- color: #1f1f21;
56
+ color: var(--input-text-color, #1f1f21);
57
57
  &, &:focus {
58
58
  border-bottom: 1px solid var(--border-light);
59
59
  }
@@ -6,7 +6,8 @@ import classNames from 'classnames';
6
6
 
7
7
  import styles from './switch.scss';
8
8
  import { withMemo } from '../../../helper/withMemo';
9
- import {OptionalListener, useListenerWithExtractedProps} from "../../Hooks/useListener";
9
+ import { OptionalListener, useListenerWithExtractedProps } from "../../Hooks/useListener";
10
+ import { FormError } from "../FormError";
10
11
 
11
12
  export type SwitchProps<OnChangeCheckedData> = RbmComponentProps<
12
13
  Override<
@@ -17,67 +18,70 @@ export type SwitchProps<OnChangeCheckedData> = RbmComponentProps<
17
18
  children?: string;
18
19
  isLabelBeforeSwitch?: boolean;
19
20
  isDual?: boolean;
21
+ error?: string;
20
22
  } & OptionalListener<"onChangeChecked", OnChangeCheckedData, boolean>
21
23
  >
22
24
  >;
23
25
 
24
26
  export const Switch = withMemo(function Switch<OnChangeCheckedData>({
25
- children,
26
- label = '',
27
- preLabel = '',
28
- isLabelBeforeSwitch = false,
29
- isDual = undefined,
30
- id,
31
- className,
32
- style,
33
- onChange,
34
- ...props
35
- }: SwitchProps<OnChangeCheckedData>) {
36
- // Variables
27
+ children,
28
+ label = '',
29
+ preLabel = '',
30
+ isLabelBeforeSwitch = false,
31
+ isDual = undefined,
32
+ id,
33
+ className,
34
+ style,
35
+ error,
36
+ onChange,
37
+ ...props
38
+ }: SwitchProps<OnChangeCheckedData>) {
39
+ // Variables
37
40
 
38
- // States
41
+ // States
39
42
 
40
- // Refs
43
+ // Refs
41
44
 
42
- // Callbacks
43
- const [onChangeChecked, otherProps] = useListenerWithExtractedProps("onChangeChecked", props);
45
+ // Callbacks
46
+ const [onChangeChecked, otherProps] = useListenerWithExtractedProps("onChangeChecked", props);
44
47
 
45
- const realOnChange = useCallback<ChangeEventHandler<HTMLInputElement>>(
46
- (e) => {
47
- onChange?.(e);
48
- onChangeChecked(e.target.checked);
49
- },
50
- [onChange, onChangeChecked]
51
- );
48
+ const realOnChange = useCallback<ChangeEventHandler<HTMLInputElement>>(
49
+ (e) => {
50
+ onChange?.(e);
51
+ onChangeChecked(e.target.checked);
52
+ },
53
+ [onChange, onChangeChecked]
54
+ );
52
55
 
53
- // Effects
56
+ // Effects
54
57
 
55
- // Other
58
+ // Other
56
59
 
57
- // Render Functions
60
+ // Render Functions
58
61
 
59
- if (React.Children.count(children) === 1 && typeof children === 'string') {
60
- label = children;
61
- }
62
+ if (React.Children.count(children) === 1 && typeof children === 'string') {
63
+ label = children;
64
+ }
62
65
 
63
- if (isLabelBeforeSwitch) {
64
- [label, preLabel] = [preLabel, label];
65
- }
66
+ if (isLabelBeforeSwitch) {
67
+ [label, preLabel] = [preLabel, label];
68
+ }
66
69
 
67
- if (label && preLabel && isDual === undefined) {
68
- isDual = true;
69
- }
70
- return (
71
- <span className={classNames(styles.switch, { [styles.dual]: isDual }, className)} style={style}>
70
+ if (label && preLabel && isDual === undefined) {
71
+ isDual = true;
72
+ }
73
+ return (
74
+ <span className={classNames(styles.switch, {[styles.dual]: isDual}, className)} style={style}>
72
75
  <label htmlFor={id} key={id}>
73
76
  <span className={styles.label}>{preLabel}</span>
74
- <input {...otherProps} type="checkbox" id={id} onChange={realOnChange} />
77
+ <input {...otherProps} type="checkbox" id={id} onChange={realOnChange}/>
75
78
  <div className={styles.toggle}>
76
- <span className={styles.handle} />
79
+ <span className={styles.handle}/>
77
80
  </div>
78
81
  <span className={styles.label}>{label}</span>
82
+ <FormError error={error}/>
79
83
  </label>
80
84
  </span>
81
- );
82
- },
83
- styles);
85
+ );
86
+ },
87
+ styles);
@@ -0,0 +1,4 @@
1
+ .error {
2
+ font-size: 0.7rem;
3
+ --text-primary-default-color: var(--text-error)
4
+ }
@@ -0,0 +1,14 @@
1
+ import { useEffect } from "react";
2
+
3
+ export function useDelayedEffect(effect: () => (() => void|void), dependencies: any[], delay = 100){
4
+ useEffect(() => {
5
+ let cleanup: (() => void|void) | undefined;
6
+ let timeout = setTimeout(() => {
7
+ cleanup = effect();
8
+ }, delay);
9
+ return () => {
10
+ clearTimeout(timeout);
11
+ cleanup?.()
12
+ };
13
+ }, dependencies);
14
+ }