@onewelcome/react-lib-components 8.5.0 → 8.6.0

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 (208) hide show
  1. package/dist/cjs/Form/Checkbox/Checkbox.cjs.js +1 -1
  2. package/dist/cjs/Form/Checkbox/Checkbox.cjs.js.map +1 -1
  3. package/dist/cjs/Form/Checkbox/Checkbox.module.scss.cjs.js +1 -1
  4. package/dist/cjs/Form/Fieldset/Fieldset.cjs.js +1 -1
  5. package/dist/cjs/Form/Fieldset/Fieldset.cjs.js.map +1 -1
  6. package/dist/cjs/Form/FileUpload/FileItem/FileItem.cjs.js +1 -1
  7. package/dist/cjs/Form/FileUpload/FileItem/FileItem.cjs.js.map +1 -1
  8. package/dist/cjs/Form/FileUpload/FileItem/FileItem.module.scss.cjs.js +1 -1
  9. package/dist/cjs/Form/FileUpload/FileUpload.cjs.js +1 -1
  10. package/dist/cjs/Form/FileUpload/FileUpload.cjs.js.map +1 -1
  11. package/dist/cjs/Form/FileUpload/FileUpload.module.scss.cjs.js +1 -1
  12. package/dist/cjs/Form/FormHelperText/FormHelperText.module.scss.cjs.js +1 -1
  13. package/dist/cjs/Form/Input/Input.cjs.js +1 -1
  14. package/dist/cjs/Form/Input/Input.cjs.js.map +1 -1
  15. package/dist/cjs/Form/Input/Input.module.scss.cjs.js +1 -1
  16. package/dist/cjs/Form/Radio/Radio.cjs.js +1 -1
  17. package/dist/cjs/Form/Radio/Radio.cjs.js.map +1 -1
  18. package/dist/cjs/Form/Radio/Radio.module.scss.cjs.js +1 -1
  19. package/dist/cjs/Form/Select/MultiSelect/MultiSelect.cjs.js +1 -1
  20. package/dist/cjs/Form/Select/MultiSelect/MultiSelect.cjs.js.map +1 -1
  21. package/dist/cjs/Form/Select/MultiSelect/MultiSelect.module.scss.cjs.js +1 -1
  22. package/dist/cjs/Form/Select/MultiSelect/SelectedOptions.module.scss.cjs.js +1 -1
  23. package/dist/cjs/Form/Select/MultiSelect/useArrowNavigation.cjs.js +1 -1
  24. package/dist/cjs/Form/Select/MultiSelect/useArrowNavigation.cjs.js.map +1 -1
  25. package/dist/cjs/Form/Select/MultiSelect/useMultiSelect.cjs.js +2 -0
  26. package/dist/cjs/Form/Select/MultiSelect/useMultiSelect.cjs.js.map +1 -0
  27. package/dist/cjs/Form/Select/Select.interfaces.cjs.js +2 -0
  28. package/dist/cjs/Form/Select/Select.interfaces.cjs.js.map +1 -0
  29. package/dist/cjs/Form/Select/SingleSelect/Select.cjs.js +1 -1
  30. package/dist/cjs/Form/Select/SingleSelect/Select.cjs.js.map +1 -1
  31. package/dist/cjs/Form/Select/SingleSelect/Select.module.scss.cjs.js +1 -1
  32. package/dist/cjs/Form/Select/SingleSelect/useArrowNavigation.cjs.js +1 -1
  33. package/dist/cjs/Form/Select/SingleSelect/useArrowNavigation.cjs.js.map +1 -1
  34. package/dist/cjs/Form/Select/useSelectPositionList.cjs.js +1 -1
  35. package/dist/cjs/Form/Select/useSelectPositionList.cjs.js.map +1 -1
  36. package/dist/cjs/Form/Textarea/Textarea.cjs.js +1 -1
  37. package/dist/cjs/Form/Textarea/Textarea.cjs.js.map +1 -1
  38. package/dist/cjs/Form/Textarea/Textarea.module.scss.cjs.js +1 -1
  39. package/dist/cjs/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.cjs.js +1 -1
  40. package/dist/cjs/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.cjs.js.map +1 -1
  41. package/dist/cjs/Form/Wrapper/InputWrapper/InputWrapper.cjs.js +1 -1
  42. package/dist/cjs/Form/Wrapper/InputWrapper/InputWrapper.cjs.js.map +1 -1
  43. package/dist/cjs/Form/Wrapper/InputWrapper/InputWrapper.module.scss.cjs.js +1 -1
  44. package/dist/cjs/Form/Wrapper/MultiSelectWrapper/MultiSelectWrapper.cjs.js +1 -1
  45. package/dist/cjs/Form/Wrapper/MultiSelectWrapper/MultiSelectWrapper.cjs.js.map +1 -1
  46. package/dist/cjs/Form/Wrapper/RadioWrapper/RadioWrapper.cjs.js +1 -1
  47. package/dist/cjs/Form/Wrapper/RadioWrapper/RadioWrapper.cjs.js.map +1 -1
  48. package/dist/cjs/Form/Wrapper/SelectWrapper/SelectWrapper.cjs.js +1 -1
  49. package/dist/cjs/Form/Wrapper/SelectWrapper/SelectWrapper.cjs.js.map +1 -1
  50. package/dist/cjs/Form/Wrapper/TextareaWrapper/TextareaWrapper.cjs.js +1 -1
  51. package/dist/cjs/Form/Wrapper/TextareaWrapper/TextareaWrapper.cjs.js.map +1 -1
  52. package/dist/cjs/Form/Wrapper/TextareaWrapper/TextareaWrapper.module.scss.cjs.js +1 -1
  53. package/dist/cjs/Form/Wrapper/Wrapper/Wrapper.module.scss.cjs.js +1 -1
  54. package/dist/cjs/_BaseStyling_/BaseStyling.cjs.js +1 -1
  55. package/dist/cjs/_BaseStyling_/BaseStyling.cjs.js.map +1 -1
  56. package/dist/cjs/src/components/Form/Checkbox/Checkbox.d.ts +1 -1
  57. package/dist/cjs/src/components/Form/Fieldset/Fieldset.d.ts +1 -1
  58. package/dist/cjs/src/components/Form/FileUpload/FileItem/FileItem.d.ts +1 -1
  59. package/dist/cjs/src/components/Form/FileUpload/FileUpload.d.ts +6 -1
  60. package/dist/cjs/src/components/Form/Input/Input.d.ts +2 -1
  61. package/dist/cjs/src/components/Form/Radio/Radio.d.ts +1 -1
  62. package/dist/cjs/src/components/Form/Select/MultiSelect/MultiSelect.d.ts +1 -1
  63. package/dist/cjs/src/components/Form/Select/MultiSelect/useArrowNavigation.d.ts +2 -1
  64. package/dist/cjs/src/components/Form/Select/MultiSelect/useMultiSelect.d.ts +16 -0
  65. package/dist/cjs/src/components/Form/Select/MultiSelect/useMultiSelect.test.d.ts +1 -0
  66. package/dist/cjs/src/components/Form/Select/Select.interfaces.d.ts +6 -4
  67. package/dist/cjs/src/components/Form/Select/SingleSelect/Select.d.ts +1 -1
  68. package/dist/cjs/src/components/Form/Select/SingleSelect/useArrowNavigation.d.ts +1 -1
  69. package/dist/cjs/src/components/Form/Select/useSelectPositionList.d.ts +2 -2
  70. package/dist/cjs/src/components/Form/Textarea/Textarea.d.ts +2 -1
  71. package/dist/cjs/src/components/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.d.ts +1 -1
  72. package/dist/cjs/src/components/Form/Wrapper/InputWrapper/InputWrapper.d.ts +1 -1
  73. package/dist/cjs/src/components/Form/Wrapper/MultiSelectWrapper/MultiSelectWrapper.d.ts +1 -1
  74. package/dist/cjs/src/components/Form/Wrapper/RadioWrapper/RadioWrapper.d.ts +1 -1
  75. package/dist/cjs/src/components/Form/Wrapper/SelectWrapper/SelectWrapper.d.ts +1 -1
  76. package/dist/cjs/src/components/Form/Wrapper/TextareaWrapper/TextareaWrapper.d.ts +2 -1
  77. package/dist/cjs/src/components/_BaseStyling_/BaseStyling.d.ts +2 -0
  78. package/dist/cjs/src/components/withReadOnly.d.ts +8 -0
  79. package/dist/cjs/src/components/withReadOnly.test.d.ts +1 -0
  80. package/dist/cjs/src/index.cjs.js +1 -1
  81. package/dist/cjs/src/index.d.ts +1 -0
  82. package/dist/cjs/src/util/unitTestUtils.d.ts +12 -0
  83. package/dist/cjs/withReadOnly.cjs.js +2 -0
  84. package/dist/cjs/withReadOnly.cjs.js.map +1 -0
  85. package/dist/esm/Form/Checkbox/Checkbox.esm.js +2 -1
  86. package/dist/esm/Form/Checkbox/Checkbox.esm.js.map +1 -1
  87. package/dist/esm/Form/Checkbox/Checkbox.module.scss.esm.js +1 -1
  88. package/dist/esm/Form/Fieldset/Fieldset.esm.js +2 -1
  89. package/dist/esm/Form/Fieldset/Fieldset.esm.js.map +1 -1
  90. package/dist/esm/Form/FileUpload/FileItem/FileItem.esm.js +10 -3
  91. package/dist/esm/Form/FileUpload/FileItem/FileItem.esm.js.map +1 -1
  92. package/dist/esm/Form/FileUpload/FileItem/FileItem.module.scss.esm.js +1 -1
  93. package/dist/esm/Form/FileUpload/FileUpload.esm.js +9 -6
  94. package/dist/esm/Form/FileUpload/FileUpload.esm.js.map +1 -1
  95. package/dist/esm/Form/FileUpload/FileUpload.module.scss.esm.js +2 -2
  96. package/dist/esm/Form/FormHelperText/FormHelperText.module.scss.esm.js +1 -1
  97. package/dist/esm/Form/Input/Input.esm.js +7 -5
  98. package/dist/esm/Form/Input/Input.esm.js.map +1 -1
  99. package/dist/esm/Form/Input/Input.module.scss.esm.js +2 -2
  100. package/dist/esm/Form/Radio/Radio.esm.js +2 -1
  101. package/dist/esm/Form/Radio/Radio.esm.js.map +1 -1
  102. package/dist/esm/Form/Radio/Radio.module.scss.esm.js +1 -1
  103. package/dist/esm/Form/Select/MultiSelect/MultiSelect.esm.js +24 -13
  104. package/dist/esm/Form/Select/MultiSelect/MultiSelect.esm.js.map +1 -1
  105. package/dist/esm/Form/Select/MultiSelect/MultiSelect.module.scss.esm.js +2 -2
  106. package/dist/esm/Form/Select/MultiSelect/SelectedOptions.module.scss.esm.js +1 -1
  107. package/dist/esm/Form/Select/MultiSelect/useArrowNavigation.esm.js +4 -1
  108. package/dist/esm/Form/Select/MultiSelect/useArrowNavigation.esm.js.map +1 -1
  109. package/dist/esm/Form/Select/MultiSelect/useMultiSelect.esm.js +63 -0
  110. package/dist/esm/Form/Select/MultiSelect/useMultiSelect.esm.js.map +1 -0
  111. package/dist/esm/Form/Select/Select.interfaces.esm.js +23 -0
  112. package/dist/esm/Form/Select/Select.interfaces.esm.js.map +1 -0
  113. package/dist/esm/Form/Select/SingleSelect/Select.esm.js +20 -15
  114. package/dist/esm/Form/Select/SingleSelect/Select.esm.js.map +1 -1
  115. package/dist/esm/Form/Select/SingleSelect/Select.module.scss.esm.js +2 -2
  116. package/dist/esm/Form/Select/SingleSelect/useArrowNavigation.esm.js +4 -1
  117. package/dist/esm/Form/Select/SingleSelect/useArrowNavigation.esm.js.map +1 -1
  118. package/dist/esm/Form/Select/useSelectPositionList.esm.js +5 -4
  119. package/dist/esm/Form/Select/useSelectPositionList.esm.js.map +1 -1
  120. package/dist/esm/Form/Textarea/Textarea.esm.js +12 -5
  121. package/dist/esm/Form/Textarea/Textarea.esm.js.map +1 -1
  122. package/dist/esm/Form/Textarea/Textarea.module.scss.esm.js +1 -1
  123. package/dist/esm/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.esm.js +4 -1
  124. package/dist/esm/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.esm.js.map +1 -1
  125. package/dist/esm/Form/Wrapper/InputWrapper/InputWrapper.esm.js +4 -2
  126. package/dist/esm/Form/Wrapper/InputWrapper/InputWrapper.esm.js.map +1 -1
  127. package/dist/esm/Form/Wrapper/InputWrapper/InputWrapper.module.scss.esm.js +1 -1
  128. package/dist/esm/Form/Wrapper/MultiSelectWrapper/MultiSelectWrapper.esm.js +3 -2
  129. package/dist/esm/Form/Wrapper/MultiSelectWrapper/MultiSelectWrapper.esm.js.map +1 -1
  130. package/dist/esm/Form/Wrapper/RadioWrapper/RadioWrapper.esm.js +17 -10
  131. package/dist/esm/Form/Wrapper/RadioWrapper/RadioWrapper.esm.js.map +1 -1
  132. package/dist/esm/Form/Wrapper/SelectWrapper/SelectWrapper.esm.js +5 -2
  133. package/dist/esm/Form/Wrapper/SelectWrapper/SelectWrapper.esm.js.map +1 -1
  134. package/dist/esm/Form/Wrapper/TextareaWrapper/TextareaWrapper.esm.js +20 -10
  135. package/dist/esm/Form/Wrapper/TextareaWrapper/TextareaWrapper.esm.js.map +1 -1
  136. package/dist/esm/Form/Wrapper/TextareaWrapper/TextareaWrapper.module.scss.esm.js +2 -2
  137. package/dist/esm/Form/Wrapper/Wrapper/Wrapper.module.scss.esm.js +1 -1
  138. package/dist/esm/_BaseStyling_/BaseStyling.esm.js +2 -0
  139. package/dist/esm/_BaseStyling_/BaseStyling.esm.js.map +1 -1
  140. package/dist/esm/src/components/Form/Checkbox/Checkbox.d.ts +1 -1
  141. package/dist/esm/src/components/Form/Fieldset/Fieldset.d.ts +1 -1
  142. package/dist/esm/src/components/Form/FileUpload/FileItem/FileItem.d.ts +1 -1
  143. package/dist/esm/src/components/Form/FileUpload/FileUpload.d.ts +6 -1
  144. package/dist/esm/src/components/Form/Input/Input.d.ts +2 -1
  145. package/dist/esm/src/components/Form/Radio/Radio.d.ts +1 -1
  146. package/dist/esm/src/components/Form/Select/MultiSelect/MultiSelect.d.ts +1 -1
  147. package/dist/esm/src/components/Form/Select/MultiSelect/useArrowNavigation.d.ts +2 -1
  148. package/dist/esm/src/components/Form/Select/MultiSelect/useMultiSelect.d.ts +16 -0
  149. package/dist/esm/src/components/Form/Select/MultiSelect/useMultiSelect.test.d.ts +1 -0
  150. package/dist/esm/src/components/Form/Select/Select.interfaces.d.ts +6 -4
  151. package/dist/esm/src/components/Form/Select/SingleSelect/Select.d.ts +1 -1
  152. package/dist/esm/src/components/Form/Select/SingleSelect/useArrowNavigation.d.ts +1 -1
  153. package/dist/esm/src/components/Form/Select/useSelectPositionList.d.ts +2 -2
  154. package/dist/esm/src/components/Form/Textarea/Textarea.d.ts +2 -1
  155. package/dist/esm/src/components/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.d.ts +1 -1
  156. package/dist/esm/src/components/Form/Wrapper/InputWrapper/InputWrapper.d.ts +1 -1
  157. package/dist/esm/src/components/Form/Wrapper/MultiSelectWrapper/MultiSelectWrapper.d.ts +1 -1
  158. package/dist/esm/src/components/Form/Wrapper/RadioWrapper/RadioWrapper.d.ts +1 -1
  159. package/dist/esm/src/components/Form/Wrapper/SelectWrapper/SelectWrapper.d.ts +1 -1
  160. package/dist/esm/src/components/Form/Wrapper/TextareaWrapper/TextareaWrapper.d.ts +2 -1
  161. package/dist/esm/src/components/_BaseStyling_/BaseStyling.d.ts +2 -0
  162. package/dist/esm/src/components/withReadOnly.d.ts +8 -0
  163. package/dist/esm/src/components/withReadOnly.test.d.ts +1 -0
  164. package/dist/esm/src/index.d.ts +1 -0
  165. package/dist/esm/src/index.esm.js +1 -0
  166. package/dist/esm/src/index.esm.js.map +1 -1
  167. package/dist/esm/src/util/unitTestUtils.d.ts +12 -0
  168. package/dist/esm/withReadOnly.esm.js +70 -0
  169. package/dist/esm/withReadOnly.esm.js.map +1 -0
  170. package/package.json +15 -15
  171. package/src/components/Form/Checkbox/Checkbox.module.scss +70 -0
  172. package/src/components/Form/Checkbox/Checkbox.tsx +2 -1
  173. package/src/components/Form/Fieldset/Fieldset.tsx +2 -1
  174. package/src/components/Form/FileUpload/FileItem/FileItem.module.scss +16 -0
  175. package/src/components/Form/FileUpload/FileItem/FileItem.tsx +17 -3
  176. package/src/components/Form/FileUpload/FileUpload.module.scss +57 -1
  177. package/src/components/Form/FileUpload/FileUpload.tsx +16 -6
  178. package/src/components/Form/FormHelperText/FormHelperText.module.scss +4 -0
  179. package/src/components/Form/Input/Input.module.scss +26 -0
  180. package/src/components/Form/Input/Input.tsx +10 -1
  181. package/src/components/Form/Radio/Radio.module.scss +46 -0
  182. package/src/components/Form/Radio/Radio.tsx +2 -1
  183. package/src/components/Form/Select/MultiSelect/MultiSelect.module.scss +35 -1
  184. package/src/components/Form/Select/MultiSelect/MultiSelect.tsx +41 -26
  185. package/src/components/Form/Select/MultiSelect/SelectedOptions.module.scss +8 -0
  186. package/src/components/Form/Select/MultiSelect/useArrowNavigation.ts +6 -1
  187. package/src/components/Form/Select/MultiSelect/useMultiSelect.tsx +98 -0
  188. package/src/components/Form/Select/Select.interfaces.ts +6 -4
  189. package/src/components/Form/Select/SingleSelect/Select.module.scss +60 -1
  190. package/src/components/Form/Select/SingleSelect/Select.tsx +30 -25
  191. package/src/components/Form/Select/SingleSelect/useArrowNavigation.ts +6 -1
  192. package/src/components/Form/Select/useSelectPositionList.ts +4 -4
  193. package/src/components/Form/Textarea/Textarea.module.scss +24 -0
  194. package/src/components/Form/Textarea/Textarea.tsx +24 -3
  195. package/src/components/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.tsx +4 -1
  196. package/src/components/Form/Wrapper/InputWrapper/InputWrapper.module.scss +14 -0
  197. package/src/components/Form/Wrapper/InputWrapper/InputWrapper.tsx +4 -2
  198. package/src/components/Form/Wrapper/MultiSelectWrapper/MultiSelectWrapper.tsx +3 -1
  199. package/src/components/Form/Wrapper/RadioWrapper/RadioWrapper.tsx +17 -12
  200. package/src/components/Form/Wrapper/SelectWrapper/SelectWrapper.tsx +6 -1
  201. package/src/components/Form/Wrapper/TextareaWrapper/TextareaWrapper.module.scss +43 -0
  202. package/src/components/Form/Wrapper/TextareaWrapper/TextareaWrapper.tsx +45 -20
  203. package/src/components/Form/Wrapper/Wrapper/Wrapper.module.scss +6 -0
  204. package/src/components/_BaseStyling_/BaseStyling.tsx +4 -0
  205. package/src/components/withReadOnly.tsx +112 -0
  206. package/src/index.ts +1 -0
  207. package/src/mixins.module.scss +6 -0
  208. package/src/util/unitTestUtils.ts +32 -0
