@rpg-engine/long-bow 0.7.97 → 0.7.99

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 (53) hide show
  1. package/dist/components/DPad/JoystickDPad.d.ts +21 -0
  2. package/dist/components/InformationCenter/InformationCenter.d.ts +29 -0
  3. package/dist/components/InformationCenter/InformationCenterCell.d.ts +14 -0
  4. package/dist/components/InformationCenter/InformationCenterTabView.d.ts +19 -0
  5. package/dist/components/InformationCenter/InformationCenterTypes.d.ts +79 -0
  6. package/dist/components/InformationCenter/sections/bestiary/BestiarySection.d.ts +12 -0
  7. package/dist/components/InformationCenter/sections/bestiary/InformationCenterNPCDetails.d.ts +12 -0
  8. package/dist/components/InformationCenter/sections/bestiary/InformationCenterNPCTooltip.d.ts +9 -0
  9. package/dist/components/InformationCenter/sections/faq/FaqSection.d.ts +8 -0
  10. package/dist/components/InformationCenter/sections/items/InformationCenterItemDetails.d.ts +11 -0
  11. package/dist/components/InformationCenter/sections/items/InformationCenterItemTooltip.d.ts +7 -0
  12. package/dist/components/InformationCenter/sections/items/ItemsSection.d.ts +11 -0
  13. package/dist/components/InformationCenter/sections/tutorials/TutorialsSection.d.ts +8 -0
  14. package/dist/components/InformationCenter/shared/BaseInformationDetails.d.ts +10 -0
  15. package/dist/components/shared/BaseTooltip.d.ts +12 -0
  16. package/dist/components/shared/Collapsible/Collapsible.d.ts +9 -0
  17. package/dist/components/shared/Portal/Portal.d.ts +6 -0
  18. package/dist/index.d.ts +1 -0
  19. package/dist/long-bow.cjs.development.js +271 -5
  20. package/dist/long-bow.cjs.development.js.map +1 -1
  21. package/dist/long-bow.cjs.production.min.js +1 -1
  22. package/dist/long-bow.cjs.production.min.js.map +1 -1
  23. package/dist/long-bow.esm.js +273 -8
  24. package/dist/long-bow.esm.js.map +1 -1
  25. package/dist/mocks/informationCenter.mocks.d.ts +6 -0
  26. package/dist/stories/Features/craftbook/CraftBook.stories.d.ts +2 -0
  27. package/dist/stories/UI/info/InformationCenter.stories.d.ts +7 -0
  28. package/dist/stories/UI/joystick/JoystickDPad.stories.d.ts +6 -0
  29. package/package.json +1 -1
  30. package/src/components/CraftBook/CraftBook.tsx +70 -31
  31. package/src/components/DPad/JoystickDPad.tsx +417 -0
  32. package/src/components/InformationCenter/InformationCenter.tsx +155 -0
  33. package/src/components/InformationCenter/InformationCenterCell.tsx +96 -0
  34. package/src/components/InformationCenter/InformationCenterTabView.tsx +121 -0
  35. package/src/components/InformationCenter/InformationCenterTypes.ts +87 -0
  36. package/src/components/InformationCenter/sections/bestiary/BestiarySection.tsx +170 -0
  37. package/src/components/InformationCenter/sections/bestiary/InformationCenterNPCDetails.tsx +366 -0
  38. package/src/components/InformationCenter/sections/bestiary/InformationCenterNPCTooltip.tsx +204 -0
  39. package/src/components/InformationCenter/sections/faq/FaqSection.tsx +71 -0
  40. package/src/components/InformationCenter/sections/items/InformationCenterItemDetails.tsx +323 -0
  41. package/src/components/InformationCenter/sections/items/InformationCenterItemTooltip.tsx +88 -0
  42. package/src/components/InformationCenter/sections/items/ItemsSection.tsx +180 -0
  43. package/src/components/InformationCenter/sections/tutorials/TutorialsSection.tsx +144 -0
  44. package/src/components/InformationCenter/shared/BaseInformationDetails.tsx +162 -0
  45. package/src/components/InternalTabs/InternalTabs.tsx +1 -3
  46. package/src/components/shared/BaseTooltip.tsx +60 -0
  47. package/src/components/shared/Collapsible/Collapsible.tsx +70 -0
  48. package/src/components/shared/Portal/Portal.tsx +19 -0
  49. package/src/index.tsx +1 -0
  50. package/src/mocks/informationCenter.mocks.ts +562 -0
  51. package/src/stories/Features/craftbook/CraftBook.stories.tsx +15 -1
  52. package/src/stories/UI/info/InformationCenter.stories.tsx +58 -0
  53. package/src/stories/UI/joystick/JoystickDPad.stories.tsx +52 -0
