@rpg-engine/long-bow 0.8.44 → 0.8.45
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.
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Meta } from '@storybook/react';
|
|
2
|
+
import { ICharacterProps } from '../../../components/Character/CharacterSelection';
|
|
3
|
+
export interface ICharacterSkinSelectionModalProps {
|
|
4
|
+
isOpen: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
onConfirm: (textureKey: string) => void;
|
|
7
|
+
availableCharacters: ICharacterProps[];
|
|
8
|
+
atlasJSON: any;
|
|
9
|
+
atlasIMG: any;
|
|
10
|
+
initialSelectedSkin?: string;
|
|
11
|
+
}
|
|
12
|
+
declare const meta: Meta;
|
|
13
|
+
export default meta;
|
|
14
|
+
export declare const Default: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ICharacterSkinSelectionModalProps>;
|
|
15
|
+
export declare const EmptySelection: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ICharacterSkinSelectionModalProps>;
|
package/package.json
CHANGED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { Meta, Story } from '@storybook/react';
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
import { RPGUIRoot } from '../../..';
|
|
5
|
+
import { Button, ButtonTypes } from '../../../components/Button';
|
|
6
|
+
import CharacterSelection, { ICharacterProps } from '../../../components/Character/CharacterSelection';
|
|
7
|
+
import { DraggableContainer } from '../../../components/DraggableContainer';
|
|
8
|
+
import { RPGUIContainerTypes } from '../../../components/RPGUI/RPGUIContainer';
|
|
9
|
+
import atlasJSON from '../../../mocks/atlas/entities/entities.json';
|
|
10
|
+
import atlasIMG from '../../../mocks/atlas/entities/entities.png';
|
|
11
|
+
|
|
12
|
+
// Create the missing interface
|
|
13
|
+
export interface ICharacterSkinSelectionModalProps {
|
|
14
|
+
isOpen: boolean;
|
|
15
|
+
onClose: () => void;
|
|
16
|
+
onConfirm: (textureKey: string) => void;
|
|
17
|
+
availableCharacters: ICharacterProps[];
|
|
18
|
+
atlasJSON: any;
|
|
19
|
+
atlasIMG: any;
|
|
20
|
+
initialSelectedSkin?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Temporary component to replace the missing one
|
|
24
|
+
const CharacterSkinSelectionModal: React.FC<ICharacterSkinSelectionModalProps> = ({
|
|
25
|
+
isOpen,
|
|
26
|
+
onClose,
|
|
27
|
+
onConfirm,
|
|
28
|
+
availableCharacters,
|
|
29
|
+
atlasJSON,
|
|
30
|
+
atlasIMG,
|
|
31
|
+
initialSelectedSkin = '',
|
|
32
|
+
}) => {
|
|
33
|
+
const [selectedSkin, setSelectedSkin] = useState<string>(initialSelectedSkin);
|
|
34
|
+
|
|
35
|
+
// Determine if we have a valid skin selection to enable/disable confirm button
|
|
36
|
+
const isConfirmEnabled = Boolean(selectedSkin);
|
|
37
|
+
|
|
38
|
+
// Reset selected skin when initial value changes or component mounts
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
// Allow for empty strings but not undefined
|
|
41
|
+
if (initialSelectedSkin !== undefined) {
|
|
42
|
+
setSelectedSkin(initialSelectedSkin);
|
|
43
|
+
} else if (availableCharacters.length > 0) {
|
|
44
|
+
// Default to first skin if none provided
|
|
45
|
+
setSelectedSkin(availableCharacters[0].textureKey);
|
|
46
|
+
}
|
|
47
|
+
}, [initialSelectedSkin, availableCharacters]);
|
|
48
|
+
|
|
49
|
+
const handleConfirm = (): void => {
|
|
50
|
+
if (selectedSkin) {
|
|
51
|
+
onConfirm(selectedSkin);
|
|
52
|
+
onClose();
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const handleCancel = (): void => {
|
|
57
|
+
onClose();
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
if (!isOpen) return null;
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<ModalOverlay>
|
|
64
|
+
<DraggableContainer
|
|
65
|
+
type={RPGUIContainerTypes.Framed}
|
|
66
|
+
width="30rem"
|
|
67
|
+
onCloseButton={onClose}
|
|
68
|
+
title="Selecionar Skin"
|
|
69
|
+
>
|
|
70
|
+
<ModalContent>
|
|
71
|
+
<CharacterSelectionWrapper>
|
|
72
|
+
<CharacterSelection
|
|
73
|
+
availableCharacters={availableCharacters}
|
|
74
|
+
atlasJSON={atlasJSON}
|
|
75
|
+
atlasIMG={atlasIMG}
|
|
76
|
+
onChange={(textureKey) => setSelectedSkin(textureKey)}
|
|
77
|
+
/>
|
|
78
|
+
</CharacterSelectionWrapper>
|
|
79
|
+
|
|
80
|
+
<ButtonsContainer>
|
|
81
|
+
<Button
|
|
82
|
+
buttonType={ButtonTypes.RPGUIButton}
|
|
83
|
+
onClick={handleCancel}
|
|
84
|
+
>
|
|
85
|
+
Cancelar
|
|
86
|
+
</Button>
|
|
87
|
+
<Button
|
|
88
|
+
buttonType={ButtonTypes.RPGUIButton}
|
|
89
|
+
onClick={handleConfirm}
|
|
90
|
+
disabled={!isConfirmEnabled}
|
|
91
|
+
>
|
|
92
|
+
Confirmar
|
|
93
|
+
</Button>
|
|
94
|
+
</ButtonsContainer>
|
|
95
|
+
</ModalContent>
|
|
96
|
+
</DraggableContainer>
|
|
97
|
+
</ModalOverlay>
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const meta: Meta = {
|
|
102
|
+
title: 'Character/Character/Skin Selection Modal',
|
|
103
|
+
component: CharacterSkinSelectionModal,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export default meta;
|
|
107
|
+
|
|
108
|
+
const Template: Story<ICharacterSkinSelectionModalProps> = (args: ICharacterSkinSelectionModalProps) => (
|
|
109
|
+
<RPGUIRoot>
|
|
110
|
+
<CharacterSkinSelectionModal {...args} />
|
|
111
|
+
</RPGUIRoot>
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
export const Default = Template.bind({});
|
|
115
|
+
export const EmptySelection = Template.bind({});
|
|
116
|
+
|
|
117
|
+
// Dados de exemplo para os personagens disponíveis
|
|
118
|
+
const availableCharacters = [
|
|
119
|
+
{
|
|
120
|
+
name: 'Woman',
|
|
121
|
+
textureKey: 'woman-1',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: 'Kid',
|
|
125
|
+
textureKey: 'kid-1',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'Purple Hair Hero 1',
|
|
129
|
+
textureKey: 'purple-hair-hero-1',
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
Default.args = {
|
|
134
|
+
isOpen: true,
|
|
135
|
+
onClose: () => console.log('Modal fechado'),
|
|
136
|
+
onConfirm: (textureKey: string) => console.log('Skin selecionada:', textureKey),
|
|
137
|
+
availableCharacters: availableCharacters,
|
|
138
|
+
atlasJSON: atlasJSON,
|
|
139
|
+
atlasIMG: atlasIMG,
|
|
140
|
+
initialSelectedSkin: 'woman-1',
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
EmptySelection.args = {
|
|
144
|
+
isOpen: true,
|
|
145
|
+
onClose: () => console.log('Modal fechado'),
|
|
146
|
+
onConfirm: (textureKey: string) => console.log('Skin selecionada:', textureKey),
|
|
147
|
+
availableCharacters: availableCharacters,
|
|
148
|
+
atlasJSON: atlasJSON,
|
|
149
|
+
atlasIMG: atlasIMG,
|
|
150
|
+
initialSelectedSkin: '',
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// Componentes estilizados
|
|
154
|
+
const ModalOverlay = styled.div`
|
|
155
|
+
position: fixed;
|
|
156
|
+
top: 0;
|
|
157
|
+
left: 0;
|
|
158
|
+
right: 0;
|
|
159
|
+
bottom: 0;
|
|
160
|
+
display: flex;
|
|
161
|
+
align-items: center;
|
|
162
|
+
justify-content: center;
|
|
163
|
+
z-index: 100;
|
|
164
|
+
`;
|
|
165
|
+
|
|
166
|
+
const ModalContent = styled.div`
|
|
167
|
+
padding: 20px;
|
|
168
|
+
display: flex;
|
|
169
|
+
flex-direction: column;
|
|
170
|
+
align-items: center;
|
|
171
|
+
min-width: 300px;
|
|
172
|
+
`;
|
|
173
|
+
|
|
174
|
+
const CharacterSelectionWrapper = styled.div`
|
|
175
|
+
width: 100%;
|
|
176
|
+
margin-bottom: 20px;
|
|
177
|
+
`;
|
|
178
|
+
|
|
179
|
+
const ButtonsContainer = styled.div`
|
|
180
|
+
display: flex;
|
|
181
|
+
justify-content: space-between;
|
|
182
|
+
width: 100%;
|
|
183
|
+
margin-top: 20px;
|
|
184
|
+
|
|
185
|
+
button {
|
|
186
|
+
margin: 0 10px;
|
|
187
|
+
}
|
|
188
|
+
`;
|