From 5e7fa16c725f0067f67b2df8e65ff0b4ec121e04 Mon Sep 17 00:00:00 2001 From: Iajret Creature <122297233+Steals-The-PRs@users.noreply.github.com> Date: Sun, 21 Apr 2024 14:22:41 +0300 Subject: [PATCH] [MIRROR] Makes dropdowns better (#2986) * [MIRROR] Makes dropdowns better (#2078) * Makes dropdowns better (#82697) ## About The Pull Request Kind of a pain to work with, confusing people with its prop names (many such cases!) After recently discovering deathmatch it's very obvious to me how broken it is, so I made it less so (now comes with a complete ui upgrade!) It now scrolls with the selection and to the selection on open, which felt like major QoL
pics/vids In motion ![7627sWJ2nS](https://github.com/tgstation/tgstation/assets/42397676/982427b2-6dc8-4c91-90cf-6e17d211f5ae) Deathmatch got some UI facelifts ![GAotCHxtZg](https://github.com/tgstation/tgstation/assets/42397676/769317ad-7a9f-410a-a60f-4ddfb377210c) ![Ca2UJSpxlY](https://github.com/tgstation/tgstation/assets/42397676/ea188cda-a79b-4ca0-9209-1c69f57231dc) Fixes #75741 ![image](https://github.com/tgstation/tgstation/assets/42397676/d30a1ae4-cf08-4512-9ce6-5499084647b4)
## Why It's Good For The Game Better UX Bug fixes Potential exploit patched (ui validation for ai voice changer) Fixes #81506 ## Changelog :cl: fix: Dropdowns received some much-needed QoL, like having the scrollbar follow your selection. fix: AI voice changer now shows its current voice selection. fix: Deathmatch screen has been touched up. fix: Prefs menu has their dropdowns simplified, hopefully fixing issues /:cl: --------- Co-authored-by: san7890 * Makes dropdowns better * Initial pass, things still broken * Initial pass, things still broken * Update LimbsPage.tsx --------- Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Co-authored-by: san7890 Co-authored-by: Mal <13398309+vinylspiders@users.noreply.github.com> * Update character_voice.tsx --------- Co-authored-by: NovaBot <154629622+NovaBot13@users.noreply.github.com> Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Co-authored-by: san7890 Co-authored-by: Mal <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: Iajret --- .../antagonists/malf_ai/malf_ai_modules.dm | 21 +- tgui/packages/tgui/components/Dropdown.tsx | 206 ++++---- tgui/packages/tgui/interfaces/AdminFax.jsx | 5 +- tgui/packages/tgui/interfaces/AdminPDA.jsx | 3 +- .../tgui/interfaces/AiVoiceChanger.tsx | 36 +- tgui/packages/tgui/interfaces/Changelog.jsx | 4 +- .../tgui/interfaces/CircuitModule.jsx | 2 +- .../tgui/interfaces/CircuitSignalHandler.tsx | 2 +- .../tgui/interfaces/CommandReport.tsx | 4 +- .../tgui/interfaces/DeathmatchLobby.tsx | 468 +++++++++++------- .../tgui/interfaces/DeathmatchPanel.jsx | 95 ---- .../tgui/interfaces/DeathmatchPanel.tsx | 162 ++++++ .../IntegratedCircuit/ComponentMenu.jsx | 3 +- .../IntegratedCircuit/FundamentalTypes.jsx | 2 +- .../IntegratedCircuit/VariableMenu.jsx | 4 +- .../tgui/interfaces/LibraryConsole.jsx | 2 +- tgui/packages/tgui/interfaces/MODsuit.tsx | 2 +- tgui/packages/tgui/interfaces/MineBot.tsx | 2 +- tgui/packages/tgui/interfaces/NavBeacon.tsx | 8 +- tgui/packages/tgui/interfaces/NtosCard.tsx | 3 +- .../tgui/interfaces/NtosRoboControl.jsx | 26 +- .../packages/tgui/interfaces/NtosScipaper.jsx | 8 +- .../tgui/interfaces/NtosVirtualPet.tsx | 6 +- .../tgui/interfaces/PlaneMasterDebug.tsx | 1 - .../CharacterPreferenceWindow.tsx | 4 +- .../interfaces/PreferencesMenu/JobsPage.tsx | 13 +- .../interfaces/PreferencesMenu/LimbsPage.tsx | 11 +- .../PreferencesMenu/RandomizationButton.tsx | 5 +- .../preferences/features/base.tsx | 143 +----- .../character_preferences/ai_core_display.tsx | 3 +- .../ai_emote_display.tsx | 2 +- .../ai_hologram_display.tsx | 2 +- .../character_preferences/body_type.tsx | 3 +- .../character_preferences/food_allergy.tsx | 3 +- .../character_preferences/glasses.tsx | 2 +- .../character_preferences/hemiplegic.tsx | 3 +- .../features/character_preferences/junkie.tsx | 3 +- .../character_preferences/language.tsx | 3 +- .../nova/antag_optin.tsx | 3 +- .../character_preferences/nova/brain_type.tsx | 3 +- .../nova/character_laugh.tsx | 3 +- .../nova/character_scream.tsx | 3 +- .../nova/echolocation.tsx | 2 +- .../character_preferences/nova/entombed.tsx | 2 +- .../character_preferences/nova/genitals.tsx | 2 +- .../nova/height_scaling.tsx | 3 +- .../nova/loadout_override_preference.tsx | 3 +- .../character_preferences/nova/pet_owner.tsx | 8 +- .../nova/photophobia.tsx | 3 +- .../nova/species_features.tsx | 2 +- .../nova/underworld_connections.tsx | 8 +- .../features/character_preferences/pda.tsx | 8 +- .../features/character_preferences/phobia.tsx | 3 +- .../character_preferences/pride_pin.tsx | 3 +- .../character_preferences/prisoner_crime.tsx | 3 +- .../character_preferences/prosthetic_limb.tsx | 3 +- .../prosthetic_organ.tsx | 3 +- .../security_department.tsx | 3 +- .../character_preferences/skin_tone.tsx | 78 +-- .../tff/character_voice.tsx | 2 +- .../trans_prosthetic.tsx | 3 +- .../character_preferences/tts_voice.tsx | 2 +- .../character_preferences/uplink_loc.tsx | 3 +- .../features/game_preferences/admin.tsx | 2 +- .../features/game_preferences/ghost.tsx | 5 +- .../game_preferences/ghost_lighting.tsx | 3 +- .../features/game_preferences/mod_select.tsx | 3 +- .../game_preferences/nova/erp_preferences.tsx | 8 +- .../features/game_preferences/parallax.tsx | 3 +- .../game_preferences/preferred_map.tsx | 3 +- .../features/game_preferences/screentips.tsx | 2 +- .../features/game_preferences/sounds.tsx | 2 +- .../features/game_preferences/ui_style.tsx | 1 - .../preferences/features/species_features.tsx | 2 +- .../packages/tgui/interfaces/ProcCallMenu.tsx | 4 +- .../RequestsConsole/MessageWriteTab.tsx | 6 +- .../tgui/interfaces/StationTraitsPanel.tsx | 4 +- .../tgui/interfaces/TramController.tsx | 2 +- 78 files changed, 786 insertions(+), 698 deletions(-) delete mode 100644 tgui/packages/tgui/interfaces/DeathmatchPanel.jsx create mode 100644 tgui/packages/tgui/interfaces/DeathmatchPanel.tsx diff --git a/code/modules/antagonists/malf_ai/malf_ai_modules.dm b/code/modules/antagonists/malf_ai/malf_ai_modules.dm index 669c50dab7a..276b515b52c 100644 --- a/code/modules/antagonists/malf_ai/malf_ai_modules.dm +++ b/code/modules/antagonists/malf_ai/malf_ai_modules.dm @@ -945,6 +945,8 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module)) var/prev_verbs /// Saved span state, used to restore after a voice change var/prev_span + /// The list of available voices + var/static/list/voice_options = list("normal", SPAN_ROBOT, SPAN_YELL, SPAN_CLOWN) /obj/machinery/ai_voicechanger/Initialize(mapload) . = ..() @@ -972,11 +974,12 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module)) /obj/machinery/ai_voicechanger/ui_data(mob/user) var/list/data = list() - data["voices"] = list("normal", SPAN_ROBOT, SPAN_YELL, SPAN_CLOWN) //manually adding this since i dont see other option + data["voices"] = voice_options data["loud"] = loudvoice data["on"] = changing_voice data["say_verb"] = say_verb data["name"] = say_name + data["selected"] = say_span || owner.speech_span return data /obj/machinery/ai_voicechanger/ui_act(action, params) @@ -1010,9 +1013,23 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module)) if(changing_voice) owner.radio.use_command = loudvoice if("look") - say_span = params["look"] + var/selection = params["look"] + if(isnull(selection)) + return FALSE + + var/found = FALSE + for(var/option in voice_options) + if(option == selection) + found = TRUE + break + if(!found) + stack_trace("User attempted to select an unavailable voice option") + return FALSE + + say_span = selection if(changing_voice) owner.speech_span = say_span + to_chat(usr, span_notice("Voice set to [selection].")) if("verb") say_verb = params["verb"] if(changing_voice) diff --git a/tgui/packages/tgui/components/Dropdown.tsx b/tgui/packages/tgui/components/Dropdown.tsx index a103a7466d3..1cf2b53ecfd 100644 --- a/tgui/packages/tgui/components/Dropdown.tsx +++ b/tgui/packages/tgui/components/Dropdown.tsx @@ -1,12 +1,12 @@ import { classes } from 'common/react'; -import { ReactNode, useCallback, useEffect, useRef, useState } from 'react'; +import { ReactNode, useEffect, useRef, useState } from 'react'; import { BoxProps, unit } from './Box'; import { Button } from './Button'; import { Icon } from './Icon'; import { Popper } from './Popper'; -type DropdownEntry = { +export type DropdownEntry = { displayText: ReactNode; value: string | number; }; @@ -19,7 +19,11 @@ type Props = { options: DropdownOption[]; /** Called when a value is picked from the list, `value` is the value that was picked */ onSelected: (value: any) => void; + /** Currently selected entry to display. Can be left stateless to permanently display this value. */ + selected: DropdownOption | null | undefined; } & Partial<{ + /** Whether to scroll automatically on open. Defaults to true */ + autoScroll: boolean; /** Whether to display previous / next buttons */ buttons: boolean; /** Whether to clip the selected text */ @@ -28,7 +32,7 @@ type Props = { color: string; /** Disables the dropdown */ disabled: boolean; - /** Text to always display in place of the selected text */ + /** Overwrites selection text with this. Good for objects etc. */ displayText: ReactNode; /** Icon to display in dropdown button */ icon: string; @@ -44,17 +48,26 @@ type Props = { onClick: (event) => void; /** Dropdown renders over instead of below */ over: boolean; - /** Currently selected entry */ - selected: string | number; + /** Text to show when nothing has been selected. */ + placeholder: string; }> & BoxProps; +enum DIRECTION { + Previous = 'previous', + Next = 'next', + Current = 'current', +} + +const NONE = -1; + function getOptionValue(option: DropdownOption) { return typeof option === 'string' ? option : option.value; } export function Dropdown(props: Props) { const { + autoScroll = true, buttons, className, clipSelectedText = true, @@ -70,46 +83,64 @@ export function Dropdown(props: Props) { onSelected, options = [], over, + placeholder = 'Select...', selected, - width, + width = '15rem', } = props; const [open, setOpen] = useState(false); const adjustedOpen = over ? !open : open; const innerRef = useRef(null); - /** Update the selected value when clicking the left/right buttons */ - const updateSelected = useCallback( - (direction: 'previous' | 'next') => { - if (options.length < 1 || disabled) { - return; - } - const startIndex = 0; - const endIndex = options.length - 1; + const selectedIndex = + options.findIndex((option) => getOptionValue(option) === selected) || 0; - let selectedIndex = options.findIndex( - (option) => getOptionValue(option) === selected, - ); + function scrollTo(position: number) { + let scrollPos = position; + if (position < selectedIndex) { + scrollPos = position < 2 ? 0 : position - 2; + } else { + scrollPos = + position > options.length - 3 ? options.length - 1 : position - 2; + } - if (selectedIndex < 0) { - selectedIndex = direction === 'next' ? endIndex : startIndex; - } + const element = innerRef.current?.children[scrollPos]; + element?.scrollIntoView({ block: 'nearest' }); + } - let newIndex = selectedIndex; - if (direction === 'next') { - newIndex = selectedIndex === endIndex ? startIndex : ++selectedIndex; - } else { - newIndex = selectedIndex === startIndex ? endIndex : --selectedIndex; - } - - onSelected?.(getOptionValue(options[newIndex])); - }, - [disabled, onSelected, options, selected], - ); + /** Update the selected value when clicking the left/right buttons */ + function updateSelected(direction: DIRECTION) { + if (options.length < 1 || disabled) { + return; + } + + const startIndex = 0; + const endIndex = options.length - 1; + + let newIndex: number; + if (selectedIndex < 0) { + newIndex = direction === 'next' ? endIndex : startIndex; // No selection yet + } else if (direction === 'next') { + newIndex = selectedIndex === endIndex ? startIndex : selectedIndex + 1; // Move to next option + } else { + newIndex = selectedIndex === startIndex ? endIndex : selectedIndex - 1; // Move to previous option + } + + if (open && autoScroll) { + scrollTo(newIndex); + } + onSelected?.(getOptionValue(options[newIndex])); + } /** Allows the menu to be scrollable on open */ useEffect(() => { - if (!open) return; + if (!open) { + return; + } + + if (autoScroll && selectedIndex !== NONE) { + scrollTo(selectedIndex); + } innerRef.current?.focus(); }, [open]); @@ -151,69 +182,64 @@ export function Dropdown(props: Props) { } > -
-
-
{ - if (disabled && !open) { - return; - } - setOpen(!open); - onClick?.(event); +
+
{ + if (disabled && !open) { + return; + } + setOpen(!open); + onClick?.(event); + }} + > + {icon && ( + + )} + - {icon && ( - - )} - - {displayText || selected} + {displayText || + (selected && getOptionValue(selected)) || + placeholder} + + {!noChevron && ( + + - {!noChevron && ( - - - - )} -
- {buttons && ( - <> -
+ {buttons && ( + <> +
); diff --git a/tgui/packages/tgui/interfaces/AdminFax.jsx b/tgui/packages/tgui/interfaces/AdminFax.jsx index 9aeef3247a3..3e6026d4ce4 100644 --- a/tgui/packages/tgui/interfaces/AdminFax.jsx +++ b/tgui/packages/tgui/interfaces/AdminFax.jsx @@ -63,10 +63,9 @@ export const FaxMainPanel = (props) => { setFax(value)} /> diff --git a/tgui/packages/tgui/interfaces/AdminPDA.jsx b/tgui/packages/tgui/interfaces/AdminPDA.jsx index 09570265a20..fa83f200e52 100644 --- a/tgui/packages/tgui/interfaces/AdminPDA.jsx +++ b/tgui/packages/tgui/interfaces/AdminPDA.jsx @@ -33,7 +33,8 @@ const ReceiverChoice = (props) => { showInvisible || !rcvr.invisible) .map((rcvr) => ({ diff --git a/tgui/packages/tgui/interfaces/AiVoiceChanger.tsx b/tgui/packages/tgui/interfaces/AiVoiceChanger.tsx index 9e248a01033..09c1aa04e57 100644 --- a/tgui/packages/tgui/interfaces/AiVoiceChanger.tsx +++ b/tgui/packages/tgui/interfaces/AiVoiceChanger.tsx @@ -5,37 +5,40 @@ import { Button, Dropdown, Input, LabeledList, Section } from '../components'; import { Window } from '../layouts'; type Data = { - on: BooleanLike; - voices: string[]; - say_verb: string; loud: BooleanLike; name: string; + on: BooleanLike; + say_verb: string; + selected: string; + voices: string[]; }; -export const AiVoiceChanger = (props) => { +export function AiVoiceChanger(props) { const { act, data } = useBackend(); - const { loud, name, on, say_verb, voices } = data; + const { loud, name, on, say_verb, voices, selected } = data; return ( -
+
+ onSelected={(value) => { act('look', { look: value, - }) - } + }); + }} + selected={selected} /> @@ -51,10 +54,11 @@ export const AiVoiceChanger = (props) => { {
); -}; +} diff --git a/tgui/packages/tgui/interfaces/Changelog.jsx b/tgui/packages/tgui/interfaces/Changelog.jsx index accdf2429c6..fe5d72fb088 100644 --- a/tgui/packages/tgui/interfaces/Changelog.jsx +++ b/tgui/packages/tgui/interfaces/Changelog.jsx @@ -141,7 +141,7 @@ export class Changelog extends Component { { const index = dateChoices.indexOf(value); @@ -157,7 +157,7 @@ export class Changelog extends Component { return this.getData(dates[index]); }} selected={selectedDate} - width={'150px'} + width="150px" /> diff --git a/tgui/packages/tgui/interfaces/CircuitModule.jsx b/tgui/packages/tgui/interfaces/CircuitModule.jsx index 799fea9d15f..bbb323e5e5a 100644 --- a/tgui/packages/tgui/interfaces/CircuitModule.jsx +++ b/tgui/packages/tgui/interfaces/CircuitModule.jsx @@ -130,7 +130,7 @@ const PortEntry = (props) => { diff --git a/tgui/packages/tgui/interfaces/CircuitSignalHandler.tsx b/tgui/packages/tgui/interfaces/CircuitSignalHandler.tsx index 1fc1f8397f9..66d04644391 100644 --- a/tgui/packages/tgui/interfaces/CircuitSignalHandler.tsx +++ b/tgui/packages/tgui/interfaces/CircuitSignalHandler.tsx @@ -221,7 +221,7 @@ const Entry = (props: EntryProps) => { {(options.length && ( diff --git a/tgui/packages/tgui/interfaces/CommandReport.tsx b/tgui/packages/tgui/interfaces/CommandReport.tsx index dfe8cf9ff3d..9185bebb5b4 100644 --- a/tgui/packages/tgui/interfaces/CommandReport.tsx +++ b/tgui/packages/tgui/interfaces/CommandReport.tsx @@ -117,7 +117,7 @@ const AnnouncementColor = (props) => {
act('update_announcement_color', { @@ -138,7 +138,7 @@ const AnnouncementSound = (props) => {
act('set_report_sound', { diff --git a/tgui/packages/tgui/interfaces/DeathmatchLobby.tsx b/tgui/packages/tgui/interfaces/DeathmatchLobby.tsx index 457c909b2ca..12dad26bc71 100644 --- a/tgui/packages/tgui/interfaces/DeathmatchLobby.tsx +++ b/tgui/packages/tgui/interfaces/DeathmatchLobby.tsx @@ -6,228 +6,315 @@ import { Button, Divider, Dropdown, - Flex, Icon, + LabeledList, Modal, + NoticeBox, Section, + Stack, Table, + Tooltip, } from '../components'; import { ButtonCheckbox } from '../components/Button'; import { Window } from '../layouts'; -type PlayerLike = { - [key: string]: { - host: number; - ready: BooleanLike; - }; +type Player = Record; + +type PlayerInfo = { + host: number; + ready: BooleanLike; }; type Modifier = { - name: string; desc: string; modpath: string; - selected: BooleanLike; - selectable: BooleanLike; - player_selected: BooleanLike; + name: string; player_selectable: BooleanLike; + player_selected: BooleanLike; + selectable: BooleanLike; + selected: BooleanLike; +}; + +type Map = { + desc: string; + max_players: number; + min_players: number; + name: string; + time: number; }; type Data = { - self: string; - host: BooleanLike; + active_mods: string; admin: BooleanLike; - playing: BooleanLike; + host: BooleanLike; + loadoutdesc: string; loadouts: string[]; + map: Map; maps: string[]; - map: { - name: string; - desc: string; - time: number; - min_players: number; - max_players: number; - }; mod_menu_open: BooleanLike; modifiers: Modifier[]; - active_mods: string; - loadoutdesc: string; - players: PlayerLike[]; - observers: PlayerLike[]; + observers: Player[]; + players: Player[]; + playing: BooleanLike; + self: string; }; -export const DeathmatchLobby = (props) => { +export function DeathmatchLobby(props) { const { act, data } = useBackend(); - const { modifiers = [] } = data; + const { admin, observers = [], self, players } = data; + + const allReady = Object.keys(players).every( + (player) => players[player].ready, + ); + return ( - - -
- - - - Name - Loadout - Ready - - {Object.keys(data.players).map((player) => ( - - - {!!data.players[player].host && } - - - {(!( - (data.host && !data.players[player].host) || - data.admin - ) && {player}) || ( - - act('host', { - id: player, - func: value, - }) - } - /> - )} - - - - act('change_loadout', { - player: player, - loadout: value, - }) - } - /> - - - act('ready')} - /> - - - ))} - {Object.keys(data.observers).map((observer) => ( - - - {(!!data.observers[observer].host && ( - - )) || } - - - {(!( - (data.host && !data.observers[observer].host) || - data.admin - ) && {observer}) || ( - - act('host', { - id: observer, - func: value, - }) - } - /> - )} - - Observing - - ))} -
-
-
- + + + + + + + + + + + +
- - {(!!data.host && ( + + + {!!admin && ( + + )} + + + + + + + +
+
+
+
+
+ ); +} + +function PlayerColumn(props) { + const { act, data } = useBackend(); + const { + admin, + host, + loadouts = [], + observers = [], + players = [], + self, + } = data; + + const allReady = Object.keys(players).every( + (player) => players[player].ready, + ); + + return ( +
30}> + + + + Name + Loadout + + + + + + + {Object.keys(players).map((player) => { + const fullAccess = (!!host && !!players[player].host) || !admin; + + return ( + + + {!!players[player].host && } + + + {!fullAccess ? ( + {player} + ) : ( act('host', { - func: 'change_map', - map: value, + id: player, + func: value, }) } /> - )) || {data.map.name}} - - - {data.map.desc} - - - Maximum Play Time: {`${data.map.time / 600}min`} -
- Min players: {data.map.min_players} -
- Max players: {data.map.max_players} -
- Current players: {Object.keys(data.players).length} -
- - {data.active_mods} - {(!!data.admin || !!data.host) && ( - <> - -
+
+ ); +} + +function HostControls(props) { + const { act, data } = useBackend(); + const { + active_mods = [], + admin, + host, + loadoutdesc, + map, + maps = [], + players = [], + playing, + } = data; + + return ( +
+ {!host ? ( + {map.name} + ) : ( + + act('host', { + func: 'change_map', + map: value, + }) + } /> - {!!data.admin && ( - + + )} + + + Loadout Description + + + {loadoutdesc} + {!!playing && ( + <> + + + The game is currently in progress, or loading. + + + )} +
); -}; +} const ModSelector = (props) => { const { act, data } = useBackend(); @@ -235,21 +322,18 @@ const ModSelector = (props) => { if (!mod_menu_open || !(host || admin)) { return null; } + return ( - {modifiers.map((mod, index) => { return ( { modpath: mod.modpath, }) } - /> + > + {mod.name} + ); })} diff --git a/tgui/packages/tgui/interfaces/DeathmatchPanel.jsx b/tgui/packages/tgui/interfaces/DeathmatchPanel.jsx deleted file mode 100644 index 8ac2ff5f76d..00000000000 --- a/tgui/packages/tgui/interfaces/DeathmatchPanel.jsx +++ /dev/null @@ -1,95 +0,0 @@ -import { useBackend } from '../backend'; -import { - Button, - Dropdown, - Flex, - NoticeBox, - Section, - Stack, - Table, -} from '../components'; -import { Window } from '../layouts'; - -export const DeathmatchPanel = (props, context) => { - const { act, data } = useBackend(context); - const playing = data.playing || ''; - return ( - - - - If you play, you can still possibly be returned to your body (No - Guarantees)! - -
- - - Host - Map - Players - - {data.lobbies.map((lobby) => ( - - - {(!data.admin && lobby.name) || ( - - act('admin', { - id: lobby.name, - func: value, - }) - } - /> - )} - - {lobby.map} - - {lobby.players}/{lobby.max_players} - - - {(!lobby.playing && ( - <> -
-
- + + +
+
+ ); +} + +function LobbyPane(props) { + const { data } = useBackend(); + const { lobbies = [] } = data; + + return ( +
+ + + Host + Map + + + + + + + + + + + {lobbies.length === 0 && ( + + + + No lobbies found. Start one! + + + + )} + + {lobbies.map((lobby, index) => ( + + ))} +
+
+ ); +} + +function LobbyDisplay(props) { + const { act, data } = useBackend(); + const { admin, playing, hosting } = data; + const { lobby } = props; + + const isActive = (!!hosting || !!playing) && playing !== lobby.name; + + return ( + + + {!admin ? ( + lobby.name + ) : ( + + act('admin', { + id: lobby.name, + func: value, + }) + } + /> + )} + + {lobby.map} + + {lobby.players}/{lobby.max_players} + + + {!lobby.playing ? ( + <> + + + )} + + + ); +} diff --git a/tgui/packages/tgui/interfaces/IntegratedCircuit/ComponentMenu.jsx b/tgui/packages/tgui/interfaces/IntegratedCircuit/ComponentMenu.jsx index 9b91ef348fa..e243ef365b0 100644 --- a/tgui/packages/tgui/interfaces/IntegratedCircuit/ComponentMenu.jsx +++ b/tgui/packages/tgui/interfaces/IntegratedCircuit/ComponentMenu.jsx @@ -120,7 +120,8 @@ export class ComponentMenu extends Component { currentLimit: DEFAULT_COMPONENT_MENU_LIMIT, }) } - displayText={`Category: ${selectedTab}`} + selected={selectedTab} + placeholder="Category" color="transparent" className="IntegratedCircuit__BlueBorder" /> diff --git a/tgui/packages/tgui/interfaces/IntegratedCircuit/FundamentalTypes.jsx b/tgui/packages/tgui/interfaces/IntegratedCircuit/FundamentalTypes.jsx index 2ea8ce922aa..65d0814d8ce 100644 --- a/tgui/packages/tgui/interfaces/IntegratedCircuit/FundamentalTypes.jsx +++ b/tgui/packages/tgui/interfaces/IntegratedCircuit/FundamentalTypes.jsx @@ -88,7 +88,7 @@ export const FUNDAMENTAL_DATA_TYPES = { color={'transparent'} options={data} onSelected={setValue} - displayText={value} + selected={value} menuWidth={large ? '200px' : undefined} /> ); diff --git a/tgui/packages/tgui/interfaces/IntegratedCircuit/VariableMenu.jsx b/tgui/packages/tgui/interfaces/IntegratedCircuit/VariableMenu.jsx index 955e45da41b..45e7e90d737 100644 --- a/tgui/packages/tgui/interfaces/IntegratedCircuit/VariableMenu.jsx +++ b/tgui/packages/tgui/interfaces/IntegratedCircuit/VariableMenu.jsx @@ -1,4 +1,5 @@ import { shallowDiffers } from 'common/react'; +import { multiline } from 'common/string'; import { Component } from 'react'; import { @@ -15,7 +16,6 @@ import { VARIABLE_LIST, VARIABLE_NOT_A_LIST, } from './constants'; -import { multiline } from 'common/string'; export class VariableMenu extends Component { constructor(props) { @@ -145,7 +145,7 @@ export class VariableMenu extends Component { { over mb={1.7} width="100%" - displayText={bookName} + selected={bookName} options={inventory.map((book) => book.title)} value={bookName} onSelected={(e) => setBookName(e)} diff --git a/tgui/packages/tgui/interfaces/MODsuit.tsx b/tgui/packages/tgui/interfaces/MODsuit.tsx index 9d7fab88bd9..f78bd4dd1d8 100644 --- a/tgui/packages/tgui/interfaces/MODsuit.tsx +++ b/tgui/packages/tgui/interfaces/MODsuit.tsx @@ -226,7 +226,7 @@ const ConfigureListEntry = (props) => { const { act } = useBackend(); return ( act('configure', { diff --git a/tgui/packages/tgui/interfaces/MineBot.tsx b/tgui/packages/tgui/interfaces/MineBot.tsx index 4a3087cf8d6..9118562cdd0 100644 --- a/tgui/packages/tgui/interfaces/MineBot.tsx +++ b/tgui/packages/tgui/interfaces/MineBot.tsx @@ -97,7 +97,7 @@ export const MineBot = (props) => { { return possible_color.color_name; })} diff --git a/tgui/packages/tgui/interfaces/NavBeacon.tsx b/tgui/packages/tgui/interfaces/NavBeacon.tsx index 5194fe42c1c..6cc5036c87f 100644 --- a/tgui/packages/tgui/interfaces/NavBeacon.tsx +++ b/tgui/packages/tgui/interfaces/NavBeacon.tsx @@ -20,11 +20,11 @@ export type Data = { }; export type NavBeaconControl = { - location: String; + location: string; patrol_enabled: BooleanLike; - patrol_next: String; + patrol_next: string; delivery_enabled: BooleanLike; - delivery_direction: String; + delivery_direction: string; cover_locked: BooleanLike; }; @@ -107,7 +107,7 @@ export const NavBeaconControlSection = (props: DisabledProps) => { act('set_delivery_direction', { direction: value, diff --git a/tgui/packages/tgui/interfaces/NtosCard.tsx b/tgui/packages/tgui/interfaces/NtosCard.tsx index 7c3991a487c..5997aa0e91c 100644 --- a/tgui/packages/tgui/interfaces/NtosCard.tsx +++ b/tgui/packages/tgui/interfaces/NtosCard.tsx @@ -240,7 +240,7 @@ const TemplateDropdown = (props) => { { return templates[path]; })} @@ -249,6 +249,7 @@ const TemplateDropdown = (props) => { name: sel, }) } + selected="None" /> diff --git a/tgui/packages/tgui/interfaces/NtosRoboControl.jsx b/tgui/packages/tgui/interfaces/NtosRoboControl.jsx index 20c70220d36..9b55c90a456 100644 --- a/tgui/packages/tgui/interfaces/NtosRoboControl.jsx +++ b/tgui/packages/tgui/interfaces/NtosRoboControl.jsx @@ -2,7 +2,6 @@ import { useBackend, useSharedState } from '../backend'; import { Box, Button, - Dropdown, LabeledList, ProgressBar, Section, @@ -71,19 +70,22 @@ export const NtosRoboControl = (props) => { + Drone Pings + {dronepingtypes.map((ping_type) => ( + + ))}
{drones?.map((drone) => ( diff --git a/tgui/packages/tgui/interfaces/NtosScipaper.jsx b/tgui/packages/tgui/interfaces/NtosScipaper.jsx index 3866ccab24c..2af2cd12f43 100644 --- a/tgui/packages/tgui/interfaces/NtosScipaper.jsx +++ b/tgui/packages/tgui/interfaces/NtosScipaper.jsx @@ -93,7 +93,7 @@ const PaperPublishing = (props) => { act('select_file', { selected_uid: fileList[ordfile_name], @@ -117,7 +117,7 @@ const PaperPublishing = (props) => { act('select_experiment', { selected_expath: expList[experiment_name], @@ -141,7 +141,7 @@ const PaperPublishing = (props) => { String(number))} - displayText={tier ? String(tier) : '-'} + selected={String(tier)} onSelected={(new_tier) => act('select_tier', { selected_tier: Number(new_tier), @@ -165,7 +165,7 @@ const PaperPublishing = (props) => { act('select_partner', { selected_partner: allowedPartners[new_partner], diff --git a/tgui/packages/tgui/interfaces/NtosVirtualPet.tsx b/tgui/packages/tgui/interfaces/NtosVirtualPet.tsx index 7b61f2b566e..1894aa703d6 100644 --- a/tgui/packages/tgui/interfaces/NtosVirtualPet.tsx +++ b/tgui/packages/tgui/interfaces/NtosVirtualPet.tsx @@ -268,7 +268,7 @@ const PetTricks = (props) => { UpdateSequence(index, selected)} /> @@ -354,7 +354,7 @@ const Customization = (props) => {
{ return selected_hat.hat_name; })} @@ -369,7 +369,7 @@ const Customization = (props) => {
{ return possible_color.color_name; })} diff --git a/tgui/packages/tgui/interfaces/PlaneMasterDebug.tsx b/tgui/packages/tgui/interfaces/PlaneMasterDebug.tsx index 1a623bb2079..c85cdec2d13 100644 --- a/tgui/packages/tgui/interfaces/PlaneMasterDebug.tsx +++ b/tgui/packages/tgui/interfaces/PlaneMasterDebug.tsx @@ -885,7 +885,6 @@ const GroupDropdown = (props) => { act('set_group', { target_group: value, diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx index 6d1ed9fa3b6..a4889965d00 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx @@ -36,14 +36,14 @@ const CharacterProfiles = (props: { const { profiles, activeSlot, onClick } = props; // NOVA EDIT CHANGE return ( - ({ value: slot, diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/JobsPage.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/JobsPage.tsx index 775c073bdf7..148a44e2a26 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/JobsPage.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/JobsPage.tsx @@ -274,7 +274,7 @@ const JobRow = (props: { className?: string; job: Job; name: string }) => { act('set_job_title', { job: name, new_title: value }) } @@ -374,18 +374,17 @@ const JoblessRoleDropdown = (props) => { }, ]; + const selection = options?.find( + (option) => option.value === selected, + )!.displayText; + return ( - {options.find((option) => option.value === selected)!.displayText} - - } /> ); diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/LimbsPage.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/LimbsPage.tsx index da74d6b267a..ae113007fbc 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/LimbsPage.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/LimbsPage.tsx @@ -45,7 +45,7 @@ export const Markings = (props) => { act('change_marking', { limb_slot: props.limb.slot, @@ -141,7 +141,7 @@ export const AugmentationPage = (props) => { { // Since the costs are positive, // it's added and not substracted @@ -167,7 +167,7 @@ export const AugmentationPage = (props) => { act('set_limb_aug_style', { limb_slot: props.limb.slot, @@ -198,7 +198,7 @@ export const OrganPage = (props) => { { // Since the costs are positive, it's added and not substracted if ( @@ -232,7 +232,8 @@ export const LimbsPage = (props) => { act('set_preset', { preset: value })} />
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/RandomizationButton.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/RandomizationButton.tsx index 4152e2d77c1..0620f22da3a 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/RandomizationButton.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/RandomizationButton.tsx @@ -1,6 +1,6 @@ import { exhaustiveCheck } from 'common/exhaustive'; -import { Dropdown, Icon } from '../../components'; +import { Dropdown } from '../../components'; import { RandomSetting } from './data'; const options = [ @@ -48,12 +48,13 @@ export const RandomizationButton = (props: { color={color} {...dropdownProps} clipSelectedText={false} - displayText={} + icon="dice-d20" options={options} noChevron onSelected={setValue} menuWidth="120px" width={1.85} + selected="None" /> ); }; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx index b437fd22d96..50fd962d129 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx @@ -1,5 +1,5 @@ -import { sort, sortBy } from 'common/collections'; -import { BooleanLike, classes } from 'common/react'; +import { sortBy } from 'common/collections'; +import { BooleanLike } from 'common/react'; import { ComponentType, createElement, @@ -124,16 +124,15 @@ export const CheckboxInputInverse = ( ); }; -export const createDropdownInput = ( +export function createDropdownInput( // Map of value to display texts choices: Record, dropdownProps?: Record, -): FeatureValue => { +): FeatureValue { return (props: FeatureValueProps) => { return ( ( /> ); }; -}; +} export type FeatureChoicedServerData = { choices: string[]; @@ -158,136 +157,6 @@ export type FeatureChoicedServerData = { export type FeatureChoiced = Feature; -const capitalizeFirstLetter = (text: string) => - text.toString().charAt(0).toUpperCase() + text.toString().slice(1); - -export const StandardizedDropdown = (props: { - choices: string[]; - disabled?: boolean; - displayNames: Record; - onSetValue: (newValue: string) => void; - value: string; - buttons?: boolean; -}) => { - const { choices, disabled, buttons, displayNames, onSetValue, value } = props; - - return ( - { - return { - displayText: displayNames[choice], - value: choice, - }; - })} - /> - ); -}; - -export const FeatureDropdownInput = ( - props: FeatureValueProps & { - disabled?: boolean; - buttons?: boolean; - }, -) => { - const serverData = props.serverData; - if (!serverData) { - return null; - } - - const displayNames = - serverData.display_names || - Object.fromEntries( - serverData.choices.map((choice) => [ - choice, - capitalizeFirstLetter(choice), - ]), - ); - - return ( - - ); -}; - -export type FeatureWithIcons = Feature< - { value: T }, - T, - FeatureChoicedServerData ->; - -export const FeatureIconnedDropdownInput = ( - props: FeatureValueProps< - { - value: string; - }, - string, - FeatureChoicedServerData - >, -) => { - const serverData = props.serverData; - if (!serverData) { - return null; - } - - const icons = serverData.icons; - - const textNames = - serverData.display_names || - Object.fromEntries( - serverData.choices.map((choice) => [ - choice, - capitalizeFirstLetter(choice), - ]), - ); - - const displayNames = Object.fromEntries( - Object.entries(textNames).map(([choice, textName]) => { - let element: ReactNode = textName; - - if (icons && icons[choice]) { - const icon = icons[choice]; - element = ( - - - - - - {element} - - ); - } - - return [choice, element]; - }), - ); - - return ( - - ); -}; - export type FeatureNumericData = { minimum: number; maximum: number; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_core_display.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_core_display.tsx index 6b3e10bb10c..0e73c28526a 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_core_display.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_core_display.tsx @@ -1,4 +1,5 @@ -import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../base'; +import {} from '../base'; +import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../dropdowns'; export const preferred_ai_core_display: FeatureWithIcons = { name: 'AI core display', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_emote_display.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_emote_display.tsx index c8a59a5d9a4..3e958297b88 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_emote_display.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_emote_display.tsx @@ -1,4 +1,4 @@ -import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../base'; +import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../dropdowns'; export const preferred_ai_emote_display: FeatureWithIcons = { name: 'AI emote display', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_hologram_display.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_hologram_display.tsx index 423fcea8ed2..46d572fcda6 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_hologram_display.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_hologram_display.tsx @@ -1,4 +1,4 @@ -import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../base'; +import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../dropdowns'; export const preferred_ai_hologram_display: FeatureWithIcons = { name: 'AI hologram display', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/body_type.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/body_type.tsx index de9d6523e2c..3746e62ceee 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/body_type.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/body_type.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const body_type: FeatureChoiced = { name: 'Body type', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/food_allergy.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/food_allergy.tsx index f5b0ea37ca8..bdcd91ac7af 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/food_allergy.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/food_allergy.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const food_allergy: FeatureChoiced = { name: 'Food Allergy', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/glasses.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/glasses.tsx index 60cb3131f1b..df73451c35a 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/glasses.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/glasses.tsx @@ -1,4 +1,4 @@ -import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../base'; +import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../dropdowns'; export const glasses: FeatureWithIcons = { name: 'Glasses', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/hemiplegic.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/hemiplegic.tsx index 0494558ba77..35837c80099 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/hemiplegic.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/hemiplegic.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const hemiplegic: FeatureChoiced = { name: 'Hemiplegic', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/junkie.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/junkie.tsx index 8ac11ed968d..586b69d86c2 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/junkie.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/junkie.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const junkie: FeatureChoiced = { name: 'Addiction', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/language.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/language.tsx index 6b1a1be1220..39c48ae40d6 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/language.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/language.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const language: FeatureChoiced = { name: 'Language', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/antag_optin.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/antag_optin.tsx index 8e3032932a2..b8c96920b06 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/antag_optin.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/antag_optin.tsx @@ -1,5 +1,6 @@ // THIS IS A NOVA SECTOR UI FILE -import { FeatureChoiced, FeatureDropdownInput } from '../../base'; +import { FeatureChoiced } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const antag_opt_in_status_pref: FeatureChoiced = { name: 'Be Antagonist Target', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/brain_type.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/brain_type.tsx index 70d29aa6d20..c303b6f885a 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/brain_type.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/brain_type.tsx @@ -1,5 +1,6 @@ // THIS IS A NOVA SECTOR UI FILE -import { FeatureChoiced, FeatureDropdownInput } from '../../base'; +import { FeatureChoiced } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const brain_type: FeatureChoiced = { name: 'Silicon and Synthetic Brain Type', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/character_laugh.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/character_laugh.tsx index 03b11aaeccb..1f9f9c4cf5c 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/character_laugh.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/character_laugh.tsx @@ -1,5 +1,6 @@ // THIS IS A NOVA SECTOR UI FILE -import { FeatureChoiced, FeatureDropdownInput } from '../../base'; +import { FeatureChoiced } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const character_laugh: FeatureChoiced = { name: 'Character Laugh', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/character_scream.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/character_scream.tsx index 1441b1ab1e7..c41b327ba21 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/character_scream.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/character_scream.tsx @@ -1,5 +1,6 @@ // THIS IS A NOVA SECTOR UI FILE -import { FeatureChoiced, FeatureDropdownInput } from '../../base'; +import { FeatureChoiced } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const character_scream: FeatureChoiced = { name: 'Character Scream', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/echolocation.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/echolocation.tsx index 0f88d783bac..2e2340958a7 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/echolocation.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/echolocation.tsx @@ -4,9 +4,9 @@ import { Feature, FeatureChoiced, FeatureColorInput, - FeatureDropdownInput, FeatureToggle, } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const echolocation_outline: Feature = { name: 'Echo outline color', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/entombed.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/entombed.tsx index 48c6c63fab2..3b04e33711c 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/entombed.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/entombed.tsx @@ -3,10 +3,10 @@ import { CheckboxInput, Feature, FeatureChoiced, - FeatureDropdownInput, FeatureShortTextInput, FeatureToggle, } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const entombed_skin: FeatureChoiced = { name: 'MODsuit Skin', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/genitals.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/genitals.tsx index 80445e4df6d..0b817a52bbb 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/genitals.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/genitals.tsx @@ -4,7 +4,6 @@ import { Feature, FeatureChoiced, FeatureChoicedServerData, - FeatureDropdownInput, FeatureNumberInput, FeatureNumeric, FeatureToggle, @@ -12,6 +11,7 @@ import { FeatureTriColorInput, FeatureValueProps, } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const feature_penis: Feature = { name: 'Penis Choice', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/height_scaling.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/height_scaling.tsx index 99e9bb14326..3f1310792b9 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/height_scaling.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/height_scaling.tsx @@ -1,5 +1,6 @@ // THIS IS A NOVA SECTOR UI FILE -import { FeatureChoiced, FeatureDropdownInput } from '../../base'; +import { FeatureChoiced } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const height_scaling: FeatureChoiced = { name: 'Body Height', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/loadout_override_preference.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/loadout_override_preference.tsx index d29f71b2f34..f47e9a3df54 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/loadout_override_preference.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/loadout_override_preference.tsx @@ -1,5 +1,6 @@ // THIS IS A NOVA SECTOR UI FILE -import { Feature, FeatureDropdownInput } from '../../base'; +import { Feature } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const loadout_override_preference: Feature = { name: 'Loadout Item Preference', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/pet_owner.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/pet_owner.tsx index b782c389855..0938e4b5da5 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/pet_owner.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/pet_owner.tsx @@ -1,10 +1,6 @@ // THIS IS A NOVA SECTOR UI FILE -import { - Feature, - FeatureChoiced, - FeatureDropdownInput, - FeatureShortTextInput, -} from '../../base'; +import { Feature, FeatureChoiced, FeatureShortTextInput } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const pet_owner: FeatureChoiced = { name: 'Pet Type', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/photophobia.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/photophobia.tsx index 4e1fcbfea8f..6cf0afd1571 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/photophobia.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/photophobia.tsx @@ -1,5 +1,6 @@ // THIS IS A NOVA SECTOR UI FILE -import { FeatureChoiced, FeatureDropdownInput } from '../../base'; +import { FeatureChoiced } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const photophobia_severity: FeatureChoiced = { name: 'Severity', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/species_features.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/species_features.tsx index 31c5912d8e0..6c89d1a9963 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/species_features.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/species_features.tsx @@ -5,7 +5,6 @@ import { FeatureChoiced, FeatureChoicedServerData, FeatureColorInput, - FeatureDropdownInput, FeatureNumberInput, FeatureShortTextInput, FeatureTextInput, @@ -14,6 +13,7 @@ import { FeatureTriColorInput, FeatureValueProps, } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const feature_leg_type: FeatureChoiced = { name: 'Leg type', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/underworld_connections.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/underworld_connections.tsx index ce2d7763ffe..cd5535a94eb 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/underworld_connections.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/nova/underworld_connections.tsx @@ -1,10 +1,6 @@ // THIS IS A NOVA SECTOR UI FILE -import { - Feature, - FeatureChoiced, - FeatureDropdownInput, - FeatureShortTextInput, -} from '../../base'; +import { Feature, FeatureChoiced, FeatureShortTextInput } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const underworld_uplink_skin: FeatureChoiced = { name: 'Uplink Skin', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pda.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pda.tsx index fdc9a2be5da..196dea45c5d 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pda.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pda.tsx @@ -1,9 +1,5 @@ -import { - Feature, - FeatureChoiced, - FeatureDropdownInput, - FeatureShortTextInput, -} from '../base'; +import { Feature, FeatureChoiced, FeatureShortTextInput } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const pda_theme: FeatureChoiced = { name: 'PDA Theme', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/phobia.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/phobia.tsx index dd14349277f..f2f35f65e16 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/phobia.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/phobia.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const phobia: FeatureChoiced = { name: 'Phobia', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pride_pin.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pride_pin.tsx index b0fae6092a1..70c6f8a8efe 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pride_pin.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pride_pin.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const pride_pin: FeatureChoiced = { name: 'Pride Pin', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prisoner_crime.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prisoner_crime.tsx index 2ca17aa4e36..b551b68ee2e 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prisoner_crime.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prisoner_crime.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const prisoner_crime: FeatureChoiced = { name: 'Prisoner crime', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_limb.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_limb.tsx index adbaefe90c8..87a8ea23de1 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_limb.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_limb.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const prosthetic: FeatureChoiced = { name: 'Prosthetic', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_organ.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_organ.tsx index da0e37a4173..5b484d5960e 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_organ.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_organ.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const prosthetic_organ: FeatureChoiced = { name: 'Prosthetic Organ', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/security_department.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/security_department.tsx index e9f380bd675..a1311e347c8 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/security_department.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/security_department.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const prefered_security_department: FeatureChoiced = { name: 'Security department', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skin_tone.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skin_tone.tsx index 2e5c18f2324..95029374bd2 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skin_tone.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skin_tone.tsx @@ -1,12 +1,8 @@ import { sortBy } from 'common/collections'; +import { useMemo } from 'react'; +import { Box, Dropdown, Stack } from 'tgui/components'; -import { Box, Stack } from '../../../../../components'; -import { - Feature, - FeatureChoicedServerData, - FeatureValueProps, - StandardizedDropdown, -} from '../base'; +import { Feature, FeatureChoicedServerData, FeatureValueProps } from '../base'; type HexValue = { lightness: number; @@ -24,43 +20,53 @@ const sortHexValues = (array: [string, HexValue][]) => export const skin_tone: Feature = { name: 'Skin tone', component: (props: FeatureValueProps) => { - const { handleSetValue, serverData, value } = props; + const { handleSetValue, serverData } = props; if (!serverData) { return null; } - return ( - key, - )} - displayNames={Object.fromEntries( - Object.entries(serverData.display_names).map(([key, displayName]) => { - const hexColor = serverData.to_hex[key]; + const value = { value: props.value }; + + const displayNames = useMemo(() => { + const sorted = sortHexValues(Object.entries(serverData.to_hex)); + + return sorted.map(([key, colorInfo]) => { + const displayName = serverData.display_names[key]; - return [ - key, - - - - + return { + value: key, + displayText: ( + + + + - {displayName} - , - ]; - }), - )} - onSetValue={handleSetValue} - value={value} + {displayName} + + ), + }; + }); + }, [serverData.display_names]); + + return ( + option.value === value.value) + ?.displayText + } + onSelected={(value) => handleSetValue(value)} + options={displayNames} + selected={value.value} + width="100%" /> ); }, diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/tff/character_voice.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/tff/character_voice.tsx index 149a5207703..7f8a5f4158f 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/tff/character_voice.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/tff/character_voice.tsx @@ -3,12 +3,12 @@ import { CheckboxInput, FeatureChoiced, FeatureChoicedServerData, - FeatureDropdownInput, FeatureNumberInput, FeatureNumeric, FeatureToggle, FeatureValueProps, } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; const FeatureBlooperDropdownInput = ( props: FeatureValueProps, diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/trans_prosthetic.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/trans_prosthetic.tsx index 368a2a16a1b..fc8601e3cc7 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/trans_prosthetic.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/trans_prosthetic.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const trans_prosthetic: FeatureChoiced = { name: 'Augment', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/tts_voice.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/tts_voice.tsx index 94a208158c5..1f588f07f15 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/tts_voice.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/tts_voice.tsx @@ -2,11 +2,11 @@ import { Button, Stack } from '../../../../../components'; import { FeatureChoiced, FeatureChoicedServerData, - FeatureDropdownInput, FeatureNumeric, FeatureSliderInput, FeatureValueProps, } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; const FeatureTTSDropdownInput = ( props: FeatureValueProps, diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/uplink_loc.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/uplink_loc.tsx index 06c125c33fc..2b1ffe26a32 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/uplink_loc.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/uplink_loc.tsx @@ -1,4 +1,5 @@ -import { FeatureChoiced, FeatureDropdownInput } from '../base'; +import { FeatureChoiced } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const uplink_loc: FeatureChoiced = { name: 'Uplink Spawn Location', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/admin.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/admin.tsx index 03244e9f6ee..d99cd329f55 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/admin.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/admin.tsx @@ -4,9 +4,9 @@ import { CheckboxInput, Feature, FeatureColorInput, - FeatureDropdownInput, FeatureToggle, } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const asaycolor: Feature = { name: 'Admin chat color', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx index ab973e3659e..5ec16867197 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx @@ -10,10 +10,10 @@ import { CheckboxInput, FeatureChoiced, FeatureChoicedServerData, - FeatureDropdownInput, FeatureToggle, FeatureValueProps, } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const ghost_accs: FeatureChoiced = { name: 'Ghost accessories', @@ -81,9 +81,10 @@ const GhostFormInput = ( return ( = { name: 'MOD active module key', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/nova/erp_preferences.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/nova/erp_preferences.tsx index 504bc4114d1..ce4b0211782 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/nova/erp_preferences.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/nova/erp_preferences.tsx @@ -1,10 +1,6 @@ // THIS IS A NOVA SECTOR UI FILE -import { - CheckboxInput, - FeatureChoiced, - FeatureDropdownInput, - FeatureToggle, -} from '../../base'; +import { CheckboxInput, FeatureChoiced, FeatureToggle } from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; export const master_erp_pref: FeatureToggle = { name: 'Show/Hide Erotic Roleplay Preferences', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/parallax.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/parallax.tsx index a7b143a6d3d..914af27c382 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/parallax.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/parallax.tsx @@ -1,4 +1,5 @@ -import { Feature, FeatureDropdownInput } from '../base'; +import { Feature } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const parallax: Feature = { name: 'Parallax (fancy space)', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/preferred_map.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/preferred_map.tsx index 1a1755ce714..5b0860ef91e 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/preferred_map.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/preferred_map.tsx @@ -1,6 +1,7 @@ import { multiline } from 'common/string'; -import { Feature, FeatureDropdownInput } from '../base'; +import { Feature } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const preferred_map: Feature = { name: 'Preferred map', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/screentips.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/screentips.tsx index 5c65c4f100a..ff2cf95a048 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/screentips.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/screentips.tsx @@ -5,9 +5,9 @@ import { Feature, FeatureChoiced, FeatureColorInput, - FeatureDropdownInput, FeatureToggle, } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const screentip_color: Feature = { name: 'Screentips: Screentips color', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx index 0bce5e0982e..34e968f35c4 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx @@ -4,10 +4,10 @@ import { CheckboxInput, Feature, FeatureChoiced, - FeatureDropdownInput, FeatureSliderInput, FeatureToggle, } from '../base'; +import { FeatureDropdownInput } from '../dropdowns'; export const sound_ambience: FeatureToggle = { name: 'Enable ambience', diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx index 218b5b3c580..d3fdc0b94de 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx @@ -46,7 +46,6 @@ const UIStyleInput = ( = { name: 'Eye color', diff --git a/tgui/packages/tgui/interfaces/ProcCallMenu.tsx b/tgui/packages/tgui/interfaces/ProcCallMenu.tsx index 716ae19a147..6db723bcfb4 100644 --- a/tgui/packages/tgui/interfaces/ProcCallMenu.tsx +++ b/tgui/packages/tgui/interfaces/ProcCallMenu.tsx @@ -45,7 +45,7 @@ export const ProcCallMenu = (props) => { @@ -139,7 +139,7 @@ const PortEntry = (props) => { { width="100%" options={sorted_assistance} selected={recipient} - displayText={recipient || 'Pick a Recipient'} + placeholder="Pick a Recipient" onSelected={(value) => setRecipient(value)} /> )} @@ -94,7 +94,7 @@ export const MessageWriteTab = (props) => { width="100%" options={sorted_supply} selected={recipient} - displayText={recipient || 'Pick a Recipient'} + placeholder="Pick a Recipient" onSelected={(value) => setRecipient(value)} /> )} @@ -103,7 +103,7 @@ export const MessageWriteTab = (props) => { width="100%" options={sorted_information} selected={recipient} - displayText={recipient || 'Pick a Recipient'} + placeholder="Pick a Recipient" onSelected={(value) => setRecipient(value)} /> )} diff --git a/tgui/packages/tgui/interfaces/StationTraitsPanel.tsx b/tgui/packages/tgui/interfaces/StationTraitsPanel.tsx index e6e7b02ce67..8496d62552f 100644 --- a/tgui/packages/tgui/interfaces/StationTraitsPanel.tsx +++ b/tgui/packages/tgui/interfaces/StationTraitsPanel.tsx @@ -34,7 +34,7 @@ const FutureStationTraitsPage = (props) => { const { act, data } = useBackend(); const { future_station_traits } = data; - const [selectedTrait, setSelectedTrait] = useState(); + const [selectedTrait, setSelectedTrait] = useState(''); const traitsByName = Object.fromEntries( data.valid_station_traits.map((trait) => { @@ -50,9 +50,9 @@ const FutureStationTraitsPage = (props) => { diff --git a/tgui/packages/tgui/interfaces/TramController.tsx b/tgui/packages/tgui/interfaces/TramController.tsx index 0fccd23a911..f787c8726b5 100644 --- a/tgui/packages/tgui/interfaces/TramController.tsx +++ b/tgui/packages/tgui/interfaces/TramController.tsx @@ -193,7 +193,7 @@ export const TramController = (props) => { width="98.5%" options={destinations.map((id) => id.name)} selected={tripDestination} - displayText={tripDestination || 'Pick a Destination'} + placeholder="Pick a Destination" onSelected={(value) => setTripDestination(value)} />