tgui-core 1.0.2 → 1.0.4

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 (158) hide show
  1. package/{src/components → components}/AnimatedNumber.tsx +185 -185
  2. package/{src/components → components}/BlockQuote.tsx +15 -15
  3. package/{src/components → components}/BodyZoneSelector.tsx +149 -149
  4. package/{src/components → components}/Box.tsx +255 -255
  5. package/{src/components → components}/Button.tsx +415 -415
  6. package/{src/components → components}/ByondUi.jsx +121 -121
  7. package/{src/components → components}/Chart.tsx +160 -160
  8. package/{src/components → components}/ColorBox.tsx +30 -30
  9. package/{src/components → components}/Dimmer.tsx +19 -19
  10. package/{src/components → components}/Divider.tsx +26 -26
  11. package/{src/components → components}/DmIcon.tsx +72 -72
  12. package/{src/components → components}/DraggableControl.jsx +282 -282
  13. package/{src/components → components}/Dropdown.tsx +246 -246
  14. package/{src/components → components}/Flex.tsx +105 -105
  15. package/{src/components → components}/Icon.tsx +91 -91
  16. package/{src/components → components}/Input.tsx +181 -181
  17. package/{src/components → components}/KeyListener.tsx +40 -40
  18. package/{src/components → components}/Knob.tsx +185 -185
  19. package/{src/components → components}/LabeledList.tsx +130 -130
  20. package/{src/components → components}/MenuBar.tsx +233 -238
  21. package/{src/components → components}/Modal.tsx +25 -25
  22. package/{src/components → components}/NoticeBox.tsx +48 -48
  23. package/{src/components → components}/NumberInput.tsx +328 -328
  24. package/{src/components → components}/ProgressBar.tsx +79 -79
  25. package/{src/components → components}/RestrictedInput.jsx +301 -301
  26. package/{src/components → components}/RoundGauge.tsx +189 -189
  27. package/{src/components → components}/Section.tsx +125 -125
  28. package/{src/components → components}/Slider.tsx +173 -173
  29. package/{src/components → components}/Stack.tsx +101 -101
  30. package/{src/components → components}/Table.tsx +90 -90
  31. package/{src/components → components}/Tabs.tsx +90 -90
  32. package/{src/components → components}/TextArea.tsx +198 -198
  33. package/{src/components → components}/TimeDisplay.jsx +64 -64
  34. package/components/index.ts +51 -0
  35. package/{src/debug/KitchenSink.jsx → debug/KitchenSink.tsx} +56 -56
  36. package/{src/debug/actions.js → debug/actions.ts} +11 -11
  37. package/{src/debug/hooks.js → debug/hooks.ts} +10 -10
  38. package/{src/debug/middleware.js → debug/middleware.ts} +67 -86
  39. package/{src/debug/reducer.js → debug/reducer.ts} +27 -22
  40. package/{src/debug/selectors.js → debug/selectors.ts} +7 -7
  41. package/{src/layouts → layouts}/Layout.tsx +75 -75
  42. package/{src/layouts → layouts}/NtosWindow.tsx +162 -162
  43. package/{src/layouts → layouts}/Pane.tsx +56 -56
  44. package/{src/layouts → layouts}/Window.tsx +227 -227
  45. package/layouts/index.ts +10 -0
  46. package/package.json +3 -2
  47. package/src/assets.ts +43 -43
  48. package/src/backend.ts +368 -369
  49. package/src/drag.ts +280 -280
  50. package/src/events.ts +237 -237
  51. package/src/hotkeys.ts +212 -212
  52. package/src/renderer.ts +50 -50
  53. package/stories/Blink.stories.tsx +20 -0
  54. package/stories/BlockQuote.stories.tsx +23 -0
  55. package/stories/Box.stories.tsx +27 -0
  56. package/stories/Button.stories.tsx +68 -0
  57. package/stories/ByondUi.stories.tsx +45 -0
  58. package/stories/Collapsible.stories.tsx +23 -0
  59. package/stories/Flex.stories.tsx +68 -0
  60. package/stories/Input.stories.tsx +124 -0
  61. package/stories/LabeledList.stories.tsx +73 -0
  62. package/stories/Popper.stories.tsx +58 -0
  63. package/stories/ProgressBar.stories.tsx +58 -0
  64. package/stories/Stack.stories.tsx +55 -0
  65. package/stories/Storage.stories.tsx +46 -0
  66. package/stories/Themes.stories.tsx +30 -0
  67. package/stories/Tooltip.stories.tsx +48 -0
  68. package/stories/common.tsx +19 -0
  69. package/tsconfig.json +0 -21
  70. package/src/components/Grid.tsx +0 -44
  71. /package/{src/common → common}/collections.ts +0 -0
  72. /package/{src/common → common}/color.ts +0 -0
  73. /package/{src/common → common}/events.ts +0 -0
  74. /package/{src/common → common}/exhaustive.ts +0 -0
  75. /package/{src/common → common}/fp.ts +0 -0
  76. /package/{src/common → common}/keycodes.ts +0 -0
  77. /package/{src/common → common}/keys.ts +0 -0
  78. /package/{src/common → common}/math.ts +0 -0
  79. /package/{src/common → common}/perf.ts +0 -0
  80. /package/{src/common → common}/random.ts +0 -0
  81. /package/{src/common → common}/react.ts +0 -0
  82. /package/{src/common → common}/redux.ts +0 -0
  83. /package/{src/common → common}/storage.js +0 -0
  84. /package/{src/common → common}/string.ts +0 -0
  85. /package/{src/common → common}/timer.ts +0 -0
  86. /package/{src/common → common}/type-utils.ts +0 -0
  87. /package/{src/common → common}/types.ts +0 -0
  88. /package/{src/common → common}/uuid.ts +0 -0
  89. /package/{src/common → common}/vector.ts +0 -0
  90. /package/{src/components → components}/Autofocus.tsx +0 -0
  91. /package/{src/components → components}/Blink.jsx +0 -0
  92. /package/{src/components → components}/Collapsible.tsx +0 -0
  93. /package/{src/components → components}/Dialog.tsx +0 -0
  94. /package/{src/components → components}/FakeTerminal.jsx +0 -0
  95. /package/{src/components → components}/FitText.tsx +0 -0
  96. /package/{src/components → components}/Image.tsx +0 -0
  97. /package/{src/components → components}/InfinitePlane.jsx +0 -0
  98. /package/{src/components → components}/LabeledControls.tsx +0 -0
  99. /package/{src/components → components}/Popper.tsx +0 -0
  100. /package/{src/components → components}/StyleableSection.tsx +0 -0
  101. /package/{src/components → components}/Tooltip.tsx +0 -0
  102. /package/{src/components → components}/TrackOutsideClicks.tsx +0 -0
  103. /package/{src/components → components}/VirtualList.tsx +0 -0
  104. /package/{src/debug → debug}/index.ts +0 -0
  105. /package/{src/styles → styles}/base.scss +0 -0
  106. /package/{src/styles → styles}/colors.scss +0 -0
  107. /package/{src/styles → styles}/components/BlockQuote.scss +0 -0
  108. /package/{src/styles → styles}/components/Button.scss +0 -0
  109. /package/{src/styles → styles}/components/ColorBox.scss +0 -0
  110. /package/{src/styles → styles}/components/Dialog.scss +0 -0
  111. /package/{src/styles → styles}/components/Dimmer.scss +0 -0
  112. /package/{src/styles → styles}/components/Divider.scss +0 -0
  113. /package/{src/styles → styles}/components/Dropdown.scss +0 -0
  114. /package/{src/styles → styles}/components/Flex.scss +0 -0
  115. /package/{src/styles → styles}/components/Icon.scss +0 -0
  116. /package/{src/styles → styles}/components/Input.scss +0 -0
  117. /package/{src/styles → styles}/components/Knob.scss +0 -0
  118. /package/{src/styles → styles}/components/LabeledList.scss +0 -0
  119. /package/{src/styles → styles}/components/MenuBar.scss +0 -0
  120. /package/{src/styles → styles}/components/Modal.scss +0 -0
  121. /package/{src/styles → styles}/components/NoticeBox.scss +0 -0
  122. /package/{src/styles → styles}/components/NumberInput.scss +0 -0
  123. /package/{src/styles → styles}/components/ProgressBar.scss +0 -0
  124. /package/{src/styles → styles}/components/RoundGauge.scss +0 -0
  125. /package/{src/styles → styles}/components/Section.scss +0 -0
  126. /package/{src/styles → styles}/components/Slider.scss +0 -0
  127. /package/{src/styles → styles}/components/Stack.scss +0 -0
  128. /package/{src/styles → styles}/components/Table.scss +0 -0
  129. /package/{src/styles → styles}/components/Tabs.scss +0 -0
  130. /package/{src/styles → styles}/components/TextArea.scss +0 -0
  131. /package/{src/styles → styles}/components/Tooltip.scss +0 -0
  132. /package/{src/styles → styles}/functions.scss +0 -0
  133. /package/{src/styles → styles}/layouts/Layout.scss +0 -0
  134. /package/{src/styles → styles}/layouts/NtosHeader.scss +0 -0
  135. /package/{src/styles → styles}/layouts/NtosWindow.scss +0 -0
  136. /package/{src/styles → styles}/layouts/TitleBar.scss +0 -0
  137. /package/{src/styles → styles}/layouts/Window.scss +0 -0
  138. /package/{src/styles → styles}/main.scss +0 -0
  139. /package/{src/styles → styles}/reset.scss +0 -0
  140. /package/{src/styles → styles}/themes/abductor.scss +0 -0
  141. /package/{src/styles → styles}/themes/admin.scss +0 -0
  142. /package/{src/styles → styles}/themes/cardtable.scss +0 -0
  143. /package/{src/styles → styles}/themes/hackerman.scss +0 -0
  144. /package/{src/styles → styles}/themes/malfunction.scss +0 -0
  145. /package/{src/styles → styles}/themes/neutral.scss +0 -0
  146. /package/{src/styles → styles}/themes/ntOS95.scss +0 -0
  147. /package/{src/styles → styles}/themes/ntos.scss +0 -0
  148. /package/{src/styles → styles}/themes/ntos_cat.scss +0 -0
  149. /package/{src/styles → styles}/themes/ntos_darkmode.scss +0 -0
  150. /package/{src/styles → styles}/themes/ntos_lightmode.scss +0 -0
  151. /package/{src/styles → styles}/themes/ntos_spooky.scss +0 -0
  152. /package/{src/styles → styles}/themes/ntos_synth.scss +0 -0
  153. /package/{src/styles → styles}/themes/ntos_terminal.scss +0 -0
  154. /package/{src/styles → styles}/themes/paper.scss +0 -0
  155. /package/{src/styles → styles}/themes/retro.scss +0 -0
  156. /package/{src/styles → styles}/themes/spookyconsole.scss +0 -0
  157. /package/{src/styles → styles}/themes/syndicate.scss +0 -0
  158. /package/{src/styles → styles}/themes/wizard.scss +0 -0
