tgui-core 1.1.11 → 1.1.13

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 (292) hide show
  1. package/dist/ProgressBar.module-BkAFfFy0.js +29 -0
  2. package/dist/Section.module-CLVHJ4yA.js +15 -0
  3. package/dist/assets/BlockQuote.css +1 -0
  4. package/dist/assets/Button.css +1 -0
  5. package/dist/assets/ColorBox.css +1 -0
  6. package/dist/assets/Dialog.css +1 -0
  7. package/dist/assets/Dimmer.css +1 -0
  8. package/dist/assets/Divider.css +1 -0
  9. package/dist/assets/Flex.css +1 -0
  10. package/dist/assets/Icon.css +6 -0
  11. package/dist/assets/Input.css +1 -0
  12. package/dist/assets/Knob.css +1 -0
  13. package/dist/assets/LabeledList.css +1 -0
  14. package/dist/assets/MenuBar.css +1 -0
  15. package/dist/assets/Modal.css +1 -0
  16. package/dist/assets/NoticeBox.css +1 -0
  17. package/dist/assets/NumberInput.css +1 -0
  18. package/dist/assets/ProgressBar.css +1 -0
  19. package/dist/assets/RoundGauge.css +1 -0
  20. package/dist/assets/Section.css +1 -0
  21. package/dist/assets/Slider.css +1 -0
  22. package/dist/assets/Stack.css +1 -0
  23. package/dist/assets/Table.css +1 -0
  24. package/dist/assets/Tabs.css +1 -0
  25. package/dist/assets/TextArea.css +1 -0
  26. package/dist/assets/Tooltip.css +1 -0
  27. package/dist/common/assets.d.ts +4 -0
  28. package/dist/common/assets.js +25 -0
  29. package/dist/common/collections.d.ts +10 -0
  30. package/dist/common/collections.js +15 -0
  31. package/dist/common/color.d.ts +25 -0
  32. package/dist/common/color.js +69 -0
  33. package/dist/common/constants.d.ts +102 -0
  34. package/dist/common/constants.js +312 -0
  35. package/dist/common/events.d.ts +33 -0
  36. package/dist/common/events.js +147 -0
  37. package/{lib/common/exhaustive.ts → dist/common/exhaustive.d.ts} +1 -3
  38. package/dist/common/exhaustive.js +6 -0
  39. package/dist/common/format.d.ts +11 -0
  40. package/dist/common/format.js +114 -0
  41. package/{lib/common/fp.ts → dist/common/fp.d.ts} +2 -16
  42. package/dist/common/fp.js +9 -0
  43. package/dist/common/hotkeys.d.ts +25 -0
  44. package/dist/common/hotkeys.js +112 -0
  45. package/dist/common/http.d.ts +4 -0
  46. package/dist/common/http.js +10 -0
  47. package/dist/common/keycodes.d.ts +85 -0
  48. package/dist/common/keycodes.js +88 -0
  49. package/{lib/common/keys.ts → dist/common/keys.d.ts} +21 -24
  50. package/dist/common/keys.js +8 -0
  51. package/dist/common/math.d.ts +39 -0
  52. package/dist/common/math.js +41 -0
  53. package/dist/common/perf.d.ts +24 -0
  54. package/dist/common/perf.js +33 -0
  55. package/dist/common/random.d.ts +16 -0
  56. package/dist/common/random.js +18 -0
  57. package/dist/common/react.d.ts +23 -0
  58. package/dist/common/react.js +30 -0
  59. package/dist/common/redux.d.ts +64 -0
  60. package/dist/common/redux.js +72 -0
  61. package/dist/common/storage.d.ts +24 -0
  62. package/dist/common/storage.js +133 -0
  63. package/dist/common/string.d.ts +65 -0
  64. package/dist/common/string.js +83 -0
  65. package/dist/common/timer.d.ts +18 -0
  66. package/dist/common/timer.js +28 -0
  67. package/dist/common/type-utils.d.ts +9 -0
  68. package/dist/common/type-utils.js +25 -0
  69. package/dist/common/uuid.d.ts +9 -0
  70. package/dist/common/uuid.js +10 -0
  71. package/dist/components/AnimatedNumber.d.ts +60 -0
  72. package/dist/components/AnimatedNumber.js +76 -0
  73. package/dist/components/Autofocus.d.ts +4 -0
  74. package/dist/components/Autofocus.js +17 -0
  75. package/dist/components/Blink.d.ts +26 -0
  76. package/dist/components/Blink.js +56 -0
  77. package/dist/components/BlockQuote.d.ts +3 -0
  78. package/dist/components/BlockQuote.js +13 -0
  79. package/dist/components/BodyZoneSelector.d.ts +28 -0
  80. package/dist/components/BodyZoneSelector.js +115 -0
  81. package/dist/components/Box.d.ts +91 -0
  82. package/dist/components/Box.js +133 -0
  83. package/dist/components/Button.d.ts +93 -0
  84. package/dist/components/Button.js +298 -0
  85. package/dist/components/ByondUi.js +73 -0
  86. package/dist/components/Chart.d.ts +28 -0
  87. package/dist/components/Chart.js +95 -0
  88. package/dist/components/Collapsible.d.ts +15 -0
  89. package/dist/components/Collapsible.js +27 -0
  90. package/dist/components/ColorBox.d.ts +8 -0
  91. package/dist/components/ColorBox.js +24 -0
  92. package/dist/components/Dialog.d.ts +24 -0
  93. package/dist/components/Dialog.js +67 -0
  94. package/dist/components/Dimmer.d.ts +3 -0
  95. package/dist/components/Dimmer.js +13 -0
  96. package/dist/components/Divider.d.ts +6 -0
  97. package/dist/components/Divider.js +22 -0
  98. package/dist/components/DmIcon.d.ts +33 -0
  99. package/dist/components/DmIcon.js +29 -0
  100. package/dist/components/DraggableControl.js +176 -0
  101. package/dist/components/Dropdown.d.ts +48 -0
  102. package/dist/components/Dropdown.js +152 -0
  103. package/dist/components/FakeTerminal.js +38 -0
  104. package/dist/components/FitText.d.ts +22 -0
  105. package/dist/components/FitText.js +63 -0
  106. package/dist/components/Flex.d.ts +93 -0
  107. package/dist/components/Flex.js +72 -0
  108. package/dist/components/Icon.d.ts +30 -0
  109. package/dist/components/Icon.js +51 -0
  110. package/dist/components/Image.d.ts +14 -0
  111. package/dist/components/Image.js +35 -0
  112. package/dist/components/InfinitePlane.js +139 -0
  113. package/dist/components/Input.d.ts +61 -0
  114. package/dist/components/Input.js +89 -0
  115. package/dist/components/KeyListener.d.ts +15 -0
  116. package/dist/components/KeyListener.js +23 -0
  117. package/dist/components/Knob.d.ts +49 -0
  118. package/dist/components/Knob.js +162 -0
  119. package/dist/components/LabeledControls.d.ts +11 -0
  120. package/dist/components/LabeledControls.js +39 -0
  121. package/dist/components/LabeledList.d.ts +57 -0
  122. package/dist/components/LabeledList.js +94 -0
  123. package/dist/components/MenuBar.d.ts +28 -0
  124. package/dist/components/MenuBar.js +174 -0
  125. package/dist/components/Modal.d.ts +3 -0
  126. package/dist/components/Modal.js +25 -0
  127. package/dist/components/NoticeBox.d.ts +20 -0
  128. package/dist/components/NoticeBox.js +49 -0
  129. package/dist/components/NumberInput.d.ts +45 -0
  130. package/dist/components/NumberInput.js +221 -0
  131. package/dist/components/Popper.d.ts +27 -0
  132. package/dist/components/Popper.js +177 -0
  133. package/dist/components/ProgressBar.d.ts +46 -0
  134. package/dist/components/ProgressBar.js +37 -0
  135. package/dist/components/RestrictedInput.js +155 -0
  136. package/dist/components/RoundGauge.d.ts +53 -0
  137. package/dist/components/RoundGauge.js +147 -0
  138. package/dist/components/Section.d.ts +63 -0
  139. package/dist/components/Section.js +62 -0
  140. package/dist/components/Slider.d.ts +46 -0
  141. package/dist/components/Slider.js +124 -0
  142. package/dist/components/Stack.d.ts +27 -0
  143. package/dist/components/Stack.js +67 -0
  144. package/dist/components/StyleableSection.d.ts +11 -0
  145. package/dist/components/StyleableSection.js +16 -0
  146. package/dist/components/Table.d.ts +29 -0
  147. package/dist/components/Table.js +67 -0
  148. package/dist/components/Tabs.d.ts +23 -0
  149. package/dist/components/Tabs.js +89 -0
  150. package/dist/components/TextArea.d.ts +39 -0
  151. package/dist/components/TextArea.js +118 -0
  152. package/dist/components/TimeDisplay.js +34 -0
  153. package/dist/components/Tooltip.d.ts +29 -0
  154. package/dist/components/Tooltip.js +83 -0
  155. package/dist/components/TrackOutsideClicks.d.ts +13 -0
  156. package/dist/components/TrackOutsideClicks.js +24 -0
  157. package/dist/components/VirtualList.d.ts +8 -0
  158. package/dist/components/VirtualList.js +34 -0
  159. package/dist/components/index.js +92 -0
  160. package/dist/popper-CiqSDJTE.js +906 -0
  161. package/package.json +8 -10
  162. package/lib/common/assets.ts +0 -38
  163. package/lib/common/collections.ts +0 -27
  164. package/lib/common/color.ts +0 -88
  165. package/lib/common/constants.ts +0 -349
  166. package/lib/common/events.ts +0 -262
  167. package/lib/common/format.ts +0 -167
  168. package/lib/common/hotkeys.ts +0 -207
  169. package/lib/common/http.ts +0 -16
  170. package/lib/common/keycodes.ts +0 -86
  171. package/lib/common/math.ts +0 -76
  172. package/lib/common/perf.ts +0 -72
  173. package/lib/common/random.ts +0 -32
  174. package/lib/common/react.ts +0 -59
  175. package/lib/common/redux.ts +0 -187
  176. package/lib/common/storage.ts +0 -207
  177. package/lib/common/string.ts +0 -169
  178. package/lib/common/timer.ts +0 -63
  179. package/lib/common/type-utils.ts +0 -41
  180. package/lib/common/types.d.ts +0 -12
  181. package/lib/common/uuid.ts +0 -18
  182. package/lib/components/AnimatedNumber.tsx +0 -180
  183. package/lib/components/Autofocus.tsx +0 -23
  184. package/lib/components/Blink.tsx +0 -91
  185. package/lib/components/BlockQuote.tsx +0 -9
  186. package/lib/components/BodyZoneSelector.tsx +0 -149
  187. package/lib/components/Box.tsx +0 -252
  188. package/lib/components/Button.tsx +0 -425
  189. package/lib/components/ByondUi.jsx +0 -110
  190. package/lib/components/Chart.tsx +0 -155
  191. package/lib/components/Collapsible.tsx +0 -43
  192. package/lib/components/ColorBox.tsx +0 -29
  193. package/lib/components/Dialog.tsx +0 -81
  194. package/lib/components/Dimmer.tsx +0 -13
  195. package/lib/components/Divider.tsx +0 -20
  196. package/lib/components/DmIcon.tsx +0 -86
  197. package/lib/components/DraggableControl.jsx +0 -276
  198. package/lib/components/Dropdown.tsx +0 -246
  199. package/lib/components/FakeTerminal.jsx +0 -52
  200. package/lib/components/FitText.tsx +0 -99
  201. package/lib/components/Flex.tsx +0 -159
  202. package/lib/components/Icon.tsx +0 -95
  203. package/lib/components/Image.tsx +0 -54
  204. package/lib/components/InfinitePlane.jsx +0 -192
  205. package/lib/components/Input.tsx +0 -176
  206. package/lib/components/KeyListener.tsx +0 -40
  207. package/lib/components/Knob.tsx +0 -178
  208. package/lib/components/LabeledControls.tsx +0 -44
  209. package/lib/components/LabeledList.tsx +0 -154
  210. package/lib/components/MenuBar.tsx +0 -228
  211. package/lib/components/Modal.tsx +0 -23
  212. package/lib/components/NoticeBox.tsx +0 -45
  213. package/lib/components/NumberInput.tsx +0 -328
  214. package/lib/components/Popper.tsx +0 -100
  215. package/lib/components/ProgressBar.tsx +0 -105
  216. package/lib/components/RestrictedInput.jsx +0 -301
  217. package/lib/components/RoundGauge.tsx +0 -180
  218. package/lib/components/Section.tsx +0 -120
  219. package/lib/components/Slider.tsx +0 -169
  220. package/lib/components/Stack.tsx +0 -96
  221. package/lib/components/StyleableSection.tsx +0 -33
  222. package/lib/components/Table.tsx +0 -84
  223. package/lib/components/Tabs.tsx +0 -89
  224. package/lib/components/TextArea.tsx +0 -182
  225. package/lib/components/TimeDisplay.jsx +0 -64
  226. package/lib/components/Tooltip.tsx +0 -152
  227. package/lib/components/TrackOutsideClicks.tsx +0 -35
  228. package/lib/components/VirtualList.tsx +0 -69
  229. package/lib/styles/atomic/candystripe.scss +0 -8
  230. package/lib/styles/atomic/centered-image.scss +0 -7
  231. package/lib/styles/atomic/color.scss +0 -21
  232. package/lib/styles/atomic/debug-layout.scss +0 -17
  233. package/lib/styles/atomic/fit-text.scss +0 -14
  234. package/lib/styles/atomic/links.scss +0 -12
  235. package/lib/styles/atomic/outline.scss +0 -47
  236. package/lib/styles/atomic/text.scss +0 -44
  237. package/lib/styles/base.scss +0 -32
  238. package/lib/styles/colors.scss +0 -92
  239. package/lib/styles/components/BlockQuote.module.scss +0 -20
  240. package/lib/styles/components/BlockQuote.module.scss.d.ts +0 -4
  241. package/lib/styles/components/Button.module.scss +0 -157
  242. package/lib/styles/components/Button.module.scss.d.ts +0 -46
  243. package/lib/styles/components/ColorBox.module.scss +0 -12
  244. package/lib/styles/components/ColorBox.module.scss.d.ts +0 -4
  245. package/lib/styles/components/Dialog.module.scss +0 -60
  246. package/lib/styles/components/Dialog.module.scss.d.ts +0 -10
  247. package/lib/styles/components/Dimmer.module.scss +0 -22
  248. package/lib/styles/components/Dimmer.module.scss.d.ts +0 -4
  249. package/lib/styles/components/Divider.module.scss +0 -27
  250. package/lib/styles/components/Divider.module.scss.d.ts +0 -6
  251. package/lib/styles/components/Dropdown.scss +0 -72
  252. package/lib/styles/components/Flex.module.scss +0 -13
  253. package/lib/styles/components/Flex.module.scss.d.ts +0 -5
  254. package/lib/styles/components/Icon.module.scss +0 -25
  255. package/lib/styles/components/Icon.module.scss.d.ts +0 -5
  256. package/lib/styles/components/Input.module.scss +0 -64
  257. package/lib/styles/components/Input.module.scss.d.ts +0 -8
  258. package/lib/styles/components/Knob.module.scss +0 -131
  259. package/lib/styles/components/Knob.module.scss.d.ts +0 -33
  260. package/lib/styles/components/LabeledList.module.scss +0 -49
  261. package/lib/styles/components/LabeledList.module.scss.d.ts +0 -8
  262. package/lib/styles/components/MenuBar.module.scss +0 -75
  263. package/lib/styles/components/MenuBar.module.scss.d.ts +0 -14
  264. package/lib/styles/components/Modal.module.scss +0 -14
  265. package/lib/styles/components/Modal.module.scss.d.ts +0 -4
  266. package/lib/styles/components/NoticeBox.module.scss +0 -65
  267. package/lib/styles/components/NoticeBox.module.scss.d.ts +0 -27
  268. package/lib/styles/components/NumberInput.module.scss +0 -71
  269. package/lib/styles/components/NumberInput.module.scss.d.ts +0 -9
  270. package/lib/styles/components/ProgressBar.module.scss +0 -63
  271. package/lib/styles/components/ProgressBar.module.scss.d.ts +0 -27
  272. package/lib/styles/components/RoundGauge.module.scss +0 -85
  273. package/lib/styles/components/RoundGauge.module.scss.d.ts +0 -49
  274. package/lib/styles/components/Section.module.scss +0 -130
  275. package/lib/styles/components/Section.module.scss.d.ts +0 -13
  276. package/lib/styles/components/Slider.module.scss +0 -54
  277. package/lib/styles/components/Slider.module.scss.d.ts +0 -8
  278. package/lib/styles/components/Stack.module.scss +0 -60
  279. package/lib/styles/components/Stack.module.scss.d.ts +0 -12
  280. package/lib/styles/components/Table.module.scss +0 -44
  281. package/lib/styles/components/Table.module.scss.d.ts +0 -10
  282. package/lib/styles/components/Tabs.module.scss +0 -144
  283. package/lib/styles/components/Tabs.module.scss.d.ts +0 -35
  284. package/lib/styles/components/TextArea.module.scss +0 -86
  285. package/lib/styles/components/TextArea.module.scss.d.ts +0 -11
  286. package/lib/styles/components/Tooltip.module.scss +0 -24
  287. package/lib/styles/components/Tooltip.module.scss.d.ts +0 -4
  288. package/lib/styles/functions.scss +0 -79
  289. package/lib/styles/input.scss +0 -9
  290. package/lib/styles/main.scss +0 -20
  291. package/lib/styles/reset.scss +0 -68
  292. /package/{lib/components/index.ts → dist/components/index.d.ts} +0 -0
