@rpg-engine/long-bow 0.7.70 → 0.7.71

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 (25) hide show
  1. package/dist/components/Item/Inventory/ItemSlot.d.ts +5 -18
  2. package/dist/components/Item/Inventory/ItemSlotTooltips.d.ts +12 -1
  3. package/dist/components/Item/Inventory/context/DraggingContext.d.ts +11 -0
  4. package/dist/hooks/useCursorPosition.d.ts +1 -1
  5. package/dist/long-bow.cjs.development.js +572 -660
  6. package/dist/long-bow.cjs.development.js.map +1 -1
  7. package/dist/long-bow.cjs.production.min.js +1 -1
  8. package/dist/long-bow.cjs.production.min.js.map +1 -1
  9. package/dist/long-bow.esm.js +574 -662
  10. package/dist/long-bow.esm.js.map +1 -1
  11. package/package.json +2 -3
  12. package/src/components/Equipment/EquipmentSet.tsx +29 -61
  13. package/src/components/Item/Inventory/DraggedItem.tsx +2 -2
  14. package/src/components/Item/Inventory/ItemContainer.tsx +44 -68
  15. package/src/components/Item/Inventory/ItemSlot.tsx +447 -239
  16. package/src/components/Item/Inventory/ItemSlotTooltips.tsx +46 -48
  17. package/src/components/Item/Inventory/context/DraggingContext.tsx +26 -0
  18. package/src/hooks/useCursorPosition.ts +20 -29
  19. package/src/stories/UI/containers/ItemContainer.stories.tsx +3 -30
  20. package/dist/components/Item/Inventory/context/ItemSlotDraggingContext.d.ts +0 -26
  21. package/dist/components/Item/Inventory/context/ItemSlotTooltipContext.d.ts +0 -28
  22. package/dist/components/Item/Inventory/hooks/useItemSlotDragAndDrop.d.ts +0 -39
  23. package/src/components/Item/Inventory/context/ItemSlotDraggingContext.tsx +0 -52
  24. package/src/components/Item/Inventory/context/ItemSlotTooltipContext.tsx +0 -95
  25. package/src/components/Item/Inventory/hooks/useItemSlotDragAndDrop.ts +0 -248
@@ -1,15 +1,24 @@
1
1
  import { IEquipmentSet, IItem } from '@rpg-engine/shared';
2
2
  import React from 'react';
3
+ import { IPosition } from '../../../types/eventTypes';
3
4
  import { RelativeListMenu } from '../../RelativeListMenu';
4
5
  import { ItemTooltip } from '../Cards/ItemTooltip';
5
6
  import { MobileItemTooltip } from '../Cards/MobileItemTooltip';
6
- import { useItemSlotTooltip } from './context/ItemSlotTooltipContext';
7
+ import { IContextMenuItem } from './itemContainerHelper';
7
8
 
