@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.
- package/dist/components/InformationCenter/sections/bestiary/{BestiarySection.d.ts → InformationCenterBestiarySection.d.ts} +1 -1
- package/dist/components/InformationCenter/sections/faq/{FaqSection.d.ts → InformationCenterFaqSection.d.ts} +1 -1
- package/dist/components/InformationCenter/sections/items/{ItemsSection.d.ts → InformationCenterItemsSection.d.ts} +1 -1
- package/dist/components/InformationCenter/sections/tutorials/{TutorialsSection.d.ts → InformationCenterTutorialsSection.d.ts} +2 -1
- package/dist/components/Item/Inventory/ItemPropertyColorSelector.d.ts +10 -0
- package/dist/components/Item/Inventory/ItemPropertySimpleHandler.d.ts +10 -0
- package/dist/components/Store/CartView.d.ts +15 -0
- package/dist/components/Store/StoreItemDetails.d.ts +16 -0
- package/dist/components/Store/StoreItemRow.d.ts +1 -2
- package/dist/components/Store/StoreTypes.d.ts +33 -4
- package/dist/components/Store/hooks/useStoreCart.d.ts +14 -0
- package/dist/components/Store/sections/StoreItemsSection.d.ts +12 -0
- package/dist/components/Store/sections/StorePacksSection.d.ts +9 -0
- package/dist/components/shared/CTAButton/CTAButton.d.ts +13 -0
- package/dist/components/shared/Card/Card.d.ts +14 -0
- package/dist/components/shared/Ellipsis.d.ts +1 -1
- package/dist/components/shared/PaginatedContent/PaginatedContent.d.ts +3 -1
- package/dist/components/shared/ScrollableContent/ScrollableContent.d.ts +23 -0
- package/dist/components/shared/SearchBar/SearchBar.d.ts +2 -3
- package/dist/components/shared/SearchHeader/SearchHeader.d.ts +17 -0
- package/dist/components/shared/ShoppingCart/CartCard.d.ts +14 -0
- package/dist/components/shared/ShoppingCart/CartCardHorizontal.d.ts +13 -0
- package/dist/index.d.ts +1 -0
- package/dist/long-bow.cjs.development.js +105 -39
- 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 +105 -40
- package/dist/long-bow.esm.js.map +1 -1
- package/dist/stories/UI/buttonsAndInputs/CTAButton.stories.d.ts +18 -0
- package/dist/stories/UI/dropdownsAndSelectors/ItemPropertyColorSelector.stories.d.ts +3 -0
- package/package.json +3 -2
- package/src/components/InformationCenter/InformationCenter.tsx +8 -8
- package/src/components/InformationCenter/InformationCenterTabView.tsx +0 -1
- package/src/components/InformationCenter/sections/bestiary/{BestiarySection.tsx → InformationCenterBestiarySection.tsx} +2 -1
- package/src/components/InformationCenter/sections/faq/InformationCenterFaqSection.tsx +81 -0
- package/src/components/InformationCenter/sections/items/{ItemsSection.tsx → InformationCenterItemsSection.tsx} +2 -10
- package/src/components/InformationCenter/sections/tutorials/InformationCenterTutorialsSection.tsx +135 -0
- package/src/components/Item/Inventory/ItemPropertyColorSelector.tsx +75 -0
- package/src/components/Item/Inventory/ItemPropertySimpleHandler.tsx +26 -0
- package/src/components/Item/Inventory/itemContainerHelper.ts +10 -1
- package/src/components/Store/CartView.tsx +271 -0
- package/src/components/Store/Store.tsx +199 -96
- package/src/components/Store/StoreItemDetails.tsx +161 -0
- package/src/components/Store/StoreItemRow.tsx +24 -40
- package/src/components/Store/StoreTypes.ts +38 -4
- package/src/components/Store/hooks/useStoreCart.ts +121 -0
- package/src/components/Store/sections/StoreItemsSection.tsx +52 -0
- package/src/components/Store/sections/StorePacksSection.tsx +89 -0
- package/src/components/Store/sections/images/custom-skin.png +0 -0
- package/src/components/shared/CTAButton/CTAButton.tsx +127 -0
- package/src/components/shared/Card/Card.tsx +107 -0
- package/src/components/shared/Ellipsis.tsx +20 -22
- package/src/components/shared/PaginatedContent/PaginatedContent.tsx +48 -79
- package/src/components/shared/ScrollableContent/ScrollableContent.tsx +160 -0
- package/src/components/shared/SearchBar/SearchBar.tsx +43 -24
- package/src/components/shared/SearchHeader/SearchHeader.tsx +80 -0
- package/src/components/shared/ShoppingCart/CartCard.tsx +116 -0
- package/src/components/shared/ShoppingCart/CartCardHorizontal.tsx +120 -0
- package/src/components/shared/SpriteFromAtlas.tsx +2 -0
- package/src/index.tsx +1 -0
- package/src/stories/Features/store/Store.stories.tsx +54 -4
- package/src/stories/UI/buttonsAndInputs/CTAButton.stories.tsx +77 -0
- package/src/stories/UI/dropdownsAndSelectors/ItemPropertyColorSelector.stories.tsx +77 -0
- package/dist/components/Store/InternalStoreTab.d.ts +0 -15
- package/dist/components/Store/StoreTabContent.d.ts +0 -14
- package/src/components/InformationCenter/sections/faq/FaqSection.tsx +0 -51
- package/src/components/InformationCenter/sections/tutorials/TutorialsSection.tsx +0 -144
- package/src/components/Store/InternalStoreTab.tsx +0 -142
- 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.
|
|
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.
|
|
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 {
|
|
10
|
-
import {
|
|
9
|
+
import { InformationCenterBestiarySection } from './sections/bestiary/InformationCenterBestiarySection';
|
|
10
|
+
import { InformationCenterFAQSection } from './sections/faq/InformationCenterFaqSection';
|
|
11
11
|
import { InformationCenterItemDetails } from './sections/items/InformationCenterItemDetails';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
116
|
+
<InformationCenterTutorialsSection
|
|
117
117
|
videoGuides={videoGuides}
|
|
118
118
|
initialSearchQuery={initialSearchQuery}
|
|
119
119
|
tabId="tutorials"
|
|
@@ -17,7 +17,7 @@ interface IBestiarySectionProps {
|
|
|
17
17
|
tabId: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export const
|
|
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
|
|
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;
|
package/src/components/InformationCenter/sections/tutorials/InformationCenterTutorialsSection.tsx
ADDED
|
@@ -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;
|