@@ -1,425 +0,0 @@
1
- import { Placement } from '@popperjs/core';
2
- import {
3
- ChangeEvent,
4
- createRef,
5
- MouseEvent,
6
- ReactNode,
7
- useEffect,
8
- useRef,
9
- useState,
10
- } from 'react';
11
-
12
- import { KEY } from '../common/keys';
13
- import { BooleanLike, classes } from '../common/react';
14
- import styles from '../styles/components/Button.module.scss';
15
- import { Box, BoxProps, computeBoxClassName, computeBoxProps } from './Box';
16
- import { Icon } from './Icon';
17
- import { Tooltip } from './Tooltip';
18
-
19
- /**
20
- * Getting ellipses to work requires that you use:
21
- * 1. A string rather than a node
22
- * 2. A fixed width here or in a parent
23
- * 3. Children prop rather than content
24
- */
25
- type EllipsisUnion =
26
- | {
27
- children: string;
28
- /** @deprecated use children instead */
29
- content?: never;
30
- /** Cuts off text with an ellipsis */
31
- ellipsis: true;
32
- }
33
- | Partial<{
34
- children: ReactNode;
35
- /** @deprecated use children instead */
36
- content: ReactNode;
37
- ellipsis: undefined;
38
- }>;
39
-
40
- type Props = Partial<{
41
- /** Captures keyboard events */
42
- captureKeys: boolean;
43
- /** Makes the button circular */
44
- circular: boolean;
45
- /** Reduces the padding of the button */
46
- compact: boolean;
47
- /** Disables and greys out the button */
48
- disabled: BooleanLike;
49
- /** Fill all available horizontal space */
50
- fluid: boolean;
51
- /** Adds an icon to the button */
52
- icon: string | false;
53
- /** Icon color */
54
- iconColor: string;
55
- /** Icon position */
56
- iconPosition: string;
57
- /** Icon rotation */
58
- iconRotation: number;
59
- /** Makes the icon spin */
60
- iconSpin: BooleanLike;
61
- /** Called when element is clicked */
62
- onClick: (e: any) => void;
63
- /** Activates the button (gives it a green color) */
64
- selected: BooleanLike;
65
- /** A fancy, boxy tooltip, which appears when hovering over the button */
66
- tooltip: ReactNode;
67
- /** Position of the tooltip. See [`Popper`](#Popper) for valid options. */
68
- tooltipPosition: Placement;
69
- /** Align content vertically using flex. Use lineHeight if the height is static. */
70
- verticalAlignContent: string;
71
- }> &
72
- EllipsisUnion &
73
- BoxProps;
74
-
75
- /** Clickable button. Comes with variants. Read more in the documentation. */
76
- export function Button(props: Props) {
77
- const {
78
- captureKeys = true,
79
- children,
80
- circular,
81
- className,
82
- color,
83
- compact,
84
- content,
85
- disabled,
86
- ellipsis,
87
- fluid,
88
- icon,
89
- iconColor,
90
- iconPosition,
91
- iconRotation,
92
- iconSpin,
93
- onClick,
94
- selected,
95
- tooltip,
96
- tooltipPosition,
97
- verticalAlignContent,
98
- ...rest
99
- } = props;
100
-
101
- const toDisplay: ReactNode = content || children;
102
-
103
- let buttonContent = (
104
- <div
105
- className={classes([
106
- styles.button,
107
- fluid && styles.fluid,
108
- disabled && styles.disabled,
109
- selected && styles.selected,
110
- circular && styles.circular,
111
- compact && styles.compact,
112
- verticalAlignContent && styles.flex,
113
- verticalAlignContent && fluid && styles.flex__fluid,
114
- verticalAlignContent &&
115
- styles['verticalAlignContent__' + verticalAlignContent],
116
- color && typeof color === 'string'
117
- ? styles['color__' + color]
118
- : styles['color__default'],
119
- className,
120
- computeBoxClassName(rest),
121
- ])}
122
- tabIndex={!disabled ? 0 : undefined}
123
- onClick={(event) => {
124
- if (!disabled && onClick) {
125
- onClick(event);
126
- }
127
- }}
128
- onKeyDown={(event) => {
129
- if (!captureKeys) {
130
- return;
131
- }
132
-
133
- // Simulate a click when pressing space or enter.
134
- if (event.key === KEY.Space || event.key === KEY.Enter) {
135
- event.preventDefault();
136
- if (!disabled && onClick) {
137
- onClick(event);
138
- }
139
- return;
140
- }
141
-
142
- // Refocus layout on pressing escape.
143
- if (event.key === KEY.Escape) {
144
- event.preventDefault();
145
- }
146
- }}
147
- {...computeBoxProps(rest)}
148
- >
149
- <div className={styles.content}>
150
- {icon && iconPosition !== 'right' && (
151
- <Icon
152
- mr={1}
153
- name={icon}
154
- color={iconColor}
155
- rotation={iconRotation}
156
- spin={iconSpin}
157
- />
158
- )}
159
- {!ellipsis ? (
160
- toDisplay
161
- ) : (
162
- <span
163
- className={classes([styles.ellipsis, icon && styles.textMargin])}
164
- >
165
- {toDisplay}
166
- </span>
167
- )}
168
- {icon && iconPosition === 'right' && (
169
- <Icon
170
- ml={1}
171
- name={icon}
172
- color={iconColor}
173
- rotation={iconRotation}
174
- spin={iconSpin}
175
- />
176
- )}
177
- </div>
178
- </div>
179
- );
180
-
181
- if (tooltip) {
182
- buttonContent = (
183
- <Tooltip content={tooltip} position={tooltipPosition as Placement}>
184
- {buttonContent}
185
- </Tooltip>
186
- );
187
- }
188
-
189
- return buttonContent;
190
- }
191
-
192
- type CheckProps = Partial<{
193
- checked: BooleanLike;
194
- }> &
195
- Props;
196
-
197
- /** Visually toggles between checked and unchecked states. */
198
- export function ButtonCheckbox(props: CheckProps) {
199
- const { checked, ...rest } = props;
200
-
201
- return (
202
- <Button
203
- color="transparent"
204
- icon={checked ? 'check-square-o' : 'square-o'}
205
- selected={checked}
206
- {...rest}
207
- />
208
- );
209
- }
210
-
211
- Button.Checkbox = ButtonCheckbox;
212
-
213
- type ConfirmProps = Partial<{
214
- confirmColor: string;
215
- confirmContent: ReactNode;
216
- confirmIcon: string;
217
- }> &
218
- Props;
219
-
220
- /** Requires user confirmation before triggering its action. */
221
- function ButtonConfirm(props: ConfirmProps) {
222
- const {
223
- children,
224
- color,
225
- confirmColor = 'bad',
226
- confirmContent = 'Confirm?',
227
- confirmIcon,
228
- ellipsis = true,
229
- icon,
230
- onClick,
231
- ...rest
232
- } = props;
233
- const [clickedOnce, setClickedOnce] = useState(false);
234
-
235
- function handleClick(event: MouseEvent<HTMLDivElement>) {
236
- if (!clickedOnce) {
237
- setClickedOnce(true);
238
- return;
239
- }
240
-
241
- onClick?.(event);
242
- setClickedOnce(false);
243
- }
244
-
245
- return (
246
- <Button
247
- icon={clickedOnce ? confirmIcon : icon}
248
- color={clickedOnce ? confirmColor : color}
249
- onClick={handleClick}
250
- {...rest}
251
- >
252
- {clickedOnce ? confirmContent : children}
253
- </Button>
254
- );
255
- }
256
-
257
- Button.Confirm = ButtonConfirm;
258
-
259
- type InputProps = Partial<{
260
- currentValue: string;
261
- defaultValue: string;
262
- fluid: boolean;
263
- maxLength: number;
264
- onCommit: (e: any, value: string) => void;
265
- placeholder: string;
266
- }> &
267
- Props;
268
-
269
- /** Accepts and handles user input. */
270
- function ButtonInput(props: InputProps) {
271
- const {
272
- children,
273
- color = 'default',
274
- content,
275
- currentValue,
276
- defaultValue,
277
- disabled,
278
- fluid,
279
- icon,
280
- iconRotation,
281
- iconSpin,
282
- maxLength,
283
- onCommit = () => null,
284
- placeholder,
285
- tooltip,
286
- tooltipPosition,
287
- ...rest
288
- } = props;
289
- const [inInput, setInInput] = useState(false);
290
- const inputRef = createRef<HTMLInputElement>();
291
-
292
- const toDisplay = content || children;
293
-
294
- function commitResult(e) {
295
- const input = inputRef.current;
296
- if (!input) return;
297
-
298
- const hasValue = input.value !== '';
299
- if (hasValue) {
300
- onCommit(e, input.value);
301
- } else {
302
- if (defaultValue) {
303
- onCommit(e, defaultValue);
304
- }
305
- }
306
- }
307
-
308
- useEffect(() => {
309
- const input = inputRef.current;
310
- if (!input) return;
311
-
312
- if (inInput) {
313
- input.value = currentValue || '';
314
- try {
315
- input.focus();
316
- input.select();
317
- } catch {
318
- // Ignore errors
319
- }
320
- }
321
- }, [inInput, currentValue]);
322
-
323
- let buttonContent = (
324
- <Box
325
- className={classes([
326
- styles.button,
327
- fluid && styles.fluid,
328
- styles['color__' + color],
329
- ])}
330
- {...rest}
331
- onClick={() => setInInput(true)}
332
- >
333
- {icon && <Icon name={icon} rotation={iconRotation} spin={iconSpin} />}
334
- <div>{toDisplay}</div>
335
- <input
336
- disabled={!!disabled}
337
- ref={inputRef}
338
- className="NumberInput__input"
339
- style={{
340
- display: !inInput ? 'none' : '',
341
- textAlign: 'left',
342
- }}
343
- onBlur={(event) => {
344
- if (!inInput) {
345
- return;
346
- }
347
- setInInput(false);
348
- commitResult(event);
349
- }}
350
- onKeyDown={(event) => {
351
- if (event.key === KEY.Enter) {
352
- setInInput(false);
353
- commitResult(event);
354
- return;
355
- }
356
- if (event.key === KEY.Escape) {
357
- setInInput(false);
358
- }
359
- }}
360
- />
361
- </Box>
362
- );
363
-
364
- if (tooltip) {
365
- buttonContent = (
366
- <Tooltip content={tooltip} position={tooltipPosition as Placement}>
367
- {buttonContent}
368
- </Tooltip>
369
- );
370
- }
371
-
372
- return buttonContent;
373
- }
374
-
375
- Button.Input = ButtonInput;
376
-
377
- type FileProps = {
378
- accept: string;
379
- multiple?: boolean;
380
- onSelectFiles: (files: string | string[]) => void;
381
- } & Props;
382
-
383
- /** Accepts file input */
384
- function ButtonFile(props: FileProps) {
385
- const { accept, multiple, onSelectFiles, ...rest } = props;
386
-
387
- const inputRef = useRef<HTMLInputElement>(null);
388
-
389
- async function read(files: FileList) {
390
- const promises = Array.from(files).map((file) => {
391
- const reader = new FileReader();
392
-
393
- return new Promise<string>((resolve) => {
394
- reader.onload = () => resolve(reader.result as string);
395
- reader.readAsText(file);
396
- });
397
- });
398
-
399
- return await Promise.all(promises);
400
- }
401
-
402
- async function handleChange(event: ChangeEvent<HTMLInputElement>) {
403
- const files = event.target.files;
404
- if (files?.length) {
405
- const readFiles = await read(files);
406
- onSelectFiles(multiple ? readFiles : readFiles[0]);
407
- }
408
- }
409
-
410
- return (
411
- <>
412
- <Button onClick={() => inputRef.current?.click()} {...rest} />
413
- <input
414
- hidden
415
- type="file"
416
- ref={inputRef}
417
- accept={accept}
418
- multiple={multiple}
419
- onChange={handleChange}
420
- />
421
- </>
422
- );
423
- }
424
-
425
- Button.File = ButtonFile;
@@ -1,110 +0,0 @@
1
- import { Component, createRef } from 'react';
2
-
3
- import { shallowDiffers } from '../common/react';
4
- import { debounce } from '../common/timer';
5
- import { computeBoxProps } from './Box';
6
-
7
- // Stack of currently allocated BYOND UI element ids.
8
- const byondUiStack = [];
9
-
10
- function createByondUiElement(elementId) {
11
- // Reserve an index in the stack
12
- const index = byondUiStack.length;
13
- byondUiStack.push(null);
14
- // Get a unique id
15
- const id = elementId || 'byondui_' + index;
16
- // Return a control structure
17
- return {
18
- render: (params) => {
19
- byondUiStack[index] = id;
20
- Byond.winset(id, params);
21
- },
22
- unmount: () => {
23
- byondUiStack[index] = null;
24
- Byond.winset(id, {
25
- parent: '',
26
- });
27
- },
28
- };
29
- }
30
-
31
- window.addEventListener('beforeunload', () => {
32
- // Cleanly unmount all visible UI elements
33
- for (let index = 0; index < byondUiStack.length; index++) {
34
- const id = byondUiStack[index];
35
- if (typeof id === 'string') {
36
- byondUiStack[index] = null;
37
- Byond.winset(id, {
38
- parent: '',
39
- });
40
- }
41
- }
42
- });
43
-
44
- /**
45
- * Get the bounding box of the DOM element in display-pixels.
46
- */
47
- function getBoundingBox(element) {
48
- const pixelRatio = window.devicePixelRatio ?? 1;
49
- const rect = element.getBoundingClientRect();
50
-
51
- return {
52
- pos: [rect.left * pixelRatio, rect.top * pixelRatio],
53
- size: [
54
- (rect.right - rect.left) * pixelRatio,
55
- (rect.bottom - rect.top) * pixelRatio,
56
- ],
57
- };
58
- }
59
-
60
- export class ByondUi extends Component {
61
- constructor(props) {
62
- super(props);
63
- this.containerRef = createRef();
64
- this.byondUiElement = createByondUiElement(props.params?.id);
65
- this.handleResize = debounce(() => {
66
- this.forceUpdate();
67
- }, 100);
68
- }
69
-
70
- shouldComponentUpdate(nextProps) {
71
- const { params: prevParams = {}, ...prevRest } = this.props;
72
- const { params: nextParams = {}, ...nextRest } = nextProps;
73
- return (
74
- shallowDiffers(prevParams, nextParams) ||
75
- shallowDiffers(prevRest, nextRest)
76
- );
77
- }
78
-
79
- componentDidMount() {
80
- window.addEventListener('resize', this.handleResize);
81
- this.componentDidUpdate();
82
- this.handleResize();
83
- }
84
-
85
- componentDidUpdate() {
86
- const { params = {} } = this.props;
87
- const box = getBoundingBox(this.containerRef.current);
88
- this.byondUiElement.render({
89
- parent: Byond.windowId,
90
- ...params,
91
- pos: box.pos[0] + ',' + box.pos[1],
92
- size: box.size[0] + 'x' + box.size[1],
93
- });
94
- }
95
-
96
- componentWillUnmount() {
97
- window.removeEventListener('resize', this.handleResize);
98
- this.byondUiElement.unmount();
99
- }
100
-
101
- render() {
102
- const { params, ...rest } = this.props;
103
- return (
104
- <div ref={this.containerRef} {...computeBoxProps(rest)}>
105
- {/* Filler */}
106
- <div style={{ minHeight: '22px' }} />
107
- </div>
108
- );
109
- }
110
- }
@@ -1,155 +0,0 @@
1
- import { Component, createRef, RefObject } from 'react';
2
-
3
- import { zip } from '../common/collections';
4
- import { Box, BoxProps } from './Box';
5
-
6
- type Props = {
7
- data: number[][];
8
- } & Partial<{
9
- fillColor: string;
10
- rangeX: [number, number];
11
- rangeY: [number, number];
12
- strokeColor: string;
13
- strokeWidth: number;
14
- }> &
15
- BoxProps;
16
-
17
- type State = {
18
- viewBox: [number, number];
19
- };
20
-
21
- type Point = number[];
22
- type Range = [number, number];
23
-
24
- function normalizeData(
25
- data: Point[],
26
- scale: number[],
27
- rangeX?: Range,
28
- rangeY?: Range,
29
- ) {
30
- if (data.length === 0) {
31
- return [];
32
- }
33
-
34
- const zipped = zip(...data);
35
-
36
- const min = zipped.map((p) => Math.min(...p));
37
- const max = zipped.map((p) => Math.max(...p));
38
-
39
- if (rangeX !== undefined) {
40
- min[0] = rangeX[0];
41
- max[0] = rangeX[1];
42
- }
43
-
44
- if (rangeY !== undefined) {
45
- min[1] = rangeY[0];
46
- max[1] = rangeY[1];
47
- }
48
-
49
- const normalized = data.map((point) =>
50
- zip(point, min, max, scale).map(
51
- ([value, min, max, scale]) => ((value - min) / (max - min)) * scale,
52
- ),
53
- );
54
-
55
- return normalized;
56
- }
57
-
58
- function dataToPolylinePoints(data) {
59
- let points = '';
60
- for (let i = 0; i < data.length; i++) {
61
- const point = data[i];
62
- points += point[0] + ',' + point[1] + ' ';
63
- }
64
- return points;
65
- }
66
-
67
- class LineChart extends Component<Props> {
68
- ref: RefObject<HTMLDivElement>;
69
- state: State;
70
-
71
- constructor(props: Props) {
72
- super(props);
73
- this.ref = createRef();
74
- this.state = {
75
- // Initial guess
76
- viewBox: [600, 200],
77
- };
78
- this.handleResize = this.handleResize.bind(this);
79
- }
80
-
81
- componentDidMount() {
82
- window.addEventListener('resize', this.handleResize);
83
- this.handleResize();
84
- }
85
-
86
- componentWillUnmount() {
87
- window.removeEventListener('resize', this.handleResize);
88
- }
89
-
90
- handleResize = () => {
91
- const element = this.ref.current;
92
- if (!element) {
93
- return;
94
- }
95
- this.setState({
96
- viewBox: [element.offsetWidth, element.offsetHeight],
97
- });
98
- };
99
-
100
- render() {
101
- const {
102
- data = [],
103
- rangeX,
104
- rangeY,
105
- fillColor = 'none',
106
- strokeColor = '#ffffff',
107
- strokeWidth = 2,
108
- ...rest
109
- } = this.props;
110
- const { viewBox } = this.state;
111
- const normalized = normalizeData(data, viewBox, rangeX, rangeY);
112
- // Push data outside viewBox and form a fillable polygon
113
- if (normalized.length > 0) {
114
- const first = normalized[0];
115
- const last = normalized[normalized.length - 1];
116
- normalized.push([viewBox[0] + strokeWidth, last[1]]);
117
- normalized.push([viewBox[0] + strokeWidth, -strokeWidth]);
118
- normalized.push([-strokeWidth, -strokeWidth]);
119
- normalized.push([-strokeWidth, first[1]]);
120
- }
121
- const points = dataToPolylinePoints(normalized);
122
- const divProps = { ...rest, className: '', ref: this.ref };
123
-
124
- return (
125
- <Box position="relative" {...rest}>
126
- <Box {...divProps}>
127
- <svg
128
- viewBox={`0 0 ${viewBox[0]} ${viewBox[1]}`}
129
- preserveAspectRatio="none"
130
- style={{
131
- position: 'absolute',
132
- top: 0,
133
- left: 0,
134
- right: 0,
135
- bottom: 0,
136
- overflow: 'hidden',
137
- }}
138
- >
139
- <polyline
140
- transform={`scale(1, -1) translate(0, -${viewBox[1]})`}
141
- fill={fillColor}
142
- stroke={strokeColor}
143
- strokeWidth={strokeWidth}
144
- points={points}
145
- />
146
- </svg>
147
- </Box>
148
- </Box>
149
- );
150
- }
151
- }
152
-
153
- export const Chart = {
154
- Line: LineChart,
155
- };