@rpg-engine/long-bow 0.1.92 → 0.1.96

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 (90) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +181 -181
  3. package/dist/components/Item/Inventory/ItemContainer.d.ts +1 -1
  4. package/dist/components/Item/Inventory/ItemSlot.d.ts +1 -1
  5. package/dist/components/Item/Inventory/itemContainerHelper.d.ts +1 -0
  6. package/dist/long-bow.cjs.development.js +13 -41
  7. package/dist/long-bow.cjs.development.js.map +1 -1
  8. package/dist/long-bow.cjs.production.min.js +1 -1
  9. package/dist/long-bow.cjs.production.min.js.map +1 -1
  10. package/dist/long-bow.esm.js +13 -41
  11. package/dist/long-bow.esm.js.map +1 -1
  12. package/package.json +98 -98
  13. package/src/components/Abstractions/SlotsContainer.tsx +42 -42
  14. package/src/components/Button.tsx +30 -30
  15. package/src/components/Chat/Chat.tsx +193 -193
  16. package/src/components/CheckButton.tsx +65 -65
  17. package/src/components/DraggableContainer.tsx +150 -150
  18. package/src/components/Dropdown.tsx +57 -57
  19. package/src/components/Equipment/EquipmentSet.tsx +134 -134
  20. package/src/components/Input.tsx +11 -11
  21. package/src/components/Item/Cards/ItemTooltip.tsx +32 -32
  22. package/src/components/Item/Inventory/ItemContainer.tsx +65 -65
  23. package/src/components/Item/Inventory/ItemContainerTypes.ts +4 -4
  24. package/src/components/Item/Inventory/ItemSlot.tsx +198 -199
  25. package/src/components/Item/Inventory/itemContainerHelper.ts +86 -94
  26. package/src/components/ListMenu.tsx +65 -65
  27. package/src/components/Multitab/Tab.tsx +57 -57
  28. package/src/components/Multitab/TabBody.tsx +13 -13
  29. package/src/components/Multitab/TabsContainer.tsx +97 -97
  30. package/src/components/NPCDialog/NPCDialog.tsx +145 -145
  31. package/src/components/NPCDialog/NPCDialogText.tsx +53 -53
  32. package/src/components/NPCDialog/QuestionDialog/QuestionDialog.tsx +239 -239
  33. package/src/components/ProgressBar.tsx +91 -91
  34. package/src/components/PropertySelect/PropertySelect.tsx +101 -101
  35. package/src/components/PropertySelect/img/ui-arrows/arrow01-left-clicked.png +0 -0
  36. package/src/components/PropertySelect/img/ui-arrows/arrow01-left.png +0 -0
  37. package/src/components/PropertySelect/img/ui-arrows/arrow01-right-clicked.png +0 -0
  38. package/src/components/PropertySelect/img/ui-arrows/arrow01-right.png +0 -0
  39. package/src/components/PropertySelect/img/ui-arrows/arrow02-left-clicked.png +0 -0
  40. package/src/components/PropertySelect/img/ui-arrows/arrow02-left.png +0 -0
  41. package/src/components/PropertySelect/img/ui-arrows/arrow02-right-clicked.png +0 -0
  42. package/src/components/PropertySelect/img/ui-arrows/arrow02-right.png +0 -0
  43. package/src/components/QuestInfo/QuestInfo.tsx +143 -143
  44. package/src/components/RPGUIContainer.tsx +47 -47
  45. package/src/components/RPGUIRoot.tsx +14 -14
  46. package/src/components/RadioButton.tsx +53 -53
  47. package/src/components/RangeSlider.tsx +68 -68
  48. package/src/components/RelativeListMenu.tsx +83 -83
  49. package/src/components/ScrollList.tsx +77 -77
  50. package/src/components/SimpleProgressBar.tsx +62 -62
  51. package/src/components/SkillProgressBar.tsx +123 -123
  52. package/src/components/SkillsContainer.tsx +196 -196
  53. package/src/components/TextArea.tsx +11 -11
  54. package/src/components/Truncate.tsx +25 -25
  55. package/src/components/shared/Column.tsx +16 -16
  56. package/src/components/shared/SpriteFromAtlas.tsx +99 -99
  57. package/src/components/typography/DynamicText.tsx +49 -49
  58. package/src/constants/uiColors.ts +10 -10
  59. package/src/hooks/useEventListener.ts +21 -21
  60. package/src/hooks/useOutsideAlerter.ts +25 -25
  61. package/src/index.tsx +25 -25
  62. package/src/libs/StringHelpers.ts +3 -3
  63. package/src/mocks/atlas/icons/icons.json +735 -735
  64. package/src/mocks/atlas/items/items.json +5215 -5215
  65. package/src/mocks/equipmentSet.mocks.ts +347 -347
  66. package/src/mocks/itemContainer.mocks.ts +249 -249
  67. package/src/mocks/skills.mocks.ts +122 -122
  68. package/src/stories/Button.stories.tsx +36 -36
  69. package/src/stories/Chat.stories.tsx +170 -170
  70. package/src/stories/CheckButton.stories.tsx +48 -48
  71. package/src/stories/DraggableContainer.stories.tsx +28 -28
  72. package/src/stories/Dropdown.stories.tsx +46 -46
  73. package/src/stories/EquipmentSet.stories.tsx +50 -50
  74. package/src/stories/ItemContainer.stories.tsx +50 -50
  75. package/src/stories/ListMenu.stories.tsx +56 -56
  76. package/src/stories/Multitab.stories.tsx +51 -51
  77. package/src/stories/NPCDialog.stories.tsx +130 -130
  78. package/src/stories/ProgressBar.stories.tsx +23 -23
  79. package/src/stories/PropertySelect.stories.tsx +41 -41
  80. package/src/stories/QuestInfo.stories.tsx +76 -76
  81. package/src/stories/RPGUIContainers.stories.tsx +42 -42
  82. package/src/stories/RadioButton.stories.tsx +49 -49
  83. package/src/stories/RangeSlider.stories.tsx +60 -60
  84. package/src/stories/ScrollList.stories.tsx +85 -85
  85. package/src/stories/SimpleProgressBar.stories.tsx +22 -22
  86. package/src/stories/SkillProgressBar.stories.tsx +30 -30
  87. package/src/stories/SkillsContainer.stories.tsx +31 -31
  88. package/src/stories/Text.stories.tsx +42 -42
  89. package/src/types/eventTypes.ts +4 -4
  90. package/src/types/index.d.ts +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"long-bow.cjs.production.min.js","sources":["../src/components/Button.tsx","../src/components/RPGUIContainer.tsx","../src/components/Input.tsx","../src/components/shared/Column.tsx","../src/components/Chat/Chat.tsx","../src/constants/uiColors.ts","../src/hooks/useOutsideAlerter.ts","../src/components/Item/Inventory/ItemContainerTypes.ts","../src/components/DraggableContainer.tsx","../src/components/RPGUIRoot.tsx","../src/components/Item/Inventory/itemContainerHelper.ts","../src/components/RelativeListMenu.tsx","../src/components/shared/SpriteFromAtlas.tsx","../src/components/Item/Cards/ItemTooltip.tsx","../src/components/NPCDialog/NPCDialog.tsx","../src/components/Item/Inventory/ItemSlot.tsx","../src/components/Equipment/EquipmentSet.tsx","../src/components/Abstractions/SlotsContainer.tsx","../src/components/Item/Inventory/ItemContainer.tsx","../src/components/ListMenu.tsx","../src/components/typography/DynamicText.tsx","../src/components/NPCDialog/NPCDialogText.tsx","../src/libs/StringHelpers.ts","../src/hooks/useEventListener.ts","../src/components/NPCDialog/QuestionDialog/QuestionDialog.tsx","../src/components/RangeSlider.tsx","../src/components/ProgressBar.tsx","../src/components/PropertySelect/PropertySelect.tsx","../src/components/SimpleProgressBar.tsx","../src/components/SkillProgressBar.tsx","../src/components/SkillsContainer.tsx","../src/components/Truncate.tsx","../src/components/CheckButton.tsx","../src/components/Dropdown.tsx","../src/components/RadioButton.tsx","../src/components/TextArea.tsx"],"sourcesContent":["import React from 'react';\r\nimport styled from 'styled-components';\r\n\r\nexport enum ButtonTypes {\r\n RPGUIButton = 'rpgui-button',\r\n RPGUIGoldButton = 'rpgui-button golden',\r\n}\r\n\r\nexport interface IButtonProps {\r\n disabled?: boolean;\r\n children: React.ReactNode;\r\n buttonType: ButtonTypes;\r\n}\r\n\r\nexport const Button: React.FC<IButtonProps &\r\n React.DetailedHTMLProps<\r\n React.ButtonHTMLAttributes<HTMLButtonElement>,\r\n HTMLButtonElement\r\n >> = ({ disabled = false, children, buttonType, ...props }) => {\r\n return (\r\n <ButtonContainer className={`${buttonType}`} disabled={disabled} {...props}>\r\n <p>{children}</p>\r\n </ButtonContainer>\r\n );\r\n};\r\n\r\nconst ButtonContainer = styled.button<any>`\r\n height: 45px;\r\n font-size: 11.5px;\r\n`;\r\n","import React from 'react';\r\nimport styled from 'styled-components';\r\n\r\nexport enum RPGUIContainerTypes {\r\n Framed = 'framed',\r\n FramedGold = 'framed-golden',\r\n FramedGold2 = 'framed-golden-2',\r\n FramedGrey = 'framed-grey',\r\n}\r\nexport interface IRPGUIContainerProps {\r\n type: RPGUIContainerTypes;\r\n children: React.ReactNode;\r\n width?: string;\r\n height?: string;\r\n className?: string;\r\n}\r\n\r\nexport const RPGUIContainer: React.FC<IRPGUIContainerProps> = ({\r\n children,\r\n type,\r\n width = '50%',\r\n height,\r\n className,\r\n}) => {\r\n return (\r\n <Container\r\n width={width}\r\n height={height || 'auto'}\r\n className={`rpgui-container ${type} ${className}`}\r\n >\r\n {children}\r\n </Container>\r\n );\r\n};\r\n\r\ninterface IContainerProps {\r\n width: string;\r\n height: string;\r\n}\r\n\r\nconst Container = styled.div<IContainerProps>`\r\n height: ${props => props.height};\r\n width: ${({ width }) => width};\r\n display: flex;\r\n flex-wrap: wrap;\r\n image-rendering: pixelated;\r\n`;\r\n","import React from 'react';\r\n\r\nexport interface IInputProps\r\n extends React.DetailedHTMLProps<\r\n React.InputHTMLAttributes<HTMLInputElement>,\r\n HTMLInputElement\r\n > {}\r\n\r\nexport const Input: React.FC<IInputProps> = ({ ...props }) => {\r\n return <input {...props} />;\r\n};\r\n","import styled from 'styled-components';\r\n\r\ninterface IColumn {\r\n flex?: number;\r\n alignItems?: string;\r\n justifyContent?: string;\r\n flexWrap?: string;\r\n}\r\n\r\nexport const Column = styled.div<IColumn>`\r\n flex: ${props => props.flex || 'auto'};\r\n display: flex;\r\n flex-wrap: ${props => props.flexWrap || 'nowrap'};\r\n align-items: ${props => props.alignItems || 'flex-start'};\r\n justify-content: ${props => props.justifyContent || 'flex-start'};\r\n`;\r\n","import { IChatMessage } from '@rpg-engine/shared';\r\nimport dayjs from 'dayjs';\r\nimport React, { useEffect, useState } from 'react';\r\nimport { ErrorBoundary } from 'react-error-boundary';\r\nimport styled from 'styled-components';\r\nimport { colors } from '../../constants/uiColors';\r\nimport { Button, ButtonTypes } from '../Button';\r\nimport { Input } from '../Input';\r\nimport { RPGUIContainer, RPGUIContainerTypes } from '../RPGUIContainer';\r\nimport { Column } from '../shared/Column';\r\n\r\ninterface IEmitter {\r\n _id: string;\r\n name: string;\r\n}\r\nexport interface IChatProps {\r\n chatMessages: IChatMessage[];\r\n onSendChatMessage: (message: string) => void;\r\n onCloseButton: () => void;\r\n opacity?: number;\r\n width?: string;\r\n height?: string;\r\n}\r\n\r\nexport const Chat: React.FC<IChatProps> = ({\r\n chatMessages,\r\n onSendChatMessage,\r\n opacity = 1,\r\n width = '100%',\r\n height = '250px',\r\n onCloseButton,\r\n}) => {\r\n const [message, setMessage] = useState('');\r\n\r\n useEffect(() => {\r\n scrollChatToBottom();\r\n }, []);\r\n\r\n useEffect(() => {\r\n scrollChatToBottom();\r\n }, [chatMessages]);\r\n\r\n const scrollChatToBottom = () => {\r\n const scrollingElement = document.querySelector('.chat-body');\r\n if (scrollingElement) {\r\n scrollingElement.scrollTop = scrollingElement.scrollHeight;\r\n }\r\n };\r\n\r\n const handleSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {\r\n event.preventDefault();\r\n onSendChatMessage(message);\r\n setMessage('');\r\n };\r\n const getInputValue = (value: string) => {\r\n setMessage(value);\r\n };\r\n\r\n const onRenderMessageLines = (\r\n emitter: IEmitter,\r\n createdAt: string | undefined,\r\n message: string\r\n ) => {\r\n return `${dayjs(createdAt || new Date()).format('HH:mm')} ${\r\n emitter?.name ? `${emitter.name}: ` : 'Unknown: '\r\n } ${message}`;\r\n };\r\n\r\n const onRenderChatMessages = (chatMessages: IChatMessage[]) => {\r\n return chatMessages?.length ? (\r\n chatMessages?.map(({ _id, createdAt, emitter, message }, index) => (\r\n <MessageText key={`${_id}_${index}`}>\r\n {onRenderMessageLines(emitter, createdAt, message)}\r\n </MessageText>\r\n ))\r\n ) : (\r\n <MessageText>No messages available.</MessageText>\r\n );\r\n };\r\n\r\n return (\r\n <Container>\r\n <CustomContainer\r\n type={RPGUIContainerTypes.FramedGrey}\r\n width={width}\r\n height={height}\r\n className=\"chat-container\"\r\n opacity={opacity}\r\n >\r\n <ErrorBoundary fallback={<p>Oops! Your chat has crashed.</p>}>\r\n {onCloseButton && (\r\n <CloseButton onClick={onCloseButton} onTouchStart={onCloseButton}>\r\n X\r\n </CloseButton>\r\n )}\r\n <RPGUIContainer\r\n type={RPGUIContainerTypes.FramedGrey}\r\n width={'100%'}\r\n height={'80%'}\r\n className=\"chat-body dark-background\"\r\n >\r\n {onRenderChatMessages(chatMessages)}\r\n </RPGUIContainer>\r\n\r\n <Form onSubmit={handleSubmit}>\r\n <Column flex={70}>\r\n <CustomInput\r\n value={message}\r\n id=\"inputMessage\"\r\n onChange={e => getInputValue(e.target.value)}\r\n height={20}\r\n className=\"chat-input dark-background\"\r\n type=\"text\"\r\n autoComplete=\"off\"\r\n />\r\n </Column>\r\n <Column justifyContent=\"flex-end\">\r\n <Button\r\n buttonType={ButtonTypes.RPGUIButton}\r\n id=\"chat-send-button\"\r\n >\r\n Send\r\n </Button>\r\n </Column>\r\n </Form>\r\n </ErrorBoundary>\r\n </CustomContainer>\r\n </Container>\r\n );\r\n};\r\n\r\nconst Container = styled.div`\r\n position: relative;\r\n`;\r\n\r\nconst CloseButton = styled.div`\r\n position: absolute;\r\n top: 2px;\r\n right: 0px;\r\n color: white;\r\n z-index: 22;\r\n font-size: 0.7rem;\r\n`;\r\n\r\nconst CustomInput = styled(Input)`\r\n height: 30px;\r\n width: 100%;\r\n\r\n .rpgui-content .input {\r\n min-height: 39px;\r\n }\r\n`;\r\n\r\ninterface ICustomContainerProps {\r\n opacity: number;\r\n}\r\n\r\nconst CustomContainer = styled(RPGUIContainer)`\r\n display: block;\r\n\r\n opacity: ${(props: ICustomContainerProps) => props.opacity};\r\n\r\n &:hover {\r\n opacity: 1;\r\n }\r\n\r\n .dark-background {\r\n background-color: ${colors.darkGrey} !important;\r\n }\r\n\r\n .chat-body {\r\n &.rpgui-container.framed-grey {\r\n background: unset;\r\n }\r\n max-height: 170px;\r\n overflow-y: auto;\r\n }\r\n`;\r\n\r\nconst Form = styled.form`\r\n display: flex;\r\n width: 100%;\r\n justify-content: center;\r\n align-items: center;\r\n`;\r\n\r\nconst MessageText = styled.p`\r\n display: block !important;\r\n width: 100%;\r\n font-size: 0.7rem !important;\r\n overflow-y: auto;\r\n margin: 0;\r\n`;\r\n","export const colors = {\r\n darkGrey: '#3e3e3e',\r\n darkYellow: '#FFC857',\r\n orange: '#E9724C',\r\n cardinal: '#C5283D',\r\n raisinBlack: '#191923',\r\n navyBlue: '#0E79B2',\r\n purple: '#8C3D8C',\r\n blue: '#3772FF',\r\n};\r\n","import { useEffect } from 'react';\r\n\r\nexport function useOutsideClick(ref: any, id: string) {\r\n useEffect(() => {\r\n /**\r\n * Alert if clicked on outside of element\r\n */\r\n function handleClickOutside(event: any) {\r\n if (ref.current && !ref.current.contains(event.target)) {\r\n const event = new CustomEvent('clickOutside', {\r\n detail: {\r\n id,\r\n },\r\n });\r\n document.dispatchEvent(event);\r\n }\r\n }\r\n // Bind the event listener\r\n document.addEventListener('mousedown', handleClickOutside);\r\n return () => {\r\n // Unbind the event listener on clean up\r\n document.removeEventListener('mousedown', handleClickOutside);\r\n };\r\n }, [ref]);\r\n}\r\n","export enum SlotContainerType {\r\n INVENTORY = 'Inventory',\r\n EQUIPMENT_SET = 'EquipmentSet',\r\n}\r\n","import React, { useEffect, useRef } from 'react';\r\nimport Draggable, { DraggableData } from 'react-draggable';\r\nimport styled from 'styled-components';\r\nimport { useOutsideClick } from '../hooks/useOutsideAlerter';\r\nimport { IPosition } from '../types/eventTypes';\r\nimport { RPGUIContainerTypes } from './RPGUIContainer';\r\n\r\nexport interface IDraggableContainerProps {\r\n children: React.ReactNode;\r\n width?: string;\r\n height?: string;\r\n className?: string;\r\n type?: RPGUIContainerTypes;\r\n title?: string;\r\n imgSrc?: string;\r\n imgWidth?: string;\r\n onCloseButton?: () => void;\r\n cancelDrag?: string;\r\n onPositionChange?: (position: IPosition) => void;\r\n onOutsideClick?: () => void;\r\n}\r\n\r\nexport const DraggableContainer: React.FC<IDraggableContainerProps> = ({\r\n children,\r\n width = '50%',\r\n height,\r\n className,\r\n type = RPGUIContainerTypes.FramedGold,\r\n onCloseButton,\r\n title,\r\n imgSrc,\r\n imgWidth = '20px',\r\n cancelDrag,\r\n onPositionChange,\r\n onOutsideClick,\r\n}) => {\r\n const draggableRef = useRef(null);\r\n\r\n useOutsideClick(draggableRef, 'item-container');\r\n\r\n useEffect(() => {\r\n document.addEventListener('clickOutside', event => {\r\n const e = event as CustomEvent;\r\n\r\n if (e.detail.id === 'item-container') {\r\n if (onOutsideClick) {\r\n onOutsideClick();\r\n }\r\n }\r\n });\r\n\r\n return () => {\r\n document.removeEventListener('clickOutside', _e => {});\r\n };\r\n }, []);\r\n\r\n return (\r\n <Draggable\r\n cancel={`.container-close,${cancelDrag}`}\r\n onDrag={(_e, data: DraggableData) => {\r\n if (onPositionChange) {\r\n onPositionChange({\r\n x: data.x,\r\n y: data.y,\r\n });\r\n }\r\n }}\r\n >\r\n <Container\r\n ref={draggableRef}\r\n width={width}\r\n height={height || 'auto'}\r\n className={`rpgui-container ${type} ${className}`}\r\n >\r\n {title && (\r\n <TitleContainer className=\"drag-handler\">\r\n <Title>\r\n {imgSrc && <Icon src={imgSrc} width={imgWidth} />}\r\n {title}\r\n </Title>\r\n </TitleContainer>\r\n )}\r\n {onCloseButton && (\r\n <CloseButton\r\n className=\"container-close\"\r\n onClick={onCloseButton}\r\n onTouchStart={onCloseButton}\r\n >\r\n X\r\n </CloseButton>\r\n )}\r\n\r\n {children}\r\n </Container>\r\n </Draggable>\r\n );\r\n};\r\n\r\ninterface IContainerProps {\r\n width: string;\r\n height: string;\r\n}\r\n\r\nconst Container = styled.div<IContainerProps>`\r\n height: ${props => props.height};\r\n width: ${({ width }) => width};\r\n display: flex;\r\n flex-wrap: wrap;\r\n image-rendering: pixelated;\r\n\r\n &.rpgui-container {\r\n padding-top: 1.5rem;\r\n }\r\n`;\r\n\r\nconst CloseButton = styled.div`\r\n position: absolute;\r\n top: 3px;\r\n right: 0px;\r\n color: white;\r\n z-index: 22;\r\n font-size: 0.8rem;\r\n`;\r\n\r\nconst TitleContainer = styled.div`\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n flex-wrap: wrap;\r\n justify-content: flex-start;\r\n align-items: center;\r\n`;\r\n\r\nconst Title = styled.h1`\r\n color: white;\r\n z-index: 22;\r\n font-size: 0.6rem;\r\n`;\r\n\r\ninterface ICustomIconProps {\r\n width: string;\r\n}\r\n\r\nconst Icon = styled.img`\r\n color: white;\r\n z-index: 22;\r\n font-size: 10px;\r\n width: ${(props: ICustomIconProps) => props.width};\r\n margin-right: 0.5rem;\r\n`;\r\n","import React from 'react';\r\nimport 'rpgui/rpgui.min.css';\r\nimport 'rpgui/rpgui.min.js';\r\n\r\ninterface IProps {\r\n children: React.ReactNode;\r\n}\r\n\r\n//@ts-ignore\r\nexport const _RPGUI = RPGUI;\r\n\r\nexport const RPGUIRoot: React.FC<IProps> = ({ children }) => {\r\n return <div className=\"rpgui-content\">{children}</div>;\r\n};\r\n","import {\r\n ActionsByItemType,\r\n ItemSocketEventsDisplayLabels,\r\n ItemType,\r\n} from '@rpg-engine/shared';\r\nimport { SlotContainerType } from './ItemContainerTypes';\r\n\r\nexport interface IContextMenuItem {\r\n id: string;\r\n text: string;\r\n}\r\n\r\nexport enum ContainerType {\r\n INVENTORY = 'Inventory',\r\n EQUIPMENT_SET = 'EquipmentSet',\r\n}\r\n\r\nexport const handleContextMenuList = (itemType: ItemType, slotContainerType: SlotContainerType | null) => {\r\n let contextActionMenu: IContextMenuItem[] = [];\r\n if(slotContainerType === SlotContainerType.INVENTORY){\r\n contextActionMenu = handleItemContainerContextMenuList(itemType);\r\n }else{\r\n contextActionMenu = handleEquipmentContextMenuList(itemType);\r\n }\r\n\r\n return contextActionMenu;\r\n \r\n};\r\n\r\n// TODO: Refactor this file\r\nconst generateContextList = (actionsByTypeList: any) => {\r\n const contextMenu: IContextMenuItem[] = actionsByTypeList.map(\r\n (action: string) => {\r\n return { id: action, text: ItemSocketEventsDisplayLabels[action] };\r\n }\r\n );\r\n return contextMenu;\r\n};\r\n\r\nconst handleItemContainerContextMenuList = (itemType: ItemType) => {\r\n let contextActionMenu: IContextMenuItem[] = [];\r\n\r\n switch (itemType) {\r\n case ItemType.Weapon:\r\n case ItemType.Armor:\r\n case ItemType.Accessory:\r\n case ItemType.Jewelry:\r\n case ItemType.Tool:\r\n contextActionMenu = generateContextList(ActionsByItemType.Equipment);\r\n break;\r\n case ItemType.Consumable:\r\n contextActionMenu = generateContextList(ActionsByItemType.Consumable);\r\n break;\r\n case ItemType.CraftMaterial:\r\n contextActionMenu = generateContextList(ActionsByItemType.CraftMaterial);\r\n break;\r\n case ItemType.Other:\r\n case ItemType.Information:\r\n case ItemType.Quest:\r\n case ItemType.Container:\r\n contextActionMenu = generateContextList(ActionsByItemType.Other);\r\n break;\r\n default:\r\n contextActionMenu = generateContextList(ActionsByItemType.Other);\r\n break;\r\n }\r\n return contextActionMenu;\r\n};\r\n\r\nconst handleEquipmentContextMenuList = (itemType: ItemType) => {\r\n let contextActionMenu: IContextMenuItem[] = [];\r\n switch (itemType) {\r\n case ItemType.Weapon:\r\n case ItemType.Armor:\r\n case ItemType.Accessory:\r\n case ItemType.Jewelry:\r\n case ItemType.Tool:\r\n contextActionMenu = generateContextList(\r\n ActionsByItemType.EquipmenSetItems\r\n );\r\n break;\r\n case ItemType.Container:\r\n contextActionMenu = generateContextList(\r\n ActionsByItemType.EquipmenSetContainer\r\n );\r\n break;\r\n default:\r\n contextActionMenu = generateContextList(\r\n ActionsByItemType.EquipmenSetItems\r\n );\r\n break;\r\n }\r\n return contextActionMenu;\r\n};\r\n","import React, { useEffect, useRef } from 'react';\r\nimport styled from 'styled-components';\r\nimport { useOutsideClick } from '../hooks/useOutsideAlerter';\r\n\r\ninterface IListMenuOption {\r\n id: string;\r\n text: string;\r\n}\r\n\r\nexport interface IRelativeMenuProps {\r\n options: IListMenuOption[];\r\n onSelected: (selectedOptionId: string) => void;\r\n fontSize?: number;\r\n onOutsideClick?: () => void;\r\n}\r\n\r\nexport const RelativeListMenu: React.FC<IRelativeMenuProps> = ({\r\n options,\r\n onSelected,\r\n onOutsideClick,\r\n fontSize = 0.8,\r\n}) => {\r\n const ref = useRef(null);\r\n\r\n useOutsideClick(ref, 'relative-context-menu');\r\n\r\n useEffect(() => {\r\n document.addEventListener('clickOutside', event => {\r\n const e = event as CustomEvent;\r\n\r\n if (e.detail.id === 'relative-context-menu') {\r\n if (onOutsideClick) {\r\n onOutsideClick();\r\n }\r\n }\r\n });\r\n\r\n return () => {\r\n document.removeEventListener('clickOutside', _e => {});\r\n };\r\n }, []);\r\n\r\n return (\r\n <Container fontSize={fontSize} ref={ref}>\r\n <ul className=\"rpgui-list-imp\" style={{ overflow: 'hidden' }}>\r\n {options.map((params, index) => (\r\n <ListElement\r\n key={params?.id || index}\r\n onClick={() => {\r\n onSelected(params?.id);\r\n }}\r\n >\r\n {params?.text || 'No text'}\r\n </ListElement>\r\n ))}\r\n </ul>\r\n </Container>\r\n );\r\n};\r\n\r\ninterface IContainerProps {\r\n fontSize?: number;\r\n}\r\n\r\nconst Container = styled.div<IContainerProps>`\r\n position: absolute;\r\n top: 1rem;\r\n left: 4rem;\r\n\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n justify-content: start;\r\n align-items: flex-start;\r\n\r\n li {\r\n font-size: ${props => props.fontSize}em;\r\n }\r\n`;\r\n\r\nconst ListElement = styled.li`\r\n margin-right: 0.5rem;\r\n`;\r\n","import { GRID_HEIGHT, GRID_WIDTH } from '@rpg-engine/shared';\r\nimport React from 'react';\r\nimport styled from 'styled-components';\r\n\r\ninterface IProps {\r\n atlasJSON: any;\r\n atlasIMG: any;\r\n spriteKey: string;\r\n width?: number;\r\n height?: number;\r\n grayScale?: boolean;\r\n opacity?: number;\r\n onClick?: () => void;\r\n containerStyle?: any;\r\n imgStyle?: any;\r\n imgScale?: number;\r\n}\r\n\r\nexport const SpriteFromAtlas: React.FC<IProps> = ({\r\n atlasJSON,\r\n atlasIMG,\r\n spriteKey,\r\n width = GRID_WIDTH,\r\n height = GRID_HEIGHT,\r\n imgScale = 2,\r\n imgStyle,\r\n onClick,\r\n containerStyle,\r\n grayScale = false,\r\n opacity = 1,\r\n}) => {\r\n //! 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).\r\n //!Due to React's limitations, we cannot import it from the public folder directly!\r\n\r\n const spriteData = atlasJSON.frames[spriteKey];\r\n\r\n return (\r\n <Container\r\n width={width}\r\n height={height}\r\n hasHover={grayScale}\r\n onClick={onClick}\r\n style={containerStyle}\r\n >\r\n <ImgSprite\r\n className=\"sprite-from-atlas-img\"\r\n atlasIMG={atlasIMG}\r\n frame={spriteData.frame}\r\n scale={imgScale}\r\n grayScale={grayScale}\r\n opacity={opacity}\r\n style={imgStyle}\r\n />\r\n </Container>\r\n );\r\n};\r\n\r\ninterface IImgSpriteProps {\r\n atlasIMG: any;\r\n frame: {\r\n x: number;\r\n y: number;\r\n w: number;\r\n h: number;\r\n };\r\n scale: number;\r\n grayScale: boolean;\r\n opacity: number;\r\n}\r\n\r\ninterface IContainerProps {\r\n width: number;\r\n height: number;\r\n hasHover: boolean;\r\n}\r\n\r\nconst Container = styled.div`\r\n width: ${(props: IContainerProps) => props.width}px;\r\n height: ${(props: IContainerProps) => props.height}px;\r\n ${(props: IContainerProps) =>\r\n !props.hasHover\r\n ? `&:hover {\r\n filter: sepia(100%) saturate(300%) brightness(70%) hue-rotate(180deg);\r\n }`\r\n : ``}\r\n`;\r\n\r\nconst ImgSprite = styled.div<IImgSpriteProps>`\r\n width: ${props => props.frame.w}px;\r\n height: ${props => props.frame.h}px;\r\n background-image: url(${props => props.atlasIMG});\r\n background-position: -${props => props.frame.x}px -${props => props.frame.y}px;\r\n transform: scale(${props => props.scale});\r\n position: relative;\r\n top: 8px;\r\n left: 8px;\r\n filter: ${props => (props.grayScale ? 'grayscale(100%)' : 'none')};\r\n opacity: ${props => props.opacity};\r\n`;\r\n","import React from 'react';\r\nimport styled from 'styled-components';\r\n\r\ninterface IProps {\r\n label: string;\r\n}\r\n\r\nexport const ItemTooltip: React.FC<IProps> = ({ label }) => {\r\n return (\r\n <Container>\r\n <div>{label}</div>\r\n </Container>\r\n );\r\n};\r\n\r\nconst Container = styled.div`\r\n z-index: 2;\r\n position: absolute;\r\n top: 1rem;\r\n left: 4rem;\r\n\r\n font-size: 0.5rem;\r\n color: white;\r\n background-color: black;\r\n border-radius: 5px;\r\n padding: 0.5rem;\r\n min-width: 20px;\r\n width: 100%;\r\n text-align: center;\r\n\r\n opacity: 0.75;\r\n`;\r\n","import React, { useState } from 'react';\r\nimport styled from 'styled-components';\r\nimport { RPGUIContainer, RPGUIContainerTypes } from '../RPGUIContainer';\r\nimport aliceDefaultThumbnail from './img/npcDialog/npcThumbnails/alice.png';\r\nimport pressSpaceGif from './img/space.gif';\r\nimport { NPCDialogText } from './NPCDialogText';\r\nimport {\r\n IQuestionDialog,\r\n IQuestionDialogAnswer,\r\n QuestionDialog,\r\n} from './QuestionDialog/QuestionDialog';\r\n\r\nexport enum NPCDialogType {\r\n TextOnly = 'TextOnly',\r\n TextAndThumbnail = 'TextAndThumbnail',\r\n}\r\n\r\nexport interface INPCDialogProps {\r\n text?: string;\r\n type: NPCDialogType;\r\n imagePath?: string;\r\n onClose?: () => void;\r\n isQuestionDialog?: boolean;\r\n answers?: IQuestionDialogAnswer[];\r\n questions?: IQuestionDialog[];\r\n}\r\n\r\nexport const NPCDialog: React.FC<INPCDialogProps> = ({\r\n text,\r\n type,\r\n onClose,\r\n imagePath,\r\n isQuestionDialog = false,\r\n questions,\r\n answers,\r\n}) => {\r\n const [showGoNextIndicator, setShowGoNextIndicator] = useState<boolean>(\r\n false\r\n );\r\n\r\n return (\r\n <RPGUIContainer\r\n type={RPGUIContainerTypes.FramedGold}\r\n width={isQuestionDialog ? '600px' : '50%'}\r\n height={'180px'}\r\n >\r\n {isQuestionDialog && questions && answers ? (\r\n <>\r\n <TextContainer\r\n flex={type === NPCDialogType.TextAndThumbnail ? '70%' : '100%'}\r\n >\r\n <QuestionDialog\r\n questions={questions}\r\n answers={answers}\r\n onClose={() => {\r\n if (onClose) {\r\n onClose();\r\n }\r\n }}\r\n />\r\n </TextContainer>\r\n {type === NPCDialogType.TextAndThumbnail && (\r\n <ThumbnailContainer>\r\n <NPCThumbnail src={imagePath || aliceDefaultThumbnail} />\r\n </ThumbnailContainer>\r\n )}\r\n </>\r\n ) : (\r\n <>\r\n <Container>\r\n <TextContainer\r\n flex={type === NPCDialogType.TextAndThumbnail ? '70%' : '100%'}\r\n >\r\n <NPCDialogText\r\n onStartStep={() => setShowGoNextIndicator(false)}\r\n onEndStep={() => setShowGoNextIndicator(true)}\r\n text={text || 'No text provided.'}\r\n onClose={() => {\r\n if (onClose) {\r\n onClose();\r\n }\r\n }}\r\n />\r\n </TextContainer>\r\n {type === NPCDialogType.TextAndThumbnail && (\r\n <ThumbnailContainer>\r\n <NPCThumbnail src={imagePath || aliceDefaultThumbnail} />\r\n </ThumbnailContainer>\r\n )}\r\n </Container>\r\n {showGoNextIndicator && (\r\n <PressSpaceIndicator\r\n right={type === NPCDialogType.TextOnly ? '1rem' : '10.5rem'}\r\n src={pressSpaceGif}\r\n />\r\n )}\r\n </>\r\n )}\r\n </RPGUIContainer>\r\n );\r\n};\r\n\r\nconst Container = styled.div`\r\n display: flex;\r\n width: 100%;\r\n height: 100%;\r\n\r\n box-sizing: border-box;\r\n justify-content: center;\r\n align-items: flex-start;\r\n position: relative;\r\n`;\r\n\r\ninterface ITextContainerProps {\r\n flex: string;\r\n}\r\n\r\nconst TextContainer = styled.div<ITextContainerProps>`\r\n flex: ${({ flex }) => flex} 0 0;\r\n width: 355px;\r\n`;\r\n\r\nconst ThumbnailContainer = styled.div`\r\n flex: 30% 0 0;\r\n display: flex;\r\n justify-content: flex-end;\r\n`;\r\n\r\nconst NPCThumbnail = styled.img`\r\n image-rendering: pixelated;\r\n height: 128px;\r\n width: 128px;\r\n`;\r\n\r\ninterface IPressSpaceIndicatorProps {\r\n right: string;\r\n}\r\n\r\nconst PressSpaceIndicator = styled.img<IPressSpaceIndicatorProps>`\r\n position: absolute;\r\n right: ${({ right }) => right};\r\n bottom: 1rem;\r\n height: 20.7px;\r\n image-rendering: -webkit-optimize-contrast;\r\n`;\r\n","import { IItem, IItemContainer, ItemSlotType } from '@rpg-engine/shared';\r\n\r\nimport { observer } from 'mobx-react-lite';\r\nimport React, { useEffect, useState } from 'react';\r\nimport styled from 'styled-components';\r\nimport atlasJSON from '../../../mocks/atlas/items/items.json';\r\nimport atlasIMG from '../../../mocks/atlas/items/items.png';\r\nimport { RelativeListMenu } from '../../RelativeListMenu';\r\nimport { SpriteFromAtlas } from '../../shared/SpriteFromAtlas';\r\nimport { ItemTooltip } from '../Cards/ItemTooltip';\r\nimport {\r\n handleContextMenuList,\r\n IContextMenuItem,\r\n} from './itemContainerHelper';\r\nimport { SlotContainerType } from './ItemContainerTypes';\r\n\r\nconst EquipmentSlotSpriteByType: any = {\r\n Neck: 'accessories/corruption-necklace.png',\r\n LeftHand: 'swords/broad-sword.png',\r\n Ring: 'rings/iron-ring.png',\r\n Head: 'helmets/viking-helmet.png',\r\n Torso: 'armors/iron-armor.png',\r\n Legs: 'legs/studded-legs.png',\r\n Feet: 'boots/iron-boots.png',\r\n Inventory: 'containers/bag.png',\r\n RightHand: 'shields/plate-shield.png',\r\n Accessory: 'gloves/plate-gloves.png',\r\n};\r\n\r\ninterface IProps {\r\n slotIndex: number;\r\n item: IItem | null;\r\n itemContainer?: IItemContainer | null;\r\n slotContainerType: SlotContainerType | null;\r\n slotSpriteMask?: ItemSlotType | null;\r\n onSelected: (payload: any) => void;\r\n onMouseOver: (\r\n event: any,\r\n slotIndex: number,\r\n item: IItem | null,\r\n x: number,\r\n y: number\r\n ) => void;\r\n onMouseOut?: () => void;\r\n onClick: (item: IItem, slotContainerType: SlotContainerType | null) => void;\r\n}\r\n\r\nexport const ItemSlot: React.FC<IProps> = observer(\r\n ({\r\n slotIndex,\r\n item,\r\n slotContainerType,\r\n slotSpriteMask,\r\n onMouseOver,\r\n onMouseOut,\r\n onClick,\r\n onSelected,\r\n }) => {\r\n const [isTooltipVisible, setTooltipVisible] = useState(false);\r\n\r\n const [isContextMenuVisible, setIsContextMenuVisible] = useState(false);\r\n\r\n const [contextActions, setContextActions] = useState<IContextMenuItem[]>(\r\n []\r\n );\r\n\r\n useEffect(() => {\r\n if (item) { \r\n setContextActions(handleContextMenuList(item.type, slotContainerType) );\r\n }\r\n }, [item]);\r\n\r\n const getLeftPositionValue = (quantity: number) => {\r\n if (quantity > 0 && quantity < 10) return '2.5rem';\r\n else if (quantity > 9 && quantity < 100) return '2.0rem';\r\n else if (quantity > 99) return '1rem';\r\n return '2.5rem';\r\n };\r\n\r\n const renderItem = (itemToRender: IItem | null) => {\r\n const element = [];\r\n if (itemToRender?.texturePath) {\r\n element.push(\r\n <SpriteFromAtlas\r\n key={itemToRender._id}\r\n atlasIMG={atlasIMG}\r\n atlasJSON={atlasJSON}\r\n spriteKey={itemToRender.texturePath}\r\n imgScale={3}\r\n />\r\n );\r\n }\r\n if (itemToRender?.isStackable && itemToRender?.stackQty) {\r\n element.push(\r\n <ItemQty\r\n left={getLeftPositionValue(itemToRender.stackQty)}\r\n key={`qty-${itemToRender._id}`}\r\n >\r\n {' '}\r\n {itemToRender.stackQty}{' '}\r\n </ItemQty>\r\n );\r\n }\r\n return element;\r\n };\r\n\r\n const renderEquipment = (itemToRender: IItem | null) => {\r\n if (\r\n itemToRender?.texturePath &&\r\n itemToRender.allowedEquipSlotType?.includes(slotSpriteMask!)\r\n ) {\r\n return (\r\n <SpriteFromAtlas\r\n key={itemToRender._id}\r\n atlasIMG={atlasIMG}\r\n atlasJSON={atlasJSON}\r\n spriteKey={itemToRender.texturePath}\r\n imgScale={3}\r\n />\r\n );\r\n } else {\r\n return (\r\n <SpriteFromAtlas\r\n atlasIMG={atlasIMG}\r\n atlasJSON={atlasJSON}\r\n spriteKey={EquipmentSlotSpriteByType[slotSpriteMask!]}\r\n imgScale={3}\r\n grayScale={true}\r\n opacity={0.4}\r\n />\r\n );\r\n }\r\n };\r\n\r\n const onRenderSlot = (itemToRender: IItem | null) => {\r\n if (slotContainerType === SlotContainerType.EQUIPMENT_SET)\r\n return renderEquipment(itemToRender);\r\n return renderItem(itemToRender);\r\n };\r\n\r\n return (\r\n <Container\r\n className=\"rpgui-icon empty-slot\"\r\n onMouseOver={event =>\r\n onMouseOver(event, slotIndex, item, event.clientX, event.clientY)\r\n }\r\n onMouseOut={() => {\r\n if (onMouseOut) onMouseOut();\r\n }}\r\n onMouseEnter={() => setTooltipVisible(true)}\r\n onMouseLeave={() => setTooltipVisible(false)}\r\n onClick={() => {\r\n setTooltipVisible(false);\r\n\r\n if (item) {\r\n setIsContextMenuVisible(!isContextMenuVisible);\r\n onClick(item, slotContainerType);\r\n }\r\n }}\r\n >\r\n {isContextMenuVisible && contextActions && (\r\n <RelativeListMenu\r\n options={contextActions}\r\n onSelected={(optionId: string) => {\r\n setIsContextMenuVisible(false);\r\n onSelected(optionId);\r\n }}\r\n onOutsideClick={() => {\r\n setIsContextMenuVisible(false);\r\n }}\r\n />\r\n )}\r\n\r\n {isTooltipVisible && item && <ItemTooltip label={item.name} />}\r\n\r\n {onRenderSlot(item)}\r\n </Container>\r\n );\r\n }\r\n);\r\n\r\nconst Container = styled.div`\r\n margin: 0.1rem;\r\n .sprite-from-atlas-img {\r\n position: relative;\r\n top: 1.5rem;\r\n left: 1.5rem;\r\n }\r\n position: relative;\r\n`;\r\n\r\ninterface IItemQtyProps {\r\n left: string;\r\n}\r\nconst ItemQty = styled.span<IItemQtyProps>`\r\n position: relative;\r\n top: 1.5rem;\r\n left: ${props => props.left};\r\n`;\r\n","import {\r\n IEquipmentSet,\r\n IItem,\r\n IItemContainer,\r\n ItemSlotType,\r\n} from '@rpg-engine/shared';\r\nimport React from 'react';\r\nimport styled from 'styled-components';\r\nimport { DraggableContainer } from '../DraggableContainer';\r\nimport { SlotContainerType } from '../Item/Inventory/ItemContainerTypes';\r\nimport { ItemSlot } from '../Item/Inventory/ItemSlot';\r\nimport { RPGUIContainerTypes } from '../RPGUIContainer';\r\n\r\nexport interface IEquipmentSetProps {\r\n equipmentSet: IEquipmentSet;\r\n onClose?: () => void;\r\n onItemClick?: (\r\n item: IItem,\r\n slotContainerType: SlotContainerType | null\r\n ) => void;\r\n onMouseOver?: (e: any, slotIndex: number, item: IItem | null) => void;\r\n onSelected?: (optionId: string) => void;\r\n initialPosition?: { x: number; y: number };\r\n}\r\n\r\nexport const EquipmentSet: React.FC<IEquipmentSetProps> = ({\r\n equipmentSet,\r\n onClose,\r\n onMouseOver,\r\n onSelected,\r\n onItemClick,\r\n}) => {\r\n const {\r\n neck,\r\n leftHand,\r\n ring,\r\n head,\r\n armor,\r\n legs,\r\n boot,\r\n inventory,\r\n rightHand,\r\n accessory,\r\n } = equipmentSet;\r\n\r\n const equipmentData = [\r\n neck,\r\n leftHand,\r\n ring,\r\n head,\r\n armor,\r\n legs,\r\n boot,\r\n inventory,\r\n rightHand,\r\n accessory,\r\n ];\r\n\r\n const equipmentMaskSlots = [\r\n ItemSlotType.Neck,\r\n ItemSlotType.LeftHand,\r\n ItemSlotType.Ring,\r\n ItemSlotType.Head,\r\n ItemSlotType.Torso,\r\n ItemSlotType.Legs,\r\n ItemSlotType.Feet,\r\n ItemSlotType.Inventory,\r\n ItemSlotType.RightHand,\r\n ItemSlotType.Accessory,\r\n ];\r\n\r\n const onRenderEquipmentSlotRange = (start: number, end: number) => {\r\n const equipmentRange = equipmentData.slice(start, end);\r\n const slotMaksRange = equipmentMaskSlots.slice(start, end);\r\n\r\n return equipmentRange.map((data, i) => {\r\n const item = data as IItem;\r\n const itemContainer =\r\n (item && (item.itemContainer as IItemContainer)) ?? null;\r\n return (\r\n <ItemSlot\r\n key={i}\r\n slotIndex={i}\r\n item={item}\r\n itemContainer={itemContainer}\r\n slotContainerType={SlotContainerType.EQUIPMENT_SET}\r\n slotSpriteMask={slotMaksRange[i]}\r\n onMouseOver={(event, slotIndex, item) => {\r\n if (onMouseOver) onMouseOver(event, slotIndex, item);\r\n }}\r\n onClick={(item, slotContainerType) => {\r\n if (onItemClick) onItemClick(item, slotContainerType);\r\n }}\r\n onSelected={(optionId: string) => {\r\n if (onSelected) onSelected(optionId);\r\n }}\r\n />\r\n );\r\n });\r\n };\r\n\r\n return (\r\n <DraggableContainer\r\n title={'Equipments'}\r\n type={RPGUIContainerTypes.Framed}\r\n onCloseButton={() => {\r\n if (onClose) onClose();\r\n }}\r\n width=\"330px\"\r\n cancelDrag=\".equipment-container-body\"\r\n >\r\n <EquipmentSetContainer className=\"equipment-container-body\">\r\n <EquipmentColumn>{onRenderEquipmentSlotRange(0, 3)}</EquipmentColumn>\r\n <EquipmentColumn>{onRenderEquipmentSlotRange(3, 7)}</EquipmentColumn>\r\n <EquipmentColumn>{onRenderEquipmentSlotRange(7, 10)}</EquipmentColumn>\r\n </EquipmentSetContainer>\r\n </DraggableContainer>\r\n );\r\n};\r\n\r\nconst EquipmentSetContainer = styled.div`\r\n width: inherit;\r\n display: flex;\r\n justify-content: center;\r\n flex-wrap: wrap;\r\n flex-direction: row;\r\n`;\r\n\r\nconst EquipmentColumn = styled.div`\r\n display: flex;\r\n justify-content: center;\r\n flex-wrap: wrap;\r\n flex-direction: column;\r\n`;\r\n","import React from 'react';\r\nimport { IPosition } from '../../types/eventTypes';\r\nimport { DraggableContainer } from '../DraggableContainer';\r\nimport { RPGUIContainerTypes } from '../RPGUIContainer';\r\n\r\ninterface IProps {\r\n children: React.ReactNode;\r\n title: string;\r\n onClose?: () => void;\r\n onPositionChange?: (position: IPosition) => void;\r\n onOutsideClick?: () => void;\r\n}\r\n\r\nexport const SlotsContainer: React.FC<IProps> = ({\r\n children,\r\n title,\r\n onClose,\r\n onPositionChange,\r\n onOutsideClick,\r\n}) => {\r\n return (\r\n <DraggableContainer\r\n title={title}\r\n type={RPGUIContainerTypes.Framed}\r\n onCloseButton={() => {\r\n if (onClose) {\r\n onClose();\r\n }\r\n }}\r\n width=\"330px\"\r\n cancelDrag=\".item-container-body\"\r\n onPositionChange={({ x, y }) => {\r\n if (onPositionChange) {\r\n onPositionChange({ x, y });\r\n }\r\n }}\r\n onOutsideClick={onOutsideClick}\r\n >\r\n {children}\r\n </DraggableContainer>\r\n );\r\n};\r\n","import { IItem, IItemContainer } from '@rpg-engine/shared';\r\nimport React from 'react';\r\nimport styled from 'styled-components';\r\nimport { SlotsContainer } from '../../Abstractions/SlotsContainer';\r\nimport { SlotContainerType } from './ItemContainerTypes';\r\nimport { ItemSlot } from './ItemSlot';\r\n\r\nexport interface IItemContainerProps {\r\n itemContainer: IItemContainer;\r\n onClose?: () => void;\r\n onItemClick?: (\r\n item: IItem,\r\n slotContainerType: SlotContainerType | null\r\n ) => void;\r\n onMouseOver?: (e: any, slotIndex: number, item: IItem | null) => void;\r\n onSelected?: (optionId: string) => void;\r\n}\r\n\r\nexport const ItemContainer: React.FC<IItemContainerProps> = ({\r\n itemContainer,\r\n onClose,\r\n onMouseOver,\r\n onSelected,\r\n onItemClick,\r\n}) => {\r\n const onRenderSlots = () => {\r\n const slots = [];\r\n\r\n for (let i = 0; i < itemContainer.slotQty; i++) {\r\n slots.push(\r\n <ItemSlot\r\n key={i}\r\n slotIndex={i}\r\n item={itemContainer.slots?.[i] || null}\r\n slotContainerType={SlotContainerType.INVENTORY}\r\n onMouseOver={(event, slotIndex, item) => {\r\n if (onMouseOver) onMouseOver(event, slotIndex, item);\r\n }}\r\n onClick={(item, slotContainerType) => {\r\n if (onItemClick) onItemClick(item, slotContainerType);\r\n }}\r\n onSelected={(optionId: string) => {\r\n if (onSelected) onSelected(optionId);\r\n }}\r\n />\r\n );\r\n }\r\n return slots;\r\n };\r\n\r\n return (\r\n <SlotsContainer title={itemContainer.name || 'Container'} onClose={onClose}>\r\n <ItemsContainer className=\"item-container-body\">\r\n {onRenderSlots()}\r\n </ItemsContainer>\r\n </SlotsContainer>\r\n );\r\n};\r\n\r\nconst ItemsContainer = styled.div`\r\n max-width: 280px;\r\n display: flex;\r\n justify-content: center;\r\n flex-wrap: wrap;\r\n`;\r\n","import React from 'react';\r\nimport styled from 'styled-components';\r\n\r\ninterface IListMenuOption {\r\n id: string;\r\n text: string;\r\n}\r\n\r\nexport interface IListMenuProps {\r\n x: number;\r\n y: number;\r\n options: IListMenuOption[];\r\n onSelected: (selectedOptionId: string) => void;\r\n fontSize?: number;\r\n}\r\n\r\nexport const ListMenu: React.FC<IListMenuProps> = ({\r\n options,\r\n onSelected,\r\n x,\r\n y,\r\n fontSize = 0.8,\r\n}) => {\r\n return (\r\n <Container x={x} y={y} fontSize={fontSize}>\r\n <ul className=\"rpgui-list-imp\" style={{ overflow: 'hidden' }}>\r\n {options.map((params, index) => (\r\n <ListElement\r\n key={params?.id || index}\r\n onClick={() => {\r\n onSelected(params?.id);\r\n }}\r\n >\r\n {params?.text || 'No text'}\r\n </ListElement>\r\n ))}\r\n </ul>\r\n </Container>\r\n );\r\n};\r\n\r\ninterface IContainerProps {\r\n x?: number;\r\n y?: number;\r\n fontSize?: number;\r\n}\r\n\r\nconst Container = styled.div<IContainerProps>`\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n justify-content: start;\r\n align-items: flex-start;\r\n position: absolute;\r\n top: ${props => props.y || 0}px;\r\n left: ${props => props.x || 0}px;\r\n\r\n li {\r\n font-size: ${props => props.fontSize}em;\r\n }\r\n`;\r\n\r\nconst ListElement = styled.li`\r\n margin-right: 0.5rem;\r\n`;\r\n","import React, { useEffect, useState } from 'react';\r\nimport styled from 'styled-components';\r\n\r\ninterface IProps {\r\n text: string;\r\n onFinish?: () => void;\r\n onStart?: () => void;\r\n}\r\n\r\nexport const DynamicText: React.FC<IProps> = ({ text, onFinish, onStart }) => {\r\n const [textState, setTextState] = useState<string>('');\r\n\r\n useEffect(() => {\r\n let i = 0;\r\n const interval = setInterval(() => {\r\n // on every interval, show one more character\r\n\r\n if (i === 0) {\r\n if (onStart) {\r\n onStart();\r\n }\r\n }\r\n\r\n if (i < text.length) {\r\n setTextState(text.substring(0, i + 1));\r\n i++;\r\n } else {\r\n clearInterval(interval);\r\n if (onFinish) {\r\n onFinish();\r\n }\r\n }\r\n }, 50);\r\n\r\n return () => {\r\n clearInterval(interval);\r\n };\r\n }, [text]);\r\n\r\n return <TextContainer>{textState}</TextContainer>;\r\n};\r\n\r\nconst TextContainer = styled.p`\r\n font-size: 0.7rem !important;\r\n color: white;\r\n text-shadow: 1px 1px 0px #000000;\r\n letter-spacing: 1.2px;\r\n word-break: normal;\r\n`;\r\n","import React, { useEffect, useState } from 'react';\r\nimport styled from 'styled-components';\r\nimport { chunkString } from '../../libs/StringHelpers';\r\nimport { DynamicText } from '../typography/DynamicText';\r\n\r\ninterface IProps {\r\n text: string;\r\n onClose: () => void;\r\n onEndStep: () => void;\r\n onStartStep: () => void;\r\n}\r\n\r\nexport const NPCDialogText: React.FC<IProps> = ({\r\n text,\r\n onClose,\r\n onEndStep,\r\n onStartStep,\r\n}) => {\r\n const textChunks = chunkString(text, 85);\r\n\r\n const [chunkIndex, setChunkIndex] = useState<number>(0);\r\n\r\n const onHandleSpacePress = (event: KeyboardEvent) => {\r\n if (event.code === 'Space') {\r\n const hasNextChunk = textChunks?.[chunkIndex + 1] || false;\r\n\r\n if (hasNextChunk) {\r\n setChunkIndex(prev => prev + 1);\r\n } else {\r\n // if there's no more text chunks, close the dialog\r\n onClose();\r\n }\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n document.addEventListener('keydown', onHandleSpacePress);\r\n\r\n return () => document.removeEventListener('keydown', onHandleSpacePress);\r\n }, [chunkIndex]);\r\n\r\n return (\r\n <Container>\r\n <DynamicText\r\n text={textChunks?.[chunkIndex] || ''}\r\n onFinish={onEndStep}\r\n onStart={onStartStep}\r\n />\r\n </Container>\r\n );\r\n};\r\n\r\nconst Container = styled.div``;\r\n","export const chunkString = (str: string, length: number) => {\r\n return str.match(new RegExp('.{1,' + length + '}', 'g'));\r\n};\r\n","import React from 'react';\r\n\r\n//@ts-ignore\r\nexport const useEventListener = (type, handler, el = window) => {\r\n const savedHandler = React.useRef();\r\n\r\n React.useEffect(() => {\r\n savedHandler.current = handler;\r\n }, [handler]);\r\n\r\n React.useEffect(() => {\r\n //@ts-ignore\r\n const listener = e => savedHandler.current(e);\r\n\r\n el.addEventListener(type, listener);\r\n\r\n return () => {\r\n el.removeEventListener(type, listener);\r\n };\r\n }, [type, el]);\r\n};\r\n","import React, { useEffect, useState } from 'react';\r\nimport styled from 'styled-components';\r\nimport { useEventListener } from '../../../hooks/useEventListener';\r\nimport { DynamicText } from '../../typography/DynamicText';\r\n\r\nexport interface IQuestionDialogAnswer {\r\n id: number;\r\n text: string;\r\n nextQuestionId?: number;\r\n}\r\n\r\nexport interface IQuestionDialog {\r\n id: number;\r\n text: string;\r\n answerIds?: number[];\r\n}\r\n\r\nexport interface IProps {\r\n questions: IQuestionDialog[];\r\n answers: IQuestionDialogAnswer[];\r\n onClose: () => void;\r\n}\r\n\r\nexport const QuestionDialog: React.FC<IProps> = ({\r\n questions,\r\n answers,\r\n onClose,\r\n}) => {\r\n const [currentQuestion, setCurrentQuestion] = useState(questions[0]);\r\n\r\n const [canShowAnswers, setCanShowAnswers] = useState<boolean>(false);\r\n\r\n const onGetFirstAnswer = () => {\r\n if (!currentQuestion.answerIds || currentQuestion.answerIds.length === 0) {\r\n return null;\r\n }\r\n\r\n const firstAnswerId = currentQuestion.answerIds![0];\r\n\r\n return answers.find(answer => answer.id === firstAnswerId);\r\n };\r\n\r\n const [\r\n currentAnswer,\r\n setCurrentAnswer,\r\n ] = useState<IQuestionDialogAnswer | null>(onGetFirstAnswer()!);\r\n\r\n useEffect(() => {\r\n setCurrentAnswer(onGetFirstAnswer()!);\r\n }, [currentQuestion]);\r\n\r\n const onGetAnswers = (answerIds: number[]) => {\r\n return answerIds.map((answerId: number) =>\r\n answers.find(answer => answer.id === answerId)\r\n );\r\n };\r\n\r\n const onKeyPress = (e: KeyboardEvent) => {\r\n switch (e.key) {\r\n case 'ArrowDown':\r\n // select next answer, if any.\r\n // if no next answer, select first answer\r\n // const nextAnswer = onGetAnswers(currentQuestion.answerIds!).find(\r\n // (answer) => answer?.id === currentAnswer!.id + 1\r\n // );\r\n\r\n const nextAnswerIndex = onGetAnswers(\r\n currentQuestion.answerIds!\r\n ).findIndex(answer => answer?.id === currentAnswer!.id + 1);\r\n\r\n const nextAnswerID = currentQuestion.answerIds![nextAnswerIndex];\r\n\r\n // console.log(nextAnswerIndex);\r\n\r\n const nextAnswer = onGetAnswers(currentQuestion.answerIds!).find(\r\n answer => answer?.id === nextAnswerID\r\n );\r\n\r\n setCurrentAnswer(nextAnswer || onGetFirstAnswer()!);\r\n\r\n break;\r\n case 'ArrowUp':\r\n // select previous answer, if any.\r\n // if no previous answer, select last answer\r\n\r\n const previousAnswerIndex = onGetAnswers(\r\n currentQuestion.answerIds!\r\n ).findIndex(answer => answer?.id === currentAnswer!.id - 1);\r\n\r\n const previousAnswerID =\r\n currentQuestion.answerIds &&\r\n currentQuestion.answerIds[previousAnswerIndex];\r\n\r\n const previousAnswer = onGetAnswers(currentQuestion.answerIds!).find(\r\n answer => answer?.id === previousAnswerID\r\n );\r\n\r\n if (previousAnswer) {\r\n setCurrentAnswer(previousAnswer);\r\n } else {\r\n setCurrentAnswer(onGetAnswers(currentQuestion.answerIds!).pop()!);\r\n }\r\n\r\n break;\r\n case 'Enter':\r\n setCanShowAnswers(false);\r\n\r\n if (!currentAnswer?.nextQuestionId) {\r\n onClose();\r\n return;\r\n } else {\r\n setCurrentQuestion(\r\n questions.find(\r\n question => question.id === currentAnswer!.nextQuestionId\r\n )!\r\n );\r\n }\r\n\r\n break;\r\n }\r\n };\r\n useEventListener('keydown', onKeyPress);\r\n\r\n const onAnswerClick = (answer: IQuestionDialogAnswer) => {\r\n setCanShowAnswers(false);\r\n if (answer.nextQuestionId) {\r\n // if there is a next question, go to it\r\n setCurrentQuestion(\r\n questions.find(question => question.id === answer.nextQuestionId)!\r\n );\r\n } else {\r\n // else, finish dialog!\r\n onClose();\r\n }\r\n };\r\n\r\n const onRenderCurrentAnswers = () => {\r\n const answerIds = currentQuestion.answerIds;\r\n if (!answerIds) {\r\n return null;\r\n }\r\n\r\n const answers = onGetAnswers(answerIds);\r\n\r\n if (!answers) {\r\n return null;\r\n }\r\n\r\n return answers.map(answer => {\r\n const isSelected = currentAnswer?.id === answer?.id;\r\n const selectedColor = isSelected ? 'yellow' : 'white';\r\n\r\n if (answer) {\r\n return (\r\n <AnswerRow key={`answer_${answer.id}`}>\r\n <AnswerSelectedIcon color={selectedColor}>\r\n {isSelected ? 'X' : null}\r\n </AnswerSelectedIcon>\r\n\r\n <Answer\r\n key={answer.id}\r\n onClick={() => onAnswerClick(answer)}\r\n color={selectedColor}\r\n >\r\n {answer.text}\r\n </Answer>\r\n </AnswerRow>\r\n );\r\n }\r\n\r\n return null;\r\n });\r\n };\r\n\r\n return (\r\n <Container>\r\n <QuestionContainer>\r\n <DynamicText\r\n text={currentQuestion.text}\r\n onStart={() => setCanShowAnswers(false)}\r\n onFinish={() => setCanShowAnswers(true)}\r\n />\r\n </QuestionContainer>\r\n\r\n {canShowAnswers && (\r\n <AnswersContainer>{onRenderCurrentAnswers()}</AnswersContainer>\r\n )}\r\n </Container>\r\n );\r\n};\r\n\r\nconst Container = styled.div`\r\n display: flex;\r\n word-break: break-all;\r\n box-sizing: border-box;\r\n justify-content: flex-start;\r\n align-items: flex-start;\r\n flex-wrap: wrap;\r\n`;\r\n\r\nconst QuestionContainer = styled.div`\r\n flex: 100%;\r\n width: 100%;\r\n`;\r\n\r\nconst AnswersContainer = styled.div`\r\n flex: 100%;\r\n`;\r\n\r\ninterface IAnswerProps {\r\n color: string;\r\n}\r\n\r\nconst Answer = styled.p<IAnswerProps>`\r\n flex: auto;\r\n color: ${props => props.color} !important;\r\n font-size: 0.65rem !important;\r\n background: inherit;\r\n border: none;\r\n`;\r\n\r\nconst AnswerSelectedIcon = styled.span<IAnswerProps>`\r\n flex: 5% 0 0;\r\n color: ${props => props.color} !important;\r\n`;\r\n\r\nconst AnswerRow = styled.div`\r\n display: flex;\r\n flex-wrap: wrap;\r\n justify-content: center;\r\n align-items: center;\r\n margin-bottom: 0.5rem;\r\n height: 22px;\r\n p {\r\n line-height: unset;\r\n margin-top: 0;\r\n margin-bottom: 0rem;\r\n }\r\n`;\r\n","import React, { useState } from 'react';\r\nimport styled from 'styled-components';\r\nimport { v4 as uuidv4 } from 'uuid';\r\nimport { useEventListener } from '../hooks/useEventListener';\r\nimport { _RPGUI } from './RPGUIRoot';\r\n\r\nexport enum RangeSliderType {\r\n Slider = 'rpgui-slider',\r\n GoldSlider = 'rpgui-slider golden',\r\n}\r\n\r\nexport interface IRangeSliderProps {\r\n type: RangeSliderType;\r\n valueMin: number;\r\n valueMax: number;\r\n width: string;\r\n onChange: (value: number) => void;\r\n}\r\n\r\nexport const RangeSlider: React.FC<IRangeSliderProps> = ({\r\n type,\r\n valueMin,\r\n valueMax,\r\n width,\r\n onChange,\r\n}) => {\r\n const sliderId = uuidv4();\r\n\r\n const [wasMouseDownFirst, setWasMouseDownFirst] = useState<boolean>(false);\r\n\r\n useEventListener('mouseup', () => {\r\n if (wasMouseDownFirst) {\r\n onHandleMouseUp();\r\n }\r\n setWasMouseDownFirst(false);\r\n });\r\n\r\n const onHandleMouseUp = () => {\r\n const rpguiSlider = document.getElementById(`rpgui-slider-${sliderId}`);\r\n const value = _RPGUI.get_value(rpguiSlider);\r\n\r\n onChange(Number(value));\r\n };\r\n\r\n return (\r\n <div\r\n onMouseUp={onHandleMouseUp}\r\n onMouseDown={() => setWasMouseDownFirst(true)}\r\n >\r\n <Input\r\n className={\r\n type === RangeSliderType.Slider\r\n ? RangeSliderType.Slider\r\n : RangeSliderType.GoldSlider\r\n }\r\n type=\"range\"\r\n style={{ width: width }}\r\n min={valueMin}\r\n max={valueMax}\r\n id={`rpgui-slider-${sliderId}`}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nconst Input = styled.input`\r\n opacity: 0;\r\n`;\r\n","import React from 'react';\r\nimport styled from 'styled-components';\r\n\r\nexport interface IBarProps {\r\n max: number;\r\n value: number;\r\n color: 'red' | 'blue' | 'green';\r\n style?: Record<string, any>;\r\n displayText?: boolean;\r\n percentageWidth?: number;\r\n minWidth?: number;\r\n}\r\n\r\nexport const ProgressBar: React.FC<IBarProps> = ({\r\n max,\r\n value,\r\n color,\r\n displayText = true,\r\n percentageWidth = 40,\r\n minWidth = 100,\r\n style,\r\n}) => {\r\n const calculatePercentageValue = function(max: number, value: number) {\r\n if (value > max) {\r\n value = max;\r\n }\r\n return (value * 100) / max;\r\n };\r\n\r\n return (\r\n <Container\r\n className=\"rpgui-progress\"\r\n data-value={calculatePercentageValue(max, value) / 100}\r\n data-rpguitype=\"progress\"\r\n percentageWidth={percentageWidth}\r\n minWidth={minWidth}\r\n style={style}\r\n >\r\n {displayText && (\r\n <TextOverlay>\r\n <ProgressBarText>\r\n {value}/{max}\r\n </ProgressBarText>\r\n </TextOverlay>\r\n )}\r\n <div className=\" rpgui-progress-track\">\r\n <div\r\n className={`rpgui-progress-fill ${color} `}\r\n style={{\r\n left: '0px',\r\n width: calculatePercentageValue(max, value) + '%',\r\n }}\r\n ></div>\r\n </div>\r\n <div className=\" rpgui-progress-left-edge\"></div>\r\n <div className=\" rpgui-progress-right-edge\"></div>\r\n </Container>\r\n );\r\n};\r\n\r\nconst ProgressBarText = styled.span`\r\n font-size: 1rem;\r\n color: white;\r\n text-align: center;\r\n z-index: 1;\r\n position: absolute;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n top: 12px;\r\n`;\r\n\r\nconst TextOverlay = styled.div`\r\n width: 100%;\r\n position: relative;\r\n`;\r\n\r\ninterface IContainerProps {\r\n percentageWidth?: number;\r\n minWidth?: number;\r\n style?: Record<string, any>;\r\n}\r\n\r\nconst Container = styled.div<IContainerProps>`\r\n display: flex;\r\n flex-direction: column;\r\n min-width: ${props => props.minWidth}px;\r\n width: ${props => props.percentageWidth}%;\r\n justify-content: start;\r\n align-items: flex-start;\r\n ${props => props.style}\r\n`;\r\n","import React, { useState } from 'react';\r\nimport styled from 'styled-components';\r\nimport LeftArrowClickIcon from './img/ui-arrows/arrow01-left-clicked.png';\r\nimport LeftArrowIcon from './img/ui-arrows/arrow01-left.png';\r\nimport RightArrowClickIcon from './img/ui-arrows/arrow01-right-clicked.png';\r\nimport RightArrowIcon from './img/ui-arrows/arrow01-right.png';\r\n\r\nexport interface IPropertySelectProps {\r\n availableProperties: Array<IPropertiesProps>;\r\n selectedProperty: object;\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport interface IPropertiesProps {\r\n id: string;\r\n name: string;\r\n}\r\n\r\nexport const PropertySelect: React.FC<IPropertySelectProps> = ({\r\n availableProperties,\r\n}) => {\r\n const [currentIndex, setCurrentIndex] = useState(0);\r\n const propertiesLength = availableProperties.length - 1;\r\n\r\n const onLeftClick = () => {\r\n if (currentIndex === 0) setCurrentIndex(propertiesLength);\r\n else setCurrentIndex(index => index - 1);\r\n };\r\n const onRightClick = () => {\r\n if (currentIndex === propertiesLength) setCurrentIndex(0);\r\n else setCurrentIndex(index => index + 1);\r\n };\r\n return (\r\n <Container>\r\n <TextOverlay>\r\n <Item>{availableProperties[currentIndex].name}</Item>\r\n </TextOverlay>\r\n <div className=\"rpgui-progress-track\"></div>\r\n <LeftArrow onClick={onLeftClick}></LeftArrow>\r\n <RightArrow onClick={onRightClick}></RightArrow>\r\n </Container>\r\n );\r\n};\r\n\r\nconst Item = styled.span`\r\n font-size: 1rem;\r\n color: white;\r\n text-align: center;\r\n z-index: 1;\r\n position: absolute;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n top: 12px;\r\n`;\r\n\r\nconst TextOverlay = styled.div`\r\n width: 100%;\r\n position: relative;\r\n`;\r\n\r\ninterface IContainerProps {\r\n percentageWidth?: number;\r\n minWidth?: number;\r\n style?: Record<string, any>;\r\n}\r\n\r\nconst Container = styled.div<IContainerProps>`\r\n position: relative;\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: start;\r\n align-items: flex-start;\r\n min-width: 100px;\r\n width: 40%;\r\n`;\r\n\r\nconst LeftArrow = styled.div`\r\n background-image: url(${LeftArrowIcon});\r\n background-size: 100% 100%;\r\n left: 0;\r\n position: absolute;\r\n width: 40px;\r\n height: 42px;\r\n :active {\r\n background-image: url(${LeftArrowClickIcon});\r\n }\r\n`;\r\n\r\nconst RightArrow = styled.div`\r\n background-image: url(${RightArrowIcon});\r\n right: 0;\r\n position: absolute;\r\n width: 40px;\r\n background-size: 100% 100%;\r\n height: 42px;\r\n :active {\r\n background-image: url(${RightArrowClickIcon});\r\n }\r\n`;\r\n\r\nexport default PropertySelect;\r\n","import React from 'react';\r\nimport styled from 'styled-components';\r\n\r\nexport interface ISimpleProgressBarProps {\r\n value: number;\r\n bgColor?: string;\r\n margin?: number;\r\n}\r\n\r\nexport const SimpleProgressBar: React.FC<ISimpleProgressBarProps> = ({\r\n value,\r\n bgColor = 'red',\r\n margin = 20,\r\n}) => {\r\n return (\r\n <Container className=\"simple-progress-bar\">\r\n <ProgressBarContainer margin={margin}>\r\n <BackgroundBar>\r\n <Progress value={value} bgColor={bgColor} />\r\n </BackgroundBar>\r\n </ProgressBarContainer>\r\n </Container>\r\n );\r\n};\r\n\r\nconst Container = styled.div`\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n width: 100%;\r\n`;\r\n\r\nconst BackgroundBar = styled.span`\r\n background-color: rgba(0, 0, 0, 0.075);\r\n`;\r\n\r\ninterface ISimpleProgressBarThemeProps {\r\n value: number;\r\n bgColor: string;\r\n}\r\n\r\nconst Progress = styled.span`\r\n background-color: ${(props: ISimpleProgressBarThemeProps) => props.bgColor};\r\n width: ${(props: ISimpleProgressBarThemeProps) => props.value}%;\r\n`;\r\n\r\ninterface ISimpleProgressBarTheme2Props {\r\n margin: number;\r\n}\r\n\r\nconst ProgressBarContainer = styled.div`\r\n border-radius: 60px;\r\n border: 1px solid #282424;\r\n overflow: hidden;\r\n width: 100%;\r\n span {\r\n display: block;\r\n height: 100%;\r\n }\r\n height: 8px;\r\n margin-left: ${(props: ISimpleProgressBarTheme2Props) => props.margin}px;\r\n`;\r\n","import { getSPForLevel } from '@rpg-engine/shared';\r\nimport React from 'react';\r\nimport styled from 'styled-components';\r\nimport atlasJSON from '../mocks/atlas/items/items.json';\r\nimport atlasIMG from '../mocks/atlas/items/items.png';\r\nimport { SpriteFromAtlas } from './shared/SpriteFromAtlas';\r\nimport { SimpleProgressBar } from './SimpleProgressBar';\r\n\r\nexport interface ISkillProgressBarProps {\r\n skillName: string;\r\n bgColor: string;\r\n level: number;\r\n skillPoints: number;\r\n skillPointsToNextLevel?: number;\r\n texturePath: string;\r\n showSkillPoints?: boolean;\r\n}\r\n\r\nexport const SkillProgressBar: React.FC<ISkillProgressBarProps> = ({\r\n bgColor,\r\n skillName,\r\n level,\r\n skillPoints,\r\n texturePath,\r\n showSkillPoints = true,\r\n}) => {\r\n const spForNextLevel = getSPForLevel(level + 1);\r\n\r\n const ratio = (skillPoints / spForNextLevel) * 100;\r\n\r\n return (\r\n <>\r\n <ProgressTitle>\r\n <TitleName>{skillName}</TitleName>\r\n <ValueDisplay>lv {level}</ValueDisplay>\r\n </ProgressTitle>\r\n <ProgressBody>\r\n <ProgressIconContainer>\r\n {atlasIMG && atlasJSON ? (\r\n <SpriteContainer>\r\n <SpriteFromAtlas\r\n atlasIMG={atlasIMG}\r\n atlasJSON={atlasJSON}\r\n spriteKey={texturePath}\r\n imgScale={1}\r\n grayScale\r\n opacity={0.5}\r\n />\r\n </SpriteContainer>\r\n ) : (\r\n <></>\r\n )}\r\n </ProgressIconContainer>\r\n\r\n <ProgressBarContainer>\r\n <SimpleProgressBar value={ratio} bgColor={bgColor} />\r\n </ProgressBarContainer>\r\n </ProgressBody>\r\n {showSkillPoints && (\r\n <SkillDisplayContainer>\r\n <SkillPointsDisplay>\r\n {skillPoints}/{spForNextLevel}\r\n </SkillPointsDisplay>\r\n </SkillDisplayContainer>\r\n )}\r\n </>\r\n );\r\n};\r\n\r\nconst ProgressBarContainer = styled.div`\r\n position: relative;\r\n top: 8px;\r\n width: 100%;\r\n height: auto;\r\n`;\r\n\r\nconst SpriteContainer = styled.div`\r\n position: relative;\r\n top: -3px;\r\n left: 0;\r\n`;\r\n\r\nconst SkillDisplayContainer = styled.div`\r\n margin: 0 auto;\r\n\r\n p {\r\n margin: 0;\r\n }\r\n`;\r\n\r\nconst SkillPointsDisplay = styled.p`\r\n font-size: 0.6rem !important;\r\n font-weight: bold;\r\n text-align: center;\r\n`;\r\n\r\nconst TitleName = styled.span`\r\n margin-left: 5px;\r\n`;\r\n\r\nconst ValueDisplay = styled.span``;\r\n\r\nconst ProgressIconContainer = styled.div`\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n`;\r\n\r\nconst ProgressBody = styled.div`\r\n display: flex;\r\n flex-direction: row;\r\n width: 100%;\r\n`;\r\n\r\nconst ProgressTitle = styled.div`\r\n width: 100%;\r\n display: flex;\r\n flex-direction: row;\r\n justify-content: space-between;\r\n span {\r\n font-size: 0.6rem;\r\n }\r\n`;\r\n","import { ISkill, ISkillDetails } from '@rpg-engine/shared';\r\nimport _ from 'lodash';\r\nimport React from 'react';\r\nimport styled from 'styled-components';\r\nimport { colors } from '../constants/uiColors';\r\nimport { DraggableContainer } from './DraggableContainer';\r\nimport { SkillProgressBar } from './SkillProgressBar';\r\n\r\nexport interface ISkillContainerProps {\r\n skill: ISkill;\r\n onCloseButton: () => void;\r\n}\r\n\r\nconst skillProps = {\r\n attributes: {\r\n color: colors.cardinal,\r\n values: {\r\n stamina: 'spell-icons/regenerate.png',\r\n magic: 'spell-icons/fireball.png',\r\n magicResistance: 'spell-icons/freeze.png',\r\n strength: 'spell-icons/enchanted-blow.png',\r\n resistance: 'spell-icons/magic-shield.png',\r\n dexterity: 'spell-icons/haste.png',\r\n },\r\n },\r\n combat: {\r\n color: colors.purple,\r\n values: {\r\n first: 'gloves/leather-gloves.png',\r\n club: 'maces/club.png',\r\n sword: 'swords/double-edged-sword.png',\r\n axe: 'axes/double-axe.png',\r\n distance: 'bows/horse-bow.png',\r\n shielding: 'shields/studded-shield.png',\r\n dagger: 'daggers/dagger.png',\r\n },\r\n },\r\n crafting: {\r\n color: colors.blue,\r\n values: {\r\n fishing: 'foods/fish.png',\r\n mining: 'crafting-resources/iron-ingot.png',\r\n lumberjacking: 'crafting-resources/greater-wood-log.png',\r\n cooking: 'foods/chickens-meat.png',\r\n alchemy: 'potions/greater-mana-potion.png',\r\n },\r\n },\r\n};\r\n\r\nexport const SkillsContainer: React.FC<ISkillContainerProps> = ({\r\n onCloseButton,\r\n skill,\r\n}) => {\r\n const onRenderSkillCategory = (\r\n category: 'attributes' | 'combat' | 'crafting'\r\n ) => {\r\n const skillCategory = skillProps[category];\r\n\r\n const skillCategoryColor = skillCategory.color;\r\n\r\n const output = [];\r\n\r\n for (const [key, value] of Object.entries(skillCategory.values)) {\r\n //@ts-ignore\r\n const skillDetails = (skill[key] as unknown) as ISkillDetails;\r\n\r\n output.push(\r\n <SkillProgressBar\r\n key={key}\r\n skillName={_.capitalize(key)}\r\n bgColor={skillCategoryColor}\r\n level={skillDetails.level || 0}\r\n skillPoints={Math.round(skillDetails.skillPoints) || 0}\r\n skillPointsToNextLevel={\r\n Math.round(skillDetails.skillPointsToNextLevel) || 0\r\n }\r\n texturePath={value}\r\n />\r\n );\r\n }\r\n\r\n return output;\r\n };\r\n\r\n return (\r\n <SkillsDraggableContainer title=\"Skills\">\r\n {onCloseButton && (\r\n <CloseButton onClick={onCloseButton} onTouchStart={onCloseButton}>\r\n X\r\n </CloseButton>\r\n )}\r\n <SkillSplitDiv>\r\n <p>General</p>\r\n <hr className=\"golden\" />\r\n\r\n <SkillProgressBar\r\n skillName={'Level'}\r\n bgColor={colors.navyBlue}\r\n level={Math.round(skill.level) || 0}\r\n skillPoints={Math.round(skill.experience) || 0}\r\n skillPointsToNextLevel={Math.round(skill.xpToNextLevel) || 0}\r\n texturePath={'swords/broad-sword.png'}\r\n />\r\n\r\n <p>Combat Skills</p>\r\n <hr className=\"golden\" />\r\n </SkillSplitDiv>\r\n\r\n {onRenderSkillCategory('combat')}\r\n\r\n <SkillSplitDiv>\r\n <p>Crafting Skills</p>\r\n <hr className=\"golden\" />\r\n </SkillSplitDiv>\r\n\r\n {onRenderSkillCategory('crafting')}\r\n\r\n <SkillSplitDiv>\r\n <p>Basic Attributes</p>\r\n <hr className=\"golden\" />\r\n </SkillSplitDiv>\r\n\r\n {onRenderSkillCategory('attributes')}\r\n\r\n {/* <SkillSplitDiv>\r\n <p>Magic Skills</p>\r\n <hr className=\"golden\" />\r\n </SkillSplitDiv>\r\n <SkillProgressBar\r\n skillName={'Ice'}\r\n bgColor={'red'}\r\n level={skill?.ice?.level || 0}\r\n skillPoints={skill?.ice?.skillPoints || 0}\r\n skillPointsToNextLevel={skill?.ice?.skillPointsToNextLevel || 0}\r\n texturePath={'spell-icons/freeze.png'}\r\n />\r\n <SkillProgressBar\r\n skillName={'Earth'}\r\n bgColor={'red'}\r\n level={skill?.earth?.level || 0}\r\n skillPoints={skill?.earth?.skillPoints || 0}\r\n skillPointsToNextLevel={skill?.earth?.skillPointsToNextLevel || 0}\r\n texturePath={'spell-icons/earth-barrier.png'}\r\n />\r\n <SkillProgressBar\r\n skillName={'Air'}\r\n bgColor={'red'}\r\n level={skill?.air?.level || 0}\r\n skillPoints={skill?.air?.skillPoints || 0}\r\n skillPointsToNextLevel={skill?.air?.skillPointsToNextLevel || 0}\r\n texturePath={'spell-icons/poison-tornado.png'}\r\n />\r\n <SkillProgressBar\r\n skillName={'Water'}\r\n bgColor={'red'}\r\n level={skill?.water?.level || 0}\r\n skillPoints={skill?.water?.skillPoints || 0}\r\n skillPointsToNextLevel={skill?.water?.skillPointsToNextLevel || 0}\r\n texturePath={'spell-icons/tsunami.png'}\r\n /> */}\r\n </SkillsDraggableContainer>\r\n );\r\n};\r\n\r\nconst SkillsDraggableContainer = styled(DraggableContainer)`\r\n border: 1px solid black;\r\n width: 400px;\r\n height: 90%;\r\n overflow-y: scroll;\r\n .DraggableContainer__TitleContainer-sc-184mpyl-2 {\r\n width: auto;\r\n height: auto;\r\n }\r\n`;\r\n\r\nconst SkillSplitDiv = styled.div`\r\n width: 100%;\r\n font-size: 11px;\r\n hr {\r\n margin: 0;\r\n margin-bottom: 1rem;\r\n padding: 0px;\r\n }\r\n p {\r\n margin-bottom: 0px;\r\n }\r\n`;\r\n\r\nconst CloseButton = styled.div`\r\n position: absolute;\r\n top: 2px;\r\n right: 2px;\r\n color: white;\r\n z-index: 22;\r\n font-size: 0.7rem;\r\n`;\r\n","/* eslint-disable react/require-default-props */\r\nimport React from 'react';\r\nimport styled from 'styled-components';\r\n\r\ninterface IProps {\r\n maxLines?: number;\r\n children: React.ReactNode;\r\n}\r\n\r\nexport const Truncate: React.FC<IProps> = ({ maxLines = 1, children }) => {\r\n return <Container maxLines={maxLines}>{children}</Container>;\r\n};\r\n\r\ninterface IContainerProps {\r\n maxLines: number;\r\n}\r\n\r\nconst Container = styled.div<IContainerProps>`\r\n display: -webkit-box;\r\n max-width: 100%;\r\n max-height: 100%;\r\n -webkit-line-clamp: ${props => props.maxLines};\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n`;\r\n","import React, { useEffect, useState } from 'react';\r\n\r\nexport interface ICheckItems {\r\n label: string;\r\n value: string;\r\n}\r\n\r\nexport interface ICheckProps {\r\n items: ICheckItems[];\r\n onChange: (selectedValues: IChecklistSelectedValues) => void;\r\n}\r\n\r\ninterface IChecklistSelectedValues {\r\n [label: string]: boolean;\r\n}\r\n\r\nexport const CheckButton: React.FC<ICheckProps> = ({ items, onChange }) => {\r\n const generateSelectedValuesList = () => {\r\n const selectedValues: IChecklistSelectedValues = {};\r\n\r\n items.forEach(item => {\r\n selectedValues[item.label] = false;\r\n });\r\n\r\n return selectedValues;\r\n };\r\n\r\n const [selectedValues, setSelectedValues] = useState<\r\n IChecklistSelectedValues\r\n >(generateSelectedValuesList());\r\n\r\n const handleClick = (label: string) => {\r\n setSelectedValues({\r\n ...selectedValues,\r\n [label]: !selectedValues[label],\r\n });\r\n };\r\n\r\n useEffect(() => {\r\n if (selectedValues) {\r\n onChange(selectedValues);\r\n }\r\n }, [selectedValues]);\r\n\r\n return (\r\n <div id=\"elemento-checkbox\">\r\n {items?.map((element, index) => {\r\n return (\r\n <div key={`${element.label}_${index}`}>\r\n <input\r\n className=\"rpgui-checkbox\"\r\n type=\"checkbox\"\r\n checked={selectedValues[element.label]}\r\n onChange={() => {}}\r\n />\r\n <label onClick={() => handleClick(element.label)}>\r\n {element.label}\r\n </label>\r\n <br />\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n};\r\n","import React, { useEffect, useState } from 'react';\r\nimport { v4 as uuidv4 } from 'uuid';\r\nimport { _RPGUI } from './RPGUIRoot';\r\n\r\nexport interface IOptionsProps {\r\n id: number;\r\n value: string;\r\n option: string;\r\n}\r\n\r\nexport interface IDropdownProps {\r\n options: IOptionsProps[];\r\n width?: string;\r\n onChange: (value: string) => void;\r\n}\r\n\r\nexport const Dropdown: React.FC<IDropdownProps> = ({\r\n options,\r\n width,\r\n onChange,\r\n}) => {\r\n const dropdownId = uuidv4();\r\n\r\n const [selectedValue, setSelectedValue] = useState<string>('');\r\n\r\n useEffect(() => {\r\n const element = document.getElementById(`rpgui-dropdown-${dropdownId}`);\r\n const dropdownValue = _RPGUI.get_value(element);\r\n setSelectedValue(dropdownValue);\r\n\r\n element?.addEventListener('change', (event: any) => {\r\n setSelectedValue(event?.target.value);\r\n });\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (selectedValue) {\r\n onChange(selectedValue);\r\n }\r\n }, [selectedValue]);\r\n\r\n return (\r\n <select\r\n id={`rpgui-dropdown-${dropdownId}`}\r\n style={{ width: width }}\r\n className=\"rpgui-dropdown\"\r\n >\r\n {options.map(option => {\r\n return (\r\n <option key={option.id} value={option.value}>\r\n {option.option}\r\n </option>\r\n );\r\n })}\r\n </select>\r\n );\r\n};\r\n","import React, { useEffect, useState } from 'react';\r\n\r\nexport interface IRadioItems {\r\n label: string;\r\n value: string;\r\n}\r\n\r\nexport interface IRadioProps {\r\n name: string;\r\n items: IRadioItems[];\r\n onChange: (value: string) => void;\r\n}\r\n\r\nexport const InputRadio: React.FC<IRadioProps> = ({\r\n name,\r\n items,\r\n onChange,\r\n}) => {\r\n const [selectedValue, setSelectedValue] = useState<string>();\r\n const handleClick = () => {\r\n let element = document.querySelector(\r\n `input[name=${name}]:checked`\r\n ) as HTMLInputElement;\r\n const elementValue = element.value;\r\n setSelectedValue(elementValue);\r\n };\r\n\r\n useEffect(() => {\r\n if (selectedValue) {\r\n onChange(selectedValue);\r\n }\r\n }, [selectedValue]);\r\n\r\n return (\r\n <div id=\"elemento-radio\">\r\n {items.map(element => {\r\n return (\r\n <>\r\n <input\r\n key={element.value}\r\n className=\"rpgui-radio\"\r\n value={element.value}\r\n name={name}\r\n type=\"radio\"\r\n />\r\n <label onClick={handleClick}>{element.label}</label>\r\n <br />\r\n </>\r\n );\r\n })}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\n\r\nexport interface ITextArea\r\n extends React.DetailedHTMLProps<\r\n React.TextareaHTMLAttributes<HTMLTextAreaElement>,\r\n HTMLTextAreaElement\r\n > {}\r\n\r\nexport const TextArea: React.FC<ITextArea> = ({ ...props }) => {\r\n return <textarea {...props} />;\r\n};\r\n"],"names":["ButtonTypes","RPGUIContainerTypes","Button","disabled","children","buttonType","props","React","ButtonContainer","className","styled","button","displayName","componentId","Input","RPGUIContainer","width","Container","height","type","div","Column","flex","flexWrap","alignItems","justifyContent","CloseButton","CustomInput","CustomContainer","opacity","Form","form","MessageText","p","useOutsideClick","ref","id","useEffect","handleClickOutside","event","current","contains","target","CustomEvent","detail","document","dispatchEvent","addEventListener","removeEventListener","SlotContainerType","DraggableContainer","FramedGold","onCloseButton","title","imgSrc","imgWidth","cancelDrag","onPositionChange","onOutsideClick","draggableRef","useRef","_e","Draggable","cancel","onDrag","data","x","y","TitleContainer","Title","Icon","src","onClick","onTouchStart","h1","img","_RPGUI","RPGUI","ContainerType","RelativeListMenu","options","onSelected","fontSize","style","overflow","map","params","index","ListElement","key","text","li","SpriteFromAtlas","imgScale","grayScale","GRID_WIDTH","GRID_HEIGHT","hasHover","containerStyle","ImgSprite","atlasIMG","frame","atlasJSON","frames","spriteKey","scale","imgStyle","w","h","ItemTooltip","label","NPCDialogType","generateContextList","actionsByTypeList","action","ItemSocketEventsDisplayLabels","EquipmentSlotSpriteByType","Neck","LeftHand","Ring","Head","Torso","Legs","Feet","Inventory","RightHand","Accessory","ItemSlot","observer","itemToRender","slotIndex","item","slotContainerType","slotSpriteMask","onMouseOver","onMouseOut","useState","isTooltipVisible","setTooltipVisible","isContextMenuVisible","setIsContextMenuVisible","contextActions","setContextActions","itemType","INVENTORY","contextActionMenu","ItemType","Weapon","Armor","Jewelry","Tool","ActionsByItemType","Equipment","Consumable","CraftMaterial","Other","Information","Quest","handleItemContainerContextMenuList","EquipmenSetItems","EquipmenSetContainer","handleEquipmentContextMenuList","handleContextMenuList","clientX","clientY","onMouseEnter","onMouseLeave","optionId","name","EQUIPMENT_SET","texturePath","allowedEquipSlotType","_itemToRender$allowed","includes","_id","renderEquipment","quantity","element","push","isStackable","stackQty","ItemQty","left","renderItem","span","EquipmentSetContainer","EquipmentColumn","SlotsContainer","onClose","Framed","ItemsContainer","DynamicText","onFinish","onStart","textState","setTextState","i","interval","setInterval","length","substring","clearInterval","TextContainer","NPCDialogText","onEndStep","onStartStep","textChunks","match","RegExp","chunkIndex","setChunkIndex","onHandleSpacePress","code","prev","useEventListener","handler","el","window","savedHandler","listener","e","QuestionDialog","questions","answers","currentQuestion","setCurrentQuestion","canShowAnswers","setCanShowAnswers","onGetFirstAnswer","answerIds","firstAnswerId","find","answer","currentAnswer","setCurrentAnswer","onGetAnswers","answerId","nextAnswerIndex","findIndex","nextAnswerID","nextAnswer","previousAnswerIndex","previousAnswerID","previousAnswer","pop","nextQuestionId","question","QuestionContainer","AnswersContainer","isSelected","selectedColor","AnswerRow","AnswerSelectedIcon","color","Answer","onAnswerClick","onRenderCurrentAnswers","RangeSliderType","ThumbnailContainer","NPCThumbnail","PressSpaceIndicator","right","ProgressBarText","TextOverlay","minWidth","percentageWidth","Item","LeftArrow","RightArrow","input","SimpleProgressBar","bgColor","margin","ProgressBarContainer","BackgroundBar","Progress","value","SkillProgressBar","skillName","level","skillPoints","showSkillPoints","spForNextLevel","getSPForLevel","ratio","ProgressTitle","TitleName","ValueDisplay","ProgressBody","ProgressIconContainer","SpriteContainer","SkillDisplayContainer","SkillPointsDisplay","skillProps","attributes","values","stamina","magic","magicResistance","strength","resistance","dexterity","combat","first","club","sword","axe","distance","shielding","dagger","crafting","fishing","mining","lumberjacking","cooking","alchemy","SkillsDraggableContainer","SkillSplitDiv","maxLines","chatMessages","onSendChatMessage","message","setMessage","scrollChatToBottom","scrollingElement","querySelector","scrollTop","scrollHeight","FramedGrey","ErrorBoundary","fallback","emitter","createdAt","dayjs","Date","format","onRenderMessageLines","onRenderChatMessages","onSubmit","preventDefault","onChange","autoComplete","RPGUIButton","items","selectedValues","forEach","generateSelectedValuesList","setSelectedValues","checked","dropdownId","uuidv4","selectedValue","setSelectedValue","getElementById","dropdownValue","get_value","option","equipmentSet","onItemClick","equipmentData","neck","leftHand","ring","head","armor","legs","boot","inventory","rightHand","accessory","equipmentMaskSlots","ItemSlotType","onRenderEquipmentSlotRange","start","end","equipmentRange","slice","slotMaksRange","itemContainer","handleClick","slots","slotQty","onRenderSlots","imagePath","isQuestionDialog","showGoNextIndicator","setShowGoNextIndicator","TextAndThumbnail","aliceDefaultThumbnail","TextOnly","max","displayText","calculatePercentageValue","availableProperties","currentIndex","setCurrentIndex","propertiesLength","valueMin","valueMax","sliderId","wasMouseDownFirst","setWasMouseDownFirst","onHandleMouseUp","rpguiSlider","Number","onMouseUp","onMouseDown","Slider","GoldSlider","min","skill","onRenderSkillCategory","category","skillCategory","skillCategoryColor","output","Object","entries","skillDetails","_","capitalize","Math","round","skillPointsToNextLevel","experience","xpToNextLevel"],"mappings":"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"}
