tgui-core 1.4.0 → 1.5.1

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.
package/README.md CHANGED
@@ -11,11 +11,11 @@ You can view the code on [GitHub](https://github.com/tgstation/tgui-core).
11
11
  (assuming you have a tgui folder, navigate to the specific package)
12
12
 
13
13
  ```sh
14
- cd tgui/packages/tgui
14
+ cd tgui/packages/{package name}
15
15
  yarn add tgui-core
16
16
  ```
17
17
 
18
- ## Usage
18
+ ## Using the components
19
19
 
20
20
  Now, you can use them like normal TGUI components.
21
21
 
@@ -32,6 +32,28 @@ import { Button } from "tgui-core/components";
32
32
  import { Box } from "../components";
33
33
  ```
34
34
 
35
+ ## Using the styles
36
+
37
+ You have two options for importing styles:
38
+
39
+ ### 1. Importing All Styles
40
+
41
+ To import all styles at once, add the following line to your main Sass file:
42
+
43
+ ```scss
44
+ @use "pkg:tgui-styles";
45
+ ```
46
+
47
+ ### 2. Importing Individual Styles
48
+
49
+ To import individual styles, add any of the exported styles to your main Sass file:
50
+
51
+ ```scss
52
+ @use "pkg:tgui-styles/components/Button";
53
+ @use "pkg:tgui-styles/components/Dialog";
54
+ @use "pkg:tgui-styles/components/NoticeBox";
55
+ ```
56
+
35
57
  ## License
36
58
 
37
59
  MIT
@@ -18,6 +18,7 @@ type Props = {
18
18
  initial?: number;
19
19
  }>;
20
20
  /**
21
+ * ## AnimatedNumber
21
22
  * An animated number label. Shows a number, formatted with an optionally
22
23
  * provided function, and animates it towards its target value.
23
24
  */
@@ -1,2 +1,7 @@
1
1
  import { BoxProps } from './Box';
2
+ /**
3
+ * ## BlockQuote
4
+ * Just a block quote, just like this example in markdown:
5
+ * > Here's an example of a block quote.
6
+ */
2
7
  export declare function BlockQuote(props: BoxProps): import("react/jsx-runtime").JSX.Element;
@@ -56,8 +56,7 @@ type DangerDoNotUse = {
56
56
  };
57
57
  };
58
58
  /**
59
- * # Box
60
- *
59
+ * ## Box
61
60
  * The Box component serves as a wrapper component for most of the CSS utility
62
61
  * needs. It creates a new DOM element, a `<div>` by default that can be changed
63
62
  * with the `as` property. Let's say you want to use a `<span>` instead:
@@ -54,7 +54,10 @@ type Props = Partial<{
54
54
  /** Align content vertically using flex. Use lineHeight if the height is static. */
55
55
  verticalAlignContent: string;
56
56
  }> & EllipsisUnion & BoxProps;
57
- /** Clickable button. Comes with variants. Read more in the documentation. */
57
+ /**
58
+ * ## Button
59
+ * Buttons allow users to take actions, and make choices, with a single click.
60
+ */
58
61
  export declare function Button(props: Props): import("react/jsx-runtime").JSX.Element;
59
62
  export declare namespace Button {
60
63
  var Checkbox: typeof ButtonCheckbox;
@@ -65,14 +68,20 @@ export declare namespace Button {
65
68
  type CheckProps = Partial<{
66
69
  checked: BooleanLike;
67
70
  }> & Props;
68
- /** Visually toggles between checked and unchecked states. */
71
+ /**
72
+ * ## Button.Checkbox
73
+ * A ghetto checkbox, made entirely using existing Button API.
74
+ */
69
75
  export declare function ButtonCheckbox(props: CheckProps): import("react/jsx-runtime").JSX.Element;
70
76
  type ConfirmProps = Partial<{
71
77
  confirmColor: string;
72
78
  confirmContent: ReactNode;
73
79
  confirmIcon: string;
74
80
  }> & Props;
75
- /** Requires user confirmation before triggering its action. */
81
+ /**
82
+ * ## Button.Confirm
83
+ * A button with an extra confirmation step, using native button component.
84
+ */
76
85
  declare function ButtonConfirm(props: ConfirmProps): import("react/jsx-runtime").JSX.Element;
77
86
  type InputProps = Partial<{
78
87
  currentValue: string;
@@ -82,13 +91,21 @@ type InputProps = Partial<{
82
91
  onCommit: (e: any, value: string) => void;
83
92
  placeholder: string;
84
93
  }> & Props;
85
- /** Accepts and handles user input. */
94
+ /**
95
+ * ## Button.Input
96
+ * A button that turns into an input box after the first click.
97
+ *
98
+ * Turns back into a button after the user hits enter, defocuses, or hits escape. Enter and defocus commit, while escape cancels.
99
+ */
86
100
  declare function ButtonInput(props: InputProps): import("react/jsx-runtime").JSX.Element;
87
101
  type FileProps = {
88
102
  accept: string;
89
103
  multiple?: boolean;
90
104
  onSelectFiles: (files: string | string[]) => void;
91
105
  } & Props;
92
- /** Accepts file input */
106
+ /**
107
+ * ## Button.File
108
+ * Accepts file input, based on the native element.
109
+ */
93
110
  declare function ButtonFile(props: FileProps): import("react/jsx-runtime").JSX.Element;
94
111
  export {};
@@ -0,0 +1,50 @@
1
+ import { BoxProps } from './Box';
2
+ type SampleByondParams = Partial<{
3
+ /** Can be auto-generated. */
4
+ id: string;
5
+ /** Defaults to the current window */
6
+ parent: string;
7
+ /** The type of control. Read-only. */
8
+ type: string;
9
+ /** Text shown in label/button/input. For input controls this setting is only available at runtime. */
10
+ text: string;
11
+ }>;
12
+ type Props = Partial<{
13
+ /** An object with parameters, which are directly passed to
14
+ * the `winset` proc call.
15
+ *
16
+ * You can find a full reference of these parameters
17
+ * in [BYOND controls and parameters guide](https://secure.byond.com/docs/ref/skinparams.html). */
18
+ params: SampleByondParams & Record<string, any>;
19
+ }> & BoxProps;
20
+ /**
21
+ * ## ByondUi
22
+ * Displays a BYOND UI element on top of the browser, and leverages browser's
23
+ * layout engine to position it just like any other HTML element. It is
24
+ * especially useful if you want to display a secondary game map in your
25
+ * interface.
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * <ByondUi
30
+ * params={{
31
+ * id: 'test_button', // optional, can be auto-generated
32
+ * parent: 'some_container', // optional, defaults to the current window
33
+ * type: 'button',
34
+ * text: 'Hello, world!',
35
+ * }} />
36
+ * ```
37
+ *
38
+ * @example
39
+ * ```tsx
40
+ * <ByondUi
41
+ * params={{
42
+ * id: 'test_map',
43
+ * type: 'map',
44
+ * }} />
45
+ * ```
46
+ *
47
+ * It supports a full set of `Box` properties for layout purposes.
48
+ */
49
+ export declare function ByondUi(props: Props): import("react/jsx-runtime").JSX.Element;
50
+ export {};
@@ -1,19 +1,18 @@
1
- import { jsx as s } from "react/jsx-runtime";
2
- import { Component as a, createRef as c } from "react";
3
- import { shallowDiffers as r } from "../common/react.js";
1
+ import { jsx as l } from "react/jsx-runtime";
2
+ import { useRef as f, useEffect as p } from "react";
4
3
  import { debounce as m } from "../common/timer.js";
5
- import { computeBoxProps as l } from "../common/ui.js";
4
+ import { computeBoxProps as w } from "../common/ui.js";
6
5
  const o = [];
7
- function h(t) {
8
- const n = o.length;
6
+ function a(t) {
7
+ const e = o.length;
9
8
  o.push(null);
10
- const e = t || `byondui_${n}`;
9
+ const n = t || `byondui_${e}`;
11
10
  return {
12
11
  render: (i) => {
13
- o[n] = e, Byond.winset(e, i);
12
+ o[e] = n, Byond.winset(n, i);
14
13
  },
15
14
  unmount: () => {
16
- o[n] = null, Byond.winset(e, {
15
+ o[e] = null, Byond.winset(n, {
17
16
  parent: ""
18
17
  });
19
18
  }
@@ -21,53 +20,42 @@ function h(t) {
21
20
  }
22
21
  window.addEventListener("beforeunload", () => {
23
22
  for (let t = 0; t < o.length; t++) {
24
- const n = o[t];
25
- typeof n == "string" && (o[t] = null, Byond.winset(n, {
23
+ const e = o[t];
24
+ typeof e == "string" && (o[t] = null, Byond.winset(e, {
26
25
  parent: ""
27
26
  }));
28
27
  }
29
28
  });
30
- function u(t) {
31
- const n = window.devicePixelRatio ?? 1, e = t.getBoundingClientRect();
29
+ function x(t) {
30
+ const e = window.devicePixelRatio ?? 1, n = t.getBoundingClientRect();
32
31
  return {
33
- pos: [e.left * n, e.top * n],
32
+ pos: [n.left * e, n.top * e],
34
33
  size: [
35
- (e.right - e.left) * n,
36
- (e.bottom - e.top) * n
34
+ (n.right - n.left) * e,
35
+ (n.bottom - n.top) * e
37
36
  ]
38
37
  };
39
38
  }
40
- class U extends a {
41
- constructor(n) {
42
- var e;
43
- super(n), this.containerRef = c(), this.byondUiElement = h((e = n.params) == null ? void 0 : e.id), this.handleResize = m(() => {
44
- this.forceUpdate();
45
- }, 100);
46
- }
47
- shouldComponentUpdate(n) {
48
- const { params: e = {}, ...i } = this.props, { params: d = {}, ...p } = n;
49
- return r(e, d) || r(i, p);
50
- }
51
- componentDidMount() {
52
- window.addEventListener("resize", this.handleResize), this.componentDidUpdate(), this.handleResize();
53
- }
54
- componentDidUpdate() {
55
- const { params: n = {} } = this.props, e = u(this.containerRef.current);
56
- this.byondUiElement.render({
39
+ function h(t) {
40
+ const { params: e, ...n } = t, i = f(null), d = f(a(e == null ? void 0 : e.id));
41
+ function s() {
42
+ const c = i.current;
43
+ if (!c) return;
44
+ const r = x(c);
45
+ d.current.render({
57
46
  parent: Byond.windowId,
58
- ...n,
59
- pos: `${e.pos[0]},${e.pos[1]}`,
60
- size: `${e.size[0]}x${e.size[1]}`
47
+ ...e,
48
+ pos: `${r.pos[0]},${r.pos[1]}`,
49
+ size: `${r.size[0]}x${r.size[1]}`
61
50
  });
62
51
  }
63
- componentWillUnmount() {
64
- window.removeEventListener("resize", this.handleResize), this.byondUiElement.unmount();
65
- }
66
- render() {
67
- const { params: n, ...e } = this.props;
68
- return /* @__PURE__ */ s("div", { ref: this.containerRef, ...l(e), children: /* @__PURE__ */ s("div", { style: { minHeight: "22px" } }) });
69
- }
52
+ const u = m(() => {
53
+ s();
54
+ }, 100);
55
+ return p(() => (window.addEventListener("resize", u), s(), () => {
56
+ window.removeEventListener("resize", u), d.current.unmount();
57
+ }), []), /* @__PURE__ */ l("div", { ref: i, ...w(n), children: /* @__PURE__ */ l("div", { style: { minHeight: "22px" } }) });
70
58
  }
71
59
  export {
72
- U as ByondUi
60
+ h as ByondUi
73
61
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tgui-core",
3
- "version": "1.4.0",
3
+ "version": "1.5.1",
4
4
  "description": "TGUI core component library",
5
5
  "keywords": ["TGUI", "library", "typescript"],
6
6
  "files": ["dist"],
@@ -12,6 +12,13 @@
12
12
  "./*": {
13
13
  "import": "./dist/common/*.js",
14
14
  "require": "./dist/common/*.cjs"
15
+ },
16
+ "./styles": {
17
+ "default": "./lib/styles/main.scss",
18
+ "sass": "./lib/styles/main.scss"
19
+ },
20
+ "./styles/components/*": {
21
+ "sass": "./lib/styles/components/*"
15
22
  }
16
23
  },
17
24
  "repository": {
@@ -31,16 +38,16 @@
31
38
  "type": "module",
32
39
  "devDependencies": {
33
40
  "@biomejs/biome": "1.9.4",
34
- "@chromatic-com/storybook": "3.2.2",
41
+ "@chromatic-com/storybook": "^3.2.3",
35
42
  "@popperjs/core": "^2.11.8",
36
43
  "@storybook/addon-console": "^3.0.0",
37
- "@storybook/addon-essentials": "8.4.4",
38
- "@storybook/addon-interactions": "8.4.4",
39
- "@storybook/addon-onboarding": "8.4.4",
40
- "@storybook/blocks": "8.4.4",
41
- "@storybook/react": "8.4.4",
42
- "@storybook/react-vite": "8.4.4",
43
- "@storybook/test": "8.4.4",
44
+ "@storybook/addon-essentials": "^8.4.7",
45
+ "@storybook/addon-interactions": "^8.4.7",
46
+ "@storybook/addon-onboarding": "^8.4.7",
47
+ "@storybook/blocks": "^8.4.7",
48
+ "@storybook/react": "^8.4.7",
49
+ "@storybook/react-vite": "^8.4.7",
50
+ "@storybook/test": "^8.4.7",
44
51
  "@types/node": "^22.9.0",
45
52
  "@types/react": "^18.3.3",
46
53
  "@types/react-dom": "^18.3.0",
@@ -51,9 +58,8 @@
51
58
  "prettier": "^3.3.3",
52
59
  "react-popper": "^2.3.0",
53
60
  "sass": "^1.81.0",
54
- "storybook": "8.4.4",
61
+ "storybook": "^8.4.7",
55
62
  "storybook-addon-sass-postcss": "^0.3.2",
56
- "tgui-styles": "^0.0.8",
57
63
  "typescript": "^5.6.3",
58
64
  "vite": "^5.4.11",
59
65
  "vite-plugin-dts": "^4.3.0"
@@ -62,5 +68,5 @@
62
68
  "react": "^18.2.0",
63
69
  "react-dom": "^18.2.0"
64
70
  },
65
- "packageManager": "pnpm@9.13.0+sha512.beb9e2a803db336c10c9af682b58ad7181ca0fbd0d4119f2b33d5f2582e96d6c0d93c85b23869295b765170fbdaa92890c0da6ada457415039769edf3c959efe"
71
+ "packageManager": "pnpm@9.15.1+sha512.1acb565e6193efbebda772702950469150cf12bcc764262e7587e71d19dc98a423dff9536e57ea44c49bdf790ff694e83c27be5faa23d67e0c033b583be4bfcf"
66
72
  }