@rpg-engine/long-bow 0.3.44 → 0.3.45

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 (103) hide show
  1. package/dist/components/Abstractions/SlotsContainer.d.ts +1 -0
  2. package/dist/components/Button.d.ts +3 -2
  3. package/dist/components/Chat/Chat.d.ts +12 -2
  4. package/dist/components/Chatdeprecated/ChatDeprecated.d.ts +13 -0
  5. package/dist/components/CheckButton.d.ts +1 -2
  6. package/dist/components/CircularController/CircularController.d.ts +10 -0
  7. package/dist/components/CraftBook/CraftBook.d.ts +15 -0
  8. package/dist/components/CraftBook/MockItems.d.ts +2 -0
  9. package/dist/components/DraggableContainer.d.ts +1 -0
  10. package/dist/components/DropdownSelectorContainer.d.ts +13 -0
  11. package/dist/components/Equipment/EquipmentSet.d.ts +8 -0
  12. package/dist/components/Input.d.ts +1 -0
  13. package/dist/components/Item/Inventory/ItemContainer.d.ts +12 -0
  14. package/dist/components/Item/Inventory/ItemQuantitySelector.d.ts +7 -0
  15. package/dist/components/Item/Inventory/ItemSlot.d.ts +9 -0
  16. package/dist/components/NPCDialog/NPCDialogText.d.ts +4 -2
  17. package/dist/components/RadioInput/RadioButton.d.ts +8 -0
  18. package/dist/components/RadioInput/RadioInput.d.ts +13 -0
  19. package/dist/components/RadioInput/instruments.d.ts +4 -0
  20. package/dist/components/RangeSlider.d.ts +1 -0
  21. package/dist/components/Spellbook/QuickSpells.d.ts +10 -0
  22. package/dist/components/Spellbook/Spell.d.ts +11 -0
  23. package/dist/components/Spellbook/Spellbook.d.ts +15 -0
  24. package/dist/components/Spellbook/SpellbookShortcuts.d.ts +10 -0
  25. package/dist/components/Spellbook/constants.d.ts +3 -0
  26. package/dist/components/Spellbook/mockSpells.d.ts +2 -0
  27. package/dist/components/itemSelector/ItemSelector.d.ts +14 -0
  28. package/dist/constants/uiDevices.d.ts +1 -0
  29. package/dist/index.d.ts +8 -0
  30. package/dist/long-bow.cjs.development.js +7464 -515
  31. package/dist/long-bow.cjs.development.js.map +1 -1
  32. package/dist/long-bow.cjs.production.min.js +1 -1
  33. package/dist/long-bow.cjs.production.min.js.map +1 -1
  34. package/dist/long-bow.esm.js +7458 -518
  35. package/dist/long-bow.esm.js.map +1 -1
  36. package/dist/mocks/equipmentSet.mocks.d.ts +15 -2
  37. package/dist/mocks/skills.mocks.d.ts +2 -121
  38. package/dist/stories/ChatDeprecated.stories.d.ts +5 -0
  39. package/dist/stories/CircullarController.stories.d.ts +5 -0
  40. package/dist/stories/CraftBook.stories.d.ts +4 -0
  41. package/dist/stories/DropdownSelectorContainer.stories.d.ts +5 -0
  42. package/dist/stories/ItemQuantitySelector.stories.d.ts +5 -0
  43. package/dist/stories/ItemSelector.stories.d.ts +4 -0
  44. package/dist/stories/QuickSpells.stories.d.ts +5 -0
  45. package/dist/stories/RadioInput.stories.d.ts +5 -0
  46. package/dist/stories/Spellbook.stories.d.ts +5 -0
  47. package/package.json +4 -1
  48. package/src/components/Abstractions/SlotsContainer.tsx +3 -0
  49. package/src/components/Button.tsx +18 -8
  50. package/src/components/Chat/Chat.tsx +105 -105
  51. package/src/components/Chatdeprecated/ChatDeprecated.tsx +200 -0
  52. package/src/components/CheckButton.tsx +1 -1
  53. package/src/components/CircularController/CircularController.tsx +162 -0
  54. package/src/components/CraftBook/CraftBook.tsx +230 -0
  55. package/src/components/CraftBook/MockItems.ts +46 -0
  56. package/src/components/DraggableContainer.tsx +4 -1
  57. package/src/components/Dropdown.tsx +7 -1
  58. package/src/components/DropdownSelectorContainer.tsx +42 -0
  59. package/src/components/Equipment/EquipmentSet.tsx +46 -0
  60. package/src/components/Input.tsx +6 -2
  61. package/src/components/Item/Inventory/ItemContainer.tsx +104 -6
  62. package/src/components/Item/Inventory/ItemQuantitySelector.tsx +142 -0
  63. package/src/components/Item/Inventory/ItemSlot.tsx +234 -34
  64. package/src/components/NPCDialog/NPCDialog.tsx +4 -28
  65. package/src/components/NPCDialog/NPCDialogText.tsx +75 -15
  66. package/src/components/NPCDialog/img/press-button.gif +0 -0
  67. package/src/components/RadioInput/RadioButton.tsx +98 -0
  68. package/src/components/RadioInput/RadioInput.tsx +99 -0
  69. package/src/components/RadioInput/instruments.ts +16 -0
  70. package/src/components/RangeSlider.tsx +37 -14
  71. package/src/components/SkillsContainer.tsx +1 -1
  72. package/src/components/Spellbook/QuickSpells.tsx +120 -0
  73. package/src/components/Spellbook/Spell.tsx +201 -0
  74. package/src/components/Spellbook/Spellbook.tsx +144 -0
  75. package/src/components/Spellbook/SpellbookShortcuts.tsx +77 -0
  76. package/src/components/Spellbook/constants.ts +12 -0
  77. package/src/components/Spellbook/mockSpells.ts +60 -0
  78. package/src/components/TimeWidget/TimeWidget.tsx +1 -0
  79. package/src/components/TradingMenu/TradingItemRow.tsx +43 -6
  80. package/src/components/TradingMenu/TradingMenu.tsx +1 -1
  81. package/src/components/itemSelector/ItemSelector.tsx +136 -0
  82. package/src/components/shared/SpriteFromAtlas.tsx +4 -1
  83. package/src/constants/uiDevices.ts +5 -0
  84. package/src/hooks/useOutsideAlerter.ts +2 -2
  85. package/src/index.tsx +8 -0
  86. package/src/mocks/atlas/items/items.json +6086 -314
  87. package/src/mocks/atlas/items/items.png +0 -0
  88. package/src/mocks/equipmentSet.mocks.ts +49 -4
  89. package/src/mocks/itemContainer.mocks.ts +54 -6
  90. package/src/mocks/skills.mocks.ts +8 -2
  91. package/src/stories/Chat.stories.tsx +20 -3
  92. package/src/stories/ChatDeprecated.stories.tsx +170 -0
  93. package/src/stories/CircullarController.stories.tsx +33 -0
  94. package/src/stories/CraftBook.stories.tsx +40 -0
  95. package/src/stories/DropdownSelectorContainer.stories.tsx +41 -0
  96. package/src/stories/EquipmentSet.stories.tsx +10 -0
  97. package/src/stories/ItemContainer.stories.tsx +84 -15
  98. package/src/stories/ItemQuantitySelector.stories.tsx +26 -0
  99. package/src/stories/ItemSelector.stories.tsx +77 -0
  100. package/src/stories/QuickSpells.stories.tsx +38 -0
  101. package/src/stories/RadioInput.stories.tsx +35 -0
  102. package/src/stories/RangeSlider.stories.tsx +10 -9
  103. package/src/stories/Spellbook.stories.tsx +107 -0
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { uiFonts } from '../constants/uiFonts';
4
+ import { Dropdown } from './Dropdown';
5
+
6
+ interface IDropdownSelectorOption {
7
+ id: string;
8
+ name: string;
9
+ }
10
+
11
+ export interface IDropdownSelectorContainer {
12
+ onChange: (id: string) => void;
13
+ options: IDropdownSelectorOption[];
14
+ details?: string;
15
+ title: string;
16
+ }
17
+
18
+ export const DropdownSelectorContainer: React.FC<IDropdownSelectorContainer> = ({
19
+ title,
20
+ onChange,
21
+ options,
22
+ details,
23
+ }) => {
24
+ return (
25
+ <div>
26
+ <p>{title}</p>
27
+ <Dropdown
28
+ options={options.map((option, index) => ({
29
+ option: option.name,
30
+ value: option.id,
31
+ id: index,
32
+ }))}
33
+ onChange={onChange}
34
+ />
35
+ <Details>{details}</Details>
36
+ </div>
37
+ );
38
+ };
39
+
40
+ const Details = styled.p`
41
+ font-size: ${uiFonts.size.xsmall} !important;
42
+ `;
@@ -8,6 +8,7 @@ import {
8
8
  } from '@rpg-engine/shared';
