@rpg-engine/long-bow 0.8.70 → 0.8.71

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.70",
3
+ "version": "0.8.71",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -111,6 +111,9 @@ export const CartView: React.FC<ICartViewProps> = ({
111
111
  </ItemIconContainer>
112
112
  <ItemDetails>
113
113
  <ItemName>{cartItem.item.name}</ItemName>
114
+ {cartItem.metadata?.inputValue && (
115
+ <CartMeta>{cartItem.metadata.inputValue}</CartMeta>
116
+ )}
114
117
  <ItemInfo>
115
118
  <span>${formatPrice(cartItem.item.price)}</span>
116
119
  <span>×</span>
@@ -339,3 +342,11 @@ const MetadataValue = styled.div`
339
342
  text-overflow: ellipsis;
340
343
  white-space: nowrap;
341
344
  `;
345
+
346
+ const CartMeta = styled.div`
347
+ font-family: 'Press Start 2P', cursive;
348
+ font-size: 0.75rem;
349
+ color: #ffffff;
350
+ opacity: 0.8;
351
+ margin-top: 0.25rem;
352
+ `;
@@ -32,6 +32,7 @@ export interface IStoreProps {
32
32
  hidePremiumTab?: boolean;
33
33
  tabOrder?: TabId[];
34
34
  defaultActiveTab?: TabId;
35
+ textInputItemKeys?: string[];
35
36
  }
36
37
 
37
38
  export const Store: React.FC<IStoreProps> = ({
@@ -48,6 +49,7 @@ export const Store: React.FC<IStoreProps> = ({
48
49
  hidePremiumTab = false,
49
50
  tabOrder,
50
51
  defaultActiveTab,
52
+ textInputItemKeys = [],
51
53
  }) => {
52
54
  const [selectedPack, setSelectedPack] = useState<IItemPack | null>(null);
53
55
  const [activeTab, setActiveTab] = useState<TabId>(() => {
@@ -188,6 +190,7 @@ export const Store: React.FC<IStoreProps> = ({
188
190
  atlasJSON={atlasJSON}
189
191
  atlasIMG={atlasIMG}
190
192
  userAccountType={userAccountType}
193
+ textInputItemKeys={textInputItemKeys}
191
194
  />
192
195
  ),
193
196
  },
@@ -12,6 +12,7 @@ interface IStoreItemRowProps {
12
12
  atlasIMG: string;
13
13
  onAddToCart: (item: IStoreItem, quantity: number, metadata?: Record<string, any>) => void;
14
14
  userAccountType: UserAccountTypes;
15
+ showTextInput?: boolean;
15
16
  }
16
17
 
17
18
  export const StoreItemRow: React.FC<IStoreItemRowProps> = ({
@@ -20,8 +21,10 @@ export const StoreItemRow: React.FC<IStoreItemRowProps> = ({
20
21
  atlasIMG,
21
22
  onAddToCart,
22
23
  userAccountType,
24
+ showTextInput = false,
23
25
  }) => {
24
26
  const [quantity, setQuantity] = useState(1);
27
+ const [textInputValue, setTextInputValue] = useState('');
25
28
 
26
29
  const handleQuantityChange = (e: React.ChangeEvent<HTMLInputElement>) => {
27
30
  const value = parseInt(e.target.value) || 1;
@@ -45,10 +48,15 @@ export const StoreItemRow: React.FC<IStoreItemRowProps> = ({
45
48
  !item.requiredAccountType?.length ||
46
49
  item.requiredAccountType.includes(userAccountType);
47
50
 
48
- const handleAddToCart = () => {
51
+ const handleAddToCartInternal = () => {
49
52
  if (!hasRequiredAccount) return;
53
+ if (showTextInput) {
54
+ onAddToCart(item, 1, { inputValue: textInputValue });
55
+ setTextInputValue('');
56
+ } else {
50
57
  onAddToCart(item, quantity);
51
- setQuantity(1); // Reset quantity after adding to cart
58
+ setQuantity(1);
59
+ }
52
60
  };
53
61
 
54
62
  return (
@@ -71,6 +79,16 @@ export const StoreItemRow: React.FC<IStoreItemRowProps> = ({
71
79
  </ItemDetails>
72
80
 
73
81
  <Controls>
82
+ {/* Show text input if configured, else show arrows only for stackable items */}
83
+ {showTextInput ? (
84
+ <TextInput
85
+ type="text"
86
+ value={textInputValue}
87
+ placeholder="Enter value"
88
+ onChange={e => setTextInputValue(e.target.value)}
89
+ className="rpgui-input"
90
+ />
91
+ ) : item.isStackable ? (
74
92
  <ArrowsContainer>
75
93
  <SelectArrow
76
94
  direction="left"
@@ -94,11 +112,12 @@ export const StoreItemRow: React.FC<IStoreItemRowProps> = ({
94
112
  size={24}
95
113
  />
96
114
  </ArrowsContainer>
115
+ ) : null}
97
116
 
98
117
  <CTAButton
99
118
  icon={<FaCartPlus />}
100
119
  label="Add"
101
- onClick={handleAddToCart}
120
+ onClick={handleAddToCartInternal}
102
121
  disabled={!hasRequiredAccount}
103
122
  />
104
123
  </Controls>
@@ -179,3 +198,14 @@ const QuantityInput = styled.input`
179
198
  margin: 0;
180
199
  }
181
200
  `;
201
+
202
+ const TextInput = styled.input`
203
+ width: 120px;
204
+ text-align: center;
205
+ margin: 0 auto;
206
+ font-size: 0.875rem;
207
+ background: rgba(0, 0, 0, 0.2);
208
+ color: #ffffff;
209
+ border: none;
210
+ padding: 0.25rem;
211
+ `;
@@ -11,6 +11,7 @@ interface IStoreItemsSectionProps {
11
11
  atlasJSON: Record<string, any>;
12
12
  atlasIMG: string;
13
13
  userAccountType?: UserAccountTypes;
14
+ textInputItemKeys?: string[];
14
15
  }
15
16
 
16
17
  export const StoreItemsSection: React.FC<IStoreItemsSectionProps> = ({
@@ -19,6 +20,7 @@ export const StoreItemsSection: React.FC<IStoreItemsSectionProps> = ({
19
20
  atlasJSON,
20
21
  atlasIMG,
21
22
  userAccountType,
23
+ textInputItemKeys = [],
22
24
  }) => {
23
25
  const [searchQuery, setSearchQuery] = useState('');
24
26
 
@@ -27,7 +29,7 @@ export const StoreItemsSection: React.FC<IStoreItemsSectionProps> = ({
27
29
  );
28
30
 
29
31
  const renderStoreItem = (item: IStoreItem) => {
30
- // Use the specialized character skin row for items with character skin metadata
32
+ // Prefer a specialized character skin row when needed
31
33
  if (item.metadataType === MetadataType.CharacterSkin) {
32
34
  return (
33
35
  <StoreCharacterSkinRow
@@ -40,8 +42,21 @@ export const StoreItemsSection: React.FC<IStoreItemsSectionProps> = ({
40
42
  />
41
43
  );
42
44
  }
43
-
44
- // Use the standard item row for all other items
45
+ // Render text input row when configured for this item key
46
+ if (textInputItemKeys.includes(item.key) || textInputItemKeys.includes(item._id)) {
47
+ return (
48
+ <StoreItemRow
49
+ key={item._id}
50
+ item={item}
51
+ atlasJSON={atlasJSON}
52
+ atlasIMG={atlasIMG}
53
+ onAddToCart={onAddToCart}
54
+ userAccountType={userAccountType || UserAccountTypes.Free}
55
+ showTextInput
56
+ />
57
+ );
58
+ }
59
+ // Fallback to standard arrow-based row
45
60
  return (
46
61
  <StoreItemRow
47
62
  key={item._id}
@@ -249,6 +249,7 @@ export const Default: Story = {
249
249
  hidePremiumTab={true}
250
250
  tabOrder={['items', 'packs']}
251
251
  defaultActiveTab="items"
252
+ textInputItemKeys={['original-greater-life-potion-2', 'original-angelic-sword-1']}
252
253
  />
253
254
  ),
254
255
  };