@@ -0,0 +1,98 @@
1
+ /*
2
+ * Copyright 2022 OneWelcome B.V.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import React from "react";
18
+ import { MultiOption } from "./MultiOption";
19
+
20
+ export interface UseMultiSelectArgs {
21
+ initialOptions?: string[];
22
+ allOptions?: string[];
23
+ setAllOptions?: (options: string[]) => void;
24
+ pickedOptions: string[];
25
+ setPickedOptions: (options: string[]) => void;
26
+ onAddNew?: (newOption: string) => void;
27
+ }
28
+
29
+ export interface UseMultiSelectResult {
30
+ handleOptionChange: (e: React.ChangeEvent<HTMLSelectElement>) => void;
31
+ onAddNew: (newValue: string) => void;
32
+ optionElements: React.JSX.Element[];
33
+ }
34
+
35
+ export type UseMultiSelect = (args: UseMultiSelectArgs) => UseMultiSelectResult;
36
+
37
+ export const useMultiSelect: UseMultiSelect = ({
38
+ initialOptions,
39
+ pickedOptions,
40
+ allOptions = pickedOptions,
41
+ setPickedOptions,
42
+ setAllOptions = setPickedOptions,
43
+ onAddNew
44
+ }) => {
45
+ const handleOptionChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
46
+ const htmlOptions = e.target.options;
47
+
48
+ const newPickedOptions = [...pickedOptions];
49
+ Array.from(htmlOptions).forEach(option => {
50
+ const selected = option.selected;
51
+ const exists = pickedOptions.includes(option.value);
52
+
53
+ const shouldAdd = !exists && selected;
54
+ const shouldRemove = exists && !selected;
55
+
56
+ if (shouldAdd) {
57
+ newPickedOptions.push(option.value);
58
+ } else if (shouldRemove) {
59
+ const index = newPickedOptions.indexOf(option.value);
60
+ newPickedOptions.splice(index, 1);
61
+
62
+ if (initialOptions && !initialOptions.includes(option.value)) {
63
+ setAllOptions?.(allOptions.filter(value => value !== option.value));
64
+ }
65
+ }
66
+ });
67
+ setPickedOptions(newPickedOptions);
68
+ };
69
+
70
+ const onAddNewWrapper = (value: string) => {
71
+ if (value == undefined || value.length === 0) {
72
+ onAddNew?.("");
73
+ return;
74
+ }
75
+
76
+ const trimmedValue = value.trim();
77
+ if (trimmedValue.length === 0 || allOptions.includes(trimmedValue)) {
78
+ return;
79
+ }
80
+
81
+ setAllOptions?.([...allOptions, trimmedValue]);
82
+ setPickedOptions([...pickedOptions, trimmedValue]);
83
+
84
+ onAddNew?.(trimmedValue);
85
+ };
86
+
87
+ const optionElements = allOptions.map(option => (
88
+ <MultiOption key={option} value={option}>
89
+ {option}
90
+ </MultiOption>
91
+ ));
92
+
93
+ return {
94
+ handleOptionChange,
95
+ onAddNew: onAddNewWrapper,
96
+ optionElements
97
+ };
98
+ };
@@ -50,15 +50,16 @@ export interface SelectProps<V extends string | readonly string[] | undefined>
50
50
  noResultsLabel?: string;
51
51
  onChange?: (event: React.ChangeEvent<HTMLSelectElement>, child?: ReactElement) => void;
52
52
  addNew?: AddNewProps;
53
+ isReadOnlyView?: boolean;
53
54
  }
54
55
 
55
56
  export type SingleSelectProps = SelectProps<string>;
56
57
  export type MultiSelectProps = SelectProps<string[]>;
57
58
 
58
- export type Position = {
59
- top: number | `${number}rem` | "initial";
60
- bottom: number | `${number}rem` | "initial";
61
- };
59
+ export enum Position {
60
+ Above = "Above",
61
+ Below = "Below"
62
+ }
62
63
 
63
64
  export interface UseArrowNavigationParams {
64
65
  expanded: boolean;
@@ -72,6 +73,7 @@ export interface UseArrowNavigationParams {
72
73
  searchInputRef: React.RefObject<HTMLInputElement>;
73
74
  addBtnRef?: React.RefObject<HTMLButtonElement>;
74
75
  renderThreshold: number;
76
+ isReadOnlyView?: boolean;
75
77
  }
76
78
 
77
79
  export interface UseSelectPositionListParams {
@@ -88,6 +88,10 @@ $listItemHeight: 2.5rem;
88
88
  }
89
89
  }
90
90
 
91
+ .list-wrapper-container {
92
+ position: relative;
93
+ }
94
+
91
95
  .list-wrapper {
92
96
  border-color: var(--light-grey-border);
93
97
  border-style: var(--input-border-style);
@@ -96,7 +100,6 @@ $listItemHeight: 2.5rem;
96
100
  box-shadow: 0 8px 10px 0 #01053224;
97
101
  position: absolute;
98
102
  z-index: variables.$select-z-index;
99
- top: 44px;
100
103
  left: 0;
101
104
  width: 100%;
102
105
  overflow: auto;
@@ -157,6 +160,43 @@ $listItemHeight: 2.5rem;
157
160
  }
158
161
  }
159
162
  }
163
+
164
+ &[data-readonlyview="true"] {
165
+ user-select: text;
166
+ pointer-events: none;
167
+
168
+ & button[type="button"] {
169
+ background-color: var(--color-white);
170
+ color: var(--read-only-text-color);
171
+ border-color: var(--read-only-border-color);
172
+
173
+ & .selected {
174
+ color: var(--read-only-text-color);
175
+ }
176
+
177
+ &.error,
178
+ &.success {
179
+ border-color: var(--read-only-border-color);
180
+ color: var(--read-only-text-color);
181
+
182
+ & .status {
183
+ visibility: visible;
184
+ }
185
+ }
186
+
187
+ & .status {
188
+ & .chevron-icon {
189
+ visibility: hidden;
190
+ }
191
+ }
192
+ }
193
+ & .list-wrapper {
194
+ visibility: hidden;
195
+ & ul {
196
+ display: none;
197
+ }
198
+ }
199
+ }
160
200
  }
161
201
 
162
202
  .selected-option {
@@ -243,3 +283,22 @@ $listItemHeight: 2.5rem;
243
283
  }
244
284
  }
245
285
  }
286
+
287
+ [data-readonlyview="true"] {
288
+ [data-readonlyview] {
289
+ & button {
290
+ border-color: var(--read-only-border-color);
291
+
292
+ & .status {
293
+ & .chevron-icon {
294
+ visibility: hidden;
295
+ }
296
+ }
297
+
298
+ &.error {
299
+ border-color: var(--read-only-border-color);
300
+ color: var(--read-only-text-color);
301
+ }
302
+ }
303
+ }
304
+ }
@@ -30,11 +30,12 @@ import { useDetermineStatusIcon } from "../../../../hooks/useDetermineStatusIcon
30
30
  import readyclasses from "../../../../readyclasses.module.scss";
31
31
  import { filterProps } from "../../../../util/helper";
32
32
  import { Icon, Icons } from "../../../Icon/Icon";
33
- import { SingleSelectProps } from "../Select.interfaces";
33
+ import { Position, SingleSelectProps } from "../Select.interfaces";
34
34
  import { useSelectPositionList } from "../useSelectPositionList";
35
35
  import { useAddNewBtn } from "../useAddNewBtn";
36
36
  import { useSearch } from "./useSearch";
37
37
  import { useArrowNavigation } from "./useArrowNavigation";
38
+ import { withReadOnly } from "../../../withReadOnly";
38
39
 
39
40
  const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, SingleSelectProps> = (
40
41
  {
@@ -54,6 +55,7 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, SingleSelectP
54
55
  onChange,
55
56
  addNew,
56
57
  search,
58
+ isReadOnlyView,
57
59
  ...rest
58
60
  }: SingleSelectProps,
59
61
  ref
@@ -113,7 +115,8 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, SingleSelectP
113
115
  setShouldClick,
114
116
  searchInputRef,
115
117
  addBtnRef,
116
- renderThreshold: searchThreshold
118
+ renderThreshold: searchThreshold,
119
+ isReadOnlyView: isReadOnlyView || !!rest["data-readonlyview"]
117
120
  });
118
121
 
119
122
  const { listPosition, opacity, optionsListMaxHeight, setListPosition, setOpacity } =
@@ -205,7 +208,7 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, SingleSelectP
205
208
  (event: MouseEvent) => !(event.target as Element).closest(".custom-select") && expanded,
206
209
  () => {
207
210
  setExpanded(false);
208
- setListPosition({ top: 0, bottom: "initial" });
211
+ setListPosition(Position.Below);
209
212
  setOpacity(0);
210
213
  },
211
214
  expanded
@@ -245,13 +248,13 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, SingleSelectP
245
248
  <button
246
249
  {...selectButtonProps}
247
250
  onClick={() => {
248
- setExpanded(!expanded);
251
+ setExpanded(isReadOnlyView || rest["data-readonlyview"] ? false : !expanded);
249
252
  }}
250
253
  ref={customSelectButtonRef}
251
254
  type="button"
252
255
  name={name}
253
256
  className={`${classes["custom-select"]} ${additionalClasses.join(" ")} `}
254
- style={{ display: expanded && searchVisible ? "none" : "initial" }}
257
+ style={{ display: expanded && searchVisible ? "none" : "block" }}
255
258
  disabled={disabled}
256
259
  aria-disabled={disabled}
257
260
  aria-invalid={error}
@@ -266,29 +269,31 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, SingleSelectP
266
269
  </div>
267
270
  <div className={classes["status"]}>{icon || renderChevronIcon()}</div>
268
271
  </button>
269
-
270
- <div
271
- ref={optionListReference}
272
- className={`list-wrapper ${classes["list-wrapper"]}`}
273
- style={{
274
- display: expanded ? "block" : "none",
275
- opacity: opacity,
276
- maxHeight: optionsListMaxHeight.wrapper,
277
- pointerEvents: expanded ? "auto" : "none",
278
- ...listPosition
279
- }}
280
- >
281
- <ul
282
- className={addNewBtnOptionsContainerClassName}
283
- role="listbox"
284
- style={{ maxHeight: optionsListMaxHeight.list }}
272
+ <div className="list-wrapper-container">
273
+ <div
274
+ ref={optionListReference}
275
+ className={`list-wrapper ${classes["list-wrapper"]}`}
276
+ style={{
277
+ display: expanded ? "block" : "none",
278
+ opacity: opacity,
279
+ maxHeight: optionsListMaxHeight.wrapper,
280
+ pointerEvents: expanded ? "auto" : "none",
281
+ bottom: listPosition === Position.Above ? "2.85rem" : "initial",
282
+ marginTop: "4px"
283
+ }}
285
284
  >
286
- {renderOptions()}
287
- </ul>
288
- {renderAddNew()}
285
+ <ul
286
+ className={addNewBtnOptionsContainerClassName}
287
+ role="listbox"
288
+ style={{ maxHeight: optionsListMaxHeight.list }}
289
+ >
290
+ {renderOptions()}
291
+ </ul>
292
+ {renderAddNew()}
293
+ </div>
289
294
  </div>
290
295
  </div>
291
296
  </Fragment>
292
297
  );
293
298
  };
294
- export const Select = React.forwardRef(SelectComponent);
299
+ export const Select = withReadOnly(React.forwardRef(SelectComponent));
@@ -28,7 +28,8 @@ export const useArrowNavigation = ({
28
28
  setShouldClick,
29
29
  searchInputRef,
30
30
  addBtnRef,
31
- renderThreshold
31
+ renderThreshold,
32
+ isReadOnlyView
32
33
  }: UseArrowNavigationParams) => {
33
34
  const onArrowNavigation = (event: React.KeyboardEvent) => {
34
35
  const codesToPreventDefault = [
@@ -53,6 +54,10 @@ export const useArrowNavigation = ({
53
54
 
54
55
  const isAddBtnFocused = addBtnRef?.current === document.activeElement;
55
56
 
57
+ if (isReadOnlyView) {
58
+ return;
59
+ }
60
+
56
61
  if (expanded) {
57
62
  codesToPreventDefault.push("Tab");
58
63
  }
@@ -32,7 +32,7 @@ export const useSelectPositionList = ({
32
32
  list: undefined
33
33
  });
34
34
  const [opacity, setOpacity] = useState(0); // We set opacity because otherwise if we calculate the max height you see the list full height for a split second and then it shortens.
35
- const [listPosition, setListPosition] = useState<Partial<Position>>({});
35
+ const [listPosition, setListPosition] = useState<Position>(Position.Below);
36
36
 
37
37
  useEffect(() => {
38
38
  rePositionList();
@@ -52,11 +52,11 @@ export const useSelectPositionList = ({
52
52
  window.innerHeight - containerReference.current.getBoundingClientRect().top;
53
53
 
54
54
  // Set position as if there's more space on the bottom
55
- let position: Position = { top: "2.75rem", bottom: "initial" };
55
+ let position = Position.Below;
56
56
 
57
57
  // Set the position of the select
58
58
  if (spaceOnTopOfSelect > spaceOnBottomOfSelect) {
59
- position = { top: "initial", bottom: "2.75rem" };
59
+ position = Position.Above;
60
60
  }
61
61
 
62
62
  setListPosition(position);
@@ -72,7 +72,7 @@ export const useSelectPositionList = ({
72
72
  ? addBtnRef.current.getBoundingClientRect().height +
73
73
  parseInt(getComputedStyle(addBtnRef.current).marginBottom)
74
74
  : 0;
75
- const transformOrigin = position.top !== "initial" ? "top" : "bottom";
75
+ const transformOrigin = position === Position.Below ? "top" : "bottom";
76
76
 
77
77
  if (!containerReference.current) {
78
78
  console.error(
@@ -48,6 +48,26 @@
48
48
  }
49
49
 
50
50
  @include mixins.outlineStates();
51
+
52
+ div[data-readonlyview="true"] {
53
+ min-height: 4rem;
54
+ border: 1px solid var(--color-blue-grey100);
55
+ color: var(--read-only-text-color);
56
+ background-color: var(--color-white);
57
+ padding: 0.5rem 0.75rem;
58
+ font-family: var(--font-family);
59
+ font-size: var(--form-control-font-size);
60
+ position: relative;
61
+ border-radius: 0.125rem;
62
+
63
+ & ~ span.outline {
64
+ display: none;
65
+ }
66
+
67
+ &:has(~ [data-icon-status]) {
68
+ padding-right: 2.5rem;
69
+ }
70
+ }
51
71
  }
52
72
 
53
73
  .textarea {
@@ -77,6 +97,10 @@
77
97
  @include mixins.transition(all, 0.2s, ease-in-out);
78
98
  @include mixins.browserOutlineDisabled();
79
99
  }
100
+
101
+ &:has(~ [data-icon-status]) {
102
+ padding-right: 2.5rem;
103
+ }
80
104
  }
81
105
 
82
106
  .error {
@@ -18,9 +18,11 @@ import React, { ForwardRefRenderFunction, ComponentPropsWithRef, useState } from
18
18
  import classes from "./Textarea.module.scss";
19
19
  import { FormElement } from "../form.interfaces";
20
20
  import { useDetermineStatusIcon } from "../../../hooks/useDetermineStatusIcon";
21
+ import { withReadOnly } from "../../withReadOnly";
21
22
 
22
23
  export interface Props extends ComponentPropsWithRef<"textarea">, FormElement {
23
24
  wrapperProps?: ComponentPropsWithRef<"div">;
25
+ readOnlyView?: boolean;
24
26
  }
25
27
 
26
28
  const TextareaComponent: ForwardRefRenderFunction<HTMLTextAreaElement, Props> = (
@@ -33,6 +35,7 @@ const TextareaComponent: ForwardRefRenderFunction<HTMLTextAreaElement, Props> =
33
35
  wrapperProps,
34
36
  onFocus,
35
37
  onBlur,
38
+ value,
36
39
  ...rest
37
40
  }: Props,
38
41
  ref
@@ -50,8 +53,19 @@ const TextareaComponent: ForwardRefRenderFunction<HTMLTextAreaElement, Props> =
50
53
 
51
54
  const icon = useDetermineStatusIcon({ success, error });
52
55
 
53
- return (
54
- <div {...wrapperProps} className={wrapperClasses.join(" ")}>
56
+ const renderTextarea = () => {
57
+ if (rest["data-readonlyview"]) {
58
+ return (
59
+ <div
60
+ data-readonlyview={true}
61
+ tabIndex={0}
62
+ className={`${error ? classes["error"] : ""} ${success ? classes["success"] : ""}`}
63
+ >
64
+ {value}
65
+ </div>
66
+ );
67
+ }
68
+ return (
55
69
  <textarea
56
70
  {...rest}
57
71
  ref={ref}
@@ -66,11 +80,18 @@ const TextareaComponent: ForwardRefRenderFunction<HTMLTextAreaElement, Props> =
66
80
  setFocus(false);
67
81
  onBlur?.(event);
68
82
  }}
83
+ value={value}
69
84
  />
85
+ );
86
+ };
87
+
88
+ return (
89
+ <div {...wrapperProps} className={wrapperClasses.join(" ")}>
90
+ {renderTextarea()}
70
91
  {icon}
71
92
  <span className={outlineClasses.join(" ")}></span>
72
93
  </div>
73
94
  );
74
95
  };
75
96
 
76
- export const Textarea = React.forwardRef(TextareaComponent);
97
+ export const Textarea = withReadOnly(React.forwardRef(TextareaComponent));
@@ -25,6 +25,7 @@ import { useWrapper } from "../../../../hooks/useWrapper";
25
25
  import { Wrapper, WrapperProps } from "../Wrapper/Wrapper";
26
26
  import { Icons } from "../../../Icon/Icon";
27
27
  import { Fieldset, Props as FieldsetProps } from "../../../Form/Fieldset/Fieldset";
28
+ import { withReadOnly } from "../../../withReadOnly";
28
29
 
29
30
  export interface Props extends ComponentPropsWithRef<"div">, Omit<WrapperProps, "success"> {
30
31
  children: ReactElement[] | ReactElement;
@@ -80,7 +81,9 @@ const CheckboxWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props>
80
81
  );
81
82
  };
82
83
 
84
+ const ForwardedCheckboxWrapper = React.forwardRef(CheckboxWrapperComponent);
85
+ ForwardedCheckboxWrapper.displayName = "CheckboxWrapper";
83
86
  /**
84
87
  * @deprecated
85
88
  */
