@ainias42/react-bootstrap-mobile 0.1.7

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 (233) hide show
  1. package/.eslintrc.json +189 -0
  2. package/.prettierrc +5 -0
  3. package/LICENSE +21 -0
  4. package/README.md +1 -0
  5. package/babel.config.js +22 -0
  6. package/bin/build.js +60 -0
  7. package/bin/release.sh +35 -0
  8. package/bin/updateCopies.js +86 -0
  9. package/bootstrapReactMobile.ts +87 -0
  10. package/dist/bootstrapReactMobile.d.ts +87 -0
  11. package/dist/bootstrapReactMobile.js +6275 -0
  12. package/dist/src/Components/ActionSheet/ActionSheet.d.ts +21 -0
  13. package/dist/src/Components/Card/Card.d.ts +13 -0
  14. package/dist/src/Components/Clickable/Clickable.d.ts +14 -0
  15. package/dist/src/Components/Dialog/AlertDialog.d.ts +10 -0
  16. package/dist/src/Components/Dialog/ButtonDialog.d.ts +13 -0
  17. package/dist/src/Components/Dialog/ConfirmDialog.d.ts +11 -0
  18. package/dist/src/Components/Dialog/Dialog.d.ts +14 -0
  19. package/dist/src/Components/Dialog/DialogBackground.d.ts +7 -0
  20. package/dist/src/Components/Dialog/DialogContainer.d.ts +6 -0
  21. package/dist/src/Components/Dialog/DialogContext.d.ts +9 -0
  22. package/dist/src/Components/Dialog/useAlertDialog.d.ts +1 -0
  23. package/dist/src/Components/Dialog/useConfirmDialog.d.ts +1 -0
  24. package/dist/src/Components/DragAndDrop/DragItem.d.ts +7 -0
  25. package/dist/src/Components/DragAndDrop/DropArea.d.ts +7 -0
  26. package/dist/src/Components/DragAndDrop/useStrictEnabled.d.ts +1 -0
  27. package/dist/src/Components/FormElements/Button/Button.d.ts +8 -0
  28. package/dist/src/Components/FormElements/CheckBox/Checkbox.d.ts +10 -0
  29. package/dist/src/Components/FormElements/ColorInput/ColorInput.d.ts +17 -0
  30. package/dist/src/Components/FormElements/ColorInput/sharedSelectedColor.d.ts +4 -0
  31. package/dist/src/Components/FormElements/ImageInput/ImageInput.d.ts +17 -0
  32. package/dist/src/Components/FormElements/Input/HiddenInput.d.ts +8 -0
  33. package/dist/src/Components/FormElements/Input/Input.d.ts +10 -0
  34. package/dist/src/Components/FormElements/Input/PasswordInput/PasswordInput.d.ts +4 -0
  35. package/dist/src/Components/FormElements/SearchSelectInput/SearchSelectInput.d.ts +10 -0
  36. package/dist/src/Components/FormElements/Select/Select.d.ts +16 -0
  37. package/dist/src/Components/FormElements/Slider/Slider.d.ts +8 -0
  38. package/dist/src/Components/FormElements/Switch/Switch.d.ts +12 -0
  39. package/dist/src/Components/FormElements/Textarea/Textarea.d.ts +12 -0
  40. package/dist/src/Components/FormElements/hooks/useOnChangeDone.d.ts +2 -0
  41. package/dist/src/Components/FullScreen/FullScreen.d.ts +14 -0
  42. package/dist/src/Components/Hooks/useBreakpoint.d.ts +11 -0
  43. package/dist/src/Components/Hooks/useComposedRef.d.ts +2 -0
  44. package/dist/src/Components/Hooks/useDebounced.d.ts +1 -0
  45. package/dist/src/Components/Hooks/useDelayed.d.ts +1 -0
  46. package/dist/src/Components/Hooks/useInViewport.d.ts +2 -0
  47. package/dist/src/Components/Hooks/useKeyListener.d.ts +3 -0
  48. package/dist/src/Components/Hooks/useListener.d.ts +18 -0
  49. package/dist/src/Components/Hooks/useOnMount.d.ts +1 -0
  50. package/dist/src/Components/Hooks/useOnce.d.ts +1 -0
  51. package/dist/src/Components/Icon/Icon.d.ts +13 -0
  52. package/dist/src/Components/Image/Image.d.ts +12 -0
  53. package/dist/src/Components/InViewport/InViewport.d.ts +11 -0
  54. package/dist/src/Components/Layout/Block.d.ts +7 -0
  55. package/dist/src/Components/Layout/Container.d.ts +15 -0
  56. package/dist/src/Components/Layout/Flex.d.ts +10 -0
  57. package/dist/src/Components/Layout/Grid/Grid.d.ts +9 -0
  58. package/dist/src/Components/Layout/Grid/GridItem.d.ts +25 -0
  59. package/dist/src/Components/Layout/Grow.d.ts +9 -0
  60. package/dist/src/Components/Layout/Inline.d.ts +7 -0
  61. package/dist/src/Components/Layout/InlineBlock.d.ts +7 -0
  62. package/dist/src/Components/Layout/View.d.ts +9 -0
  63. package/dist/src/Components/Layout/ViewWithoutListeners.d.ts +8 -0
  64. package/dist/src/Components/List/BulletList/BulletList.d.ts +8 -0
  65. package/dist/src/Components/List/BulletList/ListItem.d.ts +7 -0
  66. package/dist/src/Components/List/List.d.ts +10 -0
  67. package/dist/src/Components/LoadingArea/LoadingArea.d.ts +12 -0
  68. package/dist/src/Components/LoadingCircle/LoadingCircle.d.ts +8 -0
  69. package/dist/src/Components/Menu/Menu.d.ts +16 -0
  70. package/dist/src/Components/Menu/useMenu.d.ts +3 -0
  71. package/dist/src/Components/RbmComponentProps.d.ts +31 -0
  72. package/dist/src/Components/SizeCalculator/SizeCalculator.d.ts +9 -0
  73. package/dist/src/Components/SpoilerList/Spoiler/Spoiler.d.ts +15 -0
  74. package/dist/src/Components/SpoilerList/SpoilerList.d.ts +15 -0
  75. package/dist/src/Components/SpoilerList/useSpoilerGroup.d.ts +12 -0
  76. package/dist/src/Components/TabBar/TabBar.d.ts +30 -0
  77. package/dist/src/Components/TabBar/TabBarButton.d.ts +9 -0
  78. package/dist/src/Components/Table/Table.d.ts +36 -0
  79. package/dist/src/Components/Text/Heading.d.ts +7 -0
  80. package/dist/src/Components/Text/Text.d.ts +26 -0
  81. package/dist/src/Components/Toast/Toast.d.ts +13 -0
  82. package/dist/src/Components/Toast/ToastContainer.d.ts +7 -0
  83. package/dist/src/Components/TopBar/MoreButton.d.ts +9 -0
  84. package/dist/src/Components/TopBar/TopBar.d.ts +25 -0
  85. package/dist/src/Components/TopBar/TopBarButton.d.ts +9 -0
  86. package/dist/src/StyleProvider.d.ts +2 -0
  87. package/dist/src/TypeHelpers.d.ts +4 -0
  88. package/dist/src/WindowContext/WindowContext.d.ts +3 -0
  89. package/dist/src/WrongChildError.d.ts +4 -0
  90. package/dist/src/helper/Characters.d.ts +5 -0
  91. package/dist/src/helper/DistributiveOmit.d.ts +1 -0
  92. package/dist/src/helper/EmptyProps.d.ts +1 -0
  93. package/dist/src/helper/memoComparator.d.ts +1 -0
  94. package/dist/src/helper/nonEmptyString.d.ts +1 -0
  95. package/dist/src/helper/withForwardRef.d.ts +7 -0
  96. package/dist/src/helper/withMemo.d.ts +3 -0
  97. package/dist/src/helper/withRenderBrowserOnly.d.ts +2 -0
  98. package/dist/src/helper/withRestrictedChildren.d.ts +6 -0
  99. package/package.json +92 -0
  100. package/react-bootstrap-mobile.scss +6 -0
  101. package/scripts/getPackageJson.js +25 -0
  102. package/src/Components/ActionSheet/ActionSheet.tsx +115 -0
  103. package/src/Components/ActionSheet/actionSheet.scss +153 -0
  104. package/src/Components/Card/Card.tsx +46 -0
  105. package/src/Components/Card/card.scss +76 -0
  106. package/src/Components/Clickable/Clickable.tsx +174 -0
  107. package/src/Components/Clickable/clickable.scss +3 -0
  108. package/src/Components/Dialog/AlertDialog.tsx +44 -0
  109. package/src/Components/Dialog/ButtonDialog.tsx +57 -0
  110. package/src/Components/Dialog/ConfirmDialog.tsx +46 -0
  111. package/src/Components/Dialog/Dialog.tsx +82 -0
  112. package/src/Components/Dialog/DialogBackground.tsx +38 -0
  113. package/src/Components/Dialog/DialogContainer.tsx +77 -0
  114. package/src/Components/Dialog/DialogContext.ts +21 -0
  115. package/src/Components/Dialog/buttonDialog.scss +114 -0
  116. package/src/Components/Dialog/dialog.scss +30 -0
  117. package/src/Components/Dialog/dialogBackground.scss +4 -0
  118. package/src/Components/Dialog/useAlertDialog.ts +13 -0
  119. package/src/Components/Dialog/useConfirmDialog.ts +13 -0
  120. package/src/Components/DragAndDrop/DragItem.tsx +38 -0
  121. package/src/Components/DragAndDrop/DropArea.tsx +43 -0
  122. package/src/Components/DragAndDrop/useStrictEnabled.ts +20 -0
  123. package/src/Components/FormElements/Button/Button.tsx +25 -0
  124. package/src/Components/FormElements/Button/button.scss +39 -0
  125. package/src/Components/FormElements/CheckBox/Checkbox.tsx +61 -0
  126. package/src/Components/FormElements/CheckBox/checkbox.scss +107 -0
  127. package/src/Components/FormElements/ColorInput/ColorInput.tsx +139 -0
  128. package/src/Components/FormElements/ColorInput/colorInput.scss +35 -0
  129. package/src/Components/FormElements/ColorInput/sharedSelectedColor.ts +40 -0
  130. package/src/Components/FormElements/ImageInput/ImageInput.tsx +97 -0
  131. package/src/Components/FormElements/ImageInput/imageInput.scss +24 -0
  132. package/src/Components/FormElements/Input/HiddenInput.tsx +43 -0
  133. package/src/Components/FormElements/Input/Input.tsx +102 -0
  134. package/src/Components/FormElements/Input/PasswordInput/PasswordInput.tsx +55 -0
  135. package/src/Components/FormElements/Input/PasswordInput/passwordInput.scss +7 -0
  136. package/src/Components/FormElements/Input/input.scss +57 -0
  137. package/src/Components/FormElements/SearchSelectInput/SearchSelectInput.tsx +162 -0
  138. package/src/Components/FormElements/SearchSelectInput/seachSelectInput.scss +90 -0
  139. package/src/Components/FormElements/Select/Select.tsx +77 -0
  140. package/src/Components/FormElements/Select/select.scss +51 -0
  141. package/src/Components/FormElements/Slider/Slider.tsx +80 -0
  142. package/src/Components/FormElements/Slider/slider.scss +92 -0
  143. package/src/Components/FormElements/Switch/Switch.tsx +82 -0
  144. package/src/Components/FormElements/Switch/switch.scss +149 -0
  145. package/src/Components/FormElements/Textarea/Textarea.tsx +77 -0
  146. package/src/Components/FormElements/Textarea/textarea.scss +22 -0
  147. package/src/Components/FormElements/hooks/useOnChangeDone.ts +16 -0
  148. package/src/Components/FullScreen/FullScreen.tsx +89 -0
  149. package/src/Components/Hooks/useBreakpoint.ts +66 -0
  150. package/src/Components/Hooks/useComposedRef.ts +17 -0
  151. package/src/Components/Hooks/useDebounced.ts +22 -0
  152. package/src/Components/Hooks/useDelayed.ts +46 -0
  153. package/src/Components/Hooks/useInViewport.ts +23 -0
  154. package/src/Components/Hooks/useKeyListener.ts +77 -0
  155. package/src/Components/Hooks/useListener.ts +73 -0
  156. package/src/Components/Hooks/useOnMount.ts +12 -0
  157. package/src/Components/Hooks/useOnce.ts +11 -0
  158. package/src/Components/Icon/Icon.tsx +45 -0
  159. package/src/Components/Image/Image.tsx +44 -0
  160. package/src/Components/Image/image.scss +3 -0
  161. package/src/Components/InViewport/InViewport.tsx +71 -0
  162. package/src/Components/InViewport/inViewport.scss +3 -0
  163. package/src/Components/Layout/Block.tsx +48 -0
  164. package/src/Components/Layout/Container.tsx +57 -0
  165. package/src/Components/Layout/Flex.tsx +51 -0
  166. package/src/Components/Layout/Grid/Grid.tsx +53 -0
  167. package/src/Components/Layout/Grid/GridItem.tsx +138 -0
  168. package/src/Components/Layout/Grid/grid.scss +43 -0
  169. package/src/Components/Layout/Grow.tsx +51 -0
  170. package/src/Components/Layout/Inline.tsx +48 -0
  171. package/src/Components/Layout/InlineBlock.tsx +48 -0
  172. package/src/Components/Layout/View.tsx +40 -0
  173. package/src/Components/Layout/ViewWithoutListeners.tsx +40 -0
  174. package/src/Components/Layout/container.scss +12 -0
  175. package/src/Components/Layout/layout.scss +56 -0
  176. package/src/Components/List/BulletList/BulletList.tsx +33 -0
  177. package/src/Components/List/BulletList/ListItem.tsx +34 -0
  178. package/src/Components/List/List.tsx +88 -0
  179. package/src/Components/List/list.scss +30 -0
  180. package/src/Components/LoadingArea/LoadingArea.tsx +64 -0
  181. package/src/Components/LoadingArea/loadingArea.scss +19 -0
  182. package/src/Components/LoadingCircle/LoadingCircle.tsx +41 -0
  183. package/src/Components/LoadingCircle/loadingCircle.scss +42 -0
  184. package/src/Components/Menu/Menu.tsx +113 -0
  185. package/src/Components/Menu/menu.scss +21 -0
  186. package/src/Components/Menu/useMenu.ts +20 -0
  187. package/src/Components/RbmComponentProps.ts +40 -0
  188. package/src/Components/SizeCalculator/SizeCalculator.tsx +45 -0
  189. package/src/Components/SpoilerList/Spoiler/Spoiler.tsx +106 -0
  190. package/src/Components/SpoilerList/Spoiler/spoiler.scss +120 -0
  191. package/src/Components/SpoilerList/SpoilerList.tsx +63 -0
  192. package/src/Components/SpoilerList/useSpoilerGroup.ts +39 -0
  193. package/src/Components/TabBar/TabBar.tsx +117 -0
  194. package/src/Components/TabBar/TabBarButton.tsx +44 -0
  195. package/src/Components/TabBar/tabBar.scss +108 -0
  196. package/src/Components/Table/Table.tsx +182 -0
  197. package/src/Components/Text/Heading.tsx +44 -0
  198. package/src/Components/Text/Text.tsx +79 -0
  199. package/src/Components/Text/heading.scss +3 -0
  200. package/src/Components/Text/text.scss +60 -0
  201. package/src/Components/Toast/Toast.tsx +107 -0
  202. package/src/Components/Toast/ToastContainer.tsx +35 -0
  203. package/src/Components/Toast/toast.scss +52 -0
  204. package/src/Components/TopBar/MoreButton.tsx +38 -0
  205. package/src/Components/TopBar/TopBar.tsx +176 -0
  206. package/src/Components/TopBar/TopBarButton.tsx +29 -0
  207. package/src/Components/TopBar/topBar.scss +124 -0
  208. package/src/StyleProvider.ts +4 -0
  209. package/src/TypeHelpers.ts +4 -0
  210. package/src/WindowContext/WindowContext.ts +8 -0
  211. package/src/WrongChildError.ts +19 -0
  212. package/src/env.d.ts +1 -0
  213. package/src/helper/Characters.ts +5 -0
  214. package/src/helper/DistributiveOmit.ts +1 -0
  215. package/src/helper/EmptyProps.ts +2 -0
  216. package/src/helper/memoComparator.ts +18 -0
  217. package/src/helper/nonEmptyString.ts +8 -0
  218. package/src/helper/withForwardRef.ts +28 -0
  219. package/src/helper/withMemo.ts +16 -0
  220. package/src/helper/withRenderBrowserOnly.tsx +30 -0
  221. package/src/helper/withRestrictedChildren.tsx +57 -0
  222. package/src/scss/_animations.scss +46 -0
  223. package/src/scss/_baseClasses.scss +27 -0
  224. package/src/scss/_colors.scss +13 -0
  225. package/src/scss/_default.scss +17 -0
  226. package/src/scss/_designMixin.scss +13 -0
  227. package/src/scss/_mobileMixin.scss +35 -0
  228. package/src/scss/_variables.scss +22 -0
  229. package/src/types/isomorphic-style-loader.d.ts +3 -0
  230. package/src/types/react-table-config.d.ts +120 -0
  231. package/src/types/scss-module.d.ts +7 -0
  232. package/tsconfig.json +57 -0
  233. package/webpack.config.js +85 -0
