@luscii-healthtech/web-ui 2.0.0 → 2.3.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 (57) hide show
  1. package/dist/components/Accordion/Accordion.d.ts +10 -0
  2. package/dist/components/Accordion/AccordionItem.d.ts +9 -0
  3. package/dist/components/Form/Form.d.ts +9 -0
  4. package/dist/components/Form/FormFieldDecorator.d.ts +8 -0
  5. package/dist/components/Form/FormInput.d.ts +3 -0
  6. package/dist/components/Form/FormRadioGroup.d.ts +3 -0
  7. package/dist/components/Form/FormSelect.d.ts +3 -0
  8. package/dist/components/Form/form.transformer.d.ts +20 -0
  9. package/dist/components/Form/form.types.d.ts +54 -0
  10. package/dist/components/Input/Input.d.ts +8 -7
  11. package/dist/components/Input/SearchInput.d.ts +1 -1
  12. package/dist/components/List/List.d.ts +1 -1
  13. package/dist/components/List/List.types.d.ts +1 -0
  14. package/dist/components/List/ListItemSkeleton.d.ts +2 -0
  15. package/dist/components/List/ListSkeleton.d.ts +7 -0
  16. package/dist/components/Radio/Radio.d.ts +3 -0
  17. package/dist/components/Radio/RadioV2.d.ts +17 -0
  18. package/dist/components/RadioGroup/RadioGroup.d.ts +3 -0
  19. package/dist/components/RadioGroup/RadioGroupV2.d.ts +9 -0
  20. package/dist/components/Select/Select.d.ts +3 -0
  21. package/dist/components/Select/SelectV2.d.ts +31 -0
  22. package/dist/index.d.ts +2 -0
  23. package/dist/web-ui-tailwind.css +50 -0
  24. package/dist/web-ui.cjs.development.js +604 -40
  25. package/dist/web-ui.cjs.development.js.map +1 -1
  26. package/dist/web-ui.cjs.production.min.js +1 -1
  27. package/dist/web-ui.cjs.production.min.js.map +1 -1
  28. package/dist/web-ui.esm.js +604 -41
  29. package/dist/web-ui.esm.js.map +1 -1
  30. package/package.json +6 -3
  31. package/src/components/Accordion/Accordion.tsx +33 -0
  32. package/src/components/Accordion/AccordionItem.tsx +50 -0
  33. package/src/components/Form/Form.tsx +106 -0
  34. package/src/components/Form/FormFieldDecorator.tsx +66 -0
  35. package/src/components/Form/FormInput.tsx +47 -0
  36. package/src/components/Form/FormRadioGroup.tsx +23 -0
  37. package/src/components/Form/FormSelect.tsx +32 -0
  38. package/src/components/Form/form.transformer.ts +9 -0
  39. package/src/components/Form/form.types.ts +132 -0
  40. package/src/components/Input/Input.tsx +160 -165
  41. package/src/components/Input/SearchInput.tsx +13 -3
  42. package/src/components/List/List.tsx +13 -9
  43. package/src/components/List/List.types.ts +1 -0
  44. package/src/components/List/ListItemSkeleton.tsx +26 -0
  45. package/src/components/List/ListSkeleton.scss +5 -0
  46. package/src/components/List/ListSkeleton.tsx +30 -0
  47. package/src/components/Radio/Radio.js +3 -0
  48. package/src/components/Radio/RadioV2.css +15 -0
  49. package/src/components/Radio/RadioV2.tsx +87 -0
  50. package/src/components/RadioGroup/RadioGroup.js +3 -0
  51. package/src/components/RadioGroup/RadioGroupV2.tsx +35 -0
  52. package/src/components/Select/Select.tsx +38 -12
  53. package/src/components/Select/SelectV2.tsx +171 -0
  54. package/src/index.tsx +3 -0
  55. package/src/styles/_skeleton.scss +63 -0
  56. package/src/types/general.types.ts +1 -1
  57. package/src/components/Select/Select.examples.md +0 -161
@@ -1,24 +1,15 @@
1
- import React, {
2
- HTMLInputTypeAttribute,
3
- useEffect,
4
- useRef,
5
- useState,
6
- } from "react";
1
+ import React, { useEffect, useState } from "react";
7
2
  import classNames from "classnames";
8
3
 
9
4
  import { CrossIcon } from "../Icons/CrossIcon";
5
+ import { AllowedTextInputTypes } from "../Form/form.types";
10
6
  import { IconProps } from "../Icons/types/IconProps.type";