1
+ {"version":3,"file":"long-bow.cjs.production.min.js","sources":["../src/components/Button.tsx","../src/components/RPGUIContainer.tsx","../src/components/Input.tsx","../src/components/shared/Column.tsx","../src/components/Chat/Chat.tsx","../src/constants/uiColors.ts","../src/hooks/useOutsideAlerter.ts","../src/components/Item/Inventory/ItemContainerTypes.ts","../src/components/DraggableContainer.tsx","../src/components/RPGUIRoot.tsx","../src/components/Item/Inventory/itemContainerHelper.ts","../src/components/RelativeListMenu.tsx","../src/components/shared/SpriteFromAtlas.tsx","../src/components/Item/Cards/ItemTooltip.tsx","../src/components/NPCDialog/NPCDialog.tsx","../src/components/Item/Inventory/ItemSlot.tsx","../src/components/Equipment/EquipmentSet.tsx","../src/components/Abstractions/SlotsContainer.tsx","../src/components/Item/Inventory/ItemContainer.tsx","../src/components/ListMenu.tsx","../src/components/typography/DynamicText.tsx","../src/components/NPCDialog/NPCDialogText.tsx","../src/libs/StringHelpers.ts","../src/hooks/useEventListener.ts","../src/components/NPCDialog/QuestionDialog/QuestionDialog.tsx","../src/components/RangeSlider.tsx","../src/components/ProgressBar.tsx","../src/components/PropertySelect/PropertySelect.tsx","../src/components/SimpleProgressBar.tsx","../src/components/SkillProgressBar.tsx","../src/components/SkillsContainer.tsx","../src/components/Truncate.tsx","../src/components/CheckButton.tsx","../src/components/Dropdown.tsx","../src/components/RadioButton.tsx","../src/components/TextArea.tsx"],"sourcesContent":["import React from 'react';\nimport styled from 'styled-components';\n\nexport enum ButtonTypes {\n RPGUIButton = 'rpgui-button',\n RPGUIGoldButton = 'rpgui-button golden',\n}\n\nexport interface IButtonProps {\n disabled?: boolean;\n children: React.ReactNode;\n buttonType: ButtonTypes;\n}\n\nexport const Button: React.FC<IButtonProps &\n React.DetailedHTMLProps<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n HTMLButtonElement\n >> = ({ disabled = false, children, buttonType, ...props }) => {\n return (\n <ButtonContainer className={`${buttonType}`} disabled={disabled} {...props}>\n <p>{children}</p>\n </ButtonContainer>\n );\n};\n\nconst ButtonContainer = styled.button<any>`\n height: 45px;\n font-size: 11.5px;\n`;\n","import React from 'react';\nimport styled from 'styled-components';\n\nexport enum RPGUIContainerTypes {\n Framed = 'framed',\n FramedGold = 'framed-golden',\n FramedGold2 = 'framed-golden-2',\n FramedGrey = 'framed-grey',\n}\nexport interface IRPGUIContainerProps {\n type: RPGUIContainerTypes;\n children: React.ReactNode;\n width?: string;\n height?: string;\n className?: string;\n}\n\nexport const RPGUIContainer: React.FC<IRPGUIContainerProps> = ({\n children,\n type,\n width = '50%',\n height,\n className,\n}) => {\n return (\n <Container\n width={width}\n height={height || 'auto'}\n className={`rpgui-container ${type} ${className}`}\n >\n {children}\n </Container>\n );\n};\n\ninterface IContainerProps {\n width: string;\n height: string;\n}\n\nconst Container = styled.div<IContainerProps>`\n height: ${props => props.height};\n width: ${({ width }) => width};\n display: flex;\n flex-wrap: wrap;\n image-rendering: pixelated;\n`;\n","import React from 'react';\n\nexport interface IInputProps\n extends React.DetailedHTMLProps<\n React.InputHTMLAttributes<HTMLInputElement>,\n HTMLInputElement\n > {}\n\nexport const Input: React.FC<IInputProps> = ({ ...props }) => {\n return <input {...props} />;\n};\n","import styled from 'styled-components';\n\ninterface IColumn {\n flex?: number;\n alignItems?: string;\n justifyContent?: string;\n flexWrap?: string;\n}\n\nexport const Column = styled.div<IColumn>`\n flex: ${props => props.flex || 'auto'};\n display: flex;\n flex-wrap: ${props => props.flexWrap || 'nowrap'};\n align-items: ${props => props.alignItems || 'flex-start'};\n justify-content: ${props => props.justifyContent || 'flex-start'};\n`;\n","import { IChatMessage } from '@rpg-engine/shared';\nimport dayjs from 'dayjs';\nimport React, { useEffect, useState } from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\nimport styled from 'styled-components';\nimport { colors } from '../../constants/uiColors';\nimport { Button, ButtonTypes } from '../Button';\nimport { Input } from '../Input';\nimport { RPGUIContainer, RPGUIContainerTypes } from '../RPGUIContainer';\nimport { Column } from '../shared/Column';\n\ninterface IEmitter {\n _id: string;\n name: string;\n}\nexport interface IChatProps {\n chatMessages: IChatMessage[];\n onSendChatMessage: (message: string) => void;\n onCloseButton: () => void;\n opacity?: number;\n width?: string;\n height?: string;\n}\n\nexport const Chat: React.FC<IChatProps> = ({\n chatMessages,\n onSendChatMessage,\n opacity = 1,\n width = '100%',\n height = '250px',\n onCloseButton,\n}) => {\n const [message, setMessage] = useState('');\n\n useEffect(() => {\n scrollChatToBottom();\n }, []);\n\n useEffect(() => {\n scrollChatToBottom();\n }, [chatMessages]);\n\n const scrollChatToBottom = () => {\n const scrollingElement = document.querySelector('.chat-body');\n if (scrollingElement) {\n scrollingElement.scrollTop = scrollingElement.scrollHeight;\n }\n };\n\n const handleSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {\n event.preventDefault();\n onSendChatMessage(message);\n setMessage('');\n };\n const getInputValue = (value: string) => {\n setMessage(value);\n };\n\n const onRenderMessageLines = (\n emitter: IEmitter,\n createdAt: string | undefined,\n message: string\n ) => {\n return `${dayjs(createdAt || new Date()).format('HH:mm')} ${\n emitter?.name ? `${emitter.name}: ` : 'Unknown: '\n } ${message}`;\n };\n\n const onRenderChatMessages = (chatMessages: IChatMessage[]) => {\n return chatMessages?.length ? (\n chatMessages?.map(({ _id, createdAt, emitter, message }, index) => (\n <MessageText key={`${_id}_${index}`}>\n {onRenderMessageLines(emitter, createdAt, message)}\n </MessageText>\n ))\n ) : (\n <MessageText>No messages available.</MessageText>\n );\n };\n\n return (\n <Container>\n <CustomContainer\n type={RPGUIContainerTypes.FramedGrey}\n width={width}\n height={height}\n className=\"chat-container\"\n opacity={opacity}\n >\n <ErrorBoundary fallback={<p>Oops! Your chat has crashed.</p>}>\n {onCloseButton && (\n <CloseButton onClick={onCloseButton} onTouchStart={onCloseButton}>\n X\n </CloseButton>\n )}\n <RPGUIContainer\n type={RPGUIContainerTypes.FramedGrey}\n width={'100%'}\n height={'80%'}\n className=\"chat-body dark-background\"\n >\n {onRenderChatMessages(chatMessages)}\n </RPGUIContainer>\n\n <Form onSubmit={handleSubmit}>\n <Column flex={70}>\n <CustomInput\n value={message}\n id=\"inputMessage\"\n onChange={e => getInputValue(e.target.value)}\n height={20}\n className=\"chat-input dark-background\"\n type=\"text\"\n autoComplete=\"off\"\n />\n </Column>\n <Column justifyContent=\"flex-end\">\n <Button\n buttonType={ButtonTypes.RPGUIButton}\n id=\"chat-send-button\"\n >\n Send\n </Button>\n </Column>\n </Form>\n </ErrorBoundary>\n </CustomContainer>\n </Container>\n );\n};\n\nconst Container = styled.div`\n position: relative;\n`;\n\nconst CloseButton = styled.div`\n position: absolute;\n top: 2px;\n right: 0px;\n color: white;\n z-index: 22;\n font-size: 0.7rem;\n`;\n\nconst CustomInput = styled(Input)`\n height: 30px;\n width: 100%;\n\n .rpgui-content .input {\n min-height: 39px;\n }\n`;\n\ninterface ICustomContainerProps {\n opacity: number;\n}\n\nconst CustomContainer = styled(RPGUIContainer)`\n display: block;\n\n opacity: ${(props: ICustomContainerProps) => props.opacity};\n\n &:hover {\n opacity: 1;\n }\n\n .dark-background {\n background-color: ${colors.darkGrey} !important;\n }\n\n .chat-body {\n &.rpgui-container.framed-grey {\n background: unset;\n }\n max-height: 170px;\n overflow-y: auto;\n }\n`;\n\nconst Form = styled.form`\n display: flex;\n width: 100%;\n justify-content: center;\n align-items: center;\n`;\n\nconst MessageText = styled.p`\n display: block !important;\n width: 100%;\n font-size: 0.7rem !important;\n overflow-y: auto;\n margin: 0;\n`;\n","export const colors = {\n darkGrey: '#3e3e3e',\n darkYellow: '#FFC857',\n orange: '#E9724C',\n cardinal: '#C5283D',\n raisinBlack: '#191923',\n navyBlue: '#0E79B2',\n purple: '#8C3D8C',\n blue: '#3772FF',\n};\n","import { useEffect } from 'react';\n\nexport function useOutsideClick(ref: any, id: string) {\n useEffect(() => {\n /**\n * Alert if clicked on outside of element\n */\n function handleClickOutside(event: any) {\n if (ref.current && !ref.current.contains(event.target)) {\n const event = new CustomEvent('clickOutside', {\n detail: {\n id,\n },\n });\n document.dispatchEvent(event);\n }\n }\n // Bind the event listener\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n // Unbind the event listener on clean up\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, [ref]);\n}\n","export enum SlotContainerType {\n INVENTORY = 'Inventory',\n EQUIPMENT_SET = 'EquipmentSet',\n}\n","import React, { useEffect, useRef } from 'react';\nimport Draggable, { DraggableData } from 'react-draggable';\nimport styled from 'styled-components';\nimport { useOutsideClick } from '../hooks/useOutsideAlerter';\nimport { IPosition } from '../types/eventTypes';\nimport { RPGUIContainerTypes } from './RPGUIContainer';\n\nexport interface IDraggableContainerProps {\n children: React.ReactNode;\n width?: string;\n height?: string;\n className?: string;\n type?: RPGUIContainerTypes;\n title?: string;\n imgSrc?: string;\n imgWidth?: string;\n onCloseButton?: () => void;\n cancelDrag?: string;\n onPositionChange?: (position: IPosition) => void;\n onOutsideClick?: () => void;\n}\n\nexport const DraggableContainer: React.FC<IDraggableContainerProps> = ({\n children,\n width = '50%',\n height,\n className,\n type = RPGUIContainerTypes.FramedGold,\n onCloseButton,\n title,\n imgSrc,\n imgWidth = '20px',\n cancelDrag,\n onPositionChange,\n onOutsideClick,\n}) => {\n const draggableRef = useRef(null);\n\n useOutsideClick(draggableRef, 'item-container');\n\n useEffect(() => {\n document.addEventListener('clickOutside', event => {\n const e = event as CustomEvent;\n\n if (e.detail.id === 'item-container') {\n if (onOutsideClick) {\n onOutsideClick();\n }\n }\n });\n\n return () => {\n document.removeEventListener('clickOutside', _e => {});\n };\n }, []);\n\n return (\n <Draggable\n cancel={`.container-close,${cancelDrag}`}\n onDrag={(_e, data: DraggableData) => {\n if (onPositionChange) {\n onPositionChange({\n x: data.x,\n y: data.y,\n });\n }\n }}\n >\n <Container\n ref={draggableRef}\n width={width}\n height={height || 'auto'}\n className={`rpgui-container ${type} ${className}`}\n >\n {title && (\n <TitleContainer className=\"drag-handler\">\n <Title>\n {imgSrc && <Icon src={imgSrc} width={imgWidth} />}\n {title}\n </Title>\n </TitleContainer>\n )}\n {onCloseButton && (\n <CloseButton\n className=\"container-close\"\n onClick={onCloseButton}\n onTouchStart={onCloseButton}\n >\n X\n </CloseButton>\n )}\n\n {children}\n </Container>\n </Draggable>\n );\n};\n\ninterface IContainerProps {\n width: string;\n height: string;\n}\n\nconst Container = styled.div<IContainerProps>`\n height: ${props => props.height};\n width: ${({ width }) => width};\n display: flex;\n flex-wrap: wrap;\n image-rendering: pixelated;\n\n &.rpgui-container {\n padding-top: 1.5rem;\n }\n`;\n\nconst CloseButton = styled.div`\n position: absolute;\n top: 3px;\n right: 0px;\n color: white;\n z-index: 22;\n font-size: 0.8rem;\n`;\n\nconst TitleContainer = styled.div`\n width: 100%;\n height: 100%;\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n`;\n\nconst Title = styled.h1`\n color: white;\n z-index: 22;\n font-size: 0.6rem;\n`;\n\ninterface ICustomIconProps {\n width: string;\n}\n\nconst Icon = styled.img`\n color: white;\n z-index: 22;\n font-size: 10px;\n width: ${(props: ICustomIconProps) => props.width};\n margin-right: 0.5rem;\n`;\n","import React from 'react';\nimport 'rpgui/rpgui.min.css';\nimport 'rpgui/rpgui.min.js';\n\ninterface IProps {\n children: React.ReactNode;\n}\n\n//@ts-ignore\nexport const _RPGUI = RPGUI;\n\nexport const RPGUIRoot: React.FC<IProps> = ({ children }) => {\n return <div className=\"rpgui-content\">{children}</div>;\n};\n","import {\n ActionsByItemType,\n ItemSocketEventsDisplayLabels,\n ItemType\n} from '@rpg-engine/shared';\nimport { SlotContainerType } from './ItemContainerTypes';\n\nexport interface IContextMenuItem {\n id: string;\n text: string;\n}\n\nexport enum ContainerType {\n INVENTORY = 'Inventory',\n EQUIPMENT_SET = 'EquipmentSet',\n}\n\n// TODO: Refactor this file\nconst generateContextList = (actionsByTypeList: any) => {\n const contextMenu: IContextMenuItem[] = actionsByTypeList.map(\n (action: string) => {\n return { id: action, text: ItemSocketEventsDisplayLabels[action] };\n }\n );\n return contextMenu;\n};\n\nexport const handleContextMenuList = (itemType: ItemType, slotContainerType: SlotContainerType | null) => {\n let contextActionMenu: IContextMenuItem[] = [];\n\n switch (itemType) {\n case ItemType.Weapon:\n case ItemType.Armor:\n case ItemType.Accessory:\n case ItemType.Jewelry:\n case ItemType.Tool:\n if (slotContainerType === SlotContainerType.EQUIPMENT_SET) {\n contextActionMenu = generateContextList(ActionsByItemType.EquipmentSetItems);\n } else {\n contextActionMenu = generateContextList(ActionsByItemType.Equipment);\n }\n break;\n case ItemType.Consumable:\n contextActionMenu = generateContextList(ActionsByItemType.Consumable);\n break;\n case ItemType.CraftMaterial:\n contextActionMenu = generateContextList(ActionsByItemType.CraftMaterial);\n break;\n case ItemType.Other:\n case ItemType.Information:\n case ItemType.Quest:\n case ItemType.Container:\n contextActionMenu = generateContextList(ActionsByItemType.Other);\n break;\n default:\n contextActionMenu = generateContextList(ActionsByItemType.Other);\n break;\n }\n return contextActionMenu;\n};\n\nexport const handleEquipmentContextMenuList = (itemType: ItemType) => {\n let contextActionMenu: IContextMenuItem[] = [];\n switch (itemType) {\n case ItemType.Weapon:\n case ItemType.Armor:\n case ItemType.Accessory:\n case ItemType.Jewelry:\n case ItemType.Tool:\n contextActionMenu = generateContextList(\n ActionsByItemType.EquipmentSetItems\n );\n break;\n case ItemType.Container:\n contextActionMenu = generateContextList(\n ActionsByItemType.EquipmentSetContainer\n );\n break;\n default:\n contextActionMenu = generateContextList(\n ActionsByItemType.EquipmentSetItems\n );\n break;\n }\n return contextActionMenu;\n};\n","import React, { useEffect, useRef } from 'react';\nimport styled from 'styled-components';\nimport { useOutsideClick } from '../hooks/useOutsideAlerter';\n\ninterface IListMenuOption {\n id: string;\n text: string;\n}\n\nexport interface IRelativeMenuProps {\n options: IListMenuOption[];\n onSelected: (selectedOptionId: string) => void;\n fontSize?: number;\n onOutsideClick?: () => void;\n}\n\nexport const RelativeListMenu: React.FC<IRelativeMenuProps> = ({\n options,\n onSelected,\n onOutsideClick,\n fontSize = 0.8,\n}) => {\n const ref = useRef(null);\n\n useOutsideClick(ref, 'relative-context-menu');\n\n useEffect(() => {\n document.addEventListener('clickOutside', event => {\n const e = event as CustomEvent;\n\n if (e.detail.id === 'relative-context-menu') {\n if (onOutsideClick) {\n onOutsideClick();\n }\n }\n });\n\n return () => {\n document.removeEventListener('clickOutside', _e => {});\n };\n }, []);\n\n return (\n <Container fontSize={fontSize} ref={ref}>\n <ul className=\"rpgui-list-imp\" style={{ overflow: 'hidden' }}>\n {options.map((params, index) => (\n <ListElement\n key={params?.id || index}\n onClick={() => {\n onSelected(params?.id);\n }}\n >\n {params?.text || 'No text'}\n </ListElement>\n ))}\n </ul>\n </Container>\n );\n};\n\ninterface IContainerProps {\n fontSize?: number;\n}\n\nconst Container = styled.div<IContainerProps>`\n position: absolute;\n top: 1rem;\n left: 4rem;\n\n display: flex;\n flex-direction: column;\n width: 100%;\n justify-content: start;\n align-items: flex-start;\n\n li {\n font-size: ${props => props.fontSize}em;\n }\n`;\n\nconst ListElement = styled.li`\n margin-right: 0.5rem;\n`;\n","import { GRID_HEIGHT, GRID_WIDTH } from '@rpg-engine/shared';\nimport React from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n atlasJSON: any;\n atlasIMG: any;\n spriteKey: string;\n width?: number;\n height?: number;\n grayScale?: boolean;\n opacity?: number;\n onClick?: () => void;\n containerStyle?: any;\n imgStyle?: any;\n imgScale?: number;\n}\n\nexport const SpriteFromAtlas: React.FC<IProps> = ({\n atlasJSON,\n atlasIMG,\n spriteKey,\n width = GRID_WIDTH,\n height = GRID_HEIGHT,\n imgScale = 2,\n imgStyle,\n onClick,\n containerStyle,\n grayScale = false,\n opacity = 1,\n}) => {\n //! 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).\n //!Due to React's limitations, we cannot import it from the public folder directly!\n\n const spriteData = atlasJSON.frames[spriteKey];\n\n return (\n <Container\n width={width}\n height={height}\n hasHover={grayScale}\n onClick={onClick}\n style={containerStyle}\n >\n <ImgSprite\n className=\"sprite-from-atlas-img\"\n atlasIMG={atlasIMG}\n frame={spriteData.frame}\n scale={imgScale}\n grayScale={grayScale}\n opacity={opacity}\n style={imgStyle}\n />\n </Container>\n );\n};\n\ninterface IImgSpriteProps {\n atlasIMG: any;\n frame: {\n x: number;\n y: number;\n w: number;\n h: number;\n };\n scale: number;\n grayScale: boolean;\n opacity: number;\n}\n\ninterface IContainerProps {\n width: number;\n height: number;\n hasHover: boolean;\n}\n\nconst Container = styled.div`\n width: ${(props: IContainerProps) => props.width}px;\n height: ${(props: IContainerProps) => props.height}px;\n ${(props: IContainerProps) =>\n !props.hasHover\n ? `&:hover {\n filter: sepia(100%) saturate(300%) brightness(70%) hue-rotate(180deg);\n }`\n : ``}\n`;\n\nconst ImgSprite = styled.div<IImgSpriteProps>`\n width: ${props => props.frame.w}px;\n height: ${props => props.frame.h}px;\n background-image: url(${props => props.atlasIMG});\n background-position: -${props => props.frame.x}px -${props => props.frame.y}px;\n transform: scale(${props => props.scale});\n position: relative;\n top: 8px;\n left: 8px;\n filter: ${props => (props.grayScale ? 'grayscale(100%)' : 'none')};\n opacity: ${props => props.opacity};\n`;\n","import React from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n label: string;\n}\n\nexport const ItemTooltip: React.FC<IProps> = ({ label }) => {\n return (\n <Container>\n <div>{label}</div>\n </Container>\n );\n};\n\nconst Container = styled.div`\n z-index: 2;\n position: absolute;\n top: 1rem;\n left: 4rem;\n\n font-size: 0.5rem;\n color: white;\n background-color: black;\n border-radius: 5px;\n padding: 0.5rem;\n min-width: 20px;\n width: 100%;\n text-align: center;\n\n opacity: 0.75;\n`;\n","import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { RPGUIContainer, RPGUIContainerTypes } from '../RPGUIContainer';\nimport aliceDefaultThumbnail from './img/npcDialog/npcThumbnails/alice.png';\nimport pressSpaceGif from './img/space.gif';\nimport { NPCDialogText } from './NPCDialogText';\nimport {\n IQuestionDialog,\n IQuestionDialogAnswer,\n QuestionDialog,\n} from './QuestionDialog/QuestionDialog';\n\nexport enum NPCDialogType {\n TextOnly = 'TextOnly',\n TextAndThumbnail = 'TextAndThumbnail',\n}\n\nexport interface INPCDialogProps {\n text?: string;\n type: NPCDialogType;\n imagePath?: string;\n onClose?: () => void;\n isQuestionDialog?: boolean;\n answers?: IQuestionDialogAnswer[];\n questions?: IQuestionDialog[];\n}\n\nexport const NPCDialog: React.FC<INPCDialogProps> = ({\n text,\n type,\n onClose,\n imagePath,\n isQuestionDialog = false,\n questions,\n answers,\n}) => {\n const [showGoNextIndicator, setShowGoNextIndicator] = useState<boolean>(\n false\n );\n\n return (\n <RPGUIContainer\n type={RPGUIContainerTypes.FramedGold}\n width={isQuestionDialog ? '600px' : '50%'}\n height={'180px'}\n >\n {isQuestionDialog && questions && answers ? (\n <>\n <TextContainer\n flex={type === NPCDialogType.TextAndThumbnail ? '70%' : '100%'}\n >\n <QuestionDialog\n questions={questions}\n answers={answers}\n onClose={() => {\n if (onClose) {\n onClose();\n }\n }}\n />\n </TextContainer>\n {type === NPCDialogType.TextAndThumbnail && (\n <ThumbnailContainer>\n <NPCThumbnail src={imagePath || aliceDefaultThumbnail} />\n </ThumbnailContainer>\n )}\n </>\n ) : (\n <>\n <Container>\n <TextContainer\n flex={type === NPCDialogType.TextAndThumbnail ? '70%' : '100%'}\n >\n <NPCDialogText\n onStartStep={() => setShowGoNextIndicator(false)}\n onEndStep={() => setShowGoNextIndicator(true)}\n text={text || 'No text provided.'}\n onClose={() => {\n if (onClose) {\n onClose();\n }\n }}\n />\n </TextContainer>\n {type === NPCDialogType.TextAndThumbnail && (\n <ThumbnailContainer>\n <NPCThumbnail src={imagePath || aliceDefaultThumbnail} />\n </ThumbnailContainer>\n )}\n </Container>\n {showGoNextIndicator && (\n <PressSpaceIndicator\n right={type === NPCDialogType.TextOnly ? '1rem' : '10.5rem'}\n src={pressSpaceGif}\n />\n )}\n </>\n )}\n </RPGUIContainer>\n );\n};\n\nconst Container = styled.div`\n display: flex;\n width: 100%;\n height: 100%;\n\n box-sizing: border-box;\n justify-content: center;\n align-items: flex-start;\n position: relative;\n`;\n\ninterface ITextContainerProps {\n flex: string;\n}\n\nconst TextContainer = styled.div<ITextContainerProps>`\n flex: ${({ flex }) => flex} 0 0;\n width: 355px;\n`;\n\nconst ThumbnailContainer = styled.div`\n flex: 30% 0 0;\n display: flex;\n justify-content: flex-end;\n`;\n\nconst NPCThumbnail = styled.img`\n image-rendering: pixelated;\n height: 128px;\n width: 128px;\n`;\n\ninterface IPressSpaceIndicatorProps {\n right: string;\n}\n\nconst PressSpaceIndicator = styled.img<IPressSpaceIndicatorProps>`\n position: absolute;\n right: ${({ right }) => right};\n bottom: 1rem;\n height: 20.7px;\n image-rendering: -webkit-optimize-contrast;\n`;\n","import { IItem, IItemContainer, ItemSlotType } from '@rpg-engine/shared';\n\nimport { observer } from 'mobx-react-lite';\nimport React, { useEffect, useState } from 'react';\nimport styled from 'styled-components';\nimport atlasJSON from '../../../mocks/atlas/items/items.json';\nimport atlasIMG from '../../../mocks/atlas/items/items.png';\nimport { RelativeListMenu } from '../../RelativeListMenu';\nimport { SpriteFromAtlas } from '../../shared/SpriteFromAtlas';\nimport { ItemTooltip } from '../Cards/ItemTooltip';\nimport { handleContextMenuList, IContextMenuItem } from './itemContainerHelper';\nimport { SlotContainerType } from './ItemContainerTypes';\n\nconst EquipmentSlotSpriteByType: any = {\n Neck: 'accessories/corruption-necklace.png',\n LeftHand: 'swords/broad-sword.png',\n Ring: 'rings/iron-ring.png',\n Head: 'helmets/viking-helmet.png',\n Torso: 'armors/iron-armor.png',\n Legs: 'legs/studded-legs.png',\n Feet: 'boots/iron-boots.png',\n Inventory: 'containers/bag.png',\n RightHand: 'shields/plate-shield.png',\n Accessory: 'gloves/plate-gloves.png',\n};\n\ninterface IProps {\n slotIndex: number;\n item: IItem | null;\n itemContainer?: IItemContainer | null;\n slotContainerType: SlotContainerType | null;\n slotSpriteMask?: ItemSlotType | null;\n onSelected: (selectedOption: string, item: IItem) => void;\n onMouseOver: (\n event: any,\n slotIndex: number,\n item: IItem | null,\n x: number,\n y: number\n ) => void;\n onMouseOut?: () => void;\n onClick: (item: IItem, slotContainerType: SlotContainerType | null) => void;\n}\n\nexport const ItemSlot: React.FC<IProps> = observer(\n ({\n slotIndex,\n item,\n slotContainerType,\n slotSpriteMask,\n onMouseOver,\n onMouseOut,\n onClick,\n onSelected,\n }) => {\n const [isTooltipVisible, setTooltipVisible] = useState(false);\n\n const [isContextMenuVisible, setIsContextMenuVisible] = useState(false);\n\n const [contextActions, setContextActions] = useState<IContextMenuItem[]>(\n []\n );\n\n useEffect(() => {\n if (item) {\n setContextActions(handleContextMenuList(item.type, slotContainerType));\n }\n }, [item]);\n\n const getLeftPositionValue = (quantity: number) => {\n if (quantity > 0 && quantity < 10) return '2.5rem';\n else if (quantity > 9 && quantity < 100) return '2.0rem';\n else if (quantity > 99) return '1rem';\n return '2.5rem';\n };\n\n const renderItem = (itemToRender: IItem | null) => {\n const element = [];\n if (itemToRender?.texturePath) {\n element.push(\n <SpriteFromAtlas\n key={itemToRender._id}\n atlasIMG={atlasIMG}\n atlasJSON={atlasJSON}\n spriteKey={itemToRender.texturePath}\n imgScale={3}\n />\n );\n }\n if (itemToRender?.isStackable && itemToRender?.stackQty) {\n element.push(\n <ItemQty\n left={getLeftPositionValue(itemToRender.stackQty)}\n key={`qty-${itemToRender._id}`}\n >\n {' '}\n {itemToRender.stackQty}{' '}\n </ItemQty>\n );\n }\n return element;\n };\n\n const renderEquipment = (itemToRender: IItem | null) => {\n if (\n itemToRender?.texturePath &&\n itemToRender.allowedEquipSlotType?.includes(slotSpriteMask!)\n ) {\n return (\n <SpriteFromAtlas\n key={itemToRender._id}\n atlasIMG={atlasIMG}\n atlasJSON={atlasJSON}\n spriteKey={itemToRender.texturePath}\n imgScale={3}\n />\n );\n } else {\n return (\n <SpriteFromAtlas\n atlasIMG={atlasIMG}\n atlasJSON={atlasJSON}\n spriteKey={EquipmentSlotSpriteByType[slotSpriteMask!]}\n imgScale={3}\n grayScale={true}\n opacity={0.4}\n />\n );\n }\n };\n\n const onRenderSlot = (itemToRender: IItem | null) => {\n if (slotContainerType === SlotContainerType.EQUIPMENT_SET)\n return renderEquipment(itemToRender);\n return renderItem(itemToRender);\n };\n\n return (\n <Container\n className=\"rpgui-icon empty-slot\"\n onMouseOver={event =>\n onMouseOver(event, slotIndex, item, event.clientX, event.clientY)\n }\n onMouseOut={() => {\n if (onMouseOut) onMouseOut();\n }}\n onMouseEnter={() => setTooltipVisible(true)}\n onMouseLeave={() => setTooltipVisible(false)}\n onClick={() => {\n setTooltipVisible(false);\n\n if (item) {\n setIsContextMenuVisible(!isContextMenuVisible);\n onClick(item, slotContainerType);\n }\n }}\n >\n {isContextMenuVisible && contextActions && (\n <RelativeListMenu\n options={contextActions}\n onSelected={(optionId: string) => {\n setIsContextMenuVisible(false);\n if (item) {\n onSelected(optionId, item);\n }\n }}\n onOutsideClick={() => {\n setIsContextMenuVisible(false);\n }}\n />\n )}\n\n {isTooltipVisible && item && <ItemTooltip label={item.name} />}\n\n {onRenderSlot(item)}\n </Container>\n );\n }\n);\n\nconst Container = styled.div`\n margin: 0.1rem;\n .sprite-from-atlas-img {\n position: relative;\n top: 1.5rem;\n left: 1.5rem;\n }\n position: relative;\n`;\n\ninterface IItemQtyProps {\n left: string;\n}\nconst ItemQty = styled.span<IItemQtyProps>`\n position: relative;\n top: 1.5rem;\n left: ${props => props.left};\n`;\n","import {\n IEquipmentSet,\n IItem,\n IItemContainer,\n ItemSlotType,\n} from '@rpg-engine/shared';\nimport React from 'react';\nimport styled from 'styled-components';\nimport { DraggableContainer } from '../DraggableContainer';\nimport { SlotContainerType } from '../Item/Inventory/ItemContainerTypes';\nimport { ItemSlot } from '../Item/Inventory/ItemSlot';\nimport { RPGUIContainerTypes } from '../RPGUIContainer';\n\nexport interface IEquipmentSetProps {\n equipmentSet: IEquipmentSet;\n onClose?: () => void;\n onItemClick?: (\n item: IItem,\n slotContainerType: SlotContainerType | null\n ) => void;\n onMouseOver?: (e: any, slotIndex: number, item: IItem | null) => void;\n onSelected?: (optionId: string) => void;\n initialPosition?: { x: number; y: number };\n}\n\nexport const EquipmentSet: React.FC<IEquipmentSetProps> = ({\n equipmentSet,\n onClose,\n onMouseOver,\n onSelected,\n onItemClick,\n}) => {\n const {\n neck,\n leftHand,\n ring,\n head,\n armor,\n legs,\n boot,\n inventory,\n rightHand,\n accessory,\n } = equipmentSet;\n\n const equipmentData = [\n neck,\n leftHand,\n ring,\n head,\n armor,\n legs,\n boot,\n inventory,\n rightHand,\n accessory,\n ];\n\n const equipmentMaskSlots = [\n ItemSlotType.Neck,\n ItemSlotType.LeftHand,\n ItemSlotType.Ring,\n ItemSlotType.Head,\n ItemSlotType.Torso,\n ItemSlotType.Legs,\n ItemSlotType.Feet,\n ItemSlotType.Inventory,\n ItemSlotType.RightHand,\n ItemSlotType.Accessory,\n ];\n\n const onRenderEquipmentSlotRange = (start: number, end: number) => {\n const equipmentRange = equipmentData.slice(start, end);\n const slotMaksRange = equipmentMaskSlots.slice(start, end);\n\n return equipmentRange.map((data, i) => {\n const item = data as IItem;\n const itemContainer =\n (item && (item.itemContainer as IItemContainer)) ?? null;\n return (\n <ItemSlot\n key={i}\n slotIndex={i}\n item={item}\n itemContainer={itemContainer}\n slotContainerType={SlotContainerType.EQUIPMENT_SET}\n slotSpriteMask={slotMaksRange[i]}\n onMouseOver={(event, slotIndex, item) => {\n if (onMouseOver) onMouseOver(event, slotIndex, item);\n }}\n onClick={(item, slotContainerType) => {\n if (onItemClick) onItemClick(item, slotContainerType);\n }}\n onSelected={(optionId: string) => {\n if (onSelected) onSelected(optionId);\n }}\n />\n );\n });\n };\n\n return (\n <DraggableContainer\n title={'Equipments'}\n type={RPGUIContainerTypes.Framed}\n onCloseButton={() => {\n if (onClose) onClose();\n }}\n width=\"330px\"\n cancelDrag=\".equipment-container-body\"\n >\n <EquipmentSetContainer className=\"equipment-container-body\">\n <EquipmentColumn>{onRenderEquipmentSlotRange(0, 3)}</EquipmentColumn>\n <EquipmentColumn>{onRenderEquipmentSlotRange(3, 7)}</EquipmentColumn>\n <EquipmentColumn>{onRenderEquipmentSlotRange(7, 10)}</EquipmentColumn>\n </EquipmentSetContainer>\n </DraggableContainer>\n );\n};\n\nconst EquipmentSetContainer = styled.div`\n width: inherit;\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n flex-direction: row;\n`;\n\nconst EquipmentColumn = styled.div`\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n flex-direction: column;\n`;\n","import React from 'react';\nimport { IPosition } from '../../types/eventTypes';\nimport { DraggableContainer } from '../DraggableContainer';\nimport { RPGUIContainerTypes } from '../RPGUIContainer';\n\ninterface IProps {\n children: React.ReactNode;\n title: string;\n onClose?: () => void;\n onPositionChange?: (position: IPosition) => void;\n onOutsideClick?: () => void;\n}\n\nexport const SlotsContainer: React.FC<IProps> = ({\n children,\n title,\n onClose,\n onPositionChange,\n onOutsideClick,\n}) => {\n return (\n <DraggableContainer\n title={title}\n type={RPGUIContainerTypes.Framed}\n onCloseButton={() => {\n if (onClose) {\n onClose();\n }\n }}\n width=\"330px\"\n cancelDrag=\".item-container-body\"\n onPositionChange={({ x, y }) => {\n if (onPositionChange) {\n onPositionChange({ x, y });\n }\n }}\n onOutsideClick={onOutsideClick}\n >\n {children}\n </DraggableContainer>\n );\n};\n","import { IItem, IItemContainer } from '@rpg-engine/shared';\nimport React from 'react';\nimport styled from 'styled-components';\nimport { SlotsContainer } from '../../Abstractions/SlotsContainer';\nimport { SlotContainerType } from './ItemContainerTypes';\nimport { ItemSlot } from './ItemSlot';\n\nexport interface IItemContainerProps {\n itemContainer: IItemContainer;\n onClose?: () => void;\n onItemClick?: (\n item: IItem,\n slotContainerType: SlotContainerType | null\n ) => void;\n onMouseOver?: (e: any, slotIndex: number, item: IItem | null) => void;\n onSelected?: (optionId: string, item: IItem) => void;\n}\n\nexport const ItemContainer: React.FC<IItemContainerProps> = ({\n itemContainer,\n onClose,\n onMouseOver,\n onSelected,\n onItemClick,\n}) => {\n const onRenderSlots = () => {\n const slots = [];\n\n for (let i = 0; i < itemContainer.slotQty; i++) {\n slots.push(\n <ItemSlot\n key={i}\n slotIndex={i}\n item={itemContainer.slots?.[i] || null}\n slotContainerType={SlotContainerType.INVENTORY}\n onMouseOver={(event, slotIndex, item) => {\n if (onMouseOver) onMouseOver(event, slotIndex, item);\n }}\n onClick={(item, slotContainerType) => {\n if (onItemClick) onItemClick(item, slotContainerType);\n }}\n onSelected={(optionId: string, item: IItem) => {\n if (onSelected) onSelected(optionId, item);\n }}\n />\n );\n }\n return slots;\n };\n\n return (\n <SlotsContainer title={itemContainer.name || 'Container'} onClose={onClose}>\n <ItemsContainer className=\"item-container-body\">\n {onRenderSlots()}\n </ItemsContainer>\n </SlotsContainer>\n );\n};\n\nconst ItemsContainer = styled.div`\n max-width: 280px;\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n`;\n","import React from 'react';\nimport styled from 'styled-components';\n\ninterface IListMenuOption {\n id: string;\n text: string;\n}\n\nexport interface IListMenuProps {\n x: number;\n y: number;\n options: IListMenuOption[];\n onSelected: (selectedOptionId: string) => void;\n fontSize?: number;\n}\n\nexport const ListMenu: React.FC<IListMenuProps> = ({\n options,\n onSelected,\n x,\n y,\n fontSize = 0.8,\n}) => {\n return (\n <Container x={x} y={y} fontSize={fontSize}>\n <ul className=\"rpgui-list-imp\" style={{ overflow: 'hidden' }}>\n {options.map((params, index) => (\n <ListElement\n key={params?.id || index}\n onClick={() => {\n onSelected(params?.id);\n }}\n >\n {params?.text || 'No text'}\n </ListElement>\n ))}\n </ul>\n </Container>\n );\n};\n\ninterface IContainerProps {\n x?: number;\n y?: number;\n fontSize?: number;\n}\n\nconst Container = styled.div<IContainerProps>`\n display: flex;\n flex-direction: column;\n width: 100%;\n justify-content: start;\n align-items: flex-start;\n position: absolute;\n top: ${props => props.y || 0}px;\n left: ${props => props.x || 0}px;\n\n li {\n font-size: ${props => props.fontSize}em;\n }\n`;\n\nconst ListElement = styled.li`\n margin-right: 0.5rem;\n`;\n","import React, { useEffect, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n text: string;\n onFinish?: () => void;\n onStart?: () => void;\n}\n\nexport const DynamicText: React.FC<IProps> = ({ text, onFinish, onStart }) => {\n const [textState, setTextState] = useState<string>('');\n\n useEffect(() => {\n let i = 0;\n const interval = setInterval(() => {\n // on every interval, show one more character\n\n if (i === 0) {\n if (onStart) {\n onStart();\n }\n }\n\n if (i < text.length) {\n setTextState(text.substring(0, i + 1));\n i++;\n } else {\n clearInterval(interval);\n if (onFinish) {\n onFinish();\n }\n }\n }, 50);\n\n return () => {\n clearInterval(interval);\n };\n }, [text]);\n\n return <TextContainer>{textState}</TextContainer>;\n};\n\nconst TextContainer = styled.p`\n font-size: 0.7rem !important;\n color: white;\n text-shadow: 1px 1px 0px #000000;\n letter-spacing: 1.2px;\n word-break: normal;\n`;\n","import React, { useEffect, useState } from 'react';\nimport styled from 'styled-components';\nimport { chunkString } from '../../libs/StringHelpers';\nimport { DynamicText } from '../typography/DynamicText';\n\ninterface IProps {\n text: string;\n onClose: () => void;\n onEndStep: () => void;\n onStartStep: () => void;\n}\n\nexport const NPCDialogText: React.FC<IProps> = ({\n text,\n onClose,\n onEndStep,\n onStartStep,\n}) => {\n const textChunks = chunkString(text, 85);\n\n const [chunkIndex, setChunkIndex] = useState<number>(0);\n\n const onHandleSpacePress = (event: KeyboardEvent) => {\n if (event.code === 'Space') {\n const hasNextChunk = textChunks?.[chunkIndex + 1] || false;\n\n if (hasNextChunk) {\n setChunkIndex(prev => prev + 1);\n } else {\n // if there's no more text chunks, close the dialog\n onClose();\n }\n }\n };\n\n useEffect(() => {\n document.addEventListener('keydown', onHandleSpacePress);\n\n return () => document.removeEventListener('keydown', onHandleSpacePress);\n }, [chunkIndex]);\n\n return (\n <Container>\n <DynamicText\n text={textChunks?.[chunkIndex] || ''}\n onFinish={onEndStep}\n onStart={onStartStep}\n />\n </Container>\n );\n};\n\nconst Container = styled.div``;\n","export const chunkString = (str: string, length: number) => {\n return str.match(new RegExp('.{1,' + length + '}', 'g'));\n};\n","import React from 'react';\n\n//@ts-ignore\nexport const useEventListener = (type, handler, el = window) => {\n const savedHandler = React.useRef();\n\n React.useEffect(() => {\n savedHandler.current = handler;\n }, [handler]);\n\n React.useEffect(() => {\n //@ts-ignore\n const listener = e => savedHandler.current(e);\n\n el.addEventListener(type, listener);\n\n return () => {\n el.removeEventListener(type, listener);\n };\n }, [type, el]);\n};\n","import React, { useEffect, useState } from 'react';\nimport styled from 'styled-components';\nimport { useEventListener } from '../../../hooks/useEventListener';\nimport { DynamicText } from '../../typography/DynamicText';\n\nexport interface IQuestionDialogAnswer {\n id: number;\n text: string;\n nextQuestionId?: number;\n}\n\nexport interface IQuestionDialog {\n id: number;\n text: string;\n answerIds?: number[];\n}\n\nexport interface IProps {\n questions: IQuestionDialog[];\n answers: IQuestionDialogAnswer[];\n onClose: () => void;\n}\n\nexport const QuestionDialog: React.FC<IProps> = ({\n questions,\n answers,\n onClose,\n}) => {\n const [currentQuestion, setCurrentQuestion] = useState(questions[0]);\n\n const [canShowAnswers, setCanShowAnswers] = useState<boolean>(false);\n\n const onGetFirstAnswer = () => {\n if (!currentQuestion.answerIds || currentQuestion.answerIds.length === 0) {\n return null;\n }\n\n const firstAnswerId = currentQuestion.answerIds![0];\n\n return answers.find(answer => answer.id === firstAnswerId);\n };\n\n const [\n currentAnswer,\n setCurrentAnswer,\n ] = useState<IQuestionDialogAnswer | null>(onGetFirstAnswer()!);\n\n useEffect(() => {\n setCurrentAnswer(onGetFirstAnswer()!);\n }, [currentQuestion]);\n\n const onGetAnswers = (answerIds: number[]) => {\n return answerIds.map((answerId: number) =>\n answers.find(answer => answer.id === answerId)\n );\n };\n\n const onKeyPress = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowDown':\n // select next answer, if any.\n // if no next answer, select first answer\n // const nextAnswer = onGetAnswers(currentQuestion.answerIds!).find(\n // (answer) => answer?.id === currentAnswer!.id + 1\n // );\n\n const nextAnswerIndex = onGetAnswers(\n currentQuestion.answerIds!\n ).findIndex(answer => answer?.id === currentAnswer!.id + 1);\n\n const nextAnswerID = currentQuestion.answerIds![nextAnswerIndex];\n\n // console.log(nextAnswerIndex);\n\n const nextAnswer = onGetAnswers(currentQuestion.answerIds!).find(\n answer => answer?.id === nextAnswerID\n );\n\n setCurrentAnswer(nextAnswer || onGetFirstAnswer()!);\n\n break;\n case 'ArrowUp':\n // select previous answer, if any.\n // if no previous answer, select last answer\n\n const previousAnswerIndex = onGetAnswers(\n currentQuestion.answerIds!\n ).findIndex(answer => answer?.id === currentAnswer!.id - 1);\n\n const previousAnswerID =\n currentQuestion.answerIds &&\n currentQuestion.answerIds[previousAnswerIndex];\n\n const previousAnswer = onGetAnswers(currentQuestion.answerIds!).find(\n answer => answer?.id === previousAnswerID\n );\n\n if (previousAnswer) {\n setCurrentAnswer(previousAnswer);\n } else {\n setCurrentAnswer(onGetAnswers(currentQuestion.answerIds!).pop()!);\n }\n\n break;\n case 'Enter':\n setCanShowAnswers(false);\n\n if (!currentAnswer?.nextQuestionId) {\n onClose();\n return;\n } else {\n setCurrentQuestion(\n questions.find(\n question => question.id === currentAnswer!.nextQuestionId\n )!\n );\n }\n\n break;\n }\n };\n useEventListener('keydown', onKeyPress);\n\n const onAnswerClick = (answer: IQuestionDialogAnswer) => {\n setCanShowAnswers(false);\n if (answer.nextQuestionId) {\n // if there is a next question, go to it\n setCurrentQuestion(\n questions.find(question => question.id === answer.nextQuestionId)!\n );\n } else {\n // else, finish dialog!\n onClose();\n }\n };\n\n const onRenderCurrentAnswers = () => {\n const answerIds = currentQuestion.answerIds;\n if (!answerIds) {\n return null;\n }\n\n const answers = onGetAnswers(answerIds);\n\n if (!answers) {\n return null;\n }\n\n return answers.map(answer => {\n const isSelected = currentAnswer?.id === answer?.id;\n const selectedColor = isSelected ? 'yellow' : 'white';\n\n if (answer) {\n return (\n <AnswerRow key={`answer_${answer.id}`}>\n <AnswerSelectedIcon color={selectedColor}>\n {isSelected ? 'X' : null}\n </AnswerSelectedIcon>\n\n <Answer\n key={answer.id}\n onClick={() => onAnswerClick(answer)}\n color={selectedColor}\n >\n {answer.text}\n </Answer>\n </AnswerRow>\n );\n }\n\n return null;\n });\n };\n\n return (\n <Container>\n <QuestionContainer>\n <DynamicText\n text={currentQuestion.text}\n onStart={() => setCanShowAnswers(false)}\n onFinish={() => setCanShowAnswers(true)}\n />\n </QuestionContainer>\n\n {canShowAnswers && (\n <AnswersContainer>{onRenderCurrentAnswers()}</AnswersContainer>\n )}\n </Container>\n );\n};\n\nconst Container = styled.div`\n display: flex;\n word-break: break-all;\n box-sizing: border-box;\n justify-content: flex-start;\n align-items: flex-start;\n flex-wrap: wrap;\n`;\n\nconst QuestionContainer = styled.div`\n flex: 100%;\n width: 100%;\n`;\n\nconst AnswersContainer = styled.div`\n flex: 100%;\n`;\n\ninterface IAnswerProps {\n color: string;\n}\n\nconst Answer = styled.p<IAnswerProps>`\n flex: auto;\n color: ${props => props.color} !important;\n font-size: 0.65rem !important;\n background: inherit;\n border: none;\n`;\n\nconst AnswerSelectedIcon = styled.span<IAnswerProps>`\n flex: 5% 0 0;\n color: ${props => props.color} !important;\n`;\n\nconst AnswerRow = styled.div`\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n align-items: center;\n margin-bottom: 0.5rem;\n height: 22px;\n p {\n line-height: unset;\n margin-top: 0;\n margin-bottom: 0rem;\n }\n`;\n","import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { v4 as uuidv4 } from 'uuid';\nimport { useEventListener } from '../hooks/useEventListener';\nimport { _RPGUI } from './RPGUIRoot';\n\nexport enum RangeSliderType {\n Slider = 'rpgui-slider',\n GoldSlider = 'rpgui-slider golden',\n}\n\nexport interface IRangeSliderProps {\n type: RangeSliderType;\n valueMin: number;\n valueMax: number;\n width: string;\n onChange: (value: number) => void;\n}\n\nexport const RangeSlider: React.FC<IRangeSliderProps> = ({\n type,\n valueMin,\n valueMax,\n width,\n onChange,\n}) => {\n const sliderId = uuidv4();\n\n const [wasMouseDownFirst, setWasMouseDownFirst] = useState<boolean>(false);\n\n useEventListener('mouseup', () => {\n if (wasMouseDownFirst) {\n onHandleMouseUp();\n }\n setWasMouseDownFirst(false);\n });\n\n const onHandleMouseUp = () => {\n const rpguiSlider = document.getElementById(`rpgui-slider-${sliderId}`);\n const value = _RPGUI.get_value(rpguiSlider);\n\n onChange(Number(value));\n };\n\n return (\n <div\n onMouseUp={onHandleMouseUp}\n onMouseDown={() => setWasMouseDownFirst(true)}\n >\n <Input\n className={\n type === RangeSliderType.Slider\n ? RangeSliderType.Slider\n : RangeSliderType.GoldSlider\n }\n type=\"range\"\n style={{ width: width }}\n min={valueMin}\n max={valueMax}\n id={`rpgui-slider-${sliderId}`}\n />\n </div>\n );\n};\n\nconst Input = styled.input`\n opacity: 0;\n`;\n","import React from 'react';\nimport styled from 'styled-components';\n\nexport interface IBarProps {\n max: number;\n value: number;\n color: 'red' | 'blue' | 'green';\n style?: Record<string, any>;\n displayText?: boolean;\n percentageWidth?: number;\n minWidth?: number;\n}\n\nexport const ProgressBar: React.FC<IBarProps> = ({\n max,\n value,\n color,\n displayText = true,\n percentageWidth = 40,\n minWidth = 100,\n style,\n}) => {\n const calculatePercentageValue = function(max: number, value: number) {\n if (value > max) {\n value = max;\n }\n return (value * 100) / max;\n };\n\n return (\n <Container\n className=\"rpgui-progress\"\n data-value={calculatePercentageValue(max, value) / 100}\n data-rpguitype=\"progress\"\n percentageWidth={percentageWidth}\n minWidth={minWidth}\n style={style}\n >\n {displayText && (\n <TextOverlay>\n <ProgressBarText>\n {value}/{max}\n </ProgressBarText>\n </TextOverlay>\n )}\n <div className=\" rpgui-progress-track\">\n <div\n className={`rpgui-progress-fill ${color} `}\n style={{\n left: '0px',\n width: calculatePercentageValue(max, value) + '%',\n }}\n ></div>\n </div>\n <div className=\" rpgui-progress-left-edge\"></div>\n <div className=\" rpgui-progress-right-edge\"></div>\n </Container>\n );\n};\n\nconst ProgressBarText = styled.span`\n font-size: 1rem;\n color: white;\n text-align: center;\n z-index: 1;\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n top: 12px;\n`;\n\nconst TextOverlay = styled.div`\n width: 100%;\n position: relative;\n`;\n\ninterface IContainerProps {\n percentageWidth?: number;\n minWidth?: number;\n style?: Record<string, any>;\n}\n\nconst Container = styled.div<IContainerProps>`\n display: flex;\n flex-direction: column;\n min-width: ${props => props.minWidth}px;\n width: ${props => props.percentageWidth}%;\n justify-content: start;\n align-items: flex-start;\n ${props => props.style}\n`;\n","import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport LeftArrowClickIcon from './img/ui-arrows/arrow01-left-clicked.png';\nimport LeftArrowIcon from './img/ui-arrows/arrow01-left.png';\nimport RightArrowClickIcon from './img/ui-arrows/arrow01-right-clicked.png';\nimport RightArrowIcon from './img/ui-arrows/arrow01-right.png';\n\nexport interface IPropertySelectProps {\n availableProperties: Array<IPropertiesProps>;\n selectedProperty: object;\n children?: React.ReactNode;\n}\n\nexport interface IPropertiesProps {\n id: string;\n name: string;\n}\n\nexport const PropertySelect: React.FC<IPropertySelectProps> = ({\n availableProperties,\n}) => {\n const [currentIndex, setCurrentIndex] = useState(0);\n const propertiesLength = availableProperties.length - 1;\n\n const onLeftClick = () => {\n if (currentIndex === 0) setCurrentIndex(propertiesLength);\n else setCurrentIndex(index => index - 1);\n };\n const onRightClick = () => {\n if (currentIndex === propertiesLength) setCurrentIndex(0);\n else setCurrentIndex(index => index + 1);\n };\n return (\n <Container>\n <TextOverlay>\n <Item>{availableProperties[currentIndex].name}</Item>\n </TextOverlay>\n <div className=\"rpgui-progress-track\"></div>\n <LeftArrow onClick={onLeftClick}></LeftArrow>\n <RightArrow onClick={onRightClick}></RightArrow>\n </Container>\n );\n};\n\nconst Item = styled.span`\n font-size: 1rem;\n color: white;\n text-align: center;\n z-index: 1;\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n top: 12px;\n`;\n\nconst TextOverlay = styled.div`\n width: 100%;\n position: relative;\n`;\n\ninterface IContainerProps {\n percentageWidth?: number;\n minWidth?: number;\n style?: Record<string, any>;\n}\n\nconst Container = styled.div<IContainerProps>`\n position: relative;\n display: flex;\n flex-direction: column;\n justify-content: start;\n align-items: flex-start;\n min-width: 100px;\n width: 40%;\n`;\n\nconst LeftArrow = styled.div`\n background-image: url(${LeftArrowIcon});\n background-size: 100% 100%;\n left: 0;\n position: absolute;\n width: 40px;\n height: 42px;\n :active {\n background-image: url(${LeftArrowClickIcon});\n }\n`;\n\nconst RightArrow = styled.div`\n background-image: url(${RightArrowIcon});\n right: 0;\n position: absolute;\n width: 40px;\n background-size: 100% 100%;\n height: 42px;\n :active {\n background-image: url(${RightArrowClickIcon});\n }\n`;\n\nexport default PropertySelect;\n","import React from 'react';\nimport styled from 'styled-components';\n\nexport interface ISimpleProgressBarProps {\n value: number;\n bgColor?: string;\n margin?: number;\n}\n\nexport const SimpleProgressBar: React.FC<ISimpleProgressBarProps> = ({\n value,\n bgColor = 'red',\n margin = 20,\n}) => {\n return (\n <Container className=\"simple-progress-bar\">\n <ProgressBarContainer margin={margin}>\n <BackgroundBar>\n <Progress value={value} bgColor={bgColor} />\n </BackgroundBar>\n </ProgressBarContainer>\n </Container>\n );\n};\n\nconst Container = styled.div`\n display: flex;\n justify-content: center;\n align-items: center;\n width: 100%;\n`;\n\nconst BackgroundBar = styled.span`\n background-color: rgba(0, 0, 0, 0.075);\n`;\n\ninterface ISimpleProgressBarThemeProps {\n value: number;\n bgColor: string;\n}\n\nconst Progress = styled.span`\n background-color: ${(props: ISimpleProgressBarThemeProps) => props.bgColor};\n width: ${(props: ISimpleProgressBarThemeProps) => props.value}%;\n`;\n\ninterface ISimpleProgressBarTheme2Props {\n margin: number;\n}\n\nconst ProgressBarContainer = styled.div`\n border-radius: 60px;\n border: 1px solid #282424;\n overflow: hidden;\n width: 100%;\n span {\n display: block;\n height: 100%;\n }\n height: 8px;\n margin-left: ${(props: ISimpleProgressBarTheme2Props) => props.margin}px;\n`;\n","import { getSPForLevel } from '@rpg-engine/shared';\nimport React from 'react';\nimport styled from 'styled-components';\nimport atlasJSON from '../mocks/atlas/items/items.json';\nimport atlasIMG from '../mocks/atlas/items/items.png';\nimport { SpriteFromAtlas } from './shared/SpriteFromAtlas';\nimport { SimpleProgressBar } from './SimpleProgressBar';\n\nexport interface ISkillProgressBarProps {\n skillName: string;\n bgColor: string;\n level: number;\n skillPoints: number;\n skillPointsToNextLevel?: number;\n texturePath: string;\n showSkillPoints?: boolean;\n}\n\nexport const SkillProgressBar: React.FC<ISkillProgressBarProps> = ({\n bgColor,\n skillName,\n level,\n skillPoints,\n texturePath,\n showSkillPoints = true,\n}) => {\n const spForNextLevel = getSPForLevel(level + 1);\n\n const ratio = (skillPoints / spForNextLevel) * 100;\n\n return (\n <>\n <ProgressTitle>\n <TitleName>{skillName}</TitleName>\n <ValueDisplay>lv {level}</ValueDisplay>\n </ProgressTitle>\n <ProgressBody>\n <ProgressIconContainer>\n {atlasIMG && atlasJSON ? (\n <SpriteContainer>\n <SpriteFromAtlas\n atlasIMG={atlasIMG}\n atlasJSON={atlasJSON}\n spriteKey={texturePath}\n imgScale={1}\n grayScale\n opacity={0.5}\n />\n </SpriteContainer>\n ) : (\n <></>\n )}\n </ProgressIconContainer>\n\n <ProgressBarContainer>\n <SimpleProgressBar value={ratio} bgColor={bgColor} />\n </ProgressBarContainer>\n </ProgressBody>\n {showSkillPoints && (\n <SkillDisplayContainer>\n <SkillPointsDisplay>\n {skillPoints}/{spForNextLevel}\n </SkillPointsDisplay>\n </SkillDisplayContainer>\n )}\n </>\n );\n};\n\nconst ProgressBarContainer = styled.div`\n position: relative;\n top: 8px;\n width: 100%;\n height: auto;\n`;\n\nconst SpriteContainer = styled.div`\n position: relative;\n top: -3px;\n left: 0;\n`;\n\nconst SkillDisplayContainer = styled.div`\n margin: 0 auto;\n\n p {\n margin: 0;\n }\n`;\n\nconst SkillPointsDisplay = styled.p`\n font-size: 0.6rem !important;\n font-weight: bold;\n text-align: center;\n`;\n\nconst TitleName = styled.span`\n margin-left: 5px;\n`;\n\nconst ValueDisplay = styled.span``;\n\nconst ProgressIconContainer = styled.div`\n display: flex;\n justify-content: center;\n align-items: center;\n`;\n\nconst ProgressBody = styled.div`\n display: flex;\n flex-direction: row;\n width: 100%;\n`;\n\nconst ProgressTitle = styled.div`\n width: 100%;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n span {\n font-size: 0.6rem;\n }\n`;\n","import { ISkill, ISkillDetails } from '@rpg-engine/shared';\nimport _ from 'lodash';\nimport React from 'react';\nimport styled from 'styled-components';\nimport { colors } from '../constants/uiColors';\nimport { DraggableContainer } from './DraggableContainer';\nimport { SkillProgressBar } from './SkillProgressBar';\n\nexport interface ISkillContainerProps {\n skill: ISkill;\n onCloseButton: () => void;\n}\n\nconst skillProps = {\n attributes: {\n color: colors.cardinal,\n values: {\n stamina: 'spell-icons/regenerate.png',\n magic: 'spell-icons/fireball.png',\n magicResistance: 'spell-icons/freeze.png',\n strength: 'spell-icons/enchanted-blow.png',\n resistance: 'spell-icons/magic-shield.png',\n dexterity: 'spell-icons/haste.png',\n },\n },\n combat: {\n color: colors.purple,\n values: {\n first: 'gloves/leather-gloves.png',\n club: 'maces/club.png',\n sword: 'swords/double-edged-sword.png',\n axe: 'axes/double-axe.png',\n distance: 'bows/horse-bow.png',\n shielding: 'shields/studded-shield.png',\n dagger: 'daggers/dagger.png',\n },\n },\n crafting: {\n color: colors.blue,\n values: {\n fishing: 'foods/fish.png',\n mining: 'crafting-resources/iron-ingot.png',\n lumberjacking: 'crafting-resources/greater-wood-log.png',\n cooking: 'foods/chickens-meat.png',\n alchemy: 'potions/greater-mana-potion.png',\n },\n },\n};\n\nexport const SkillsContainer: React.FC<ISkillContainerProps> = ({\n onCloseButton,\n skill,\n}) => {\n const onRenderSkillCategory = (\n category: 'attributes' | 'combat' | 'crafting'\n ) => {\n const skillCategory = skillProps[category];\n\n const skillCategoryColor = skillCategory.color;\n\n const output = [];\n\n for (const [key, value] of Object.entries(skillCategory.values)) {\n //@ts-ignore\n const skillDetails = (skill[key] as unknown) as ISkillDetails;\n\n output.push(\n <SkillProgressBar\n key={key}\n skillName={_.capitalize(key)}\n bgColor={skillCategoryColor}\n level={skillDetails.level || 0}\n skillPoints={Math.round(skillDetails.skillPoints) || 0}\n skillPointsToNextLevel={\n Math.round(skillDetails.skillPointsToNextLevel) || 0\n }\n texturePath={value}\n />\n );\n }\n\n return output;\n };\n\n return (\n <SkillsDraggableContainer title=\"Skills\">\n {onCloseButton && (\n <CloseButton onClick={onCloseButton} onTouchStart={onCloseButton}>\n X\n </CloseButton>\n )}\n <SkillSplitDiv>\n <p>General</p>\n <hr className=\"golden\" />\n\n <SkillProgressBar\n skillName={'Level'}\n bgColor={colors.navyBlue}\n level={Math.round(skill.level) || 0}\n skillPoints={Math.round(skill.experience) || 0}\n skillPointsToNextLevel={Math.round(skill.xpToNextLevel) || 0}\n texturePath={'swords/broad-sword.png'}\n />\n\n <p>Combat Skills</p>\n <hr className=\"golden\" />\n </SkillSplitDiv>\n\n {onRenderSkillCategory('combat')}\n\n <SkillSplitDiv>\n <p>Crafting Skills</p>\n <hr className=\"golden\" />\n </SkillSplitDiv>\n\n {onRenderSkillCategory('crafting')}\n\n <SkillSplitDiv>\n <p>Basic Attributes</p>\n <hr className=\"golden\" />\n </SkillSplitDiv>\n\n {onRenderSkillCategory('attributes')}\n\n {/* <SkillSplitDiv>\n <p>Magic Skills</p>\n <hr className=\"golden\" />\n </SkillSplitDiv>\n <SkillProgressBar\n skillName={'Ice'}\n bgColor={'red'}\n level={skill?.ice?.level || 0}\n skillPoints={skill?.ice?.skillPoints || 0}\n skillPointsToNextLevel={skill?.ice?.skillPointsToNextLevel || 0}\n texturePath={'spell-icons/freeze.png'}\n />\n <SkillProgressBar\n skillName={'Earth'}\n bgColor={'red'}\n level={skill?.earth?.level || 0}\n skillPoints={skill?.earth?.skillPoints || 0}\n skillPointsToNextLevel={skill?.earth?.skillPointsToNextLevel || 0}\n texturePath={'spell-icons/earth-barrier.png'}\n />\n <SkillProgressBar\n skillName={'Air'}\n bgColor={'red'}\n level={skill?.air?.level || 0}\n skillPoints={skill?.air?.skillPoints || 0}\n skillPointsToNextLevel={skill?.air?.skillPointsToNextLevel || 0}\n texturePath={'spell-icons/poison-tornado.png'}\n />\n <SkillProgressBar\n skillName={'Water'}\n bgColor={'red'}\n level={skill?.water?.level || 0}\n skillPoints={skill?.water?.skillPoints || 0}\n skillPointsToNextLevel={skill?.water?.skillPointsToNextLevel || 0}\n texturePath={'spell-icons/tsunami.png'}\n /> */}\n </SkillsDraggableContainer>\n );\n};\n\nconst SkillsDraggableContainer = styled(DraggableContainer)`\n border: 1px solid black;\n width: 400px;\n height: 90%;\n overflow-y: scroll;\n .DraggableContainer__TitleContainer-sc-184mpyl-2 {\n width: auto;\n height: auto;\n }\n`;\n\nconst SkillSplitDiv = styled.div`\n width: 100%;\n font-size: 11px;\n hr {\n margin: 0;\n margin-bottom: 1rem;\n padding: 0px;\n }\n p {\n margin-bottom: 0px;\n }\n`;\n\nconst CloseButton = styled.div`\n position: absolute;\n top: 2px;\n right: 2px;\n color: white;\n z-index: 22;\n font-size: 0.7rem;\n`;\n","/* eslint-disable react/require-default-props */\nimport React from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n maxLines?: number;\n children: React.ReactNode;\n}\n\nexport const Truncate: React.FC<IProps> = ({ maxLines = 1, children }) => {\n return <Container maxLines={maxLines}>{children}</Container>;\n};\n\ninterface IContainerProps {\n maxLines: number;\n}\n\nconst Container = styled.div<IContainerProps>`\n display: -webkit-box;\n max-width: 100%;\n max-height: 100%;\n -webkit-line-clamp: ${props => props.maxLines};\n -webkit-box-orient: vertical;\n overflow: hidden;\n`;\n","import React, { useEffect, useState } from 'react';\n\nexport interface ICheckItems {\n label: string;\n value: string;\n}\n\nexport interface ICheckProps {\n items: ICheckItems[];\n onChange: (selectedValues: IChecklistSelectedValues) => void;\n}\n\ninterface IChecklistSelectedValues {\n [label: string]: boolean;\n}\n\nexport const CheckButton: React.FC<ICheckProps> = ({ items, onChange }) => {\n const generateSelectedValuesList = () => {\n const selectedValues: IChecklistSelectedValues = {};\n\n items.forEach(item => {\n selectedValues[item.label] = false;\n });\n\n return selectedValues;\n };\n\n const [selectedValues, setSelectedValues] = useState<\n IChecklistSelectedValues\n >(generateSelectedValuesList());\n\n const handleClick = (label: string) => {\n setSelectedValues({\n ...selectedValues,\n [label]: !selectedValues[label],\n });\n };\n\n useEffect(() => {\n if (selectedValues) {\n onChange(selectedValues);\n }\n }, [selectedValues]);\n\n return (\n <div id=\"elemento-checkbox\">\n {items?.map((element, index) => {\n return (\n <div key={`${element.label}_${index}`}>\n <input\n className=\"rpgui-checkbox\"\n type=\"checkbox\"\n checked={selectedValues[element.label]}\n onChange={() => {}}\n />\n <label onClick={() => handleClick(element.label)}>\n {element.label}\n </label>\n <br />\n </div>\n );\n })}\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport { v4 as uuidv4 } from 'uuid';\nimport { _RPGUI } from './RPGUIRoot';\n\nexport interface IOptionsProps {\n id: number;\n value: string;\n option: string;\n}\n\nexport interface IDropdownProps {\n options: IOptionsProps[];\n width?: string;\n onChange: (value: string) => void;\n}\n\nexport const Dropdown: React.FC<IDropdownProps> = ({\n options,\n width,\n onChange,\n}) => {\n const dropdownId = uuidv4();\n\n const [selectedValue, setSelectedValue] = useState<string>('');\n\n useEffect(() => {\n const element = document.getElementById(`rpgui-dropdown-${dropdownId}`);\n const dropdownValue = _RPGUI.get_value(element);\n setSelectedValue(dropdownValue);\n\n element?.addEventListener('change', (event: any) => {\n setSelectedValue(event?.target.value);\n });\n }, []);\n\n useEffect(() => {\n if (selectedValue) {\n onChange(selectedValue);\n }\n }, [selectedValue]);\n\n return (\n <select\n id={`rpgui-dropdown-${dropdownId}`}\n style={{ width: width }}\n className=\"rpgui-dropdown\"\n >\n {options.map(option => {\n return (\n <option key={option.id} value={option.value}>\n {option.option}\n </option>\n );\n })}\n </select>\n );\n};\n","import React, { useEffect, useState } from 'react';\n\nexport interface IRadioItems {\n label: string;\n value: string;\n}\n\nexport interface IRadioProps {\n name: string;\n items: IRadioItems[];\n onChange: (value: string) => void;\n}\n\nexport const InputRadio: React.FC<IRadioProps> = ({\n name,\n items,\n onChange,\n}) => {\n const [selectedValue, setSelectedValue] = useState<string>();\n const handleClick = () => {\n let element = document.querySelector(\n `input[name=${name}]:checked`\n ) as HTMLInputElement;\n const elementValue = element.value;\n setSelectedValue(elementValue);\n };\n\n useEffect(() => {\n if (selectedValue) {\n onChange(selectedValue);\n }\n }, [selectedValue]);\n\n return (\n <div id=\"elemento-radio\">\n {items.map(element => {\n return (\n <>\n <input\n key={element.value}\n className=\"rpgui-radio\"\n value={element.value}\n name={name}\n type=\"radio\"\n />\n <label onClick={handleClick}>{element.label}</label>\n <br />\n </>\n );\n })}\n </div>\n );\n};\n","import React from 'react';\n\nexport interface ITextArea\n extends React.DetailedHTMLProps<\n React.TextareaHTMLAttributes<HTMLTextAreaElement>,\n HTMLTextAreaElement\n > {}\n\nexport const TextArea: React.FC<ITextArea> = ({ ...props }) => {\n return <textarea {...props} />;\n};\n"],"names":["ButtonTypes","RPGUIContainerTypes","Button","disabled","children","buttonType","props","React","ButtonContainer","className","styled","button","displayName","componentId","Input","RPGUIContainer","width","Container","height","type","div","Column","flex","flexWrap","alignItems","justifyContent","CloseButton","CustomInput","CustomContainer","opacity","Form","form","MessageText","p","useOutsideClick","ref","id","useEffect","handleClickOutside","event","current","contains","target","CustomEvent","detail","document","dispatchEvent","addEventListener","removeEventListener","SlotContainerType","DraggableContainer","FramedGold","onCloseButton","title","imgSrc","imgWidth","cancelDrag","onPositionChange","onOutsideClick","draggableRef","useRef","_e","Draggable","cancel","onDrag","data","x","y","TitleContainer","Title","Icon","src","onClick","onTouchStart","h1","img","_RPGUI","RPGUI","ContainerType","RelativeListMenu","options","onSelected","fontSize","style","overflow","map","params","index","ListElement","key","text","li","SpriteFromAtlas","imgScale","grayScale","GRID_WIDTH","GRID_HEIGHT","hasHover","containerStyle","ImgSprite","atlasIMG","frame","atlasJSON","frames","spriteKey","scale","imgStyle","w","h","ItemTooltip","label","NPCDialogType","generateContextList","actionsByTypeList","action","ItemSocketEventsDisplayLabels","EquipmentSlotSpriteByType","Neck","LeftHand","Ring","Head","Torso","Legs","Feet","Inventory","RightHand","Accessory","ItemSlot","observer","itemToRender","slotIndex","item","slotContainerType","slotSpriteMask","onMouseOver","onMouseOut","useState","isTooltipVisible","setTooltipVisible","isContextMenuVisible","setIsContextMenuVisible","contextActions","setContextActions","itemType","contextActionMenu","ItemType","Weapon","Armor","Jewelry","Tool","EQUIPMENT_SET","ActionsByItemType","EquipmentSetItems","Equipment","Consumable","CraftMaterial","Other","Information","Quest","handleContextMenuList","clientX","clientY","onMouseEnter","onMouseLeave","optionId","name","texturePath","allowedEquipSlotType","_itemToRender$allowed","includes","_id","renderEquipment","quantity","element","push","isStackable","stackQty","ItemQty","left","renderItem","span","EquipmentSetContainer","EquipmentColumn","SlotsContainer","onClose","Framed","ItemsContainer","DynamicText","onFinish","onStart","textState","setTextState","i","interval","setInterval","length","substring","clearInterval","TextContainer","NPCDialogText","onEndStep","onStartStep","textChunks","match","RegExp","chunkIndex","setChunkIndex","onHandleSpacePress","code","prev","useEventListener","handler","el","window","savedHandler","listener","e","QuestionDialog","questions","answers","currentQuestion","setCurrentQuestion","canShowAnswers","setCanShowAnswers","onGetFirstAnswer","answerIds","firstAnswerId","find","answer","currentAnswer","setCurrentAnswer","onGetAnswers","answerId","nextAnswerIndex","findIndex","nextAnswerID","nextAnswer","previousAnswerIndex","previousAnswerID","previousAnswer","pop","nextQuestionId","question","QuestionContainer","AnswersContainer","isSelected","selectedColor","AnswerRow","AnswerSelectedIcon","color","Answer","onAnswerClick","onRenderCurrentAnswers","RangeSliderType","ThumbnailContainer","NPCThumbnail","PressSpaceIndicator","right","ProgressBarText","TextOverlay","minWidth","percentageWidth","Item","LeftArrow","RightArrow","input","SimpleProgressBar","bgColor","margin","ProgressBarContainer","BackgroundBar","Progress","value","SkillProgressBar","skillName","level","skillPoints","showSkillPoints","spForNextLevel","getSPForLevel","ratio","ProgressTitle","TitleName","ValueDisplay","ProgressBody","ProgressIconContainer","SpriteContainer","SkillDisplayContainer","SkillPointsDisplay","skillProps","attributes","values","stamina","magic","magicResistance","strength","resistance","dexterity","combat","first","club","sword","axe","distance","shielding","dagger","crafting","fishing","mining","lumberjacking","cooking","alchemy","SkillsDraggableContainer","SkillSplitDiv","maxLines","chatMessages","onSendChatMessage","message","setMessage","scrollChatToBottom","scrollingElement","querySelector","scrollTop","scrollHeight","FramedGrey","ErrorBoundary","fallback","emitter","createdAt","dayjs","Date","format","onRenderMessageLines","onRenderChatMessages","onSubmit","preventDefault","onChange","autoComplete","RPGUIButton","items","selectedValues","forEach","generateSelectedValuesList","setSelectedValues","checked","dropdownId","uuidv4","selectedValue","setSelectedValue","getElementById","dropdownValue","get_value","option","equipmentSet","onItemClick","equipmentData","neck","leftHand","ring","head","armor","legs","boot","inventory","rightHand","accessory","equipmentMaskSlots","ItemSlotType","onRenderEquipmentSlotRange","start","end","equipmentRange","slice","slotMaksRange","itemContainer","handleClick","slots","slotQty","INVENTORY","onRenderSlots","imagePath","isQuestionDialog","showGoNextIndicator","setShowGoNextIndicator","TextAndThumbnail","aliceDefaultThumbnail","TextOnly","max","displayText","calculatePercentageValue","availableProperties","currentIndex","setCurrentIndex","propertiesLength","valueMin","valueMax","sliderId","wasMouseDownFirst","setWasMouseDownFirst","onHandleMouseUp","rpguiSlider","Number","onMouseUp","onMouseDown","Slider","GoldSlider","min","skill","onRenderSkillCategory","category","skillCategory","skillCategoryColor","output","Object","entries","skillDetails","_","capitalize","Math","round","skillPointsToNextLevel","experience","xpToNextLevel"],"mappings":"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"}
@@ -5811,19 +5811,8 @@ var ContainerType;
5811
5811
  (function (ContainerType) {
5812
5812
  ContainerType["INVENTORY"] = "Inventory";
5813
5813
  ContainerType["EQUIPMENT_SET"] = "EquipmentSet";
5814
- })(ContainerType || (ContainerType = {}));
5814
+ })(ContainerType || (ContainerType = {})); // TODO: Refactor this file
5815
5815
 
