[TGUI]Dropdown upgrade (#26987)

* dropdown

* Update tgui/packages/tgui/interfaces/BrigTimer.js

Co-authored-by: Aylong <69762909+AyIong@users.noreply.github.com>
Signed-off-by: ROdenFL <ROdenFL@yandex.ru>

---------

Signed-off-by: ROdenFL <ROdenFL@yandex.ru>
Co-authored-by: Aylong <69762909+AyIong@users.noreply.github.com>
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
This commit is contained in:
ROdenFL
2024-11-10 01:26:59 +03:00
committed by GitHub
parent 0c770b558c
commit 0b79bc23e9
8 changed files with 290 additions and 200 deletions
+125 -34
View File
@@ -2,7 +2,9 @@ import { createPopper, VirtualElement } from '@popperjs/core';
import { classes } from 'common/react';
import { Component, findDOMFromVNode, InfernoNode, render } from 'inferno';
import { Box, BoxProps } from './Box';
import { Button } from './Button';
import { Icon } from './Icon';
import { Stack } from './Stack';
export interface DropdownEntry {
displayText: string | number | InfernoNode;
@@ -24,6 +26,7 @@ type DropdownUniqueProps = {
// you freaks really are just doing anything with this shit
selected?: any;
onSelected?: (selected: any) => void;
buttons?: boolean;
};
export type DropdownProps = BoxProps & DropdownUniqueProps;
@@ -230,6 +233,57 @@ export class Dropdown extends Component<DropdownProps, DropdownState> {
}
}
getOptionValue(option): string {
return typeof option === 'string' ? option : option.value;
}
getSelectedIndex(): number {
const selected = this.state.selected || this.props.selected;
const { options = [] } = this.props;
return options.findIndex((option) => {
return this.getOptionValue(option) === selected;
});
}
toPrevious(): void {
if (this.props.options.length < 1) {
return;
}
let selectedIndex = this.getSelectedIndex();
const startIndex = 0;
const endIndex = this.props.options.length - 1;
const hasSelected = selectedIndex >= 0;
if (!hasSelected) {
selectedIndex = startIndex;
}
const previousIndex = selectedIndex === startIndex ? endIndex : selectedIndex - 1;
this.setSelected(this.getOptionValue(this.props.options[previousIndex]));
}
toNext(): void {
if (this.props.options.length < 1) {
return;
}
let selectedIndex = this.getSelectedIndex();
const startIndex = 0;
const endIndex = this.props.options.length - 1;
const hasSelected = selectedIndex >= 0;
if (!hasSelected) {
selectedIndex = endIndex;
}
const nextIndex = selectedIndex === endIndex ? startIndex : selectedIndex + 1;
this.setSelected(this.getOptionValue(this.props.options[nextIndex]));
}
render() {
const { props } = this;
const {
@@ -247,6 +301,7 @@ export class Dropdown extends Component<DropdownProps, DropdownState> {
selected,
disabled,
displayText,
buttons,
...boxProps
} = props;
const { className, ...rest } = boxProps;
@@ -254,41 +309,77 @@ export class Dropdown extends Component<DropdownProps, DropdownState> {
const adjustedOpen = over ? !this.state.open : this.state.open;
return (
<Box
width={width}
className={classes([
'Dropdown__control',
'Button',
'Button--color--' + color,
disabled && 'Button--disabled',
className,
])}
onClick={(event) => {
if (disabled && !this.state.open) {
return;
}
this.setOpen(!this.state.open);
if (onClick) {
onClick(event);
}
}}
{...rest}
>
{icon && <Icon name={icon} rotation={iconRotation} spin={iconSpin} mr={1} />}
<span
className="Dropdown__selected-text"
style={{
overflow: clipSelectedText ? 'hidden' : 'visible',
}}
>
{displayText || this.state.selected}
</span>
{nochevron || (
<span className="Dropdown__arrow-button">
<Icon name={adjustedOpen ? 'chevron-up' : 'chevron-down'} />
</span>
<Stack inline fill width={width}>
<Stack.Item grow>
<Box
width={'100%'}
className={classes([
'Dropdown__control',
'Button',
'Button--color--' + color,
disabled && 'Button--disabled',
className,
])}
onClick={(event) => {
if (disabled && !this.state.open) {
return;
}
this.setOpen(!this.state.open);
if (onClick) {
onClick(event);
}
}}
{...rest}
>
{icon && <Icon name={icon} rotation={iconRotation} spin={iconSpin} mr={1} />}
<span
className="Dropdown__selected-text"
style={{
overflow: clipSelectedText ? 'hidden' : 'visible',
}}
>
{displayText || this.state.selected}
</span>
{nochevron || (
<span className="Dropdown__arrow-button">
<Icon name={adjustedOpen ? 'chevron-up' : 'chevron-down'} />
</span>
)}
</Box>
</Stack.Item>
{buttons && (
<>
<Stack.Item height={'100%'}>
<Button
height={'100%'}
icon="chevron-left"
disabled={disabled}
onClick={() => {
if (disabled) {
return;
}
this.toPrevious();
}}
/>
</Stack.Item>
<Stack.Item height={'100%'}>
<Button
height={'100%'}
icon="chevron-right"
disabled={disabled}
onClick={() => {
if (disabled) {
return;
}
this.toNext();
}}
/>
</Stack.Item>
</>
)}
</Box>
</Stack>
);
}
}
+12 -10
View File
@@ -64,16 +64,18 @@ export const BrigTimer = (props, context) => {
onClick={() => act('prisoner_name')}
/>
{!!data.spns.length && (
<Dropdown
disabled={!data.isAllowed || !data.spns.length}
options={data.spns}
width="250px"
onSelected={(value) =>
act('prisoner_name', {
prisoner_name: value,
})
}
/>
<Box mt="0.3rem">
<Dropdown
disabled={!data.isAllowed || !data.spns.length}
options={data.spns}
width="250px"
onSelected={(value) =>
act('prisoner_name', {
prisoner_name: value,
})
}
/>
</Box>
)}
</LabeledList.Item>
<LabeledList.Item label="Prisoner Crimes">
@@ -129,6 +129,7 @@ const Designs = (properties, context) => {
className="Exofab__designs"
title={
<Dropdown
width="19rem"
className="Exofab__dropdown"
selected={curCategory}
options={categories}
+9 -12
View File
@@ -1,5 +1,5 @@
import { useBackend, useLocalState } from '../backend';
import { Button, DmIcon, LabeledList, Section, Table, Dropdown, Flex, Icon, Box } from '../components';
import { Button, DmIcon, LabeledList, Section, Table, Dropdown, Flex, Icon, Box, Stack } from '../components';
import { Window } from '../layouts';
const SelectableTile = (props, context) => {
@@ -36,26 +36,23 @@ export const FloorPainter = (props, context) => {
<Window width={405} height={475}>
<Window.Content scrollable>
<Section title="Decal setup">
<Flex>
<Flex.Item>
<Stack fill>
<Stack.Item>
<Button icon="chevron-left" onClick={() => act('cycle_style', { offset: -1 })} />
</Flex.Item>
<Flex.Item>
</Stack.Item>
<Stack.Item>
<Dropdown
options={availableStyles}
selected={selectedStyle}
width="150px"
height="20px"
ml="2px"
mr="2px"
nochevron
onSelected={(val) => act('select_style', { style: val })}
/>
</Flex.Item>
<Flex.Item>
</Stack.Item>
<Stack.Item>
<Button icon="chevron-right" onClick={() => act('cycle_style', { offset: 1 })} />
</Flex.Item>
</Flex>
</Stack.Item>
</Stack>
<Box mt="5px" mb="5px">
<Flex
@@ -484,6 +484,7 @@ const InstrumentStatusAdvanced = (properties, context) => {
<Dropdown
options={['Linear', 'Exponential']}
selected={smt}
mb="0.4rem"
onSelected={(v) =>
act('setsustainmode', {
new: v,
@@ -153,14 +153,12 @@ export const MessengerList = (props, context) => {
<Button icon="bell" onClick={() => act('Ringtone')}>
Set Custom Ringtone
</Button>
<Button>
<Dropdown
selected={ringtone}
width="100px"
options={Object.keys(ringtone_list)}
onSelected={(value) => act('Available_Ringtones', { selected_ringtone: value })}
/>
</Button>
<Dropdown
selected={ringtone}
width="100px"
options={Object.keys(ringtone_list)}
onSelected={(value) => act('Available_Ringtones', { selected_ringtone: value })}
/>
</LabeledList.Item>
</LabeledList>
{(!toff && (
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long