@rpg-engine/long-bow 0.1.91 → 0.1.92

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 (88) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +181 -181
  3. package/dist/components/Item/Inventory/itemContainerHelper.d.ts +2 -2
  4. package/dist/long-bow.cjs.development.js +49 -2
  5. package/dist/long-bow.cjs.development.js.map +1 -1
  6. package/dist/long-bow.cjs.production.min.js +1 -1
  7. package/dist/long-bow.cjs.production.min.js.map +1 -1
  8. package/dist/long-bow.esm.js +49 -2
  9. package/dist/long-bow.esm.js.map +1 -1
  10. package/package.json +98 -98
  11. package/src/components/Abstractions/SlotsContainer.tsx +42 -42
  12. package/src/components/Button.tsx +30 -30
  13. package/src/components/Chat/Chat.tsx +193 -193
  14. package/src/components/CheckButton.tsx +65 -65
  15. package/src/components/DraggableContainer.tsx +150 -150
  16. package/src/components/Dropdown.tsx +57 -57
  17. package/src/components/Equipment/EquipmentSet.tsx +134 -134
  18. package/src/components/Input.tsx +11 -11
  19. package/src/components/Item/Cards/ItemTooltip.tsx +32 -32
  20. package/src/components/Item/Inventory/ItemContainer.tsx +65 -65
  21. package/src/components/Item/Inventory/ItemContainerTypes.ts +4 -4
  22. package/src/components/Item/Inventory/ItemSlot.tsx +199 -199
  23. package/src/components/Item/Inventory/itemContainerHelper.ts +94 -81
  24. package/src/components/ListMenu.tsx +65 -65
  25. package/src/components/Multitab/Tab.tsx +57 -57
  26. package/src/components/Multitab/TabBody.tsx +13 -13
  27. package/src/components/Multitab/TabsContainer.tsx +97 -97
  28. package/src/components/NPCDialog/NPCDialog.tsx +145 -145
  29. package/src/components/NPCDialog/NPCDialogText.tsx +53 -53
  30. package/src/components/NPCDialog/QuestionDialog/QuestionDialog.tsx +239 -239
  31. package/src/components/ProgressBar.tsx +91 -91
  32. package/src/components/PropertySelect/PropertySelect.tsx +101 -101
  33. package/src/components/PropertySelect/img/ui-arrows/arrow01-left-clicked.png +0 -0
  34. package/src/components/PropertySelect/img/ui-arrows/arrow01-left.png +0 -0
  35. package/src/components/PropertySelect/img/ui-arrows/arrow01-right-clicked.png +0 -0
  36. package/src/components/PropertySelect/img/ui-arrows/arrow01-right.png +0 -0
  37. package/src/components/PropertySelect/img/ui-arrows/arrow02-left-clicked.png +0 -0
  38. package/src/components/PropertySelect/img/ui-arrows/arrow02-left.png +0 -0
  39. package/src/components/PropertySelect/img/ui-arrows/arrow02-right-clicked.png +0 -0
  40. package/src/components/PropertySelect/img/ui-arrows/arrow02-right.png +0 -0
  41. package/src/components/QuestInfo/QuestInfo.tsx +143 -143
  42. package/src/components/RPGUIContainer.tsx +47 -47
  43. package/src/components/RPGUIRoot.tsx +14 -14
  44. package/src/components/RadioButton.tsx +53 -53
  45. package/src/components/RangeSlider.tsx +68 -68
  46. package/src/components/RelativeListMenu.tsx +83 -83
  47. package/src/components/ScrollList.tsx +77 -77
  48. package/src/components/SimpleProgressBar.tsx +62 -62
  49. package/src/components/SkillProgressBar.tsx +123 -123
  50. package/src/components/SkillsContainer.tsx +196 -196
  51. package/src/components/TextArea.tsx +11 -11
  52. package/src/components/Truncate.tsx +25 -25
  53. package/src/components/shared/Column.tsx +16 -16
  54. package/src/components/shared/SpriteFromAtlas.tsx +99 -99
  55. package/src/components/typography/DynamicText.tsx +49 -49
  56. package/src/constants/uiColors.ts +10 -10
  57. package/src/hooks/useEventListener.ts +21 -21
  58. package/src/hooks/useOutsideAlerter.ts +25 -25
  59. package/src/index.tsx +25 -25
  60. package/src/libs/StringHelpers.ts +3 -3
  61. package/src/mocks/atlas/icons/icons.json +735 -735
  62. package/src/mocks/atlas/items/items.json +5215 -5215
  63. package/src/mocks/equipmentSet.mocks.ts +347 -347
  64. package/src/mocks/itemContainer.mocks.ts +249 -249
  65. package/src/mocks/skills.mocks.ts +122 -122
  66. package/src/stories/Button.stories.tsx +36 -36
  67. package/src/stories/Chat.stories.tsx +170 -170
  68. package/src/stories/CheckButton.stories.tsx +48 -48
  69. package/src/stories/DraggableContainer.stories.tsx +28 -28
  70. package/src/stories/Dropdown.stories.tsx +46 -46
  71. package/src/stories/EquipmentSet.stories.tsx +50 -50
  72. package/src/stories/ItemContainer.stories.tsx +50 -50
  73. package/src/stories/ListMenu.stories.tsx +56 -56
  74. package/src/stories/Multitab.stories.tsx +51 -51
  75. package/src/stories/NPCDialog.stories.tsx +130 -130
  76. package/src/stories/ProgressBar.stories.tsx +23 -23
  77. package/src/stories/PropertySelect.stories.tsx +41 -41
  78. package/src/stories/QuestInfo.stories.tsx +76 -76
  79. package/src/stories/RPGUIContainers.stories.tsx +42 -42
  80. package/src/stories/RadioButton.stories.tsx +49 -49
  81. package/src/stories/RangeSlider.stories.tsx +60 -60
  82. package/src/stories/ScrollList.stories.tsx +85 -85
  83. package/src/stories/SimpleProgressBar.stories.tsx +22 -22
  84. package/src/stories/SkillProgressBar.stories.tsx +30 -30
  85. package/src/stories/SkillsContainer.stories.tsx +31 -31
  86. package/src/stories/Text.stories.tsx +42 -42
  87. package/src/types/eventTypes.ts +4 -4
  88. package/src/types/index.d.ts +2 -2