8
9
  interface IProps {
10
+ isTooltipVisible: boolean;
9
11
  isFocused: boolean;
12
+ isContextMenuVisible: boolean;
10
13
  isContextMenuDisabled: boolean;
11
-
14
+ item: IItem | null;
15
+ isTooltipMobileVisible: boolean;
16
+ contextActions: IContextMenuItem[];
17
+ contextMenuPosition: IPosition;
12
18
  dragScale: number | undefined;
19
+ setIsContextMenuVisible: (visible: boolean) => void;
20
+ setIsTooltipMobileVisible: (visible: boolean) => void;
21
+ setIsTooltipVisible: (visible: boolean) => void;
13
22
  onSelected?: (optionId: string, item: IItem) => void;
14
23
  atlasIMG: any;
15
24
  atlasJSON: any;
@@ -17,48 +26,25 @@ interface IProps {
17
26
  }
18
27
 
19
28
  export const ItemSlotToolTips = ({
29
+ isTooltipVisible,
20
30
  isFocused,
31
+ isContextMenuVisible,
21
32
  isContextMenuDisabled,
22
-
33
+ item,
34
+ contextActions,
35
+ contextMenuPosition,
23
36
  dragScale,
37
+ setIsContextMenuVisible,
38
+ setIsTooltipMobileVisible,
39
+ isTooltipMobileVisible,
24
40
  onSelected,
25
41
  atlasIMG,
26
42
  atlasJSON,
27
43
  equipmentSet,
28
44
  }: IProps): JSX.Element => {
29
- const { itemDetails, updateItemDetails } = useItemSlotTooltip();
30
-
31
- const item = itemDetails.item;
32
-
33
- const handleCloseTooltip = () => {
34
- updateItemDetails({
35
- item,
36
- tooltip: { mobileVisible: false },
37
- });
38
- };
39
-
40
- const handleContextMenuSelect = (optionId: string) => {
41
- updateItemDetails({
42
- item,
43
- contextMenu: { visible: false },
44
- });
45
- if (item) {
46
- onSelected?.(optionId, item);
47
- }
48
- };
49
-
50
- const handleOutsideClick = () => {
51
- updateItemDetails({
52
- item,
53
- contextMenu: { visible: false },
54
- });
55
- };
56
-
57
- // monitor why mobileVisible is not working
58
-
59
45
  return (
60
46
  <>
61
- {itemDetails.tooltip?.visible && item && !isFocused && (
47
+ {isTooltipVisible && item && !isFocused && (
62
48
  <ItemTooltip
63
49
  item={item}
64
50
  atlasIMG={atlasIMG}
@@ -67,29 +53,41 @@ export const ItemSlotToolTips = ({
67
53
  />
68
54
  )}
69
55
 
70
- {itemDetails.tooltip?.mobileVisible && item && (
56
+ {isTooltipMobileVisible && item && (
71
57
  <MobileItemTooltip
72
58
  item={item}
73
59
  atlasIMG={atlasIMG}
74
60
  atlasJSON={atlasJSON}
75
61
  equipmentSet={equipmentSet}
76
- closeTooltip={handleCloseTooltip}
62
+ closeTooltip={() => {
63
+ setIsTooltipMobileVisible(false);
64
+ }}
77
65
  scale={dragScale}
78
- options={itemDetails.contextMenu?.actions || []}
79
- onSelected={handleContextMenuSelect}
66
+ options={contextActions}
67
+ onSelected={(optionId: string) => {
68
+ setIsContextMenuVisible(false);
69
+ if (item) {
70
+ onSelected?.(optionId, item);
71
+ }
72
+ }}
80
73
  />
81
74
  )}
82
75
 
83
- {!isContextMenuDisabled &&
84
- itemDetails.contextMenu?.visible &&
85
- itemDetails.contextMenu.actions && (
86
- <RelativeListMenu
87
- options={itemDetails.contextMenu.actions}
88
- onSelected={handleContextMenuSelect}
89
- onOutsideClick={handleOutsideClick}
90
- pos={itemDetails.contextMenu.position!}
91
- />
92
- )}
76
+ {!isContextMenuDisabled && isContextMenuVisible && contextActions && (
77
+ <RelativeListMenu
78
+ options={contextActions}
79
+ onSelected={(optionId: string) => {
80
+ setIsContextMenuVisible(false);
81
+ if (item) {
82
+ onSelected?.(optionId, item);
83
+ }
84
+ }}
85
+ onOutsideClick={() => {
86
+ setIsContextMenuVisible(false);
87
+ }}
88
+ pos={contextMenuPosition}
89
+ />
90
+ )}
93
91
  </>
94
92
  );
95
93
  };
@@ -0,0 +1,26 @@
1
+ import { IItem } from '@rpg-engine/shared';
2
+ import React, { createContext, useContext, useState } from 'react';
3
+
4
+ const DraggingContext = createContext<{
5
+ item: IItem | null;
6
+ setDraggingItem: React.Dispatch<React.SetStateAction<IItem | null>>;
7
+ }>({
8
+ item: null,
9
+ setDraggingItem: () => {},
10
+ });
11
+
12
+ export const useDragging = () => useContext(DraggingContext);
13
+
14
+ interface IProps {
15
+ children: React.ReactNode;
16
+ }
17
+
18
+ export const DraggingProvider = ({ children }: IProps) => {
19
+ const [item, setDraggingItem] = useState<IItem | null>(null);
20
+
21
+ return (
22
+ <DraggingContext.Provider value={{ item, setDraggingItem }}>
23
+ {children}
24
+ </DraggingContext.Provider>
25
+ );
26
+ };
@@ -6,46 +6,37 @@ interface ICursorPositionProps {
6
6
  scale?: number;
7
7
  }
8
8
 
9
- export const useCursorPosition = ({
10
- scale = 1,
11
- }: ICursorPositionProps): IPosition => {
9
+ export const useCursorPosition = ({ scale = 1 }: ICursorPositionProps): IPosition => {
12
10
  const [position, setPosition] = useState<IPosition>({ x: 0, y: 0 });
13
11
 
14
- const scalePosition = useCallback(
15
- (x: number, y: number): IPosition => {
16
- return {
17
- x: (x - GRID_WIDTH / 2) / scale + GRID_WIDTH / 2,
18
- y: (y - GRID_HEIGHT / 2) / scale + GRID_HEIGHT / 2,
19
- };
20
- },
21
- [scale]
22
- );
12
+ const scalePosition = useCallback((x: number, y: number): IPosition => {
13
+ return {
14
+ x: ((x - GRID_WIDTH / 2) / scale) + GRID_WIDTH / 2,
15
+ y: ((y - GRID_HEIGHT / 2) / scale) + GRID_HEIGHT / 2,
16
+ };
17
+ }, [scale]);
23
18
 
24
- const setFromEvent = useCallback(
25
- (e: MouseEvent | TouchEvent) => {
26
- let x, y;
19
+ const setFromEvent = useCallback((e: MouseEvent | TouchEvent) => {
20
+ let x, y;
27
21
 
28
- if ('touches' in e) {
29
- x = e.touches[0].clientX;
30
- y = e.touches[0].clientY;
31
- } else {
32
- x = e.clientX;
33
- y = e.clientY;
34
- }
22
+ if ('touches' in e) {
23
+ x = e.touches[0].clientX;
24
+ y = e.touches[0].clientY;
25
+ } else {
26
+ x = e.clientX;
27
+ y = e.clientY;
28
+ }
35
29
 
36
- const scaledPosition = scalePosition(x, y);
37
- setPosition(scaledPosition);
38
- },
39
- [scale, scalePosition]
40
- );
30
+ const scaledPosition = scalePosition(x, y);
31
+ setPosition(scaledPosition);
32
+ }, [scale, scalePosition]);
41
33
 
42
34
  const cleanup = useCallback(() => {
43
35
  setPosition({ x: 0, y: 0 });
44
36
  }, []);
45
37
 
46
38
  useEffect(() => {
47
- const handleEvent = (e: Event) =>
48
- setFromEvent(e as MouseEvent | TouchEvent);
39
+ const handleEvent = (e: Event) => setFromEvent(e as MouseEvent | TouchEvent);
49
40
 
50
41
  window.addEventListener('mousemove', handleEvent);
51
42
  window.addEventListener('touchmove', handleEvent);
@@ -1,4 +1,4 @@
1
- import { IItem, ItemContainerType, ItemType } from '@rpg-engine/shared';
1
+ import { IItem, ItemContainerType } from '@rpg-engine/shared';
2
2
  import { Meta, Story } from '@storybook/react';
3
3
  import React, { useState } from 'react';
4
4
  import {
@@ -21,26 +21,10 @@ const meta: Meta = {
21
21
 
22
22
  export default meta;
23
23
 
24
- const onMouseOver = (_event: any, slotIndex: number, item: IItem | null) => {
25
- if (!item) {
26
- console.log(`Free at ${slotIndex}`);
27
- return;
28
- }
29
- console.log(`${item.name} at ${slotIndex}`);
30
- };
31
-
32
24
  const onSelected = (payload: string, item: IItem) => {
33
25
  console.log('onSelected', payload, item);
34
26
  };
35
27
 
36
- const onItemClick = (
37
- item: IItem,
38
- ItemType: ItemType,
39
- itemContainerType: ItemContainerType | null
40
- ) => {
41
- console.log(item, ItemType, itemContainerType, 'was clicked!');
42
- };
43
-
44
28
  // THIS IS ONLY LONG-BOW EXAMPLE FOR DRAG AND DROP
45
29
  let dragItem: IItem | null = null;
46
30
  let dropItem: IItem | null = null;
@@ -69,9 +53,9 @@ const Template: Story<IItemContainerProps & ITemplateProps> = ({
69
53
  <ItemContainer
70
54
  itemContainer={itemContainer}
71
55
  onClose={() => console.log('closing item container')}
72
- onMouseOver={onMouseOver}
56
+ onMouseOver={() => {}}
73
57
  onSelected={onSelected}
74
- onItemClick={onItemClick}
58
+ onItemClick={() => {}}
75
59
  checkIfItemCanBeMoved={() => allowedToDrop}
76
60
  onItemDragEnd={quantity => {
77
61
  // THIS IS ONLY LONG-BOW EXAMPLE FOR DRAG AND DROP
@@ -115,22 +99,11 @@ const Template: Story<IItemContainerProps & ITemplateProps> = ({
115
99
  onItemPlaceDrop={(item, slotIndex) => {
116
100
  // THIS IS ONLY LONG-BOW EXAMPLE FOR DRAG AND DROP
117
101
 
118
- console.log({
119
- item: item?.name,
120
- sI: slotIndex,
121
- dragK: dragItem?.key,
122
- itemK: item?.key,
123
- dragSlot,
124
- slotIndex,
125
- });
126
-
127
102
  if (!item || (dragItem?.key === item?.key && dragSlot !== slotIndex)) {
128
- console.log('allow');
129
103
  allowedToDrop = true;
130
104
  dropSlot = slotIndex;
131
105
  dropItem = item ? item : null;
132
106
  } else {
133
- console.log('not allowing drop');
134
107
  allowedToDrop = false;
135
108
  dropSlot = -1;
136
109
  dropItem = null;
@@ -1,26 +0,0 @@
1
- import { IItem } from '@rpg-engine/shared';
2
- import React from 'react';
3
- export interface IDragState {
4
- isFocused: boolean;
5
- wasDragged: boolean;
6
- position: {
7
- x: number;
8
- y: number;
9
- };
10
- dropPosition: {
11
- x: number;
12
- y: number;
13
- } | null;
14
- }
15
- interface IDraggingContextType {
16
- item: IItem | null;
17
- setDraggingItem: React.Dispatch<React.SetStateAction<IItem | null>>;
18
- dragState: IDragState;
19
- setDragState: React.Dispatch<React.SetStateAction<IDragState>>;
20
- }
21
- interface IProps {
22
- children: React.ReactNode;
23
- }
24
- export declare const ItemSlotDraggingProvider: ({ children }: IProps) => JSX.Element;
25
- export declare const useItemSlotDragging: () => IDraggingContextType;
26
- export {};
@@ -1,28 +0,0 @@
1
- import { IItem } from '@rpg-engine/shared';
2
- import { FC, ReactNode } from 'react';
3
- import { IPosition } from '../../../../types/eventTypes';
4
- import { IContextMenuItem } from '../itemContainerHelper';
5
- interface TooltipState {
6
- visible?: boolean;
7
- mobileVisible?: boolean;
8
- }
9
- interface ContextMenuState {
10
- visible?: boolean;
11
- position?: IPosition;
12
- actions?: IContextMenuItem[];
13
- }
14
- interface ItemDetails {
15
- item?: IItem | null;
16
- tooltip?: TooltipState;
17
- contextMenu?: ContextMenuState;
18
- }
19
- interface ItemSlotTooltipContextProps {
20
- itemDetails: ItemDetails;
21
- updateItemDetails: (updates: Partial<ItemDetails>) => void;
22
- clearItemDetails: () => void;
23
- }
24
- export declare const ItemSlotTooltipProvider: FC<{
25
- children: ReactNode;
26
- }>;
27
- export declare const useItemSlotTooltip: () => ItemSlotTooltipContextProps;
28
- export {};
@@ -1,39 +0,0 @@
1
- /// <reference types="react" />
2
- import { IItem, ItemContainerType, ItemType } from '@rpg-engine/shared';
3
- import { DraggableEventHandler } from 'react-draggable';
4
- interface IUseItemSlotDragAndDrop {
5
- isDepotSystem: boolean;
6
- item: IItem;
7
- onDrop: (item: IItem, dropPosition: {
8
- x: number;
9
- y: number;
10
- }) => void;
11
- onDragEnd?: (quantity?: number) => void;
12
- checkIfItemCanBeMoved?: () => boolean;
13
- checkIfItemShouldDragEnd?: () => boolean;
14
- setItemShortcut?: (item: IItem, index: number) => void;
15
- isSelectingShortcut?: boolean;
16
- onDragStart?: (item: IItem, slotIndex: number, containerType: ItemContainerType) => void;
17
- onPointerDown: (ItemType: ItemType, itemContainerType: ItemContainerType | null, item: IItem) => void;
18
- containerType: ItemContainerType;
19
- slotIndex: number;
20
- openQuantitySelector: (quantity: number, onSuccess: (quantity?: number) => void) => void;
21
- isContextMenuDisabled: boolean;
22
- }
23
- export declare const useItemSlotDragAndDrop: ({ isDepotSystem, item, onDrop, onDragEnd, checkIfItemCanBeMoved, checkIfItemShouldDragEnd, setItemShortcut, isSelectingShortcut, onDragStart, onPointerDown, containerType, slotIndex, openQuantitySelector, isContextMenuDisabled, }: IUseItemSlotDragAndDrop) => {
24
- dragContainer: import("react").RefObject<HTMLDivElement>;
25
- dragState: import("../context/ItemSlotDraggingContext").IDragState;
26
- draggingItem: IItem | null;
27
- setDraggingItem: import("react").Dispatch<import("react").SetStateAction<IItem | null>>;
28
- getContainerBounds: () => {
29
- left: number;
30
- top: number;
31
- right: number;
32
- bottom: number;
33
- };
34
- onDraggableStart: DraggableEventHandler;
35
- onDraggableProgress: DraggableEventHandler;
36
- onDraggableStop: DraggableEventHandler;
37
- resetItem: () => void;
38
- };
39
- export {};
@@ -1,52 +0,0 @@
1
- import { IItem } from '@rpg-engine/shared';
2
- import React, { createContext, useContext, useState } from 'react';
3
-
4
- export interface IDragState {
5
- isFocused: boolean;
6
- wasDragged: boolean;
7
- position: { x: number; y: number };
8
- dropPosition: { x: number; y: number } | null;
9
- }
10
-
11
- interface IDraggingContextType {
12
- item: IItem | null;
13
- setDraggingItem: React.Dispatch<React.SetStateAction<IItem | null>>;
14
- dragState: IDragState;
15
- setDragState: React.Dispatch<React.SetStateAction<IDragState>>;
16
- }
17
-
18
- const ItemSlotDraggingContext = createContext<IDraggingContextType>({
19
- item: null,
20
- setDraggingItem: () => {},
21
- dragState: {
22
- isFocused: false,
23
- wasDragged: false,
24
- position: { x: 0, y: 0 },
25
- dropPosition: null,
26
- },
27
- setDragState: () => {},
28
- });
29
-
30
- interface IProps {
31
- children: React.ReactNode;
32
- }
33
-
34
- export const ItemSlotDraggingProvider = ({ children }: IProps) => {
35
- const [item, setDraggingItem] = useState<IItem | null>(null);
36
- const [dragState, setDragState] = useState<IDragState>({
37
- isFocused: false,
38
- wasDragged: false,
39
- position: { x: 0, y: 0 },
40
- dropPosition: null,
41
- });
42
-
43
- return (
44
- <ItemSlotDraggingContext.Provider
45
- value={{ item, setDraggingItem, dragState, setDragState }}
46
- >
47
- {children}
48
- </ItemSlotDraggingContext.Provider>
49
- );
50
- };
51
-
52
- export const useItemSlotDragging = () => useContext(ItemSlotDraggingContext);
@@ -1,95 +0,0 @@
1
- import { IItem } from '@rpg-engine/shared';
2
- import React, {
3
- createContext,
4
- FC,
5
- ReactNode,
6
- useCallback,
7
- useContext,
8
- useEffect,
9
- useState,
10
- } from 'react';
11
- import { IPosition } from '../../../../types/eventTypes';
12
- import { IContextMenuItem } from '../itemContainerHelper';
13
-
14
- // Define smaller, focused interfaces for better readability
15
- interface TooltipState {
16
- visible?: boolean;
17
- mobileVisible?: boolean;
18
- }
19
-
20
- interface ContextMenuState {
21
- visible?: boolean;
22
- position?: IPosition;
23
- actions?: IContextMenuItem[];
24
- }
25
-
26
- interface ItemDetails {
27
- item?: IItem | null;
28
- tooltip?: TooltipState;
29
- contextMenu?: ContextMenuState;
30
- }
31
-
32
- interface ItemSlotTooltipContextProps {
33
- itemDetails: ItemDetails;
34
- updateItemDetails: (updates: Partial<ItemDetails>) => void;
35
- clearItemDetails: () => void;
36
- }
37
-
38
- // Set default state with clearly defined initial values
39
- const defaultItemDetails: ItemDetails = {
40
- item: null,
41
- tooltip: { visible: false, mobileVisible: false },
42
- contextMenu: { visible: false, position: { x: 0, y: 0 }, actions: [] },
43
- };
44
-
45
- // Create context with default values
46
- const ItemSlotTooltipContext = createContext<ItemSlotTooltipContextProps>({
47
- itemDetails: defaultItemDetails,
48
- updateItemDetails: () => {},
49
- clearItemDetails: () => {},
50
- });
51
-
52
- // Provider component
53
- export const ItemSlotTooltipProvider: FC<{ children: ReactNode }> = ({
54
- children,
55
- }) => {
56
- const [itemDetails, setItemDetails] = useState<ItemDetails>(
57
- defaultItemDetails
58
- );
59
-
60
- useEffect(() => {
61
- console.log('itemDetails', itemDetails);
62
- }, [itemDetails]);
63
-
64
- // Memoize the update function to optimize performance
65
- const updateItemDetails = useCallback((updates: Partial<ItemDetails>) => {
66
- setItemDetails(prev => ({
67
- ...prev,
68
- ...updates,
69
- tooltip: { ...prev.tooltip, ...updates.tooltip },
70
- contextMenu: {
71
- ...prev.contextMenu,
72
- ...updates.contextMenu,
73
- // Ensure actions are properly merged or overridden
74
- actions: updates.contextMenu?.actions ?? prev.contextMenu?.actions,
75
- },
76
- }));
77
- }, []);
78
-
79
- const clearItemDetails = useCallback(() => {
80
- setItemDetails(defaultItemDetails);
81
- }, []);
82
-
83
- return (
84
- <ItemSlotTooltipContext.Provider
85
- value={{ itemDetails, updateItemDetails, clearItemDetails }}
86
- >
87
- {children}
88
- </ItemSlotTooltipContext.Provider>
89
- );
90
- };
91
-
92
- // Custom hook for consuming the context
93
- export const useItemSlotTooltip = (): ItemSlotTooltipContextProps => {
94
- return useContext(ItemSlotTooltipContext);
95
- };