tgui-core 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/components/ByondUi.jsx +0 -5
  2. package/package.json +3 -2
  3. package/styles/main.scss +0 -39
  4. package/debug/KitchenSink.tsx +0 -56
  5. package/debug/actions.ts +0 -11
  6. package/debug/hooks.ts +0 -10
  7. package/debug/index.ts +0 -10
  8. package/debug/middleware.ts +0 -67
  9. package/debug/reducer.ts +0 -27
  10. package/debug/selectors.ts +0 -7
  11. package/layouts/Layout.tsx +0 -75
  12. package/layouts/NtosWindow.tsx +0 -162
  13. package/layouts/Pane.tsx +0 -56
  14. package/layouts/Window.tsx +0 -227
  15. package/layouts/index.ts +0 -10
  16. package/src/backend.ts +0 -368
  17. package/src/drag.ts +0 -280
  18. package/src/focus.ts +0 -25
  19. package/src/renderer.ts +0 -50
  20. package/stories/Blink.stories.tsx +0 -20
  21. package/stories/BlockQuote.stories.tsx +0 -23
  22. package/stories/Box.stories.tsx +0 -27
  23. package/stories/Button.stories.tsx +0 -68
  24. package/stories/ByondUi.stories.tsx +0 -45
  25. package/stories/Collapsible.stories.tsx +0 -23
  26. package/stories/Flex.stories.tsx +0 -68
  27. package/stories/Input.stories.tsx +0 -124
  28. package/stories/LabeledList.stories.tsx +0 -73
  29. package/stories/Popper.stories.tsx +0 -58
  30. package/stories/ProgressBar.stories.tsx +0 -58
  31. package/stories/Stack.stories.tsx +0 -55
  32. package/stories/Storage.stories.tsx +0 -46
  33. package/stories/Themes.stories.tsx +0 -30
  34. package/stories/Tooltip.stories.tsx +0 -48
  35. package/stories/common.tsx +0 -19
  36. package/styles/layouts/Layout.scss +0 -57
  37. package/styles/layouts/NtosHeader.scss +0 -20
  38. package/styles/layouts/NtosWindow.scss +0 -26
  39. package/styles/layouts/TitleBar.scss +0 -111
  40. package/styles/layouts/Window.scss +0 -103
  41. package/styles/themes/abductor.scss +0 -68
  42. package/styles/themes/admin.scss +0 -38
  43. package/styles/themes/cardtable.scss +0 -57
  44. package/styles/themes/hackerman.scss +0 -70
  45. package/styles/themes/malfunction.scss +0 -67
  46. package/styles/themes/neutral.scss +0 -50
  47. package/styles/themes/ntOS95.scss +0 -166
  48. package/styles/themes/ntos.scss +0 -44
  49. package/styles/themes/ntos_cat.scss +0 -148
  50. package/styles/themes/ntos_darkmode.scss +0 -44
  51. package/styles/themes/ntos_lightmode.scss +0 -67
  52. package/styles/themes/ntos_spooky.scss +0 -69
  53. package/styles/themes/ntos_synth.scss +0 -99
  54. package/styles/themes/ntos_terminal.scss +0 -112
  55. package/styles/themes/paper.scss +0 -184
  56. package/styles/themes/retro.scss +0 -72
  57. package/styles/themes/spookyconsole.scss +0 -73
  58. package/styles/themes/syndicate.scss +0 -67
  59. package/styles/themes/wizard.scss +0 -68
@@ -10,8 +10,6 @@ import { Component, createRef } from 'react';
10
10
 
11
11
  import { computeBoxProps } from './Box';
12
12
 
13
- const logger = createLogger('ByondUi');
14
-
15
13
  // Stack of currently allocated BYOND UI element ids.
16
14
  const byondUiStack = [];
17
15
 
