@ainias42/react-bootstrap-mobile 0.2.0 → 0.2.1

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 (52) hide show
  1. package/bin/updateCopies.js +3 -2
  2. package/bootstrapReactMobile.ts +9 -0
  3. package/dist/bootstrapReactMobile.d.ts +9 -0
  4. package/dist/bootstrapReactMobile.js +881 -670
  5. package/dist/bootstrapReactMobile.js.map +1 -1
  6. package/dist/src/Components/Clickable/Clickable.d.ts +6 -3
  7. package/dist/src/Components/FormElements/Button/Button.d.ts +4 -1
  8. package/dist/src/Components/FormElements/Controller/HookForm.d.ts +8 -0
  9. package/dist/src/Components/FormElements/Controller/InputController.d.ts +4 -0
  10. package/dist/src/Components/FormElements/Controller/MultipleFileInputController.d.ts +3 -0
  11. package/dist/src/Components/FormElements/Controller/PasswordInputController.d.ts +4 -0
  12. package/dist/src/Components/FormElements/Controller/SelectController.d.ts +3 -0
  13. package/dist/src/Components/FormElements/Controller/SendFormContext.d.ts +3 -0
  14. package/dist/src/Components/FormElements/Controller/TextareaController.d.ts +4 -0
  15. package/dist/src/Components/FormElements/Controller/withHookController.d.ts +4 -0
  16. package/dist/src/Components/FormElements/Input/FileInput/MultipleFileInput.d.ts +2 -1
  17. package/dist/src/Components/FormElements/Input/Input.d.ts +1 -0
  18. package/dist/src/Components/FormElements/Select/Select.d.ts +2 -1
  19. package/dist/src/Components/FormElements/Textarea/Textarea.d.ts +1 -0
  20. package/dist/src/Components/Hooks/useComposedRef.d.ts +1 -1
  21. package/dist/src/Components/Image/Image.d.ts +2 -2
  22. package/dist/src/Size.d.ts +8 -0
  23. package/package.json +5 -3
  24. package/src/Components/Clickable/Clickable.tsx +41 -6
  25. package/src/Components/FormElements/Button/Button.tsx +14 -8
  26. package/src/Components/FormElements/Button/button.scss +17 -0
  27. package/src/Components/FormElements/Controller/HookForm.tsx +43 -0
  28. package/src/Components/FormElements/Controller/InputController.ts +4 -0
  29. package/src/Components/FormElements/Controller/MultipleFileInputController.ts +4 -0
  30. package/src/Components/FormElements/Controller/PasswordInputController.ts +4 -0
  31. package/src/Components/FormElements/Controller/SelectController.ts +4 -0
  32. package/src/Components/FormElements/Controller/SendFormContext.ts +7 -0
  33. package/src/Components/FormElements/Controller/TextareaController.ts +4 -0
  34. package/src/Components/FormElements/Controller/withHookController.tsx +53 -0
  35. package/src/Components/FormElements/Input/FileInput/MultipleFileInput.tsx +4 -1
  36. package/src/Components/FormElements/Input/FileInput/fileInput.scss +5 -6
  37. package/src/Components/FormElements/Input/Input.tsx +17 -6
  38. package/src/Components/FormElements/Input/PasswordInput/PasswordInput.tsx +1 -1
  39. package/src/Components/FormElements/Input/input.scss +5 -0
  40. package/src/Components/FormElements/Select/Select.tsx +5 -0
  41. package/src/Components/FormElements/Select/select.scss +5 -0
  42. package/src/Components/FormElements/Textarea/Textarea.tsx +9 -4
  43. package/src/Components/FormElements/Textarea/textarea.scss +10 -1
  44. package/src/Components/FormElements/hooks/useOnChangeDone.ts +1 -1
  45. package/src/Components/Hooks/useComposedRef.ts +13 -16
  46. package/src/Components/Image/Image.tsx +2 -2
  47. package/src/Size.ts +9 -0
  48. package/src/scss/_baseClasses.scss +7 -11
  49. package/src/scss/_colors.scss +10 -5
  50. package/src/scss/_default.scss +2 -2
  51. package/src/scss/_variables.scss +2 -2
  52. package/webpack.config.js +1 -0
@@ -6,8 +6,9 @@ type OnPointerDownListener<Data> = OptionalListener<'onPointerDown', Data, Point
6
6
  type OnPointerUpListener<Data> = OptionalListener<'onPointerUp', Data, PointerEvent>;
