@rpg-engine/long-bow 0.8.7 → 0.8.9

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.
Files changed (70) hide show
  1. package/dist/components/InformationCenter/sections/bestiary/{BestiarySection.d.ts → InformationCenterBestiarySection.d.ts} +1 -1
  2. package/dist/components/InformationCenter/sections/faq/{FaqSection.d.ts → InformationCenterFaqSection.d.ts} +1 -1
  3. package/dist/components/InformationCenter/sections/items/{ItemsSection.d.ts → InformationCenterItemsSection.d.ts} +1 -1
  4. package/dist/components/InformationCenter/sections/tutorials/{TutorialsSection.d.ts → InformationCenterTutorialsSection.d.ts} +2 -1
  5. package/dist/components/Item/Inventory/ItemPropertyColorSelector.d.ts +10 -0
  6. package/dist/components/Item/Inventory/ItemPropertySimpleHandler.d.ts +10 -0
  7. package/dist/components/Store/CartView.d.ts +15 -0
  8. package/dist/components/Store/StoreItemDetails.d.ts +16 -0
  9. package/dist/components/Store/StoreItemRow.d.ts +1 -2
  10. package/dist/components/Store/StoreTypes.d.ts +33 -4
  11. package/dist/components/Store/hooks/useStoreCart.d.ts +14 -0
  12. package/dist/components/Store/sections/StoreItemsSection.d.ts +12 -0
  13. package/dist/components/Store/sections/StorePacksSection.d.ts +9 -0
  14. package/dist/components/shared/CTAButton/CTAButton.d.ts +13 -0
  15. package/dist/components/shared/Card/Card.d.ts +14 -0
  16. package/dist/components/shared/Ellipsis.d.ts +1 -1
  17. package/dist/components/shared/PaginatedContent/PaginatedContent.d.ts +3 -1
  18. package/dist/components/shared/ScrollableContent/ScrollableContent.d.ts +23 -0
  19. package/dist/components/shared/SearchBar/SearchBar.d.ts +2 -3
  20. package/dist/components/shared/SearchHeader/SearchHeader.d.ts +17 -0
  21. package/dist/components/shared/ShoppingCart/CartCard.d.ts +14 -0
  22. package/dist/components/shared/ShoppingCart/CartCardHorizontal.d.ts +13 -0
  23. package/dist/index.d.ts +1 -0
  24. package/dist/long-bow.cjs.development.js +105 -39
  25. package/dist/long-bow.cjs.development.js.map +1 -1
  26. package/dist/long-bow.cjs.production.min.js +1 -1
  27. package/dist/long-bow.cjs.production.min.js.map +1 -1
  28. package/dist/long-bow.esm.js +105 -40
  29. package/dist/long-bow.esm.js.map +1 -1
  30. package/dist/stories/UI/buttonsAndInputs/CTAButton.stories.d.ts +18 -0
  31. package/dist/stories/UI/dropdownsAndSelectors/ItemPropertyColorSelector.stories.d.ts +3 -0
  32. package/package.json +3 -2
  33. package/src/components/InformationCenter/InformationCenter.tsx +8 -8
  34. package/src/components/InformationCenter/InformationCenterTabView.tsx +0 -1
  35. package/src/components/InformationCenter/sections/bestiary/{BestiarySection.tsx → InformationCenterBestiarySection.tsx} +2 -1
  36. package/src/components/InformationCenter/sections/faq/InformationCenterFaqSection.tsx +81 -0
  37. package/src/components/InformationCenter/sections/items/{ItemsSection.tsx → InformationCenterItemsSection.tsx} +2 -10
  38. package/src/components/InformationCenter/sections/tutorials/InformationCenterTutorialsSection.tsx +135 -0
  39. package/src/components/Item/Inventory/ItemPropertyColorSelector.tsx +75 -0
  40. package/src/components/Item/Inventory/ItemPropertySimpleHandler.tsx +26 -0
  41. package/src/components/Item/Inventory/itemContainerHelper.ts +10 -1
  42. package/src/components/Store/CartView.tsx +271 -0
  43. package/src/components/Store/Store.tsx +199 -96
  44. package/src/components/Store/StoreItemDetails.tsx +161 -0
  45. package/src/components/Store/StoreItemRow.tsx +24 -40
  46. package/src/components/Store/StoreTypes.ts +38 -4
  47. package/src/components/Store/hooks/useStoreCart.ts +121 -0
  48. package/src/components/Store/sections/StoreItemsSection.tsx +52 -0
  49. package/src/components/Store/sections/StorePacksSection.tsx +89 -0
  50. package/src/components/Store/sections/images/custom-skin.png +0 -0
  51. package/src/components/shared/CTAButton/CTAButton.tsx +127 -0
  52. package/src/components/shared/Card/Card.tsx +107 -0
  53. package/src/components/shared/Ellipsis.tsx +20 -22
  54. package/src/components/shared/PaginatedContent/PaginatedContent.tsx +48 -79
  55. package/src/components/shared/ScrollableContent/ScrollableContent.tsx +160 -0
  56. package/src/components/shared/SearchBar/SearchBar.tsx +43 -24
  57. package/src/components/shared/SearchHeader/SearchHeader.tsx +80 -0
  58. package/src/components/shared/ShoppingCart/CartCard.tsx +116 -0
  59. package/src/components/shared/ShoppingCart/CartCardHorizontal.tsx +120 -0
  60. package/src/components/shared/SpriteFromAtlas.tsx +2 -0
  61. package/src/index.tsx +1 -0
  62. package/src/stories/Features/store/Store.stories.tsx +54 -4
  63. package/src/stories/UI/buttonsAndInputs/CTAButton.stories.tsx +77 -0
  64. package/src/stories/UI/dropdownsAndSelectors/ItemPropertyColorSelector.stories.tsx +77 -0
  65. package/dist/components/Store/InternalStoreTab.d.ts +0 -15
  66. package/dist/components/Store/StoreTabContent.d.ts +0 -14
  67. package/src/components/InformationCenter/sections/faq/FaqSection.tsx +0 -51
  68. package/src/components/InformationCenter/sections/tutorials/TutorialsSection.tsx +0 -144
  69. package/src/components/Store/InternalStoreTab.tsx +0 -142
  70. package/src/components/Store/StoreTabContent.tsx +0 -46
