catchup-library-web 1.0.0 → 1.0.2
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.
- package/dist/index.d.mts +239 -2
- package/dist/index.d.ts +239 -2
- package/dist/index.js +4686 -2
- package/dist/index.mjs +4621 -1
- package/package.json +10 -2
- package/src/components/activities/DropdownActivityContent.tsx +73 -0
- package/src/components/activities/FillInTheBlanksActivityContent.tsx +102 -0
- package/src/components/activities/GroupingActivityContent.tsx +62 -0
- package/src/components/activities/MCMAActivityContent.tsx +65 -0
- package/src/components/activities/MCSAActivityContent.tsx +58 -0
- package/src/components/activities/MatchingActivityContent.tsx +57 -0
- package/src/components/activities/OpenEndedActivityContent.tsx +92 -0
- package/src/components/activities/OrderingActivityContent.tsx +59 -0
- package/src/components/activities/TrueFalseActivityContent.tsx +98 -0
- package/src/components/activities/body-content/ActivityBodyContent.tsx +108 -0
- package/src/components/activities/body-content/ShowBodyMediaByContentType.tsx +404 -0
- package/src/components/activities/empty-content/ActivityEmptyContent.tsx +15 -0
- package/src/components/activities/material-content/DropdownActivityMaterialContent.tsx +227 -0
- package/src/components/activities/material-content/FillInTheBlanksActivityMaterialContent.tsx +270 -0
- package/src/components/activities/material-content/GroupingActivityMaterialContent.tsx +359 -0
- package/src/components/activities/material-content/MCMAActivityMaterialContent.tsx +166 -0
- package/src/components/activities/material-content/MCSAActivityMaterialContent.tsx +165 -0
- package/src/components/activities/material-content/MatchingActivityMaterialContent.tsx +332 -0
- package/src/components/activities/material-content/OpenEndedActivityMaterialContent.tsx +818 -0
- package/src/components/activities/material-content/OrderingActivityMaterialContent.tsx +216 -0
- package/src/components/activities/material-content/ShowMaterialMediaByContentType.tsx +172 -0
- package/src/components/activities/material-content/TrueFalseActivityMaterialContent.tsx +217 -0
- package/src/components/activities/solution-content/ActivitySolutionContent.tsx +86 -0
- package/src/components/dividers/BlueVerticalDividerLine.tsx +13 -0
- package/src/components/dividers/DividerLine.tsx +5 -0
- package/src/components/dividers/VerticalDividerLine.tsx +5 -0
- package/src/components/dnds/DraggableDroppableItem.tsx +62 -0
- package/src/components/dnds/DraggableItem.tsx +41 -0
- package/src/components/dnds/DroppableItem.tsx +38 -0
- package/src/components/dropdowns/MediaDropdown.tsx +51 -0
- package/src/components/groups/InputGroup.tsx +330 -0
- package/src/hooks/useScreenSize.ts +40 -0
- package/src/index.ts +24 -0
- package/src/language/i18n.ts +10 -0
- package/src/properties/ActivityProperties.ts +204 -0
- package/src/properties/ButtonProperties.ts +1 -1
- package/src/properties/CommonProperties.ts +1 -1
- package/src/properties/DividerLineProperties.ts +3 -0
- package/src/properties/DnDProperties.ts +28 -0
- package/src/properties/DropdownProperties.ts +5 -0
- package/src/properties/EnumProperties.ts +11 -0
- package/src/properties/GroupProperties.ts +19 -0
- package/src/utilization/AppUtilization.ts +56 -0
- package/src/utilization/CatchtivityUtilization.ts +1566 -0
- package/src/utilization/StorageUtilization.ts +35 -0
- package/tsconfig.json +2 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IDividerLineProps } from "../../properties/DividerLineProperties";
|
|
2
|
+
|
|
3
|
+
const BlueVerticalDividerLine = ({ opacity }: IDividerLineProps) => {
|
|
4
|
+
return (
|
|
5
|
+
<div
|
|
6
|
+
className={`w-[2px] h-[40px] my-4 bg-catchup-blue ${
|
|
7
|
+
opacity === "medium" ? "opacity-50" : ""
|
|
8
|
+
}`}
|
|
9
|
+
/>
|
|
10
|
+
);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default BlueVerticalDividerLine;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
import { useDrag, useDrop } from "react-dnd";
|
|
3
|
+
import { IDraggableDroppableItemProps } from "../../properties/DnDProperties";
|
|
4
|
+
|
|
5
|
+
const DraggableDroppableItem = ({
|
|
6
|
+
key,
|
|
7
|
+
item,
|
|
8
|
+
type,
|
|
9
|
+
component,
|
|
10
|
+
moveCardHandler,
|
|
11
|
+
dropRef,
|
|
12
|
+
target,
|
|
13
|
+
setTarget,
|
|
14
|
+
}: IDraggableDroppableItemProps) => {
|
|
15
|
+
const ref = useRef(null);
|
|
16
|
+
|
|
17
|
+
const [, drop] = useDrop({
|
|
18
|
+
accept: type,
|
|
19
|
+
hover() {
|
|
20
|
+
if (!ref.current) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (item.index && target !== item.index) {
|
|
24
|
+
setTarget(item.index);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const [{ isDragging }, drag] = useDrag({
|
|
30
|
+
type,
|
|
31
|
+
item,
|
|
32
|
+
end: (item, monitor) => {
|
|
33
|
+
const dropResult = monitor.getDropResult();
|
|
34
|
+
if (dropResult) {
|
|
35
|
+
moveCardHandler();
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
collect: (monitor) => ({
|
|
39
|
+
isDragging: monitor.isDragging(),
|
|
40
|
+
}),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const opacity = isDragging ? 0.4 : 1;
|
|
44
|
+
|
|
45
|
+
drag(drop(ref));
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div
|
|
49
|
+
key={key}
|
|
50
|
+
className={`${
|
|
51
|
+
isDragging ? "w-[0px] opacity-0" : "w-full opacity-100"
|
|
52
|
+
} transition-all duration-500`}
|
|
53
|
+
ref={dropRef}
|
|
54
|
+
>
|
|
55
|
+
<div ref={ref} className="w-full" style={{ opacity }}>
|
|
56
|
+
{component}
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export default DraggableDroppableItem;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useDrag } from "react-dnd";
|
|
2
|
+
import { IDraggableItemProps } from "../../properties/DnDProperties";
|
|
3
|
+
|
|
4
|
+
const DraggableItem = ({
|
|
5
|
+
key,
|
|
6
|
+
item,
|
|
7
|
+
type,
|
|
8
|
+
component,
|
|
9
|
+
moveCardHandler,
|
|
10
|
+
}: IDraggableItemProps) => {
|
|
11
|
+
const [{ isDragging }, drag] = useDrag({
|
|
12
|
+
type,
|
|
13
|
+
item,
|
|
14
|
+
end: (item, monitor) => {
|
|
15
|
+
const dropResult = monitor.getDropResult();
|
|
16
|
+
if (dropResult) {
|
|
17
|
+
moveCardHandler();
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
collect: (monitor) => ({
|
|
21
|
+
isDragging: monitor.isDragging(),
|
|
22
|
+
}),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const opacity = isDragging ? 0.4 : 1;
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div
|
|
29
|
+
key={key}
|
|
30
|
+
className={`${
|
|
31
|
+
isDragging ? "w-[0px] opacity-0" : "opacity-100"
|
|
32
|
+
} transition-all duration-500`}
|
|
33
|
+
>
|
|
34
|
+
<div ref={drag} className="" style={{ opacity }}>
|
|
35
|
+
{component}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default DraggableItem;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
import { useDrop } from "react-dnd";
|
|
3
|
+
import { IDroppableItemProps } from "../../properties/DnDProperties";
|
|
4
|
+
|
|
5
|
+
const DroppableItem = ({
|
|
6
|
+
key,
|
|
7
|
+
item,
|
|
8
|
+
type,
|
|
9
|
+
component,
|
|
10
|
+
dropRef,
|
|
11
|
+
target,
|
|
12
|
+
setTarget,
|
|
13
|
+
}: IDroppableItemProps) => {
|
|
14
|
+
const ref = useRef(null);
|
|
15
|
+
|
|
16
|
+
const [, drop] = useDrop({
|
|
17
|
+
accept: type,
|
|
18
|
+
hover() {
|
|
19
|
+
if (item.index !== null && target !== item.index) {
|
|
20
|
+
setTarget(item.index);
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
dropRef(drop(ref));
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div
|
|
29
|
+
key={key}
|
|
30
|
+
className={`w-full transition-all duration-500 h-full`}
|
|
31
|
+
ref={ref}
|
|
32
|
+
>
|
|
33
|
+
{component}
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default DroppableItem;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { IDropdownProps } from "../../properties/DropdownProperties";
|
|
3
|
+
|
|
4
|
+
const MediaDropdown = ({ id, answer, optionList }: IDropdownProps) => {
|
|
5
|
+
const [showDropdown, setShowDropdown] = useState<boolean>(false);
|
|
6
|
+
|
|
7
|
+
return (
|
|
8
|
+
<div
|
|
9
|
+
key={id}
|
|
10
|
+
className="w-full relative"
|
|
11
|
+
onMouseEnter={() => {
|
|
12
|
+
setShowDropdown(true);
|
|
13
|
+
}}
|
|
14
|
+
onMouseLeave={() => {
|
|
15
|
+
setShowDropdown(false);
|
|
16
|
+
}}
|
|
17
|
+
>
|
|
18
|
+
<div className="w-full flex flex-col items-center justify-center">
|
|
19
|
+
{answer}
|
|
20
|
+
</div>
|
|
21
|
+
<ul
|
|
22
|
+
className={`absolute ${
|
|
23
|
+
showDropdown ? "opacity-100 visible" : "opacity-0 invisible"
|
|
24
|
+
} flex flex-col items-center w-[300px] rounded-catchup-xlarge border-3 transition-all duration-300 border-catchup-blue bg-catchup-white px-4 py-4 translate-x-1/2 right-1/2 mt-2 z-10`}
|
|
25
|
+
>
|
|
26
|
+
{optionList.map((option: any, index: number) => (
|
|
27
|
+
<li
|
|
28
|
+
key={option.id}
|
|
29
|
+
className={`${
|
|
30
|
+
option.listItemClassNames ? option.listItemClassNames : ""
|
|
31
|
+
}`}
|
|
32
|
+
>
|
|
33
|
+
<div
|
|
34
|
+
className={`w-full flex flex-col my-2 ${
|
|
35
|
+
option.divClassNames ? option.divClassNames : ""
|
|
36
|
+
}`}
|
|
37
|
+
onClick={option.onClick}
|
|
38
|
+
>
|
|
39
|
+
{option.media}
|
|
40
|
+
</div>
|
|
41
|
+
{index !== optionList.length - 1 ? (
|
|
42
|
+
<div className="w-full border my-1 border-catchup-light-blue rounded-catchup-full" />
|
|
43
|
+
) : null}
|
|
44
|
+
</li>
|
|
45
|
+
))}
|
|
46
|
+
</ul>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default MediaDropdown;
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import Select from "react-select";
|
|
2
|
+
import i18n from "../../language/i18n";
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { IInputGroupProps } from "../../properties/GroupProperties";
|
|
5
|
+
import BaseImage from "../images/BaseImage";
|
|
6
|
+
import { IOptionProps } from "../../properties/CommonProperties";
|
|
7
|
+
|
|
8
|
+
const InputGroup = ({
|
|
9
|
+
type,
|
|
10
|
+
title,
|
|
11
|
+
defaultValue,
|
|
12
|
+
placeholder,
|
|
13
|
+
value,
|
|
14
|
+
onFocus,
|
|
15
|
+
onChange,
|
|
16
|
+
onClick,
|
|
17
|
+
onKeyDown,
|
|
18
|
+
optionList,
|
|
19
|
+
errorText,
|
|
20
|
+
multiple,
|
|
21
|
+
accept,
|
|
22
|
+
theme,
|
|
23
|
+
useMinHeight,
|
|
24
|
+
disabled,
|
|
25
|
+
limit,
|
|
26
|
+
}: IInputGroupProps) => {
|
|
27
|
+
const textAreaRef = useRef<HTMLTextAreaElement>(null);
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!textAreaRef) return;
|
|
31
|
+
if (!textAreaRef.current) return;
|
|
32
|
+
if (value) {
|
|
33
|
+
textAreaRef.current.style.height = `${textAreaRef.current.scrollHeight}px`;
|
|
34
|
+
} else {
|
|
35
|
+
textAreaRef.current.style.height = `44px`;
|
|
36
|
+
}
|
|
37
|
+
}, [textAreaRef, value]);
|
|
38
|
+
|
|
39
|
+
const retrieveNullableOptionList = () => {
|
|
40
|
+
if (!optionList) return [];
|
|
41
|
+
const currentOptionList = {
|
|
42
|
+
text: i18n.t("option_please_select"),
|
|
43
|
+
value: "DEFAULT_OPTION",
|
|
44
|
+
};
|
|
45
|
+
return [currentOptionList, ...optionList];
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const convertOptionListToSelectComponent = (optionList: IOptionProps[]) => {
|
|
49
|
+
return optionList.map((option: IOptionProps) => ({
|
|
50
|
+
value: option.value,
|
|
51
|
+
label: option.text,
|
|
52
|
+
}));
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const handleTextAreaOnChange = (e: any) => {
|
|
56
|
+
if (!textAreaRef) return;
|
|
57
|
+
if (!textAreaRef.current) return;
|
|
58
|
+
textAreaRef.current.style.height = `30px`;
|
|
59
|
+
textAreaRef.current.style.height = `${e.target.scrollHeight + 6}px`;
|
|
60
|
+
if (limit) {
|
|
61
|
+
if (e.target.value.length <= limit) {
|
|
62
|
+
onChange && onChange(e);
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
onChange && onChange(e);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const CheckboxInputGroup = () => {
|
|
70
|
+
return (
|
|
71
|
+
<div
|
|
72
|
+
className="flex flex-row items-center gap-x-1 cursor-pointer"
|
|
73
|
+
onClick={onClick}
|
|
74
|
+
>
|
|
75
|
+
<BaseImage
|
|
76
|
+
src={value ? "/icons/checkbox.png" : "/icons/checkbox-empty.png"}
|
|
77
|
+
alt="checkbox"
|
|
78
|
+
size="xsmall"
|
|
79
|
+
onClick={() => {}}
|
|
80
|
+
/>
|
|
81
|
+
<p className="">{title}</p>
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const FileInputGroup = () => {
|
|
87
|
+
return (
|
|
88
|
+
<div className="my-1">
|
|
89
|
+
{title ? (
|
|
90
|
+
<p className="text-md font-semibold pl-2 py-1 text-catchup-gray-400">
|
|
91
|
+
{title}
|
|
92
|
+
</p>
|
|
93
|
+
) : null}
|
|
94
|
+
<input
|
|
95
|
+
className="w-full py-2 px-4 border border-catchup-gray-100 placeholder-catchup-gray-200 rounded-catchup-large text-black focus:outline-none focus:border-catchup-blue-400 focus:shadow-input"
|
|
96
|
+
type={type}
|
|
97
|
+
defaultValue={defaultValue}
|
|
98
|
+
placeholder={placeholder}
|
|
99
|
+
value={value}
|
|
100
|
+
onChange={onChange}
|
|
101
|
+
onClick={onClick}
|
|
102
|
+
multiple={multiple}
|
|
103
|
+
accept={accept}
|
|
104
|
+
/>
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const DateInputGroup = () => {
|
|
110
|
+
return (
|
|
111
|
+
<div className="my-1">
|
|
112
|
+
{title ? (
|
|
113
|
+
<p className="text-md font-semibold pl-2 py-1 text-catchup-gray-400">
|
|
114
|
+
{title}
|
|
115
|
+
</p>
|
|
116
|
+
) : null}
|
|
117
|
+
<input
|
|
118
|
+
className={`w-full py-2 px-4 border ${
|
|
119
|
+
errorText
|
|
120
|
+
? "border-catchup-red shadow-error"
|
|
121
|
+
: theme === "red"
|
|
122
|
+
? "border-catchup-red bg-catchup-red text-catchup-white focus:border-catchup-red"
|
|
123
|
+
: "border-catchup-gray-100 placeholder-catchup-gray-200 focus:border-catchup-blue-400"
|
|
124
|
+
} rounded-catchup-large text-black focus:outline-none focus:shadow-input`}
|
|
125
|
+
type={type}
|
|
126
|
+
defaultValue={defaultValue}
|
|
127
|
+
placeholder={placeholder}
|
|
128
|
+
value={value}
|
|
129
|
+
onChange={onChange}
|
|
130
|
+
disabled={disabled}
|
|
131
|
+
/>
|
|
132
|
+
</div>
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const SearchableSelectInputGroup = () => {
|
|
137
|
+
return (
|
|
138
|
+
<div className="my-1">
|
|
139
|
+
{title ? (
|
|
140
|
+
<p className="text-md font-semibold pl-2 py-1 text-catchup-gray-400 ">
|
|
141
|
+
{title}
|
|
142
|
+
</p>
|
|
143
|
+
) : null}
|
|
144
|
+
<Select
|
|
145
|
+
options={convertOptionListToSelectComponent(
|
|
146
|
+
retrieveNullableOptionList()
|
|
147
|
+
)}
|
|
148
|
+
className={`w-full`}
|
|
149
|
+
styles={{
|
|
150
|
+
control: (baseStyles: any, state: any) => ({
|
|
151
|
+
...baseStyles,
|
|
152
|
+
borderWidth: 1,
|
|
153
|
+
borderStyle: "solid",
|
|
154
|
+
borderRadius: 16,
|
|
155
|
+
borderColor: errorText
|
|
156
|
+
? "#ff6b6b"
|
|
157
|
+
: theme === "red"
|
|
158
|
+
? "#ff6b6b"
|
|
159
|
+
: state.isFocused
|
|
160
|
+
? "#73d7e6"
|
|
161
|
+
: state.isActive
|
|
162
|
+
? "#d2dde1"
|
|
163
|
+
: "#d2dde1",
|
|
164
|
+
backgroundColor: theme !== "red" ? "#ffffff" : "#ff6b6b",
|
|
165
|
+
paddingRight: 6,
|
|
166
|
+
paddingLeft: 6,
|
|
167
|
+
paddingTop: 2,
|
|
168
|
+
paddingBottom: 2,
|
|
169
|
+
outline: "none",
|
|
170
|
+
margin: 0,
|
|
171
|
+
text: theme === "red" ? "#ffffff" : "#55777f",
|
|
172
|
+
boxShadow: errorText
|
|
173
|
+
? "0px 0px 7px 0px rgba(255, 107, 107, 1)"
|
|
174
|
+
: state.isFocused
|
|
175
|
+
? "0px 0px 7px 0px rgba(115, 215, 230, 100)"
|
|
176
|
+
: "none",
|
|
177
|
+
"&:hover": {
|
|
178
|
+
outline: "none",
|
|
179
|
+
},
|
|
180
|
+
}),
|
|
181
|
+
menu: (baseStyles: any, state: any) => ({
|
|
182
|
+
...baseStyles,
|
|
183
|
+
borderRadius: 16,
|
|
184
|
+
paddingTop: 10,
|
|
185
|
+
paddingBottom: 10,
|
|
186
|
+
boxShadow: "0px 0px 6px 0px rgba(0, 0, 0, 0.25)",
|
|
187
|
+
}),
|
|
188
|
+
option: (baseStyles: any, state: any) => ({
|
|
189
|
+
...baseStyles,
|
|
190
|
+
color: state.isSelected ? "#2b3a41" : "#2b3a41",
|
|
191
|
+
backgroundColor: state.isSelected ? "#eaecf1" : "",
|
|
192
|
+
"&:hover": {
|
|
193
|
+
backgroundColor: "#eaecf1",
|
|
194
|
+
},
|
|
195
|
+
paddingLeft: 20,
|
|
196
|
+
paddingRight: 20,
|
|
197
|
+
}),
|
|
198
|
+
dropdownIndicator: (baseStyles: any, state: any) => ({
|
|
199
|
+
...baseStyles,
|
|
200
|
+
color: state.isFocused ? "#57c2d3" : "#55777f",
|
|
201
|
+
"&:hover": {
|
|
202
|
+
color: state.isFocused ? "#57c2d3" : "#55777f",
|
|
203
|
+
},
|
|
204
|
+
}),
|
|
205
|
+
}}
|
|
206
|
+
components={{
|
|
207
|
+
IndicatorSeparator: () => null,
|
|
208
|
+
}}
|
|
209
|
+
value={convertOptionListToSelectComponent(
|
|
210
|
+
retrieveNullableOptionList()
|
|
211
|
+
).find((option) => option.value === value)}
|
|
212
|
+
onChange={(target: any) => {
|
|
213
|
+
const event = { target };
|
|
214
|
+
onChange && onChange(event);
|
|
215
|
+
}}
|
|
216
|
+
/>
|
|
217
|
+
</div>
|
|
218
|
+
);
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const TextAreaInputGroup = () => {
|
|
222
|
+
return (
|
|
223
|
+
<div className="my-1 flex-1 flex flex-col relative">
|
|
224
|
+
<div className="flex flex-row justify-between items-center">
|
|
225
|
+
<div>
|
|
226
|
+
{title ? (
|
|
227
|
+
<p className="text-md font-semibold pl-2 py-1 text-catchup-gray-400">
|
|
228
|
+
{title}
|
|
229
|
+
</p>
|
|
230
|
+
) : null}
|
|
231
|
+
</div>
|
|
232
|
+
<div>
|
|
233
|
+
{limit ? (
|
|
234
|
+
<p className="text-md font-semibold pr-2 py-1 text-catchup-gray-400">
|
|
235
|
+
{value.length} / {limit}
|
|
236
|
+
</p>
|
|
237
|
+
) : null}
|
|
238
|
+
</div>
|
|
239
|
+
</div>
|
|
240
|
+
<textarea
|
|
241
|
+
ref={textAreaRef}
|
|
242
|
+
disabled={disabled}
|
|
243
|
+
className={`w-full ${
|
|
244
|
+
useMinHeight ? "min-h-[250px]" : ""
|
|
245
|
+
} resize-none overflow-hidden py-2 px-4 border ${
|
|
246
|
+
errorText
|
|
247
|
+
? "border-catchup-red shadow-error placeholder:text-catchup-red placeholder:opacity-80"
|
|
248
|
+
: "border-catchup-gray-100"
|
|
249
|
+
} placeholder-catchup-gray-200 rounded-catchup-large focus:outline-none focus:border-catchup-blue-400 ${
|
|
250
|
+
disabled ? "bg-catchup-lighter-gray" : null
|
|
251
|
+
} focus:shadow-input`}
|
|
252
|
+
placeholder={errorText ? errorText : placeholder}
|
|
253
|
+
value={value}
|
|
254
|
+
onLoad={(e) => {
|
|
255
|
+
console.log(e);
|
|
256
|
+
}}
|
|
257
|
+
onChange={handleTextAreaOnChange}
|
|
258
|
+
onFocus={onFocus}
|
|
259
|
+
onKeyDown={onKeyDown}
|
|
260
|
+
/>
|
|
261
|
+
{/* <div
|
|
262
|
+
className={`${
|
|
263
|
+
title ? "absolute top-0 right-0" : "absolute top-3 left-5"
|
|
264
|
+
}`}
|
|
265
|
+
>
|
|
266
|
+
<p className="italic text-catchup-red opacity-70">{errorText}</p>
|
|
267
|
+
</div> */}
|
|
268
|
+
</div>
|
|
269
|
+
);
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const TextInputGroup = () => {
|
|
273
|
+
return (
|
|
274
|
+
<div className="my-1 relative">
|
|
275
|
+
{title ? (
|
|
276
|
+
<p className="text-md font-semibold pl-2 py-1 text-catchup-gray-400">
|
|
277
|
+
{title}
|
|
278
|
+
</p>
|
|
279
|
+
) : null}
|
|
280
|
+
<input
|
|
281
|
+
disabled={disabled}
|
|
282
|
+
className={`w-full py-2 px-4 border ${
|
|
283
|
+
errorText
|
|
284
|
+
? "border-catchup-red shadow-error placeholder:text-catchup-red placeholder:opacity-80"
|
|
285
|
+
: "border-catchup-gray-100"
|
|
286
|
+
} rounded-catchup-large focus:outline-none placeholder-catchup-gray-200 focus:border-catchup-blue-400 ${
|
|
287
|
+
disabled ? "bg-catchup-lighter-gray" : null
|
|
288
|
+
} focus:shadow-input`}
|
|
289
|
+
type={type}
|
|
290
|
+
defaultValue={defaultValue}
|
|
291
|
+
placeholder={errorText ? errorText : placeholder}
|
|
292
|
+
value={value}
|
|
293
|
+
onChange={onChange}
|
|
294
|
+
onFocus={onFocus}
|
|
295
|
+
onKeyDown={onKeyDown}
|
|
296
|
+
/>
|
|
297
|
+
|
|
298
|
+
{/* <div
|
|
299
|
+
className={`${
|
|
300
|
+
title ? "absolute top-0 right-0" : "absolute top-3 left-5"
|
|
301
|
+
}`}
|
|
302
|
+
>
|
|
303
|
+
<p className="italic text-catchup-red opacity-70">{errorText}</p>
|
|
304
|
+
</div> */}
|
|
305
|
+
</div>
|
|
306
|
+
);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
const RenderMainContent = () => {
|
|
310
|
+
if (type === "text" || type === "number") {
|
|
311
|
+
return TextInputGroup();
|
|
312
|
+
} else if (type === "textarea") {
|
|
313
|
+
return TextAreaInputGroup();
|
|
314
|
+
} else if (type === "password") {
|
|
315
|
+
return TextInputGroup();
|
|
316
|
+
} else if (type === "select") {
|
|
317
|
+
return SearchableSelectInputGroup();
|
|
318
|
+
} else if (type === "date" || type === "datetime-local") {
|
|
319
|
+
return DateInputGroup();
|
|
320
|
+
} else if (type === "file") {
|
|
321
|
+
return FileInputGroup();
|
|
322
|
+
} else if (type === "checkbox") {
|
|
323
|
+
return CheckboxInputGroup();
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
return RenderMainContent();
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
export default InputGroup;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
const useScreenSize = () => {
|
|
4
|
+
const [containerSize, setContainerSize] = useState({
|
|
5
|
+
width: 0,
|
|
6
|
+
height: 0,
|
|
7
|
+
});
|
|
8
|
+
const [screenSize, setScreenSize] = useState({
|
|
9
|
+
width: window.innerWidth,
|
|
10
|
+
height: window.innerHeight,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const handleResize = () => {
|
|
15
|
+
setScreenSize({
|
|
16
|
+
width: window.innerWidth,
|
|
17
|
+
height: window.innerHeight,
|
|
18
|
+
});
|
|
19
|
+
const container = document.getElementById("container");
|
|
20
|
+
if (!container) return;
|
|
21
|
+
const boundingClientRect = container.getBoundingClientRect();
|
|
22
|
+
setContainerSize({
|
|
23
|
+
width: boundingClientRect.width,
|
|
24
|
+
height: boundingClientRect.height,
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
handleResize();
|
|
28
|
+
|
|
29
|
+
window.addEventListener("resize", handleResize);
|
|
30
|
+
|
|
31
|
+
// Clean up the event listener when the component unmounts
|
|
32
|
+
return () => {
|
|
33
|
+
window.removeEventListener("resize", handleResize);
|
|
34
|
+
};
|
|
35
|
+
}, []);
|
|
36
|
+
|
|
37
|
+
return { screenSize, containerSize };
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default useScreenSize;
|
package/src/index.ts
CHANGED
|
@@ -8,3 +8,27 @@ export { default as ApproveButton } from "./components/buttons/ApproveButton";
|
|
|
8
8
|
export { default as BaseImage } from "./components/images/BaseImage";
|
|
9
9
|
|
|
10
10
|
export { default as BaseLoading } from "./components/loading/BaseLoading";
|
|
11
|
+
|
|
12
|
+
export { default as DropdownActivityContent } from "./components/activities/DropdownActivityContent";
|
|
13
|
+
export { default as FillInTheBlanksActivityContent } from "./components/activities/FillInTheBlanksActivityContent";
|
|
14
|
+
export { default as GroupingActivityContent } from "./components/activities/GroupingActivityContent";
|
|
15
|
+
export { default as MatchingActivityContent } from "./components/activities/MatchingActivityContent";
|
|
16
|
+
export { default as MCMAActivityContent } from "./components/activities/MCMAActivityContent";
|
|
17
|
+
export { default as MCSAActivityContent } from "./components/activities/MCSAActivityContent";
|
|
18
|
+
export { default as OpenEndedActivityContent } from "./components/activities/OpenEndedActivityContent";
|
|
19
|
+
export { default as OrderingActivityContent } from "./components/activities/OrderingActivityContent";
|
|
20
|
+
export { default as TrueFalseActivityContent } from "./components/activities/TrueFalseActivityContent";
|
|
21
|
+
|
|
22
|
+
export { default as BlueVerticalDividerLine } from "./components/dividers/BlueVerticalDividerLine";
|
|
23
|
+
export { default as DividerLine } from "./components/dividers/DividerLine";
|
|
24
|
+
export { default as VerticalDividerLine } from "./components/dividers/VerticalDividerLine";
|
|
25
|
+
|
|
26
|
+
export { default as InputGroup } from "./components/groups/InputGroup";
|
|
27
|
+
|
|
28
|
+
export { default as useScreenSize } from "./hooks/useScreenSize";
|
|
29
|
+
|
|
30
|
+
export { default as i18n } from "./language/i18n";
|
|
31
|
+
|
|
32
|
+
export * from "./utilization/AppUtilization";
|
|
33
|
+
export * from "./utilization/CatchtivityUtilization";
|
|
34
|
+
export * from "./utilization/StorageUtilization";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import i18n from "i18next";
|
|
2
|
+
import { initReactI18next } from "react-i18next";
|
|
3
|
+
|
|
4
|
+
// the translations
|
|
5
|
+
// (tip move them in a JSON file and import them,
|
|
6
|
+
// or even better, manage them separated from your code: https://react.i18next.com/guides/multiple-translation-files)
|
|
7
|
+
|
|
8
|
+
i18n.use(initReactI18next);
|
|
9
|
+
|
|
10
|
+
export default i18n;
|