86
- export const CheckboxWrapper = React.forwardRef(CheckboxWrapperComponent);
89
+ export const CheckboxWrapper = withReadOnly(ForwardedCheckboxWrapper);
@@ -37,6 +37,10 @@ input {
37
37
  justify-content: center;
38
38
 
39
39
  @include mixins.transition(all, 0.2s, ease-in-out);
40
+
41
+ &[data-readonlyview="true"] {
42
+ padding: auto;
43
+ }
40
44
  }
41
45
 
42
46
  [data-prefix],
@@ -61,4 +65,14 @@ input {
61
65
  cursor: not-allowed;
62
66
  color: var(--greyed-out);
63
67
  }
68
+
69
+ &[data-readonlyview="true"] {
70
+ & label {
71
+ color: var(--read-only-text-color);
72
+ }
73
+
74
+ & input {
75
+ color: var(--read-only-text-color);
76
+ }
77
+ }
64
78
  }
@@ -19,6 +19,7 @@ import { Input, Type, Props as InputProps } from "../../Input/Input";
19
19
  import classes from "./InputWrapper.module.scss";
20
20
  import { Wrapper, WrapperProps } from "../Wrapper/Wrapper";
21
21
  import { useWrapper } from "../../../../hooks/useWrapper";
22
+ import { withReadOnly } from "../../../withReadOnly";
22
23
 