7
7
  type OnPointerMoveListener<Data> = OptionalListener<'onPointerMove', Data, PointerEvent>;
8
8
  type OnDropListener<Data> = OptionalListener<'onDrop', Data>;
9
+ type OnDragStartListener<Data> = OptionalListener<'onDragStart', Data>;
9
10
  type OnDragOverListener<Data> = OptionalListener<'onDragOver', Data>;
10
- export type ClickableProps<OnClickData, OnMouseDownData, OnMouseMoveData, OnMouseUpData, OnClickCaptureData, OnDropData, OnDragOverData, OnMouseEnterData, OnMouseLeaveData, OnDoubleClickData, HrefType extends string | undefined> = RbmComponentProps<{
11
+ export type ClickableProps<OnClickData, OnMouseDownData, OnMouseMoveData, OnMouseUpData, OnClickCaptureData, OnDropData, OnDragStartData, OnDragOverData, OnMouseEnterData, OnMouseLeaveData, OnDoubleClickData, HrefType extends string | undefined> = RbmComponentProps<{
11
12
  interactable?: boolean;
12
13
  href?: HrefType;
13
14
  target?: string;
@@ -15,6 +16,8 @@ export type ClickableProps<OnClickData, OnMouseDownData, OnMouseMoveData, OnMous
15
16
  stopPropagation?: boolean;
16
17
  useReactOnMouseLeave?: boolean;
17
18
  id?: string;
18
- } & OnClickListener<OnClickData> & OnPointerDownListener<OnMouseDownData> & OnPointerMoveListener<OnMouseMoveData> & OnPointerUpListener<OnMouseUpData> & OnDropListener<OnDropData> & OnDragOverListener<OnDragOverData> & OptionalListener<'onClickCapture', OnClickCaptureData> & OptionalListener<'onMouseEnter', OnMouseEnterData> & OptionalListener<'onMouseLeave', OnMouseLeaveData, MouseEvent | ReactMouseEvent> & OptionalListener<'onDoubleClick', OnDoubleClickData>>;
19
- declare const ClickableMemo: import("../../helper/withForwardRef").RefComponent<ClickableProps<unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, string | undefined>, HTMLAnchorElement | HTMLSpanElement>;
19
+ tabIndex?: number;
20
+ draggable?: boolean;
21
+ } & OnClickListener<OnClickData> & OnPointerDownListener<OnMouseDownData> & OnPointerMoveListener<OnMouseMoveData> & OnPointerUpListener<OnMouseUpData> & OnDropListener<OnDropData> & OnDragStartListener<OnDragStartData> & OnDragOverListener<OnDragOverData> & OptionalListener<'onClickCapture', OnClickCaptureData> & OptionalListener<'onMouseEnter', OnMouseEnterData> & OptionalListener<'onMouseLeave', OnMouseLeaveData, MouseEvent | ReactMouseEvent> & OptionalListener<'onDoubleClick', OnDoubleClickData>>;
22
+ declare const ClickableMemo: import("../../helper/withForwardRef").RefComponent<ClickableProps<unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, string | undefined>, HTMLAnchorElement | HTMLSpanElement>;
20
23
  export { ClickableMemo as Clickable };
@@ -5,9 +5,12 @@ import { HTMLAttributes } from 'react';
5
5
  import { RbmComponentProps } from '../../RbmComponentProps';
6
6
  import { ButtonType } from "./ButtonType";
7
7
  import { Flavor } from "../../Flavor";
8
+ import { Size } from "../../../Size";
8
9
  export type ButtonProps<ClickData> = RbmComponentProps<Override<HTMLAttributes<HTMLButtonElement>, {
9
10
  type?: ButtonType;
10
11
  disabled?: boolean;
11
12
  flavor?: Flavor;
13
+ fullWidth?: boolean;
14
+ size?: Omit<Size, "xxLarge" | "xLarge" | "large" | "xSmall">;
12
15
  } & OptionalListener<'onClick', ClickData>>>;
