@rpg-engine/long-bow 0.1.46 → 0.1.47

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.
@@ -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/components/RPGUIRoot.tsx","../src/components/ListMenu.tsx","../src/components/NPCDialog/img/npcDialog/npcThumbnails/alice.png","../src/components/NPCDialog/img/space.gif","../src/libs/StringHelpers.ts","../src/components/NPCDialog/NPCDialog.tsx","../src/components/typography/DynamicText.tsx","../src/components/NPCDialog/NPCDialogText.tsx","../src/hooks/useEventListener.ts","../src/components/NPCDialog/QuestionDialog/QuestionDialog.tsx","../src/components/RangeSlider.tsx","../src/components/ProgressBar.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 children: React.ReactNode;\n buttonType: ButtonTypes;\n}\n\nexport const Button: React.FC<\n IButtonProps &\n React.DetailedHTMLProps<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n HTMLButtonElement\n >\n> = ({ children, buttonType, ...props }) => {\n return (\n <ButtonContainer className={`${buttonType}`} {...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 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\nexport interface IChatProps {\n chatMessages: IChatMessage[];\n onSendChatMessage: (message: string) => 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}) => {\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 return (\n <>\n <CustomContainer\n type={RPGUIContainerTypes.FramedGrey}\n width={width}\n height={height}\n className=\"chat-container\"\n opacity={opacity}\n >\n <RPGUIContainer\n type={RPGUIContainerTypes.FramedGrey}\n width={'100%'}\n height={'80%'}\n className=\"chat-body dark-background\"\n >\n {chatMessages.length ? (\n chatMessages.map(({ _id, createdAt, emitter, message }, index) => (\n <MessageText key={`${_id}_${index}`}>{`${dayjs(createdAt).format(\n 'HH:mm'\n )} ${emitter.name}: ${message}`}</MessageText>\n ))\n ) : (\n <MessageText>No messages available.</MessageText>\n )}\n </RPGUIContainer>\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=\"dark-background\"\n type=\"text\"\n autoComplete=\"off\"\n />\n </Column>\n <Column justifyContent=\"flex-end\">\n <Button buttonType={ButtonTypes.RPGUIButton}>Send</Button>\n </Column>\n </Form>\n </CustomContainer>\n </>\n );\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};\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 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) => (\n <ListElement\n key={params.text}\n onClick={() => {\n onSelected(params.id);\n }}\n >\n {params.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","const img = require('./alice.png'); export default img;","const img = require('./space.gif'); export default img;","export const chunkString = (str: string, length: number) => {\n return str.match(new RegExp('.{1,' + length + '}', 'g'));\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] =\n useState<boolean>(false);\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 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","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 [currentAnswer, 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\n word-break: break-all;\n\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\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","/* 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] =\n useState<IChecklistSelectedValues>(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","children","buttonType","props","React","ButtonContainer","className","styled","button","displayName","componentId","Input","RPGUIContainer","width","Container","height","type","div","Column","flex","flexWrap","alignItems","justifyContent","CustomInput","CustomContainer","opacity","Form","form","MessageText","p","_RPGUI","RPGUI","y","x","fontSize","ListElement","li","img","require","NPCDialogType","DynamicText","text","onFinish","onStart","useState","textState","setTextState","useEffect","i","interval","setInterval","length","substring","clearInterval","TextContainer","NPCDialogText","onClose","onEndStep","onStartStep","textChunks","match","RegExp","chunkIndex","setChunkIndex","onHandleSpacePress","event","code","prev","document","addEventListener","removeEventListener","useEventListener","handler","el","window","savedHandler","useRef","current","listener","e","QuestionDialog","questions","answers","currentQuestion","setCurrentQuestion","canShowAnswers","setCanShowAnswers","onGetFirstAnswer","answerIds","firstAnswerId","find","answer","id","currentAnswer","setCurrentAnswer","onGetAnswers","map","answerId","key","nextAnswerIndex","findIndex","nextAnswerID","nextAnswer","previousAnswerIndex","previousAnswerID","previousAnswer","pop","nextQuestionId","question","QuestionContainer","AnswersContainer","isSelected","selectedColor","AnswerRow","AnswerSelectedIcon","color","Answer","onClick","onAnswerClick","onRenderCurrentAnswers","span","RangeSliderType","ThumbnailContainer","NPCThumbnail","PressSpaceIndicator","right","ProgressBarText","TextOverlay","minWidth","percentageWidth","style","input","maxLines","chatMessages","onSendChatMessage","message","setMessage","scrollChatToBottom","scrollingElement","querySelector","scrollTop","scrollHeight","FramedGrey","index","emitter","_id","dayjs","createdAt","format","name","onSubmit","preventDefault","value","onChange","target","autoComplete","RPGUIButton","items","selectedValues","forEach","item","label","generateSelectedValuesList","setSelectedValues","element","checked","options","dropdownId","uuidv4","selectedValue","setSelectedValue","getElementById","dropdownValue","get_value","option","handleClick","onSelected","overflow","params","imagePath","isQuestionDialog","showGoNextIndicator","setShowGoNextIndicator","FramedGold","TextAndThumbnail","src","aliceDefaultThumbnail","TextOnly","pressSpaceGif","max","displayText","calculatePercentageValue","left","valueMin","valueMax","sliderId","wasMouseDownFirst","setWasMouseDownFirst","onHandleMouseUp","rpguiSlider","Number","onMouseUp","onMouseDown","Slider","GoldSlider","min"],"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/components/RPGUIRoot.tsx","../src/components/ListMenu.tsx","../src/components/NPCDialog/img/npcDialog/npcThumbnails/alice.png","../src/components/NPCDialog/img/space.gif","../src/libs/StringHelpers.ts","../src/components/NPCDialog/NPCDialog.tsx","../src/components/typography/DynamicText.tsx","../src/components/NPCDialog/NPCDialogText.tsx","../src/hooks/useEventListener.ts","../src/components/NPCDialog/QuestionDialog/QuestionDialog.tsx","../src/components/RangeSlider.tsx","../src/components/ProgressBar.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 children: React.ReactNode;\n buttonType: ButtonTypes;\n}\n\nexport const Button: React.FC<\n IButtonProps &\n React.DetailedHTMLProps<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n HTMLButtonElement\n >\n> = ({ children, buttonType, ...props }) => {\n return (\n <ButtonContainer className={`${buttonType}`} {...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 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\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 return (\n <Container>\n <CustomContainer\n type={RPGUIContainerTypes.FramedGrey}\n width={width}\n height={height}\n className=\"chat-container\"\n opacity={opacity}\n >\n {onCloseButton && <CloseButton onClick={onCloseButton}>X</CloseButton>}\n <RPGUIContainer\n type={RPGUIContainerTypes.FramedGrey}\n width={'100%'}\n height={'80%'}\n className=\"chat-body dark-background\"\n >\n {chatMessages.length ? (\n chatMessages.map(({ _id, createdAt, emitter, message }, index) => (\n <MessageText key={`${_id}_${index}`}>{`${dayjs(createdAt).format(\n 'HH:mm'\n )} ${emitter.name}: ${message}`}</MessageText>\n ))\n ) : (\n <MessageText>No messages available.</MessageText>\n )}\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=\"dark-background\"\n type=\"text\"\n autoComplete=\"off\"\n />\n </Column>\n <Column justifyContent=\"flex-end\">\n <Button buttonType={ButtonTypes.RPGUIButton}>Send</Button>\n </Column>\n </Form>\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: 3px;\n right: 0px;\n color: white;\n z-index: 22;\n font-size: 10px;\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};\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 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) => (\n <ListElement\n key={params.text}\n onClick={() => {\n onSelected(params.id);\n }}\n >\n {params.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","const img = require('./alice.png'); export default img;","const img = require('./space.gif'); export default img;","export const chunkString = (str: string, length: number) => {\n return str.match(new RegExp('.{1,' + length + '}', 'g'));\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] =\n useState<boolean>(false);\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 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","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 [currentAnswer, 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\n word-break: break-all;\n\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\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","/* 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] =\n useState<IChecklistSelectedValues>(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","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","_RPGUI","RPGUI","y","x","fontSize","ListElement","li","img","require","NPCDialogType","DynamicText","text","onFinish","onStart","useState","textState","setTextState","useEffect","i","interval","setInterval","length","substring","clearInterval","TextContainer","NPCDialogText","onClose","onEndStep","onStartStep","textChunks","match","RegExp","chunkIndex","setChunkIndex","onHandleSpacePress","event","code","prev","document","addEventListener","removeEventListener","useEventListener","handler","el","window","savedHandler","useRef","current","listener","e","QuestionDialog","questions","answers","currentQuestion","setCurrentQuestion","canShowAnswers","setCanShowAnswers","onGetFirstAnswer","answerIds","firstAnswerId","find","answer","id","currentAnswer","setCurrentAnswer","onGetAnswers","map","answerId","key","nextAnswerIndex","findIndex","nextAnswerID","nextAnswer","previousAnswerIndex","previousAnswerID","previousAnswer","pop","nextQuestionId","question","QuestionContainer","AnswersContainer","isSelected","selectedColor","AnswerRow","AnswerSelectedIcon","color","Answer","onClick","onAnswerClick","onRenderCurrentAnswers","span","RangeSliderType","ThumbnailContainer","NPCThumbnail","PressSpaceIndicator","right","ProgressBarText","TextOverlay","minWidth","percentageWidth","style","input","maxLines","chatMessages","onSendChatMessage","onCloseButton","message","setMessage","scrollChatToBottom","scrollingElement","querySelector","scrollTop","scrollHeight","FramedGrey","index","emitter","_id","dayjs","createdAt","format","name","onSubmit","preventDefault","value","onChange","target","autoComplete","RPGUIButton","items","selectedValues","forEach","item","label","generateSelectedValuesList","setSelectedValues","element","checked","options","dropdownId","uuidv4","selectedValue","setSelectedValue","getElementById","dropdownValue","get_value","option","handleClick","onSelected","overflow","params","imagePath","isQuestionDialog","showGoNextIndicator","setShowGoNextIndicator","FramedGold","TextAndThumbnail","src","aliceDefaultThumbnail","TextOnly","pressSpaceGif","max","displayText","calculatePercentageValue","left","valueMin","valueMax","sliderId","wasMouseDownFirst","setWasMouseDownFirst","onHandleMouseUp","rpguiSlider","Number","onMouseUp","onMouseDown","Slider","GoldSlider","min"],"mappings":"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"}
@@ -168,7 +168,8 @@ var Chat = function Chat(_ref) {
168
168
  _ref$width = _ref.width,
169
169
  width = _ref$width === void 0 ? '100%' : _ref$width,
170
170
  _ref$height = _ref.height,
171
- height = _ref$height === void 0 ? '250px' : _ref$height;
171
+ height = _ref$height === void 0 ? '250px' : _ref$height,
172
+ onCloseButton = _ref.onCloseButton;
172
173
 
173
174
  var _useState = useState(''),
174
175
  message = _useState[0],
@@ -199,13 +200,15 @@ var Chat = function Chat(_ref) {
199
200
  setMessage(value);
200
201
  };
201
202
 
202
- return React.createElement(React.Fragment, null, React.createElement(CustomContainer, {
203
+ return React.createElement(Container$1, null, React.createElement(CustomContainer, {
203
204
  type: RPGUIContainerTypes.FramedGrey,
204
205
  width: width,
205
206
  height: height,
206
207
  className: "chat-container",
207
208
  opacity: opacity
208
- }, React.createElement(RPGUIContainer, {
209
+ }, onCloseButton && React.createElement(CloseButton, {
210
+ onClick: onCloseButton
211
+ }, "X"), React.createElement(RPGUIContainer, {
209
212
  type: RPGUIContainerTypes.FramedGrey,
210
213
  width: '100%',
211
214
  height: '80%',
@@ -238,23 +241,31 @@ var Chat = function Chat(_ref) {
238
241
  buttonType: ButtonTypes.RPGUIButton
239
242
  }, "Send")))));
240
243
  };
244
+ var Container$1 = /*#__PURE__*/styled.div.withConfig({
245
+ displayName: "Chat__Container",
246
+ componentId: "sc-1bk05n6-0"
247
+ })(["position:relative;"]);
248
+ var CloseButton = /*#__PURE__*/styled.div.withConfig({
249
+ displayName: "Chat__CloseButton",
250
+ componentId: "sc-1bk05n6-1"
251
+ })(["position:absolute;top:3px;right:0px;color:white;z-index:22;font-size:10px;"]);
241
252
  var CustomInput = /*#__PURE__*/styled(Input).withConfig({
242
253
  displayName: "Chat__CustomInput",
243
- componentId: "sc-1bk05n6-0"
254
+ componentId: "sc-1bk05n6-2"
244
255
  })(["height:30px;width:100%;.rpgui-content .input{min-height:39px;}"]);
245
256
  var CustomContainer = /*#__PURE__*/styled(RPGUIContainer).withConfig({
246
257
  displayName: "Chat__CustomContainer",
247
- componentId: "sc-1bk05n6-1"
258
+ componentId: "sc-1bk05n6-3"
248
259
  })(["display:block;opacity:", ";&:hover{opacity:1;}.dark-background{background-color:", " !important;}.chat-body{&.rpgui-container.framed-grey{background:unset;}max-height:170px;overflow-y:auto;}"], function (props) {
249
260
  return props.opacity;
250
261
  }, colors.darkGrey);
251
262
  var Form = /*#__PURE__*/styled.form.withConfig({
252
263
  displayName: "Chat__Form",
253
- componentId: "sc-1bk05n6-2"
264
+ componentId: "sc-1bk05n6-4"
254
265
  })(["display:flex;width:100%;justify-content:center;align-items:center;"]);
255
266
  var MessageText = /*#__PURE__*/styled.p.withConfig({
256
267
  displayName: "Chat__MessageText",
257
- componentId: "sc-1bk05n6-3"
268
+ componentId: "sc-1bk05n6-5"
258
269
  })(["display:block !important;width:100%;font-size:0.7rem !important;overflow-y:auto;margin:0;"]);
259
270
 
260
271
  var _RPGUI = RPGUI;
@@ -311,7 +322,7 @@ var ListMenu = function ListMenu(_ref) {
311
322
  y = _ref.y,
312
323
  _ref$fontSize = _ref.fontSize,
313
324
  fontSize = _ref$fontSize === void 0 ? 0.8 : _ref$fontSize;
314
- return React.createElement(Container$1, {
325
+ return React.createElement(Container$2, {
315
326
  x: x,
316
327
  y: y,
317
328
  fontSize: fontSize
@@ -329,7 +340,7 @@ var ListMenu = function ListMenu(_ref) {
329
340
  }, params.text);
330
341
  })));
331
342
  };
332
- var Container$1 = /*#__PURE__*/styled.div.withConfig({
343
+ var Container$2 = /*#__PURE__*/styled.div.withConfig({
333
344
  displayName: "ListMenu__Container",
334
345
  componentId: "sc-i9097t-0"
335
346
  })(["display:flex;flex-direction:column;width:100%;justify-content:start;align-items:flex-start;position:absolute;top:", "px;left:", "px;li{font-size:", "em;}"], function (props) {
@@ -425,13 +436,13 @@ var NPCDialogText = function NPCDialogText(_ref) {
425
436
  return document.removeEventListener('keydown', onHandleSpacePress);
426
437
  };
427
438
  }, [chunkIndex]);
428
- return React.createElement(Container$2, null, React.createElement(DynamicText, {
439
+ return React.createElement(Container$3, null, React.createElement(DynamicText, {
429
440
  text: (textChunks == null ? void 0 : textChunks[chunkIndex]) || '',
430
441
  onFinish: onEndStep,
431
442
  onStart: onStartStep
432
443
  }));
433
444
  };
434
- var Container$2 = /*#__PURE__*/styled.div.withConfig({
445
+ var Container$3 = /*#__PURE__*/styled.div.withConfig({
435
446
  displayName: "NPCDialogText__Container",
436
447
  componentId: "sc-1cxkdh9-0"
437
448
  })([""]);
@@ -603,7 +614,7 @@ var QuestionDialog = function QuestionDialog(_ref) {
603
614
  });
604
615
  };
605
616
 
606
- return React.createElement(Container$3, null, React.createElement(QuestionContainer, null, React.createElement(DynamicText, {
617
+ return React.createElement(Container$4, null, React.createElement(QuestionContainer, null, React.createElement(DynamicText, {
607
618
  text: currentQuestion.text,
608
619
  onStart: function onStart() {
609
620
  return setCanShowAnswers(false);
@@ -613,7 +624,7 @@ var QuestionDialog = function QuestionDialog(_ref) {
613
624
  }
614
625
  })), canShowAnswers && React.createElement(AnswersContainer, null, onRenderCurrentAnswers()));
615
626
  };
616
- var Container$3 = /*#__PURE__*/styled.div.withConfig({
627
+ var Container$4 = /*#__PURE__*/styled.div.withConfig({
617
628
  displayName: "QuestionDialog__Container",
618
629
  componentId: "sc-bxc5u0-0"
619
630
  })(["display:flex;word-break:break-all;box-sizing:border-box;justify-content:flex-start;align-items:flex-start;flex-wrap:wrap;"]);
@@ -679,7 +690,7 @@ var NPCDialog = function NPCDialog(_ref) {
679
690
  }
680
691
  })), type === NPCDialogType.TextAndThumbnail && React.createElement(ThumbnailContainer, null, React.createElement(NPCThumbnail, {
681
692
  src: imagePath || img
682
- }))) : React.createElement(React.Fragment, null, React.createElement(Container$4, null, React.createElement(TextContainer$1, {
693
+ }))) : React.createElement(React.Fragment, null, React.createElement(Container$5, null, React.createElement(TextContainer$1, {
683
694
  flex: type === NPCDialogType.TextAndThumbnail ? '70%' : '100%'
684
695
  }, React.createElement(NPCDialogText, {
685
696
  onStartStep: function onStartStep() {
@@ -701,7 +712,7 @@ var NPCDialog = function NPCDialog(_ref) {
701
712
  src: img$1
702
713
  })));
703
714
  };
704
- var Container$4 = /*#__PURE__*/styled.div.withConfig({
715
+ var Container$5 = /*#__PURE__*/styled.div.withConfig({
705
716
  displayName: "NPCDialog__Container",
706
717
  componentId: "sc-1b4aw74-0"
707
718
  })(["display:flex;width:100%;height:100%;box-sizing:border-box;justify-content:center;align-items:flex-start;position:relative;"]);
@@ -748,7 +759,7 @@ var ProgressBar = function ProgressBar(_ref) {
748
759
  return value * 100 / max;
749
760
  };
750
761
 
751
- return React.createElement(Container$5, {
762
+ return React.createElement(Container$6, {
752
763
  className: "rpgui-progress",
753
764
  "data-value": calculatePercentageValue(max, value) / 100,
754
765
  "data-rpguitype": "progress",
@@ -777,7 +788,7 @@ var TextOverlay = /*#__PURE__*/styled.div.withConfig({
777
788
  displayName: "ProgressBar__TextOverlay",
778
789
  componentId: "sc-qa6fzh-1"
779
790
  })(["width:100%;position:relative;"]);
780
- var Container$5 = /*#__PURE__*/styled.div.withConfig({
791
+ var Container$6 = /*#__PURE__*/styled.div.withConfig({
781
792
  displayName: "ProgressBar__Container",
782
793
  componentId: "sc-qa6fzh-2"
783
794
  })(["display:flex;flex-direction:column;min-width:", "px;width:", "%;justify-content:start;align-items:flex-start;", ""], function (props) {
@@ -890,11 +901,11 @@ var Truncate = function Truncate(_ref) {
890
901
  var _ref$maxLines = _ref.maxLines,
891
902
  maxLines = _ref$maxLines === void 0 ? 1 : _ref$maxLines,
892
903
  children = _ref.children;
893
- return React.createElement(Container$6, {
904
+ return React.createElement(Container$7, {
894
905
  maxLines: maxLines
895
906
  }, children);
896
907
  };
897
- var Container$6 = /*#__PURE__*/styled.div.withConfig({
908
+ var Container$7 = /*#__PURE__*/styled.div.withConfig({
898
909
  displayName: "Truncate__Container",
899
910
  componentId: "sc-6x00qb-0"
900
911
  })(["display:-webkit-box;max-width:100%;max-height:100%;-webkit-line-clamp:", ";-webkit-box-orient:vertical;overflow:hidden;"], function (props) {