@@ -0,0 +1,18 @@
1
+ import { Meta } from '@storybook/react';
2
+ import React from 'react';
3
+ interface ICTAButtonProps {
4
+ icon: React.ReactNode;
5
+ label?: React.ReactNode;
6
+ onClick?: () => void;
7
+ fullWidth?: boolean;
8
+ textColor?: string;
9
+ iconColor?: string;
10
+ disabled?: boolean;
11
+ }
12
+ declare const meta: Meta;
13
+ export default meta;
14
+ export declare const CartButton: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ICTAButtonProps>;
15
+ export declare const DeleteButton: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ICTAButtonProps>;
16
+ export declare const AddButton: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ICTAButtonProps>;
17
+ export declare const CheckoutButton: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ICTAButtonProps>;
18
+ export declare const DisabledCheckoutButton: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ICTAButtonProps>;
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@storybook/csf").ComponentAnnotations<import("@storybook/react").ReactFramework, import("@storybook/react").Args>;
2
+ export default _default;
3
+ export declare const Default: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, import("@storybook/react").Args>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpg-engine/long-bow",
3
- "version": "0.8.7",
3
+ "version": "0.8.9",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -84,7 +84,7 @@
84
84
  "dependencies": {
85
85
  "@capacitor/core": "^6.1.0",
86
86
  "@rollup/plugin-image": "^2.1.1",
87
- "@rpg-engine/shared": "^0.9.89",
87
+ "@rpg-engine/shared": "^0.9.92",
88
88
  "dayjs": "^1.11.2",
89
89
  "font-awesome": "^4.7.0",
90
90
  "fs-extra": "^10.1.0",
@@ -92,6 +92,7 @@
92
92
  "lodash-es": "^4.17.21",
93
93
  "mobx": "^6.6.0",
94
94
  "mobx-react": "^7.5.0",
95
+ "react-colorful": "^5.6.1",
95
96
  "react-draggable": "^4.4.5",
96
97
  "react-error-boundary": "^3.1.4",
97
98
  "react-icons": "^4.7.1",
@@ -6,11 +6,11 @@ import {
6
6
  IInformationCenterItem,
7
7
  IInformationCenterNPC,
8
8
  } from './InformationCenterTypes';
9
- import { BestiarySection } from './sections/bestiary/BestiarySection';
10
- import { FaqSection } from './sections/faq/FaqSection';
9
+ import { InformationCenterBestiarySection } from './sections/bestiary/InformationCenterBestiarySection';
10
+ import { InformationCenterFAQSection } from './sections/faq/InformationCenterFaqSection';
11
11
  import { InformationCenterItemDetails } from './sections/items/InformationCenterItemDetails';
12
- import { ItemsSection } from './sections/items/ItemsSection';
13
- import { TutorialsSection } from './sections/tutorials/TutorialsSection';
12
+ import { InformationCenterItemsSection } from './sections/items/InformationCenterItemsSection';
13
+ import { InformationCenterTutorialsSection } from './sections/tutorials/InformationCenterTutorialsSection';
14
14
 
15
15
  export interface IFaqItem {
16
16
  id: string;
@@ -73,7 +73,7 @@ export const InformationCenter: React.FC<IInformationCenterProps> = ({
73
73
  id: 'bestiary',
74
74
  title: 'Bestiary',
75
75
  content: (
76
- <BestiarySection
76
+ <InformationCenterBestiarySection
77
77
  bestiaryItems={bestiaryItems}
78
78
  itemsAtlasJSON={itemsAtlasJSON}
79
79
  itemsAtlasIMG={itemsAtlasIMG}
@@ -88,7 +88,7 @@ export const InformationCenter: React.FC<IInformationCenterProps> = ({
88
88
  id: 'items',
89
89
  title: 'Items',
90
90
  content: (
91
- <ItemsSection
91
+ <InformationCenterItemsSection
92
92
  items={items}
93
93
  bestiaryItems={bestiaryItems}
94
94
  itemsAtlasJSON={itemsAtlasJSON}
@@ -102,7 +102,7 @@ export const InformationCenter: React.FC<IInformationCenterProps> = ({
102
102
  id: 'faq',
103
103
  title: 'FAQ',
104
104
  content: (
105
- <FaqSection
105
+ <InformationCenterFAQSection
106
106
  faqItems={faqItems}
107
107
  initialSearchQuery={initialSearchQuery}
108
108
  tabId="faq"
@@ -113,7 +113,7 @@ export const InformationCenter: React.FC<IInformationCenterProps> = ({
113
113
  id: 'tutorials',
114
114
  title: 'Tutorials',
115
115
  content: (
116
- <TutorialsSection
116
+ <InformationCenterTutorialsSection
117
117
  videoGuides={videoGuides}
118
118
  initialSearchQuery={initialSearchQuery}
119
119
  tabId="tutorials"
@@ -94,7 +94,6 @@ const HeaderContainer = styled.div`
94
94
  justify-content: space-between;
95
95
  align-items: flex-start;
96
96
  gap: 1rem;
97
- padding: 0 1rem;
98
97
  margin-top: 1.5rem;
99
98
  `;
100
99
 
@@ -17,7 +17,7 @@ interface IBestiarySectionProps {
17
17
  tabId: string;
18
18
  }
19
19
 
20
- export const BestiarySection: React.FC<IBestiarySectionProps> = ({
20
+ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> = ({
21
21
  bestiaryItems,
22
22
  itemsAtlasJSON,
23
23
  itemsAtlasIMG,
@@ -119,6 +119,7 @@ export const BestiarySection: React.FC<IBestiarySectionProps> = ({
119
119
  onChange: setSearchQuery,
120
120
  placeholder: 'Search monsters...',
121
121
  }}
122
+ itemHeight="180px"
122
123
  />
123
124
  {tooltipData && (
124
125
  <Portal>
@@ -0,0 +1,81 @@
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import styled from 'styled-components';
3
+ import { Collapsible } from '../../../shared/Collapsible/Collapsible';
4
+ import { PaginatedContent } from '../../../shared/PaginatedContent/PaginatedContent';
5
+ import { SearchHeader } from '../../../shared/SearchHeader/SearchHeader';
6
+ import { IFaqItem } from '../../InformationCenter';
7
+
8
+ interface IFaqSectionProps {
9
+ faqItems: IFaqItem[];
10
+ initialSearchQuery: string;
11
+ tabId: string;
12
+ }
13
+
14
+ export const InformationCenterFAQSection: React.FC<IFaqSectionProps> = ({
15
+ faqItems,
16
+ initialSearchQuery,
17
+ tabId,
18
+ }) => {
19
+ const [searchQuery, setSearchQuery] = useState(initialSearchQuery);
20
+
21
+ useEffect(() => {
22
+ setSearchQuery(initialSearchQuery);
23
+ }, [initialSearchQuery]);
24
+
25
+ const filteredFaqs = useMemo(() => {
26
+ if (!searchQuery) return faqItems;
27
+ return faqItems.filter(
28
+ faq =>
29
+ faq.question.toLowerCase().includes(searchQuery.toLowerCase()) ||
30
+ faq.answer.toLowerCase().includes(searchQuery.toLowerCase())
31
+ );
32
+ }, [searchQuery, faqItems]);
33
+
34
+ const renderItem = (item: IFaqItem) => (
35
+ <StyledCollapsible title={item.question}>
36
+ <Answer>{item.answer}</Answer>
37
+ </StyledCollapsible>
38
+ );
39
+
40
+ return (
41
+ <Container>
42
+ <SearchHeader
43
+ searchOptions={{
44
+ value: searchQuery,
45
+ onChange: setSearchQuery,
46
+ placeholder: 'Search FAQs...',
47
+ }}
48
+ />
49
+ <PaginatedContent<IFaqItem>
50
+ items={filteredFaqs}
51
+ renderItem={renderItem}
52
+ emptyMessage="No FAQ items found"
53
+ tabId={tabId}
54
+ layout="list"
55
+ itemsPerPage={10}
56
+ />
57
+ </Container>
58
+ );
59
+ };
60
+
61
+ const Container = styled.div`
62
+ display: flex;
63
+ flex-direction: column;
64
+ gap: 1rem;
65
+ width: 100%;
66
+ `;
67
+
68
+ const StyledCollapsible = styled(Collapsible)`
69
+ margin-bottom: 0.5rem;
70
+
71
+ &:last-child {
72
+ margin-bottom: 0;
73
+ }
74
+ `;
75
+
76
+ const Answer = styled.p`
77
+ font-size: 0.9rem;
78
+ color: #ffffff;
79
+ margin: 0;
80
+ line-height: 1.5;
81
+ `;
@@ -22,7 +22,7 @@ interface IItemsSectionProps {
22
22
  tabId: string;
23
23
  }
24
24
 
25
- export const ItemsSection: React.FC<IItemsSectionProps> = ({
25
+ export const InformationCenterItemsSection: React.FC<IItemsSectionProps> = ({
26
26
  items,
27
27
  bestiaryItems,
28
28
  itemsAtlasJSON,
@@ -142,6 +142,7 @@ export const ItemsSection: React.FC<IItemsSectionProps> = ({
142
142
  dependencies={[selectedItemCategory]}
143
143
  tabId={tabId}
144
144
  layout="grid"
145
+ itemHeight="180px"
145
146
  />
146
147
  {hoveredItem && (
147
148
  <TooltipWrapper
@@ -163,15 +164,6 @@ export const ItemsSection: React.FC<IItemsSectionProps> = ({
163
164
  );
164
165
  };
165
166
 
166
- const StyledPaginatedContent = styled(PaginatedContent)`
167
- .PaginatedContent-content {
168
- display: grid;
169
- grid-template-columns: repeat(4, 1fr);
170
- gap: 0.5rem;
171
- padding: 0 1rem;
172
- }
173
- `;
174
-
175
167
  const TooltipWrapper = styled.div`
176
168
  position: fixed;
177
169
  z-index: 1000;
@@ -0,0 +1,135 @@
1
+ import React, { useState } from 'react';
2
+ import styled from 'styled-components';
3
+ import { uiColors } from '../../../../constants/uiColors';
4
+ import { IOptionsProps } from '../../../Dropdown';
5
+ import { PaginatedContent } from '../../../shared/PaginatedContent/PaginatedContent';
6
+ import { IVideoGuide } from '../../InformationCenter';
7
+
8
+ interface ITutorialsSectionProps {
9
+ videoGuides: IVideoGuide[];
10
+ initialSearchQuery: string;
11
+ tabId: string;
12
+ }
13
+
14
+ export const InformationCenterTutorialsSection: React.FC<ITutorialsSectionProps> = ({
15
+ videoGuides,
16
+ initialSearchQuery,
17
+ tabId,
18
+ }) => {
19
+ const [searchQuery, setSearchQuery] = useState(initialSearchQuery);
20
+ const [selectedCategory, setSelectedCategory] = useState<string>('all');
21
+
22
+ const categoryOptions: IOptionsProps[] = [
23
+ { id: 0, value: 'all', option: 'All' },
24
+ { id: 1, value: 'Combat', option: 'Combat' },
25
+ { id: 2, value: 'Crafting', option: 'Crafting' },
26
+ { id: 3, value: 'Exploration', option: 'Exploration' },
27
+ { id: 4, value: 'General', option: 'General' },
28
+ ];
29
+
30
+ const renderItem = (guide: IVideoGuide) => (
31
+ <GuideItem key={guide.id}>
32
+ <GuideThumbnail>
33
+ <img
34
+ src={guide.thumbnailUrl || '/placeholder-thumbnail.png'}
35
+ alt={guide.title}
36
+ />
37
+ </GuideThumbnail>
38
+ <GuideContent>
39
+ <GuideTitle>{guide.title}</GuideTitle>
40
+ <GuideDescription>{guide.description}</GuideDescription>
41
+ <GuideCategory>{guide.category}</GuideCategory>
42
+ </GuideContent>
43
+ </GuideItem>
44
+ );
45
+
46
+ const filteredGuides = videoGuides.filter(
47
+ guide =>
48
+ (selectedCategory === 'all' || guide.category === selectedCategory) &&
49
+ (guide.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
50
+ guide.description.toLowerCase().includes(searchQuery.toLowerCase()))
51
+ );
52
+
53
+ return (
54
+ <PaginatedContent<IVideoGuide>
55
+ items={filteredGuides}
56
+ renderItem={renderItem}
57
+ emptyMessage="No guides found"
58
+ searchOptions={{
59
+ value: searchQuery,
60
+ onChange: setSearchQuery,
61
+ placeholder: 'Search guides...',
62
+ }}
63
+ filterOptions={{
64
+ options: categoryOptions,
65
+ selectedOption: selectedCategory,
66
+ onOptionChange: setSelectedCategory,
67
+ }}
68
+ dependencies={[selectedCategory]}
69
+ tabId={tabId}
70
+ layout="grid"
71
+ gridColumns={3}
72
+ itemsPerPage={3}
73
+ itemHeight="400px"
74
+ />
75
+ );
76
+ };
77
+
78
+ const GuideItem = styled.div`
79
+ background: rgba(0, 0, 0, 0.3);
80
+ border-radius: 4px;
81
+ overflow: hidden;
82
+ border: 1px solid ${uiColors.darkGray};
83
+ cursor: pointer;
84
+ transition: transform 0.2s ease;
85
+ height: 100%;
86
+ &:hover {
87
+ transform: translateY(-2px);
88
+ }
89
+ `;
90
+
91
+ const GuideThumbnail = styled.div`
92
+ width: 100%;
93
+ height: 168px;
94
+ background: rgba(0, 0, 0, 0.2);
95
+ overflow: hidden;
96
+
97
+ img {
98
+ width: 100%;
99
+ height: 100%;
100
+ object-fit: cover;
101
+ }
102
+
103
+ font-size: 0.8rem;
104
+ line-height: 1.8;
105
+ `;
106
+
107
+ const GuideContent = styled.div`
108
+ padding: 12px;
109
+ `;
110
+
111
+ const GuideTitle = styled.h3`
112
+ margin: 0;
113
+ font-size: 0.6rem;
114
+ color: ${uiColors.yellow};
115
+ font-family: 'Press Start 2P', cursive;
116
+ margin-bottom: 8px;
117
+ `;
118
+
119
+ const GuideDescription = styled.p`
120
+ margin: 0;
121
+ font-size: 0.55rem;
122
+ color: ${uiColors.lightGray};
123
+ font-family: 'Press Start 2P', cursive;
124
+ margin-bottom: 8px;
125
+ line-height: 1.4;
126
+ `;
127
+
128
+ const GuideCategory = styled.span`
129
+ font-size: 0.5rem;
130
+ color: ${uiColors.yellow};
131
+ font-family: 'Press Start 2P', cursive;
132
+ background: rgba(255, 255, 255, 0.1);
133
+ padding: 4px 8px;
134
+ border-radius: 4px;
135
+ `;
@@ -0,0 +1,75 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { HexColorPicker } from 'react-colorful';
3
+ import styled from 'styled-components';
4
+ import { Button, ButtonTypes } from '../../Button';
5
+ import { DraggableContainer } from '../../DraggableContainer';
6
+ import { RPGUIContainerTypes } from '../../RPGUI/RPGUIContainer';
7
+
8
+ interface Props {
9
+ selectedColor: string;
10
+ isOpen: boolean;
11
+ onClose: () => void;
12
+ onConfirm: (color: string) => void;
13
+ onChange: (color: string) => void;
14
+ }
15
+
16
+ export const ColorSelector: React.FC<Props> = ({
17
+ selectedColor,
18
+ isOpen,
19
+ onClose,
20
+ onConfirm,
21
+ onChange,
22
+ }) => {
23
+ const [currentColor, setCurrentColor] = useState(selectedColor);
24
+
25
+ useEffect(() => {
26
+ if (isOpen) setCurrentColor(selectedColor);
27
+ }, [isOpen, selectedColor]);
28
+
29
+ const handleConfirm = () => {
30
+ onConfirm(currentColor);
31
+ onClose();
32
+ };
33
+
34
+ if (!isOpen) return null;
35
+
36
+ return isOpen ? (
37
+ <DraggableContainer
38
+ type={RPGUIContainerTypes.Framed}
39
+ cancelDrag=".react-colorful"
40
+ width="20rem"
41
+ onCloseButton={onClose}
42
+ >
43
+ <Container>
44
+ <Header>Select Color</Header>
45
+ <HexColorPicker
46
+ color={currentColor}
47
+ onChange={color => {
48
+ setCurrentColor(color);
49
+ onChange(color);
50
+ }}
51
+ />
52
+ <Button
53
+ buttonType={ButtonTypes.RPGUIButton}
54
+ type="button"
55
+ onClick={handleConfirm}
56
+ >
57
+ Confirm
58
+ </Button>
59
+ </Container>
60
+ </DraggableContainer>
61
+ ) : null;
62
+ };
63
+
64
+ const Container = styled.div`
65
+ padding: 2rem;
66
+ text-align: center;
67
+ background: inherit;
68
+ `;
69
+
70
+ const Header = styled.h2`
71
+ font-family: 'Press Start 2P', cursive;
72
+ color: white;
73
+ font-size: 1rem;
74
+ margin-bottom: 1rem;
75
+ `;
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import { ColorSelector } from './ItemPropertyColorSelector';
3
+
4
+ interface Props {
5
+ isOpen: boolean;
6
+ selectedColor: string;
7
+ onClose: () => void;
8
+ onConfirm: (color: string) => void;
9
+ onChange: (color: string) => void;
10
+ }
11
+
12
+ export const ItemPropertySimpleHandler: React.FC<Props> = ({
13
+ isOpen,
14
+ selectedColor,
15
+ onClose,
16
+ onConfirm,
17
+ onChange,
18
+ }) => (
19
+ <ColorSelector
20
+ selectedColor={selectedColor}
21
+ isOpen={isOpen}
22
+ onClose={onClose}
23
+ onConfirm={onConfirm}
24
+ onChange={onChange}
25
+ />
26
+ );
@@ -8,7 +8,7 @@ import {
8
8
  ItemContainerType,
9
9
  ItemSocketEvents,
10
10
  ItemSocketEventsDisplayLabels,
11
- ItemType,
11
+ ItemType
12
12
  } from '@rpg-engine/shared';
13
13
 
14
14
  export interface IContextMenuItem {
@@ -192,6 +192,15 @@ export const generateContextMenu = (
192
192
  if (!existInContextAction) {
193
193
  contextActionMenu.push({ id: DepotSocketEvents.OpenContainer, text: 'Open' });
194
194
  }
195
+
196
+ if (itemContainerType === ItemContainerType.Inventory) {
197
+ if (item.textureAtlas === 'items' && item.type === ItemType.Container) {
198
+ contextActionMenu.push({
199
+ id: ItemSocketEvents.ItemPropertyUpdate,
200
+ text: 'Set Color...'
201
+ });
202
+ }
203
+ }
195
204
  }
196
205
 
197
206
  return contextActionMenu;