13
- export declare const Button: <ClickData>({ children, className, disabled, flavor, type, ...props }: ButtonProps<ClickData>) => React.JSX.Element;
16
+ export declare const Button: <ClickData>({ children, className, disabled, size, fullWidth, flavor, type, ...props }: ButtonProps<ClickData>) => React.JSX.Element;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { FormProviderProps } from "react-hook-form";
3
+ type FieldValues = Record<string, any>;
4
+ export type HookFormProps<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues extends FieldValues | undefined = undefined> = FormProviderProps<TFieldValues, TContext, TTransformedValues> & {
5
+ onSend?: () => void;
6
+ };
7
+ export declare const HookForm: <TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues extends FieldValues | undefined = undefined>({ children, onSend, ...methods }: HookFormProps<TFieldValues, TContext, TTransformedValues>) => React.JSX.Element;
8
+ export {};
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ export declare const InputController: import("../../../helper/withForwardRef").RefComponent<Omit<import("../Input/Input").InputProps<unknown, unknown, unknown> & import("react").RefAttributes<HTMLInputElement>, "value" | "ref" | "onBlur" | "name" | "onChangeText"> & {
3
+ name: string;
4
+ }, HTMLInputElement>;
@@ -0,0 +1,3 @@
1
+ export declare const MultipleFileInputController: import("../../../helper/withForwardRef").RefComponent<Omit<import("../Input/FileInput/MultipleFileInput").MultipleFileInputProps<unknown>, "value" | "ref" | "onBlur" | "name" | "onChangeFiles"> & {
2
+ name: string;
3
+ }, never>;
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ export declare const PasswordInputController: import("../../../helper/withForwardRef").RefComponent<Omit<import("../Input/PasswordInput/PasswordInput").PasswordInputProps<unknown, unknown, unknown> & import("react").RefAttributes<HTMLInputElement>, "value" | "ref" | "onBlur" | "name" | "onChangeText"> & {
3
+ name: string;
4
+ }, HTMLInputElement>;
@@ -0,0 +1,3 @@
1
+ export declare const SelectController: import("../../../helper/withForwardRef").RefComponent<Omit<import("../Select/Select").SelectProps<unknown>, "value" | "ref" | "onBlur" | "name" | "onChangeValue"> & {
2
+ name: string;
3
+ }, never>;
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ export declare const SendFormContext: import("react").Context<(() => void) | undefined>;
3
+ export declare function useSendFormContext(): (() => void) | undefined;
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ export declare const TextareaController: import("../../../helper/withForwardRef").RefComponent<Omit<import("../Textarea/Textarea").TextareaProps<unknown, unknown> & import("react").RefAttributes<HTMLTextAreaElement>, "value" | "ref" | "onBlur" | "name" | "onChangeText"> & {
3
+ name: string;
4
+ }, HTMLTextAreaElement>;
@@ -0,0 +1,4 @@
1
+ import React, { ComponentProps, ComponentType } from "react";
2
+ export declare function withHookController<C extends ComponentType<any>, OnChangeProp extends keyof ComponentProps<C>>(Comp: C, onChangeProp: OnChangeProp, emptyValue?: any): import("../../../helper/withForwardRef").RefComponent<Omit<React.ComponentProps<C>, "value" | "ref" | "onBlur" | "name" | OnChangeProp> & {
3
+ name: string;
4
+ }, React.ComponentRef<C>>;
@@ -13,5 +13,6 @@ export type MultipleFileInputProps<OnChangeFilesData> = RbmComponentProps<Overri
13
13
  onError?: (error: string) => void;
14
14
  allowOverride?: boolean;
15
15
  showDeleteButton?: boolean;
16
+ error?: string;
16
17
  } & Listener<'onChangeFiles', OnChangeFilesData, FileType[]>>>;
17
- export declare const MultipleFileInput: <OnChangeData>({ className, style, value, label, mimeTypes, maxFiles, maxSizePerFile, allowOverride, onError, showDeleteButton, ...otherProps }: MultipleFileInputProps<OnChangeData>) => React.JSX.Element;
18
+ export declare const MultipleFileInput: <OnChangeData>({ className, style, value, label, mimeTypes, maxFiles, maxSizePerFile, allowOverride, onError, showDeleteButton, error, ...otherProps }: MultipleFileInputProps<OnChangeData>) => React.JSX.Element;
@@ -7,5 +7,6 @@ export type InputProps<OnChangeData, OnBlurData, OnChangeDoneData> = RbmComponen
7
7
  inline?: boolean;
8
8
  onChangeText?: (newText: string) => void;
9
9
  onEnter?: (newText: string) => void;
10
+ error?: string;
10
11
  } & OptionalListener<'onChange', OnChangeData> & OptionalListener<'onBlur', OnBlurData> & OptionalListener<'onChangeDone', OnChangeDoneData>>>;
