@rpg-engine/long-bow 0.8.6 → 0.8.8

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 (73) 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/components/shared/SpriteFromAtlas.d.ts +1 -0
  24. package/dist/index.d.ts +1 -0
  25. package/dist/long-bow.cjs.development.js +109 -44
  26. package/dist/long-bow.cjs.development.js.map +1 -1
  27. package/dist/long-bow.cjs.production.min.js +1 -1
  28. package/dist/long-bow.cjs.production.min.js.map +1 -1
  29. package/dist/long-bow.esm.js +109 -45
  30. package/dist/long-bow.esm.js.map +1 -1
  31. package/dist/stories/UI/buttonsAndInputs/CTAButton.stories.d.ts +18 -0
  32. package/dist/stories/UI/dropdownsAndSelectors/ItemPropertyColorSelector.stories.d.ts +3 -0
  33. package/package.json +3 -2
  34. package/src/components/InformationCenter/InformationCenter.tsx +8 -8
  35. package/src/components/InformationCenter/InformationCenterTabView.tsx +0 -1
  36. package/src/components/InformationCenter/sections/bestiary/{BestiarySection.tsx → InformationCenterBestiarySection.tsx} +2 -1
  37. package/src/components/InformationCenter/sections/faq/InformationCenterFaqSection.tsx +81 -0
  38. package/src/components/InformationCenter/sections/items/{ItemsSection.tsx → InformationCenterItemsSection.tsx} +2 -10
  39. package/src/components/InformationCenter/sections/tutorials/InformationCenterTutorialsSection.tsx +135 -0
  40. package/src/components/Item/Inventory/ItemPropertyColorSelector.tsx +75 -0
  41. package/src/components/Item/Inventory/ItemPropertySimpleHandler.tsx +26 -0
  42. package/src/components/Item/Inventory/ItemSlotRenderer.tsx +1 -0
  43. package/src/components/Item/Inventory/itemContainerHelper.ts +10 -1
  44. package/src/components/Store/CartView.tsx +271 -0
  45. package/src/components/Store/Store.tsx +199 -96
  46. package/src/components/Store/StoreItemDetails.tsx +161 -0
  47. package/src/components/Store/StoreItemRow.tsx +24 -40
  48. package/src/components/Store/StoreTypes.ts +38 -4
  49. package/src/components/Store/hooks/useStoreCart.ts +121 -0
  50. package/src/components/Store/sections/StoreItemsSection.tsx +52 -0
  51. package/src/components/Store/sections/StorePacksSection.tsx +89 -0
  52. package/src/components/Store/sections/images/custom-skin.png +0 -0
  53. package/src/components/shared/CTAButton/CTAButton.tsx +127 -0
  54. package/src/components/shared/Card/Card.tsx +107 -0
  55. package/src/components/shared/Ellipsis.tsx +20 -22
  56. package/src/components/shared/PaginatedContent/PaginatedContent.tsx +48 -79
  57. package/src/components/shared/ScrollableContent/ScrollableContent.tsx +160 -0
  58. package/src/components/shared/SearchBar/SearchBar.tsx +43 -24
  59. package/src/components/shared/SearchHeader/SearchHeader.tsx +80 -0
  60. package/src/components/shared/ShoppingCart/CartCard.tsx +116 -0
  61. package/src/components/shared/ShoppingCart/CartCardHorizontal.tsx +120 -0
  62. package/src/components/shared/SpriteFromAtlas.tsx +59 -38
  63. package/src/index.tsx +1 -0
  64. package/src/mocks/itemContainer.mocks.ts +1 -0
  65. package/src/stories/Features/store/Store.stories.tsx +54 -4
  66. package/src/stories/UI/buttonsAndInputs/CTAButton.stories.tsx +77 -0
  67. package/src/stories/UI/dropdownsAndSelectors/ItemPropertyColorSelector.stories.tsx +77 -0
  68. package/dist/components/Store/InternalStoreTab.d.ts +0 -15
  69. package/dist/components/Store/StoreTabContent.d.ts +0 -14
  70. package/src/components/InformationCenter/sections/faq/FaqSection.tsx +0 -51
  71. package/src/components/InformationCenter/sections/tutorials/TutorialsSection.tsx +0 -144
  72. package/src/components/Store/InternalStoreTab.tsx +0 -142
  73. package/src/components/Store/StoreTabContent.tsx +0 -46
