@rpg-engine/long-bow 0.8.44 → 0.8.46
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/components/Character/CharacterSkinSelectionModal.d.ts +13 -0
- package/dist/index.d.ts +1 -0
- package/dist/stories/Character/character/CharacterSkinSelectionModal.stories.d.ts +5 -0
- package/package.json +1 -1
- package/src/components/Character/CharacterSkinSelectionModal.tsx +157 -0
- package/src/index.tsx +1 -0
- package/src/stories/Character/character/CharacterSkinSelectionModal.stories.tsx +49 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ICharacterProps } from './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 CharacterSkinSelectionModal: React.FC<ICharacterSkinSelectionModalProps>;
|
|
13
|
+
export default CharacterSkinSelectionModal;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from './components/Arrow/SelectArrow';
|
|
|
2
2
|
export * from './components/AsyncDropdown';
|
|
3
3
|
export * from './components/Button';
|
|
4
4
|
export * from './components/Character/CharacterSelection';
|
|
5
|
+
export * from './components/Character/CharacterSkinSelectionModal';
|
|
5
6
|
export * from './components/Chat/Chat';
|
|
6
7
|
export * from './components/Chatdeprecated/ChatDeprecated';
|
|
7
8
|
export * from './components/ChatRevamp/ChatRevamp';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Meta } from '@storybook/react';
|
|
2
|
+
import { ICharacterSkinSelectionModalProps } from '../../../components/Character/CharacterSkinSelectionModal';
|
|
3
|
+
declare const meta: Meta;
|
|
4
|
+
export default meta;
|
|
5
|
+
export declare const KnightSkins: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ICharacterSkinSelectionModalProps>;
|
package/package.json
CHANGED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
import { Button, ButtonTypes } from '../Button';
|
|
4
|
+
import { ErrorBoundary } from '../Item/Inventory/ErrorBoundary';
|
|
5
|
+
import PropertySelect, { IPropertiesProps } from '../PropertySelect/PropertySelect';
|
|
6
|
+
import { SpriteFromAtlas } from '../shared/SpriteFromAtlas';
|
|
7
|
+
import { ICharacterProps } from './CharacterSelection';
|
|
8
|
+
|
|
9
|
+
export interface ICharacterSkinSelectionModalProps {
|
|
10
|
+
isOpen: boolean;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
onConfirm: (textureKey: string) => void;
|
|
13
|
+
availableCharacters: ICharacterProps[];
|
|
14
|
+
atlasJSON: any;
|
|
15
|
+
atlasIMG: any;
|
|
16
|
+
initialSelectedSkin?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const CharacterSkinSelectionModal: React.FC<ICharacterSkinSelectionModalProps> = ({
|
|
20
|
+
isOpen,
|
|
21
|
+
onClose,
|
|
22
|
+
onConfirm,
|
|
23
|
+
availableCharacters,
|
|
24
|
+
atlasJSON,
|
|
25
|
+
atlasIMG,
|
|
26
|
+
initialSelectedSkin = '',
|
|
27
|
+
}) => {
|
|
28
|
+
// Convert availableCharacters to the format used by PropertySelect
|
|
29
|
+
const propertySelectValues = availableCharacters.map((item) => ({
|
|
30
|
+
id: item.textureKey,
|
|
31
|
+
name: item.name,
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
// State to store the selected skin and the sprite key
|
|
35
|
+
const [selectedValue, setSelectedValue] = useState<IPropertiesProps | undefined>();
|
|
36
|
+
const [selectedSpriteKey, setSelectedSpriteKey] = useState('');
|
|
37
|
+
|
|
38
|
+
// Update sprite when the selected value changes
|
|
39
|
+
const updateSelectedSpriteKey = () => {
|
|
40
|
+
const textureKey = selectedValue ? selectedValue.id : '';
|
|
41
|
+
const spriteKey = textureKey ? textureKey + '/down/standing/0.png' : '';
|
|
42
|
+
|
|
43
|
+
if (spriteKey === selectedSpriteKey) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
setSelectedSpriteKey(spriteKey);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// Update sprite when selectedValue changes
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
updateSelectedSpriteKey();
|
|
53
|
+
}, [selectedValue]);
|
|
54
|
+
|
|
55
|
+
// Initialize selectedValue
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (initialSelectedSkin) {
|
|
58
|
+
const initialProperty = propertySelectValues.find(
|
|
59
|
+
(prop) => prop.id === initialSelectedSkin
|
|
60
|
+
);
|
|
61
|
+
setSelectedValue(initialProperty || propertySelectValues[0]);
|
|
62
|
+
} else if (propertySelectValues.length > 0) {
|
|
63
|
+
setSelectedValue(propertySelectValues[0]);
|
|
64
|
+
}
|
|
65
|
+
}, [initialSelectedSkin, availableCharacters]);
|
|
66
|
+
|
|
67
|
+
// Functions to handle confirmation and cancellation
|
|
68
|
+
const handleConfirm = () => {
|
|
69
|
+
if (selectedValue) {
|
|
70
|
+
onConfirm(selectedValue.id);
|
|
71
|
+
onClose();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const handleCancel = () => {
|
|
76
|
+
onClose();
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
if (!isOpen) return null;
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
|
|
83
|
+
<Container>
|
|
84
|
+
{selectedSpriteKey && atlasIMG && atlasJSON && (
|
|
85
|
+
<ErrorBoundary>
|
|
86
|
+
<SpriteFromAtlas
|
|
87
|
+
spriteKey={selectedSpriteKey}
|
|
88
|
+
atlasIMG={atlasIMG}
|
|
89
|
+
atlasJSON={atlasJSON}
|
|
90
|
+
imgScale={4}
|
|
91
|
+
height={80}
|
|
92
|
+
width={64}
|
|
93
|
+
containerStyle={{
|
|
94
|
+
display: 'flex',
|
|
95
|
+
alignItems: 'center',
|
|
96
|
+
paddingBottom: '15px',
|
|
97
|
+
}}
|
|
98
|
+
imgStyle={{
|
|
99
|
+
left: '22px',
|
|
100
|
+
}}
|
|
101
|
+
/>
|
|
102
|
+
</ErrorBoundary>
|
|
103
|
+
)}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
<PropertySelect
|
|
107
|
+
availableProperties={propertySelectValues}
|
|
108
|
+
onChange={(value) => {
|
|
109
|
+
setSelectedValue(value);
|
|
110
|
+
}}
|
|
111
|
+
/>
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
<ButtonsContainer>
|
|
116
|
+
<Button
|
|
117
|
+
buttonType={ButtonTypes.RPGUIButton}
|
|
118
|
+
onClick={handleCancel}
|
|
119
|
+
>
|
|
120
|
+
Cancel
|
|
121
|
+
</Button>
|
|
122
|
+
<Button
|
|
123
|
+
buttonType={ButtonTypes.RPGUIButton}
|
|
124
|
+
onClick={handleConfirm}
|
|
125
|
+
disabled={!selectedValue}
|
|
126
|
+
>
|
|
127
|
+
Confirm
|
|
128
|
+
</Button>
|
|
129
|
+
</ButtonsContainer>
|
|
130
|
+
</Container>
|
|
131
|
+
);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// Styled components
|
|
135
|
+
|
|
136
|
+
const Container = styled.div`
|
|
137
|
+
display: flex;
|
|
138
|
+
flex-direction: column;
|
|
139
|
+
align-items: center;
|
|
140
|
+
image-rendering: pixelated;
|
|
141
|
+
`;
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
const ButtonsContainer = styled.div`
|
|
145
|
+
display: flex;
|
|
146
|
+
justify-content: center;
|
|
147
|
+
gap: 0.8rem;
|
|
148
|
+
width: 100%;
|
|
149
|
+
margin: 3rem 0 0.75rem;
|
|
150
|
+
|
|
151
|
+
button {
|
|
152
|
+
min-width: 95px;
|
|
153
|
+
font-size: 0.9rem;
|
|
154
|
+
}
|
|
155
|
+
`;
|
|
156
|
+
|
|
157
|
+
export default CharacterSkinSelectionModal;
|
package/src/index.tsx
CHANGED
|
@@ -2,6 +2,7 @@ export * from './components/Arrow/SelectArrow';
|
|
|
2
2
|
export * from './components/AsyncDropdown';
|
|
3
3
|
export * from './components/Button';
|
|
4
4
|
export * from './components/Character/CharacterSelection';
|
|
5
|
+
export * from './components/Character/CharacterSkinSelectionModal';
|
|
5
6
|
export * from './components/Chat/Chat';
|
|
6
7
|
export * from './components/Chatdeprecated/ChatDeprecated';
|
|
7
8
|
export * from './components/ChatRevamp/ChatRevamp';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Meta, Story } from '@storybook/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { RPGUIRoot } from '../../..';
|
|
4
|
+
import CharacterSkinSelectionModal, {
|
|
5
|
+
ICharacterSkinSelectionModalProps
|
|
6
|
+
} from '../../../components/Character/CharacterSkinSelectionModal';
|
|
7
|
+
import atlasJSON from '../../../mocks/atlas/entities/entities.json';
|
|
8
|
+
import atlasIMG from '../../../mocks/atlas/entities/entities.png';
|
|
9
|
+
|
|
10
|
+
const meta: Meta = {
|
|
11
|
+
title: 'Character/Character/Skin Selection',
|
|
12
|
+
component: CharacterSkinSelectionModal,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
16
|
+
|
|
17
|
+
const Template: Story<ICharacterSkinSelectionModalProps> = (args: ICharacterSkinSelectionModalProps) => (
|
|
18
|
+
<RPGUIRoot>
|
|
19
|
+
<CharacterSkinSelectionModal {...args} />
|
|
20
|
+
</RPGUIRoot>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export const KnightSkins = Template.bind({});
|
|
24
|
+
|
|
25
|
+
// Example of different knight skins
|
|
26
|
+
const knightCharacters = [
|
|
27
|
+
{
|
|
28
|
+
name: 'Black Knight',
|
|
29
|
+
textureKey: 'black-knight',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'Dragon Knight',
|
|
33
|
+
textureKey: 'dragon-knight',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'Senior Knight',
|
|
37
|
+
textureKey: 'senior-knight-1',
|
|
38
|
+
}
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
KnightSkins.args = {
|
|
42
|
+
isOpen: true,
|
|
43
|
+
onClose: () => console.log('Modal closed'),
|
|
44
|
+
onConfirm: (textureKey: string) => console.log('Selected skin:', textureKey),
|
|
45
|
+
availableCharacters: knightCharacters,
|
|
46
|
+
atlasJSON: atlasJSON,
|
|
47
|
+
atlasIMG: atlasIMG,
|
|
48
|
+
initialSelectedSkin: 'black-knight',
|
|
49
|
+
};
|