11
12
  export declare const Input: import("../../../helper/withForwardRef").RefComponent<InputProps<unknown, unknown, unknown>, HTMLInputElement>;
@@ -14,5 +14,6 @@ export type SelectProps<OnChangeData> = RbmComponentProps<Override<SelectHTMLAtt
14
14
  onChangeValue?: (newValue: string) => void;
15
15
  inline?: boolean;
16
16
  small?: boolean;
17
+ error?: string;
17
18
  } & OptionalListener<'onChange', OnChangeData>>>;
18
- export declare const Select: <OnChangeData>({ label, options, className, style, onChangeValue, inline, small, ...otherProps }: SelectProps<OnChangeData>) => React.JSX.Element;
19
+ export declare const Select: <OnChangeData>({ label, options, className, style, onChangeValue, inline, small, error, ...otherProps }: SelectProps<OnChangeData>) => React.JSX.Element;
@@ -9,5 +9,6 @@ export type TextareaProps<OnChangeData, OnChangeDoneData> = RbmComponentProps<Ov
9
9
  onEscape?: (newText: string) => void;
10
10
  textareaStyles?: CSSProperties & Record<`--${string}`, string | number | undefined>;
11
11
  containerRef?: MutableRefObject<HTMLLabelElement | null>;
12
+ error?: string;
12
13
  } & OptionalListener<'onChange', OnChangeData> & OptionalListener<'onChangeDone', OnChangeDoneData>>>;
13
14
  export declare const Textarea: import("../../../helper/withForwardRef").RefComponent<TextareaProps<unknown, unknown>, HTMLTextAreaElement>;
@@ -1,2 +1,2 @@
1
1
  import { ForwardedRef } from 'react';
2
- export declare const useComposedRef: <T>(ref: ForwardedRef<T>, initialValue?: T | null) => import("react").RefObject<T>;
2
+ export declare function useComposedRef<RefVal>(...refs: (ForwardedRef<RefVal> | undefined)[]): (val: RefVal | null) => void;
@@ -1,8 +1,8 @@
1
1
  import * as React from 'react';
2
2
  import { RbmComponentProps, WithNoChildren } from '../RbmComponentProps';
3
- import { CSSProperties, DOMAttributes } from 'react';
3
+ import { CSSProperties } from 'react';
4
4
  import { Override } from '../../TypeHelpers';
