@rpg-engine/long-bow 0.1.78 → 0.1.79
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/LICENSE +20 -20
- package/README.md +181 -181
- package/dist/components/store/UI.store.d.ts +3 -0
- package/dist/long-bow.cjs.development.js +19 -10
- package/dist/long-bow.cjs.development.js.map +1 -1
- package/dist/long-bow.cjs.production.min.js +1 -1
- package/dist/long-bow.cjs.production.min.js.map +1 -1
- package/dist/long-bow.esm.js +19 -10
- package/dist/long-bow.esm.js.map +1 -1
- package/package.json +96 -96
- package/src/components/Abstractions/SlotsContainer.tsx +42 -42
- package/src/components/Button.tsx +29 -29
- package/src/components/Chat/Chat.tsx +193 -193
- package/src/components/CheckButton.tsx +65 -65
- package/src/components/DraggableContainer.tsx +150 -150
- package/src/components/Dropdown.tsx +57 -57
- package/src/components/Equipment/EquipmentSet.tsx +179 -179
- package/src/components/Input.tsx +11 -11
- package/src/components/Item/Cards/ItemCard.tsx +36 -36
- package/src/components/Item/Inventory/ItemContainer.tsx +113 -113
- package/src/components/Item/Inventory/ItemSlot.tsx +158 -158
- package/src/components/Item/Inventory/itemContainerHelper.ts +81 -81
- package/src/components/ListMenu.tsx +65 -65
- package/src/components/Multitab/Tab.tsx +57 -57
- package/src/components/Multitab/TabBody.tsx +13 -13
- package/src/components/Multitab/TabsContainer.tsx +97 -97
- package/src/components/NPCDialog/NPCDialog.tsx +145 -145
- package/src/components/NPCDialog/NPCDialogText.tsx +53 -53
- package/src/components/NPCDialog/QuestionDialog/QuestionDialog.tsx +242 -242
- package/src/components/ProgressBar.tsx +91 -91
- package/src/components/RPGUIContainer.tsx +47 -47
- package/src/components/RPGUIRoot.tsx +14 -14
- package/src/components/RadioButton.tsx +53 -53
- package/src/components/RangeSlider.tsx +68 -68
- package/src/components/ScrollList.tsx +77 -77
- package/src/components/SimpleProgressBar.tsx +62 -62
- package/src/components/SkillProgressBar.tsx +124 -124
- package/src/components/SkillsContainer.tsx +235 -235
- package/src/components/TextArea.tsx +11 -11
- package/src/components/Truncate.tsx +25 -25
- package/src/components/shared/Column.tsx +16 -16
- package/src/components/shared/SpriteFromAtlas.tsx +99 -99
- package/src/components/shared/SpriteIcon.tsx +67 -67
- package/src/components/store/UI.store.ts +205 -192
- package/src/components/typography/DynamicText.tsx +49 -49
- package/src/constants/uiColors.ts +10 -10
- package/src/hooks/useEventListener.ts +21 -21
- package/src/hooks/useOutsideAlerter.ts +25 -25
- package/src/index.tsx +25 -25
- package/src/libs/StringHelpers.ts +3 -3
- package/src/mocks/atlas/icons/icons.json +303 -303
- package/src/mocks/atlas/items/items.json +5195 -5195
- package/src/mocks/equipmentSet.mocks.ts +347 -347
- package/src/mocks/itemContainer.mocks.ts +249 -249
- package/src/mocks/skills.mocks.ts +122 -122
- package/src/types/eventTypes.ts +4 -4
- package/src/types/index.d.ts +2 -2
|
@@ -1,193 +1,193 @@
|
|
|
1
|
-
import { IChatMessage } from '@rpg-engine/shared';
|
|
2
|
-
import dayjs from 'dayjs';
|
|
3
|
-
import React, { useEffect, useState } from 'react';
|
|
4
|
-
import { ErrorBoundary } from 'react-error-boundary';
|
|
5
|
-
import styled from 'styled-components';
|
|
6
|
-
import { colors } from '../../constants/uiColors';
|
|
7
|
-
import { Button, ButtonTypes } from '../Button';
|
|
8
|
-
import { Input } from '../Input';
|
|
9
|
-
import { RPGUIContainer, RPGUIContainerTypes } from '../RPGUIContainer';
|
|
10
|
-
import { Column } from '../shared/Column';
|
|
11
|
-
|
|
12
|
-
interface IEmitter {
|
|
13
|
-
_id: string;
|
|
14
|
-
name: string;
|
|
15
|
-
}
|
|
16
|
-
export interface IChatProps {
|
|
17
|
-
chatMessages: IChatMessage[];
|
|
18
|
-
onSendChatMessage: (message: string) => void;
|
|
19
|
-
onCloseButton: () => void;
|
|
20
|
-
opacity?: number;
|
|
21
|
-
width?: string;
|
|
22
|
-
height?: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const Chat: React.FC<IChatProps> = ({
|
|
26
|
-
chatMessages,
|
|
27
|
-
onSendChatMessage,
|
|
28
|
-
opacity = 1,
|
|
29
|
-
width = '100%',
|
|
30
|
-
height = '250px',
|
|
31
|
-
onCloseButton,
|
|
32
|
-
}) => {
|
|
33
|
-
const [message, setMessage] = useState('');
|
|
34
|
-
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
scrollChatToBottom();
|
|
37
|
-
}, []);
|
|
38
|
-
|
|
39
|
-
useEffect(() => {
|
|
40
|
-
scrollChatToBottom();
|
|
41
|
-
}, [chatMessages]);
|
|
42
|
-
|
|
43
|
-
const scrollChatToBottom = () => {
|
|
44
|
-
const scrollingElement = document.querySelector('.chat-body');
|
|
45
|
-
if (scrollingElement) {
|
|
46
|
-
scrollingElement.scrollTop = scrollingElement.scrollHeight;
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const handleSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
|
|
51
|
-
event.preventDefault();
|
|
52
|
-
onSendChatMessage(message);
|
|
53
|
-
setMessage('');
|
|
54
|
-
};
|
|
55
|
-
const getInputValue = (value: string) => {
|
|
56
|
-
setMessage(value);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const onRenderMessageLines = (
|
|
60
|
-
emitter: IEmitter,
|
|
61
|
-
createdAt: string | undefined,
|
|
62
|
-
message: string
|
|
63
|
-
) => {
|
|
64
|
-
return `${dayjs(createdAt || new Date()).format('HH:mm')} ${
|
|
65
|
-
emitter?.name ? `${emitter.name}: ` : 'Unknown: '
|
|
66
|
-
} ${message}`;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const onRenderChatMessages = (chatMessages: IChatMessage[]) => {
|
|
70
|
-
return chatMessages?.length ? (
|
|
71
|
-
chatMessages?.map(({ _id, createdAt, emitter, message }, index) => (
|
|
72
|
-
<MessageText key={`${_id}_${index}`}>
|
|
73
|
-
{onRenderMessageLines(emitter, createdAt, message)}
|
|
74
|
-
</MessageText>
|
|
75
|
-
))
|
|
76
|
-
) : (
|
|
77
|
-
<MessageText>No messages available.</MessageText>
|
|
78
|
-
);
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
return (
|
|
82
|
-
<Container>
|
|
83
|
-
<CustomContainer
|
|
84
|
-
type={RPGUIContainerTypes.FramedGrey}
|
|
85
|
-
width={width}
|
|
86
|
-
height={height}
|
|
87
|
-
className="chat-container"
|
|
88
|
-
opacity={opacity}
|
|
89
|
-
>
|
|
90
|
-
<ErrorBoundary fallback={<p>Oops! Your chat has crashed.</p>}>
|
|
91
|
-
{onCloseButton && (
|
|
92
|
-
<CloseButton onClick={onCloseButton} onTouchStart={onCloseButton}>
|
|
93
|
-
X
|
|
94
|
-
</CloseButton>
|
|
95
|
-
)}
|
|
96
|
-
<RPGUIContainer
|
|
97
|
-
type={RPGUIContainerTypes.FramedGrey}
|
|
98
|
-
width={'100%'}
|
|
99
|
-
height={'80%'}
|
|
100
|
-
className="chat-body dark-background"
|
|
101
|
-
>
|
|
102
|
-
{onRenderChatMessages(chatMessages)}
|
|
103
|
-
</RPGUIContainer>
|
|
104
|
-
|
|
105
|
-
<Form onSubmit={handleSubmit}>
|
|
106
|
-
<Column flex={70}>
|
|
107
|
-
<CustomInput
|
|
108
|
-
value={message}
|
|
109
|
-
id="inputMessage"
|
|
110
|
-
onChange={e => getInputValue(e.target.value)}
|
|
111
|
-
height={20}
|
|
112
|
-
className="chat-input dark-background"
|
|
113
|
-
type="text"
|
|
114
|
-
autoComplete="off"
|
|
115
|
-
/>
|
|
116
|
-
</Column>
|
|
117
|
-
<Column justifyContent="flex-end">
|
|
118
|
-
<Button
|
|
119
|
-
buttonType={ButtonTypes.RPGUIButton}
|
|
120
|
-
id="chat-send-button"
|
|
121
|
-
>
|
|
122
|
-
Send
|
|
123
|
-
</Button>
|
|
124
|
-
</Column>
|
|
125
|
-
</Form>
|
|
126
|
-
</ErrorBoundary>
|
|
127
|
-
</CustomContainer>
|
|
128
|
-
</Container>
|
|
129
|
-
);
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
const Container = styled.div`
|
|
133
|
-
position: relative;
|
|
134
|
-
`;
|
|
135
|
-
|
|
136
|
-
const CloseButton = styled.div`
|
|
137
|
-
position: absolute;
|
|
138
|
-
top: 2px;
|
|
139
|
-
right: 0px;
|
|
140
|
-
color: white;
|
|
141
|
-
z-index: 22;
|
|
142
|
-
font-size: 0.7rem;
|
|
143
|
-
`;
|
|
144
|
-
|
|
145
|
-
const CustomInput = styled(Input)`
|
|
146
|
-
height: 30px;
|
|
147
|
-
width: 100%;
|
|
148
|
-
|
|
149
|
-
.rpgui-content .input {
|
|
150
|
-
min-height: 39px;
|
|
151
|
-
}
|
|
152
|
-
`;
|
|
153
|
-
|
|
154
|
-
interface ICustomContainerProps {
|
|
155
|
-
opacity: number;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const CustomContainer = styled(RPGUIContainer)`
|
|
159
|
-
display: block;
|
|
160
|
-
|
|
161
|
-
opacity: ${(props: ICustomContainerProps) => props.opacity};
|
|
162
|
-
|
|
163
|
-
&:hover {
|
|
164
|
-
opacity: 1;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
.dark-background {
|
|
168
|
-
background-color: ${colors.darkGrey} !important;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
.chat-body {
|
|
172
|
-
&.rpgui-container.framed-grey {
|
|
173
|
-
background: unset;
|
|
174
|
-
}
|
|
175
|
-
max-height: 170px;
|
|
176
|
-
overflow-y: auto;
|
|
177
|
-
}
|
|
178
|
-
`;
|
|
179
|
-
|
|
180
|
-
const Form = styled.form`
|
|
181
|
-
display: flex;
|
|
182
|
-
width: 100%;
|
|
183
|
-
justify-content: center;
|
|
184
|
-
align-items: center;
|
|
185
|
-
`;
|
|
186
|
-
|
|
187
|
-
const MessageText = styled.p`
|
|
188
|
-
display: block !important;
|
|
189
|
-
width: 100%;
|
|
190
|
-
font-size: 0.7rem !important;
|
|
191
|
-
overflow-y: auto;
|
|
192
|
-
margin: 0;
|
|
193
|
-
`;
|
|
1
|
+
import { IChatMessage } from '@rpg-engine/shared';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
3
|
+
import React, { useEffect, useState } from 'react';
|
|
4
|
+
import { ErrorBoundary } from 'react-error-boundary';
|
|
5
|
+
import styled from 'styled-components';
|
|
6
|
+
import { colors } from '../../constants/uiColors';
|
|
7
|
+
import { Button, ButtonTypes } from '../Button';
|
|
8
|
+
import { Input } from '../Input';
|
|
9
|
+
import { RPGUIContainer, RPGUIContainerTypes } from '../RPGUIContainer';
|
|
10
|
+
import { Column } from '../shared/Column';
|
|
11
|
+
|
|
12
|
+
interface IEmitter {
|
|
13
|
+
_id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
}
|
|
16
|
+
export interface IChatProps {
|
|
17
|
+
chatMessages: IChatMessage[];
|
|
18
|
+
onSendChatMessage: (message: string) => void;
|
|
19
|
+
onCloseButton: () => void;
|
|
20
|
+
opacity?: number;
|
|
21
|
+
width?: string;
|
|
22
|
+
height?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const Chat: React.FC<IChatProps> = ({
|
|
26
|
+
chatMessages,
|
|
27
|
+
onSendChatMessage,
|
|
28
|
+
opacity = 1,
|
|
29
|
+
width = '100%',
|
|
30
|
+
height = '250px',
|
|
31
|
+
onCloseButton,
|
|
32
|
+
}) => {
|
|
33
|
+
const [message, setMessage] = useState('');
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
scrollChatToBottom();
|
|
37
|
+
}, []);
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
scrollChatToBottom();
|
|
41
|
+
}, [chatMessages]);
|
|
42
|
+
|
|
43
|
+
const scrollChatToBottom = () => {
|
|
44
|
+
const scrollingElement = document.querySelector('.chat-body');
|
|
45
|
+
if (scrollingElement) {
|
|
46
|
+
scrollingElement.scrollTop = scrollingElement.scrollHeight;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const handleSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
|
|
51
|
+
event.preventDefault();
|
|
52
|
+
onSendChatMessage(message);
|
|
53
|
+
setMessage('');
|
|
54
|
+
};
|
|
55
|
+
const getInputValue = (value: string) => {
|
|
56
|
+
setMessage(value);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const onRenderMessageLines = (
|
|
60
|
+
emitter: IEmitter,
|
|
61
|
+
createdAt: string | undefined,
|
|
62
|
+
message: string
|
|
63
|
+
) => {
|
|
64
|
+
return `${dayjs(createdAt || new Date()).format('HH:mm')} ${
|
|
65
|
+
emitter?.name ? `${emitter.name}: ` : 'Unknown: '
|
|
66
|
+
} ${message}`;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const onRenderChatMessages = (chatMessages: IChatMessage[]) => {
|
|
70
|
+
return chatMessages?.length ? (
|
|
71
|
+
chatMessages?.map(({ _id, createdAt, emitter, message }, index) => (
|
|
72
|
+
<MessageText key={`${_id}_${index}`}>
|
|
73
|
+
{onRenderMessageLines(emitter, createdAt, message)}
|
|
74
|
+
</MessageText>
|
|
75
|
+
))
|
|
76
|
+
) : (
|
|
77
|
+
<MessageText>No messages available.</MessageText>
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<Container>
|
|
83
|
+
<CustomContainer
|
|
84
|
+
type={RPGUIContainerTypes.FramedGrey}
|
|
85
|
+
width={width}
|
|
86
|
+
height={height}
|
|
87
|
+
className="chat-container"
|
|
88
|
+
opacity={opacity}
|
|
89
|
+
>
|
|
90
|
+
<ErrorBoundary fallback={<p>Oops! Your chat has crashed.</p>}>
|
|
91
|
+
{onCloseButton && (
|
|
92
|
+
<CloseButton onClick={onCloseButton} onTouchStart={onCloseButton}>
|
|
93
|
+
X
|
|
94
|
+
</CloseButton>
|
|
95
|
+
)}
|
|
96
|
+
<RPGUIContainer
|
|
97
|
+
type={RPGUIContainerTypes.FramedGrey}
|
|
98
|
+
width={'100%'}
|
|
99
|
+
height={'80%'}
|
|
100
|
+
className="chat-body dark-background"
|
|
101
|
+
>
|
|
102
|
+
{onRenderChatMessages(chatMessages)}
|
|
103
|
+
</RPGUIContainer>
|
|
104
|
+
|
|
105
|
+
<Form onSubmit={handleSubmit}>
|
|
106
|
+
<Column flex={70}>
|
|
107
|
+
<CustomInput
|
|
108
|
+
value={message}
|
|
109
|
+
id="inputMessage"
|
|
110
|
+
onChange={e => getInputValue(e.target.value)}
|
|
111
|
+
height={20}
|
|
112
|
+
className="chat-input dark-background"
|
|
113
|
+
type="text"
|
|
114
|
+
autoComplete="off"
|
|
115
|
+
/>
|
|
116
|
+
</Column>
|
|
117
|
+
<Column justifyContent="flex-end">
|
|
118
|
+
<Button
|
|
119
|
+
buttonType={ButtonTypes.RPGUIButton}
|
|
120
|
+
id="chat-send-button"
|
|
121
|
+
>
|
|
122
|
+
Send
|
|
123
|
+
</Button>
|
|
124
|
+
</Column>
|
|
125
|
+
</Form>
|
|
126
|
+
</ErrorBoundary>
|
|
127
|
+
</CustomContainer>
|
|
128
|
+
</Container>
|
|
129
|
+
);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const Container = styled.div`
|
|
133
|
+
position: relative;
|
|
134
|
+
`;
|
|
135
|
+
|
|
136
|
+
const CloseButton = styled.div`
|
|
137
|
+
position: absolute;
|
|
138
|
+
top: 2px;
|
|
139
|
+
right: 0px;
|
|
140
|
+
color: white;
|
|
141
|
+
z-index: 22;
|
|
142
|
+
font-size: 0.7rem;
|
|
143
|
+
`;
|
|
144
|
+
|
|
145
|
+
const CustomInput = styled(Input)`
|
|
146
|
+
height: 30px;
|
|
147
|
+
width: 100%;
|
|
148
|
+
|
|
149
|
+
.rpgui-content .input {
|
|
150
|
+
min-height: 39px;
|
|
151
|
+
}
|
|
152
|
+
`;
|
|
153
|
+
|
|
154
|
+
interface ICustomContainerProps {
|
|
155
|
+
opacity: number;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const CustomContainer = styled(RPGUIContainer)`
|
|
159
|
+
display: block;
|
|
160
|
+
|
|
161
|
+
opacity: ${(props: ICustomContainerProps) => props.opacity};
|
|
162
|
+
|
|
163
|
+
&:hover {
|
|
164
|
+
opacity: 1;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.dark-background {
|
|
168
|
+
background-color: ${colors.darkGrey} !important;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.chat-body {
|
|
172
|
+
&.rpgui-container.framed-grey {
|
|
173
|
+
background: unset;
|
|
174
|
+
}
|
|
175
|
+
max-height: 170px;
|
|
176
|
+
overflow-y: auto;
|
|
177
|
+
}
|
|
178
|
+
`;
|
|
179
|
+
|
|
180
|
+
const Form = styled.form`
|
|
181
|
+
display: flex;
|
|
182
|
+
width: 100%;
|
|
183
|
+
justify-content: center;
|
|
184
|
+
align-items: center;
|
|
185
|
+
`;
|
|
186
|
+
|
|
187
|
+
const MessageText = styled.p`
|
|
188
|
+
display: block !important;
|
|
189
|
+
width: 100%;
|
|
190
|
+
font-size: 0.7rem !important;
|
|
191
|
+
overflow-y: auto;
|
|
192
|
+
margin: 0;
|
|
193
|
+
`;
|
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
export interface ICheckItems {
|
|
4
|
-
label: string;
|
|
5
|
-
value: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface ICheckProps {
|
|
9
|
-
items: ICheckItems[];
|
|
10
|
-
onChange: (selectedValues: IChecklistSelectedValues) => void;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface IChecklistSelectedValues {
|
|
14
|
-
[label: string]: boolean;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const CheckButton: React.FC<ICheckProps> = ({ items, onChange }) => {
|
|
18
|
-
const generateSelectedValuesList = () => {
|
|
19
|
-
const selectedValues: IChecklistSelectedValues = {};
|
|
20
|
-
|
|
21
|
-
items.forEach(item => {
|
|
22
|
-
selectedValues[item.label] = false;
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
return selectedValues;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const [selectedValues, setSelectedValues] = useState<
|
|
29
|
-
IChecklistSelectedValues
|
|
30
|
-
>(generateSelectedValuesList());
|
|
31
|
-
|
|
32
|
-
const handleClick = (label: string) => {
|
|
33
|
-
setSelectedValues({
|
|
34
|
-
...selectedValues,
|
|
35
|
-
[label]: !selectedValues[label],
|
|
36
|
-
});
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
useEffect(() => {
|
|
40
|
-
if (selectedValues) {
|
|
41
|
-
onChange(selectedValues);
|
|
42
|
-
}
|
|
43
|
-
}, [selectedValues]);
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<div id="elemento-checkbox">
|
|
47
|
-
{items?.map((element, index) => {
|
|
48
|
-
return (
|
|
49
|
-
<div key={`${element.label}_${index}`}>
|
|
50
|
-
<input
|
|
51
|
-
className="rpgui-checkbox"
|
|
52
|
-
type="checkbox"
|
|
53
|
-
checked={selectedValues[element.label]}
|
|
54
|
-
onChange={() => {}}
|
|
55
|
-
/>
|
|
56
|
-
<label onClick={() => handleClick(element.label)}>
|
|
57
|
-
{element.label}
|
|
58
|
-
</label>
|
|
59
|
-
<br />
|
|
60
|
-
</div>
|
|
61
|
-
);
|
|
62
|
-
})}
|
|
63
|
-
</div>
|
|
64
|
-
);
|
|
65
|
-
};
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface ICheckItems {
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ICheckProps {
|
|
9
|
+
items: ICheckItems[];
|
|
10
|
+
onChange: (selectedValues: IChecklistSelectedValues) => void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface IChecklistSelectedValues {
|
|
14
|
+
[label: string]: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const CheckButton: React.FC<ICheckProps> = ({ items, onChange }) => {
|
|
18
|
+
const generateSelectedValuesList = () => {
|
|
19
|
+
const selectedValues: IChecklistSelectedValues = {};
|
|
20
|
+
|
|
21
|
+
items.forEach(item => {
|
|
22
|
+
selectedValues[item.label] = false;
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return selectedValues;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const [selectedValues, setSelectedValues] = useState<
|
|
29
|
+
IChecklistSelectedValues
|
|
30
|
+
>(generateSelectedValuesList());
|
|
31
|
+
|
|
32
|
+
const handleClick = (label: string) => {
|
|
33
|
+
setSelectedValues({
|
|
34
|
+
...selectedValues,
|
|
35
|
+
[label]: !selectedValues[label],
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (selectedValues) {
|
|
41
|
+
onChange(selectedValues);
|
|
42
|
+
}
|
|
43
|
+
}, [selectedValues]);
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div id="elemento-checkbox">
|
|
47
|
+
{items?.map((element, index) => {
|
|
48
|
+
return (
|
|
49
|
+
<div key={`${element.label}_${index}`}>
|
|
50
|
+
<input
|
|
51
|
+
className="rpgui-checkbox"
|
|
52
|
+
type="checkbox"
|
|
53
|
+
checked={selectedValues[element.label]}
|
|
54
|
+
onChange={() => {}}
|
|
55
|
+
/>
|
|
56
|
+
<label onClick={() => handleClick(element.label)}>
|
|
57
|
+
{element.label}
|
|
58
|
+
</label>
|
|
59
|
+
<br />
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
})}
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
};
|