11
7
 
12
8
  import "./Input.css";
13
9
 
14
- type AllowedInputTypes = Extract<
15
- HTMLInputTypeAttribute,
16
- "email" | "number" | "password" | "text"
17
- >;
18
-
19
10
  // FIXME: something in the tsdx.js build doesn't allow me to use `Uppercase<AllowedInputTypes>`
20
11
  // Don't know why yet but it can be fixed later.
21
- export const INPUT_TYPES: Record<string, AllowedInputTypes> = {
12
+ export const INPUT_TYPES: Record<string, AllowedTextInputTypes> = {
22
13
  EMAIL: "email",
23
14
  NUMBER: "number",
24
15
  PASSWORD: "password",
@@ -29,7 +20,10 @@ export const INPUT_TYPES: Record<string, AllowedInputTypes> = {
29
20
  * It's very complicated to tap into the onChange events of inputs,
30
21
  * so I omit the type it requires and add a easier one to deal with.
31
22
  */
32
- type CustomHTMLInputProps = Omit<React.HTMLProps<HTMLInputElement>, "onChange">;
23
+ type CustomHTMLInputProps = Omit<
24
+ React.HTMLProps<HTMLInputElement>,
25
+ "onChange"
26
+ > & { isError?: boolean };
33
27
 
34
28
  type FakeEventTarget = {
35
29
  target: {
@@ -43,174 +37,175 @@ type FakeEventTarget = {
43
37
  };
44
38
 
45
39
  export interface InputProps extends CustomHTMLInputProps {
46
- type?: AllowedInputTypes;
40
+ type?: AllowedTextInputTypes;
47
41
  clearable?: boolean;
48
42
  isDisabled?: boolean;
49
43
  withPrefix?: string;
50
44
  withSuffix?: string;
51
45
  icon?: React.VoidFunctionComponent<IconProps>;
52
46
  onChange?: (event: FakeEventTarget) => void;
53
- // FIXME: this is used in the SearchAndFilterBar in Vitals, but we can use forwardRef instead
54
- // and lose this function later.
55
- setRef?: (refTarget: HTMLInputElement) => void;
56
47
  }
57
48
 
58
- const Input: React.VoidFunctionComponent<InputProps> = ({
59
- withSuffix = "",
60
- withPrefix = "",
61
- className,
62
- clearable = false,
63
- type = "text",
64
- isDisabled = false,
65
- icon,
66
- setRef,
67
- name,
68
- value,
69
- onChange,
70
- ...otherProps
71
- }) => {
72
- const hasNoExtraContent = withPrefix === "" && withSuffix === "";
73
- const [innerValue, setInnerValue] = useState(value);
74
- const inputRef = useRef<HTMLInputElement | null>(null);
75
-
76
- useEffect(() => {
77
- setInnerValue(value);
78
- }, [value]);
79
-
80
- const clearField = () => {
81
- setInnerValue("");
82
-
83
- // This allows backwards compatibility with our usages of the input
84
- onChange?.({
85
- target: {
86
- name: name || "",
87
- value: "",
88
- },
89
- currentTarget: {
90
- name: name || "",
91
- value: "",
92
- },
93
- });
94
- };
95
-
96
- const handleChangeEvent = (event: React.ChangeEvent<HTMLInputElement>) => {
97
- setInnerValue(event.currentTarget.value);
98
-
99
- // This allows backwards compatibility with our usages of the input
100
- onChange?.({
101
- target: {
102
- name: name || "",
103
- value: event.currentTarget.value,
104
- },
105
- currentTarget: {
106
- name: name || "",
107
- value: event.currentTarget.value,
108
- },
109
- });
110
- };
111
-
112
- const isClearIconVisible = clearable && value;
113
-
114
- return (
115
- <div
116
- data-test-id="input-component-container"
117
- className="relative inline-block"
118
- >
119
- <div className="flex flex-row">
120
- <span
121
- className={classNames(
122
- "h-11",
123
- {
124
- hidden: hasNoExtraContent,
125
- "order-1": withPrefix !== "",
126
- "order-2": withSuffix !== "",
127
- "rounded-l border-l": withPrefix !== "",
128
- "rounded-r border-r": withSuffix !== "",
129
- },
130
- "border-t border-b border-solid border-input-border",
131
- "flex flex-col items-center p-3",
132
- "text-sm",
133
- "text-slate-500",
134
- "bg-main-background"
49
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
50
+ (
51
+ {
52
+ withSuffix = "",
53
+ withPrefix = "",
54
+ className,
55
+ clearable = false,
56
+ type = "text",
57
+ isDisabled = false,
58
+ icon,
59
+ name,
60
+ value = "",
61
+ onChange,
62
+ isError,
63
+ ...otherProps
64
+ },
65
+ ref
66
+ ) => {
67
+ const hasNoExtraContent = withPrefix === "" && withSuffix === "";
68
+ const [innerValue, setInnerValue] = useState(value);
69
+
70
+ useEffect(() => {
71
+ setInnerValue(value);
72
+ }, [value]);
73
+
74
+ const clearField = () => {
75
+ setInnerValue("");
76
+
77
+ // This allows backwards compatibility with our usages of the input
78
+ onChange?.({
79
+ target: {
80
+ name: name || "",
81
+ value: "",
82
+ },
83
+ currentTarget: {
84
+ name: name || "",
85
+ value: "",
86
+ },
87
+ });
88
+ };
89
+
90
+ const handleChangeEvent = (event: React.ChangeEvent<HTMLInputElement>) => {
91
+ setInnerValue(event.currentTarget.value);
92
+
93
+ // This allows backwards compatibility with our usages of the input
94
+ onChange?.({
95
+ target: {
96
+ name: name || "",
97
+ value: event.currentTarget.value,
98
+ },
99
+ currentTarget: {
100
+ name: name || "",
101
+ value: event.currentTarget.value,
102
+ },
103
+ });
104
+ };
105
+
106
+ const isClearIconVisible = clearable && value;
107
+
108
+ return (
109
+ <div
110
+ data-test-id="input-component-container"
111
+ className="relative inline-block"
112
+ >
113
+ <div className="flex flex-row">
114
+ <span
115
+ className={classNames(
116
+ "h-11 border-t border-b border-solid border-input-border",
117
+ {
118
+ hidden: hasNoExtraContent,
119
+ "order-1": withPrefix !== "",
120
+ "order-2": withSuffix !== "",
121
+ "rounded-l border-l": withPrefix !== "",
122
+ "rounded-r border-r": withSuffix !== "",
123
+ },
124
+
125
+ "flex flex-col items-center p-3",
126
+ "text-sm",
127
+ "text-slate-500",
128
+ "bg-main-background"
129
+ )}
130
+ >
131
+ {withSuffix || withPrefix}
132
+ </span>
133
+ {icon && (
134
+ <div
135
+ className="absolute top-1/2 left-4"
136
+ style={{
137
+ transform: "translateY(-50%)",
138
+ }}
139
+ >
140
+ {React.createElement(icon, {
141
+ className: "w-6 h-6 text-slate-300 ",
142
+ })}
143
+ </div>
135
144
  )}
136
- >
137
- {withSuffix || withPrefix}
138
- </span>
139
- {icon && (
145
+ <input
146
+ {...otherProps}
147
+ data-test-id="input-component"
148
+ name={name}
149
+ value={innerValue}
150
+ onChange={handleChangeEvent}
151
+ ref={ref}
152
+ size={otherProps.maxLength}
153
+ type={type}
154
+ disabled={isDisabled}
155
+ className={classNames(
156
+ "input",
157
+ "block",
158
+ { "pl-12": icon, "pr-11": clearable },
159
+ {
160
+ "text-slate-400 bg-slate-50": isDisabled,
161
+ "text-slate-700": !isDisabled,
162
+ "border-input-border": !isDisabled && !isError,
163
+ "hover:border-input-border-dark": !isDisabled,
164
+ "border-red-700": isError,
165
+ "focus:outline-negative": isError,
166
+ "focus:border-blue-800": !isError,
167
+ "focus:outline-primary": !isError,
168
+ "bg-white": !isDisabled,
169
+ },
170
+ "h-11",
171
+ "p-2",
172
+ "border",
173
+ "text-sm",
174
+ "placeholder-slate-500",
175
+ "border-solid",
176
+
177
+ "transition-colors",
178
+ "duration-300",
179
+ {
180
+ "z-10": withSuffix !== "" || withPrefix !== "", // to make sure the outline is displayed completely
181
+ rounded: hasNoExtraContent,
182
+ "rounded-l": withSuffix !== "",
183
+ "rounded-r": withPrefix !== "",
184
+ "order-2": withPrefix !== "",
185
+ "order-1": withSuffix !== "",
186
+ },
187
+ "shadow-default",
188
+ className
189
+ )}
190
+ />
140
191
  <div
141
- className="absolute top-1/2 left-4"
192
+ className="absolute right-0 top-1/2"
142
193
  style={{
143
194
  transform: "translateY(-50%)",
144
195
  }}
145
196
  >
146
- {React.createElement(icon, {
147
- className: "w-6 h-6 text-slate-300 ",
148
- })}
197
+ <CrossIcon
198
+ className={classNames(
199
+ "w-6 h-6 mr-3 cursor-pointer text-slate-300",
200
+ { block: isClearIconVisible, hidden: !isClearIconVisible }
201
+ )}
202
+ onClick={clearField}
203
+ />
149
204
  </div>
150
- )}
151
- <input
152
- {...otherProps}
153
- data-test-id="input-component"
154
- name={name}
155
- value={innerValue}
156
- onChange={handleChangeEvent}
157
- ref={element => {
158
- inputRef.current = element;
159
- element && setRef?.(element);
160
- }}
161
- size={otherProps.maxLength}
162
- type={type}
163
- disabled={isDisabled}
164
- className={classNames(
165
- "input",
166
- "block",
167
- { "pl-12": icon, "pr-11": clearable },
168
- {
169
- "text-slate-400 bg-slate-50": isDisabled,
170
- "text-slate-700": !isDisabled,
171
- "border-input-border": !isDisabled,
172
- "hover:border-input-border-dark": !isDisabled,
173
- "bg-white": !isDisabled,
174
- },
175
- "h-11",
176
- "p-2",
177
- "border",
178
- "text-sm",
179
- "placeholder-slate-500",
180
- "border-solid",
181
- "focus:outline-primary",
182
- "transition-colors",
183
- "duration-300",
184
- "focus:border-blue-800",
185
- {
186
- "z-10": withSuffix !== "" || withPrefix !== "", // to make sure the outline is displayed completely
187
- rounded: hasNoExtraContent,
188
- "rounded-l": withSuffix !== "",
189
- "rounded-r": withPrefix !== "",
190
- "order-2": withPrefix !== "",
191
- "order-1": withSuffix !== "",
192
- },
193
- "shadow-default",
194
- className
195
- )}
196
- />
197
- <div
198
- className="absolute right-0 top-1/2"
199
- style={{
200
- transform: "translateY(-50%)",
201
- }}
202
- >
203
- <CrossIcon
204
- className={classNames(
205
- "w-6 h-6 mr-3 cursor-pointer text-slate-300",
206
- { block: isClearIconVisible, hidden: !isClearIconVisible }
207
- )}
208
- onClick={clearField}
209
- />
210
205
  </div>
211
206
  </div>
212
- </div>
213
- );
214
- };
207
+ );
208
+ }
209
+ );
215
210
 
216
211
  export default Input;
@@ -9,6 +9,16 @@ export type SearchInputProps = Omit<
9
9
  "icon" | "withSuffix" | "withPrefix" | "type" | "clearable"
10
10
  >;
11
11
 
12
- export const SearchInput: React.VoidFunctionComponent<SearchInputProps> = props => {
13
- return <Input {...props} icon={SearchIcon} type="text" clearable={true} />;
14
- };
12
+ export const SearchInput = React.forwardRef<HTMLInputElement, SearchInputProps>(
13
+ (props, ref) => {
14
+ return (
15
+ <Input
16
+ {...props}
17
+ icon={SearchIcon}
18
+ type="text"
19
+ clearable={true}
20
+ ref={ref}
21
+ />
22
+ );
23
+ }
24
+ );
@@ -12,6 +12,7 @@ import {
12
12
  OnAssetLoadErrorPayload,
13
13
  Dragula,
14
14
  } from "./List.types";
15
+ import { ListSkeleton } from "./ListSkeleton";
15
16
 
16
17
  export { ListProps, ListItemProps, OnAssetLoadErrorPayload };
17
18
 
@@ -23,6 +24,7 @@ export const List = ({
23
24
  onAssetLoadError,
24
25
  onDragEnd,
25
26
  emptyStateMessage,
27
+ isLoading,
26
28
  }: ListProps): JSX.Element => {
27
29
  const listRef = useRef<HTMLUListElement | null>(null);
28
30
  const dragulaRef = useRef<Dragula | null>(null);
@@ -43,17 +45,15 @@ export const List = ({
43
45
  const draggedItemId = element.dataset["id"];
44
46
 
45
47
  if (listRef.current && draggedItemId) {
46
- const itemIdsWithOldOrder = items.map(item => item.itemId.toString());
48
+ const itemIdsWithOldOrder = items.map((item) => item.itemId.toString());
47
49
  const itemIdsWithNewOrder = Array.from(listRef.current.children)
48
- .map(child => (child as HTMLElement).dataset["id"])
50
+ .map((child) => (child as HTMLElement).dataset["id"])
49
51
  .filter((itemId): itemId is string => !!itemId);
50
52
 
51
- const oldIndexOfDraggedItemId = itemIdsWithOldOrder.indexOf(
52
- draggedItemId
53
- );
54
- const newIndexOfDraggedItemId = itemIdsWithNewOrder.indexOf(
55
- draggedItemId
56
- );
53
+ const oldIndexOfDraggedItemId =
54
+ itemIdsWithOldOrder.indexOf(draggedItemId);
55
+ const newIndexOfDraggedItemId =
56
+ itemIdsWithNewOrder.indexOf(draggedItemId);
57
57
 
58
58
  if (oldIndexOfDraggedItemId !== newIndexOfDraggedItemId) {
59
59
  onDragEnd?.(draggedItemId, newIndexOfDraggedItemId);
@@ -72,6 +72,10 @@ export const List = ({
72
72
 
73
73
  const roundTop = !hasHeader || (hasHeader && headerTransparent);
74
74
 
75
+ if (isLoading) {
76
+ return <ListSkeleton items={items.length} />;
77
+ }
78
+
75
79
  return (
76
80
  <div data-test-id="list-component">
77
81
  {(title || headerButton) && (
@@ -103,7 +107,7 @@ export const List = ({
103
107
  )}
104
108
 
105
109
  <ul ref={listRef}>
106
- {items.map(item => (
110
+ {items.map((item) => (
107
111
  <ListItem
108
112
  {...item}
109
113
  roundTop={roundTop}
@@ -37,6 +37,7 @@ export type ListProps = {
37
37
  onAssetLoadError?: (payload: OnAssetLoadErrorPayload) => void;
38
38
  onDragEnd?: (itemId: string | number, newIndex: number) => void;
39
39
  emptyStateMessage?: string;
40
+ isLoading?: boolean;
40
41
  };
41
42
 
42
43
  export interface Dragula {
@@ -0,0 +1,26 @@
1
+ import React from "react";
2
+
3
+ export const ListItemSkeleton = (): JSX.Element => {
4
+ return (
5
+ <div className="flex flex-row items-center p-4">
6
+ <div
7
+ className="skeleton-box is-circle mr-2"
8
+ style={{ width: `${32}px`, height: `${32}px` }}
9
+ />
10
+ <div className="flex flex-col">
11
+ <div
12
+ className="skeleton-box mb-1"
13
+ style={{ width: `${160}px`, height: `${14}px` }}
14
+ />
15
+ <div
16
+ className="skeleton-box"
17
+ style={{ width: `${110}px`, height: `${14}px` }}
18
+ />
19
+ </div>
20
+ <div
21
+ className="skeleton-box is-button ml-auto rounded-full"
22
+ style={{ width: `${24}px`, height: `${24}px` }}
23
+ />
24
+ </div>
25
+ );
26
+ };
@@ -0,0 +1,5 @@
1
+ @import "../../styles/skeleton";
2
+
3
+ .list-skeleton {
4
+ @include skeleton();
5
+ }
@@ -0,0 +1,30 @@
1
+ import React from "react";
2
+
3
+ import "./ListSkeleton.scss";
4
+ import { ListItemSkeleton } from "./ListItemSkeleton";
5
+
6
+ type ListSkeletonProps = {
7
+ items: number;
8
+ };
9
+
10
+ export const ListSkeleton = ({ items }: ListSkeletonProps): JSX.Element => {
11
+ const skeletonItems = Array.from({ length: items || 5 }, (_, i) => {
12
+ return <ListItemSkeleton key={i} />;
13
+ });
14
+
15
+ return (
16
+ <div className="flex flex-col divide-y divide-slate-200 bg-white border-slate-50 border rounded-lg shadow list-skeleton">
17
+ <div className="flex flex-row items-center px-4 py-2">
18
+ <div
19
+ className="skeleton-box"
20
+ style={{ width: `${160}px`, height: `${14}px` }}
21
+ />
22
+ <div
23
+ className="skeleton-box is-button ml-auto"
24
+ style={{ width: `${110}px`, height: `${44}px` }}
25
+ />
26
+ </div>
27
+ {skeletonItems}
28
+ </div>
29
+ );
30
+ };
@@ -5,6 +5,9 @@ import classNames from "classnames";
5
5
  import "./Radio.scss";
6
6
  import { Text } from "../Text/Text";
7
7
 
8
+ /**
9
+ * @deprecated: use RadioV2 instead
10
+ */
8
11
  class Radio extends PureComponent {
9
12
  static propTypes = {
10
13
  className: PropTypes.string,
@@ -0,0 +1,15 @@
1
+ .radio-form-field-label input[type="radio"]:checked + .radio-circle {
2
+ @apply bg-primary;
3
+ }
4
+
5
+ .radio-form-field-label[data-has-error="true"] .radio-circle {
6
+ @apply border-red-700;
7
+ @apply outline-negative;
8
+ }
9
+
10
+ .radio-form-field-label
11
+ input[type="radio"]:checked
12
+ + .radio-circle
13
+ .radio-inner-circle {
14
+ @apply bg-white;
15
+ }
@@ -0,0 +1,87 @@
1
+ import React from "react";
2
+ import classNames from "classnames";
3
+
4
+ import Text from "../Text/Text";
5
+
6
+ import "./RadioV2.css";
7
+
8
+ export interface RadioProps
9
+ extends React.InputHTMLAttributes<HTMLInputElement> {
10
+ name: string;
11
+ value: string | number;
12
+ // text shown to the user to explain the option
13
+ text?: string;
14
+ // text shown to the user underneath the text for extra information
15
+ info?: string;
16
+ isError?: boolean;
17
+ innerRef?: React.Ref<HTMLInputElement>;
18
+ // value field is used by react-hook-form as the value returned
19
+ }
20
+
21
+ function RadioInner({
22
+ text,
23
+ info,
24
+ isError,
25
+ innerRef,
26
+ className,
27
+ ...otherProps
28
+ }: RadioProps): JSX.Element {
29
+ const { value, disabled } = otherProps;
30
+ const nameHtmlFor = `field-${value}`;
31
+
32
+ return (
33
+ <label
34
+ className="radio-form-field-label leading-tight"
35
+ htmlFor={nameHtmlFor}
36
+ data-has-error={isError}
37
+ data-test-id={nameHtmlFor}
38
+ >
39
+ <div className="flex flex-row items-center ">
40
+ <input
41
+ {...otherProps}
42
+ className={classNames("appearance-none", className)}
43
+ ref={innerRef}
44
+ type="radio"
45
+ id={nameHtmlFor}
46
+ disabled={disabled}
47
+ />
48
+ <span
49
+ className={classNames(
50
+ "flex flex-col items-center justify-center w-4 h-4 transition-colors duration-300 ease-in-out border radio-circle rounded-xl border-slate-300"
51
+ )}
52
+ >
53
+ <span className="block transition-colors duration-300 ease-in-out radio-inner-circle w-1.5 h-1.5 rounded-xl"></span>
54
+ </span>
55
+ {text && (
56
+ <div className="ml-2">
57
+ <Text
58
+ inline={true}
59
+ text={text}
60
+ type="base"
61
+ color={disabled ? "slate-500" : undefined}
62
+ />
63
+ </div>
64
+ )}
65
+ </div>
66
+ {info && (
67
+ <Text
68
+ inline={true}
69
+ className="ml-6"
70
+ text={info}
71
+ type="sm"
72
+ color={disabled ? "slate-200" : "slate-500"}
73
+ />
74
+ )}
75
+ </label>
76
+ );
77
+ }
78
+
79
+ /**
80
+ * TODO: The CSS styling is all messed up, including isError
81
+ * Warning: don't use this prop before this is resolved
82
+ * Issue to track: https://github.com/Luscii/web-ui/issues/57
83
+ * TODO: remove this comment once this is resolved
84
+ */
85
+ export const RadioV2 = React.forwardRef<HTMLInputElement, RadioProps>(
86
+ (props, ref) => <RadioInner {...props} innerRef={ref} />
87
+ );
@@ -6,6 +6,9 @@ import Radio from "../Radio/Radio";
6
6
 
7
7
  import "./RadioGroup.scss";
8
8
 
9
+ /**
10
+ * @deprecated: use RadioV2 instead
11
+ */
9
12
  function RadioGroup({
10
13
  className,
11
14
  radioClassName,