5
- export type ImageProps = RbmComponentProps<Override<Omit<React.ComponentPropsWithoutRef<'img'>, keyof DOMAttributes<'img'>>, {
5
+ export type ImageProps = RbmComponentProps<Override<React.ComponentPropsWithoutRef<'img'>, {
6
6
  src: string;
7
7
  style?: CSSProperties;
8
8
  alt?: string;
@@ -0,0 +1,8 @@
1
+ export declare enum Size {
2
+ xSmall = 0,
3
+ small = 1,
4
+ medium = 2,
5
+ large = 3,
6
+ xLarge = 4,
7
+ xxLarge = 5
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainias42/react-bootstrap-mobile",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Mobile React Components using Bootstrap",
5
5
  "main": "dist/bootstrapReactMobile",
6
6
  "scripts": {
@@ -38,9 +38,11 @@
38
38
  "@fortawesome/react-fontawesome": "^0.2.2",
39
39
  "bootstrap": "^5.3.3",
40
40
  "react": ">=18.0.0",
41
- "react-beautiful-dnd": "^13.1.1"
41
+ "react-beautiful-dnd": "^13.1.1",
42
+ "react-hook-form": "^7.53.0"
42
43
  },
43
44
  "devDependencies": {
45
+ "react-hook-form": "^7.53.0",
44
46
  "ajv": "^8.14.0",
45
47
  "bootstrap": "^5.3.3",
46
48
  "react": ">=18.0.0",
@@ -90,7 +92,7 @@
90
92
  "webpack-dev-server": "^5.0.4"
91
93
  },
92
94
  "dependencies": {
93
- "@ainias42/js-helper": ">=0.8.14",
95
+ "@ainias42/js-helper": ">=0.8.15",
94
96
  "@types/react-virtualized-auto-sizer": "^1.0.4",
95
97
  "classnames": "^2.5.1",
96
98
  "isomorphic-style-loader": "^5.3.2",
@@ -4,7 +4,15 @@ import {OptionalListener, useListener} from '../Hooks/useListener';
4
4
 
5
5
  import styles from './clickable.scss';
6
6
  import classNames from 'classnames';
7
- import { useCallback, MouseEvent as ReactMouseEvent, ForwardedRef, useEffect, MouseEvent, PointerEvent } from 'react';
7
+ import {
8
+ useCallback,
9
+ MouseEvent as ReactMouseEvent,
10
+ ForwardedRef,
11
+ useEffect,
12
+ MouseEvent,
13
+ PointerEvent,
14
+ useRef, DragEventHandler
15
+ } from 'react';
8
16
  import {withForwardRef} from '../../helper/withForwardRef';
9
17
  import {useComposedRef} from "../Hooks/useComposedRef";
10
18
 
@@ -13,6 +21,7 @@ type OnPointerDownListener<Data> = OptionalListener<'onPointerDown', Data, Point
13
21
  type OnPointerUpListener<Data> = OptionalListener<'onPointerUp', Data, PointerEvent>;
14
22
  type OnPointerMoveListener<Data> = OptionalListener<'onPointerMove', Data, PointerEvent>;
15
23
  type OnDropListener<Data> = OptionalListener<'onDrop', Data>;
24
+ type OnDragStartListener<Data> = OptionalListener<'onDragStart', Data>;
16
25
  type OnDragOverListener<Data> = OptionalListener<'onDragOver', Data>;
17
26
 
18
27
  export type ClickableProps<
@@ -22,6 +31,7 @@ export type ClickableProps<
22
31
  OnMouseUpData,
23
32
  OnClickCaptureData,
24
33
  OnDropData,
34
+ OnDragStartData,
25
35
  OnDragOverData,
26
36
  OnMouseEnterData,
27
37
  OnMouseLeaveData,
@@ -36,11 +46,14 @@ export type ClickableProps<
36
46
  stopPropagation?: boolean;
37
47
  useReactOnMouseLeave?: boolean;
38
48
  id?: string;
49
+ tabIndex?: number;
50
+ draggable?: boolean
39
51
  } & OnClickListener<OnClickData> &
40
52
  OnPointerDownListener<OnMouseDownData> &
41
53
  OnPointerMoveListener<OnMouseMoveData> &
42
54
  OnPointerUpListener<OnMouseUpData> &
43
55
  OnDropListener<OnDropData> &
56
+ OnDragStartListener<OnDragStartData> &
44
57
  OnDragOverListener<OnDragOverData> &
45
58
  OptionalListener<'onClickCapture', OnClickCaptureData> &
46
59
  OptionalListener<'onMouseEnter', OnMouseEnterData> &
@@ -55,6 +68,7 @@ function Clickable<
55
68
  OnPointerUpData,
56
69
  OnClickCaptureData,
57
70
  OnDropData,
71
+ OnDragStartData,
58
72
  OnDragOverData,
59
73
  OnMouseEnterData,
60
74
  OnMouseLeaveData,
@@ -72,8 +86,10 @@ function Clickable<
72
86
  preventDefault = false,
73
87
  stopPropagation = true,
74
88
  useReactOnMouseLeave = false,
89
+ tabIndex,
90
+ draggable,
75
91
  ...clickData
76
- }: ClickableProps<OnClickData, OnPointerDownData, OnPointerMoveData, OnPointerUpData, OnClickCaptureData, OnDropData, OnDragOverData,OnMouseEnterData, OnMouseLeaveData, OnDoubleClickData, HrefType>,
92
+ }: ClickableProps<OnClickData, OnPointerDownData, OnPointerMoveData, OnPointerUpData, OnClickCaptureData, OnDropData,OnDragStartData, OnDragOverData,OnMouseEnterData, OnMouseLeaveData, OnDoubleClickData, HrefType>,
77
93
  ref: ForwardedRef<HrefType extends string ? HTMLAnchorElement : HTMLSpanElement>
78
94
  ) {
79
95
  // Variables
@@ -81,7 +97,8 @@ function Clickable<
81
97
  // States
82
98
 
83
99
  // Refs
84
- const clickableRef = useComposedRef(ref);
100
+ const clickableRef = useRef<HrefType extends string ? HTMLAnchorElement : HTMLSpanElement>(null);
101
+ const refSetter = useComposedRef(ref, clickableRef);
85
102
 
86
103
  // Callbacks
87
104
  const onClickInner = useListener<'onClick', OnClickData>('onClick', clickData);
@@ -196,6 +213,22 @@ function Clickable<
196
213
  [clickData.onDragOver, onDragOver, preventDefault, stopPropagation]
197
214
  );
198
215
 
