@rpg-engine/long-bow 0.8.14 → 0.8.16
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/ConfirmModal.d.ts +2 -2
- package/dist/components/Item/Inventory/ItemPropertyColorSelector.d.ts +6 -2
- package/dist/components/Item/Inventory/ItemPropertySimpleHandler.d.ts +6 -2
- package/dist/long-bow.cjs.development.js +113 -60
- 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 +113 -60
- package/dist/long-bow.esm.js.map +1 -1
- package/dist/stories/UI/dropdownsAndSelectors/ItemPropertyColorSelector.stories.d.ts +3 -0
- package/package.json +1 -1
- package/src/components/ConfirmModal.tsx +20 -8
- package/src/components/Item/Inventory/ItemPropertyColorSelector.tsx +118 -31
- package/src/components/Item/Inventory/ItemPropertySimpleHandler.tsx +8 -2
- package/src/stories/UI/dropdownsAndSelectors/ItemPropertyColorSelector.stories.tsx +51 -25
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
declare const _default: import("@storybook/csf").ComponentAnnotations<import("@storybook/react").ReactFramework, import("@storybook/react").Args>;
|
|
2
2
|
export default _default;
|
|
3
3
|
export declare const Default: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, import("@storybook/react").Args>;
|
|
4
|
+
export declare const WithCostWarning: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, import("@storybook/react").Args>;
|
|
5
|
+
export declare const WithCustomCurrency: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, import("@storybook/react").Args>;
|
|
6
|
+
export declare const Closed: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, import("@storybook/react").Args>;
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
import ModalPortal from './Abstractions/ModalPortal';
|
|
4
4
|
import { Button, ButtonTypes } from './Button';
|
|
@@ -7,34 +7,46 @@ import { DraggableContainer } from './DraggableContainer';
|
|
|
7
7
|
export interface IConfirmModalProps {
|
|
8
8
|
onConfirm: () => void;
|
|
9
9
|
onClose: () => void;
|
|
10
|
-
message?: string;
|
|
10
|
+
message?: string | ReactNode;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export const ConfirmModal: React.FC<IConfirmModalProps> = ({
|
|
14
14
|
onConfirm,
|
|
15
15
|
onClose,
|
|
16
|
-
message,
|
|
16
|
+
message = 'Are you sure?',
|
|
17
17
|
}) => {
|
|
18
|
+
const handleConfirm = (e: React.MouseEvent) => {
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
e.stopPropagation();
|
|
21
|
+
onConfirm();
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const handleClose = (e: React.MouseEvent) => {
|
|
25
|
+
e.preventDefault();
|
|
26
|
+
e.stopPropagation();
|
|
27
|
+
onClose();
|
|
28
|
+
};
|
|
29
|
+
|
|
18
30
|
return (
|
|
19
31
|
<ModalPortal>
|
|
20
32
|
<Background />
|
|
21
|
-
<Container
|
|
33
|
+
<Container onClick={handleClose}>
|
|
22
34
|
<DraggableContainer width="auto" dragDisabled>
|
|
23
|
-
<Wrapper
|
|
24
|
-
|
|
35
|
+
<Wrapper onClick={e => e.stopPropagation()}>
|
|
36
|
+
{typeof message === 'string' ? <p>{message}</p> : message}
|
|
25
37
|
|
|
26
38
|
<ButtonsWrapper>
|
|
27
39
|
<div className="cancel-button">
|
|
28
40
|
<Button
|
|
29
41
|
buttonType={ButtonTypes.RPGUIButton}
|
|
30
|
-
|
|
42
|
+
onClick={handleClose}
|
|
31
43
|
>
|
|
32
44
|
No
|
|
33
45
|
</Button>
|
|
34
46
|
</div>
|
|
35
47
|
<Button
|
|
36
48
|
buttonType={ButtonTypes.RPGUIButton}
|
|
37
|
-
|
|
49
|
+
onClick={handleConfirm}
|
|
38
50
|
>
|
|
39
51
|
Yes
|
|
40
52
|
</Button>
|
|
@@ -1,75 +1,162 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { HexColorPicker } from 'react-colorful';
|
|
3
3
|
import styled from 'styled-components';
|
|
4
|
+
import { uiColors } from '../../../constants/uiColors';
|
|
4
5
|
import { Button, ButtonTypes } from '../../Button';
|
|
6
|
+
import { ConfirmModal } from '../../ConfirmModal';
|
|
5
7
|
import { DraggableContainer } from '../../DraggableContainer';
|
|
6
8
|
import { RPGUIContainerTypes } from '../../RPGUI/RPGUIContainer';
|
|
7
9
|
|
|
8
|
-
interface
|
|
10
|
+
interface IColorSelectorProps {
|
|
9
11
|
selectedColor: string;
|
|
10
12
|
isOpen: boolean;
|
|
11
13
|
onClose: () => void;
|
|
12
14
|
onConfirm: (color: string) => void;
|
|
13
15
|
onChange: (color: string) => void;
|
|
16
|
+
costWarning?: {
|
|
17
|
+
cost: number;
|
|
18
|
+
currency?: string;
|
|
19
|
+
};
|
|
14
20
|
}
|
|
15
21
|
|
|
16
|
-
export const ColorSelector: React.FC<
|
|
22
|
+
export const ColorSelector: React.FC<IColorSelectorProps> = ({
|
|
17
23
|
selectedColor,
|
|
18
24
|
isOpen,
|
|
19
25
|
onClose,
|
|
20
26
|
onConfirm,
|
|
21
27
|
onChange,
|
|
28
|
+
costWarning,
|
|
22
29
|
}) => {
|
|
23
30
|
const [currentColor, setCurrentColor] = useState(selectedColor);
|
|
31
|
+
const [showConfirmModal, setShowConfirmModal] = useState(false);
|
|
24
32
|
|
|
25
33
|
useEffect(() => {
|
|
26
34
|
if (isOpen) setCurrentColor(selectedColor);
|
|
27
35
|
}, [isOpen, selectedColor]);
|
|
28
36
|
|
|
29
|
-
const handleConfirm = () => {
|
|
37
|
+
const handleConfirm = (e: React.MouseEvent) => {
|
|
38
|
+
e.preventDefault();
|
|
39
|
+
if (costWarning) {
|
|
40
|
+
setShowConfirmModal(true);
|
|
41
|
+
} else {
|
|
42
|
+
onConfirm(currentColor);
|
|
43
|
+
onClose();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handleConfirmCost = () => {
|
|
30
48
|
onConfirm(currentColor);
|
|
49
|
+
setShowConfirmModal(false);
|
|
31
50
|
onClose();
|
|
32
51
|
};
|
|
33
52
|
|
|
53
|
+
const handleClose = () => {
|
|
54
|
+
setShowConfirmModal(false);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const renderConfirmMessage = () => (
|
|
58
|
+
<ConfirmContent>
|
|
59
|
+
<p>
|
|
60
|
+
Cost:
|
|
61
|
+
<CostDisplay>
|
|
62
|
+
{costWarning?.cost.toLocaleString()}
|
|
63
|
+
{costWarning?.currency || ' gold'}
|
|
64
|
+
</CostDisplay>
|
|
65
|
+
</p>
|
|
66
|
+
<p>Proceed with color change?</p>
|
|
67
|
+
</ConfirmContent>
|
|
68
|
+
);
|
|
69
|
+
|
|
34
70
|
if (!isOpen) return null;
|
|
35
71
|
|
|
36
|
-
return
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
72
|
+
return (
|
|
73
|
+
<>
|
|
74
|
+
<DraggableContainer
|
|
75
|
+
type={RPGUIContainerTypes.Framed}
|
|
76
|
+
cancelDrag=".react-colorful"
|
|
77
|
+
width="25rem"
|
|
78
|
+
onCloseButton={onClose}
|
|
79
|
+
>
|
|
80
|
+
<Container>
|
|
81
|
+
<Header>Select Color</Header>
|
|
82
|
+
<ColorPickerWrapper>
|
|
83
|
+
<HexColorPicker
|
|
84
|
+
color={currentColor}
|
|
85
|
+
onChange={color => {
|
|
86
|
+
setCurrentColor(color);
|
|
87
|
+
onChange(color);
|
|
88
|
+
}}
|
|
89
|
+
/>
|
|
90
|
+
</ColorPickerWrapper>
|
|
91
|
+
<ButtonContainer>
|
|
92
|
+
<Button
|
|
93
|
+
buttonType={ButtonTypes.RPGUIButton}
|
|
94
|
+
type="button"
|
|
95
|
+
onClick={handleConfirm}
|
|
96
|
+
>
|
|
97
|
+
Confirm
|
|
98
|
+
</Button>
|
|
99
|
+
</ButtonContainer>
|
|
100
|
+
</Container>
|
|
101
|
+
</DraggableContainer>
|
|
102
|
+
|
|
103
|
+
{showConfirmModal && costWarning && (
|
|
104
|
+
<ConfirmModal
|
|
105
|
+
message={renderConfirmMessage()}
|
|
106
|
+
onConfirm={handleConfirmCost}
|
|
107
|
+
onClose={handleClose}
|
|
51
108
|
/>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
onClick={handleConfirm}
|
|
56
|
-
>
|
|
57
|
-
Confirm
|
|
58
|
-
</Button>
|
|
59
|
-
</Container>
|
|
60
|
-
</DraggableContainer>
|
|
61
|
-
) : null;
|
|
109
|
+
)}
|
|
110
|
+
</>
|
|
111
|
+
);
|
|
62
112
|
};
|
|
63
113
|
|
|
64
114
|
const Container = styled.div`
|
|
65
|
-
padding: 2rem;
|
|
66
115
|
text-align: center;
|
|
67
116
|
background: inherit;
|
|
117
|
+
display: flex;
|
|
118
|
+
flex-direction: column;
|
|
119
|
+
gap: 1.5rem;
|
|
120
|
+
align-items: center;
|
|
121
|
+
width: 100%;
|
|
122
|
+
max-width: 24rem;
|
|
123
|
+
margin: 0 auto;
|
|
68
124
|
`;
|
|
69
125
|
|
|
70
126
|
const Header = styled.h2`
|
|
71
|
-
font-family: 'Press Start 2P', cursive;
|
|
72
127
|
color: white;
|
|
73
128
|
font-size: 1rem;
|
|
74
|
-
margin
|
|
129
|
+
margin: 0;
|
|
130
|
+
width: 100%;
|
|
131
|
+
text-align: center;
|
|
132
|
+
`;
|
|
133
|
+
|
|
134
|
+
const ColorPickerWrapper = styled.div`
|
|
135
|
+
display: flex;
|
|
136
|
+
justify-content: center;
|
|
137
|
+
width: 100%;
|
|
138
|
+
|
|
139
|
+
.react-colorful {
|
|
140
|
+
width: 100%;
|
|
141
|
+
max-width: 200px;
|
|
142
|
+
}
|
|
143
|
+
`;
|
|
144
|
+
|
|
145
|
+
const ButtonContainer = styled.div`
|
|
146
|
+
display: flex;
|
|
147
|
+
justify-content: center;
|
|
148
|
+
width: 100%;
|
|
149
|
+
`;
|
|
150
|
+
|
|
151
|
+
const ConfirmContent = styled.div`
|
|
152
|
+
display: flex;
|
|
153
|
+
flex-direction: column;
|
|
154
|
+
gap: 0.5rem;
|
|
155
|
+
text-align: center;
|
|
156
|
+
font-family: 'Press Start 2P', cursive;
|
|
157
|
+
font-size: 0.75rem;
|
|
158
|
+
`;
|
|
159
|
+
|
|
160
|
+
const CostDisplay = styled.span`
|
|
161
|
+
color: ${uiColors.yellow} !important;
|
|
75
162
|
`;
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ColorSelector } from './ItemPropertyColorSelector';
|
|
3
3
|
|
|
4
|
-
interface
|
|
4
|
+
interface IItemPropertySimpleHandlerProps {
|
|
5
5
|
isOpen: boolean;
|
|
6
6
|
selectedColor: string;
|
|
7
7
|
onClose: () => void;
|
|
8
8
|
onConfirm: (color: string) => void;
|
|
9
9
|
onChange: (color: string) => void;
|
|
10
|
+
costWarning?: {
|
|
11
|
+
cost: number;
|
|
12
|
+
currency?: string;
|
|
13
|
+
};
|
|
10
14
|
}
|
|
11
15
|
|
|
12
|
-
export const ItemPropertySimpleHandler: React.FC<
|
|
16
|
+
export const ItemPropertySimpleHandler: React.FC<IItemPropertySimpleHandlerProps> = ({
|
|
13
17
|
isOpen,
|
|
14
18
|
selectedColor,
|
|
15
19
|
onClose,
|
|
16
20
|
onConfirm,
|
|
17
21
|
onChange,
|
|
22
|
+
costWarning,
|
|
18
23
|
}) => (
|
|
19
24
|
<ColorSelector
|
|
20
25
|
selectedColor={selectedColor}
|
|
@@ -22,5 +27,6 @@ export const ItemPropertySimpleHandler: React.FC<Props> = ({
|
|
|
22
27
|
onClose={onClose}
|
|
23
28
|
onConfirm={onConfirm}
|
|
24
29
|
onChange={onChange}
|
|
30
|
+
costWarning={costWarning}
|
|
25
31
|
/>
|
|
26
32
|
);
|
|
@@ -1,39 +1,36 @@
|
|
|
1
1
|
import { Meta, Story } from '@storybook/react';
|
|
2
2
|
import React, { useState } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { ColorSelector } from '../../../components/Item/Inventory/ItemPropertyColorSelector';
|
|
4
|
+
import { RPGUIRoot } from '../../../components/RPGUI/RPGUIRoot';
|
|
4
5
|
|
|
5
6
|
export default {
|
|
6
|
-
title: 'UI/Dropdowns & Selectors/
|
|
7
|
-
component:
|
|
7
|
+
title: 'UI/Dropdowns & Selectors/Item Property Color Selector',
|
|
8
|
+
component: ColorSelector,
|
|
8
9
|
parameters: {
|
|
10
|
+
layout: 'centered',
|
|
9
11
|
docs: {
|
|
10
12
|
description: {
|
|
11
13
|
component:
|
|
12
|
-
'A
|
|
14
|
+
'A color selector component for items with optional cost warning.',
|
|
13
15
|
},
|
|
14
16
|
},
|
|
15
17
|
},
|
|
16
18
|
argTypes: {
|
|
17
|
-
isOpen: {
|
|
18
|
-
control: { type: 'boolean' },
|
|
19
|
-
description: 'Controls whether the color selector is open.',
|
|
20
|
-
},
|
|
21
19
|
selectedColor: {
|
|
22
20
|
control: { type: 'color' },
|
|
23
21
|
description: 'Initial selected color.',
|
|
24
22
|
},
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
description: '
|
|
28
|
-
},
|
|
29
|
-
onConfirm: {
|
|
30
|
-
action: 'onConfirm',
|
|
31
|
-
description: 'Callback when a color is confirmed.',
|
|
23
|
+
isOpen: {
|
|
24
|
+
control: { type: 'boolean' },
|
|
25
|
+
description: 'Controls whether the color selector is open.',
|
|
32
26
|
},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
description: '
|
|
27
|
+
costWarning: {
|
|
28
|
+
control: 'object',
|
|
29
|
+
description: 'Optional warning about the cost of changing colors.',
|
|
36
30
|
},
|
|
31
|
+
onClose: { action: 'closed' },
|
|
32
|
+
onConfirm: { action: 'confirmed' },
|
|
33
|
+
onChange: { action: 'changed' },
|
|
37
34
|
},
|
|
38
35
|
} as Meta;
|
|
39
36
|
|
|
@@ -60,13 +57,16 @@ const Template: Story = args => {
|
|
|
60
57
|
};
|
|
61
58
|
|
|
62
59
|
return (
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
60
|
+
<RPGUIRoot>
|
|
61
|
+
<ColorSelector
|
|
62
|
+
isOpen={isOpen}
|
|
63
|
+
selectedColor={currentColor}
|
|
64
|
+
onClose={handleClose}
|
|
65
|
+
onConfirm={handleConfirm}
|
|
66
|
+
onChange={handleChange}
|
|
67
|
+
{...args}
|
|
68
|
+
/>
|
|
69
|
+
</RPGUIRoot>
|
|
70
70
|
);
|
|
71
71
|
};
|
|
72
72
|
|
|
@@ -75,3 +75,29 @@ Default.args = {
|
|
|
75
75
|
isOpen: true,
|
|
76
76
|
selectedColor: '#ff0000',
|
|
77
77
|
};
|
|
78
|
+
|
|
79
|
+
export const WithCostWarning = Template.bind({});
|
|
80
|
+
WithCostWarning.args = {
|
|
81
|
+
isOpen: true,
|
|
82
|
+
selectedColor: '#ff0000',
|
|
83
|
+
costWarning: {
|
|
84
|
+
cost: 10000,
|
|
85
|
+
currency: ' gold',
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const WithCustomCurrency = Template.bind({});
|
|
90
|
+
WithCustomCurrency.args = {
|
|
91
|
+
isOpen: true,
|
|
92
|
+
selectedColor: '#ff0000',
|
|
93
|
+
costWarning: {
|
|
94
|
+
cost: 5000,
|
|
95
|
+
currency: ' crystals',
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const Closed = Template.bind({});
|
|
100
|
+
Closed.args = {
|
|
101
|
+
isOpen: false,
|
|
102
|
+
selectedColor: '#ff0000',
|
|
103
|
+
};
|