23
24
  interface PartialInputProps extends Partial<InputProps> {}
24
25
 
@@ -63,7 +64,7 @@ const InputWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
63
64
  inputProps?.wrapperProps?.className &&
64
65
  inputWrapperClasses.push(inputProps?.wrapperProps?.className);
65
66
  disabled && inputWrapperClasses.push(classes["disabled"]);
66
-
67
+ const readValue = rest["data-readonlyview"] as boolean;
67
68
  return (
68
69
  <Wrapper
69
70
  {...rest}
@@ -88,6 +89,7 @@ const InputWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
88
89
  {...inputProps}
89
90
  prefix={prefix}
90
91
  suffix={suffix}
92
+ readOnlyView={readValue}
91
93
  wrapperProps={{
92
94
  className: inputWrapperClasses.join(" ")
93
95
  }}
@@ -116,4 +118,4 @@ const InputWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
116
118
  );
117
119
  };
118
120
 
119
- export const InputWrapper = React.forwardRef(InputWrapperComponent);
121
+ export const InputWrapper = withReadOnly(React.forwardRef(InputWrapperComponent));
@@ -20,6 +20,7 @@ import { Wrapper, WrapperProps } from "../Wrapper/Wrapper";
20
20
  import { useWrapper } from "../../../../hooks/useWrapper";