@@ -1,11 +1,11 @@
1
- import React from 'react';
2
-
3
- export interface IInputProps
4
- extends React.DetailedHTMLProps<
5
- React.InputHTMLAttributes<HTMLInputElement>,
6
- HTMLInputElement
7
- > {}
8
-
9
- export const Input: React.FC<IInputProps> = ({ ...props }) => {
10
- return <input {...props} />;
11
- };
1
+ import React from 'react';
2
+
3
+ export interface IInputProps
4
+ extends React.DetailedHTMLProps<
5
+ React.InputHTMLAttributes<HTMLInputElement>,
6
+ HTMLInputElement
7
+ > {}
8
+
9
+ export const Input: React.FC<IInputProps> = ({ ...props }) => {
10
+ return <input {...props} />;
11
+ };
@@ -1,32 +1,32 @@
1
- import React from 'react';
2
- import styled from 'styled-components';
3
-
4
- interface IProps {
5
- label: string;
6
- }
7
-
8
- export const ItemTooltip: React.FC<IProps> = ({ label }) => {
9
- return (
10
- <Container>
11
- <div>{label}</div>
12
- </Container>
13
- );
14
- };
15
-
16
- const Container = styled.div`
17
- z-index: 2;
18
- position: absolute;
19
- top: 1rem;
20
- left: 4rem;
21
-
22
- font-size: 0.5rem;
23
- color: white;
24
- background-color: black;
25
- border-radius: 5px;
26
- padding: 0.5rem;
27
- min-width: 20px;
28
- width: 100%;
29
- text-align: center;
30
-
31
- opacity: 0.75;
32
- `;
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ interface IProps {
5
+ label: string;
6
+ }
7
+
8
+ export const ItemTooltip: React.FC<IProps> = ({ label }) => {
9
+ return (
10
+ <Container>
11
+ <div>{label}</div>
12
+ </Container>
13
+ );
14
+ };
15
+
16
+ const Container = styled.div`
17
+ z-index: 2;
18
+ position: absolute;
19
+ top: 1rem;
20
+ left: 4rem;
21
+
22
+ font-size: 0.5rem;
23
+ color: white;
24
+ background-color: black;
25
+ border-radius: 5px;
26
+ padding: 0.5rem;
27
+ min-width: 20px;
28
+ width: 100%;
29
+ text-align: center;
30
+
31
+ opacity: 0.75;
32
+ `;
@@ -1,65 +1,65 @@
1
- import { IItem, IItemContainer } from '@rpg-engine/shared';
2
- import React from 'react';
3
- import styled from 'styled-components';
4
- import { SlotsContainer } from '../../Abstractions/SlotsContainer';
5
- import { SlotContainerType } from './ItemContainerTypes';
6
- import { ItemSlot } from './ItemSlot';
7
-
8
- export interface IItemContainerProps {
9
- itemContainer: IItemContainer;
10
- onClose?: () => void;
11
- onItemClick?: (
12
- item: IItem,
13
- slotContainerType: SlotContainerType | null
14
- ) => void;
15
- onMouseOver?: (e: any, slotIndex: number, item: IItem | null) => void;
16
- onSelected?: (optionId: string) => void;
17
- }
18
-
19
- export const ItemContainer: React.FC<IItemContainerProps> = ({
20
- itemContainer,
21
- onClose,
22
- onMouseOver,
23
- onSelected,
24
- onItemClick,
25
- }) => {
26
- const onRenderSlots = () => {
27
- const slots = [];
28
-
29
- for (let i = 0; i < itemContainer.slotQty; i++) {
30
- slots.push(
31
- <ItemSlot
32
- key={i}
33
- slotIndex={i}
34
- item={itemContainer.slots?.[i] || null}
35
- slotContainerType={SlotContainerType.INVENTORY}
36
- onMouseOver={(event, slotIndex, item) => {
37
- if (onMouseOver) onMouseOver(event, slotIndex, item);
38
- }}
39
- onClick={(item, slotContainerType) => {
40
- if (onItemClick) onItemClick(item, slotContainerType);
41
- }}
42
- onSelected={(optionId: string) => {
43
- if (onSelected) onSelected(optionId);
44
- }}
45
- />
46
- );
47
- }
48
- return slots;
49
- };
50
-
51
- return (
52
- <SlotsContainer title={itemContainer.name || 'Container'} onClose={onClose}>
53
- <ItemsContainer className="item-container-body">
54
- {onRenderSlots()}
55
- </ItemsContainer>
56
- </SlotsContainer>
57
- );
58
- };
59
-
60
- const ItemsContainer = styled.div`
61
- max-width: 280px;
62
- display: flex;
63
- justify-content: center;
64
- flex-wrap: wrap;
65
- `;
1
+ import { IItem, IItemContainer } from '@rpg-engine/shared';
2
+ import React from 'react';
3
+ import styled from 'styled-components';
4
+ import { SlotsContainer } from '../../Abstractions/SlotsContainer';
5
+ import { SlotContainerType } from './ItemContainerTypes';
6
+ import { ItemSlot } from './ItemSlot';
7
+
8
+ export interface IItemContainerProps {
9
+ itemContainer: IItemContainer;
10
+ onClose?: () => void;
11
+ onItemClick?: (
12
+ item: IItem,
13
+ slotContainerType: SlotContainerType | null
14
+ ) => void;
15
+ onMouseOver?: (e: any, slotIndex: number, item: IItem | null) => void;
16
+ onSelected?: (optionId: string) => void;
17
+ }
18
+
19
+ export const ItemContainer: React.FC<IItemContainerProps> = ({
20
+ itemContainer,
21
+ onClose,
22
+ onMouseOver,
23
+ onSelected,
24
+ onItemClick,
25
+ }) => {
26
+ const onRenderSlots = () => {
27
+ const slots = [];
28
+
29
+ for (let i = 0; i < itemContainer.slotQty; i++) {
30
+ slots.push(
31
+ <ItemSlot
32
+ key={i}
33
+ slotIndex={i}
34
+ item={itemContainer.slots?.[i] || null}
35
+ slotContainerType={SlotContainerType.INVENTORY}
36
+ onMouseOver={(event, slotIndex, item) => {
37
+ if (onMouseOver) onMouseOver(event, slotIndex, item);
38
+ }}
39
+ onClick={(item, slotContainerType) => {
40
+ if (onItemClick) onItemClick(item, slotContainerType);
41
+ }}
42
+ onSelected={(optionId: string) => {
43
+ if (onSelected) onSelected(optionId);
44
+ }}
45
+ />
46
+ );
47
+ }
48
+ return slots;
49
+ };
50
+
51
+ return (
52
+ <SlotsContainer title={itemContainer.name || 'Container'} onClose={onClose}>
53
+ <ItemsContainer className="item-container-body">
54
+ {onRenderSlots()}
55
+ </ItemsContainer>
56
+ </SlotsContainer>
57
+ );
58
+ };
59
+
60
+ const ItemsContainer = styled.div`
61
+ max-width: 280px;
62
+ display: flex;
63
+ justify-content: center;
64
+ flex-wrap: wrap;
65
+ `;
@@ -1,4 +1,4 @@
1
- export enum SlotContainerType {
2
- INVENTORY = 'Inventory',
3
- EQUIPMENT_SET = 'EquipmentSet',
4
- }
1
+ export enum SlotContainerType {
2
+ INVENTORY = 'Inventory',
3
+ EQUIPMENT_SET = 'EquipmentSet',
4
+ }
@@ -1,199 +1,199 @@
1
- import { IItem, IItemContainer, ItemSlotType } from '@rpg-engine/shared';
2
-
3
- import { observer } from 'mobx-react-lite';
4
- import React, { useEffect, useState } from 'react';
5
- import styled from 'styled-components';
6
- import atlasJSON from '../../../mocks/atlas/items/items.json';
7
- import atlasIMG from '../../../mocks/atlas/items/items.png';
8
- import { RelativeListMenu } from '../../RelativeListMenu';
9
- import { SpriteFromAtlas } from '../../shared/SpriteFromAtlas';
10
- import { ItemTooltip } from '../Cards/ItemTooltip';
11
- import {
12
- handleEquipmentContextMenuList,
13
- IContextMenuItem,
14
- } from './itemContainerHelper';
15
- import { SlotContainerType } from './ItemContainerTypes';
16
-
17
- const EquipmentSlotSpriteByType: any = {
18
- Neck: 'accessories/corruption-necklace.png',
19
- LeftHand: 'swords/broad-sword.png',
20
- Ring: 'rings/iron-ring.png',
21
- Head: 'helmets/viking-helmet.png',
22
- Torso: 'armors/iron-armor.png',
23
- Legs: 'legs/studded-legs.png',
24
- Feet: 'boots/iron-boots.png',
25
- Inventory: 'containers/bag.png',
26
- RightHand: 'shields/plate-shield.png',
27
- Accessory: 'gloves/plate-gloves.png',
28
- };
29
-
30
- interface IProps {
31
- slotIndex: number;
32
- item: IItem | null;
33
- itemContainer?: IItemContainer | null;
34
- slotContainerType: SlotContainerType | null;
35
- slotSpriteMask?: ItemSlotType | null;
36
- onSelected: (payload: any) => void;
37
- onMouseOver: (
38
- event: any,
39
- slotIndex: number,
40
- item: IItem | null,
41
- x: number,
42
- y: number
43
- ) => void;
44
- onMouseOut?: () => void;
45
- onClick: (item: IItem, slotContainerType: SlotContainerType | null) => void;
46
- }
47
-
48
- export const ItemSlot: React.FC<IProps> = observer(
49
- ({
50
- slotIndex,
51
- item,
52
- slotContainerType,
53
- slotSpriteMask,
54
- onMouseOver,
55
- onMouseOut,
56
- onClick,
57
- onSelected,
58
- }) => {
59
- const [isTooltipVisible, setTooltipVisible] = useState(false);
60
-
61
- const [isContextMenuVisible, setIsContextMenuVisible] = useState(false);
62
-
63
- const [contextActions, setContextActions] = useState<IContextMenuItem[]>(
64
- []
65
- );
66
-
67
- useEffect(() => {
68
- if (item) {
69
- setContextActions(handleEquipmentContextMenuList(item.type));
70
- }
71
- }, [item]);
72
-
73
- const getLeftPositionValue = (quantity: number) => {
74
- if (quantity > 0 && quantity < 10) return '2.5rem';
75
- else if (quantity > 9 && quantity < 100) return '2.0rem';
76
- else if (quantity > 99) return '1rem';
77
- return '2.5rem';
78
- };
79
-
80
- const renderItem = (itemToRender: IItem | null) => {
81
- const element = [];
82
- if (itemToRender?.texturePath) {
83
- element.push(
84
- <SpriteFromAtlas
85
- key={itemToRender._id}
86
- atlasIMG={atlasIMG}
87
- atlasJSON={atlasJSON}
88
- spriteKey={itemToRender.texturePath}
89
- imgScale={3}
90
- />
91
- );
92
- }
93
- if (itemToRender?.isStackable && itemToRender?.stackQty) {
94
- element.push(
95
- <ItemQty
96
- left={getLeftPositionValue(itemToRender.stackQty)}
97
- key={`qty-${itemToRender._id}`}
98
- >
99
- {' '}
100
- {itemToRender.stackQty}{' '}
101
- </ItemQty>
102
- );
103
- }
104
- return element;
105
- };
106
-
107
- const renderEquipment = (itemToRender: IItem | null) => {
108
- if (
109
- itemToRender?.texturePath &&
110
- itemToRender.allowedEquipSlotType?.includes(slotSpriteMask!)
111
- ) {
112
- return (
113
- <SpriteFromAtlas
114
- key={itemToRender._id}
115
- atlasIMG={atlasIMG}
116
- atlasJSON={atlasJSON}
117
- spriteKey={itemToRender.texturePath}
118
- imgScale={3}
119
- />
120
- );
121
- } else {
122
- return (
123
- <SpriteFromAtlas
124
- atlasIMG={atlasIMG}
125
- atlasJSON={atlasJSON}
126
- spriteKey={EquipmentSlotSpriteByType[slotSpriteMask!]}
127
- imgScale={3}
128
- grayScale={true}
129
- opacity={0.4}
130
- />
131
- );
132
- }
133
- };
134
-
135
- const onRenderSlot = (itemToRender: IItem | null) => {
136
- if (slotContainerType === SlotContainerType.EQUIPMENT_SET)
137
- return renderEquipment(itemToRender);
138
- return renderItem(itemToRender);
139
- };
140
-
141
- return (
142
- <Container
143
- className="rpgui-icon empty-slot"
144
- onMouseOver={event =>
145
- onMouseOver(event, slotIndex, item, event.clientX, event.clientY)
146
- }
147
- onMouseOut={() => {
148
- if (onMouseOut) onMouseOut();
149
- }}
150
- onMouseEnter={() => setTooltipVisible(true)}
151
- onMouseLeave={() => setTooltipVisible(false)}
152
- onClick={() => {
153
- setTooltipVisible(false);
154
-
155
- if (item) {
156
- setIsContextMenuVisible(!isContextMenuVisible);
157
- onClick(item, slotContainerType);
158
- }
159
- }}
160
- >
161
- {isContextMenuVisible && contextActions && (
162
- <RelativeListMenu
163
- options={contextActions}
164
- onSelected={(optionId: string) => {
165
- setIsContextMenuVisible(false);
166
- onSelected(optionId);
167
- }}
168
- onOutsideClick={() => {
169
- setIsContextMenuVisible(false);
170
- }}
171
- />
172
- )}
173
-
174
- {isTooltipVisible && item && <ItemTooltip label={item.name} />}
175
-
176
- {onRenderSlot(item)}
177
- </Container>
178
- );
179
- }
180
- );
181
-
182
- const Container = styled.div`
183
- margin: 0.1rem;
184
- .sprite-from-atlas-img {
185
- position: relative;
186
- top: 1.5rem;
187
- left: 1.5rem;
188
- }
189
- position: relative;
190
- `;
191
-
192
- interface IItemQtyProps {
193
- left: string;
194
- }
195
- const ItemQty = styled.span<IItemQtyProps>`
196
- position: relative;
197
- top: 1.5rem;
198
- left: ${props => props.left};
199
- `;
1
+ import { IItem, IItemContainer, ItemSlotType } from '@rpg-engine/shared';
2
+
3
+ import { observer } from 'mobx-react-lite';
4
+ import React, { useEffect, useState } from 'react';
5
+ import styled from 'styled-components';
6
+ import atlasJSON from '../../../mocks/atlas/items/items.json';
7
+ import atlasIMG from '../../../mocks/atlas/items/items.png';
8
+ import { RelativeListMenu } from '../../RelativeListMenu';
9
+ import { SpriteFromAtlas } from '../../shared/SpriteFromAtlas';
10
+ import { ItemTooltip } from '../Cards/ItemTooltip';
11
+ import {
12
+ handleContextMenuList,
13
+ IContextMenuItem,
14
+ } from './itemContainerHelper';
15
+ import { SlotContainerType } from './ItemContainerTypes';
16
+
17
+ const EquipmentSlotSpriteByType: any = {
18
+ Neck: 'accessories/corruption-necklace.png',
19
+ LeftHand: 'swords/broad-sword.png',
20
+ Ring: 'rings/iron-ring.png',
21
+ Head: 'helmets/viking-helmet.png',
22
+ Torso: 'armors/iron-armor.png',
23
+ Legs: 'legs/studded-legs.png',
24
+ Feet: 'boots/iron-boots.png',
25
+ Inventory: 'containers/bag.png',
26
+ RightHand: 'shields/plate-shield.png',
27
+ Accessory: 'gloves/plate-gloves.png',
28
+ };
29
+
30
+ interface IProps {
31
+ slotIndex: number;
32
+ item: IItem | null;
33
+ itemContainer?: IItemContainer | null;
34
+ slotContainerType: SlotContainerType | null;
35
+ slotSpriteMask?: ItemSlotType | null;
36
+ onSelected: (payload: any) => void;
37
+ onMouseOver: (
38
+ event: any,
39
+ slotIndex: number,
40
+ item: IItem | null,
41
+ x: number,
42
+ y: number
43
+ ) => void;
44
+ onMouseOut?: () => void;
45
+ onClick: (item: IItem, slotContainerType: SlotContainerType | null) => void;
46
+ }
47
+
48
+ export const ItemSlot: React.FC<IProps> = observer(
49
+ ({
50
+ slotIndex,
51
+ item,
52
+ slotContainerType,
53
+ slotSpriteMask,
54
+ onMouseOver,
55
+ onMouseOut,
56
+ onClick,
57
+ onSelected,
58
+ }) => {
59
+ const [isTooltipVisible, setTooltipVisible] = useState(false);
60
+
61
+ const [isContextMenuVisible, setIsContextMenuVisible] = useState(false);
62
+
63
+ const [contextActions, setContextActions] = useState<IContextMenuItem[]>(
64
+ []
65
+ );
66
+
67
+ useEffect(() => {
68
+ if (item) {
69
+ setContextActions(handleContextMenuList(item.type, slotContainerType) );
70
+ }
71
+ }, [item]);
72
+
73
+ const getLeftPositionValue = (quantity: number) => {
74
+ if (quantity > 0 && quantity < 10) return '2.5rem';
75
+ else if (quantity > 9 && quantity < 100) return '2.0rem';
76
+ else if (quantity > 99) return '1rem';
77
+ return '2.5rem';
78
+ };
79
+
80
+ const renderItem = (itemToRender: IItem | null) => {
81
+ const element = [];
82
+ if (itemToRender?.texturePath) {
83
+ element.push(
84
+ <SpriteFromAtlas
85
+ key={itemToRender._id}
86
+ atlasIMG={atlasIMG}
87
+ atlasJSON={atlasJSON}
88
+ spriteKey={itemToRender.texturePath}
89
+ imgScale={3}
90
+ />
91
+ );
92
+ }
93
+ if (itemToRender?.isStackable && itemToRender?.stackQty) {
94
+ element.push(
95
+ <ItemQty
96
+ left={getLeftPositionValue(itemToRender.stackQty)}
97
+ key={`qty-${itemToRender._id}`}
98
+ >
99
+ {' '}
100
+ {itemToRender.stackQty}{' '}
101
+ </ItemQty>
102
+ );
103
+ }
104
+ return element;
105
+ };
106
+
107
+ const renderEquipment = (itemToRender: IItem | null) => {
108
+ if (
109
+ itemToRender?.texturePath &&
110
+ itemToRender.allowedEquipSlotType?.includes(slotSpriteMask!)
111
+ ) {
112
+ return (
113
+ <SpriteFromAtlas
114
+ key={itemToRender._id}
115
+ atlasIMG={atlasIMG}
116
+ atlasJSON={atlasJSON}
117
+ spriteKey={itemToRender.texturePath}
118
+ imgScale={3}
119
+ />
120
+ );
121
+ } else {
122
+ return (
123
+ <SpriteFromAtlas
124
+ atlasIMG={atlasIMG}
125
+ atlasJSON={atlasJSON}
126
+ spriteKey={EquipmentSlotSpriteByType[slotSpriteMask!]}
127
+ imgScale={3}
128
+ grayScale={true}
129
+ opacity={0.4}
130
+ />
131
+ );
132
+ }
133
+ };
134
+
135
+ const onRenderSlot = (itemToRender: IItem | null) => {
136
+ if (slotContainerType === SlotContainerType.EQUIPMENT_SET)
137
+ return renderEquipment(itemToRender);
138
+ return renderItem(itemToRender);
139
+ };
140
+
141
+ return (
142
+ <Container
143
+ className="rpgui-icon empty-slot"
144
+ onMouseOver={event =>
145
+ onMouseOver(event, slotIndex, item, event.clientX, event.clientY)
146
+ }
147
+ onMouseOut={() => {
148
+ if (onMouseOut) onMouseOut();
149
+ }}
150
+ onMouseEnter={() => setTooltipVisible(true)}
151
+ onMouseLeave={() => setTooltipVisible(false)}
152
+ onClick={() => {
153
+ setTooltipVisible(false);
154
+
155
+ if (item) {
156
+ setIsContextMenuVisible(!isContextMenuVisible);
157
+ onClick(item, slotContainerType);
158
+ }
159
+ }}
160
+ >
161
+ {isContextMenuVisible && contextActions && (
162
+ <RelativeListMenu
163
+ options={contextActions}
164
+ onSelected={(optionId: string) => {
165
+ setIsContextMenuVisible(false);
166
+ onSelected(optionId);
167
+ }}
168
+ onOutsideClick={() => {
169
+ setIsContextMenuVisible(false);
170
+ }}
171
+ />
172
+ )}
173
+
174
+ {isTooltipVisible && item && <ItemTooltip label={item.name} />}
175
+
176
+ {onRenderSlot(item)}
177
+ </Container>
178
+ );
179
+ }
180
+ );
181
+
182
+ const Container = styled.div`
183
+ margin: 0.1rem;
184
+ .sprite-from-atlas-img {
185
+ position: relative;
186
+ top: 1.5rem;
187
+ left: 1.5rem;
188
+ }
189
+ position: relative;
190
+ `;
191
+
192
+ interface IItemQtyProps {
193
+ left: string;
194
+ }
195
+ const ItemQty = styled.span<IItemQtyProps>`
196
+ position: relative;
197
+ top: 1.5rem;
198
+ left: ${props => props.left};
199
+ `;