@@ -1,246 +1,246 @@
1
- import { classes } from '../common/react';
2
- import { ReactNode, useEffect, useRef, useState } from 'react';
3
-
4
- import { BoxProps, unit } from './Box';
5
- import { Button } from './Button';
6
- import { Icon } from './Icon';
7
- import { Popper } from './Popper';
8
-
9
- export type DropdownEntry = {
10
- displayText: ReactNode;
11
- value: string | number;
12
- };
13
-
14
- type DropdownOption = string | DropdownEntry;
15
-
16
- type Props = {
17
- /** An array of strings which will be displayed in the
18
- dropdown when open. See Dropdown.tsx for more advanced usage with DropdownEntry */
19
- options: DropdownOption[];
20
- /** Called when a value is picked from the list, `value` is the value that was picked */
21
- onSelected: (value: any) => void;
22
- /** Currently selected entry to display. Can be left stateless to permanently display this value. */
23
- selected: DropdownOption | null | undefined;
24
- } & Partial<{
25
- /** Whether to scroll automatically on open. Defaults to true */
26
- autoScroll: boolean;
27
- /** Whether to display previous / next buttons */
28
- buttons: boolean;
29
- /** Whether to clip the selected text */
30
- clipSelectedText: boolean;
31
- /** Color of dropdown button */
32
- color: string;
33
- /** Disables the dropdown */
34
- disabled: boolean;
35
- /** Overwrites selection text with this. Good for objects etc. */
36
- displayText: ReactNode;
37
- /** Icon to display in dropdown button */
38
- icon: string;
39
- /** Angle of the icon */
40
- iconRotation: number;
41
- /** Whether or not the icon should spin */
42
- iconSpin: boolean;
43
- /** Width of the dropdown menu. Default: 15rem */
44
- menuWidth: string;
45
- /** Whether or not the arrow on the right hand side of the dropdown button is visible */
46
- noChevron: boolean;
47
- /** Called when dropdown button is clicked */
48
- onClick: (event) => void;
49
- /** Dropdown renders over instead of below */
50
- over: boolean;
51
- /** Text to show when nothing has been selected. */
52
- placeholder: string;
53
- }> &
54
- BoxProps;
55
-
56
- enum DIRECTION {
57
- Previous = 'previous',
58
- Next = 'next',
59
- Current = 'current',
60
- }
61
-
62
- const NONE = -1;
63
-
64
- function getOptionValue(option: DropdownOption) {
65
- return typeof option === 'string' ? option : option.value;
66
- }
67
-
68
- export function Dropdown(props: Props) {
69
- const {
70
- autoScroll = true,
71
- buttons,
72
- className,
73
- clipSelectedText = true,
74
- color = 'default',
75
- disabled,
76
- displayText,
77
- icon,
78
- iconRotation,
79
- iconSpin,
80
- menuWidth = '15rem',
81
- noChevron,
82
- onClick,
83
- onSelected,
84
- options = [],
85
- over,
86
- placeholder = 'Select...',
87
- selected,
88
- width = '15rem',
89
- } = props;
90
-
91
- const [open, setOpen] = useState(false);
92
- const adjustedOpen = over ? !open : open;
93
- const innerRef = useRef<HTMLDivElement>(null);
94
-
95
- const selectedIndex =
96
- options.findIndex((option) => getOptionValue(option) === selected) || 0;
97
-
98
- function scrollTo(position: number) {
99
- let scrollPos = position;
100
- if (position < selectedIndex) {
101
- scrollPos = position < 2 ? 0 : position - 2;
102
- } else {
103
- scrollPos =
104
- position > options.length - 3 ? options.length - 1 : position - 2;
105
- }
106
-
107
- const element = innerRef.current?.children[scrollPos];
108
- element?.scrollIntoView({ block: 'nearest' });
109
- }
110
-
111
- /** Update the selected value when clicking the left/right buttons */
112
- function updateSelected(direction: DIRECTION) {
113
- if (options.length < 1 || disabled) {
114
- return;
115
- }
116
-
117
- const startIndex = 0;
118
- const endIndex = options.length - 1;
119
-
120
- let newIndex: number;
121
- if (selectedIndex < 0) {
122
- newIndex = direction === 'next' ? endIndex : startIndex; // No selection yet
123
- } else if (direction === 'next') {
124
- newIndex = selectedIndex === endIndex ? startIndex : selectedIndex + 1; // Move to next option
125
- } else {
126
- newIndex = selectedIndex === startIndex ? endIndex : selectedIndex - 1; // Move to previous option
127
- }
128
-
129
- if (open && autoScroll) {
130
- scrollTo(newIndex);
131
- }
132
- onSelected?.(getOptionValue(options[newIndex]));
133
- }
134
-
135
- /** Allows the menu to be scrollable on open */
136
- useEffect(() => {
137
- if (!open) {
138
- return;
139
- }
140
-
141
- if (autoScroll && selectedIndex !== NONE) {
142
- scrollTo(selectedIndex);
143
- }
144
-
145
- innerRef.current?.focus();
146
- }, [open]);
147
-
148
- return (
149
- <Popper
150
- isOpen={open}
151
- onClickOutside={() => setOpen(false)}
152
- placement={over ? 'top-start' : 'bottom-start'}
153
- content={
154
- <div
155
- className="Layout Dropdown__menu"
156
- style={{ minWidth: menuWidth }}
157
- ref={innerRef}
158
- >
159
- {options.length === 0 && (
160
- <div className="Dropdown__menuentry">No options</div>
161
- )}
162
-
163
- {options.map((option, index) => {
164
- const value = getOptionValue(option);
165
-
166
- return (
167
- <div
168
- className={classes([
169
- 'Dropdown__menuentry',
170
- selected === value && 'selected',
171
- ])}
172
- key={index}
173
- onClick={() => {
174
- setOpen(false);
175
- onSelected?.(value);
176
- }}
177
- >
178
- {typeof option === 'string' ? option : option.displayText}
179
- </div>
180
- );
181
- })}
182
- </div>
183
- }
184
- >
185
- <div className="Dropdown" style={{ width: unit(width) }}>
186
- <div
187
- className={classes([
188
- 'Dropdown__control',
189
- 'Button',
190
- 'Button--dropdown',
191
- 'Button--color--' + color,
192
- disabled && 'Button--disabled',
193
- className,
194
- ])}
195
- onClick={(event) => {
196
- if (disabled && !open) {
197
- return;
198
- }
199
- setOpen(!open);
200
- onClick?.(event);
201
- }}
202
- >
203
- {icon && (
204
- <Icon mr={1} name={icon} rotation={iconRotation} spin={iconSpin} />
205
- )}
206
- <span
207
- className="Dropdown__selected-text"
208
- style={{
209
- overflow: clipSelectedText ? 'hidden' : 'visible',
210
- }}
211
- >
212
- {displayText ||
213
- (selected && getOptionValue(selected)) ||
214
- placeholder}
215
- </span>
216
- {!noChevron && (
217
- <span className="Dropdown__arrow-button">
218
- <Icon name={adjustedOpen ? 'chevron-up' : 'chevron-down'} />
219
- </span>
220
- )}
221
- </div>
222
- {buttons && (
223
- <>
224
- <Button
225
- disabled={disabled}
226
- height={1.8}
227
- icon="chevron-left"
228
- onClick={() => {
229
- updateSelected(DIRECTION.Previous);
230
- }}
231
- />
232
-
233
- <Button
234
- disabled={disabled}
235
- height={1.8}
236
- icon="chevron-right"
237
- onClick={() => {
238
- updateSelected(DIRECTION.Next);
239
- }}
240
- />
241
- </>
242
- )}
243
- </div>
244
- </Popper>
245
- );
246
- }
1
+ import { classes } from '../common/react';
2
+ import { ReactNode, useEffect, useRef, useState } from 'react';
3
+
4
+ import { BoxProps, unit } from './Box';
5
+ import { Button } from './Button';
6
+ import { Icon } from './Icon';
7
+ import { Popper } from './Popper';
8
+
9
+ export type DropdownEntry = {
10
+ displayText: ReactNode;
11
+ value: string | number;
12
+ };
13
+
14
+ type DropdownOption = string | DropdownEntry;
15
+
16
+ type Props = {
17
+ /** An array of strings which will be displayed in the
18
+ dropdown when open. See Dropdown.tsx for more advanced usage with DropdownEntry */
19
+ options: DropdownOption[];
20
+ /** Called when a value is picked from the list, `value` is the value that was picked */
21
+ onSelected: (value: any) => void;
22
+ /** Currently selected entry to display. Can be left stateless to permanently display this value. */
23
+ selected: DropdownOption | null | undefined;
24
+ } & Partial<{
25
+ /** Whether to scroll automatically on open. Defaults to true */
26
+ autoScroll: boolean;
27
+ /** Whether to display previous / next buttons */
28
+ buttons: boolean;
29
+ /** Whether to clip the selected text */
30
+ clipSelectedText: boolean;
31
+ /** Color of dropdown button */
32
+ color: string;
33
+ /** Disables the dropdown */
34
+ disabled: boolean;
35
+ /** Overwrites selection text with this. Good for objects etc. */
36
+ displayText: ReactNode;
37
+ /** Icon to display in dropdown button */
38
+ icon: string;
39
+ /** Angle of the icon */
40
+ iconRotation: number;
41
+ /** Whether or not the icon should spin */
42
+ iconSpin: boolean;
43
+ /** Width of the dropdown menu. Default: 15rem */
44
+ menuWidth: string;
45
+ /** Whether or not the arrow on the right hand side of the dropdown button is visible */
46
+ noChevron: boolean;
47
+ /** Called when dropdown button is clicked */
48
+ onClick: (event) => void;
49
+ /** Dropdown renders over instead of below */
50
+ over: boolean;
51
+ /** Text to show when nothing has been selected. */
52
+ placeholder: string;
53
+ }> &
54
+ BoxProps;
55
+
56
+ enum DIRECTION {
57
+ Previous = 'previous',
58
+ Next = 'next',
59
+ Current = 'current',
60
+ }
61
+
62
+ const NONE = -1;
63
+
64
+ function getOptionValue(option: DropdownOption) {
65
+ return typeof option === 'string' ? option : option.value;
66
+ }
67
+
68
+ export function Dropdown(props: Props) {
69
+ const {
70
+ autoScroll = true,
71
+ buttons,
72
+ className,
73
+ clipSelectedText = true,
74
+ color = 'default',
75
+ disabled,
76
+ displayText,
77
+ icon,
78
+ iconRotation,
79
+ iconSpin,
80
+ menuWidth = '15rem',
81
+ noChevron,
82
+ onClick,
83
+ onSelected,
84
+ options = [],
85
+ over,
86
+ placeholder = 'Select...',
87
+ selected,
88
+ width = '15rem',
89
+ } = props;
90
+
91
+ const [open, setOpen] = useState(false);
92
+ const adjustedOpen = over ? !open : open;
93
+ const innerRef = useRef<HTMLDivElement>(null);
94
+
95
+ const selectedIndex =
96
+ options.findIndex((option) => getOptionValue(option) === selected) || 0;
97
+
98
+ function scrollTo(position: number) {
99
+ let scrollPos = position;
100
+ if (position < selectedIndex) {
101
+ scrollPos = position < 2 ? 0 : position - 2;
102
+ } else {
103
+ scrollPos =
104
+ position > options.length - 3 ? options.length - 1 : position - 2;
105
+ }
106
+
107
+ const element = innerRef.current?.children[scrollPos];
108
+ element?.scrollIntoView({ block: 'nearest' });
109
+ }
110
+
111
+ /** Update the selected value when clicking the left/right buttons */
112
+ function updateSelected(direction: DIRECTION) {
113
+ if (options.length < 1 || disabled) {
114
+ return;
115
+ }
116
+
117
+ const startIndex = 0;
118
+ const endIndex = options.length - 1;
119
+
120
+ let newIndex: number;
121
+ if (selectedIndex < 0) {
122
+ newIndex = direction === 'next' ? endIndex : startIndex; // No selection yet
123
+ } else if (direction === 'next') {
124
+ newIndex = selectedIndex === endIndex ? startIndex : selectedIndex + 1; // Move to next option
125
+ } else {
126
+ newIndex = selectedIndex === startIndex ? endIndex : selectedIndex - 1; // Move to previous option
127
+ }
128
+
129
+ if (open && autoScroll) {
130
+ scrollTo(newIndex);
131
+ }
132
+ onSelected?.(getOptionValue(options[newIndex]));
133
+ }
134
+
135
+ /** Allows the menu to be scrollable on open */
136
+ useEffect(() => {
137
+ if (!open) {
138
+ return;
139
+ }
140
+
141
+ if (autoScroll && selectedIndex !== NONE) {
142
+ scrollTo(selectedIndex);
143
+ }
144
+
145
+ innerRef.current?.focus();
146
+ }, [open]);
147
+
148
+ return (
149
+ <Popper
150
+ isOpen={open}
151
+ onClickOutside={() => setOpen(false)}
152
+ placement={over ? 'top-start' : 'bottom-start'}
153
+ content={
154
+ <div
155
+ className="Layout Dropdown__menu"
156
+ style={{ minWidth: menuWidth }}
157
+ ref={innerRef}
158
+ >
159
+ {options.length === 0 && (
160
+ <div className="Dropdown__menuentry">No options</div>
161
+ )}
162
+
163
+ {options.map((option, index) => {
164
+ const value = getOptionValue(option);
165
+
166
+ return (
167
+ <div
168
+ className={classes([
169
+ 'Dropdown__menuentry',
170
+ selected === value && 'selected',
171
+ ])}
172
+ key={index}
173
+ onClick={() => {
174
+ setOpen(false);
175
+ onSelected?.(value);
176
+ }}
177
+ >
178
+ {typeof option === 'string' ? option : option.displayText}
179
+ </div>
180
+ );
181
+ })}
182
+ </div>
183
+ }
184
+ >
185
+ <div className="Dropdown" style={{ width: unit(width) }}>
186
+ <div
187
+ className={classes([
188
+ 'Dropdown__control',
189
+ 'Button',
190
+ 'Button--dropdown',
191
+ 'Button--color--' + color,
192
+ disabled && 'Button--disabled',
193
+ className,
194
+ ])}
195
+ onClick={(event) => {
196
+ if (disabled && !open) {
197
+ return;
198
+ }
199
+ setOpen(!open);
200
+ onClick?.(event);
201
+ }}
202
+ >
203
+ {icon && (
204
+ <Icon mr={1} name={icon} rotation={iconRotation} spin={iconSpin} />
205
+ )}
206
+ <span
207
+ className="Dropdown__selected-text"
208
+ style={{
209
+ overflow: clipSelectedText ? 'hidden' : 'visible',
210
+ }}
211
+ >
212
+ {displayText ||
213
+ (selected && getOptionValue(selected)) ||
214
+ placeholder}
215
+ </span>
216
+ {!noChevron && (
217
+ <span className="Dropdown__arrow-button">
218
+ <Icon name={adjustedOpen ? 'chevron-up' : 'chevron-down'} />
219
+ </span>
220
+ )}
221
+ </div>
222
+ {buttons && (
223
+ <>
224
+ <Button
225
+ disabled={disabled}
226
+ height={1.8}
227
+ icon="chevron-left"
228
+ onClick={() => {
229
+ updateSelected(DIRECTION.Previous);
230
+ }}
231
+ />
232
+
233
+ <Button
234
+ disabled={disabled}
235
+ height={1.8}
236
+ icon="chevron-right"
237
+ onClick={() => {
238
+ updateSelected(DIRECTION.Next);
239
+ }}
240
+ />
241
+ </>
242
+ )}
243
+ </div>
244
+ </Popper>
245
+ );
246
+ }