21
21
  import { MultiSelect } from "../../Select/MultiSelect/MultiSelect";
22
22
  import { MultiSelectProps } from "../../Select/Select.interfaces";
23
+ import { withReadOnly } from "../../../withReadOnly";
23
24
 
24
25
  interface PartialSelectProps extends Partial<MultiSelectProps> {}
25
26
 
@@ -74,6 +75,7 @@ const MultiSelectWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Prop
74
75
  onChange={onChange}
75
76
  placeholder={placeholder}
76
77
  className={`${selectProps?.className ?? ""}`}
78
+ isReadOnlyView={!!rest["data-readonlyview"]}
77
79
  >
78
80
  {children as ReactElement[]}
79
81
  </MultiSelect>
@@ -81,4 +83,4 @@ const MultiSelectWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Prop
81
83
  );
82
84
  };
83
85
 
84
- export const MultiSelectWrapper = React.forwardRef(MultiSelectWrapperComponent);
86
+ export const MultiSelectWrapper = withReadOnly(React.forwardRef(MultiSelectWrapperComponent));
@@ -25,6 +25,7 @@ import { Wrapper, WrapperProps } from "../Wrapper/Wrapper";
25
25
  import { useWrapper } from "../../../../hooks/useWrapper";
26
26
  import { Icons } from "../../../Icon/Icon";