9
9
  import React from 'react';
10
10
  import styled from 'styled-components';
11
+ import { IPosition } from '../../types/eventTypes';
11
12
  import { DraggableContainer } from '../DraggableContainer';
12
13
  import { ItemSlot } from '../Item/Inventory/ItemSlot';
13
14
  import { RPGUIContainerTypes } from '../RPGUIContainer';
@@ -20,6 +21,21 @@ export interface IEquipmentSetProps {
20
21
  item: IItem,
21
22
  itemContainerType: ItemContainerType | null
22
23
  ) => void;
24
+ onItemDragStart?: (
25
+ item: IItem,
26
+ slotIndex: number,
27
+ itemContainerType: ItemContainerType | null
28
+ ) => void;
29
+ onItemDragEnd?: (quantity?: number) => void;
30
+ onItemPlaceDrop?: (
31
+ item: IItem | null,
32
+ slotIndex: number,
33
+ itemContainerType: ItemContainerType | null
34
+ ) => void;
35
+ onItemOutsideDrop?: (item: IItem, position: IPosition) => void;
36
+ dragScale?: number;
37
+ checkIfItemCanBeMoved: () => boolean;
38
+ checkIfItemShouldDragEnd?: () => boolean;
23
39
  onMouseOver?: (e: any, slotIndex: number, item: IItem | null) => void;
