tgui-core 5.7.2 → 5.9.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.
- package/dist/common/timer.d.ts +5 -0
- package/dist/common/timer.js +1 -1
- package/dist/common/ui.d.ts +1 -1
- package/dist/components/AnimatedNumber.js +1 -1
- package/dist/components/Input.d.ts +34 -25
- package/dist/components/Input.js +1 -1
- package/dist/components/RestrictedInput.d.ts +1 -50
- package/dist/components/RestrictedInput.js +1 -1
- package/dist/components/TextArea.d.ts +0 -3
- package/dist/components/TextArea.js +1 -1
- package/package.json +1 -1
package/dist/common/timer.d.ts
CHANGED
|
@@ -16,3 +16,8 @@ export declare function throttle<F extends (...args: any[]) => any>(fn: F, time:
|
|
|
16
16
|
* @param {number} time
|
|
17
17
|
*/
|
|
18
18
|
export declare function sleep(time: number): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Prevent input parent change event from being called too often
|
|
21
|
+
* @param dTime Debounce time, default is 250
|
|
22
|
+
*/
|
|
23
|
+
export declare function inputDebounce(dTime?: number): (onChange: () => void) => void;
|
package/dist/common/timer.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(t,n,
|
|
1
|
+
function e(t,n,u=!1){let o;return(...e)=>{let i=u&&!o;clearTimeout(o),o=setTimeout(function(){o=null,u||t(...e)},n),i&&t(...e)}}function t(e,t){let n,u;return function o(...i){let r=Date.now();u&&clearTimeout(u),!n||r-n>=t?(e(...i),n=r):u=setTimeout(()=>o(...i),t-(r-(n??0)))}}function n(e){return new Promise(t=>setTimeout(t,e))}function u(t=250){return e(e=>e(),t)}export{e as debounce,u as inputDebounce,n as sleep,t as throttle};
|
package/dist/common/ui.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DOMAttributes } from 'react';
|
|
2
2
|
import type { BoxProps } from '../components/Box';
|
|
3
|
-
import { type BooleanLike } from './react';
|
|
3
|
+
import { type BooleanLike } from './react.ts';
|
|
4
4
|
type UnitMapper = (value: unknown) => string | undefined;
|
|
5
5
|
/**
|
|
6
6
|
* Coverts our rem-like spacing unit into a CSS unit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as r}from"react/jsx-runtime";import{clamp as
|
|
1
|
+
import{jsx as r}from"react/jsx-runtime";import{clamp as n,isSafeNumber as t,toFixed as e}from"../common/math.js";import{useEffect as u,useMemo as l,useRef as c,useState as i}from"react";let m=1e3/60;function o(o){let{format:a,initial:f,value:p}=o,s=c(null),h=c(null),[d,g]=i(void 0!==f&&t(f)?f:t(p)?p:0),x=l(()=>{if(!t(p))return 0;let r=String(p).split(".")[1];return n(r?r.length:0,0,8)},[p]);function A(){null===s.current&&(h.current=null,s.current=requestAnimationFrame(j))}function b(){null!==s.current&&(cancelAnimationFrame(s.current),s.current=null,h.current=null)}function j(r){if(s.current=null,!t(p))return void b();let n=null===h.current?m:r-h.current;h.current=r;let e=.8333**(n/m),u=!0;g(r=>{let n=r*e+p*(1-e);return Math.abs(p-n)<Math.max(.001,.001*p)?(u=!1,p):n}),u&&A()}return u(()=>(d!==p&&A(),()=>b()),[p]),r("span",{children:t(p)?a?a(d):e(d,x):String(p)})}export{o as AnimatedNumber};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type RefObject } from 'react';
|
|
2
2
|
import type { BoxProps } from './Box';
|
|
3
|
-
|
|
3
|
+
/** Takes two optional params: The dom element type & the input type */
|
|
4
|
+
export type BaseInputProps<TElement = HTMLInputElement, TInput = string> = Partial<{
|
|
4
5
|
/** Automatically focuses the input on mount */
|
|
5
6
|
autoFocus: boolean;
|
|
6
7
|
/** Automatically selects the input value on focus */
|
|
@@ -15,31 +16,32 @@ export type BaseInputProps<TElement = HTMLInputElement> = Partial<{
|
|
|
15
16
|
* Do this if it's performing expensive ops on each input, like filtering or
|
|
16
17
|
* sending the value immediate to Byond (via act).
|
|
17
18
|
*
|
|
18
|
-
* It will only fire once every 250ms.
|
|
19
|
+
* It will only fire once every 250ms by default. Pass in a number in ms
|
|
20
|
+
* for a custom fire rate
|
|
19
21
|
*/
|
|
20
|
-
expensive: boolean;
|
|
22
|
+
expensive: boolean | number;
|
|
21
23
|
/** Fills the parent container */
|
|
22
24
|
fluid: boolean;
|
|
23
25
|
/** Mark this if you want to use a monospace font */
|
|
24
26
|
monospace: boolean;
|
|
25
|
-
/** Allows to toggle on spellcheck on inputs */
|
|
26
|
-
spellcheck: boolean;
|
|
27
|
-
}> & BoxProps<TElement>;
|
|
28
|
-
export type TextInputProps<TElement = HTMLInputElement> = Partial<{
|
|
29
|
-
/** The maximum length of the input value */
|
|
30
|
-
maxLength: number;
|
|
31
27
|
/** Fires each time focus leaves the input, including if Esc or Enter are pressed */
|
|
32
|
-
onBlur: (value:
|
|
33
|
-
/**
|
|
34
|
-
|
|
28
|
+
onBlur: (value: TInput) => void;
|
|
29
|
+
/**
|
|
30
|
+
* Fires each time the input has been changed. You do not need to enter the second param unless you're using it. All of these are valid:
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```tsx
|
|
34
|
+
* <Input onChange={(value) => console.log(value)} />
|
|
35
|
+
* <Input onChange={(value, event) => console.log(value, event)} />
|
|
36
|
+
* <Input onChange={console.log} /> // This will log the value and the event
|
|
37
|
+
* <Input onChange={setValue} /> // This will just change the value state
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
onChange: (value: TInput, event?: React.ChangeEvent<TElement>) => void;
|
|
35
41
|
/** Fires once the enter key is pressed */
|
|
36
|
-
onEnter: (value:
|
|
42
|
+
onEnter: (value: TInput, event?: React.KeyboardEvent<TElement>) => void;
|
|
37
43
|
/** Fires once the escape key is pressed */
|
|
38
|
-
onEscape: (value:
|
|
39
|
-
/** The placeholder text when everything is cleared */
|
|
40
|
-
placeholder: string;
|
|
41
|
-
/** Clears the input value on enter */
|
|
42
|
-
selfClear: boolean;
|
|
44
|
+
onEscape: (value: TInput, event?: React.KeyboardEvent<TElement>) => void;
|
|
43
45
|
/**
|
|
44
46
|
* Generally, input can handle its own state value. You might not NEED this.
|
|
45
47
|
*
|
|
@@ -80,12 +82,20 @@ export type TextInputProps<TElement = HTMLInputElement> = Partial<{
|
|
|
80
82
|
* )
|
|
81
83
|
* ```
|
|
82
84
|
*/
|
|
83
|
-
value:
|
|
84
|
-
}> &
|
|
85
|
-
type
|
|
85
|
+
value: TInput;
|
|
86
|
+
}> & BoxProps<TElement>;
|
|
87
|
+
export type TextInputProps<TElement = HTMLInputElement> = Partial<{
|
|
88
|
+
/** The maximum length of the input value */
|
|
89
|
+
maxLength: number;
|
|
90
|
+
/** The placeholder text when everything is cleared */
|
|
91
|
+
placeholder: string;
|
|
86
92
|
/** Ref of the input element */
|
|
87
|
-
ref: RefObject<
|
|
88
|
-
|
|
93
|
+
ref: RefObject<TElement | null>;
|
|
94
|
+
/** Clears the input value on enter */
|
|
95
|
+
selfClear: boolean;
|
|
96
|
+
/** Allows to toggle on spellcheck on inputs */
|
|
97
|
+
spellcheck: boolean;
|
|
98
|
+
}> & BaseInputProps<TElement>;
|
|
89
99
|
/**
|
|
90
100
|
* ## Input
|
|
91
101
|
*
|
|
@@ -94,5 +104,4 @@ type Props = Partial<{
|
|
|
94
104
|
* - [View documentation on tgui core](https://tgstation.github.io/tgui-core/?path=/docs/components-input--docs)
|
|
95
105
|
* - [View inherited Box props](https://tgstation.github.io/tgui-core/?path=/docs/components-box--docs)
|
|
96
106
|
*/
|
|
97
|
-
export declare function Input(props:
|
|
98
|
-
export {};
|
|
107
|
+
export declare function Input(props: TextInputProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/components/Input.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e}from"react/jsx-runtime";import{KEY as t,isEscape as r}from"../common/keys.js";import{classes as n}from"../common/react.js";import{
|
|
1
|
+
import{jsx as e}from"react/jsx-runtime";import{KEY as t,isEscape as r}from"../common/keys.js";import{classes as n}from"../common/react.js";import{inputDebounce as u}from"../common/timer.js";import{computeBoxClassName as o,computeBoxProps as m}from"../common/ui.js";import{useEffect as c,useRef as l,useState as a}from"react";function p(p){let{autoFocus:i,autoSelect:f,className:s,disabled:d,expensive:g,fluid:v,maxLength:T,monospace:y,onBlur:b,onChange:j,onEnter:I,onEscape:h,onKeyDown:k,placeholder:x,ref:C,selfClear:D,spellcheck:E=!1,value:w,...B}=p,K=l(null),L=C??K,[N,q]=a(w??"");c(()=>{let e;return(i||f)&&(e=setTimeout(()=>{L.current?.focus(),f&&L.current?.select()},1)),()=>clearTimeout(e)},[]),c(()=>{L.current&&document.activeElement!==L.current&&w!==N&&q(w??"")},[w]);let z=m(B),A=n(["Input",d&&"Input--disabled",v&&"Input--fluid",y&&"Input--monospace",o(B),s]);return e("input",{...z,autoComplete:"off",className:A,disabled:d,maxLength:T,onBlur:()=>b?.(N),onChange:function(e){let t=e.currentTarget.value;q(t),g?u("number"==typeof g?g:250)(()=>j?.(t,e)):j?.(t,e)},onKeyDown:function(e){if(k?.(e),e.key===t.Enter){e.preventDefault(),I?.(e.currentTarget.value,e),D&&q(""),e.currentTarget.blur();return}r(e.key)&&(e.preventDefault(),h?.(e.currentTarget.value,e),e.currentTarget.blur())},placeholder:x,ref:L,spellCheck:E,type:"text",value:N})}export{p as Input};
|
|
@@ -6,58 +6,9 @@ type Props = Partial<{
|
|
|
6
6
|
maxValue: number;
|
|
7
7
|
/** Min value. 0 by default. */
|
|
8
8
|
minValue: number;
|
|
9
|
-
/** Fires each time focus leaves the input, including if Esc or Enter are pressed */
|
|
10
|
-
onBlur: (value: number) => void;
|
|
11
|
-
/** Fires each time the input has been changed */
|
|
12
|
-
onChange: (value: number) => void;
|
|
13
|
-
/** Fires once the enter key is pressed */
|
|
14
|
-
onEnter: (value: number) => void;
|
|
15
|
-
/** Fires once the escape key is pressed */
|
|
16
|
-
onEscape: (value: number) => void;
|
|
17
9
|
/** Fires on input validation change */
|
|
18
10
|
onValidationChange: (isValid: boolean) => void;
|
|
19
|
-
|
|
20
|
-
* Generally, input can handle its own state value. You might not NEED this.
|
|
21
|
-
*
|
|
22
|
-
* Use this if you want to hold the value in the parent for external
|
|
23
|
-
* manipulation. For instance:
|
|
24
|
-
*
|
|
25
|
-
* Clearing the input
|
|
26
|
-
*
|
|
27
|
-
* ```tsx
|
|
28
|
-
* const [value, setValue] = useState(1);
|
|
29
|
-
*
|
|
30
|
-
* return (
|
|
31
|
-
* <>
|
|
32
|
-
* <Button onClick={() => act('inputVal', {inputVal: value})}>
|
|
33
|
-
* Submit
|
|
34
|
-
* </Button>
|
|
35
|
-
* <RestrictedInput
|
|
36
|
-
* value={value}
|
|
37
|
-
* onChange={setValue} />
|
|
38
|
-
* <Button onClick={() => setValue(1)}>
|
|
39
|
-
* Clear
|
|
40
|
-
* </Button>
|
|
41
|
-
* </>
|
|
42
|
-
* )
|
|
43
|
-
* ```
|
|
44
|
-
*
|
|
45
|
-
* Updating the value from the backend
|
|
46
|
-
*
|
|
47
|
-
* ```tsx
|
|
48
|
-
* const { data } = useBackend<Data>();
|
|
49
|
-
* const { valveSetting } = data;
|
|
50
|
-
*
|
|
51
|
-
* return (
|
|
52
|
-
* <RestrictedInput
|
|
53
|
-
* value={valveSetting}
|
|
54
|
-
* onEnter={(value) => act('submit', { valveSetting: value })}
|
|
55
|
-
* />
|
|
56
|
-
* )
|
|
57
|
-
* ```
|
|
58
|
-
*/
|
|
59
|
-
value: number;
|
|
60
|
-
}> & BaseInputProps;
|
|
11
|
+
}> & BaseInputProps<HTMLInputElement, number>;
|
|
61
12
|
/**
|
|
62
13
|
* ## RestrictedInput
|
|
63
14
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e}from"react/jsx-runtime";import{KEY as t,isEscape as r}from"../common/keys.js";import{classes as n}from"../common/react.js";import{
|
|
1
|
+
import{jsx as e}from"react/jsx-runtime";import{KEY as t,isEscape as r}from"../common/keys.js";import{classes as n}from"../common/react.js";import{inputDebounce as u}from"../common/timer.js";import{computeBoxClassName as o,computeBoxProps as i}from"../common/ui.js";import{useEffect as m,useRef as c,useState as l}from"react";function f(f){let{allowFloats:p,autoFocus:a,autoSelect:s,className:d,disabled:v,expensive:y,fluid:b,maxValue:I=1e4,minValue:j=0,monospace:k,onBlur:D,onChange:x,onEnter:C,onEscape:R,onKeyDown:g,onValidationChange:h,value:E,...N}=f,T=c(null),[w,B]=l(E??j),[K,M]=l(!0);function q(e,t){x&&(y?u("number"==typeof y?y:250)(()=>x?.(e,t)):x(e,t))}m(()=>{let e;return(a||s)&&(e=setTimeout(()=>{T.current?.focus(),s&&T.current?.select()},1)),()=>clearTimeout(e)},[]),m(()=>{if(T.current){let e=T.current.validity.valid;K!==e&&(M(e),h?.(e))}},[w]),m(()=>{T.current&&document.activeElement!==T.current&&E!==w&&B(E??j)},[E]);let z=i(N),A=n(["Input","RestrictedInput",v&&"Input--disabled",b&&"Input--fluid",k&&"Input--monospace",o(N),d,!K&&"RestrictedInput--invalid"]);return e("input",{...z,autoComplete:"off",className:A,disabled:v,max:I,min:j,onBlur:function(e){D?.(w)},onChange:function(e){let t=Number(e.target.value);B(t),q(t,e)},onKeyDown:function(e){if(g?.(e),e.key===t.Enter){e.preventDefault(),C?.(w,e),T.current?.blur();return}if(r(e.key)){e.preventDefault(),R?.(w,e),T.current?.blur();return}if(e.key===t.Minus){e.preventDefault();let t=-1*w;B(t),q(t,e);return}},ref:T,spellCheck:!1,step:p?"any":"1",type:"number",value:w})}export{f as RestrictedInput};
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import type { RefObject } from 'react';
|
|
2
1
|
import type { TextInputProps } from './Input';
|
|
3
2
|
type Props = Partial<{
|
|
4
3
|
/** Don't use tab for indent */
|
|
5
4
|
dontUseTabForIndent: boolean;
|
|
6
|
-
/** Ref to the textarea element. */
|
|
7
|
-
ref: RefObject<HTMLTextAreaElement | null>;
|
|
8
5
|
/**
|
|
9
6
|
* Provides a Record with key: markupChar entries which can be used for
|
|
10
7
|
* ctrl + key combinations to surround a selected text with the markup
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e}from"react/jsx-runtime";import{KEY as
|
|
1
|
+
import{jsx as e}from"react/jsx-runtime";import{KEY as r,isEscape as t}from"../common/keys.js";import{classes as n}from"../common/react.js";import{computeBoxClassName as u,computeBoxProps as o}from"../common/ui.js";import{inputDebounce as a}from"../common/timer.js";import{useEffect as c,useRef as l,useState as m}from"react";function i(i){let{autoFocus:s,autoSelect:f,className:g,disabled:p,dontUseTabForIndent:T,expensive:y,fluid:b,maxLength:v,monospace:d,onBlur:k,onChange:$,onEnter:h,onEscape:x,onKeyDown:j,placeholder:D,ref:E,selfClear:I,spellcheck:K=!1,userMarkup:C,value:A,...w}=i,B=l(null),L=E??B,[N,q]=m(A??"");c(()=>{(s||f)&&setTimeout(()=>{L.current?.focus(),f&&L.current?.select()},1)},[]),c(()=>{L.current&&document.activeElement!==L.current&&A!==N&&q(A??"")},[A]);let z=o(w),F=n(["Input","TextArea",b&&"Input--fluid",d&&"Input--monospace",p&&"Input--disabled",u(w),g]);return e("textarea",{...z,autoComplete:"off",className:F,maxLength:v,onBlur:function(e){k?.(N)},onChange:function(e){let r=e.currentTarget.value;q(r),$&&(y?a("number"==typeof y?y:250)(()=>$?.(r,e)):$(r,e))},onKeyDown:function(e){if(j?.(e),e.key===r.Enter&&!e.shiftKey){e.preventDefault(),h?.(e.currentTarget.value,e),I&&q(""),e.currentTarget.blur();return}if(t(e.key)){x?.(e.currentTarget.value,e),e.currentTarget.blur();return}if(!T&&e.key===r.Tab){e.preventDefault();let{value:r,selectionStart:t,selectionEnd:n}=e.currentTarget;q(`${r.substring(0,t)} ${r.substring(n)}`),e.currentTarget.selectionEnd=t+1,$?.(e.currentTarget.value,e);return}if(C&&(e.ctrlKey||e.metaKey)&&C[e.key]){e.preventDefault();let{selectionStart:r,selectionEnd:t,value:n}=e.currentTarget,u=C[e.key];q(`${n.substring(0,r)}${u}${n.substring(r,t)}${u}${n.substring(t)}`),e.currentTarget.selectionEnd=t+2*u.length,$?.(e.currentTarget.value,e);return}},placeholder:D,ref:L,spellCheck:K,value:N})}export{i as TextArea};
|
package/package.json
CHANGED