@@ -24,12 +22,10 @@ const createByondUiElement = (elementId) => {
24
22
  // Return a control structure
25
23
  return {
26
24
  render: (params) => {
27
- logger.log(`rendering '${id}'`);
28
25
  byondUiStack[index] = id;
29
26
  Byond.winset(id, params);
30
27
  },
31
28
  unmount: () => {
32
- logger.log(`unmounting '${id}'`);
33
29
  byondUiStack[index] = null;
34
30
  Byond.winset(id, {
35
31
  parent: '',
@@ -43,7 +39,6 @@ window.addEventListener('beforeunload', () => {
43
39
  for (let index = 0; index < byondUiStack.length; index++) {
44
40
  const id = byondUiStack[index];
45
41
  if (typeof id === 'string') {
46
- logger.log(`unmounting '${id}' (beforeunload)`);
47
42
  byondUiStack[index] = null;
48
43
  Byond.winset(id, {
49
44
  parent: '',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tgui-core",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "TGUI core component library",
5
5
  "keywords": [
6
6
  "TGUI",
@@ -19,6 +19,7 @@
19
19
  "@types/node": "^20.12.12",
20
20
  "@types/react": "^18.3.3",
21
21
  "@types/react-dom": "^18.3.0",
22
- "@types/webpack-env": "^1.18.5"
22
+ "@types/webpack-env": "^1.18.5",
23
+ "typescript": "^5.4.5"
23
24
  }
24
25
  }
package/styles/main.scss CHANGED
@@ -47,45 +47,6 @@
47
47
  @include meta.load-css('./components/TextArea.scss');
48
48
  @include meta.load-css('./components/Tooltip.scss');
49
49
 
50
- // Interfaces
51
- @include meta.load-css('./interfaces/AlertModal.scss');
52
- @include meta.load-css('./interfaces/Changelog.scss');
53
- @include meta.load-css('./interfaces/CrewManifest.scss');
54
- @include meta.load-css('./interfaces/Emojipedia.scss');
55
- @include meta.load-css('./interfaces/ExperimentConfigure.scss');
56
- @include meta.load-css('./interfaces/Fabricator.scss');
57
- @include meta.load-css('./interfaces/Fishing.scss');
58
- @include meta.load-css('./interfaces/HellishRunes.scss');
59
- @include meta.load-css('./interfaces/HotKeysHelp.scss');
60
- @include meta.load-css('./interfaces/Hypertorus.scss');
61
- @include meta.load-css('./interfaces/IntegratedCircuit.scss');
62
- @include meta.load-css('./interfaces/LibraryAdmin.scss');
63
- @include meta.load-css('./interfaces/LibraryComputer.scss');
64
- @include meta.load-css('./interfaces/ListInput.scss');
65
- @include meta.load-css('./interfaces/Mecha.scss');
66
- @include meta.load-css('./interfaces/NtosMessenger.scss');
67
- @include meta.load-css('./interfaces/NtosNotepad.scss');
68
- @include meta.load-css('./interfaces/NuclearBomb.scss');
69
- @include meta.load-css('./interfaces/Orbit.scss');
70
- @include meta.load-css('./interfaces/Paper.scss');
71
- @include meta.load-css('./interfaces/PersonalCrafting.scss');
72
- @include meta.load-css('./interfaces/PreferencesMenu.scss');
73
- @include meta.load-css('./interfaces/RequestManager.scss');
74
- @include meta.load-css('./interfaces/Roulette.scss');
75
- @include meta.load-css('./interfaces/Safe.scss');
76
- @include meta.load-css('./interfaces/TachyonArray.scss');
77
- @include meta.load-css('./interfaces/Techweb.scss');
78
- @include meta.load-css('./interfaces/Trophycase.scss');
79
- @include meta.load-css('./interfaces/Uplink.scss');
80
- @include meta.load-css('./interfaces/UtilityModulesPane.scss');
81
-
82
- // Layouts
83
- @include meta.load-css('./layouts/Layout.scss');
84
- @include meta.load-css('./layouts/NtosHeader.scss');
85
- @include meta.load-css('./layouts/NtosWindow.scss');
86
- @include meta.load-css('./layouts/TitleBar.scss');
87
- @include meta.load-css('./layouts/Window.scss');
88
-
89
50
  @include meta.load-css('highlight.js/scss/github-dark.scss');
90
51
 
91
52
  // NT Theme
@@ -1,56 +0,0 @@
1
- /**
2
- * @file
3
- * @copyright 2020 Aleksej Komarov
4
- * @license MIT
5
- */
6
-
7
- import { useState } from 'react';
8
-
9
- import { Flex, Section, Tabs } from '../components';
10
- import { Pane, Window } from '../layouts';
11
-
12
- const r = require.context('../stories', false, /\.stories\.jsx$/);
13
-
14
- /**
15
- * @returns {{
16
- * meta: {
17
- * title: string,
18
- * render: () => any,
19
- * },
20
- * }[]}
21
- */
22
- const getStories = () => r.keys().map((path) => r(path));
23
-
24
- export const KitchenSink = (props) => {
25
- const { panel } = props;
26
- const [theme] = useState('');
27
- const [pageIndex, setPageIndex] = useState(0);
28
- const stories = getStories();
29
- const story = stories[pageIndex];
30
- const Layout = panel ? Pane : Window;
31
- return (
32
- <Layout title="Kitchen Sink" width={600} height={500} theme={theme}>
33
- <Flex height="100%">
34
- <Flex.Item m={1} mr={0}>
35
- <Section fill fitted>
36
- <Tabs vertical>
37
- {stories.map((story, i) => (
38
- <Tabs.Tab
39
- key={i}
40
- color="transparent"
41
- selected={i === pageIndex}
42
- onClick={() => setPageIndex(i)}
43
- >
44
- {story.meta.title}
45
- </Tabs.Tab>
46
- ))}
47
- </Tabs>
48
- </Section>
49
- </Flex.Item>
50
- <Flex.Item position="relative" grow={1}>
51
- <Layout.Content scrollable>{story.meta.render()}</Layout.Content>
52
- </Flex.Item>
53
- </Flex>
54
- </Layout>
55
- );
56
- };
package/debug/actions.ts DELETED
@@ -1,11 +0,0 @@
1
- /**
2
- * @file
3
- * @copyright 2020 Aleksej Komarov
4
- * @license MIT
5
- */
6
-
7
- import { createAction } from '../common/redux';
8
-
9
- export const toggleKitchenSink = createAction('debug/toggleKitchenSink');
10
- export const toggleDebugLayout = createAction('debug/toggleDebugLayout');
11
- export const openExternalBrowser = createAction('debug/openExternalBrowser');
package/debug/hooks.ts DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * @file
3
- * @copyright 2020 Aleksej Komarov
4
- * @license MIT
5
- */
6
-
7
- import { useSelector } from '../src/backend';
8
- import { selectDebug } from './selectors';
9
-
10
- export const useDebug = () => useSelector(selectDebug);
package/debug/index.ts DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * @file
3
- * @copyright 2020 Aleksej Komarov
4
- * @license MIT
5
- */
6
-
7
- export { useDebug } from './hooks';
8
- export { KitchenSink } from './KitchenSink';
9
- export { debugMiddleware, relayMiddleware } from './middleware';
10
- export { debugReducer } from './reducer';
@@ -1,67 +0,0 @@
1
- /**
2
- * @file
3
- * @copyright 2020 Aleksej Komarov
4
- * @license MIT
5
- */
6
-
7
- import { KEY_BACKSPACE, KEY_F10, KEY_F11, KEY_F12 } from '../common/keycodes';
8
-
9
- import { globalEvents } from '../src/events';
10
- import { acquireHotKey } from '../src/hotkeys';
11
- import {
12
- openExternalBrowser,
13
- toggleDebugLayout,
14
- toggleKitchenSink,
15
- } from './actions';
16
-
17
- const relayedTypes = ['backend/update', 'chat/message'];
18
-
19
- export const debugMiddleware = (store) => {
20
- acquireHotKey(KEY_F11);
21
- acquireHotKey(KEY_F12);
22
- globalEvents.on('keydown', (key) => {
23
- if (key.code === KEY_F11) {
24
- store.dispatch(toggleDebugLayout());
25
- }
26
- if (key.code === KEY_F12) {
27
- store.dispatch(toggleKitchenSink());
28
- }
29
- if (key.ctrl && key.alt && key.code === KEY_BACKSPACE) {
30
- // NOTE: We need to call this in a timeout, because we need a clean
31
- // stack in order for this to be a fatal error.
32
- setTimeout(() => {
33
- throw new Error(
34
- 'OOPSIE WOOPSIE!! UwU We made a fucky wucky!! A wittle' +
35
- ' fucko boingo! The code monkeys at our headquarters are' +
36
- ' working VEWY HAWD to fix this!'
37
- );
38
- });
39
- }
40
- });
41
- return (next) => (action) => next(action);
42
- };
43
-
44
- export const relayMiddleware = (store) => {
45
- const externalBrowser = location.search === '?external';
46
- if (externalBrowser) {
47
- // todo: implement
48
- } else {
49
- acquireHotKey(KEY_F10);
50
- globalEvents.on('keydown', (key) => {
51
- if (key === KEY_F10) {
52
- store.dispatch(openExternalBrowser());
53
- }
54
- });
55
- }
56
- return (next) => (action) => {
57
- const { type, payload, relayed } = action;
58
- if (type === openExternalBrowser.type) {
59
- window.open(location.href + '?external', '_blank');
60
- return;
61
- }
62
- if (relayedTypes.includes(type) && !relayed && !externalBrowser) {
63
- // todo: implement
64
- }
65
- return next(action);
66
- };
67
- };
package/debug/reducer.ts DELETED
@@ -1,27 +0,0 @@
1
- /**
2
- * @file
3
- * @copyright 2020 Aleksej Komarov
4
- * @license MIT
5
- */
6
-
7
- type DebugState = {
8
- kitchenSink: boolean;
9
- debugLayout: boolean;
10
- };
11
-
12
- export const debugReducer = (state: DebugState, action) => {
13
- const { type } = action;
14
- if (type === 'debug/toggleKitchenSink') {
15
- return {
16
- ...state,
17
- kitchenSink: !state.kitchenSink,
18
- };
19
- }
20
- if (type === 'debug/toggleDebugLayout') {
21
- return {
22
- ...state,
23
- debugLayout: !state.debugLayout,
24
- };
25
- }
26
- return state;
27
- };
@@ -1,7 +0,0 @@
1
- /**
2
- * @file
3
- * @copyright 2020 Aleksej Komarov
4
- * @license MIT
5
- */
6
-
7
- export const selectDebug = (state) => state.debug;
@@ -1,75 +0,0 @@
1
- /**
2
- * @file
3
- * @copyright 2020 Aleksej Komarov
4
- * @license MIT
5
- */
6
-
7
- import { classes } from '../common/react';
8
- import { useEffect, useRef } from 'react';
9
-
10
- import {
11
- BoxProps,
12
- computeBoxClassName,
13
- computeBoxProps,
14
- } from '../components/Box';
15
- import { addScrollableNode, removeScrollableNode } from '../src/events';
16
-
17
- type Props = Partial<{
18
- theme: string;
19
- }> &
20
- BoxProps;
21
-
22
- export function Layout(props: Props) {
23
- const { className, theme = 'nanotrasen', children, ...rest } = props;
24
-
25
- return (
26
- <div className={'theme-' + theme}>
27
- <div
28
- className={classes(['Layout', className, computeBoxClassName(rest)])}
29
- {...computeBoxProps(rest)}
30
- >
31
- {children}
32
- </div>
33
- </div>
34
- );
35
- }
36
-
37
- type ContentProps = Partial<{
38
- scrollable: boolean;
39
- }> &
40
- BoxProps;
41
-
42
- function LayoutContent(props: ContentProps) {
43
- const { className, scrollable, children, ...rest } = props;
44
- const node = useRef<HTMLDivElement>(null);
45
-
46
- useEffect(() => {
47
- const self = node.current;
48
-
49
- if (self && scrollable) {
50
- addScrollableNode(self);
51
- }
52
- return () => {
53
- if (self && scrollable) {
54
- removeScrollableNode(self);
55
- }
56
- };
57
- }, []);
58
-
59
- return (
60
- <div
61
- className={classes([
62
- 'Layout__content',
63
- scrollable && 'Layout__content--scrollable',
64
- className,
65
- computeBoxClassName(rest),
66
- ])}
67
- ref={node}
68
- {...computeBoxProps(rest)}
69
- >
70
- {children}
71
- </div>
72
- );
73
- }
74
-
75
- Layout.Content = LayoutContent;
@@ -1,162 +0,0 @@
1
- /**
2
- * @file
3
- * @copyright 2020 Aleksej Komarov
4
- * @license MIT
5
- */
6
-
7
- import { BooleanLike } from '../common/react';
8
-
9
- import { resolveAsset } from '../src/assets';
10
- import { useBackend } from '../src/backend';
11
- import { Box } from '../components/Box';
12
- import { Button } from '../components/Button';
13
- import { Window } from './Window';
14
-
15
- export type NTOSData = {
16
- authenticatedUser: string | null;
17
- authIDName: string;
18
- comp_light_color: string;
19
- has_id: BooleanLike;
20
- has_light: BooleanLike;
21
- id_name: string;
22
- light_on: BooleanLike;
23
- login: Login;
24
- pai: string | null;
25
- PC_batteryicon: string | null;
26
- PC_batterypercent: string | null;
27
- PC_device_theme: string;
28
- PC_lowpower_mode: BooleanLike;
29
- PC_ntneticon: string;
30
- PC_programheaders: Program[];
31
- PC_showexitprogram: BooleanLike;
32
- PC_stationdate: string;
33
- PC_stationtime: string;
34
- programs: Program[];
35
- proposed_login: Login;
36
- removable_media: string[];
37
- show_imprint: BooleanLike;
38
- };
39
-
40
- type Program = {
41
- alert: BooleanLike;
42
- desc: string;
43
- header_program: BooleanLike;
44
- icon: string;
45
- name: string;
46
- running: BooleanLike;
47
- };
48
-
49
- type Login = {
50
- IDInserted?: BooleanLike;
51
- IDJob: string | null;
52
- IDName: string | null;
53
- };
54
-
55
- export const NtosWindow = (props) => {
56
- const { title, width = 575, height = 700, children } = props;
57
- const { act, data } = useBackend<NTOSData>();
58
- const {
59
- PC_device_theme,
60
- PC_batteryicon,
61
- PC_batterypercent,
62
- PC_ntneticon,
63
- PC_stationdate,
64
- PC_stationtime,
65
- PC_programheaders = [],
66
- PC_showexitprogram,
67
- PC_lowpower_mode,
68
- } = data;
69
-
70
- return (
71
- <Window title={title} width={width} height={height} theme={PC_device_theme}>
72
- <div className="NtosWindow">
73
- <div className="NtosWindow__header NtosHeader">
74
- <div className="NtosHeader__left">
75
- <Box inline bold mr={2}>
76
- <Button
77
- width="26px"
78
- lineHeight="22px"
79
- textAlign="left"
80
- tooltip={PC_stationdate}
81
- color="transparent"
82
- icon="calendar"
83
- tooltipPosition="bottom"
84
- />
85
- {PC_stationtime}
86
- </Box>
87
- <Box inline italic mr={2} opacity={0.33}>
88
- {(PC_device_theme === 'syndicate' && 'Syndix') || 'NtOS'}
89
- {!!PC_lowpower_mode && ' - RUNNING ON LOW POWER MODE'}
90
- </Box>
91
- </div>
92
- <div className="NtosHeader__right">
93
- {PC_programheaders.map((header) => (
94
- <Box key={header.icon} inline mr={1}>
95
- <img
96
- className="NtosHeader__icon"
97
- src={resolveAsset(header.icon)}
98
- />
99
- </Box>
100
- ))}
101
- <Box inline>
102
- {PC_ntneticon && (
103
- <img
104
- className="NtosHeader__icon"
105
- src={resolveAsset(PC_ntneticon)}
106
- />
107
- )}
108
- </Box>
109
- {!!PC_batteryicon && (
110
- <Box inline mr={1}>
111
- <img
112
- className="NtosHeader__icon"
113
- src={resolveAsset(PC_batteryicon)}
114
- />
115
- {PC_batterypercent}
116
- </Box>
117
- )}
118
- {!!PC_showexitprogram && (
119
- <Button
120
- color="transparent"
121
- icon="window-minimize-o"
122
- tooltip="Minimize"
123
- tooltipPosition="bottom"
124
- onClick={() => act('PC_minimize')}
125
- />
126
- )}
127
- {!!PC_showexitprogram && (
128
- <Button
129
- color="transparent"
130
- icon="window-close-o"
131
- tooltip="Close"
132
- tooltipPosition="bottom-start"
133
- onClick={() => act('PC_exit')}
134
- />
135
- )}
136
- {!PC_showexitprogram && (
137
- <Button
138
- textAlign="center"
139
- color="transparent"
140
- icon="power-off"
141
- tooltip="Power off"
142
- tooltipPosition="bottom-start"
143
- onClick={() => act('PC_shutdown')}
144
- />
145
- )}
146
- </div>
147
- </div>
148
- {children}
149
- </div>
150
- </Window>
151
- );
152
- };
153
-
154
- const NtosWindowContent = (props) => {
155
- return (
156
- <div className="NtosWindow__content">
157
- <Window.Content {...props} />
158
- </div>
159
- );
160
- };
161
-
162
- NtosWindow.Content = NtosWindowContent;
package/layouts/Pane.tsx DELETED
@@ -1,56 +0,0 @@
1
- /**
2
- * @file
3
- * @copyright 2020 Aleksej Komarov
4
- * @license MIT
5
- */
6
-
7
- import { classes } from '../common/react';
8
-
9
- import { useBackend } from '../src/backend';
10
- import { Box, BoxProps } from '../components/Box';
11
- import { useDebug } from '../debug';
12
- import { Layout } from './Layout';
13
-
14
- type Props = Partial<{
15
- theme: string;
16
- }> &
17
- BoxProps;
18
-
19
- export function Pane(props: Props) {
20
- const { theme, children, className, ...rest } = props;
21
- const { suspended } = useBackend();
22
- const { debugLayout = false } = useDebug();
23
-
24
- return (
25
- <Layout className={classes(['Window', className])} theme={theme} {...rest}>
26
- <Box fillPositionedParent className={debugLayout && 'debug-layout'}>
27
- {!suspended && children}
28
- </Box>
29
- </Layout>
30
- );
31
- }
32
-
33
- type ContentProps = Partial<{
34
- fitted: boolean;
35
- scrollable: boolean;
36
- }> &
37
- BoxProps;
38
-
39
- function PaneContent(props: ContentProps) {
40
- const { className, fitted, children, ...rest } = props;
41
-
42
- return (
43
- <Layout.Content
44
- className={classes(['Window__content', className])}
45
- {...rest}
46
- >
47
- {fitted ? (
48
- children
49
- ) : (
50
- <div className="Window__contentPadding">{children}</div>
51
- )}
52
- </Layout.Content>
53
- );
54
- }
55
-
56
- Pane.Content = PaneContent;