@rpg-engine/long-bow 0.2.61 → 0.2.63

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.
@@ -0,0 +1,4 @@
1
+ import { Meta } from '@storybook/react';
2
+ declare const meta: Meta;
3
+ export default meta;
4
+ export declare const Default: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, import("@storybook/react").Args>;
@@ -0,0 +1,5 @@
1
+ import { Meta } from '@storybook/react';
2
+ import { IRadioInput } from '../components/RadioInput/RadioInput';
3
+ declare const meta: Meta;
4
+ export default meta;
5
+ export declare const RadioInputElement: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, IRadioInput>;
@@ -0,0 +1,5 @@
1
+ import { Meta } from '@storybook/react';
2
+ import { IServerSelectionProps } from '../components/ServerSelection';
3
+ declare const meta: Meta;
4
+ export default meta;
5
+ export declare const Default: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, IServerSelectionProps>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpg-engine/long-bow",
3
- "version": "0.2.61",
3
+ "version": "0.2.63",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "dependencies": {
85
85
  "@rollup/plugin-image": "^2.1.1",
86
- "@rpg-engine/shared": "^0.5.89",
86
+ "@rpg-engine/shared": "^0.5.96",
87
87
  "dayjs": "^1.11.2",
88
88
  "fs-extra": "^10.1.0",
89
89
  "lodash": "^4.17.21",
@@ -28,7 +28,7 @@ export const Dropdown: React.FC<IDropdownProps> = ({
28
28
  useEffect(() => {
29
29
  const firstOption = options[0];
30
30
 
31
- if (firstOption) {
31
+ if (firstOption && !selectedValue) {
32
32
  setSelectedValue(firstOption.value);
33
33
  setSelectedOption(firstOption.option);
34
34
  }
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, { useEffect, useRef, useState } from 'react';
2
2
  import styled from 'styled-components';
3
3
  import { chunkString } from '../../libs/StringHelpers';
4
4
  import { DynamicText } from '../typography/DynamicText';
@@ -16,10 +16,27 @@ export const NPCDialogText: React.FC<IProps> = ({
16
16
  onEndStep,
17
17
  onStartStep,
18
18
  }) => {
19
- const textChunks = chunkString(text, 85);
19
+ const windowSize = useRef([window.innerWidth, window.innerHeight]);
20
+ function maxCharacters(width: number) {
21
+ // Set the font size to 16 pixels
22
+ var fontSize = 11.2;
20
23
 
21
- const [chunkIndex, setChunkIndex] = useState<number>(0);
24
+ // Calculate the number of characters that can fit in one line
25
+ var charactersPerLine = Math.floor(width / 2 / fontSize);
26
+
27
+ // Calculate the number of lines that can fit in the div
28
+ var linesPerDiv = Math.floor(180 / fontSize);
29
+
30
+ // Calculate the maximum number of characters that can fit in the div
31
+ var maxCharacters = charactersPerLine * linesPerDiv;
22
32
 
33
+ // Return the maximum number of characters
34
+ return Math.round(maxCharacters / 5);
35
+ }
36
+
37
+ const textChunks = chunkString(text, maxCharacters(windowSize.current[0]));
38
+
39
+ const [chunkIndex, setChunkIndex] = useState<number>(0);
23
40
  const onHandleSpacePress = (event: KeyboardEvent) => {
24
41
  if (event.code === 'Space') {
25
42
  const hasNextChunk = textChunks?.[chunkIndex + 1] || false;
@@ -0,0 +1,98 @@
1
+ import { capitalize } from 'lodash';
2
+ import React from 'react';
3
+ import styled from 'styled-components';
4
+ import { uiColors } from '../../constants/uiColors';
5
+ import { Ellipsis } from '../shared/Ellipsis';
6
+
7
+ export interface IRadioProps {
8
+ title:string,
9
+ subtitle:string,
10
+ instrument:string|null
11
+ setInstrument: (value: string) => void;
12
+ }
13
+
14
+ export const RadioButton: React.FC<IRadioProps> = ({
15
+ title,
16
+ subtitle,
17
+ instrument,
18
+ setInstrument,
19
+ }) => {
20
+ const isRadioSelected=(value:string):boolean=>instrument===value;
21
+
22
+ const handleClick = (e:string):void => {
23
+ setInstrument(e)
24
+ };
25
+
26
+ return (
27
+ <ItemWrapper onClick={() => handleClick(title)} >
28
+ <ItemIconContainer>
29
+ <SpriteContainer id='elemento-radio'>
30
+ <input
31
+ type='radio'
32
+ name='react-radio-btn'
33
+ className='rpgui-radio'
34
+ value={title}
35
+ checked={isRadioSelected(title)}
36
+ onChange={(e)=>(e)}
37
+ />
38
+ </SpriteContainer>
39
+ </ItemIconContainer>
40
+ <ItemNameContainer>
41
+ <NameValue onClick={() => handleClick(title)}>
42
+ <p>{title}</p>
43
+ <p>
44
+ <Ellipsis maxLines={1} maxWidth="250px">
45
+ {capitalize(subtitle)}
46
+ </Ellipsis>
47
+ </p>
48
+
49
+ </NameValue>
50
+ </ItemNameContainer>
51
+ </ItemWrapper>
52
+ );
53
+ };
54
+
55
+ const ItemWrapper = styled.div`
56
+ width: 100%;
57
+ margin: auto;
58
+ display: flex;
59
+ justify-content: space-between;
60
+ margin-bottom: 1rem;
61
+
62
+ &:hover {
63
+ background-color: ${uiColors.darkGray};
64
+ }
65
+ padding: 0.5rem;
66
+ `;
67
+
68
+
69
+ const ItemNameContainer = styled.div`
70
+ flex: 80%;
71
+ `;
72
+
73
+ const ItemIconContainer = styled.div`
74
+ display: flex;
75
+ justify-content: flex-start;
76
+ align-items: center;
77
+
78
+ flex: 0 0 58px;
79
+ `;
80
+
81
+ const SpriteContainer = styled.div`
82
+ input {
83
+ display:block !important;
84
+ &:hover {
85
+ cursor: pointer;
86
+ }
87
+ };
88
+ position: relative;
89
+ top: -0.5rem;
90
+ left: 0.5rem;
91
+ `;
92
+
93
+ const NameValue = styled.div`
94
+ p {
95
+ font-size: 0.75rem;
96
+ margin: 0;
97
+ }
98
+ `;
@@ -0,0 +1,99 @@
1
+ import React, { useState } from 'react';
2
+ import styled from 'styled-components';
3
+ import { DraggableContainer } from '../DraggableContainer';
4
+ import { RPGUIContainerTypes } from '../RPGUIContainer';
5
+ import { Button, ButtonTypes } from '../Button';
6
+ import { RadioButton } from './RadioButton';
7
+
8
+ export interface IRadioItems {
9
+ title: string;
10
+ subtitle: string;
11
+ }
12
+ export interface IRadioInput {
13
+ title:string,
14
+ subtitle:string,
15
+ onSelect:(a:string)=>void,
16
+ onCancel:()=>void,
17
+ items:IRadioItems[]
18
+ }
19
+
20
+ export const RadioInput: React.FC<IRadioInput>=({title,subtitle,onSelect,onCancel,items})=>{
21
+ const [instrument, setInstrument] = useState('')
22
+
23
+ const confirHandler=()=>{
24
+ if(instrument){
25
+ onSelect(instrument)
26
+ }
27
+ }
28
+
29
+ return (
30
+ <DraggableContainer
31
+ type={RPGUIContainerTypes.Framed}
32
+ onCloseButton={() => {
33
+ if (onCancel) onCancel();
34
+ }}
35
+ width="500px"
36
+ cancelDrag=".equipment-container-body .arrow-selector"
37
+ >
38
+ <>
39
+ <div style={{ width: '100%' }}>
40
+ <Title>{title}</Title>
41
+ <Subtitle>{subtitle}</Subtitle>
42
+ <hr className="golden" />
43
+ </div>
44
+ <RadioInputScroller>{
45
+ items.map((item,index)=>(
46
+ <RadioButton
47
+ key={`${item.title}_${index}`}
48
+ title={item.title}
49
+ subtitle={item.subtitle}
50
+ setInstrument={setInstrument}
51
+ instrument={instrument}
52
+ />
53
+ ))
54
+ }
55
+ </RadioInputScroller>
56
+ <ButtonWrapper>
57
+ <Button
58
+ buttonType={ButtonTypes.RPGUIButton}
59
+ onClick={() => onCancel()}
60
+ >
61
+ Cancel
62
+ </Button>
63
+ <Button
64
+ buttonType={ButtonTypes.RPGUIButton}
65
+ onClick={ confirHandler}
66
+ >
67
+ Select
68
+ </Button>
69
+
70
+ </ButtonWrapper>
71
+
72
+ </>
73
+ </DraggableContainer>
74
+ )
75
+ }
76
+ const RadioInputScroller = styled.div`
77
+ overflow-y: scroll;
78
+ height: 390px;
79
+ width: 100%;
80
+ margin-top: 1rem;
81
+ `;
82
+
83
+ const Title = styled.h1`
84
+ z-index: 22;
85
+ font-size: 0.6rem;
86
+ color: yellow !important;
87
+ `;
88
+ const Subtitle = styled.h1`
89
+ z-index: 22;
90
+ font-size: 0.4rem;
91
+ color: yellow !important;
92
+ `;
93
+ const ButtonWrapper = styled.div`
94
+ display: flex;
95
+ justify-content: flex-end;
96
+ padding-top: 20px;
97
+ width: 100%;
98
+ margin-top: 1rem;
99
+ `;
@@ -0,0 +1,16 @@
1
+
2
+ export const Itools:{title:string,subtitle:string}[] = [
3
+ {
4
+ title : 'Ax',
5
+ subtitle:'Cut down trees',
6
+ }, {
7
+ title : 'Sawing',
8
+ subtitle:'cut the wood into small pieces',
9
+ }, {
10
+ title : 'Sickle',
11
+ subtitle:'harvesting cereal plants',
12
+ }, {
13
+ title : 'Bow',
14
+ subtitle:'Hunting monsters',
15
+ },
16
+ ];
@@ -0,0 +1,40 @@
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 IServer {
7
+ id: string;
8
+ name: string;
9
+ }
10
+
11
+ export interface IServerSelectionProps {
12
+ onChange: (serverId: string) => void;
13
+ servers: IServer[];
14
+ details?: string;
15
+ }
16
+
17
+ export const ServerSelection: React.FC<IServerSelectionProps> = ({
18
+ onChange,
19
+ servers,
20
+ details,
21
+ }) => {
22
+ return (
23
+ <div>
24
+ <p>Select server</p>
25
+ <Dropdown
26
+ options={servers.map((server, index) => ({
27
+ option: server.name,
28
+ value: server.id,
29
+ id: index,
30
+ }))}
31
+ onChange={onChange}
32
+ />
33
+ <Details>{details}</Details>
34
+ </div>
35
+ );
36
+ };
37
+
38
+ const Details = styled.p`
39
+ font-size: ${uiFonts.size.xsmall} !important;
40
+ `;
@@ -37,6 +37,7 @@ const WidgetContainer = styled.div`
37
37
  background-repeat: no-repeat;
38
38
  width: 10rem;
39
39
  position: absolute;
40
+ height: 100px;
40
41
  `;
41
42
 
42
43
  const Time = styled.div`
@@ -0,0 +1,132 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import styled from 'styled-components';
3
+ import { Button, ButtonTypes } from '../Button';
4
+ import { DraggableContainer } from '../DraggableContainer';
5
+ import { RPGUIContainerTypes } from '../RPGUIContainer';
6
+ import { SpriteFromAtlas } from '../shared/SpriteFromAtlas';
7
+
8
+ export interface IOptionsItemSelectorProps {
9
+ name: string;
10
+ description: string;
11
+ imageKey: string;
12
+ }
13
+
14
+ export interface IItemSelectorProps {
15
+ atlasJSON: any;
16
+ atlasIMG: any;
17
+ options: IOptionsItemSelectorProps[];
18
+ onClose: () => void;
19
+ onSelect: (value: string) => void;
20
+ }
21
+
22
+ export const ItemSelector: React.FC<IItemSelectorProps> = ({
23
+ atlasIMG,
24
+ atlasJSON,
25
+ options,
26
+ onClose,
27
+ onSelect,
28
+ }) => {
29
+ const [selectedValue, setSelectedValue] = useState<string>();
30
+ const handleClick = () => {
31
+ let element = document.querySelector(
32
+ `input[name='test']:checked`
33
+ ) as HTMLInputElement;
34
+ const elementValue = element.value;
35
+ setSelectedValue(elementValue);
36
+ };
37
+
38
+ useEffect(() => {
39
+ if (selectedValue) {
40
+ onSelect(selectedValue);
41
+ }
42
+ }, [selectedValue]);
43
+ return (
44
+ <DraggableContainer
45
+ type={RPGUIContainerTypes.Framed}
46
+ width="500px"
47
+ cancelDrag=".equipment-container-body .arrow-selector"
48
+ onCloseButton={() => {
49
+ if (onClose) {
50
+ onClose();
51
+ }
52
+ }}
53
+ >
54
+ <div style={{ width: '100%' }}>
55
+ <Title>{'Harvesting instruments'}</Title>
56
+ <Subtitle>{'Use the tool, you need it'}</Subtitle>
57
+ <hr className="golden" />
58
+ </div>
59
+ <RadioInputScroller>
60
+ {options?.map((option, index) => (
61
+ <RadioOptionsWrapper key={index}>
62
+ <SpriteAtlasWrapper>
63
+ <SpriteFromAtlas
64
+ atlasIMG={atlasIMG}
65
+ atlasJSON={atlasJSON}
66
+ spriteKey={option.imageKey}
67
+ imgScale={3}
68
+ />
69
+ </SpriteAtlasWrapper>
70
+ <div>
71
+ <input
72
+ className="rpgui-radio"
73
+ type="radio"
74
+ value={option.name}
75
+ name="test"
76
+ />
77
+ <label
78
+ onClick={handleClick}
79
+ style={{ display: 'flex', alignItems: 'center' }}
80
+ >
81
+ {option.name} <br />
82
+ {option.description}
83
+ </label>
84
+ </div>
85
+ </RadioOptionsWrapper>
86
+ ))}
87
+ </RadioInputScroller>
88
+ <ButtonWrapper>
89
+ <Button buttonType={ButtonTypes.RPGUIButton} onClick={onClose}>
90
+ Cancel
91
+ </Button>
92
+ <Button buttonType={ButtonTypes.RPGUIButton}>Select</Button>
93
+ </ButtonWrapper>
94
+ </DraggableContainer>
95
+ );
96
+ };
97
+
98
+ const Title = styled.h1`
99
+ font-size: 0.6rem;
100
+ color: yellow !important;
101
+ `;
102
+ const Subtitle = styled.h1`
103
+ font-size: 0.4rem;
104
+ color: yellow !important;
105
+ `;
106
+
107
+ const RadioInputScroller = styled.div`
108
+ width: 100%;
109
+ margin-top: 1rem;
110
+ align-items: center;
111
+ margin-left: 20px;
112
+ align-items: flex-start;
113
+ overflow-y: scroll;
114
+ height: 360px;
115
+ `;
116
+
117
+ const SpriteAtlasWrapper = styled.div`
118
+ margin-right: 40px;
119
+ `;
120
+
121
+ const RadioOptionsWrapper = styled.div`
122
+ display: flex;
123
+ align-items: stretch;
124
+ margin-bottom: 40px;
125
+ `;
126
+
127
+ const ButtonWrapper = styled.div`
128
+ display: flex;
129
+ justify-content: space-around;
130
+ padding-top: 20px;
131
+ width: 100%;
132
+ `;
package/src/index.tsx CHANGED
@@ -9,6 +9,7 @@ export * from './components/HistoryDialog';
9
9
  export * from './components/Input';
10
10
  export * from './components/Item/Inventory/ItemContainer';
11
11
  export * from './components/Item/Inventory/ItemSlot';
12
+ export * from './components/itemSelector/ItemSelector';
12
13
  export * from './components/ListMenu';
13
14
  export * from './components/NPCDialog/NPCDialog';
14
15
  export * from './components/NPCDialog/NPCMultiDialog';
@@ -21,6 +22,7 @@ export * from './components/RadioButton';
21
22
  export * from './components/RangeSlider';
22
23
  export * from './components/RPGUIContainer';
23
24
  export * from './components/RPGUIRoot';
25
+ export * from './components/ServerSelection';
24
26
  export * from './components/shared/SpriteFromAtlas';
25
27
  export * from './components/SkillProgressBar';
26
28
  export * from './components/SkillsContainer';
@@ -0,0 +1,77 @@
1
+ import { Meta, Story } from '@storybook/react';
2
+ import React from 'react';
3
+ import { RPGUIRoot } from '..';
4
+ import {
5
+ IOptionsItemSelectorProps,
6
+ ItemSelector,
7
+ } from '../components/itemSelector/ItemSelector';
8
+ import atlasJSON from '../mocks/atlas/items/items.json';
9
+ import atlasIMG from '../mocks/atlas/items/items.png';
10
+
11
+ const meta: Meta = {
12
+ title: 'Item Selector',
13
+ component: ItemSelector,
14
+ };
15
+
16
+ export default meta;
17
+
18
+ const Template: Story = args => (
19
+ <RPGUIRoot>
20
+ <ItemSelector
21
+ atlasIMG={atlasIMG}
22
+ atlasJSON={atlasJSON}
23
+ options={options}
24
+ onSelect={onSelect}
25
+ onClose={() => console.log('closing Equipment Set Container')}
26
+ {...args}
27
+ />
28
+ </RPGUIRoot>
29
+ );
30
+
31
+ export const Default = Template.bind({});
32
+
33
+ const onSelect = (value: string): void => {
34
+ console.log('Story package', value);
35
+ };
36
+
37
+ const options: IOptionsItemSelectorProps[] = [
38
+ {
39
+ name: 'Human',
40
+ description: 'Human',
41
+ imageKey: 'axes/frost-double-axe.png',
42
+ },
43
+ {
44
+ name: 'Human',
45
+ description: 'Human',
46
+ imageKey: 'maces/spiked-club.png',
47
+ },
48
+ {
49
+ name: 'Human2',
50
+ description: 'Human2',
51
+ imageKey: 'axes/frost-double-axe.png',
52
+ },
53
+ {
54
+ name: 'Human3',
55
+ description: 'Human3',
56
+ imageKey: 'maces/spiked-club.png',
57
+ },
58
+ {
59
+ name: 'Human4',
60
+ description: 'Human4',
61
+ imageKey: 'axes/frost-double-axe.png',
62
+ },
63
+ {
64
+ name: 'Human5',
65
+ description: 'Human5',
66
+ imageKey: 'maces/spiked-club.png',
67
+ },
68
+ {
69
+ name: 'Human6',
70
+ description: 'Human6',
71
+ imageKey: 'axes/frost-double-axe.png',
72
+ },
73
+ ];
74
+
75
+ Default.args = {
76
+ options,
77
+ };
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import { Meta, Story } from '@storybook/react';
3
+ import { RadioInput ,IRadioInput} from '../components/RadioInput/RadioInput';
4
+ import { RPGUIRoot } from '../components/RPGUIRoot';
5
+ import { Itools } from '../components/RadioInput/instruments';
6
+
7
+ const meta: Meta = {
8
+ component: RadioInput,
9
+ };
10
+
11
+ export default meta;
12
+ const Template: Story<IRadioInput> = args => (
13
+ <RPGUIRoot>
14
+ <RadioInput {...args} />
15
+ </RPGUIRoot>
16
+ );
17
+
18
+ export const RadioInputElement = Template.bind({});
19
+
20
+ const onSelectIt = (value:string):void => {
21
+ console.log('Story package', value);
22
+ };
23
+
24
+ const onClose = () => {
25
+ console.log('close');
26
+ };
27
+
28
+ RadioInputElement.args={
29
+ title:"Harvesting instruments",
30
+ subtitle:'Use the tool, you need it',
31
+ onSelect:onSelectIt,
32
+ onCancel:onClose,
33
+ items:Itools
34
+
35
+ }
@@ -0,0 +1,40 @@
1
+ import { Meta, Story } from '@storybook/react';
2
+ import React from 'react';
3
+ import { RPGUIRoot } from '..';
4
+ import {
5
+ IServerSelectionProps,
6
+ ServerSelection,
7
+ } from '../components/ServerSelection';
8
+
9
+ const meta: Meta = {
10
+ title: 'ServerSelection',
11
+ component: ServerSelection,
12
+ };
13
+
14
+ export default meta;
15
+
16
+ const Template: Story<IServerSelectionProps> = args => (
17
+ <RPGUIRoot>
18
+ <ServerSelection {...args} details="There are server details" />
19
+ </RPGUIRoot>
20
+ );
21
+
22
+ export const Default = Template.bind({});
23
+
24
+ Default.args = {
25
+ onChange: () => {},
26
+ servers: [
27
+ {
28
+ id: 'europe-germany',
29
+ name: 'Europe',
30
+ },
31
+ {
32
+ id: 'europe-uk',
33
+ name: 'Europe',
34
+ },
35
+ {
36
+ id: 'america-us',
37
+ name: 'America',
38
+ },
39
+ ],
40
+ };