5816
- var handleContextMenuList = function handleContextMenuList(itemType, slotContainerType) {
5817
- var contextActionMenu = [];
5818
-
5819
- if (slotContainerType === SlotContainerType.INVENTORY) {
5820
- contextActionMenu = handleItemContainerContextMenuList(itemType);
5821
- } else {
5822
- contextActionMenu = handleEquipmentContextMenuList(itemType);
5823
- }
5824
-
5825
- return contextActionMenu;
5826
- }; // TODO: Refactor this file
5827
5816
 
5828
5817
  var generateContextList = function generateContextList(actionsByTypeList) {
5829
5818
  var contextMenu = actionsByTypeList.map(function (action) {
@@ -5835,7 +5824,7 @@ var generateContextList = function generateContextList(actionsByTypeList) {
5835
5824
  return contextMenu;
5836
5825
  };
5837
5826
 
5838
- var handleItemContainerContextMenuList = function handleItemContainerContextMenuList(itemType) {
5827
+ var handleContextMenuList = function handleContextMenuList(itemType, slotContainerType) {
5839
5828
  var contextActionMenu = [];
5840
5829
 
5841
5830
  switch (itemType) {
@@ -5844,7 +5833,12 @@ var handleItemContainerContextMenuList = function handleItemContainerContextMenu
5844
5833
  case ItemType.Accessory:
5845
5834
  case ItemType.Jewelry:
5846
5835
  case ItemType.Tool:
5847
- contextActionMenu = generateContextList(ActionsByItemType.Equipment);
5836
+ if (slotContainerType === SlotContainerType.EQUIPMENT_SET) {
5837
+ contextActionMenu = generateContextList(ActionsByItemType.EquipmentSetItems);
5838
+ } else {
5839
+ contextActionMenu = generateContextList(ActionsByItemType.Equipment);
5840
+ }
5841
+
5848
5842
  break;
5849
5843
 
5850
5844
  case ItemType.Consumable:
@@ -5870,30 +5864,6 @@ var handleItemContainerContextMenuList = function handleItemContainerContextMenu
5870
5864
  return contextActionMenu;
5871
5865
  };
5872
5866
 
5873
- var handleEquipmentContextMenuList = function handleEquipmentContextMenuList(itemType) {
5874
- var contextActionMenu = [];
5875
-
5876
- switch (itemType) {
5877
- case ItemType.Weapon:
5878
- case ItemType.Armor:
5879
- case ItemType.Accessory:
5880
- case ItemType.Jewelry:
5881
- case ItemType.Tool:
5882
- contextActionMenu = generateContextList(ActionsByItemType.EquipmenSetItems);
5883
- break;
5884
-
5885
- case ItemType.Container:
5886
- contextActionMenu = generateContextList(ActionsByItemType.EquipmenSetContainer);
5887
- break;
5888
-
5889
- default:
5890
- contextActionMenu = generateContextList(ActionsByItemType.EquipmenSetItems);
5891
- break;
5892
- }
5893
-
5894
- return contextActionMenu;
5895
- };
5896
-
5897
5867
  var EquipmentSlotSpriteByType = {
5898
5868
  Neck: 'accessories/corruption-necklace.png',
5899
5869
  LeftHand: 'swords/broad-sword.png',
@@ -6018,7 +5988,9 @@ var ItemSlot = /*#__PURE__*/observer(function (_ref) {
6018
5988
  onSelected: function onSelected(optionId) {
6019
5989
  setIsContextMenuVisible(false);
6020
5990
 
6021
- _onSelected(optionId);
5991
+ if (item) {
5992
+ _onSelected(optionId, item);
5993
+ }
6022
5994
  },
6023
5995
  onOutsideClick: function onOutsideClick() {
6024
5996
  setIsContextMenuVisible(false);
@@ -6161,8 +6133,8 @@ var ItemContainer = function ItemContainer(_ref) {
6161
6133
  onClick: function onClick(item, slotContainerType) {
6162
6134
  if (onItemClick) onItemClick(item, slotContainerType);
6163
6135
  },
6164
- onSelected: function onSelected(optionId) {
6165
- if (_onSelected) _onSelected(optionId);
6136
+ onSelected: function onSelected(optionId, item) {
6137
+ if (_onSelected) _onSelected(optionId, item);
6166
6138
  }
6167
6139
  }));
6168
6140
  }