From 4872b56b16288befe2d58adb73c73678da9d21b0 Mon Sep 17 00:00:00 2001 From: ShadowLarkens Date: Fri, 27 Sep 2024 21:54:01 -0700 Subject: [PATCH] Add tgui-core to package.json and merk all unused components --- tgui/packages/tgui-panel/styles/main.scss | 1 - tgui/packages/tgui/components/Blink.jsx | 69 ----- tgui/packages/tgui/components/BlockQuote.tsx | 15 -- tgui/packages/tgui/components/DmIcon.tsx | 72 ------ .../packages/tgui/components/FakeTerminal.jsx | 52 ---- tgui/packages/tgui/components/FitText.tsx | 99 -------- tgui/packages/tgui/components/Grid.tsx | 44 ---- .../tgui/components/InfinitePlane.jsx | 192 -------------- tgui/packages/tgui/components/KeyListener.tsx | 40 --- tgui/packages/tgui/components/MenuBar.tsx | 238 ------------------ tgui/packages/tgui/components/RoundGauge.jsx | 133 ---------- .../tgui/components/StyleableSection.tsx | 30 --- tgui/packages/tgui/components/TimeDisplay.jsx | 64 ----- .../tgui/components/TrackOutsideClicks.tsx | 35 --- tgui/packages/tgui/components/VirtualList.tsx | 69 ----- tgui/packages/tgui/components/index.ts | 13 - tgui/packages/tgui/package.json | 1 + tgui/packages/tgui/stories/Blink.stories.jsx | 20 -- .../tgui/stories/BlockQuote.stories.jsx | 23 -- .../tgui/styles/components/BlockQuote.scss | 20 -- .../tgui/styles/components/MenuBar.scss | 75 ------ .../tgui/styles/components/RoundGauge.scss | 88 ------- tgui/packages/tgui/styles/main.scss | 3 - tgui/webpack.config.js | 2 +- tgui/yarn.lock | 11 + 25 files changed, 13 insertions(+), 1396 deletions(-) delete mode 100644 tgui/packages/tgui/components/Blink.jsx delete mode 100644 tgui/packages/tgui/components/BlockQuote.tsx delete mode 100644 tgui/packages/tgui/components/DmIcon.tsx delete mode 100644 tgui/packages/tgui/components/FakeTerminal.jsx delete mode 100644 tgui/packages/tgui/components/FitText.tsx delete mode 100644 tgui/packages/tgui/components/Grid.tsx delete mode 100644 tgui/packages/tgui/components/InfinitePlane.jsx delete mode 100644 tgui/packages/tgui/components/KeyListener.tsx delete mode 100644 tgui/packages/tgui/components/MenuBar.tsx delete mode 100644 tgui/packages/tgui/components/RoundGauge.jsx delete mode 100644 tgui/packages/tgui/components/StyleableSection.tsx delete mode 100644 tgui/packages/tgui/components/TimeDisplay.jsx delete mode 100644 tgui/packages/tgui/components/TrackOutsideClicks.tsx delete mode 100644 tgui/packages/tgui/components/VirtualList.tsx delete mode 100644 tgui/packages/tgui/stories/Blink.stories.jsx delete mode 100644 tgui/packages/tgui/stories/BlockQuote.stories.jsx delete mode 100644 tgui/packages/tgui/styles/components/BlockQuote.scss delete mode 100644 tgui/packages/tgui/styles/components/MenuBar.scss delete mode 100644 tgui/packages/tgui/styles/components/RoundGauge.scss diff --git a/tgui/packages/tgui-panel/styles/main.scss b/tgui/packages/tgui-panel/styles/main.scss index 08e60d18ee6..4b606447937 100644 --- a/tgui/packages/tgui-panel/styles/main.scss +++ b/tgui/packages/tgui-panel/styles/main.scss @@ -24,7 +24,6 @@ @include meta.load-css('~tgui/styles/atomic/text.scss'); // Components -@include meta.load-css('~tgui/styles/components/BlockQuote.scss'); @include meta.load-css('~tgui/styles/components/Button.scss'); @include meta.load-css('~tgui/styles/components/ColorBox.scss'); @include meta.load-css('~tgui/styles/components/Dimmer.scss'); diff --git a/tgui/packages/tgui/components/Blink.jsx b/tgui/packages/tgui/components/Blink.jsx deleted file mode 100644 index dc12f84346e..00000000000 --- a/tgui/packages/tgui/components/Blink.jsx +++ /dev/null @@ -1,69 +0,0 @@ -import { Component } from 'react'; - -const DEFAULT_BLINKING_INTERVAL = 1000; -const DEFAULT_BLINKING_TIME = 1000; - -export class Blink extends Component { - constructor(props) { - super(props); - this.state = { - hidden: false, - }; - } - - createTimer() { - const { - interval = DEFAULT_BLINKING_INTERVAL, - time = DEFAULT_BLINKING_TIME, - } = this.props; - - clearInterval(this.interval); - clearTimeout(this.timer); - - this.setState({ - hidden: false, - }); - - this.interval = setInterval(() => { - this.setState({ - hidden: true, - }); - - this.timer = setTimeout(() => { - this.setState({ - hidden: false, - }); - }, time); - }, interval + time); - } - - componentDidMount() { - this.createTimer(); - } - - componentDidUpdate(prevProps) { - if ( - prevProps.interval !== this.props.interval || - prevProps.time !== this.props.time - ) { - this.createTimer(); - } - } - - componentWillUnmount() { - clearInterval(this.interval); - clearTimeout(this.timer); - } - - render() { - return ( - - {this.props.children} - - ); - } -} diff --git a/tgui/packages/tgui/components/BlockQuote.tsx b/tgui/packages/tgui/components/BlockQuote.tsx deleted file mode 100644 index 3c627d3fac2..00000000000 --- a/tgui/packages/tgui/components/BlockQuote.tsx +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @file - * @copyright 2020 Aleksej Komarov - * @license MIT - */ - -import { classes } from 'common/react'; - -import { Box, BoxProps } from './Box'; - -export function BlockQuote(props: BoxProps) { - const { className, ...rest } = props; - - return ; -} diff --git a/tgui/packages/tgui/components/DmIcon.tsx b/tgui/packages/tgui/components/DmIcon.tsx deleted file mode 100644 index fb6816576ac..00000000000 --- a/tgui/packages/tgui/components/DmIcon.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { ReactNode, useEffect, useState } from 'react'; - -import { resolveAsset } from '../assets'; -import { fetchRetry } from '../http'; -import { BoxProps } from './Box'; -import { Image } from './Image'; - -enum Direction { - NORTH = 1, - SOUTH = 2, - EAST = 4, - WEST = 8, - NORTHEAST = NORTH | EAST, - NORTHWEST = NORTH | WEST, - SOUTHEAST = SOUTH | EAST, - SOUTHWEST = SOUTH | WEST, -} - -type Props = { - /** Required: The path of the icon */ - icon: string; - /** Required: The state of the icon */ - icon_state: string; -} & Partial<{ - /** Facing direction. See direction enum. Default is South */ - direction: Direction; - /** Fallback icon. */ - fallback: ReactNode; - /** Frame number. Default is 1 */ - frame: number; - /** Movement state. Default is false */ - movement: boolean; -}> & - BoxProps; - -let refMap: Record | undefined; - -export function DmIcon(props: Props) { - const { - className, - direction = Direction.SOUTH, - fallback, - frame = 1, - icon_state, - icon, - movement = false, - ...rest - } = props; - - const [iconRef, setIconRef] = useState(''); - - const query = `${iconRef}?state=${icon_state}&dir=${direction}&movement=${movement}&frame=${frame}`; - - useEffect(() => { - async function fetchRefMap() { - const response = await fetchRetry(resolveAsset('icon_ref_map.json')); - const data = await response.json(); - refMap = data; - setIconRef(data[icon]); - } - - if (!refMap) { - fetchRefMap(); - } else { - setIconRef(refMap[icon]); - } - }, []); - - if (!iconRef) return fallback; - - return ; -} diff --git a/tgui/packages/tgui/components/FakeTerminal.jsx b/tgui/packages/tgui/components/FakeTerminal.jsx deleted file mode 100644 index d3b7fbe65db..00000000000 --- a/tgui/packages/tgui/components/FakeTerminal.jsx +++ /dev/null @@ -1,52 +0,0 @@ -import { Component, Fragment } from 'react'; - -import { Box } from './Box'; - -export class FakeTerminal extends Component { - constructor(props) { - super(props); - this.timer = null; - this.state = { - currentIndex: 0, - currentDisplay: [], - }; - } - - tick() { - const { props, state } = this; - if (state.currentIndex <= props.allMessages.length) { - this.setState((prevState) => { - return { - currentIndex: prevState.currentIndex + 1, - }; - }); - const { currentDisplay } = state; - currentDisplay.push(props.allMessages[state.currentIndex]); - } else { - clearTimeout(this.timer); - setTimeout(props.onFinished, props.finishedTimeout); - } - } - - componentDidMount() { - const { linesPerSecond = 2.5 } = this.props; - this.timer = setInterval(() => this.tick(), 1000 / linesPerSecond); - } - - componentWillUnmount() { - clearTimeout(this.timer); - } - - render() { - return ( - - {this.state.currentDisplay.map((value) => ( - - {value} -
-
- ))} -
- ); - } -} diff --git a/tgui/packages/tgui/components/FitText.tsx b/tgui/packages/tgui/components/FitText.tsx deleted file mode 100644 index 049c887ed74..00000000000 --- a/tgui/packages/tgui/components/FitText.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import { - Component, - createRef, - HTMLAttributes, - PropsWithChildren, - RefObject, -} from 'react'; - -const DEFAULT_ACCEPTABLE_DIFFERENCE = 5; - -type Props = { - acceptableDifference?: number; - maxWidth: number; - maxFontSize: number; - native?: HTMLAttributes; -} & PropsWithChildren; - -type State = { - fontSize: number; -}; - -export class FitText extends Component { - ref: RefObject = createRef(); - state: State = { - fontSize: 0, - }; - - constructor(props: Props) { - super(props); - - this.resize = this.resize.bind(this); - - window.addEventListener('resize', this.resize); - } - - componentDidUpdate(prevProps) { - if (prevProps.children !== this.props.children) { - this.resize(); - } - } - - componentWillUnmount() { - window.removeEventListener('resize', this.resize); - } - - resize() { - const element = this.ref.current; - if (!element) { - return; - } - - const maxWidth = this.props.maxWidth; - - let start = 0; - let end = this.props.maxFontSize; - - for (let _ = 0; _ < 10; _++) { - const middle = Math.round((start + end) / 2); - element.style.fontSize = `${middle}px`; - - const difference = element.offsetWidth - maxWidth; - - if (difference > 0) { - end = middle; - } else if ( - difference < - (this.props.acceptableDifference ?? DEFAULT_ACCEPTABLE_DIFFERENCE) - ) { - start = middle; - } else { - break; - } - } - - this.setState({ - fontSize: Math.round((start + end) / 2), - }); - } - - componentDidMount() { - this.resize(); - } - - render() { - return ( - - {this.props.children} - - ); - } -} diff --git a/tgui/packages/tgui/components/Grid.tsx b/tgui/packages/tgui/components/Grid.tsx deleted file mode 100644 index 91c9256753b..00000000000 --- a/tgui/packages/tgui/components/Grid.tsx +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @file - * @copyright 2020 Aleksej Komarov - * @license MIT - */ - -import { PropsWithChildren } from 'react'; - -import { logger } from '../logging'; -import { BoxProps } from './Box'; -import { Table } from './Table'; - -/** @deprecated Do not use. Use stack instead. */ -export function Grid(props: PropsWithChildren) { - const { children, ...rest } = props; - logger.error('Grid component is deprecated. Use a Stack instead.'); - return ( - - {children} -
- ); -} - -type Props = Partial<{ - /** Width of the column in percentage. */ - size: number; -}> & - BoxProps; - -/** @deprecated Do not use. Use stack instead. */ -export function GridColumn(props: Props) { - const { size = 1, style, ...rest } = props; - return ( - - ); -} - -Grid.Column = GridColumn; diff --git a/tgui/packages/tgui/components/InfinitePlane.jsx b/tgui/packages/tgui/components/InfinitePlane.jsx deleted file mode 100644 index 5277f2ad796..00000000000 --- a/tgui/packages/tgui/components/InfinitePlane.jsx +++ /dev/null @@ -1,192 +0,0 @@ -import { Component } from 'react'; - -import { computeBoxProps } from './Box'; -import { Button } from './Button'; -import { ProgressBar } from './ProgressBar'; -import { Stack } from './Stack'; - -const ZOOM_MIN_VAL = 0.5; -const ZOOM_MAX_VAL = 1.5; - -const ZOOM_INCREMENT = 0.1; - -export class InfinitePlane extends Component { - constructor(props) { - super(props); - - this.state = { - mouseDown: false, - - left: 0, - top: 0, - - lastLeft: 0, - lastTop: 0, - - zoom: 1, - }; - - this.handleMouseDown = this.handleMouseDown.bind(this); - this.handleMouseMove = this.handleMouseMove.bind(this); - this.handleZoomIncrease = this.handleZoomIncrease.bind(this); - this.handleZoomDecrease = this.handleZoomDecrease.bind(this); - this.onMouseUp = this.onMouseUp.bind(this); - - this.doOffsetMouse = this.doOffsetMouse.bind(this); - } - - componentDidMount() { - window.addEventListener('mouseup', this.onMouseUp); - - window.addEventListener('mousedown', this.doOffsetMouse); - window.addEventListener('mousemove', this.doOffsetMouse); - window.addEventListener('mouseup', this.doOffsetMouse); - } - - componentWillUnmount() { - window.removeEventListener('mouseup', this.onMouseUp); - - window.removeEventListener('mousedown', this.doOffsetMouse); - window.removeEventListener('mousemove', this.doOffsetMouse); - window.removeEventListener('mouseup', this.doOffsetMouse); - } - - doOffsetMouse(event) { - const { zoom } = this.state; - event.screenZoomX = event.screenX * Math.pow(zoom, -1); - event.screenZoomY = event.screenY * Math.pow(zoom, -1); - } - - handleMouseDown(event) { - this.setState((state) => { - return { - mouseDown: true, - lastLeft: event.clientX - state.left, - lastTop: event.clientY - state.top, - }; - }); - } - - onMouseUp() { - this.setState({ - mouseDown: false, - }); - } - - handleZoomIncrease(event) { - const { onZoomChange } = this.props; - const { zoom } = this.state; - const newZoomValue = Math.min(zoom + ZOOM_INCREMENT, ZOOM_MAX_VAL); - this.setState({ - zoom: newZoomValue, - }); - if (onZoomChange) { - onZoomChange(newZoomValue); - } - } - - handleZoomDecrease(event) { - const { onZoomChange } = this.props; - const { zoom } = this.state; - const newZoomValue = Math.max(zoom - ZOOM_INCREMENT, ZOOM_MIN_VAL); - this.setState({ - zoom: newZoomValue, - }); - - if (onZoomChange) { - onZoomChange(newZoomValue); - } - } - - handleMouseMove(event) { - const { onBackgroundMoved, initialLeft = 0, initialTop = 0 } = this.props; - if (this.state.mouseDown) { - let newX, newY; - this.setState((state) => { - newX = event.clientX - state.lastLeft; - newY = event.clientY - state.lastTop; - return { - left: newX, - top: newY, - }; - }); - if (onBackgroundMoved) { - onBackgroundMoved(newX + initialLeft, newY + initialTop); - } - } - } - - render() { - const { - children, - backgroundImage, - imageWidth, - initialLeft = 0, - initialTop = 0, - ...rest - } = this.props; - const { left, top, zoom } = this.state; - - const finalLeft = initialLeft + left; - const finalTop = initialTop + top; - - return ( -
-
-
- {children} -
- - - -
- ); - } -} diff --git a/tgui/packages/tgui/components/KeyListener.tsx b/tgui/packages/tgui/components/KeyListener.tsx deleted file mode 100644 index 566026f0cb3..00000000000 --- a/tgui/packages/tgui/components/KeyListener.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { Component } from 'react'; - -import { KeyEvent } from '../events'; -import { listenForKeyEvents } from '../hotkeys'; - -type KeyListenerProps = Partial<{ - onKey: (key: KeyEvent) => void; - onKeyDown: (key: KeyEvent) => void; - onKeyUp: (key: KeyEvent) => void; -}>; - -export class KeyListener extends Component { - dispose: () => void; - - constructor(props) { - super(props); - - this.dispose = listenForKeyEvents((key) => { - if (this.props.onKey) { - this.props.onKey(key); - } - - if (key.isDown() && this.props.onKeyDown) { - this.props.onKeyDown(key); - } - - if (key.isUp() && this.props.onKeyUp) { - this.props.onKeyUp(key); - } - }); - } - - componentWillUnmount() { - this.dispose(); - } - - render() { - return null; - } -} diff --git a/tgui/packages/tgui/components/MenuBar.tsx b/tgui/packages/tgui/components/MenuBar.tsx deleted file mode 100644 index acf35e82812..00000000000 --- a/tgui/packages/tgui/components/MenuBar.tsx +++ /dev/null @@ -1,238 +0,0 @@ -/** - * @file - * @copyright 2022 Aleksej Komarov - * @license MIT - */ - -import { classes } from 'common/react'; -import { Component, createRef, ReactNode, RefObject } from 'react'; - -import { logger } from '../logging'; -import { Box } from './Box'; -import { Icon } from './Icon'; - -type MenuProps = { - children: any; - width: string; - menuRef: RefObject; - onOutsideClick: () => void; -}; - -class Menu extends Component { - private readonly handleClick: (event) => void; - - constructor(props) { - super(props); - this.handleClick = (event) => { - if (!this.props.menuRef.current) { - logger.log(`Menu.handleClick(): No ref`); - return; - } - - if (this.props.menuRef.current.contains(event.target)) { - logger.log(`Menu.handleClick(): Inside`); - } else { - logger.log(`Menu.handleClick(): Outside`); - this.props.onOutsideClick(); - } - }; - } - - // eslint-disable-next-line react/no-deprecated - componentWillMount() { - window.addEventListener('click', this.handleClick); - } - - componentWillUnmount() { - window.removeEventListener('click', this.handleClick); - } - - render() { - const { width, children } = this.props; - return ( -
- {children} -
- ); - } -} - -type MenuBarDropdownProps = { - open: boolean; - openWidth: string; - children: any; - disabled?: boolean; - display: any; - onMouseOver: () => void; - onClick: () => void; - onOutsideClick: () => void; - className?: string; -}; - -class MenuBarButton extends Component { - private readonly menuRef: RefObject; - - constructor(props) { - super(props); - this.menuRef = createRef(); - } - - render() { - const { props } = this; - const { - open, - openWidth, - children, - disabled, - display, - onMouseOver, - onClick, - onOutsideClick, - ...boxProps - } = props; - const { className, ...rest } = boxProps; - - return ( -
- null : onClick} - onMouseOver={onMouseOver} - > - {display} - - {open && ( - - {children} - - )} -
- ); - } -} - -type MenuBarItemProps = { - entry: string; - children: any; - openWidth: string; - display: ReactNode; - setOpenMenuBar: (entry: string | null) => void; - openMenuBar: string | null; - setOpenOnHover: (flag: boolean) => void; - openOnHover: boolean; - disabled?: boolean; - className?: string; -}; - -export const Dropdown = (props: MenuBarItemProps) => { - const { - entry, - children, - openWidth, - display, - setOpenMenuBar, - openMenuBar, - setOpenOnHover, - openOnHover, - disabled, - className, - } = props; - - return ( - { - const open = openMenuBar === entry ? null : entry; - setOpenMenuBar(open); - setOpenOnHover(!openOnHover); - }} - onOutsideClick={() => { - setOpenMenuBar(null); - setOpenOnHover(false); - }} - onMouseOver={() => { - if (openOnHover) { - setOpenMenuBar(entry); - } - }} - > - {children} - - ); -}; - -const MenuItemToggle = (props) => { - const { value, displayText, onClick, checked } = props; - return ( - onClick(value)} - > -
- {checked && } -
- {displayText} -
- ); -}; - -Dropdown.MenuItemToggle = MenuItemToggle; - -const MenuItem = (props) => { - const { value, displayText, onClick } = props; - return ( - onClick(value)} - > - {displayText} - - ); -}; - -Dropdown.MenuItem = MenuItem; - -const Separator = () => { - return
; -}; - -Dropdown.Separator = Separator; - -type MenuBarProps = { - children: any; -}; - -export const MenuBar = (props: MenuBarProps) => { - const { children } = props; - return {children}; -}; - -MenuBar.Dropdown = Dropdown; diff --git a/tgui/packages/tgui/components/RoundGauge.jsx b/tgui/packages/tgui/components/RoundGauge.jsx deleted file mode 100644 index 652875f641e..00000000000 --- a/tgui/packages/tgui/components/RoundGauge.jsx +++ /dev/null @@ -1,133 +0,0 @@ -/** - * @file - * @copyright 2020 bobbahbrown (https://github.com/bobbahbrown) - * @license MIT - */ - -import { clamp01, keyOfMatchingRange, scale } from 'common/math'; -import { classes } from 'common/react'; - -import { AnimatedNumber } from './AnimatedNumber'; -import { Box, computeBoxClassName, computeBoxProps } from './Box'; - -export const RoundGauge = (props) => { - const { - value, - minValue = 1, - maxValue = 1, - ranges, - alertAfter, - alertBefore, - format, - size = 1, - className, - style, - ...rest - } = props; - - const scaledValue = scale(value, minValue, maxValue); - const clampedValue = clamp01(scaledValue); - const scaledRanges = ranges ? {} : { primary: [0, 1] }; - if (ranges) { - Object.keys(ranges).forEach((x) => { - const range = ranges[x]; - scaledRanges[x] = [ - scale(range[0], minValue, maxValue), - scale(range[1], minValue, maxValue), - ]; - }); - } - - const shouldShowAlert = () => { - // If both after and before alert props are set, attempt to interpret both - // in a helpful way. - if (alertAfter && alertBefore && alertAfter < alertBefore) { - // If alertAfter is before alertBefore, only display an alert if - // we're between them. - if (alertAfter < value && alertBefore > value) { - return true; - } - } else if (alertAfter < value || alertBefore > value) { - // Otherwise, we have distint ranges, or only one or neither are set. - // Either way, being on the active side of either is sufficient. - return true; - } - return false; - }; - - // prettier-ignore - const alertColor = shouldShowAlert() - && keyOfMatchingRange(clampedValue, scaledRanges); - - return ( - -
- - {(alertAfter || alertBefore) && ( - - - - )} - - - - - {Object.keys(scaledRanges).map((x, i) => { - const col_ranges = scaledRanges[x]; - return ( - - ); - })} - - - - - - -
- -
- ); -}; diff --git a/tgui/packages/tgui/components/StyleableSection.tsx b/tgui/packages/tgui/components/StyleableSection.tsx deleted file mode 100644 index 53b193707f6..00000000000 --- a/tgui/packages/tgui/components/StyleableSection.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { PropsWithChildren, ReactNode } from 'react'; - -import { Box } from './Box'; - -type Props = Partial<{ - style: Record; - titleStyle: Record; - textStyle: Record; - title: ReactNode; - titleSubtext: string; -}> & - PropsWithChildren; - -// The cost of flexibility and prettiness. -export const StyleableSection = (props: Props) => { - return ( - - {/* Yes, this box (line above) is missing the "Section" class. This is very intentional, as the layout looks *ugly* with it.*/} - - - {props.title} - -
{props.titleSubtext}
-
- - {props.children} - -
- ); -}; diff --git a/tgui/packages/tgui/components/TimeDisplay.jsx b/tgui/packages/tgui/components/TimeDisplay.jsx deleted file mode 100644 index 390dbc93af9..00000000000 --- a/tgui/packages/tgui/components/TimeDisplay.jsx +++ /dev/null @@ -1,64 +0,0 @@ -import { Component } from 'react'; - -import { formatTime } from '../format'; - -// AnimatedNumber Copypaste -const isSafeNumber = (value) => { - return ( - typeof value === 'number' && Number.isFinite(value) && !Number.isNaN(value) - ); -}; - -export class TimeDisplay extends Component { - constructor(props) { - super(props); - this.timer = null; - this.last_seen_value = undefined; - this.state = { - value: 0, - }; - // Set initial state with value provided in props - if (isSafeNumber(props.value)) { - this.state.value = Number(props.value); - this.last_seen_value = Number(props.value); - } - } - - componentDidUpdate() { - if (this.props.auto !== undefined) { - clearInterval(this.timer); - this.timer = setInterval(() => this.tick(), 1000); // every 1 s - } - } - - tick() { - let current = Number(this.state.value); - if (this.props.value !== this.last_seen_value) { - this.last_seen_value = this.props.value; - current = this.props.value; - } - const mod = this.props.auto === 'up' ? 10 : -10; // Time down by default. - const value = Math.max(0, current + mod); // one sec tick - this.setState({ value }); - } - - componentDidMount() { - if (this.props.auto !== undefined) { - this.timer = setInterval(() => this.tick(), 1000); // every 1 s - } - } - - componentWillUnmount() { - clearInterval(this.timer); - } - - render() { - const val = this.state.value; - // Directly display weird stuff - if (!isSafeNumber(val)) { - return this.state.value || null; - } - - return formatTime(val); - } -} diff --git a/tgui/packages/tgui/components/TrackOutsideClicks.tsx b/tgui/packages/tgui/components/TrackOutsideClicks.tsx deleted file mode 100644 index c8451fe12d2..00000000000 --- a/tgui/packages/tgui/components/TrackOutsideClicks.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { Component, createRef, PropsWithChildren } from 'react'; - -type Props = { - onOutsideClick: () => void; -} & PropsWithChildren; - -export class TrackOutsideClicks extends Component { - ref = createRef(); - - constructor(props) { - super(props); - - this.handleOutsideClick = this.handleOutsideClick.bind(this); - - document.addEventListener('click', this.handleOutsideClick); - } - - componentWillUnmount() { - document.removeEventListener('click', this.handleOutsideClick); - } - - handleOutsideClick(event: MouseEvent) { - if (!(event.target instanceof Node)) { - return; - } - - if (this.ref.current && !this.ref.current.contains(event.target)) { - this.props.onOutsideClick(); - } - } - - render() { - return
{this.props.children}
; - } -} diff --git a/tgui/packages/tgui/components/VirtualList.tsx b/tgui/packages/tgui/components/VirtualList.tsx deleted file mode 100644 index 6d728a983c9..00000000000 --- a/tgui/packages/tgui/components/VirtualList.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { - PropsWithChildren, - useCallback, - useEffect, - useRef, - useState, -} from 'react'; - -/** - * A vertical list that renders items to fill space up to the extents of the - * current window, and then defers rendering of other items until they come - * into view. - */ -export const VirtualList = (props: PropsWithChildren) => { - const { children } = props; - const containerRef = useRef(null as HTMLDivElement | null); - const [visibleElements, setVisibleElements] = useState(1); - const [padding, setPadding] = useState(0); - - const adjustExtents = useCallback(() => { - const { current } = containerRef; - - if ( - !children || - !Array.isArray(children) || - !current || - visibleElements >= children.length - ) { - return; - } - - const unusedArea = - document.body.offsetHeight - current.getBoundingClientRect().bottom; - - const averageItemHeight = Math.ceil(current.offsetHeight / visibleElements); - - if (unusedArea > 0) { - const newVisibleElements = Math.min( - children.length, - visibleElements + - Math.max(1, Math.ceil(unusedArea / averageItemHeight)), - ); - - setVisibleElements(newVisibleElements); - - setPadding((children.length - newVisibleElements) * averageItemHeight); - } - }, [containerRef, visibleElements, children]); - - useEffect(() => { - adjustExtents(); - - const interval = setInterval(adjustExtents, 100); - - return () => clearInterval(interval); - }, [adjustExtents]); - - return ( -
-
- {Array.isArray(children) ? children.slice(0, visibleElements) : null} -
-
-
- ); -}; diff --git a/tgui/packages/tgui/components/index.ts b/tgui/packages/tgui/components/index.ts index 600958e14a6..51d1ebe36e9 100644 --- a/tgui/packages/tgui/components/index.ts +++ b/tgui/packages/tgui/components/index.ts @@ -6,8 +6,6 @@ export { AnimatedNumber } from './AnimatedNumber'; export { Autofocus } from './Autofocus'; -export { Blink } from './Blink'; -export { BlockQuote } from './BlockQuote'; export { Box } from './Box'; export { Button } from './Button'; export { ByondUi } from './ByondUi'; @@ -17,21 +15,15 @@ export { ColorBox } from './ColorBox'; export { Dialog } from './Dialog'; export { Dimmer } from './Dimmer'; export { Divider } from './Divider'; -export { DmIcon } from './DmIcon'; export { DraggableControl } from './DraggableControl'; export { Dropdown } from './Dropdown'; -export { FitText } from './FitText'; export { Flex } from './Flex'; -export { Grid } from './Grid'; export { Icon } from './Icon'; export { Image } from './Image'; -export { InfinitePlane } from './InfinitePlane'; export { Input } from './Input'; -export { KeyListener } from './KeyListener'; export { Knob } from './Knob'; export { LabeledControls } from './LabeledControls'; export { LabeledList } from './LabeledList'; -export { MenuBar } from './MenuBar'; export { Modal } from './Modal'; export { NanoMap } from './NanoMap'; export { NoticeBox } from './NoticeBox'; @@ -39,15 +31,10 @@ export { NumberInput } from './NumberInput'; export { Popper } from './Popper'; export { ProgressBar } from './ProgressBar'; export { RestrictedInput } from './RestrictedInput'; -export { RoundGauge } from './RoundGauge'; export { Section } from './Section'; export { Slider } from './Slider'; export { Stack } from './Stack'; -export { StyleableSection } from './StyleableSection'; export { Table } from './Table'; export { Tabs } from './Tabs'; export { TextArea } from './TextArea'; -export { TimeDisplay } from './TimeDisplay'; export { Tooltip } from './Tooltip'; -export { TrackOutsideClicks } from './TrackOutsideClicks'; -export { VirtualList } from './VirtualList'; diff --git a/tgui/packages/tgui/package.json b/tgui/packages/tgui/package.json index b933df189d7..98468ff5c24 100644 --- a/tgui/packages/tgui/package.json +++ b/tgui/packages/tgui/package.json @@ -16,6 +16,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-popper": "^2.3.0", + "tgui-core": "^1.2.0", "tgui-dev-server": "workspace:*", "tgui-polyfill": "workspace:*" } diff --git a/tgui/packages/tgui/stories/Blink.stories.jsx b/tgui/packages/tgui/stories/Blink.stories.jsx deleted file mode 100644 index 5a789954073..00000000000 --- a/tgui/packages/tgui/stories/Blink.stories.jsx +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @file - * @copyright 2021 Aleksej Komarov - * @license MIT - */ - -import { Blink, Section } from '../components'; - -export const meta = { - title: 'Blink', - render: () => , -}; - -const Story = (props) => { - return ( -
- Blink -
- ); -}; diff --git a/tgui/packages/tgui/stories/BlockQuote.stories.jsx b/tgui/packages/tgui/stories/BlockQuote.stories.jsx deleted file mode 100644 index adb7564b856..00000000000 --- a/tgui/packages/tgui/stories/BlockQuote.stories.jsx +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @file - * @copyright 2021 Aleksej Komarov - * @license MIT - */ - -import { BlockQuote, Section } from '../components'; -import { BoxWithSampleText } from './common'; - -export const meta = { - title: 'BlockQuote', - render: () => , -}; - -const Story = (props) => { - return ( -
-
- -
-
- ); -}; diff --git a/tgui/packages/tgui/styles/components/BlockQuote.scss b/tgui/packages/tgui/styles/components/BlockQuote.scss deleted file mode 100644 index 4e54030e5b6..00000000000 --- a/tgui/packages/tgui/styles/components/BlockQuote.scss +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT - */ - -@use '../base.scss'; -@use '../colors.scss'; - -$color-default: colors.fg(colors.$label) !default; - -.BlockQuote { - color: $color-default; - border-left: base.em(2px) solid $color-default; - padding-left: 0.5em; - margin-bottom: 0.5em; - - &:last-child { - margin-bottom: 0; - } -} diff --git a/tgui/packages/tgui/styles/components/MenuBar.scss b/tgui/packages/tgui/styles/components/MenuBar.scss deleted file mode 100644 index 0f5eb47380c..00000000000 --- a/tgui/packages/tgui/styles/components/MenuBar.scss +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT - */ - -@use '../base.scss'; - -$separator-color: base.$color-bg-section; -$background-color: base.$color-bg !default; -$dropdown-z-index: 5; - -.MenuBar { - display: flex; -} - -.MenuBar__font { - font-family: Verdana, sans-serif; - font-size: base.em(12px); - line-height: base.em(17px); -} - -.MenuBar__hover { - &:hover { - background-color: lighten($background-color, 30%); - transition: background-color 0ms; - } -} - -.MenuBar__MenuBarButton { - padding: 0.2rem 0.5rem 0.2rem 0.5rem; -} - -.MenuBar__menu { - position: absolute; - z-index: $dropdown-z-index; - background-color: $background-color; - padding: 0.3rem 0.3rem 0.3rem 0.3rem; - box-shadow: 4px 6px 5px -2px rgba(0, 0, 0, 0.55); -} - -.MenuBar__MenuItem { - z-index: $dropdown-z-index; - transition: background-color 100ms ease-out; - background-color: $background-color; - white-space: nowrap; - padding: 0.3rem 2rem 0.3rem 3rem; -} - -.MenuBar__MenuItemToggle { - padding: 0.3rem 2rem 0.3rem 0; -} - -.MenuBar__MenuItemToggle__check { - display: inline-block; - vertical-align: middle; - min-width: 3rem; - margin-left: 0.3rem; -} - -.MenuBar__over { - top: auto; - bottom: 100%; -} - -.MenuBar__MenuBarButton-text { - text-overflow: clip; - white-space: nowrap; - height: base.em(17px); -} - -.MenuBar__Separator { - display: block; - margin: 0.3rem 0.3rem 0.3rem 2.3rem; - border-top: 1px solid $separator-color; -} diff --git a/tgui/packages/tgui/styles/components/RoundGauge.scss b/tgui/packages/tgui/styles/components/RoundGauge.scss deleted file mode 100644 index be95519d646..00000000000 --- a/tgui/packages/tgui/styles/components/RoundGauge.scss +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright (c) 2020 bobbahbrown (https://github.com/bobbahbrown) - * SPDX-License-Identifier: MIT - */ - -@use '../base.scss'; -@use '../colors.scss'; -@use '../functions.scss' as *; - -$fg-map: colors.$fg-map !default; -$ring-color: #6a96c9 !default; - -.RoundGauge { - font-size: 1rem; - width: 2.6em; - height: 1.3em; - margin: 0 auto; - margin-bottom: 0.2em; -} - -$pi: 3.1416; - -.RoundGauge__ringTrack { - fill: transparent; - stroke: rgba(255, 255, 255, 0.1); - stroke-width: 10; - stroke-dasharray: 50 * $pi; - stroke-dashoffset: 50 * $pi; -} - -.RoundGauge__ringFill { - fill: transparent; - stroke: $ring-color; - stroke-width: 10; - stroke-dasharray: 100 * $pi; - transition: stroke 50ms ease-out; -} - -.RoundGauge__needle, -.RoundGauge__ringFill { - transition: transform 50ms ease-in-out; -} - -.RoundGauge__needleLine, -.RoundGauge__needleMiddle { - fill: colors.$bad; -} - -.RoundGauge__alert { - fill-rule: evenodd; - clip-rule: evenodd; - stroke-linejoin: round; - stroke-miterlimit: 2; - fill: rgba(255, 255, 255, 0.1); -} - -.RoundGauge__alert.max { - fill: colors.$bad; -} - -@each $color-name, $color-value in $fg-map { - .RoundGauge--color--#{$color-name}.RoundGauge__ringFill { - stroke: $color-value; - } -} - -@each $color-name, $color-value in $fg-map { - .RoundGauge__alert--#{$color-name} { - fill: $color-value; - transition: opacity 0.6s cubic-bezier(0.25, 1, 0.5, 1); - animation: RoundGauge__alertAnim - 1s - cubic-bezier(0.34, 1.56, 0.64, 1) - infinite; - } -} - -@keyframes RoundGauge__alertAnim { - 0% { - opacity: 0.1; - } - 50% { - opacity: 1; - } - 100% { - opacity: 0.1; - } -} diff --git a/tgui/packages/tgui/styles/main.scss b/tgui/packages/tgui/styles/main.scss index 4f115f75d9c..dcdf4c87894 100644 --- a/tgui/packages/tgui/styles/main.scss +++ b/tgui/packages/tgui/styles/main.scss @@ -20,7 +20,6 @@ @include meta.load-css('./atomic/text.scss'); // Components -@include meta.load-css('./components/BlockQuote.scss'); @include meta.load-css('./components/Button.scss'); @include meta.load-css('./components/ColorBox.scss'); @include meta.load-css('./components/Dialog.scss'); @@ -32,13 +31,11 @@ @include meta.load-css('./components/Input.scss'); @include meta.load-css('./components/Knob.scss'); @include meta.load-css('./components/LabeledList.scss'); -@include meta.load-css('./components/MenuBar.scss'); @include meta.load-css('./components/Modal.scss'); @include meta.load-css('./components/NanoMap.scss'); @include meta.load-css('./components/NoticeBox.scss'); @include meta.load-css('./components/NumberInput.scss'); @include meta.load-css('./components/ProgressBar.scss'); -@include meta.load-css('./components/RoundGauge.scss'); @include meta.load-css('./components/Section.scss'); @include meta.load-css('./components/Slider.scss'); @include meta.load-css('./components/Stack.scss'); diff --git a/tgui/webpack.config.js b/tgui/webpack.config.js index fa1782eb073..6ff3d1bf4a0 100644 --- a/tgui/webpack.config.js +++ b/tgui/webpack.config.js @@ -60,7 +60,7 @@ module.exports = (env = {}, argv) => { ], }, { - test: /\.scss$/, + test: /\.(s)?css$/, use: [ { loader: ExtractCssPlugin.loader, diff --git a/tgui/yarn.lock b/tgui/yarn.lock index c53812c4aec..93ba3e4b449 100644 --- a/tgui/yarn.lock +++ b/tgui/yarn.lock @@ -8236,6 +8236,16 @@ __metadata: languageName: unknown linkType: soft +"tgui-core@npm:^1.2.0": + version: 1.2.0 + resolution: "tgui-core@npm:1.2.0" + peerDependencies: + react: ^18.2.0 + react-dom: ^18.2.0 + checksum: 10c0/1eead0edbe0df5c49bfa88f0d2caa5df743057be75e9c526d0afd838b8def072c67fe60435c66cba52551c4ef70749d60d68094fa103542187008998002714f7 + languageName: node + linkType: hard + "tgui-dev-server@workspace:*, tgui-dev-server@workspace:packages/tgui-dev-server": version: 0.0.0-use.local resolution: "tgui-dev-server@workspace:packages/tgui-dev-server" @@ -8344,6 +8354,7 @@ __metadata: react: "npm:^18.2.0" react-dom: "npm:^18.2.0" react-popper: "npm:^2.3.0" + tgui-core: "npm:^1.2.0" tgui-dev-server: "workspace:*" tgui-polyfill: "workspace:*" languageName: unknown