@@ -0,0 +1,144 @@
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 { IVideoGuide } from '../../InformationCenter';
6
+ import { InformationCenterTabView } from '../../InformationCenterTabView';
7
+
8
+ interface ITutorialsSectionProps {
9
+ videoGuides: IVideoGuide[];
10
+ initialSearchQuery: string;
11
+ }
12
+
13
+ export const TutorialsSection: React.FC<ITutorialsSectionProps> = ({
14
+ videoGuides,
15
+ initialSearchQuery,
16
+ }) => {
17
+ const [guidesSearchQuery, setGuidesSearchQuery] = useState(
18
+ initialSearchQuery
19
+ );
20
+ const [selectedGuideCategory, setSelectedGuideCategory] = useState<string>(
21
+ 'all'
22
+ );
23
+
24
+ const guideCategoryOptions: IOptionsProps[] = [
25
+ { id: 0, value: 'all', option: 'All Guides' },
26
+ { id: 1, value: 'Combat', option: 'Combat' },
27
+ { id: 2, value: 'Crafting', option: 'Crafting' },
28
+ { id: 3, value: 'Exploration', option: 'Exploration' },
29
+ { id: 4, value: 'General', option: 'General' },
30
+ ];
31
+
32
+ const filterItems = (items: IVideoGuide[]) => {
33
+ return items.filter(
34
+ guide =>
35
+ (selectedGuideCategory === 'all' ||
36
+ guide.category === selectedGuideCategory) &&
37
+ (guide.title.toLowerCase().includes(guidesSearchQuery.toLowerCase()) ||
38
+ guide.description
39
+ .toLowerCase()
40
+ .includes(guidesSearchQuery.toLowerCase()))
41
+ );
42
+ };
43
+
44
+ const renderContent = (items: IVideoGuide[]) => (
45
+ <GuidesGrid>
46
+ {items.map(guide => (
47
+ <GuideItem key={guide.id}>
48
+ <GuideThumbnail>
49
+ <img
50
+ src={guide.thumbnailUrl || '/placeholder-thumbnail.png'}
51
+ alt={guide.title}
52
+ />
53
+ </GuideThumbnail>
54
+ <GuideContent>
55
+ <GuideTitle>{guide.title}</GuideTitle>
56
+ <GuideDescription>{guide.description}</GuideDescription>
57
+ <GuideCategory>{guide.category}</GuideCategory>
58
+ </GuideContent>
59
+ </GuideItem>
60
+ ))}
61
+ </GuidesGrid>
62
+ );
63
+
64
+ return (
65
+ <InformationCenterTabView
66
+ items={videoGuides}
67
+ searchQuery={guidesSearchQuery}
68
+ onSearchChange={setGuidesSearchQuery}
69
+ filterItems={filterItems}
70
+ renderContent={renderContent}
71
+ searchPlaceholder="Search guides..."
72
+ filterOptions={{
73
+ options: guideCategoryOptions,
74
+ selectedOption: selectedGuideCategory,
75
+ onOptionChange: setSelectedGuideCategory,
76
+ }}
77
+ emptyMessage="No guides found"
78
+ dependencies={[selectedGuideCategory]}
79
+ />
80
+ );
81
+ };
82
+
83
+ const GuidesGrid = styled.div`
84
+ display: grid;
85
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
86
+ gap: 16px;
87
+ padding: 16px;
88
+ `;
89
+
90
+ const GuideItem = styled.div`
91
+ background: rgba(0, 0, 0, 0.3);
92
+ border-radius: 4px;
93
+ overflow: hidden;
94
+ border: 1px solid ${uiColors.darkGray};
95
+ cursor: pointer;
96
+ transition: transform 0.2s ease;
97
+
98
+ &:hover {
99
+ transform: translateY(-2px);
100
+ }
101
+ `;
102
+
103
+ const GuideThumbnail = styled.div`
104
+ width: 100%;
105
+ height: 168px;
106
+ background: rgba(0, 0, 0, 0.2);
107
+ overflow: hidden;
108
+
109
+ img {
110
+ width: 100%;
111
+ height: 100%;
112
+ object-fit: cover;
113
+ }
114
+ `;
115
+
116
+ const GuideContent = styled.div`
117
+ padding: 12px;
118
+ `;
119
+
120
+ const GuideTitle = styled.h3`
121
+ margin: 0;
122
+ font-size: 0.6rem;
123
+ color: ${uiColors.yellow};
124
+ font-family: 'Press Start 2P', cursive;
125
+ margin-bottom: 8px;
126
+ `;
127
+
128
+ const GuideDescription = styled.p`
129
+ margin: 0;
130
+ font-size: 0.55rem;
131
+ color: ${uiColors.lightGray};
132
+ font-family: 'Press Start 2P', cursive;
133
+ margin-bottom: 8px;
134
+ line-height: 1.4;
135
+ `;
136
+
137
+ const GuideCategory = styled.span`
138
+ font-size: 0.5rem;
139
+ color: ${uiColors.yellow};
140
+ font-family: 'Press Start 2P', cursive;
141
+ background: rgba(255, 255, 255, 0.1);
142
+ padding: 4px 8px;
143
+ border-radius: 4px;
144
+ `;
@@ -0,0 +1,162 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { FaTimes } from 'react-icons/fa';
3
+ import styled from 'styled-components';
4
+ import { uiColors } from '../../../constants/uiColors';
5
+ import { SpriteFromAtlas } from '../../shared/SpriteFromAtlas';
6
+
7
+ export interface IBaseInformationDetailsProps {
8
+ name: string;
9
+ spriteKey: string;
10
+ atlasJSON: Record<string, any>;
11
+ atlasIMG: string;
12
+ onBack: () => void;
13
+ children?: ReactNode;
14
+ }
15
+
16
+ export const BaseInformationDetails: React.FC<IBaseInformationDetailsProps> = ({
17
+ name,
18
+ spriteKey,
19
+ atlasJSON,
20
+ atlasIMG,
21
+ onBack,
22
+ children,
23
+ }) => {
24
+ return (
25
+ <Container>
26
+ <Overlay onClick={onBack} />
27
+ <Modal>
28
+ <CloseButton onClick={onBack}>
29
+ <FaTimes />
30
+ </CloseButton>
31
+
32
+ <Header>
33
+ <SpriteContainer>
34
+ <SpriteFromAtlas
35
+ atlasJSON={atlasJSON}
36
+ atlasIMG={atlasIMG}
37
+ spriteKey={spriteKey}
38
+ width={32}
39
+ height={32}
40
+ imgScale={1}
41
+ />
42
+ </SpriteContainer>
43
+ <Title>{name}</Title>
44
+ </Header>
45
+ <Content>{children}</Content>
46
+ </Modal>
47
+ </Container>
48
+ );
49
+ };
50
+
51
+ const Container = styled.div`
52
+ position: fixed;
53
+ top: 0;
54
+ left: 0;
55
+ right: 0;
56
+ bottom: 0;
57
+ display: flex;
58
+ justify-content: center;
59
+ align-items: center;
60
+ z-index: 1000;
61
+ `;
62
+
63
+ const Overlay = styled.div`
64
+ position: absolute;
65
+ top: 0;
66
+ left: 0;
67
+ right: 0;
68
+ bottom: 0;
69
+ background-color: rgba(0, 0, 0, 0.8);
70
+ `;
71
+
72
+ const Modal = styled.div`
73
+ position: relative;
74
+ width: 90%;
75
+ max-width: 800px;
76
+ max-height: 90vh;
77
+ background-color: rgba(0, 0, 0, 0.95);
78
+ border-radius: 4px;
79
+ padding: 16px;
80
+ overflow-y: auto;
81
+ z-index: 1;
82
+ font-family: 'Press Start 2P', cursive;
83
+ border: 1px solid ${uiColors.darkGray};
84
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
85
+
86
+ &::-webkit-scrollbar {
87
+ width: 2px;
88
+ }
89
+
90
+ &::-webkit-scrollbar-track {
91
+ background: transparent;
92
+ }
93
+
94
+ &::-webkit-scrollbar-thumb {
95
+ background-color: ${uiColors.yellow};
96
+ border-radius: 4px;
97
+ opacity: 0.5;
98
+
99
+ &:hover {
100
+ opacity: 1;
101
+ }
102
+ }
103
+
104
+ scrollbar-width: thin;
105
+ scrollbar-color: ${uiColors.yellow} transparent;
106
+ `;
107
+
108
+ const CloseButton = styled.button`
109
+ position: absolute;
110
+ top: 20px;
111
+ right: 20px;
112
+ background: none;
113
+ border: none;
114
+ color: ${uiColors.yellow};
115
+ font-size: 1.2rem;
116
+ cursor: pointer;
117
+ padding: 0;
118
+ z-index: 1;
119
+ transition: transform 0.2s ease;
120
+
121
+ &:hover {
122
+ transform: scale(1.1);
123
+ }
124
+ `;
125
+
126
+ const Header = styled.div`
127
+ display: flex;
128
+ align-items: center;
129
+ gap: 16px;
130
+ margin-bottom: 24px;
131
+ `;
132
+
133
+ const Content = styled.div`
134
+ display: flex;
135
+ flex-direction: column;
136
+ gap: 16px;
137
+ `;
138
+
139
+ const Title = styled.h2`
140
+ color: ${uiColors.yellow};
141
+ font-size: 1rem;
142
+ margin: 0;
143
+ `;
144
+
145
+ const SpriteContainer = styled.div`
146
+ width: 64px;
147
+ height: 64px;
148
+ background: rgba(0, 0, 0, 0.3);
149
+ border-radius: 4px;
150
+ display: flex;
151
+ justify-content: center;
152
+ align-items: center;
153
+ position: relative;
154
+
155
+ .sprite-from-atlas-img {
156
+ position: absolute;
157
+ top: 50%;
158
+ left: 50%;
159
+ transform: translate(-50%, -50%) scale(2);
160
+ transform-origin: center;
161
+ }
162
+ `;
@@ -88,6 +88,4 @@ const TabButton = styled.button<{
88
88
  }
