Skip to content

Commit

Permalink
actually revert this until its NOT broken (ParadiseSS13#23557)
Browse files Browse the repository at this point in the history
  • Loading branch information
Contrabang authored Dec 14, 2023
1 parent 28163dc commit e623109
Show file tree
Hide file tree
Showing 13 changed files with 523 additions and 559 deletions.
116 changes: 0 additions & 116 deletions tgui/docs/component-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,12 @@ Make sure to add new items to this list if you document new components.
- [`Table`](#table)
- [`Table.Row`](#tablerow)
- [`Table.Cell`](#tablecell)
- [`Table.Sortable`](#tablesortable)
- [`Tabs`](#tabs)
- [`Tabs.Tab`](#tabstab)
- [`Tooltip`](#tooltip)
- [`tgui/layouts`](#tguilayouts)
- [`Window`](#window)
- [`Window.Content`](#windowcontent)
- [`tgui/interfaces/common`](#tguiinterfacescommon)
- [`RecordsTable`](#recordstable)

## General Concepts

Expand Down Expand Up @@ -847,103 +844,6 @@ A straight forward mapping to `<td>` element.
- `collapsing: boolean` - Collapses table cell to the smallest possible size,
and stops any text inside from wrapping.

### `Table.Sortable`

A managed sortable table.

**Props:**

- See inherited props: [Table](#table)
- `columns: Column[]` - A list of data fields to be
used. The order in which columns are specified is the order in which they
appear in the UI.
- `columnDefaults: UnnamedColumn` - Default values for all columns.
`columnDefaults.datum.children` can be used to specify the default children,
but will get overriden by children defined at each column.
`columnDefaults.datum.props` and `columnDefaults.header.props` can be used to
specify additional props for the datum and header respectively.
- `data: object[]` - The data to put into the table.
- `datumID: object => object` - A function which takes in a datum and returns
an id.
- `filter: object[] => object[]` - A function applied to the data before
sorting the table. The `createSearch` function can be applied here.
- `headerRowProps: object` - Props to apply to the header row.
- `datumRowProps: object | object => object` - Props to apply to the data
rows. If a function is specified instead, the data associated with that row
is passed into it.
- `...rest` - The rest of the props are applied on the table.
- `children: Component[]` - Not supported. Do not use.

The column types is defined as such:

```ts
interface UnnamedColumn {
// ? signifies optional
datum?: {
// Pass the children directly or pass a function which takes the value of
// the cell and returns the props. Setting this property overrides the
// default children.
children?: React.ReactNode | ((value: object) => React.ReactNode);
// Pass the additional props directly or pass a function which takes the
// value of the cell and returns the additional props.
props?: CellProps | ((value: object) => CellProps);
};
header?: {
// Additional props for the header cell.
props?: HeaderProps;
};
}

// Inherits properties from UnnamedColumn
type Column = UnnamedColumn & {
id: string;
name: string;
};
```

The following is an example of how to use `Table.Sortable`.

```jsx
const data = [
{ 'account_number': 6224001, 'name': 'Command Account', 'suspended': 'Active', 'money': 7000, },
{ 'account_number': 3099002, 'name': 'Security Account', 'suspended': 'Active', 'money': 14000, },
{ 'account_number': 8652003, 'name': 'Science Account', 'suspended': 'Active', 'money': 7000, },
{ 'account_number': 8422004, 'name': 'Service Account', 'suspended': 'Active', 'money': 7000, },
{ 'account_number': 9853005, 'name': 'Supply Account', 'suspended': 'Active', 'money': 7000, },
{ 'account_number': 1866006, 'name': 'Engineering Account', 'suspended': 'Active', 'money': 7250, },
{ 'account_number': 3811007, 'name': 'Medical Account', 'suspended': 'Active', 'money': 7000, },
{ 'account_number': 3945008, 'name': 'Assistant Account', 'suspended': 'Active', 'money': 4500, },
]

<Table.Sortable
columns={[
{ id: "name", name: "Department Name", },
{ id: "account_number", name: "Account Number", },
{ id: "suspended", name: "Account Status", },
{ id: "money", name: "Account Balance", },
]}
data={data}
datumID={(datum) => datum.account_number}

datumRowProps={(datum) => ({
className: `AccountsUplinkTerminal__listRow--${datum.suspended}`,
})}
datumCellChildren={{
name: (value) => <><Icon name="wallet" /> {value}</>,
}}
/>
```

In the above example, the `columns` prop defines the fields in the data that
are used. `columns.id` is the key or the name of the property on the data,
while `columns.name` is what the user sees on the UI. `datumID` selects which
field in the data to use as the key for render caching. `datumID` can return
anything, but it must be unique.

`datumRowProps` applies a class to a row if the account associated with that
row is suspended, and `datumCellChildren` prepends a wallet to the contents
of the `name` column.

### `Tabs`

Tabs make it easy to explore and switch between different views.
Expand Down Expand Up @@ -1068,19 +968,3 @@ Can be scrollable.
- `className: string` - Applies a CSS class to the element.
- `scrollable: boolean` - Shows or hides the scrollbar.
- `children: any` - Main content of your window.

## `tgui/interfaces/common`

## `RecordsTable`

An extension to [`Table.Sortable`](#tablesortable) which provides a search
function and slots for buttons.

**Props:**

- See inherited props: [`Table.Sortable`](#tablesortable)
- `leftButtons: Component` - Optional buttons to add left of the search box.
- `rightButtons: Component` - Optional buttons to add right of the search box.
- `searchPlaceholder: string` - The default text in the search box.

Use a `<Fragment>`(or `<>`) to specify multiple buttons.
157 changes: 1 addition & 156 deletions tgui/packages/tgui/components/Table.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { classes, pureComponentHooks } from 'common/react';
import { computeBoxClassName, computeBoxProps } from './Box';
import { Component } from 'inferno';
import { Button } from './Button';
import { Icon } from './Icon';
import { Box, computeBoxClassName, computeBoxProps } from './Box';

export const Table = (props) => {
const { className, collapsing, children, ...rest } = props;
Expand Down Expand Up @@ -56,159 +53,7 @@ export const TableCell = (props) => {
);
};

const resolveFunctionalProp = (props, ...data) =>
props ? (props instanceof Function ? props(...data) : props) : undefined;
class HoverableIcon extends Component {
constructor() {
super();
this.state = {
hovering: false,
};
this.handleMouseOver = (e) => {
this.setState({ hovering: true });
};
this.handleMouseOut = (e) => {
this.setState({ hovering: false });
};
}

render() {
const { hoverIcon, name, ...rest } = this.props;
const { hovering } = this.state;
return (
<Icon
name={hovering ? hoverIcon : name}
{...rest}
onMouseOver={this.handleMouseOver}
onMouseOut={this.handleMouseOut}
/>
);
}
}

class SortableTable extends Component {
constructor(props) {
super();
this.state = {
// Allow null
sortId: props.sortId === undefined ? props.columns[0].id : props.sortId,
sortOrder: props.sortOrder ?? 1,
};
}

render() {
const {
className,
columnDefaults,
columns,
data,
datumID,
filter,
headerRowProps,
datumRowProps,
...rest
} = this.props;
const { sortId, sortOrder } = this.state;

const columnHeaders = columns.map(
({ id, name, header: { props } = {} }) => {
const {
header: { props: defaultProps },
} = columnDefaults;
return (
<Table.Cell key={id}>
<Button
color={sortId !== id && 'transparent'}
width="100%"
onClick={() => {
if (sortId === id) {
this.setState({
sortOrder: !sortOrder,
});
} else {
this.setState({
sortId: id,
sortOrder: true,
});
}
}}
{...defaultProps}
{...props}
>
{name}
{sortId === id && (
<HoverableIcon
name={sortOrder ? 'sort-up' : 'sort-down'}
hoverIcon="times"
position="absolute"
right={0}
top="50%"
style={{
transform: 'translate(0, -50%)',
}}
onClick={(e) => {
this.setState({
sortId: null,
});
e.preventDefault();
}}
/>
)}
</Button>
</Table.Cell>
);
}
);
const dataRows = (filter ? filter(data) : data)
.sort((a, b) => {
if (sortId) {
const i = sortOrder ? 1 : -1;
return a[sortId].toString().localeCompare(b[sortId].toString()) * i;
} else {
return 0;
}
})
.map((datum) => {
let cells = columns.map(
({ id, name, datum: { props, children } = {} }) => {
const {
datum: { children: defaultChildren, props: defaultProps },
} = columnDefaults;
return (
<Table.Cell
key={id}
{...(resolveFunctionalProp(defaultProps, datum[id]) ?? [])}
{...(resolveFunctionalProp(props, datum[id]) ?? [])}
>
{resolveFunctionalProp(children, datum[id]) ??
resolveFunctionalProp(defaultChildren, datum[id]) ??
datum[id]}
</Table.Cell>
);
}
);
return (
<Table.Row
key={datumID(datum)}
{...(resolveFunctionalProp(datumRowProps, datum) ?? [])}
>
{cells}
</Table.Row>
);
});
return (
<Table className={classes(['SortableTable', className])} {...rest}>
<Table.Row bold {...headerRowProps}>
{columnHeaders}
</Table.Row>
{dataRows}
</Table>
);
}
}

TableCell.defaultHooks = pureComponentHooks;

Table.Row = TableRow;
Table.Cell = TableCell;
Table.Sortable = SortableTable;
Loading

0 comments on commit e623109

Please sign in to comment.