@rpg-engine/long-bow 0.8.212 → 0.8.213

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpg-engine/long-bow",
3
- "version": "0.8.212",
3
+ "version": "0.8.213",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -24,7 +24,7 @@
24
24
  "build": "tsdx build",
25
25
  "test": "tsdx test --passWithNoTests",
26
26
  "lint": "tsdx lint",
27
- "prepare": "echo skip",
27
+ "prepare": "tsdx build",
28
28
  "size": "size-limit",
29
29
  "analyze": "size-limit --why",
30
30
  "storybook": "start-storybook -p 6006",
@@ -236,7 +236,8 @@ export const Marketplace: React.FC<IMarketPlaceProps> = props => {
236
236
  if (onClose) onClose();
237
237
  }}
238
238
  isFullScreen={fullScreen}
239
- width="920px"
239
+ width="1050px"
240
+ minWidth="750px"
240
241
  cancelDrag="#MarketContainer, .rpgui-dropdown-imp, input, .empty-slot, button"
241
242
  scale={scale}
242
243
  >
@@ -135,11 +135,18 @@ export const Store: React.FC<IStoreProps> = ({
135
135
  const defaultTabOrder: TabId[] = ['premium', 'packs', 'items'];
136
136
  const [selectedPack, setSelectedPack] = useState<IItemPack | null>(null);
137
137
  const [activeTab, setActiveTab] = useState<TabId>(() => {
138
- const initialTabs = (tabOrder ?? defaultTabOrder).filter(id => !(hidePremiumTab && id === 'premium'));
139
- if (defaultActiveTab && initialTabs.includes(defaultActiveTab)) {
138
+ const allTabIds: TabId[] = [
139
+ ...(tabOrder ?? defaultTabOrder),
140
+ ...(customCharactersContent ? ['characters' as TabId] : []),
141
+ ...(onRedeem ? ['redeem' as TabId] : []),
142
+ ...((onShowWallet || customWalletContent) ? ['wallet' as TabId] : []),
143
+ ...((onShowHistory || customHistoryContent) ? ['history' as TabId] : []),
144
+ ];
145
+ const validTabs = Array.from(new Set(allTabIds.filter(id => !(hidePremiumTab && id === 'premium'))));
146
+ if (defaultActiveTab && validTabs.includes(defaultActiveTab)) {
140
147
  return defaultActiveTab;
141
148
  }
142
- return initialTabs[0] ?? (hidePremiumTab ? 'items' : 'premium');
149
+ return validTabs[0] ?? (hidePremiumTab ? 'items' : 'premium');
143
150
  });
144
151
  const {
145
152
  cartItems,
@@ -355,7 +362,7 @@ export const Store: React.FC<IStoreProps> = ({
355
362
  },
356
363
  characters: {
357
364
  id: 'characters',
358
- title: 'Characters',
365
+ title: 'Char Trade',
359
366
  icon: <FaUsers size={16} />,
360
367
  content: customCharactersContent ?? null,
361
368
  },
@@ -397,8 +404,8 @@ export const Store: React.FC<IStoreProps> = ({
397
404
  <DraggableContainer
398
405
  title="Store"
399
406
  onCloseButton={onClose}
400
- width="850px"
401
- minWidth="600px"
407
+ width="1000px"
408
+ minWidth="700px"
402
409
  height="auto"
403
410
  type={RPGUIContainerTypes.Framed}
404
411
  cancelDrag="[class*='Store__Container'], [class*='CartView'], [class*='StoreItemDetails'], .close-button"
@@ -417,7 +424,7 @@ export const Store: React.FC<IStoreProps> = ({
417
424
  onRemoveFromCart={handleRemoveFromCartTracked}
418
425
  onClose={closeCart}
419
426
  onPurchase={async () => {
420
- await handleCartPurchase(onPurchase);
427
+ handleCartPurchase(onPurchase);
421
428
  return true;
422
429
  }}
423
430
  atlasJSON={atlasJSON}
@@ -482,21 +489,23 @@ export const Store: React.FC<IStoreProps> = ({
482
489
  )}
483
490
  <MainContent>
484
491
  <HeaderRow>
485
- <Tabs
486
- options={availableTabIds.map(id => ({ id, label: tabsMap[id]?.title, icon: tabsMap[id]?.icon }))}
487
- activeTabId={activeTab}
488
- onTabChange={(tabId) => {
489
- const nextTab = tabId as TabId;
490
- setActiveTab(nextTab);
491
- if (onTabChange) {
492
- const itemCount = nextTab === 'items' ? filteredItems.items.length
493
- : nextTab === 'premium' ? filteredItems.premium.length
494
- : nextTab === 'packs' ? packs.length
495
- : 0;
496
- onTabChange(nextTab, itemCount);
497
- }
498
- }}
499
- />
492
+ <TabsFlexWrapper>
493
+ <Tabs
494
+ options={availableTabIds.map(id => ({ id, label: tabsMap[id]?.title, icon: tabsMap[id]?.icon }))}
495
+ activeTabId={activeTab}
496
+ onTabChange={(tabId) => {
497
+ const nextTab = tabId as TabId;
498
+ setActiveTab(nextTab);
499
+ if (onTabChange) {
500
+ const itemCount = nextTab === 'items' ? filteredItems.items.length
501
+ : nextTab === 'premium' ? filteredItems.premium.length
502
+ : nextTab === 'packs' ? packs.length
503
+ : 0;
504
+ onTabChange(nextTab, itemCount);
505
+ }
506
+ }}
507
+ />
508
+ </TabsFlexWrapper>
500
509
  <CartButtonWrapper>
501
510
  <CTAButton
502
511
  icon={<FaShoppingCart />}
@@ -548,15 +557,21 @@ const Container = styled.div`
548
557
 
549
558
  const HeaderRow = styled.div`
550
559
  display: flex;
551
- align-items: center;
560
+ align-items: flex-end;
552
561
  justify-content: space-between;
553
562
  margin-bottom: 0.25rem;
554
563
  padding-top: 10px;
555
564
  padding-right: 12px;
556
565
  `;
557
566
 
567
+ const TabsFlexWrapper = styled.div`
568
+ flex: 1;
569
+ min-width: 0;
570
+ `;
571
+
558
572
  const CartButtonWrapper = styled.div`
559
573
  position: relative;
574
+ flex-shrink: 0;
560
575
  `;
561
576
 
562
577
  const CartBadge = styled.div`
@@ -37,6 +37,11 @@ const TabsContainer = styled.div`
37
37
  margin: 0 auto 15px auto;
38
38
  border-bottom: 2px solid rgba(255, 255, 255, 0.1);
39
39
  padding-bottom: 10px;
40
+ overflow-x: auto;
41
+ scrollbar-width: none;
42
+ &::-webkit-scrollbar {
43
+ display: none;
44
+ }
40
45
  `;
41
46
 
42
47
  const TabButton = styled.button<{ $active: boolean }>`
@@ -299,7 +299,7 @@ const mockPacks: IItemPack[] = [
299
299
 
300
300
  ];
301
301
 
302
- // Create the story with the static mock data
302
+ // Create the story with the static mock data — all tabs enabled so layout breaks are visible
303
303
  export const Default: Story = {
304
304
  render: () => (
305
305
  <Store
@@ -310,6 +310,11 @@ export const Default: Story = {
310
310
  console.log('Purchase details:', purchase);
311
311
  return Promise.resolve(true);
312
312
  }}
313
+ customCharactersContent={
314
+ <div style={{ padding: '1rem', color: '#fff', fontFamily: "'Press Start 2P', cursive", fontSize: '0.6rem', textAlign: 'center', marginTop: '2rem' }}>
315
+ Character trading content (consumer-provided)
316
+ </div>
317
+ }
313
318
  customWalletContent={<DCWalletContent
314
319
  dcBalance={150000000} // 150M
315
320
  historyData={{ transactions: [], totalPages: 1, currentPage: 1 }}
@@ -328,11 +333,14 @@ export const Default: Story = {
328
333
  loading={false}
329
334
  onRequestHistory={() => {}}
330
335
  />}
336
+ onRedeem={async (code: string) => {
337
+ if (code === 'CHB-550-ABCDEF1234') return { success: true, dcAmount: 550 };
338
+ return { success: false, error: 'Invalid voucher code.' };
339
+ }}
331
340
  onClose={() => console.log('Store closed')}
332
341
  atlasJSON={itemsAtlasJSON}
333
342
  atlasIMG={itemsAtlasIMG}
334
- hidePremiumTab={true}
335
- tabOrder={['items', 'packs']}
343
+ tabOrder={['premium', 'packs', 'items']}
336
344
  defaultActiveTab="packs"
337
345
  textInputItemKeys={['original-greater-life-potion-2', 'original-angelic-sword-1', 'character-name-change']}
338
346
  packsBadge="SAVE"
@@ -653,6 +661,38 @@ export const INR: Story = {
653
661
  ),
654
662
  };
655
663
 
664
+ export const WithCharTradeTab: Story = {
665
+ render: () => (
666
+ <Store
667
+ items={allStoreItems}
668
+ packs={mockPacks}
669
+ userAccountType={UserAccountTypes.Free}
670
+ onPurchase={(purchase: Partial<IPurchase>) => {
671
+ console.log('Purchase details:', purchase);
672
+ return Promise.resolve(true);
673
+ }}
674
+ customCharactersContent={
675
+ <div style={{ padding: '1rem', color: '#fff', fontFamily: "'Press Start 2P', cursive", fontSize: '0.6rem', textAlign: 'center', marginTop: '2rem' }}>
676
+ Character trading content goes here (provided by consumer)
677
+ </div>
678
+ }
679
+ onClose={() => console.log('Store closed')}
680
+ atlasJSON={itemsAtlasJSON}
681
+ atlasIMG={itemsAtlasIMG}
682
+ hidePremiumTab={true}
683
+ tabOrder={['items', 'packs']}
684
+ defaultActiveTab="characters"
685
+ onTabChange={(tab, count) => console.log('[tracking] tab_change', { tab, count })}
686
+ onCartOpen={() => console.log('[tracking] cart_opened')}
687
+ onAddToCart={(item, qty) => console.log('[tracking] add_to_cart', { key: item.key, qty })}
688
+ onRemoveFromCart={(key) => console.log('[tracking] remove_from_cart', { key })}
689
+ onCheckoutStart={(items, total) => console.log('[tracking] checkout_start', { items, total })}
690
+ onPurchaseSuccess={(items, total) => console.log('[tracking] purchase_success', { items, total })}
691
+ onPurchaseError={(error) => console.log('[tracking] purchase_error', { error })}
692
+ />
693
+ ),
694
+ };
695
+
656
696
  export const WithRedeemTab: Story = {
657
697
  render: () => (
658
698
  <Store