tgui-core 3.1.4 → 3.1.5
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 +6 -0
- package/dist/common/color.js +1 -1
- package/dist/common/hotkeys.d.ts +2 -0
- package/dist/common/hotkeys.js +1 -1
- package/dist/common/ui.d.ts +1 -1
- package/dist/components/Box.d.ts +14 -14
- package/dist/components/Input.d.ts +4 -4
- package/dist/components/Input.js +1 -1
- package/dist/components/RestrictedInput.js +1 -1
- package/dist/components/TextArea.d.ts +1 -1
- package/dist/components/TextArea.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -74,3 +74,9 @@ This project uses [pnpm](https://pnpm.io/installation) for its package manager.
|
|
|
74
74
|
|
|
75
75
|
To set up the repository:
|
|
76
76
|
`pnpm install`
|
|
77
|
+
|
|
78
|
+
To test your changes using [Storybook](https://storybook.js.org/docs) run:
|
|
79
|
+
`pnpm run storybook`
|
|
80
|
+
|
|
81
|
+
To run unit tests run
|
|
82
|
+
`pnpm test`
|
package/dist/common/color.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
class r{r;g;b;a;constructor(r=0,t=0,e=0,s=1){this.r=r,this.g=t,this.b=e,this.a=s}toString(){let r=this.a;return"string"==typeof r&&(r=Number.parseFloat(this.a)),Number.isNaN(r)&&(r=1),`rgba(${0|this.r}, ${0|this.g}, ${0|this.b}, ${r})`}darken(t){let e=t/100;return new r(this.r-this.r*e,this.g-this.g*e,this.b-this.b*e,this.a)}lighten(r){return this.darken(-r)}static fromHex(t){if(7===t.length)return new r(Number.parseInt(t.slice(1,3),16),Number.parseInt(t.slice(3,5),16),Number.parseInt(t.slice(5,7),16));if(9===t.length)return new r(Number.parseInt(t.slice(1,3),16),Number.parseInt(t.slice(3,5),16),Number.parseInt(t.slice(5,7),16),Number.parseInt(t.slice(7,9),16)/256);throw Error("Invalid hex color format. Expected #RRGGBB or #RRGGBBAA.")}static lerp(t,e,s){return new r((e.r-t.r)*s+t.r,(e.g-t.g)*s+t.g,(e.b-t.b)*s+t.b,(e.a-t.a)*s+t.a)}static lookup(t,e){let s=e.length;if(s<2)throw Error("Needs at least two colors!");let i=t*(s-1);if(t<1e-4)return e[0];if(t>=.9999)return e[s-1];let n=0|i;return r.lerp(e[n],e[n+1],i%1)}}export{r as Color};
|
package/dist/common/hotkeys.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export declare function acquireHotKey(keyCode: number): void;
|
|
|
10
10
|
export declare function releaseHotKey(keyCode: number): void;
|
|
11
11
|
export declare function releaseHeldKeys(): void;
|
|
12
12
|
export declare function setupHotKeys(): void;
|
|
13
|
+
export declare function startKeyPassthrough(): void;
|
|
14
|
+
export declare function stopKeyPassthrough(): void;
|
|
13
15
|
/**
|
|
14
16
|
* Registers for any key events, such as key down or key up.
|
|
15
17
|
* This should be preferred over directly connecting to keydown/keyup
|
package/dist/common/hotkeys.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as e from"./events.js";import*as t from"./keycodes.js";let o={},n=[t.KEY_ESCAPE,t.KEY_ENTER,t.KEY_SPACE,t.KEY_TAB,t.KEY_CTRL,t.KEY_SHIFT,t.KEY_UP,t.KEY_DOWN,t.KEY_LEFT,t.KEY_RIGHT,t.KEY_F5],l={},r=[];function i(e){n.push(e)}function s(e){let t=n.indexOf(e);t>=0&&n.splice(t,1)}function
|
|
1
|
+
import*as e from"./events.js";import*as t from"./keycodes.js";let o={},n=[t.KEY_ESCAPE,t.KEY_ENTER,t.KEY_SPACE,t.KEY_TAB,t.KEY_CTRL,t.KEY_SHIFT,t.KEY_UP,t.KEY_DOWN,t.KEY_LEFT,t.KEY_RIGHT,t.KEY_F5],l={},r=[];function i(e){n.push(e)}function s(e){let t=n.indexOf(e);t>=0&&n.splice(t,1)}function a(){for(let e in l)l[e]&&(l[e]=!1,Byond.command(`${globalThis.ByondKeyUp} "${e}"`))}function d(){globalThis.ByondKeyUp||(globalThis.ByondKeyUp="KeyUp",globalThis.ByondKeyDown="KeyDown"),Byond.winget("default.*").then(e=>{let t={};for(let o in e){let n=o.split("."),l=n[1],r=n[2];l&&r&&(t[l]||(t[l]={}),t[l][r]=e[o])}let n=/\\"/g;function l(e){return e.substring(1,e.length-1).replace(n,'"')}for(let e in t){let n=t[e];o[l(n.name)]=l(n.command)}}),e.globalEvents.on("window-blur",()=>{a()}),f()}function f(){e.globalEvents.on("key",y)}function u(){e.globalEvents.off("key",y)}function y(e){for(let t of r)t(e);!function(e){var t;let r=String(e);if("Ctrl+F5"===r||"Ctrl+R"===r)return location.reload();if("Ctrl+F"===r||e.event.defaultPrevented||e.isModifierKey()||n.includes(e.code))return;let i=16===(t=e.code)?"Shift":17===t?"Ctrl":18===t?"Alt":33===t?"Northeast":34===t?"Southeast":35===t?"Southwest":36===t?"Northwest":37===t?"West":38===t?"North":39===t?"East":40===t?"South":45===t?"Insert":46===t?"Delete":t>=48&&t<=57||t>=65&&t<=90?String.fromCharCode(t):t>=96&&t<=105?`Numpad${t-96}`:t>=112&&t<=123?`F${t-111}`:188===t?",":189===t?"-":190===t?".":void 0;if(!i)return;let s=o[i];if(s)return Byond.command(s);if(e.isDown()&&!l[i]){l[i]=!0;let e=`${globalThis.ByondKeyDown} "${i}"`;return Byond.command(e)}if(e.isUp()&&l[i]){l[i]=!1;let e=`${globalThis.ByondKeyUp} "${i}"`;Byond.command(e)}}(e)}function K(e){r.push(e);let t=!1;return()=>{t||(t=!0,r.splice(r.indexOf(e),1))}}export{i as acquireHotKey,K as listenForKeyEvents,a as releaseHeldKeys,s as releaseHotKey,d as setupHotKeys,f as startKeyPassthrough,u as stopKeyPassthrough};
|
package/dist/common/ui.d.ts
CHANGED
|
@@ -112,7 +112,7 @@ export type BooleanStyleMap = {
|
|
|
112
112
|
};
|
|
113
113
|
export declare const booleanStyleMap: Record<keyof BooleanStyleMap, any>;
|
|
114
114
|
export declare function computeBoxProps(props: any): Record<string, any>;
|
|
115
|
-
export declare function computeBoxClassName(props: BoxProps): string;
|
|
115
|
+
export declare function computeBoxClassName<TElement = HTMLDivElement>(props: BoxProps<TElement>): string;
|
|
116
116
|
type StyleMap = StringStyleMap & BooleanStyleMap;
|
|
117
117
|
/** Super light implementation of tailwind-like class names. */
|
|
118
118
|
export declare function computeTwClass(input: string | undefined): StyleMap;
|
package/dist/components/Box.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { type CSSProperties, type KeyboardEventHandler, type MouseEventHandler, type ReactNode, type UIEventHandler } from 'react';
|
|
2
2
|
import type { BooleanLike } from '../common/react';
|
|
3
3
|
import { type BooleanStyleMap, type StringStyleMap } from '../common/ui';
|
|
4
|
-
type EventHandlers = {
|
|
5
|
-
onClick: MouseEventHandler<
|
|
6
|
-
onContextMenu: MouseEventHandler<
|
|
7
|
-
onDoubleClick: MouseEventHandler<
|
|
8
|
-
onKeyDown: KeyboardEventHandler<
|
|
9
|
-
onKeyUp: KeyboardEventHandler<
|
|
10
|
-
onMouseDown: MouseEventHandler<
|
|
11
|
-
onMouseLeave: MouseEventHandler<
|
|
12
|
-
onMouseMove: MouseEventHandler<
|
|
13
|
-
onMouseOver: MouseEventHandler<
|
|
14
|
-
onMouseUp: MouseEventHandler<
|
|
15
|
-
onScroll: UIEventHandler<
|
|
4
|
+
type EventHandlers<TElement = HTMLDivElement> = {
|
|
5
|
+
onClick: MouseEventHandler<TElement>;
|
|
6
|
+
onContextMenu: MouseEventHandler<TElement>;
|
|
7
|
+
onDoubleClick: MouseEventHandler<TElement>;
|
|
8
|
+
onKeyDown: KeyboardEventHandler<TElement>;
|
|
9
|
+
onKeyUp: KeyboardEventHandler<TElement>;
|
|
10
|
+
onMouseDown: MouseEventHandler<TElement>;
|
|
11
|
+
onMouseLeave: MouseEventHandler<TElement>;
|
|
12
|
+
onMouseMove: MouseEventHandler<TElement>;
|
|
13
|
+
onMouseOver: MouseEventHandler<TElement>;
|
|
14
|
+
onMouseUp: MouseEventHandler<TElement>;
|
|
15
|
+
onScroll: UIEventHandler<TElement>;
|
|
16
16
|
};
|
|
17
17
|
type InternalProps = {
|
|
18
18
|
/** The component used for the root node. */
|
|
@@ -49,7 +49,7 @@ type InternalProps = {
|
|
|
49
49
|
*/
|
|
50
50
|
tw: string;
|
|
51
51
|
};
|
|
52
|
-
export type BoxProps = Partial<InternalProps & BooleanStyleMap & StringStyleMap & EventHandlers
|
|
52
|
+
export type BoxProps<TElement = HTMLDivElement> = Partial<InternalProps & BooleanStyleMap & StringStyleMap & EventHandlers<TElement>>;
|
|
53
53
|
type DangerDoNotUse = {
|
|
54
54
|
dangerouslySetInnerHTML?: {
|
|
55
55
|
__html: any;
|
|
@@ -97,7 +97,7 @@ type DangerDoNotUse = {
|
|
|
97
97
|
*
|
|
98
98
|
* Default font size (`1rem`) is equal to `12px`.
|
|
99
99
|
*/
|
|
100
|
-
export declare function Box(props: BoxProps & DangerDoNotUse): import("react").ReactElement<{
|
|
100
|
+
export declare function Box<TElement = HTMLDivElement>(props: BoxProps<TElement> & DangerDoNotUse): import("react").ReactElement<{
|
|
101
101
|
className: string;
|
|
102
102
|
}, string | import("react").JSXElementConstructor<any>>;
|
|
103
103
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type RefObject } from 'react';
|
|
2
2
|
import type { BoxProps } from './Box';
|
|
3
|
-
export type BaseInputProps = Partial<{
|
|
3
|
+
export type BaseInputProps<TElement = HTMLInputElement> = Partial<{
|
|
4
4
|
/** Automatically focuses the input on mount */
|
|
5
5
|
autoFocus: boolean;
|
|
6
6
|
/** Automatically selects the input value on focus */
|
|
@@ -22,8 +22,8 @@ export type BaseInputProps = Partial<{
|
|
|
22
22
|
fluid: boolean;
|
|
23
23
|
/** Mark this if you want to use a monospace font */
|
|
24
24
|
monospace: boolean;
|
|
25
|
-
}> & BoxProps
|
|
26
|
-
export type TextInputProps = Partial<{
|
|
25
|
+
}> & BoxProps<TElement>;
|
|
26
|
+
export type TextInputProps<TElement = HTMLInputElement> = Partial<{
|
|
27
27
|
/** The maximum length of the input value */
|
|
28
28
|
maxLength: number;
|
|
29
29
|
/** Fires each time focus leaves the input, including if Esc or Enter are pressed */
|
|
@@ -77,7 +77,7 @@ export type TextInputProps = Partial<{
|
|
|
77
77
|
* ```
|
|
78
78
|
*/
|
|
79
79
|
value: string;
|
|
80
|
-
}> & BaseInputProps
|
|
80
|
+
}> & BaseInputProps<TElement>;
|
|
81
81
|
type Props = Partial<{
|
|
82
82
|
/** Ref of the input element */
|
|
83
83
|
ref: RefObject<HTMLInputElement | null>;
|
package/dist/components/Input.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as e from"react/jsx-runtime";import*as t from"react";import*as r from"../common/keys.js";import*as u from"../common/react.js";import*as n from"../common/timer.js";import*as o from"../common/ui.js";let a=(0,n.debounce)(e=>e(),250);function c(n){let{autoFocus:c,autoSelect:s,className:m,disabled:l,expensive:p,fluid:f,maxLength:i,monospace:d,onBlur:g,onChange:v,onEnter:x,onEscape:T,
|
|
1
|
+
import*as e from"react/jsx-runtime";import*as t from"react";import*as r from"../common/keys.js";import*as u from"../common/react.js";import*as n from"../common/timer.js";import*as o from"../common/ui.js";let a=(0,n.debounce)(e=>e(),250);function c(n){let{autoFocus:c,autoSelect:s,className:m,disabled:l,expensive:p,fluid:f,maxLength:i,monospace:d,onBlur:g,onChange:v,onEnter:x,onEscape:T,onKeyDown:j,placeholder:E,ref:b,selfClear:y,value:I,...h}=n,k=(0,t.useRef)(null),C=b??k,[B,D]=(0,t.useState)(I??"");(0,t.useEffect)(()=>{let e;return(c||s)&&(e=setTimeout(()=>{C.current?.focus(),s&&C.current?.select()},1)),()=>clearTimeout(e)},[]),(0,t.useEffect)(()=>{C.current&&document.activeElement!==C.current&&I!==B&&D(I??"")},[I]);let K=(0,o.computeBoxProps)(h),N=(0,u.classes)(["Input",l&&"Input--disabled",f&&"Input--fluid",d&&"Input--monospace",(0,o.computeBoxClassName)(h),m]);return(0,e.jsx)("input",{...K,autoComplete:"off",className:N,disabled:l,maxLength:i,onBlur:function(e){g?.(B)},onChange:function(e){let t=e.currentTarget.value;D(t),p?a(()=>v?.(t)):v?.(t)},onKeyDown:function(e){if(j?.(e),e.key===r.KEY.Enter){e.preventDefault(),x?.(e.currentTarget.value),y&&D(""),e.currentTarget.blur();return}(0,r.isEscape)(e.key)&&(e.preventDefault(),T?.(e.currentTarget.value),e.currentTarget.blur())},placeholder:E,ref:C,spellCheck:!1,type:"text",value:B})}export{c as Input};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as e from"react/jsx-runtime";import*as t from"../common/react.js";import*as r from"../common/timer.js";import*as n from"../common/ui.js";import*as u from"react";import*as o from"../common/keys.js";let s=(0,r.debounce)(e=>e(),250);function c(r){let{allowFloats:c,autoFocus:i,autoSelect:m,className:a,disabled:l,expensive:f,fluid:p,maxValue:d=1e4,minValue:v=0,monospace:y,onBlur:E,onChange:b,onEnter:I,onEscape:j,
|
|
1
|
+
import*as e from"react/jsx-runtime";import*as t from"../common/react.js";import*as r from"../common/timer.js";import*as n from"../common/ui.js";import*as u from"react";import*as o from"../common/keys.js";let s=(0,r.debounce)(e=>e(),250);function c(r){let{allowFloats:c,autoFocus:i,autoSelect:m,className:a,disabled:l,expensive:f,fluid:p,maxValue:d=1e4,minValue:v=0,monospace:y,onBlur:E,onChange:b,onEnter:I,onEscape:j,onKeyDown:x,onValidationChange:k,value:C,...D}=r,R=(0,u.useRef)(null),[B,K]=(0,u.useState)(C??v),[N,g]=(0,u.useState)(!0);function h(e){b&&(f?s(()=>b(e)):b(e))}(0,u.useEffect)(()=>{let e;return(i||m)&&(e=setTimeout(()=>{R.current?.focus(),m&&R.current?.select()},1)),()=>clearTimeout(e)},[]),(0,u.useEffect)(()=>{if(R.current){let e=R.current.validity.valid;N!==e&&(g(e),k?.(e))}},[B]),(0,u.useEffect)(()=>{R.current&&document.activeElement!==R.current&&C!==B&&K(C??v)},[C]);let S=(0,n.computeBoxProps)(D),T=(0,t.classes)(["Input","RestrictedInput",l&&"Input--disabled",p&&"Input--fluid",y&&"Input--monospace",(0,n.computeBoxClassName)(D),a,!N&&"RestrictedInput--invalid"]);return(0,e.jsx)("input",{...S,autoComplete:"off",className:T,disabled:l,max:d,min:v,onBlur:function(e){E?.(B)},onChange:function(e){let t=Number(e.target.value);K(t),h(t)},onKeyDown:function(e){if(x?.(e),e.key===o.KEY.Enter){e.preventDefault(),I?.(B),R.current?.blur();return}if((0,o.isEscape)(e.key)){e.preventDefault(),j?.(B),R.current?.blur();return}if(e.key===o.KEY.Minus){e.preventDefault();let t=-1*B;K(t),h(t);return}},ref:R,spellCheck:!1,step:c?"any":"1",type:"number",value:B})}export{c as RestrictedInput};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as e from"react/jsx-runtime";import*as t from"../common/timer.js";import*as r from"react";import*as n from"../common/keys.js";import*as u from"../common/react.js";import*as a from"../common/ui.js";let o=(0,t.debounce)(e=>e(),250);function s(t){let{autoFocus:s,autoSelect:c,className:l,disabled:m,dontUseTabForIndent:i,expensive:f,fluid:p,maxLength:g,monospace:T,onBlur:b,onChange:v,onEnter:y,onEscape:x,
|
|
1
|
+
import*as e from"react/jsx-runtime";import*as t from"../common/timer.js";import*as r from"react";import*as n from"../common/keys.js";import*as u from"../common/react.js";import*as a from"../common/ui.js";let o=(0,t.debounce)(e=>e(),250);function s(t){let{autoFocus:s,autoSelect:c,className:l,disabled:m,dontUseTabForIndent:i,expensive:f,fluid:p,maxLength:g,monospace:T,onBlur:b,onChange:v,onEnter:y,onEscape:x,onKeyDown:E,placeholder:d,ref:k,selfClear:$,userMarkup:h,value:j,...K}=t,C=(0,r.useRef)(null),D=k??C,[I,B]=(0,r.useState)(j??"");(0,r.useEffect)(()=>{(s||c)&&setTimeout(()=>{D.current?.focus(),c&&D.current?.select()},1)},[]),(0,r.useEffect)(()=>{D.current&&document.activeElement!==D.current&&j!==I&&B(j??"")},[j]);let A=(0,a.computeBoxProps)(K),N=(0,u.classes)(["Input","TextArea",p&&"Input--fluid",T&&"Input--monospace",m&&"Input--disabled",(0,a.computeBoxClassName)(K),l]);return(0,e.jsx)("textarea",{...A,autoComplete:"off",className:N,maxLength:g,onBlur:function(e){b?.(I)},onChange:function(e){let t=e.currentTarget.value;B(t),v&&(f?o(()=>v(t)):v(t))},onKeyDown:function(e){if(E?.(e),e.key===n.KEY.Enter&&!e.shiftKey){e.preventDefault(),y?.(e.currentTarget.value),$&&B(""),e.currentTarget.blur();return}if((0,n.isEscape)(e.key)){x?.(e.currentTarget.value),e.currentTarget.blur();return}if(!i&&e.key===n.KEY.Tab){e.preventDefault();let{value:t,selectionStart:r,selectionEnd:n}=e.currentTarget;B(`${t.substring(0,r)} ${t.substring(n)}`),e.currentTarget.selectionEnd=r+1,v?.(e.currentTarget.value);return}if(h&&(e.ctrlKey||e.metaKey)&&h[e.key]){e.preventDefault();let{selectionStart:t,selectionEnd:r,value:n}=e.currentTarget,u=h[e.key];B(`${n.substring(0,t)}${u}${n.substring(t,r)}${u}${n.substring(r)}`),e.currentTarget.selectionEnd=r+2*u.length,v?.(e.currentTarget.value);return}},placeholder:d,ref:D,spellCheck:!1,value:I})}export{s as TextArea};
|