@@ -0,0 +1,139 @@
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
+
7
+ import styles from './colorInput.scss';
8
+ import { useSharedSelectedColor } from './sharedSelectedColor';
9
+
10
+ export type ColorInputProps<OnChangeData> = {
11
+ defaultValue?: string;
12
+ value?: string;
13
+ label?: string;
14
+ onChangeColor?: (newColor: string) => void;
15
+ onOpen?: (currentColor: string) => void;
16
+ onChangeColorComplete?: (newColor: string) => void;
17
+ onClose?: (newColor: string) => void;
18
+ disableAlpha?: boolean;
19
+ presetColors?: string[];
20
+ sharedColorKey?: string;
21
+ } & OptionalListener<'onChange', OnChangeData>;
22
+
23
+ function convertToHex(color: { r: number; g: number; b: number; a?: number }, disableAlpha?: boolean) {
24
+ let newColor = `#${color.r.toString(16).padStart(2, '0')}${color.g.toString(16).padStart(2, '0')}${color.b
25
+ .toString(16)
26
+ .padStart(2, '0')}`;
27
+ if (color.a !== undefined && !disableAlpha) {
28
+ newColor += Math.round(color.a * 255)
29
+ .toString(16)
30
+ .padStart(2, '0');
31
+ }
32
+ return newColor;
33
+ }
34
+
35
+ function ColorInput<OnChangeData>({
36
+ defaultValue,
37
+ value,
38
+ label,
39
+ onChangeColor,
40
+ onChangeColorComplete,
41
+ onOpen,
42
+ onClose,
43
+ disableAlpha,
44
+ presetColors,
45
+ sharedColorKey,
46
+ ...otherProps
47
+ }: ColorInputProps<OnChangeData>) {
48
+ // Variables
49
+ // useStyles(styles);
50
+
51
+ // Refs
52
+ const containerRef = useRef<HTMLDivElement>(null);
53
+
54
+ // States
55
+ const [color, setColor] = useState<string>(value ?? defaultValue ?? '#000000FF');
56
+ const [isOpen, setIsOpen] = useState(false);
57
+ const [position, setPosition] = useState({ x: 0, y: 0 });
58
+
59
+ const { colors, addColor } = useSharedSelectedColor(sharedColorKey);
60
+
61
+ const colVal: Color = value ?? color;
62
+ // Selectors
63
+
64
+ // Callbacks
65
+ const onChangeWithData = useListener<'onChange', OnChangeData>('onChange', otherProps);
66
+ const onChange = useCallback<ColorChangeHandler>(
67
+ (newColor: ColorResult, e) => {
68
+ const hexColor = convertToHex(newColor.rgb, disableAlpha);
69
+ setColor(hexColor);
70
+ if (onChangeColor) {
71
+ onChangeColor(hexColor);
72
+ }
73
+ onChangeWithData(e);
74
+ },
75
+ [disableAlpha, onChangeColor, onChangeWithData]
76
+ );
77
+ const onChangeComplete = useCallback(
78
+ (newColor: ColorResult) => {
79
+ const hexColor = convertToHex(newColor.rgb, disableAlpha);
80
+ setColor(hexColor);
81
+ if (onChangeColorComplete) {
82
+ onChangeColorComplete(hexColor);
83
+ }
84
+ },
85
+ [disableAlpha, onChangeColorComplete]
86
+ );
87
+
88
+ const onContainerClick = useCallback(
89
+ (e: MouseEvent) => {
90
+ if (e.target === containerRef?.current) {
91
+ setIsOpen(false);
92
+ console.log('onContainerClick', colVal);
93
+ addColor(colVal);
94
+ onClose?.(colVal);
95
+ }
96
+ },
97
+ [addColor, colVal, onClose]
98
+ );
99
+
100
+ const openElement = useCallback(
101
+ (e: MouseEvent) => {
102
+ setIsOpen(true);
103
+ setPosition({ x: e.clientX, y: e.clientY });
104
+ onOpen?.(colVal);
105
+ },
106
+ [colVal, onOpen]
107
+ );
108
+
109
+ // Effects
110
+
111
+ // Other
112
+
113
+ // Render Functions
114
+ return (
115
+ <span className={styles.colorInput}>
116
+ {isOpen ? (
117
+ <div onClick={onContainerClick} className={styles.modalContainer} ref={containerRef}>
118
+ <div className={styles.modal} style={{ top: position.y, left: position.x }}>
119
+ <SketchPicker
120
+ color={colVal}
121
+ onChange={onChange}
122
+ onChangeComplete={onChangeComplete}
123
+ disableAlpha={disableAlpha}
124
+ presetColors={presetColors ?? colors}
125
+ />
126
+ </div>
127
+ </div>
128
+ ) : null}
129
+ <span onClick={openElement} className={styles.label}>
130
+ {label}
131
+ </span>
132
+ <span onClick={openElement} style={{ backgroundColor: colVal }} className={styles.preview} />
133
+ </span>
134
+ );
135
+ }
136
+
137
+ // Need ColorInputMemo for autocompletion of phpstorm
138
+ const ColorInputMemo = withMemo(ColorInput, styles);
139
+ export { ColorInputMemo as ColorInput };
@@ -0,0 +1,35 @@
1
+ .colorInput {
2
+ margin-left: 0.5rem;
3
+ margin-right: 0.5rem;
4
+ display: flex;
5
+
6
+ .preview {
7
+ margin-left: 0.4rem;
8
+ width: 1rem;
9
+ height: 1rem;
10
+ display: inline-block;
11
+ border: 1px solid black;
12
+ }
13
+
14
+ .modalContainer {
15
+ z-index: 9999;
16
+ position: fixed;
17
+ top: 0;
18
+ left: 0;
19
+ right: 0;
20
+ bottom: 0;
21
+ width: 100vw;
22
+ height: 100vh;
23
+ overflow: auto;
24
+
25
+ .modal {
26
+ position: absolute;
27
+ background-color: white;
28
+ }
29
+ }
30
+
31
+ .label {
32
+ flex: 1;
33
+ margin-right: 0.2rem;
34
+ }
35
+ }
@@ -0,0 +1,40 @@
1
+ import { useCallback, useMemo, useRef, useState } from 'react';
2
+ import { Random } from '@ainias42/js-helper';
3
+
4
+ const sharedSelectedColor: Record<string, { colors: string[]; updateFunctions: (() => void)[] }> = {};
5
+
6
+ export function useSharedSelectedColor(key?: string, numberSavedColors = 15) {
7
+ const [, setVersion] = useState(1);
8
+ const innerKey = useRef(Random.getStringRandom(12));
9
+ const realKey = key ?? innerKey.current;
10
+
11
+ if (!sharedSelectedColor[realKey]) {
12
+ sharedSelectedColor[realKey] = {
13
+ colors: [],
14
+ updateFunctions: [],
15
+ };
16
+ }
17
+
18
+ const update = useCallback(() => setVersion((old) => old + 1), []);
19
+ useMemo(() => {
20
+ sharedSelectedColor[realKey].updateFunctions.push(update);
21
+ }, [realKey, update]);
22
+
23
+ const addColor = useCallback(
24
+ (newColor: string) => {
25
+ sharedSelectedColor[realKey].colors = sharedSelectedColor[realKey].colors.filter(
26
+ (color) => color !== newColor
27
+ );
28
+ sharedSelectedColor[realKey].colors.unshift(newColor);
29
+ if (sharedSelectedColor[realKey].colors.length > numberSavedColors) {
30
+ sharedSelectedColor[realKey].colors.splice(numberSavedColors, 1);
31
+ }
32
+
33
+ // triggers rerender
34
+ sharedSelectedColor[realKey].updateFunctions.forEach((u) => u());
35
+ },
36
+ [numberSavedColors, realKey]
37
+ );
38
+
39
+ return { colors: sharedSelectedColor[realKey]?.colors, addColor };
40
+ }
@@ -0,0 +1,97 @@
1
+ import * as React from 'react';
2
+ import { RbmComponentProps } from '../../RbmComponentProps';
3
+ import { Override } from '../../../TypeHelpers';
4
+ import { ChangeEventHandler, InputHTMLAttributes, useCallback, useState } from 'react';
5
+ import { OptionalListener, useListener } from '../../Hooks/useListener';
6
+ import { Button } from '../Button/Button';
7
+
8
+ import styles from './imageInput.scss';
9
+ import { withMemo } from '../../../helper/withMemo';
10
+ import classNames from 'classnames';
11
+
12
+ export type ImageType = { name: string; url: string };
13
+
14
+ export type ImageInputProps<OnChangeData> = RbmComponentProps<
15
+ Override<
16
+ InputHTMLAttributes<HTMLInputElement>,
17
+ {
18
+ defaultValue?: ImageType;
19
+ value?: ImageType;
20
+ label?: string;
21
+ onChangeImage?: (image: ImageType, imageData: File) => void;
22
+ } & OptionalListener<'onChange', OnChangeData>
23
+ >
24
+ >;
25
+
26
+ function ImageInput<OnChangeData>({
27
+ className,
28
+ style,
29
+ value,
30
+ defaultValue,
31
+ onChangeImage,
32
+ label,
33
+ ...otherProps
34
+ }: ImageInputProps<OnChangeData>) {
35
+ // Variables
36
+ const [image, setImage] = useState(defaultValue);
37
+
38
+ // Refs
39
+
40
+ // States
41
+
42
+ // Selectors
43
+
44
+ // Callbacks
45
+ const onChangeWithData = useListener<'onChange', OnChangeData>('onChange', otherProps);
46
+ const getBase64 = useCallback((file: Blob) => {
47
+ return new Promise<string>((resolve, reject) => {
48
+ const reader = new FileReader();
49
+ reader.onload = () => {
50
+ resolve(reader.result as string);
51
+ };
52
+ reader.onerror = reject;
53
+ reader.readAsDataURL(file);
54
+ });
55
+ }, []);
56
+ const onChange = useCallback<ChangeEventHandler<HTMLInputElement>>(
57
+ async (e) => {
58
+ if (!e.target.files || e.target.files.length === 0) {
59
+ return;
60
+ }
61
+
62
+ onChangeWithData(e);
63
+ const newUrl = await getBase64(e.target.files[0]);
64
+ const newValue = { name: e.target.files[0].name, url: newUrl };
65
+ setImage(newValue);
66
+
67
+ if (onChangeImage) {
68
+ onChangeImage(newValue, e.target.files[0]);
69
+ }
70
+ },
71
+ [onChangeWithData, onChangeImage, getBase64]
72
+ );
73
+
74
+ // Effects
75
+
76
+ // Other
77
+
78
+ // Render Functions
79
+
80
+ return (
81
+ // eslint-disable-next-line jsx-a11y/label-has-associated-control
82
+ <label className={classNames(styles.imageInput, className)} style={style}>
83
+ {label ? <span>{label}</span> : null}
84
+ <img
85
+ src={(value ?? image)?.url}
86
+ alt={(value ?? image)?.name}
87
+ className={classNames(styles.preview, (value ?? image)?.url ? undefined : styles.empty)}
88
+ />
89
+ <Button __allowChildren="all">{(value ?? image)?.name ?? <i>Select Image</i>}</Button>
90
+ <input {...otherProps} className={styles.value} onChange={onChange} type="file" />
91
+ </label>
92
+ );
93
+ }
94
+
95
+ // Need ImageInputMemo for autocompletion of phpstorm
96
+ const ImageInputMemo = withMemo(ImageInput, styles);
97
+ export { ImageInputMemo as ImageInput };
@@ -0,0 +1,24 @@
1
+ .imageInput {
2
+ display: flex;
3
+ flex-direction: column;
4
+ position: relative;
5
+ cursor: pointer;
6
+
7
+ .preview {
8
+ flex: 1;
9
+ object-fit: contain;
10
+
11
+ &.empty {
12
+ background-color: #d3d3d3;
13
+ }
14
+ }
15
+
16
+ .value {
17
+ position: absolute;
18
+ top: 0;
19
+ left: 0;
20
+ right: 0;
21
+ bottom: 0;
22
+ opacity: 0;
23
+ }
24
+ }
@@ -0,0 +1,43 @@
1
+ import * as React from 'react';
2
+ import { Input, InputProps } from './Input';
3
+ import { withMemo } from '../../../helper/withMemo';
4
+
5
+ import styles from './input.scss';
6
+ import classNames from 'classnames';
7
+
8
+ export type HiddenInputProps<OnChangeType, OnBlurData, OnChangeEndData> = InputProps<
9
+ OnChangeType,
10
+ OnBlurData,
11
+ OnChangeEndData
12
+ > & {
13
+ noFocusHint?: boolean;
14
+ };
15
+
16
+ function HiddenInput<OnChangeData, OnBlurData, OnChangeEndData>({
17
+ noFocusHint = false,
18
+ className,
19
+ ...props
20
+ }: HiddenInputProps<OnChangeData, OnBlurData, OnChangeEndData>) {
21
+ // Variables
22
+
23
+ // States
24
+
25
+ // Refs
26
+
27
+ // Callbacks
28
+
29
+ // Effects
30
+
31
+ // Other
32
+
33
+ // Render Functions
34
+ return (
35
+ <Input
36
+ className={classNames(styles.hiddenInput, { [styles.noFocusHint]: noFocusHint }, className)}
37
+ {...props}
38
+ />
39
+ );
40
+ }
41
+
42
+ const tmp = withMemo(HiddenInput);
43
+ export { tmp as HiddenInput };
@@ -0,0 +1,102 @@
1
+ import * as React from 'react';
2
+ import { ChangeEventHandler, InputHTMLAttributes, KeyboardEvent, MutableRefObject, useCallback } from 'react';
3
+ import { RbmComponentProps } from '../../RbmComponentProps';
4
+ import { Override } from '../../../TypeHelpers';
5
+ import { OptionalListener, useListenerWithExtractedProps } from '../../Hooks/useListener';
6
+ import { withForwardRef } from '../../../helper/withForwardRef';
7
+
8
+ import styles from './input.scss';
9
+ import classNames from 'classnames';
10
+ import { useComposedRef } from '../../Hooks/useComposedRef';
11
+ import { useOnChangeDone } from '../hooks/useOnChangeDone';
12
+
13
+ export type InputProps<OnChangeData, OnBlurData, OnChangeDoneData> = RbmComponentProps<
14
+ Override<
15
+ Omit<InputHTMLAttributes<HTMLInputElement>, 'onInput'>,
16
+ {
17
+ label?: string;
18
+ onChangeText?: (newText: string) => void;
19
+ onEnter?: (newText: string) => void;
20
+ } & OptionalListener<'onChange', OnChangeData> &
21
+ OptionalListener<'onBlur', OnBlurData> &
22
+ OptionalListener<'onChangeDone', OnChangeDoneData>
23
+ >
24
+ >;
25
+
26
+ export const Input = withForwardRef(function Input<OnChangeData, OnBlurData, OnChangeDoneData>(
27
+ {
28
+ label,
29
+ className,
30
+ style,
31
+ onEnter,
32
+ onKeyDown,
33
+ onChangeText,
34
+ ...otherProps
35
+ }: InputProps<OnChangeData, OnBlurData, OnChangeDoneData>,
36
+ ref: MutableRefObject<HTMLInputElement> | null
37
+ ) {
38
+ // Variables
39
+
40
+ // States
41
+
42
+ // Refs
43
+ const innerRef = useComposedRef(ref);
44
+
45
+ // Callbacks
46
+ const [onChangeWithData, otherPropsWithoutOnchange] = useListenerWithExtractedProps<'onChange', OnChangeData>(
47
+ 'onChange',
48
+ otherProps
49
+ );
50
+ const onChange = useCallback<ChangeEventHandler<HTMLInputElement>>(
51
+ (e) => {
52
+ if (onChangeText) {
53
+ onChangeText(e.target.value);
54
+ }
55
+ onChangeWithData(e);
56
+ },
57
+ [onChangeWithData, onChangeText]
58
+ );
59
+
60
+ const [onBlur, otherPropsWithoutBlur] = useListenerWithExtractedProps<'onBlur', OnBlurData>(
61
+ 'onBlur',
62
+ otherPropsWithoutOnchange
63
+ );
64
+
65
+ const [onChangeDone, otherPropsWithoutData] = useListenerWithExtractedProps<'onChangeDone', OnChangeDoneData>(
66
+ 'onChangeDone',
67
+ otherPropsWithoutBlur
68
+ );
69
+
70
+ const realOnKeyDown = useCallback(
71
+ (e: KeyboardEvent<HTMLInputElement>) => {
72
+ onKeyDown?.(e);
73
+ if (onEnter && e.key === 'Enter' && !e.defaultPrevented) {
74
+ onEnter((e.target as HTMLInputElement).value);
75
+ }
76
+ },
77
+ [onEnter, onKeyDown]
78
+ );
79
+
80
+ // Effects
81
+ useOnChangeDone(onChangeDone, innerRef);
82
+
83
+ // Other
84
+
85
+ // Render Functions
86
+
87
+ return (
88
+ // eslint-disable-next-line jsx-a11y/label-has-associated-control
89
+ <label className={classNames(styles.input, className)} style={style}>
90
+ {label ? <span className={styles.label}>{label}</span> : null}
91
+ <input
92
+ {...otherPropsWithoutData}
93
+ ref={innerRef}
94
+ className={styles.text}
95
+ onBlur={onBlur}
96
+ onChange={onChange}
97
+ onKeyDown={realOnKeyDown}
98
+ />
99
+ </label>
100
+ );
101
+ },
102
+ styles);
@@ -0,0 +1,55 @@
1
+ import React, { ForwardedRef, useCallback, useState } from 'react';
2
+ import { Input, InputProps } from '../Input';
3
+ import { DistributiveOmit } from '../../../../helper/DistributiveOmit';
4
+ import { withForwardRef } from '../../../../helper/withForwardRef';
5
+ import { Flex } from '../../../Layout/Flex';
6
+ import { Grow } from '../../../Layout/Grow';
7
+ import { Icon } from '../../../Icon/Icon';
8
+ import { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
9
+ import { Clickable } from '../../../Clickable/Clickable';
10
+
11
+ import styles from './passwordInput.scss';
12
+ import classNames from 'classnames';
13
+
14
+ export type PasswordInputProps<OnChangeData, OnBlurData, OnChangeEndData> = DistributiveOmit<
15
+ InputProps<OnChangeData, OnBlurData, OnChangeEndData>,
16
+ 'type'
17
+ >;
18
+
19
+ export const PasswordInput = withForwardRef(function PasswordInput<OnChangeData, OnBlurData, OnChangeEndData>(
20
+ { className, style, ...props }: PasswordInputProps<OnChangeData, OnBlurData, OnChangeEndData>,
21
+ ref: ForwardedRef<HTMLInputElement>
22
+ ) {
23
+ // Variables
24
+ const [isVisible, setIsVisible] = useState(false);
25
+
26
+ // Refs
27
+
28
+ // States
29
+
30
+ // Selectors
31
+
32
+ // Callbacks
33
+ const toggleVisible = useCallback(() => setIsVisible((old) => !old), []);
34
+
35
+ // Effects
36
+
37
+ // Other
38
+
39
+ // Render Functions
40
+ return (
41
+ <Flex horizontal={true} className={classNames(styles.passwordInput, className)} style={style}>
42
+ <Grow>
43
+ <Input {...props} type={isVisible ? 'text' : 'password'} ref={ref} />
44
+ </Grow>
45
+ <Clickable onClick={toggleVisible} className={styles.showButton}>
46
+ <Icon icon={isVisible ? faEye : faEyeSlash} />
47
+ </Clickable>
48
+ </Flex>
49
+ );
50
+ },
51
+ styles);
52
+
53
+ // // Need PasswordInputMemo for autocompletion of phpstorm
54
+ // const PasswordInputMemo = withMemo(PasswordInput);
55
+ // export { PasswordInputMemo as PasswordInput };
@@ -0,0 +1,7 @@
1
+ .passwordInput {
2
+ align-items: end;
3
+ }
4
+
5
+ .showButton {
6
+ padding-left: 0.4rem;
7
+ }
@@ -0,0 +1,57 @@
1
+ @import "../../../scss/variables";
2
+ @import "../../../scss/designMixin";
3
+
4
+ .input {
5
+ width: 100%;
6
+
7
+ .label {
8
+ display: block;
9
+ font-weight: bold;
10
+ }
11
+
12
+ .text {
13
+ width: 100%;
14
+ background-color: transparent;
15
+ border: 0;
16
+ outline: none;
17
+ padding: 0;
18
+ font-size: 1rem;
19
+
20
+ @include design($material) {
21
+ color: #212121;
22
+ background-image: linear-gradient(to top, transparent 1px, #afafaf 1px);
23
+ background-size: 100% 2px;
24
+ background-repeat: no-repeat;
25
+ background-position: center bottom;
26
+ padding-bottom: 2px;
27
+
28
+ &:focus {
29
+ background-image: linear-gradient(var(--flavor-focus), var(--flavor-focus)),
30
+ linear-gradient(to top, transparent 1px, #afafaf 1px);
31
+ }
32
+ }
33
+
34
+ @include design($flat) {
35
+ color: #1f1f21;
36
+ &, &:focus {
37
+ border-bottom: 1px solid var(--border-light);
38
+ }
39
+ }
40
+ }
41
+
42
+ &.hiddenInput {
43
+ .text {
44
+ background-image: none;
45
+ border-bottom: 1px solid transparent;
46
+ }
47
+
48
+ &.noFocusHint {
49
+ .text {
50
+ &:focus {
51
+ background-image: none;
52
+ border-bottom: 1px solid transparent;
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }