tgui-core 1.0.0

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 (152) hide show
  1. package/.editorconfig +10 -0
  2. package/.eslintrc.cjs +78 -0
  3. package/.gitattributes +4 -0
  4. package/.prettierrc.yml +1 -0
  5. package/.vscode/extensions.json +6 -0
  6. package/.vscode/settings.json +5 -0
  7. package/README.md +1 -0
  8. package/global.d.ts +173 -0
  9. package/package.json +25 -0
  10. package/src/assets.ts +43 -0
  11. package/src/backend.ts +369 -0
  12. package/src/common/collections.ts +349 -0
  13. package/src/common/color.ts +94 -0
  14. package/src/common/events.ts +45 -0
  15. package/src/common/exhaustive.ts +19 -0
  16. package/src/common/fp.ts +38 -0
  17. package/src/common/keycodes.ts +86 -0
  18. package/src/common/keys.ts +39 -0
  19. package/src/common/math.ts +98 -0
  20. package/src/common/perf.ts +72 -0
  21. package/src/common/random.ts +32 -0
  22. package/src/common/react.ts +65 -0
  23. package/src/common/redux.ts +196 -0
  24. package/src/common/storage.js +196 -0
  25. package/src/common/string.ts +173 -0
  26. package/src/common/timer.ts +68 -0
  27. package/src/common/type-utils.ts +41 -0
  28. package/src/common/types.ts +9 -0
  29. package/src/common/uuid.ts +24 -0
  30. package/src/common/vector.ts +51 -0
  31. package/src/components/AnimatedNumber.tsx +185 -0
  32. package/src/components/Autofocus.tsx +23 -0
  33. package/src/components/Blink.jsx +69 -0
  34. package/src/components/BlockQuote.tsx +15 -0
  35. package/src/components/BodyZoneSelector.tsx +149 -0
  36. package/src/components/Box.tsx +255 -0
  37. package/src/components/Button.tsx +415 -0
  38. package/src/components/ByondUi.jsx +121 -0
  39. package/src/components/Chart.tsx +160 -0
  40. package/src/components/Collapsible.tsx +45 -0
  41. package/src/components/ColorBox.tsx +30 -0
  42. package/src/components/Dialog.tsx +85 -0
  43. package/src/components/Dimmer.tsx +19 -0
  44. package/src/components/Divider.tsx +26 -0
  45. package/src/components/DmIcon.tsx +72 -0
  46. package/src/components/DraggableControl.jsx +282 -0
  47. package/src/components/Dropdown.tsx +246 -0
  48. package/src/components/FakeTerminal.jsx +52 -0
  49. package/src/components/FitText.tsx +99 -0
  50. package/src/components/Flex.tsx +105 -0
  51. package/src/components/Grid.tsx +44 -0
  52. package/src/components/Icon.tsx +91 -0
  53. package/src/components/Image.tsx +63 -0
  54. package/src/components/InfinitePlane.jsx +192 -0
  55. package/src/components/Input.tsx +181 -0
  56. package/src/components/KeyListener.tsx +40 -0
  57. package/src/components/Knob.tsx +185 -0
  58. package/src/components/LabeledControls.tsx +50 -0
  59. package/src/components/LabeledList.tsx +130 -0
  60. package/src/components/MenuBar.tsx +238 -0
  61. package/src/components/Modal.tsx +25 -0
  62. package/src/components/NoticeBox.tsx +48 -0
  63. package/src/components/NumberInput.tsx +328 -0
  64. package/src/components/Popper.tsx +100 -0
  65. package/src/components/ProgressBar.tsx +79 -0
  66. package/src/components/RestrictedInput.jsx +301 -0
  67. package/src/components/RoundGauge.tsx +189 -0
  68. package/src/components/Section.tsx +125 -0
  69. package/src/components/Slider.tsx +173 -0
  70. package/src/components/Stack.tsx +101 -0
  71. package/src/components/StyleableSection.tsx +30 -0
  72. package/src/components/Table.tsx +90 -0
  73. package/src/components/Tabs.tsx +90 -0
  74. package/src/components/TextArea.tsx +198 -0
  75. package/src/components/TimeDisplay.jsx +64 -0
  76. package/src/components/Tooltip.tsx +147 -0
  77. package/src/components/TrackOutsideClicks.tsx +35 -0
  78. package/src/components/VirtualList.tsx +69 -0
  79. package/src/constants.ts +355 -0
  80. package/src/debug/KitchenSink.jsx +56 -0
  81. package/src/debug/actions.js +11 -0
  82. package/src/debug/hooks.js +10 -0
  83. package/src/debug/index.ts +10 -0
  84. package/src/debug/middleware.js +86 -0
  85. package/src/debug/reducer.js +22 -0
  86. package/src/debug/selectors.js +7 -0
  87. package/src/drag.ts +280 -0
  88. package/src/events.ts +237 -0
  89. package/src/focus.ts +25 -0
  90. package/src/format.ts +173 -0
  91. package/src/hotkeys.ts +212 -0
  92. package/src/http.ts +16 -0
  93. package/src/layouts/Layout.tsx +75 -0
  94. package/src/layouts/NtosWindow.tsx +162 -0
  95. package/src/layouts/Pane.tsx +56 -0
  96. package/src/layouts/Window.tsx +227 -0
  97. package/src/renderer.ts +50 -0
  98. package/styles/base.scss +32 -0
  99. package/styles/colors.scss +92 -0
  100. package/styles/components/BlockQuote.scss +20 -0
  101. package/styles/components/Button.scss +175 -0
  102. package/styles/components/ColorBox.scss +12 -0
  103. package/styles/components/Dialog.scss +105 -0
  104. package/styles/components/Dimmer.scss +22 -0
  105. package/styles/components/Divider.scss +27 -0
  106. package/styles/components/Dropdown.scss +72 -0
  107. package/styles/components/Flex.scss +31 -0
  108. package/styles/components/Icon.scss +25 -0
  109. package/styles/components/Input.scss +68 -0
  110. package/styles/components/Knob.scss +131 -0
  111. package/styles/components/LabeledList.scss +49 -0
  112. package/styles/components/MenuBar.scss +75 -0
  113. package/styles/components/Modal.scss +14 -0
  114. package/styles/components/NoticeBox.scss +65 -0
  115. package/styles/components/NumberInput.scss +76 -0
  116. package/styles/components/ProgressBar.scss +63 -0
  117. package/styles/components/RoundGauge.scss +88 -0
  118. package/styles/components/Section.scss +143 -0
  119. package/styles/components/Slider.scss +54 -0
  120. package/styles/components/Stack.scss +59 -0
  121. package/styles/components/Table.scss +44 -0
  122. package/styles/components/Tabs.scss +144 -0
  123. package/styles/components/TextArea.scss +84 -0
  124. package/styles/components/Tooltip.scss +24 -0
  125. package/styles/functions.scss +79 -0
  126. package/styles/layouts/Layout.scss +57 -0
  127. package/styles/layouts/NtosHeader.scss +20 -0
  128. package/styles/layouts/NtosWindow.scss +26 -0
  129. package/styles/layouts/TitleBar.scss +111 -0
  130. package/styles/layouts/Window.scss +103 -0
  131. package/styles/main.scss +97 -0
  132. package/styles/reset.scss +68 -0
  133. package/styles/themes/abductor.scss +68 -0
  134. package/styles/themes/admin.scss +38 -0
  135. package/styles/themes/cardtable.scss +57 -0
  136. package/styles/themes/hackerman.scss +70 -0
  137. package/styles/themes/malfunction.scss +67 -0
  138. package/styles/themes/neutral.scss +50 -0
  139. package/styles/themes/ntOS95.scss +166 -0
  140. package/styles/themes/ntos.scss +44 -0
  141. package/styles/themes/ntos_cat.scss +148 -0
  142. package/styles/themes/ntos_darkmode.scss +44 -0
  143. package/styles/themes/ntos_lightmode.scss +67 -0
  144. package/styles/themes/ntos_spooky.scss +69 -0
  145. package/styles/themes/ntos_synth.scss +99 -0
  146. package/styles/themes/ntos_terminal.scss +112 -0
  147. package/styles/themes/paper.scss +184 -0
  148. package/styles/themes/retro.scss +72 -0
  149. package/styles/themes/spookyconsole.scss +73 -0
  150. package/styles/themes/syndicate.scss +67 -0
  151. package/styles/themes/wizard.scss +68 -0
  152. package/tsconfig.json +34 -0
package/.editorconfig ADDED
@@ -0,0 +1,10 @@
1
+ root = true
2
+
3
+ [*]
4
+ end_of_line = lf
5
+ insert_final_newline = true
6
+
7
+ [*.{js,json,yml}]
8
+ charset = utf-8
9
+ indent_style = space
10
+ indent_size = 2
package/.eslintrc.cjs ADDED
@@ -0,0 +1,78 @@
1
+ /** @type {import("eslint").Linter.Config} */
2
+ const config = {
3
+ parser: "@typescript-eslint/parser",
4
+ parserOptions: {
5
+ project: true,
6
+ },
7
+ plugins: [
8
+ "@typescript-eslint",
9
+ "eslint-plugin-simple-import-sort",
10
+ "eslint-plugin-sort-destructure-keys",
11
+ "eslint-plugin-typescript-sort-keys",
12
+ "unused-imports",
13
+ "react",
14
+ "react-hooks",
15
+ ],
16
+ extends: [
17
+ "plugin:@typescript-eslint/recommended-type-checked",
18
+ "plugin:@typescript-eslint/stylistic-type-checked",
19
+ "plugin:react/jsx-runtime",
20
+ "plugin:react-hooks/recommended",
21
+ "prettier",
22
+ ],
23
+ rules: {
24
+ "@typescript-eslint/array-type": "off",
25
+ "@typescript-eslint/consistent-type-definitions": ["error", "type"],
26
+ "@typescript-eslint/prefer-destructuring": "error",
27
+ "@typescript-eslint/consistent-type-imports": [
28
+ "warn",
29
+ {
30
+ prefer: "type-imports",
31
+ fixStyle: "inline-type-imports",
32
+ },
33
+ ],
34
+ "@typescript-eslint/no-explicit-any": "off",
35
+ "@typescript-eslint/no-floating-promises": "off",
36
+ "@typescript-eslint/no-unsafe-argument": "off",
37
+ "@typescript-eslint/no-unsafe-assignment": "off",
38
+ "@typescript-eslint/no-unsafe-enum-comparison": "off",
39
+ "@typescript-eslint/no-unsafe-member-access": "off",
40
+ "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
41
+ "@typescript-eslint/require-await": "off",
42
+ "@typescript-eslint/no-misused-promises": [
43
+ "error",
44
+ {
45
+ checksVoidReturn: { attributes: false },
46
+ },
47
+ ],
48
+ "prefer-destructuring": "off",
49
+ "react-hooks/exhaustive-deps": "off",
50
+ "react/jsx-sort-props": [
51
+ "error",
52
+ {
53
+ ignoreCase: true,
54
+ },
55
+ ],
56
+
57
+ "simple-import-sort/imports": "error",
58
+ "simple-import-sort/exports": "error",
59
+ "sort-destructure-keys/sort-destructure-keys": [
60
+ 1,
61
+ { caseSensitive: false },
62
+ ],
63
+ "typescript-sort-keys/interface": "error",
64
+ "typescript-sort-keys/string-enum": "error",
65
+ "unused-imports/no-unused-imports": "error",
66
+ "unused-imports/no-unused-vars": [
67
+ "error",
68
+ {
69
+ vars: "all",
70
+ varsIgnorePattern: "^_",
71
+ args: "after-used",
72
+ argsIgnorePattern: "^_",
73
+ },
74
+ ],
75
+ },
76
+ };
77
+
78
+ module.exports = config;
package/.gitattributes ADDED
@@ -0,0 +1,4 @@
1
+ /.yarn/** linguist-vendored
2
+ /.yarn/releases/* binary
3
+ /.yarn/plugins/**/* binary
4
+ /.pnp.* binary linguist-generated
@@ -0,0 +1 @@
1
+ singleQuote: true
@@ -0,0 +1,6 @@
1
+ {
2
+ "recommendations": [
3
+ "arcanis.vscode-zipfs",
4
+ "esbenp.prettier-vscode"
5
+ ]
6
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "editor.codeActionsOnSave": {
3
+ "source.fixAll.eslint": "explicit"
4
+ }
5
+ }
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # tgui-core
package/global.d.ts ADDED
@@ -0,0 +1,173 @@
1
+ /**
2
+ * @file
3
+ * @copyright 2021 Aleksej Komarov
4
+ * @license MIT
5
+ */
6
+
7
+ // Webpack asset modules.
8
+ // Should match extensions used in webpack config.
9
+ declare module "*.png" {
10
+ const content: string;
11
+ export default content;
12
+ }
13
+
14
+ declare module "*.jpg" {
15
+ const content: string;
16
+ export default content;
17
+ }
18
+
19
+ declare module "*.svg" {
20
+ const content: string;
21
+ export default content;
22
+ }
23
+
24
+ namespace JSX {
25
+ interface IntrinsicElements {
26
+ marquee: any;
27
+ blink: any;
28
+ }
29
+ }
30
+
31
+ type TguiMessage = {
32
+ type: string;
33
+ payload?: any;
34
+ [key: string]: any;
35
+ };
36
+
37
+ type ByondType = {
38
+ /**
39
+ * ID of the Byond window this script is running on.
40
+ * Can be used as a parameter to winget/winset.
41
+ */
42
+ windowId: string;
43
+
44
+ /**
45
+ * If `true`, unhandled errors and common mistakes result in a blue screen
46
+ * of death, which stops this window from handling incoming messages and
47
+ * closes the active instance of tgui datum if there was one.
48
+ *
49
+ * It can be defined in window.initialize() in DM, or changed in runtime
50
+ * here via this property to `true` or `false`.
51
+ *
52
+ * It is recommended that you keep this ON to detect hard to find bugs.
53
+ */
54
+ strictMode: boolean;
55
+
56
+ /**
57
+ * Makes a BYOND call.
58
+ *
59
+ * If path is empty, this will trigger a Topic call.
60
+ * You can reference a specific object by setting the "src" parameter.
61
+ *
62
+ * See: https://secure.byond.com/docs/ref/skinparams.html
63
+ */
64
+ call(path: string, params: object): void;
65
+
66
+ /**
67
+ * Makes an asynchronous BYOND call. Returns a promise.
68
+ */
69
+ callAsync(path: string, params: object): Promise<any>;
70
+
71
+ /**
72
+ * Makes a Topic call.
73
+ *
74
+ * You can reference a specific object by setting the "src" parameter.
75
+ */
76
+ topic(params: object): void;
77
+
78
+ /**
79
+ * Runs a command or a verb.
80
+ */
81
+ command(command: string): void;
82
+
83
+ /**
84
+ * Retrieves all properties of the BYOND skin element.
85
+ *
86
+ * Returns a promise with a key-value object containing all properties.
87
+ */
88
+ winget(id: string | null): Promise<object>;
89
+
90
+ /**
91
+ * Retrieves all properties of the BYOND skin element.
92
+ *
93
+ * Returns a promise with a key-value object containing all properties.
94
+ */
95
+ winget(id: string | null, propName: "*"): Promise<object>;
96
+
97
+ /**
98
+ * Retrieves an exactly one property of the BYOND skin element,
99
+ * as defined in `propName`.
100
+ *
101
+ * Returns a promise with the value of that property.
102
+ */
103
+ winget(id: string | null, propName: string): Promise<any>;
104
+
105
+ /**
106
+ * Retrieves multiple properties of the BYOND skin element,
107
+ * as defined in the `propNames` array.
108
+ *
109
+ * Returns a promise with a key-value object containing listed properties.
110
+ */
111
+ winget(id: string | null, propNames: string[]): Promise<object>;
112
+
113
+ /**
114
+ * Assigns properties to BYOND skin elements in bulk.
115
+ */
116
+ winset(props: object): void;
117
+
118
+ /**
119
+ * Assigns properties to the BYOND skin element.
120
+ */
121
+ winset(id: string | null, props: object): void;
122
+
123
+ /**
124
+ * Sets a property on the BYOND skin element to a certain value.
125
+ */
126
+ winset(id: string | null, propName: string, propValue: any): void;
127
+
128
+ /**
129
+ * Parses BYOND JSON.
130
+ *
131
+ * Uses a special encoding to preserve `Infinity` and `NaN`.
132
+ */
133
+ parseJson(text: string): any;
134
+
135
+ /**
136
+ * Sends a message to `/datum/tgui_window` which hosts this window instance.
137
+ */
138
+ sendMessage(type: string, payload?: any): void;
139
+ sendMessage(message: TguiMessage): void;
140
+
141
+ /**
142
+ * Subscribe to incoming messages that were sent from `/datum/tgui_window`.
143
+ */
144
+ subscribe(listener: (type: string, payload: any) => void): void;
145
+
146
+ /**
147
+ * Subscribe to incoming messages *of some specific type*
148
+ * that were sent from `/datum/tgui_window`.
149
+ */
150
+ subscribeTo(type: string, listener: (payload: any) => void): void;
151
+
152
+ /**
153
+ * Loads a stylesheet into the document.
154
+ */
155
+ loadCss(url: string): void;
156
+
157
+ /**
158
+ * Loads a script into the document.
159
+ */
160
+ loadJs(url: string): void;
161
+ };
162
+
163
+ /**
164
+ * Object that provides access to Byond Skin API and is available in
165
+ * any tgui application.
166
+ */
167
+ const Byond: ByondType;
168
+
169
+ interface Window {
170
+ Byond: ByondType;
171
+ __store__: Store<unknown, AnyAction>;
172
+ __augmentStack__: (store: Store) => StackAugmentor;
173
+ }
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "tgui-core",
3
+ "version": "1.0.0",
4
+ "description": "TGUI core component library",
5
+ "main": "index.js",
6
+ "keywords": [
7
+ "TGUI",
8
+ "library",
9
+ "typescript"
10
+ ],
11
+ "author": "jlsnow301",
12
+ "license": "MIT",
13
+ "dependencies": {
14
+ "@popperjs/core": "^2.11.8",
15
+ "react": "^18.3.1",
16
+ "react-dom": "^18.3.1",
17
+ "react-popper": "^2.3.0"
18
+ },
19
+ "packageManager": "pnpm@9.1.2+sha512.127dc83b9ea10c32be65d22a8efb4a65fb952e8fefbdfded39bdc3c97efc32d31b48b00420df2c1187ace28c921c902f0cb5a134a4d032b8b5295cbfa2c681e2",
20
+ "devDependencies": {
21
+ "@types/node": "^20.12.12",
22
+ "@types/react": "^18.3.3",
23
+ "@types/react-dom": "^18.3.0"
24
+ }
25
+ }
package/src/assets.ts ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @file
3
+ * @copyright 2020 Aleksej Komarov
4
+ * @license MIT
5
+ */
6
+
7
+ import { Action, AnyAction, Dispatch, Middleware } from './common/redux';
8
+
9
+ const EXCLUDED_PATTERNS = [/v4shim/i];
10
+ const loadedMappings: Record<string, string> = {};
11
+
12
+ export const resolveAsset = (name: string): string =>
13
+ loadedMappings[name] || name;
14
+
15
+ export const assetMiddleware: Middleware =
16
+ (storeApi) =>
17
+ <ActionType extends Action = AnyAction>(next: Dispatch<ActionType>) =>
18
+ (action: ActionType) => {
19
+ const { type, payload } = action as AnyAction;
20
+ if (type === 'asset/stylesheet') {
21
+ Byond.loadCss(payload);
22
+ return;
23
+ }
24
+ if (type === 'asset/mappings') {
25
+ for (const name of Object.keys(payload)) {
26
+ // Skip anything that matches excluded patterns
27
+ if (EXCLUDED_PATTERNS.some((regex) => regex.test(name))) {
28
+ continue;
29
+ }
30
+ const url = payload[name];
31
+ const ext = name.split('.').pop();
32
+ loadedMappings[name] = url;
33
+ if (ext === 'css') {
34
+ Byond.loadCss(url);
35
+ }
36
+ if (ext === 'js') {
37
+ Byond.loadJs(url);
38
+ }
39
+ }
40
+ return;
41
+ }
42
+ next(action);
43
+ };