27
27
  import { Fieldset, Props as FieldsetProps } from "../../../Form/Fieldset/Fieldset";
28
+ import { withReadOnly } from "../../../withReadOnly";
28
29
 
29
30
  export interface Props extends ComponentPropsWithRef<"div">, WrapperProps {
30
31
  children: ReactElement | ReactElement[];
@@ -49,6 +50,7 @@ const RadioWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
49
50
  ref
50
51
  ) => {
51
52
  const { errorId, helperId } = useWrapper();
53
+ const readOnlyView = !!rest["data-readonlyview"];
52
54
 
53
55
  useEffect(() => {
54
56
  if (fieldsetProps.legend === undefined) {
@@ -59,17 +61,20 @@ const RadioWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
59
61
  }, []);
60
62
 
61
63
  const renderChildren = () =>
62
- React.Children.map(children, child =>
63
- React.cloneElement(child, {
64
- parentErrorId: errorId,
65
- error: error,
66
- checked: child.props.value === value,
67
- name: name,
68
- parentHelperId: helperText ? helperId : false,
69
- onChange: onChange,
70
- disabled: child.props.disabled !== undefined ? child.props.disabled : disabled
71
- })
72
- );
64
+ React.Children.map(children, child => {
65
+ if (!readOnlyView || child.props.value === value) {
66
+ return React.cloneElement(child, {
67
+ parentErrorId: errorId,
68
+ error: error,
69
+ checked: child.props.value === value,
70
+ name: name,
71
+ parentHelperId: helperText ? helperId : false,
72
+ onChange: onChange,
73
+ disabled: child.props.disabled !== undefined ? child.props.disabled : disabled
74
+ });
75
+ }
76
+ return null;
77
+ });
73
78
 
74
79
  return (
75
80
  <Fieldset {...fieldsetProps} disabled={disabled}>
@@ -96,4 +101,4 @@ const RadioWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
96
101
  );
97
102
  };
98
103
 
99
- export const RadioWrapper = React.forwardRef(RadioWrapperComponent);
104
+ export const RadioWrapper = withReadOnly(React.forwardRef(RadioWrapperComponent));
@@ -20,6 +20,7 @@ import { Wrapper, WrapperProps } from "../Wrapper/Wrapper";
20
20
  import { Select } from "../../Select/SingleSelect/Select";
21
21
  import { useWrapper } from "../../../../hooks/useWrapper";
22
22
  import { SingleSelectProps } from "../../Select/Select.interfaces";
23
+ import { withReadOnly } from "../../../withReadOnly";
23
24
 
24
25
  interface PartialSelectProps extends Partial<SingleSelectProps> {}
25
26
 
@@ -74,6 +75,7 @@ const SelectWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> =
74
75
  onChange={onChange}
75
76
  placeholder={placeholder}
76
77
  className={`${selectProps?.className ?? ""}`}
78
+ isReadOnlyView={!!rest["data-readonlyview"]}
77
79
  >
78
80
  {children as ReactElement[]}
79
81
  </Select>
@@ -81,4 +83,7 @@ const SelectWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> =
81
83
  );
82
84
  };
83
85
 
84
- export const SelectWrapper = React.forwardRef(SelectWrapperComponent);
86
+ const forwardedSelectWrapper = React.forwardRef(SelectWrapperComponent);
87
+ forwardedSelectWrapper.displayName = "SelectWrapper";
88
+
89
+ export const SelectWrapper = withReadOnly(forwardedSelectWrapper);