216
+ const onDragStartListener = useListener<'onDragStart', OnDragStartData>('onDragStart', clickData);
217
+ const realOnDragStartListener = useCallback(
218
+ (e: ReactMouseEvent) => {
219
+ if (clickData.onDragStart) {
220
+ if (stopPropagation) {
221
+ e.stopPropagation();
222
+ }
223
+ if (preventDefault) {
224
+ e.preventDefault();
225
+ }
226
+ onDragStartListener(e);
227
+ }
228
+ },
229
+ [clickData.onDragStart, onDragStartListener, preventDefault, stopPropagation]
230
+ );
231
+
199
232
  const onMouseEnter = useListener<'onMouseEnter', OnMouseEnterData>('onMouseEnter', clickData);
200
233
  const realOnMouseEnter = useCallback(
201
234
  (e: ReactMouseEvent) => {
@@ -276,17 +309,19 @@ function Clickable<
276
309
  onMouseEnter: realOnMouseEnter,
277
310
  onMouseLeave: useReactOnMouseLeave ? realOnMouseLeave : undefined,
278
311
  onDoubleClick: realOnDoubleClick,
279
- tabIndex: interactable ? 0 : undefined,
312
+ tabIndex: interactable ? 0 : tabIndex,
313
+ draggable,
314
+ onDragStart: realOnDragStartListener
280
315
  };
281
316
  if (typeof href === 'string') {
282
317
  return (
283
- <a {...props} href={href} ref={clickableRef as ForwardedRef<HTMLAnchorElement>}>
318
+ <a {...props} href={href} ref={refSetter as ForwardedRef<HTMLAnchorElement>}>
284
319
  {children}
285
320
  </a>
286
321
  );
287
322
  }
288
323
  return (
289
- <span {...props} ref={clickableRef as ForwardedRef<HTMLSpanElement>}>
324
+ <span {...props} ref={refSetter as ForwardedRef<HTMLSpanElement>}>
290
325
  {children}
291
326
  </span>
292
327
  );
@@ -1,20 +1,23 @@
1
1
  import * as React from 'react';
2
- import {Override} from '@ainias42/js-helper';
3
- import {OptionalListener, useListenerWithExtractedProps} from '../../Hooks/useListener';
2
+ import { Override } from '@ainias42/js-helper';
3
+ import { OptionalListener, useListenerWithExtractedProps } from '../../Hooks/useListener';
4
4
 
5
5
  import styles from './button.scss';
6
6
  import classNames from 'classnames';
7
- import {withMemo} from '../../../helper/withMemo';
8
- import {HTMLAttributes} from 'react';
9
- import {RbmComponentProps} from '../../RbmComponentProps';
10
- import {ButtonType} from "./ButtonType";
11
- import {Flavor} from "../../Flavor";
7
+ import { withMemo } from '../../../helper/withMemo';
8
+ import { HTMLAttributes } from 'react';
9
+ import { RbmComponentProps } from '../../RbmComponentProps';
10
+ import { ButtonType } from "./ButtonType";
11
+ import { Flavor } from "../../Flavor";
12
+ import { Size } from "../../../Size";
12
13
 
13
14
  export type ButtonProps<ClickData> = RbmComponentProps<
14
15
  Override<HTMLAttributes<HTMLButtonElement>, {
15
16
  type?: ButtonType,
16
17
  disabled?: boolean;
17
18
  flavor?: Flavor
19
+ fullWidth?: boolean;
20
+ size?: Omit<Size, "xxLarge" | "xLarge" | "large" | "xSmall">
18
21
  } & OptionalListener<'onClick', ClickData>>
19
22
  >;
20
23
 
@@ -22,6 +25,8 @@ export const Button = withMemo(function Button<ClickData>({
22
25
  children,
23
26
  className,
24
27
  disabled,
28
+ size,
29
+ fullWidth = false,
25
30
  flavor = Flavor.Accent,
26
31
  type = ButtonType.Primary,
27
32
  ...props
@@ -32,11 +37,12 @@ export const Button = withMemo(function Button<ClickData>({
32
37
  [styles.primary]: type === ButtonType.Primary,
33
38
  [styles.secondary]: type === ButtonType.Secondary,
34
39
  [styles.disabled]: disabled,
40
+ [styles.small]: size === Size.small
35
41
  };
36
42
 
37
43
  return (
38
44
  <button {...otherProps} disabled={disabled} type="button" onClick={onClick}
39
- className={classNames(styles.button, classes, flavor, className)}>
45
+ className={classNames(styles.button, {[styles.fullWidth]: fullWidth}, classes, flavor, className)}>
40
46
  {children}
41
47
  </button>
42
48
  );
@@ -53,4 +53,21 @@
53
53
  cursor: default;
54
54
  pointer-events: none;
55
55
  }
56
+
57
+ &.small {
58
+ @include design($material) {
59
+ min-height: 17px;
60
+ line-height: 17px;
61
+ padding: 0 8px;
62
+ }
63
+
64
+ @include design($flat) {
65
+ line-height: 17px;
66
+ padding: 4px 9px;
67
+ }
68
+ }
69
+
70
+ &.fullWidth {
71
+ width: 100%;
72
+ }
56
73
  }
@@ -0,0 +1,43 @@
1
+ import React, { useCallback } from 'react';
2
+ import { FormProvider, FormProviderProps } from "react-hook-form";
3
+ import { withMemo } from "../../../helper/withMemo";
4
+ import { LoadingArea } from "../../LoadingArea/LoadingArea";
5
+ import { SendFormContext } from "./SendFormContext";
6
+
7
+ type FieldValues = Record<string, any>;
8
+ export type HookFormProps<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues extends FieldValues | undefined = undefined> =
9
+ FormProviderProps<TFieldValues, TContext, TTransformedValues>
10
+ & {
11
+ onSend?: () => void;
12
+ };
13
+
14
+ export const HookForm = withMemo(function HookForm<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues extends FieldValues | undefined = undefined>({
15
+ children,
16
+ onSend,
17
+ ...methods
18
+ }: HookFormProps<TFieldValues, TContext, TTransformedValues>) {
19
+ // Refs
20
+
21
+ // States/Variables/Selectors
22
+
23
+ // Create an inner, as the onSend may have other attributes
24
+ const innerOnSend = useCallback(() => onSend?.(), [onSend]);
25
+
26
+ // Dispatch
27
+
28
+ // Callbacks
29
+
30
+ // Effects
31
+
32
+ // Other
33
+
34
+ // RenderFunctions
35
+
36
+ return <FormProvider {...methods}>
37
+ <SendFormContext.Provider value={innerOnSend}>
38
+ <LoadingArea loading={methods.formState.isSubmitting} __allowChildren={"all"}>
39
+ {children}
40
+ </LoadingArea>
41
+ </SendFormContext.Provider>
42
+ </FormProvider>;
43
+ });
@@ -0,0 +1,4 @@
1
+ import { Input } from "../Input/Input";
2
+ import { withHookController } from "./withHookController";
3
+
4
+ export const InputController = withHookController(Input, "onChangeText");
@@ -0,0 +1,4 @@
1
+ import { MultipleFileInput } from "../Input/FileInput/MultipleFileInput";
2
+ import { withHookController } from "./withHookController";
3
+
4
+ export const MultipleFileInputController = withHookController(MultipleFileInput, 'onChangeFiles');
@@ -0,0 +1,4 @@
1
+ import { withHookController } from "./withHookController";
2
+ import { PasswordInput } from "../Input/PasswordInput/PasswordInput";
3
+
4
+ export const PasswordInputController = withHookController(PasswordInput, "onChangeText");
@@ -0,0 +1,4 @@
1
+ import { withHookController } from "./withHookController";
2
+ import { Select } from "../Select/Select";
3
+
4
+ export const SelectController = withHookController(Select, "onChangeValue");
@@ -0,0 +1,7 @@
1
+ import { createContext, useContext } from "react";
2
+
3
+ export const SendFormContext = createContext<(() => void)|undefined>(undefined);
4
+
5
+ export function useSendFormContext(){
6
+ return useContext(SendFormContext);
7
+ }
@@ -0,0 +1,4 @@
1
+ import { withHookController } from "./withHookController";
2
+ import { Textarea } from "../Textarea/Textarea";
3
+
4
+ export const TextareaController = withHookController(Textarea, 'onChangeText');
@@ -0,0 +1,53 @@
1
+ import React, { ComponentProps, ComponentRef, ComponentType, ForwardedRef, useCallback } from "react";
2
+ import { FieldPath, FieldValues, useController, useFormContext } from "react-hook-form";
3
+ import { useComposedRef } from "../../Hooks/useComposedRef";
4
+ import { withForwardRef } from "../../../helper/withForwardRef";
5
+
6
+ export function withHookController<C extends ComponentType<any>, OnChangeProp extends keyof ComponentProps<C>>(Comp: C, onChangeProp: OnChangeProp, emptyValue: any = null) {
7
+ type RefType = ComponentRef<C>;
8
+ type OldProps = ComponentProps<C>;
9
+
10
+ type Props<Values extends FieldValues, Name extends FieldPath<Values> = FieldPath<Values>> = Omit<
11
+ OldProps,
12
+ 'name' | 'onBlur' | OnChangeProp | 'ref' | 'value'
13
+ > & { name: Name };
14
+
15
+ function WithHookComponent<Values extends FieldValues, Name extends FieldPath<Values> = FieldPath<Values>>(
16
+ {name, ...otherProps}: Props<Values, Name>,
17
+ ref?: ForwardedRef<RefType>
18
+ ) {
19
+ const children = "children" in otherProps ? otherProps.children : undefined;
20
+
21
+ const {field, fieldState} = useController({name});
22
+ const {clearErrors} = useFormContext();
23
+ const composedRef = useComposedRef(ref, field.ref);
24
+ const errorMessage = fieldState.error?.message;
25
+
26
+ const internalOnChange = useCallback(
27
+ (arg: any) => {
28
+ clearErrors(name);
29
+ field.onChange(arg);
30
+ },
31
+ [clearErrors, field, name]
32
+ );
33
+ const onChangeProps = {
34
+ [onChangeProp]: internalOnChange
35
+ }
36
+
37
+ return (
38
+ // @ts-expect-error Because of the prop spreading, typescript is really confused here
39
+ <Comp
40
+ {...otherProps}
41
+ {...field}
42
+ {...onChangeProps}
43
+ value={field.value ?? emptyValue}
44
+ ref={composedRef}
45
+ error={errorMessage}
46
+ >
47
+ {children}
48
+ </Comp>
49
+ );
50
+ }
51
+
52
+ return withForwardRef(WithHookComponent);
53
+ }
@@ -3,7 +3,6 @@ import {RbmComponentProps} from '../../../RbmComponentProps';
3
3
  import {Override} from '../../../../TypeHelpers';
4
4
  import {ChangeEventHandler, DragEvent, InputHTMLAttributes, useCallback, useRef} from 'react';
5
5
  import {Listener, useListenerWithExtractedProps} from '../../../Hooks/useListener';
6
-
7
6
  import styles from './fileInput.scss';
8
7
  import {withMemo} from '../../../../helper/withMemo';
9
8
  import classNames from 'classnames';
@@ -17,6 +16,7 @@ import {Image} from '../../../Image/Image';
17
16
  import {Clickable} from '../../../Clickable/Clickable';
18
17
  import {Inline} from '../../../Layout/Inline';
19
18
  import {FileType} from "./FileType";
19
+ import { InlineBlock } from "../../../Layout/InlineBlock";
20
20
 
21
21
 
22
22
  export type MultipleFileInputProps<OnChangeFilesData> = RbmComponentProps<
@@ -31,6 +31,7 @@ export type MultipleFileInputProps<OnChangeFilesData> = RbmComponentProps<
31
31
  onError?: (error: string) => void;
32
32
  allowOverride?: boolean
33
33
  showDeleteButton?: boolean
34
+ error?: string,
34
35
  } & Listener<'onChangeFiles', OnChangeFilesData, FileType[]>
35
36
  >
36
37
  >;
@@ -46,6 +47,7 @@ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeDa
46
47
  allowOverride = maxFiles === 1,
47
48
  onError,
48
49
  showDeleteButton = true,
50
+ error,
49
51
  ...otherProps
50
52
  }: MultipleFileInputProps<OnChangeData>) {
51
53
  // Variables
@@ -275,6 +277,7 @@ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeDa
275
277
  </Clickable>
276
278
  </Grow>
277
279
  </Flex>
280
+ {error && <InlineBlock className={styles.error}><Text>{error}</Text></InlineBlock>}
278
281
  </span>
279
282
  );
280
283
  },
@@ -79,11 +79,10 @@
79
79
 
80
80
  .value {
81
81
  display: none;
82
- //position: absolute;
83
- //top: 0;
84
- //left: 0;
85
- //right: 0;
86
- //bottom: 0;
87
- //opacity: 0;
82
+ }
83
+
84
+ .error {
85
+ font-size: 0.7rem;
86
+ --text-primary-default-color: var(--text-error)
88
87
  }
89
88
  }