@@ -1,52 +1,71 @@
1
1
  import React from 'react';
2
+ import { FaSearch } from 'react-icons/fa';
2
3
  import styled from 'styled-components';
3
4
 
4
- interface SearchBarProps {
5
+ interface ISearchBarProps {
5
6
  value: string;
6
7
  onChange: (value: string) => void;
7
8
  placeholder?: string;
8
9
  className?: string;
9
- autoFocus?: boolean;
10
10
  }
11
11
 
12
- export const SearchBar: React.FC<SearchBarProps> = ({
12
+ export const SearchBar: React.FC<ISearchBarProps> = ({
13
13
  value,
14
14
  onChange,
15
- placeholder = 'Search...',
15
+ placeholder,
16
16
  className,
17
- autoFocus = false,
18
17
  }) => {
19
18
  return (
20
19
  <Container className={className}>
21
- <input
20
+ <Input
22
21
  type="text"
23
- className="rpgui-input"
24
- placeholder={placeholder}
25
22
  value={value}
26
23
  onChange={e => onChange(e.target.value)}
27
- autoFocus={autoFocus}
24
+ placeholder={placeholder}
25
+ className="rpgui-input"
28
26
  />
27
+ <IconContainer>
28
+ <SearchIcon />
29
+ </IconContainer>
29
30
  </Container>
30
31
  );
31
32
  };
32
33
 
33
34
  const Container = styled.div`
34
- input {
35
- width: 100%;
36
- font-size: 0.8rem;
37
- padding: 8px 12px;
38
- background-color: rgba(0, 0, 0, 0.3);
39
- border: none;
40
- color: white;
41
- border-radius: 4px;
35
+ position: relative;
36
+ width: 100%;
37
+ `;
42
38
 
43
- &::placeholder {
44
- color: rgba(255, 255, 255, 0.5);
45
- }
39
+ const Input = styled.input`
40
+ width: 100%;
41
+ padding-right: 2.5rem !important;
42
+ background: rgba(0, 0, 0, 0.2) !important;
43
+ border: 2px solid #f59e0b !important;
44
+ box-shadow: 0 0 10px rgba(245, 158, 11, 0.3);
45
+ color: #ffffff !important;
46
+ font-family: 'Press Start 2P', cursive !important;
47
+ font-size: 0.875rem !important;
46
48
 
47
- &:focus {
48
- outline: none;
49
- background-color: rgba(0, 0, 0, 0.4);
50
- }
49
+ &::placeholder {
50
+ color: rgba(255, 255, 255, 0.5) !important;
51
51
  }
52
52
  `;
53
+
54
+ const IconContainer = styled.div`
55
+ position: absolute;
56
+ right: 0.75rem;
57
+ top: 50%;
58
+ transform: translateY(-50%);
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ width: 24px;
63
+ height: 24px;
64
+ pointer-events: none;
65
+ `;
66
+
67
+ const SearchIcon = styled(FaSearch)`
68
+ font-size: 1rem;
69
+ color: #f59e0b;
70
+ filter: drop-shadow(0 0 2px rgba(245, 158, 11, 0.3));
71
+ `;
@@ -0,0 +1,80 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { Dropdown, IOptionsProps } from '../../Dropdown';
4
+ import { SearchBar } from '../SearchBar/SearchBar';
5
+
6
+ interface ISearchHeaderProps {
7
+ searchOptions?: {
8
+ value: string;
9
+ onChange: (value: string) => void;
10
+ placeholder?: string;
11
+ };
12
+ filterOptions?: {
13
+ options: IOptionsProps[];
14
+ selectedOption: string;
15
+ onOptionChange: (value: string) => void;
16
+ };
17
+ className?: string;
18
+ }
19
+
20
+ export const SearchHeader: React.FC<ISearchHeaderProps> = ({
21
+ searchOptions,
22
+ filterOptions,
23
+ className,
24
+ }) => {
25
+ if (!searchOptions && !filterOptions) return null;
26
+
27
+ return (
28
+ <HeaderContainer className={className}>
29
+ <HeaderContent>
30
+ {searchOptions && (
31
+ <SearchContainer>
32
+ <StyledSearchBar
33
+ value={searchOptions.value}
34
+ onChange={searchOptions.onChange}
35
+ placeholder={searchOptions.placeholder || 'Search...'}
36
+ />
37
+ </SearchContainer>
38
+ )}
39
+ {filterOptions && (
40
+ <FilterContainer>
41
+ <StyledDropdown
42
+ options={filterOptions.options}
43
+ onChange={filterOptions.onOptionChange}
44
+ width="200px"
45
+ />
46
+ </FilterContainer>
47
+ )}
48
+ </HeaderContent>
49
+ </HeaderContainer>
50
+ );
51
+ };
52
+
53
+ const HeaderContainer = styled.div``;
54
+
55
+ const HeaderContent = styled.div`
56
+ display: flex;
57
+ justify-content: space-between;
58
+ align-items: center;
59
+ gap: 1rem;
60
+ background: rgba(0, 0, 0, 0.2);
61
+ padding: 1rem;
62
+ border-radius: 4px;
63
+ `;
64
+
65
+ const SearchContainer = styled.div`
66
+ flex: 1;
67
+ `;
68
+
69
+ const FilterContainer = styled.div`
70
+ display: flex;
71
+ justify-content: flex-end;
72
+ `;
73
+
74
+ const StyledSearchBar = styled(SearchBar)`
75
+ width: 100%;
76
+ `;
77
+
78
+ const StyledDropdown = styled(Dropdown)`
79
+ min-width: 150px;
80
+ `;
@@ -0,0 +1,116 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { uiColors } from '../../../constants/uiColors';
4
+ import { Ellipsis } from '../Ellipsis';
5
+
6
+ export interface ICardProps {
7
+ title: string;
8
+ description: string;
9
+ imageUrl?: string | { src: string; default?: string };
10
+ category?: string;
11
+ onClick?: () => void;
12
+ footer?: React.ReactNode;
13
+ className?: string;
14
+ }
15
+
16
+ export const ShoppingCard: React.FC<ICardProps> = ({
17
+ title,
18
+ description,
19
+ imageUrl,
20
+ category,
21
+ onClick,
22
+ footer,
23
+ className,
24
+ }) => {
25
+ const getImageSrc = () => {
26
+ if (!imageUrl) return '/placeholder-thumbnail.png';
27
+ if (typeof imageUrl === 'string') return imageUrl;
28
+ return imageUrl.default || imageUrl.src;
29
+ };
30
+
31
+ return (
32
+ <CardContainer onClick={onClick} className={className}>
33
+ {imageUrl && (
34
+ <CardThumbnail>
35
+ <img src={getImageSrc()} alt={title} />
36
+ </CardThumbnail>
37
+ )}
38
+ <CardContent>
39
+ <CardTitle>
40
+ <Ellipsis maxLines={1} maxWidth="100%">
41
+ {title}
42
+ </Ellipsis>
43
+ </CardTitle>
44
+ <CardDescription>
45
+ <Ellipsis maxLines={5} maxWidth="100%">
46
+ {description}
47
+ </Ellipsis>
48
+ </CardDescription>
49
+ {category && <CardCategory>{category}</CardCategory>}
50
+ {footer && <CardFooter>{footer}</CardFooter>}
51
+ </CardContent>
52
+ </CardContainer>
53
+ );
54
+ };
55
+
56
+ const CardContainer = styled.div<{ onClick?: () => void }>`
57
+ background: rgba(0, 0, 0, 0.3);
58
+ border-radius: 4px;
59
+ overflow: hidden;
60
+ border: 1px solid ${uiColors.darkGray};
61
+ cursor: ${props => (props.onClick ? 'pointer' : 'default')};
62
+ transition: transform 0.2s ease;
63
+
64
+ &:hover {
65
+ transform: ${props => (props.onClick ? 'translateY(-2px)' : 'none')};
66
+ }
67
+ `;
68
+
69
+ const CardThumbnail = styled.div`
70
+ width: 100%;
71
+ height: 168px;
72
+ background: rgba(0, 0, 0, 0.2);
73
+ overflow: hidden;
74
+
75
+ img {
76
+ width: 100%;
77
+ height: 100%;
78
+ object-fit: cover;
79
+ }
80
+ `;
81
+
82
+ const CardContent = styled.div`
83
+ padding: 12px;
84
+ `;
85
+
86
+ const CardTitle = styled.h3`
87
+ margin: 0;
88
+ font-size: 0.6rem;
89
+ color: ${uiColors.yellow};
90
+ font-family: 'Press Start 2P', cursive;
91
+ margin-bottom: 8px;
92
+ `;
93
+
94
+ const CardDescription = styled.p`
95
+ margin: 0;
96
+ font-size: 0.55rem;
97
+ color: ${uiColors.lightGray};
98
+ font-family: 'Press Start 2P', cursive;
99
+ margin-bottom: 8px;
100
+ line-height: 1.4;
101
+ `;
102
+
103
+ const CardCategory = styled.span`
104
+ font-size: 0.5rem;
105
+ color: ${uiColors.yellow};
106
+ font-family: 'Press Start 2P', cursive;
107
+ background: rgba(255, 255, 255, 0.1);
108
+ padding: 4px 8px;
109
+ border-radius: 4px;
110
+ `;
111
+
112
+ const CardFooter = styled.div`
113
+ margin-top: 12px;
114
+ padding-top: 12px;
115
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
116
+ `;
@@ -0,0 +1,120 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { uiColors } from '../../../constants/uiColors';
4
+ import { Ellipsis } from '../Ellipsis';
5
+
6
+ export interface ICardProps {
7
+ title: string;
8
+ description: string;
9
+ imageUrl?: string | { src: string; default?: string };
10
+ onClick?: () => void;
11
+ footer?: React.ReactNode;
12
+ className?: string;
13
+ }
14
+
15
+ export const ShoppingCardHorizontal: React.FC<ICardProps> = ({
16
+ title,
17
+ description,
18
+ imageUrl,
19
+ onClick,
20
+ footer,
21
+ className,
22
+ }) => {
23
+ const getImageSrc = () => {
24
+ if (!imageUrl) return '/placeholder-thumbnail.png';
25
+ if (typeof imageUrl === 'string') return imageUrl;
26
+ return imageUrl.default || imageUrl.src;
27
+ };
28
+
29
+ return (
30
+ <CardContainer onClick={onClick} className={className}>
31
+ <LeftSection>
32
+ {imageUrl && (
33
+ <CardThumbnail>
34
+ <img src={getImageSrc()} alt={title} />
35
+ </CardThumbnail>
36
+ )}
37
+ </LeftSection>
38
+ <RightSection>
39
+ <CardTitle>
40
+ <Ellipsis maxLines={1} maxWidth="100%">
41
+ {title}
42
+ </Ellipsis>
43
+ </CardTitle>
44
+ <CardDescription>
45
+ <Ellipsis maxLines={3} maxWidth="100%">
46
+ {description}
47
+ </Ellipsis>
48
+ </CardDescription>
49
+ {footer && (
50
+ <CardFooter onClick={e => e.stopPropagation()}>{footer}</CardFooter>
51
+ )}
52
+ </RightSection>
53
+ </CardContainer>
54
+ );
55
+ };
56
+
57
+ const CardContainer = styled.div<{ onClick?: () => void }>`
58
+ display: flex;
59
+ background: rgba(0, 0, 0, 0.3);
60
+ border-radius: 4px;
61
+ border: 1px solid ${uiColors.darkGray};
62
+ cursor: ${props => (props.onClick ? 'pointer' : 'default')};
63
+ transition: transform 0.2s ease;
64
+
65
+ &:hover {
66
+ transform: ${props => (props.onClick ? 'translateY(-2px)' : 'none')};
67
+ }
68
+
69
+ max-width: 380px;
70
+ `;
71
+
72
+ const LeftSection = styled.div`
73
+ width: 120px;
74
+ flex-shrink: 0;
75
+ `;
76
+
77
+ const RightSection = styled.div`
78
+ flex: 1;
79
+ display: flex;
80
+ flex-direction: column;
81
+ padding: 12px;
82
+ min-width: 0;
83
+ max-width: 100%;
84
+ `;
85
+
86
+ const CardThumbnail = styled.div`
87
+ width: 100%;
88
+ height: 100%;
89
+ background: rgba(0, 0, 0, 0.2);
90
+ overflow: hidden;
91
+
92
+ img {
93
+ width: 100%;
94
+ height: 100%;
95
+ object-fit: cover;
96
+ }
97
+ `;
98
+
99
+ const CardTitle = styled.h3`
100
+ margin: 0;
101
+ font-size: 0.6rem;
102
+ color: ${uiColors.yellow};
103
+ font-family: 'Press Start 2P', cursive;
104
+ margin-bottom: 8px;
105
+ `;
106
+
107
+ const CardDescription = styled.p`
108
+ margin: 0;
109
+ font-size: 0.55rem;
110
+ color: ${uiColors.lightGray};
111
+ font-family: 'Press Start 2P', cursive;
112
+ line-height: 1.4;
113
+ margin-bottom: 8px;
114
+ `;
115
+
116
+ const CardFooter = styled.div`
117
+ margin-top: auto;
118
+ padding-top: 8px;
119
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
120
+ `;
@@ -10,6 +10,7 @@ interface IProps {
10
10
  height?: number;
11
11
  grayScale?: boolean;
12
12
  opacity?: number;
13
+ tintColor?: string;
13
14
  onPointerDown?: () => void;
14
15
  containerStyle?: any;
15
16
  imgStyle?: any;
@@ -31,46 +32,47 @@ export const SpriteFromAtlas: React.FC<IProps> = ({
31
32
  containerStyle,
32
33
  grayScale = false,
33
34
  opacity = 1,
35
+ tintColor,
34
36
  imgClassname,
35
37
  centered,
36
38
  borderRadius,
37
39
  }) => {
38
- //! If an item is not showing, remember that you MUST run yarn atlas:copy everytime you add a new item to the atlas (it will sync our public folder atlas with src/atlas).
39
- //!Due to React's limitations, we cannot import it from the public folder directly!
40
+ //! If an item is not showing, remember that you MUST run yarn atlas:copy everytime you add a new item to the atlas (it will sync our public folder atlas with src/atlas).
41
+ //!Due to React's limitations, we cannot import it from the public folder directly!
42
+ const spriteData =
43
+ atlasJSON?.frames?.[spriteKey] ||
44
+ atlasJSON?.frames?.['others/no-image.png'];
40
45
 
41
- const spriteData =
42
- atlasJSON?.frames?.[spriteKey] ||
43
- atlasJSON?.frames?.['others/no-image.png'];
46
+ if (!spriteData) {
47
+ console.error(
48
+ `SpriteFromAtlas: Could not find sprite with key ${spriteKey} in atlasJSON.`
49
+ );
50
+ return null;
51
+ }
44
52
 
45
- if (!spriteData) {
46
- console.error(
47
- `SpriteFromAtlas: Could not find sprite with key ${spriteKey} in atlasJSON.`
48
- );
49
- return null;
50
- }
51
-
52
- return (
53
- <Container
54
- width={width}
55
- height={height}
56
- hasHover={grayScale}
57
- onPointerDown={onPointerDown}
58
- style={containerStyle}
59
- >
60
- <ImgSprite
61
- className={`sprite-from-atlas-img ${imgClassname || ''}`}
62
- atlasIMG={atlasIMG}
63
- frame={spriteData.frame}
64
- scale={imgScale}
65
- grayScale={grayScale}
66
- opacity={opacity}
67
- style={imgStyle}
68
- centered={centered}
69
- borderRadius={borderRadius}
70
- />
71
- </Container>
72
- );
73
- };
53
+ return (
54
+ <Container
55
+ width={width}
56
+ height={height}
57
+ hasHover={grayScale}
58
+ onPointerDown={onPointerDown}
59
+ style={containerStyle}
60
+ >
61
+ <ImgSprite
62
+ className={`sprite-from-atlas-img ${imgClassname || ''}`}
63
+ atlasIMG={atlasIMG}
64
+ frame={spriteData.frame}
65
+ scale={imgScale}
66
+ grayScale={grayScale}
67
+ opacity={opacity}
68
+ style={imgStyle}
69
+ centered={centered}
70
+ borderRadius={borderRadius}
71
+ tintColor={tintColor}
72
+ />
73
+ </Container>
74
+ );
75
+ };
74
76
 
75
77
  interface IImgSpriteProps {
76
78
  atlasIMG: any;
@@ -85,6 +87,7 @@ interface IImgSpriteProps {
85
87
  opacity: number;
86
88
  centered?: boolean;
87
89
  borderRadius?: string;
90
+ tintColor?: string;
88
91
  }
89
92
 
90
93
  interface IContainerProps {
@@ -108,12 +111,30 @@ const ImgSprite = styled.div<IImgSpriteProps>`
108
111
  width: ${props => props.frame.w}px;
109
112
  height: ${props => props.frame.h}px;
110
113
  background-image: url(${props => props.atlasIMG});
111
- background-position: -${props => props.frame.x}px -${props => props.frame.y}px;
114
+ background-position: -${props => props.frame.x}px -${props =>
115
+ props.frame.y}px;
112
116
  transform: scale(${props => props.scale});
113
117
  position: relative;
114
118
  top: ${props => (props.centered ? '0' : '8px')};
115
119
  left: ${props => (props.centered ? '0' : '8px')};
116
- filter: ${props => (props.grayScale ? 'grayscale(100%)' : 'none')};
120
+ ${props =>
121
+ props.tintColor &&
122
+ `
123
+ &::after {
124
+ content: '';
125
+ position: absolute;
126
+ top: 0;
127
+ left: 0;
128
+ width: ${props.frame.w}px;
129
+ height: ${props.frame.h}px;
130
+ background-color: ${props.tintColor};
131
+ mask-image: url(${props.atlasIMG});
132
+ mask-position: -${props.frame.x}px -${props.frame.y}px;
133
+ -webkit-mask-image: url(${props.atlasIMG});
134
+ -webkit-mask-position: -${props.frame.x}px -${props.frame.y}px;
135
+ mix-blend-mode: color;
136
+ ${props.grayScale ? 'filter: grayscale(100%);' : 'none'}
137
+ }
138
+ `}
117
139
  opacity: ${props => props.opacity};
118
- border-radius: ${props => (props.borderRadius ? props.borderRadius : '0')};
119
- `;
140
+ `;
package/src/index.tsx CHANGED
@@ -22,6 +22,7 @@ export * from './components/Input';
22
22
  export * from './components/InternalTabs/InternalTabs';
23
23
  export { ErrorBoundary } from './components/Item/Inventory/ErrorBoundary';
24
24
  export * from './components/Item/Inventory/ItemContainer';
25
+ export * from './components/Item/Inventory/ItemPropertySimpleHandler';
25
26
  export * from './components/Item/Inventory/ItemQuantitySelectorModal';
26
27
  export * from './components/Item/Inventory/ItemSlot';
27
28
  export * from './components/itemSelector/ItemSelector';
@@ -322,6 +322,7 @@ export const items: IItem[] = [
322
322
  createdAt: '2022-06-04T03:18:09.335Z',
323
323
  updatedAt: '2022-06-04T18:16:49.056Z',
324
324
  rarity: ItemRarities.Common,
325
+ tintColor: '#FFD700',
325
326
  },
326
327
  {
327
328
  _id: '392acek4j7c8e80d2fs60404',
@@ -2,8 +2,9 @@ import { UserAccountTypes } from '@rpg-engine/shared';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import React from 'react';
4
4
  import { RPGUIRoot } from '../../../components/RPGUI/RPGUIRoot';
5
+ import customSkinImage from '../../../components/Store/sections/images/custom-skin.png';
5
6
  import { Store } from '../../../components/Store/Store';
6
- import { IStoreItem } from '../../../components/Store/StoreTypes';
7
+ import { IItemPack, IPurchase, IStoreItem } from '../../../components/Store/StoreTypes';
7
8
  import itemsAtlasJSON from '../../../mocks/atlas/items/items.json';
8
9
  import itemsAtlasIMG from '../../../mocks/atlas/items/items.png';
9
10
  import { mockItems } from '../../../mocks/informationCenter.mocks';
@@ -85,15 +86,64 @@ const duplicatedItems: IStoreItem[] = [
85
86
  })),
86
87
  ];
87
88
 
89
+ // Mock packs data
90
+ const mockPacks: IItemPack[] = [
91
+ // Regular Packs
92
+ {
93
+ key: 'starter-pack',
94
+ title: 'Starter Pack',
95
+ description: 'Perfect for beginners! Get essential items to start your adventure.',
96
+ priceUSD: 4.99,
97
+ image: customSkinImage,
98
+ },
99
+ {
100
+ key: 'custom-skin-pack',
101
+ title: 'Custom Skin Pack',
102
+ description: 'Get a unique look with this custom skin pack! Stand out from the crowd.',
103
+ priceUSD: 7.99,
104
+ image: customSkinImage,
105
+ },
106
+
107
+ {
108
+ key: 'ultimate-pack',
109
+ title: '👑 Ultimate Premium Pack',
110
+ description: 'The most exclusive collection of items, effects, and perks. Includes everything from previous tiers plus legendary items!',
111
+ priceUSD: 99.99,
112
+ image: customSkinImage,
113
+ },
114
+ {
115
+ key: 'gold-pack',
116
+ title: '🥇 Gold Premium Pack',
117
+ description: 'The ultimate premium experience with rare items, unique effects, and exclusive content. For true champions!',
118
+ priceUSD: 49.99,
119
+ image: customSkinImage,
120
+ },
121
+ {
122
+ key: 'silver-pack',
123
+ title: '🥈 Silver Premium Pack',
124
+ description: 'Enhanced premium features with more exclusive items and special effects. For dedicated adventurers.',
125
+ priceUSD: 24.99,
126
+ image: customSkinImage,
127
+ },
128
+ {
129
+ key: 'bronze-pack',
130
+ title: '🥉 Bronze Premium Pack',
131
+ description: 'Start your premium journey with exclusive items and basic perks. Perfect for casual players.',
132
+ priceUSD: 14.99,
133
+ image: customSkinImage,
134
+ },
135
+
136
+ ];
137
+
88
138
  // Create the story with the static mock data
89
139
  export const Default: Story = {
90
140
  render: () => (
91
141
  <Store
92
142
  items={duplicatedItems}
93
- userGold={1000}
143
+ packs={mockPacks}
94
144
  userAccountType={UserAccountTypes.Free}
95
- onPurchase={(item: IStoreItem, quantity: number) => {
96
- console.log('Purchased', quantity, 'x', item.name);
145
+ onPurchase={(purchase: IPurchase) => {
146
+ console.log('Purchase details:', purchase);
97
147
  }}
98
148
  atlasJSON={itemsAtlasJSON}
99
149
  atlasIMG={itemsAtlasIMG}