@rpg-engine/long-bow 0.8.162 → 0.8.163
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/Store/Store.d.ts +1 -0
- package/dist/components/Store/sections/StorePacksSection.d.ts +1 -1
- package/dist/long-bow.cjs.development.js +77 -28
- 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 +77 -28
- package/dist/long-bow.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Store/Store.tsx +19 -4
- package/src/components/Store/sections/StorePacksSection.tsx +90 -30
- package/src/stories/Features/store/Store.stories.tsx +2 -1
package/package.json
CHANGED
|
@@ -10,6 +10,7 @@ import { uiColors } from '../../constants/uiColors';
|
|
|
10
10
|
import { DraggableContainer } from '../DraggableContainer';
|
|
11
11
|
import { RPGUIContainerTypes } from '../RPGUI/RPGUIContainer';
|
|
12
12
|
import { Tabs } from '../shared/Tabs';
|
|
13
|
+
import { LabelPill } from '../shared/LabelPill/LabelPill';
|
|
13
14
|
import { CTAButton } from '../shared/CTAButton/CTAButton';
|
|
14
15
|
import { CartView } from './CartView';
|
|
15
16
|
import { useStoreCart } from './hooks/useStoreCart';
|
|
@@ -42,6 +43,7 @@ export interface IStoreProps {
|
|
|
42
43
|
textInputItemKeys?: string[];
|
|
43
44
|
customPacksContent?: React.ReactNode;
|
|
44
45
|
customWalletContent?: React.ReactNode;
|
|
46
|
+
packsBadge?: string;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
export const Store: React.FC<IStoreProps> = ({
|
|
@@ -64,6 +66,7 @@ export const Store: React.FC<IStoreProps> = ({
|
|
|
64
66
|
customPacksContent,
|
|
65
67
|
customWalletContent,
|
|
66
68
|
packsTabLabel = 'Packs',
|
|
69
|
+
packsBadge,
|
|
67
70
|
}) => {
|
|
68
71
|
const [selectedPack, setSelectedPack] = useState<IItemPack | null>(null);
|
|
69
72
|
const [activeTab, setActiveTab] = useState<TabId>(() => {
|
|
@@ -87,7 +90,7 @@ export const Store: React.FC<IStoreProps> = ({
|
|
|
87
90
|
const [isCollectingMetadata, setIsCollectingMetadata] = useState(false);
|
|
88
91
|
const [currentMetadataItem, setCurrentMetadataItem] = useState<IProductBlueprint | null>(null);
|
|
89
92
|
|
|
90
|
-
const handleAddPackToCart = (pack: IItemPack) => {
|
|
93
|
+
const handleAddPackToCart = (pack: IItemPack, quantity: number = 1) => {
|
|
91
94
|
const packItem: IProductBlueprint = {
|
|
92
95
|
key: pack.key,
|
|
93
96
|
name: pack.title,
|
|
@@ -105,7 +108,7 @@ export const Store: React.FC<IStoreProps> = ({
|
|
|
105
108
|
maxStackSize: 1,
|
|
106
109
|
isUsable: false,
|
|
107
110
|
};
|
|
108
|
-
handleAddToCart(packItem,
|
|
111
|
+
handleAddToCart(packItem, quantity);
|
|
109
112
|
};
|
|
110
113
|
|
|
111
114
|
const filterItems = (
|
|
@@ -163,7 +166,7 @@ export const Store: React.FC<IStoreProps> = ({
|
|
|
163
166
|
const tabIds: TabId[] = tabOrder ?? ['premium', 'packs', 'items'];
|
|
164
167
|
const availableTabIds: TabId[] = tabIds.filter(id => !(hidePremiumTab && id === 'premium'));
|
|
165
168
|
|
|
166
|
-
const tabsMap: Record<string, { id: TabId; title:
|
|
169
|
+
const tabsMap: Record<string, { id: TabId; title: ReactNode; icon: ReactNode; content: ReactNode }> = {
|
|
167
170
|
premium: {
|
|
168
171
|
id: 'premium',
|
|
169
172
|
title: 'Premium',
|
|
@@ -180,7 +183,12 @@ export const Store: React.FC<IStoreProps> = ({
|
|
|
180
183
|
},
|
|
181
184
|
packs: {
|
|
182
185
|
id: 'packs',
|
|
183
|
-
title:
|
|
186
|
+
title: packsBadge ? (
|
|
187
|
+
<TabLabelWithBadge>
|
|
188
|
+
{packsTabLabel}
|
|
189
|
+
<LabelPill background="#f59e0b" borderColor="#f59e0b" color="#000">{packsBadge}</LabelPill>
|
|
190
|
+
</TabLabelWithBadge>
|
|
191
|
+
) : packsTabLabel,
|
|
184
192
|
icon: <Gift width={18} height={18} />,
|
|
185
193
|
content: customPacksContent ?? (
|
|
186
194
|
<StorePacksSection
|
|
@@ -390,6 +398,13 @@ const CartInfo = styled.div`
|
|
|
390
398
|
}
|
|
391
399
|
`;
|
|
392
400
|
|
|
401
|
+
const TabLabelWithBadge = styled.span`
|
|
402
|
+
display: inline-flex;
|
|
403
|
+
align-items: center;
|
|
404
|
+
gap: 5px;
|
|
405
|
+
`;
|
|
406
|
+
|
|
407
|
+
|
|
393
408
|
const LoadingMessage = styled.div`
|
|
394
409
|
text-align: center;
|
|
395
410
|
color: ${uiColors.white};
|
|
@@ -6,20 +6,73 @@ import { CTAButton } from '../../shared/CTAButton/CTAButton';
|
|
|
6
6
|
import { ItemRowWrapper } from '../../shared/ItemRowWrapper';
|
|
7
7
|
import { SpriteFromAtlas } from '../../shared/SpriteFromAtlas';
|
|
8
8
|
import { ScrollableContent } from '../../shared/ScrollableContent/ScrollableContent';
|
|
9
|
+
import { SelectArrow } from '../../Arrow/SelectArrow';
|
|
9
10
|
import { usePackFiltering } from '../../../hooks/usePackFiltering';
|
|
11
|
+
import { useQuantityControl } from '../../../hooks/useQuantityControl';
|
|
10
12
|
|
|
11
13
|
interface IStorePacksSectionProps {
|
|
12
14
|
packs: IItemPack[];
|
|
13
|
-
onAddToCart: (pack: IItemPack) => void;
|
|
15
|
+
onAddToCart: (pack: IItemPack, quantity: number) => void;
|
|
14
16
|
onSelectPack?: (pack: IItemPack) => void;
|
|
15
17
|
atlasJSON?: any;
|
|
16
18
|
atlasIMG?: string;
|
|
17
19
|
}
|
|
18
20
|
|
|
21
|
+
interface IPackRowItemProps {
|
|
22
|
+
pack: IItemPack;
|
|
23
|
+
onAddToCart: (pack: IItemPack, quantity: number) => void;
|
|
24
|
+
renderPackIcon: (pack: IItemPack) => React.ReactNode;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const PackRowItem: React.FC<IPackRowItemProps> = ({ pack, onAddToCart, renderPackIcon }) => {
|
|
28
|
+
const { quantity, handleQuantityChange, handleBlur, incrementQuantity, decrementQuantity, resetQuantity } = useQuantityControl();
|
|
29
|
+
|
|
30
|
+
const handleAdd = () => {
|
|
31
|
+
onAddToCart(pack, quantity);
|
|
32
|
+
resetQuantity();
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<PackRow>
|
|
37
|
+
<LeftSection>
|
|
38
|
+
<PackIconContainer>
|
|
39
|
+
{renderPackIcon(pack)}
|
|
40
|
+
</PackIconContainer>
|
|
41
|
+
|
|
42
|
+
<PackDetails>
|
|
43
|
+
<PackName>{pack.title}</PackName>
|
|
44
|
+
<PackPrice>${pack.priceUSD}</PackPrice>
|
|
45
|
+
{pack.description && <PackDescription>{pack.description}</PackDescription>}
|
|
46
|
+
</PackDetails>
|
|
47
|
+
</LeftSection>
|
|
48
|
+
|
|
49
|
+
<Controls>
|
|
50
|
+
<ArrowsContainer>
|
|
51
|
+
<SelectArrow direction="left" onPointerDown={decrementQuantity} size={24} />
|
|
52
|
+
<QuantityInput
|
|
53
|
+
type="number"
|
|
54
|
+
value={quantity}
|
|
55
|
+
onChange={handleQuantityChange}
|
|
56
|
+
onBlur={handleBlur}
|
|
57
|
+
min={1}
|
|
58
|
+
max={99}
|
|
59
|
+
className="rpgui-input"
|
|
60
|
+
/>
|
|
61
|
+
<SelectArrow direction="right" onPointerDown={incrementQuantity} size={24} />
|
|
62
|
+
</ArrowsContainer>
|
|
63
|
+
<CTAButton
|
|
64
|
+
icon={<FaCartPlus />}
|
|
65
|
+
label="Add"
|
|
66
|
+
onClick={handleAdd}
|
|
67
|
+
/>
|
|
68
|
+
</Controls>
|
|
69
|
+
</PackRow>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
19
73
|
export const StorePacksSection: React.FC<IStorePacksSectionProps> = ({
|
|
20
74
|
packs,
|
|
21
75
|
onAddToCart,
|
|
22
|
-
onSelectPack,
|
|
23
76
|
atlasJSON,
|
|
24
77
|
atlasIMG,
|
|
25
78
|
}) => {
|
|
@@ -43,32 +96,14 @@ export const StorePacksSection: React.FC<IStorePacksSectionProps> = ({
|
|
|
43
96
|
|
|
44
97
|
const renderPack = useCallback(
|
|
45
98
|
(pack: IItemPack) => (
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
<PackDetails>
|
|
53
|
-
<PackName>{pack.title}</PackName>
|
|
54
|
-
<PackPrice>${pack.priceUSD}</PackPrice>
|
|
55
|
-
{pack.description && <PackDescription>{pack.description}</PackDescription>}
|
|
56
|
-
</PackDetails>
|
|
57
|
-
</LeftSection>
|
|
58
|
-
|
|
59
|
-
<Controls>
|
|
60
|
-
<CTAButton
|
|
61
|
-
icon={<FaCartPlus />}
|
|
62
|
-
label="Add"
|
|
63
|
-
onClick={e => {
|
|
64
|
-
e.stopPropagation();
|
|
65
|
-
onAddToCart(pack);
|
|
66
|
-
}}
|
|
67
|
-
/>
|
|
68
|
-
</Controls>
|
|
69
|
-
</PackRow>
|
|
99
|
+
<PackRowItem
|
|
100
|
+
key={pack.key}
|
|
101
|
+
pack={pack}
|
|
102
|
+
onAddToCart={onAddToCart}
|
|
103
|
+
renderPackIcon={renderPackIcon}
|
|
104
|
+
/>
|
|
70
105
|
),
|
|
71
|
-
[
|
|
106
|
+
[onAddToCart, renderPackIcon]
|
|
72
107
|
);
|
|
73
108
|
|
|
74
109
|
return (
|
|
@@ -87,9 +122,7 @@ export const StorePacksSection: React.FC<IStorePacksSectionProps> = ({
|
|
|
87
122
|
);
|
|
88
123
|
};
|
|
89
124
|
|
|
90
|
-
const PackRow = styled(ItemRowWrapper)
|
|
91
|
-
cursor: pointer;
|
|
92
|
-
`;
|
|
125
|
+
const PackRow = styled(ItemRowWrapper)``;
|
|
93
126
|
|
|
94
127
|
const LeftSection = styled.div`
|
|
95
128
|
display: flex;
|
|
@@ -144,5 +177,32 @@ const PackDescription = styled.div`
|
|
|
144
177
|
const Controls = styled.div`
|
|
145
178
|
display: flex;
|
|
146
179
|
align-items: center;
|
|
180
|
+
gap: 0.5rem;
|
|
147
181
|
flex-shrink: 0;
|
|
148
182
|
`;
|
|
183
|
+
|
|
184
|
+
const ArrowsContainer = styled.div`
|
|
185
|
+
position: relative;
|
|
186
|
+
display: flex;
|
|
187
|
+
align-items: center;
|
|
188
|
+
width: 120px;
|
|
189
|
+
height: 42px;
|
|
190
|
+
justify-content: space-between;
|
|
191
|
+
`;
|
|
192
|
+
|
|
193
|
+
const QuantityInput = styled.input`
|
|
194
|
+
width: 40px;
|
|
195
|
+
text-align: center;
|
|
196
|
+
margin: 0 auto;
|
|
197
|
+
font-size: 0.875rem;
|
|
198
|
+
background: rgba(0, 0, 0, 0.2);
|
|
199
|
+
color: #ffffff;
|
|
200
|
+
border: none;
|
|
201
|
+
padding: 0.25rem;
|
|
202
|
+
|
|
203
|
+
&::-webkit-inner-spin-button,
|
|
204
|
+
&::-webkit-outer-spin-button {
|
|
205
|
+
-webkit-appearance: none;
|
|
206
|
+
margin: 0;
|
|
207
|
+
}
|
|
208
|
+
`;
|
|
@@ -237,8 +237,9 @@ export const Default: Story = {
|
|
|
237
237
|
atlasIMG={itemsAtlasIMG}
|
|
238
238
|
hidePremiumTab={true}
|
|
239
239
|
tabOrder={['items', 'packs']}
|
|
240
|
-
defaultActiveTab="
|
|
240
|
+
defaultActiveTab="packs"
|
|
241
241
|
textInputItemKeys={['original-greater-life-potion-2', 'original-angelic-sword-1', 'character-name-change']}
|
|
242
|
+
packsBadge="SAVE"
|
|
242
243
|
/>
|
|
243
244
|
),
|
|
244
245
|
};
|