89
89
  `;
90
90
 
91
- const ContentWrapper = styled.div`
92
- padding: 1rem;
93
- `;
91
+ const ContentWrapper = styled.div``;
@@ -0,0 +1,60 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { uiColors } from '../../constants/uiColors';
4
+
5
+ interface IBaseTooltipProps {
6
+ children: React.ReactNode;
7
+ width?: string;
8
+ }
9
+
10
+ const TooltipContainer = styled.div<{ width?: string }>`
11
+ background-color: rgba(0, 0, 0, 0.95);
12
+ border-radius: 4px;
13
+ padding: 8px;
14
+ font-family: 'Press Start 2P', cursive;
15
+ font-size: 0.6rem;
16
+ width: ${props => props.width || '280px'};
17
+ border: 1px solid ${uiColors.darkGray};
18
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
19
+ `;
20
+
21
+ export const TooltipTitle = styled.div`
22
+ color: ${uiColors.yellow};
23
+ font-size: 0.6rem;
24
+ letter-spacing: 0.5px;
25
+ margin-bottom: 8px;
26
+ `;
27
+
28
+ export const Section = styled.div`
29
+ margin-top: 6px;
30
+ `;
31
+
32
+ export const SectionTitle = styled.div`
33
+ color: ${uiColors.yellow};
34
+ font-size: 0.5rem;
35
+ margin-bottom: 4px;
36
+ opacity: 0.7;
37
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
38
+ padding-bottom: 4px;
39
+ `;
40
+
41
+ export const StatsContainer = styled.div`
42
+ display: grid;
43
+ grid-template-columns: repeat(2, 1fr);
44
+ gap: 2px 8px;
45
+ `;
46
+
47
+ export const StatItem = styled.div`
48
+ color: ${uiColors.white};
49
+ font-size: 0.5rem;
50
+ text-align: left;
51
+ `;
52
+
53
+ export const BaseTooltip: React.FC<IBaseTooltipProps> = ({
54
+ children,
55
+ width,
56
+ }) => {
57
+ return <TooltipContainer width={width}>{children}</TooltipContainer>;
58
+ };
59
+
60
+ export default BaseTooltip;
@@ -0,0 +1,70 @@
1
+ import React, { useState } from 'react';
2
+ import { FaChevronDown, FaChevronUp } from 'react-icons/fa';
3
+ import styled from 'styled-components';
4
+ import { uiColors } from '../../../constants/uiColors';
5
+
6
+ interface ICollapsibleProps {
7
+ title: string;
8
+ children: React.ReactNode;
9
+ defaultOpen?: boolean;
10
+ className?: string;
11
+ }
12
+
13
+ export const Collapsible: React.FC<ICollapsibleProps> = ({
14
+ title,
15
+ children,
16
+ defaultOpen = false,
17
+ className,
18
+ }) => {
19
+ const [isOpen, setIsOpen] = useState(defaultOpen);
20
+
21
+ return (
22
+ <Container className={className}>
23
+ <Header onClick={() => setIsOpen(!isOpen)}>
24
+ <Title>{title}</Title>
25
+ <Icon>{isOpen ? <FaChevronUp /> : <FaChevronDown />}</Icon>
26
+ </Header>
27
+ {isOpen && <Content>{children}</Content>}
28
+ </Container>
29
+ );
30
+ };
31
+
32
+ const Container = styled.div`
33
+ background: rgba(0, 0, 0, 0.3);
34
+ border-radius: 4px;
35
+ overflow: hidden;
36
+ border: 1px solid ${uiColors.darkGray};
37
+ `;
38
+
39
+ const Header = styled.div`
40
+ padding: 10px 12px;
41
+ background: rgba(0, 0, 0, 0.2);
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: space-between;
45
+ cursor: pointer;
46
+ transition: background-color 0.2s ease;
47
+
48
+ &:hover {
49
+ background: rgba(0, 0, 0, 0.4);
50
+ }
51
+ `;
52
+
53
+ const Title = styled.h3`
54
+ margin: 0;
55
+ font-size: 0.6rem;
56
+ color: ${uiColors.yellow};
57
+ font-family: 'Press Start 2P', cursive;
58
+ letter-spacing: 0.5px;
59
+ `;
60
+
61
+ const Icon = styled.span`
62
+ color: ${uiColors.yellow};
63
+ font-size: 0.6rem;
64
+ display: flex;
65
+ align-items: center;
66
+ `;
67
+
68
+ const Content = styled.div`
69
+ padding: 12px;
70
+ `;
@@ -0,0 +1,19 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { createPortal } from 'react-dom';
3
+
4
+ interface IPortalProps {
5
+ children: React.ReactNode;
6
+ }
7
+
8
+ export const Portal: React.FC<IPortalProps> = ({ children }) => {
9
+ const [container] = useState(() => document.createElement('div'));
10
+
11
+ useEffect(() => {
12
+ document.body.appendChild(container);
13
+ return () => {
14
+ document.body.removeChild(container);
15
+ };
16
+ }, [container]);
17
+
18
+ return createPortal(children, container);
19
+ };
package/src/index.tsx CHANGED
@@ -9,6 +9,7 @@ export * from './components/CheckButton';
9
9
  export * from './components/CheckItem';
10
10
  export * from './components/CircularController/CircularController';
11
11
  export * from './components/CraftBook/CraftBook';
12
+ export * from './components/DPad/JoystickDPad';
12
13
  export * from './components/DraggableContainer';
13
14
  export * from './components/Dropdown';
14
15
  export * from './components/DropdownSelectorContainer';