24
40
  onSelected?: (optionId: string) => void;
25
41
  initialPosition?: { x: number; y: number };
@@ -36,6 +52,13 @@ export const EquipmentSet: React.FC<IEquipmentSetProps> = ({
36
52
  onItemClick,
37
53
  atlasIMG,
38
54
  atlasJSON,
55
+ onItemDragEnd,
56
+ onItemDragStart,
57
+ onItemPlaceDrop,
58
+ onItemOutsideDrop,
59
+ checkIfItemCanBeMoved,
60
+ checkIfItemShouldDragEnd,
61
+ dragScale,
39
62
  }) => {
40
63
  const {
41
64
  neck,
@@ -102,6 +125,27 @@ export const EquipmentSet: React.FC<IEquipmentSetProps> = ({
102
125
  onSelected={(optionId: string) => {
103
126
  if (onSelected) onSelected(optionId);
104
127
  }}
128
+ onDragStart={(item, slotIndex, itemContainerType) => {
129
+ if (!item) {
130
+ return;
131
+ }
132
+
133
+ if (onItemDragStart)
134
+ onItemDragStart(item, slotIndex, itemContainerType);
135
+ }}
136
+ onDragEnd={quantity => {
137
+ if (onItemDragEnd) onItemDragEnd(quantity);
138
+ }}
139
+ dragScale={dragScale}
140
+ checkIfItemCanBeMoved={checkIfItemCanBeMoved}
141
+ checkIfItemShouldDragEnd={checkIfItemShouldDragEnd}
142
+ onPlaceDrop={(item, slotIndex, itemContainerType) => {
143
+ if (onItemPlaceDrop)
144
+ onItemPlaceDrop(item, slotIndex, itemContainerType);
145
+ }}
146
+ onOutsideDrop={(item, position) => {
147
+ if (onItemOutsideDrop) onItemOutsideDrop(item, position);
148
+ }}
105
149
  atlasIMG={atlasIMG}
106
150
  atlasJSON={atlasJSON}
107
151
  />
@@ -134,6 +178,7 @@ const EquipmentSetContainer = styled.div`
134
178
  justify-content: center;
135
179
  flex-wrap: wrap;
136
180
  flex-direction: row;
181
+ touch-action: none;
137
182
  `;
138
183
 
139
184
  const EquipmentColumn = styled.div`
@@ -141,4 +186,5 @@ const EquipmentColumn = styled.div`
141
186
  justify-content: center;
142
187
  flex-wrap: wrap;
143
188
  flex-direction: column;
189
+ touch-action: none;
144
190
  `;
@@ -4,8 +4,12 @@ export interface IInputProps
4
4
  extends React.DetailedHTMLProps<
5
5
  React.InputHTMLAttributes<HTMLInputElement>,
6
6
  HTMLInputElement
7
- > {}
7
+ > {
8
+ innerRef?: React.Ref<HTMLInputElement>;
9
+ }
8
10
 
9
11
  export const Input: React.FC<IInputProps> = ({ ...props }) => {
10
- return <input {...props} />;
12
+ const { innerRef, ...rest } = props;
13
+
14
+ return <input {...rest} ref={props.innerRef} />;
11
15
  };
@@ -1,8 +1,10 @@
1
1
  import { IItem, IItemContainer, ItemContainerType } from '@rpg-engine/shared';
2
- import React from 'react';
2
+ import React, { useState } from 'react';
3
3
  import styled from 'styled-components';
4
4
  import { SlotsContainer } from '../../Abstractions/SlotsContainer';
5
+ import { ItemQuantitySelector } from './ItemQuantitySelector';
5
6
 
7
+ import { IPosition } from '../../../types/eventTypes';
6
8
  import { ItemSlot } from './ItemSlot';
7
9
 
8
10
  export interface IItemContainerProps {
@@ -13,12 +15,28 @@ export interface IItemContainerProps {
13
15
  ItemType: IItem['type'],
14
16
  itemContainerType: ItemContainerType | null
15
17
  ) => void;
18
+ onItemDragStart?: (
19
+ item: IItem,
20
+ slotIndex: number,
21
+ itemContainerType: ItemContainerType | null
22
+ ) => void;
23
+ onItemDragEnd?: (quantity?: number) => void;
24
+ onOutsideDrop?: (item: IItem, position: IPosition) => void;
25
+ onItemPlaceDrop?: (
26
+ item: IItem | null,
27
+ slotIndex: number,
28
+ itemContainerType: ItemContainerType | null
29
+ ) => void;
30
+ dragScale?: number;
31
+ checkIfItemCanBeMoved: () => boolean;
32
+ checkIfItemShouldDragEnd?: () => boolean;
16
33
  onMouseOver?: (e: any, slotIndex: number, item: IItem | null) => void;
17
34
  onSelected?: (optionId: string, item: IItem) => void;
18
35
  type: ItemContainerType;
19
36
  atlasJSON: any;
20
37
  atlasIMG: any;
21
38
  disableContextMenu?: boolean;
39
+ initialPosition?: { x: number; y: number };
22
40
  }
23
41
 
24
42
  export const ItemContainer: React.FC<IItemContainerProps> = ({
@@ -31,7 +49,21 @@ export const ItemContainer: React.FC<IItemContainerProps> = ({
31
49
  atlasJSON,
32
50
  atlasIMG,
33
51
  disableContextMenu = false,
52
+ onItemDragEnd,
53
+ onItemDragStart,
54
+ onItemPlaceDrop,
55
+ onOutsideDrop,
56
+ checkIfItemCanBeMoved,
57
+ initialPosition,
58
+ checkIfItemShouldDragEnd,
59
+ dragScale,
34
60
  }) => {
61
+ const [quantitySelect, setQuantitySelect] = useState({
62
+ isOpen: false,
63
+ maxQuantity: 1,
64
+ callback: (_quantity: number) => {},
65
+ });
66
+
35
67
  const onRenderSlots = () => {
36
68
  const slots = [];
37
69
 
@@ -52,6 +84,30 @@ export const ItemContainer: React.FC<IItemContainerProps> = ({
52
84
  onSelected={(optionId: string, item: IItem) => {
53
85
  if (onSelected) onSelected(optionId, item);
54
86
  }}
87
+ onDragStart={(item, slotIndex, itemContainerType) => {
88
+ if (onItemDragStart)
89
+ onItemDragStart(item, slotIndex, itemContainerType);
90
+ }}
91
+ onDragEnd={quantity => {
92
+ if (onItemDragEnd) onItemDragEnd(quantity);
93
+ }}
94
+ dragScale={dragScale}
95
+ checkIfItemCanBeMoved={checkIfItemCanBeMoved}
96
+ checkIfItemShouldDragEnd={checkIfItemShouldDragEnd}
97
+ openQuantitySelector={(maxQuantity, callback) => {
98
+ setQuantitySelect({
99
+ isOpen: true,
100
+ maxQuantity,
101
+ callback,
102
+ });
103
+ }}
104
+ onPlaceDrop={(item, slotIndex, itemContainerType) => {
105
+ if (onItemPlaceDrop)
106
+ onItemPlaceDrop(item, slotIndex, itemContainerType);
107
+ }}
108
+ onOutsideDrop={(item, position) => {
109
+ if (onOutsideDrop) onOutsideDrop(item, position);
110
+ }}
55
111
  atlasIMG={atlasIMG}
56
112
  atlasJSON={atlasJSON}
57
113
  />
@@ -61,11 +117,40 @@ export const ItemContainer: React.FC<IItemContainerProps> = ({
61
117
  };
62
118
 
63
119
  return (
64
- <SlotsContainer title={itemContainer.name || 'Container'} onClose={onClose}>
65
- <ItemsContainer className="item-container-body">
66
- {onRenderSlots()}
67
- </ItemsContainer>
68
- </SlotsContainer>
120
+ <>
121
+ <SlotsContainer
122
+ title={itemContainer.name || 'Container'}
123
+ onClose={onClose}
124
+ initialPosition={initialPosition}
125
+ >
126
+ <ItemsContainer className="item-container-body">
127
+ {onRenderSlots()}
128
+ </ItemsContainer>
129
+ </SlotsContainer>
130
+ {quantitySelect.isOpen && (
131
+ <QuantitySelectorContainer>
132
+ <ItemQuantitySelector
133
+ quantity={quantitySelect.maxQuantity}
134
+ onConfirm={quantity => {
135
+ quantitySelect.callback(quantity);
136
+ setQuantitySelect({
137
+ isOpen: false,
138
+ maxQuantity: 1,
139
+ callback: () => {},
140
+ });
141
+ }}
142
+ onClose={() => {
143
+ quantitySelect.callback(-1);
144
+ setQuantitySelect({
145
+ isOpen: false,
146
+ maxQuantity: 1,
147
+ callback: () => {},
148
+ });
149
+ }}
150
+ />
151
+ </QuantitySelectorContainer>
152
+ )}
153
+ </>
69
154
  );
70
155
  };
71
156
 
@@ -75,3 +160,16 @@ const ItemsContainer = styled.div`
75
160
  justify-content: center;
76
161
  flex-wrap: wrap;
77
162
  `;
163
+
164
+ const QuantitySelectorContainer = styled.div`
165
+ position: absolute;
166
+ top: 0;
167
+ left: 0;
168
+ width: 100vw;
169
+ height: 100vh;
170
+ z-index: 100;
171
+ display: flex;
172
+ justify-content: center;
173
+ align-items: center;
174
+ background-color: rgba(0, 0, 0, 0.5);
175
+ `;
@@ -0,0 +1,142 @@
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import styled from 'styled-components';
3
+ import { Button, ButtonTypes } from '../../Button';
4
+ import { Input } from '../../Input';
5
+ import { RPGUIContainer, RPGUIContainerTypes } from '../../RPGUIContainer';
6
+ import { RangeSlider, RangeSliderType } from '../../RangeSlider';
7
+
8
+ export interface IItemQuantitySelectorProps {
9
+ quantity: number;
10
+ onConfirm: (quantity: number) => void;
11
+ onClose: () => void;
12
+ }
13
+
14
+ export const ItemQuantitySelector: React.FC<IItemQuantitySelectorProps> = ({
15
+ quantity,
16
+ onConfirm,
17
+ onClose,
18
+ }) => {
19
+ const [value, setValue] = useState(quantity);
20
+
21
+ const inputRef = useRef<HTMLInputElement>(null);
22
+
23
+ useEffect(() => {
24
+ if (inputRef.current) {
25
+ inputRef.current.focus();
26
+ inputRef.current.select();
27
+
28
+ const closeSelector = (e: KeyboardEvent) => {
29
+ if (e.key === 'Escape') {
30
+ onClose();
31
+ }
32
+ };
33
+
34
+ document.addEventListener('keydown', closeSelector);
35
+
36
+ return () => {
37
+ document.removeEventListener('keydown', closeSelector);
38
+ };
39
+ }
40
+
41
+ return () => {};
42
+ }, []);
43
+
44
+ return (
45
+ <StyledContainer type={RPGUIContainerTypes.Framed} width="25rem">
46
+ <CloseButton
47
+ className="container-close"
48
+ onClick={onClose}
49
+ onTouchStart={onClose}
50
+ >
51
+ X
52
+ </CloseButton>
53
+ <h2>Select quantity to move</h2>
54
+ <StyledForm
55
+ style={{ width: '100%' }}
56
+ onSubmit={e => {
57
+ e.preventDefault();
58
+
59
+ const numberValue = Number(value);
60
+
61
+ if (Number.isNaN(numberValue)) {
62
+ return;
63
+ }
64
+
65
+ onConfirm(Math.max(1, Math.min(quantity, numberValue)));
66
+ }}
67
+ noValidate
68
+ >
69
+ <StyledInput
70
+ innerRef={inputRef}
71
+ placeholder="Enter quantity"
72
+ type="number"
73
+ min={1}
74
+ max={quantity}
75
+ value={value}
76
+ onChange={e => {
77
+ if (Number(e.target.value) >= quantity) {
78
+ setValue(quantity);
79
+ return;
80
+ }
81
+
82
+ setValue((e.target.value as unknown) as number);
83
+ }}
84
+ onBlur={e => {
85
+ const newValue = Math.max(
86
+ 1,
87
+ Math.min(quantity, Number(e.target.value))
88
+ );
89
+
90
+ setValue(newValue);
91
+ }}
92
+ />
93
+ <RangeSlider
94
+ type={RangeSliderType.Slider}
95
+ valueMin={1}
96
+ valueMax={quantity}
97
+ width="100%"
98
+ onChange={setValue}
99
+ value={value}
100
+ />
101
+ <Button buttonType={ButtonTypes.RPGUIButton} type="submit">
102
+ Confirm
103
+ </Button>
104
+ </StyledForm>
105
+ </StyledContainer>
106
+ );
107
+ };
108
+
109
+ const StyledContainer = styled(RPGUIContainer)`
110
+ display: flex;
111
+ flex-direction: column;
112
+ align-items: center;
113
+ `;
114
+
115
+ const StyledForm = styled.form`
116
+ display: flex;
117
+ flex-direction: column;
118
+ align-items: center;
119
+ width: 100%;
120
+ `;
121
+ const StyledInput = styled(Input)`
122
+ text-align: center;
123
+
124
+ &::-webkit-outer-spin-button,
125
+ &::-webkit-inner-spin-button {
126
+ -webkit-appearance: none;
127
+ margin: 0;
128
+ }
129
+
130
+ &[type='number'] {
131
+ -moz-appearance: textfield;
132
+ }
133
+ `;
134
+
135
+ const CloseButton = styled.div`
136
+ position: absolute;
137
+ top: 3px;
138
+ right: 0px;
139
+ color: white;
140
+ z-index: 22;
141
+ font-size: 0.8rem;
142
+ `;