tgui-core 5.8.0 → 5.10.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.
@@ -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;
@@ -1 +1 @@
1
- function e(t,n,o=!1){let u;return(...e)=>{let i=o&&!u;clearTimeout(u),u=setTimeout(function(){u=null,o||t(...e)},n),i&&t(...e)}}function t(e,t){let n,o;return function u(...i){let r=Date.now();o&&clearTimeout(o),!n||r-n>=t?(e(...i),n=r):o=setTimeout(()=>u(...i),t-(r-(n??0)))}}function n(e){return new Promise(t=>setTimeout(t,e))}export{e as debounce,n as sleep,t as throttle};
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};
@@ -118,6 +118,6 @@ type StyleMap = StringStyleMap & BooleanStyleMap;
118
118
  /** Super light implementation of tailwind-like class names. */
119
119
  export declare function computeTwClass(input: string | undefined): StyleMap;
120
120
  /** Short list of accepted DOM event handlers */
121
- export declare const eventHandlers: ["onClick", "onContextMenu", "onDoubleClick", "onKeyDown", "onKeyUp", "onMouseDown", "onMouseLeave", "onMouseMove", "onMouseOver", "onMouseUp", "onScroll", "onWheel", "onDrag", "onDragEnd", "onDragEnter", "onDragExit", "onDragLeave", "onDragOver", "onDragStart", "onDrop"];
121
+ export declare const eventHandlers: ["onClick", "onAuxClick", "onContextMenu", "onDoubleClick", "onKeyDown", "onKeyUp", "onMouseDown", "onMouseEnter", "onMouseLeave", "onMouseMove", "onMouseOver", "onMouseUp", "onScroll", "onWheel", "onDrag", "onDragEnd", "onDragEnter", "onDragExit", "onDragLeave", "onDragOver", "onDragStart", "onDrop"];
122
122
  export type EventHandlers<TElement = HTMLDivElement> = Pick<DOMAttributes<TElement>, (typeof eventHandlers)[number]>;
123
123
  export {};
package/dist/common/ui.js CHANGED
@@ -1 +1 @@
1
- import{CSS_COLORS as t}from"./constants.js";import{classes as o}from"./react.js";let e=t=>"string"==typeof t?t.endsWith("px")?`${Number.parseFloat(t)/12}rem`:t:"number"==typeof t?`${t}rem`:void 0,n=t=>"string"==typeof t?e(t):"number"==typeof t?e(.5*t):void 0;function i(o){return"string"==typeof o&&t.includes(o)}let r=t=>(o,e)=>{("number"==typeof e||"string"==typeof e)&&(o[t]=e)},l=(t,o)=>(e,n)=>{("number"==typeof n||"string"==typeof n)&&(e[t]=o(n))},p=(t,o)=>(e,n)=>{n&&(e[t]=o)},a=(t,o,e)=>(n,i)=>{if("number"==typeof i||"string"==typeof i)for(let r=0;r<e.length;r++)n[t+e[r]]=o(i)},g=t=>(o,e)=>{i(e)||(o[t]=e)},f={align:r("textAlign"),backgroundColor:g("backgroundColor"),bottom:l("bottom",e),color:g("color"),fontFamily:r("fontFamily"),fontSize:l("fontSize",e),fontWeight:r("fontWeight"),g:l("gap",n),gc:l("columnGap",n),gr:l("rowGap",n),height:l("height",e),left:l("left",e),lineHeight:(t,o)=>{"number"==typeof o?t.lineHeight=o:"string"==typeof o&&(t.lineHeight=e(o))},m:a("margin",n,["Top","Bottom","Left","Right"]),maxHeight:l("maxHeight",e),maxWidth:l("maxWidth",e),mb:l("marginBottom",n),minHeight:l("minHeight",e),minWidth:l("minWidth",e),ml:l("marginLeft",n),mr:l("marginRight",n),mt:l("marginTop",n),mx:a("margin",n,["Left","Right"]),my:a("margin",n,["Top","Bottom"]),opacity:r("opacity"),overflow:r("overflow"),overflowX:r("overflowX"),overflowY:r("overflowY"),p:a("padding",n,["Top","Bottom","Left","Right"]),pb:l("paddingBottom",n),pl:l("paddingLeft",n),position:r("position"),pr:l("paddingRight",n),pt:l("paddingTop",n),px:a("padding",n,["Left","Right"]),py:a("padding",n,["Top","Bottom"]),right:l("right",e),textAlign:r("textAlign"),textColor:g("color"),top:l("top",e),verticalAlign:r("verticalAlign"),width:l("width",e)},m={bold:p("fontWeight","bold"),fillPositionedParent:(t,o)=>{o&&(t.position="absolute",t.top=0,t.bottom=0,t.left=0,t.right=0)},inline:p("display","inline-block"),italic:p("fontStyle","italic"),nowrap:p("whiteSpace","nowrap"),preserveWhitespace:p("whiteSpace","pre-wrap")};function s(t){let o={},e={};for(let n in t){if("style"===n)continue;let i=t[n],r=f[n]||m[n];r?r(e,i):o[n]=i}return o.style={...e,...t.style},o}function u(t){let e=t.textColor||t.color,{backgroundColor:n}=t;return o([i(e)&&`color-${e}`,i(n)&&`color-bg-${n}`])}function c(t){let o={};if(!t)return o;for(let e of t.split(" ")){let[t,n]=e.split("-");if(t)if(t in f){if(""===n)continue;let e=Number(n);!Number.isNaN(e)&&Number.isFinite(e)?o[t]=e:o[t]=n}else t in m?o[t]=!0:console.warn(`Unknown prop ${t}`)}return o}let h=["onClick","onContextMenu","onDoubleClick","onKeyDown","onKeyUp","onMouseDown","onMouseLeave","onMouseMove","onMouseOver","onMouseUp","onScroll","onWheel","onDrag","onDragEnd","onDragEnter","onDragExit","onDragLeave","onDragOver","onDragStart","onDrop"];export{m as booleanStyleMap,u as computeBoxClassName,s as computeBoxProps,c as computeTwClass,h as eventHandlers,n as halfUnit,f as stringStyleMap,e as unit};
1
+ import{CSS_COLORS as t}from"./constants.js";import{classes as o}from"./react.js";let e=t=>"string"==typeof t?t.endsWith("px")?`${Number.parseFloat(t)/12}rem`:t:"number"==typeof t?`${t}rem`:void 0,n=t=>"string"==typeof t?e(t):"number"==typeof t?e(.5*t):void 0;function i(o){return"string"==typeof o&&t.includes(o)}let r=t=>(o,e)=>{("number"==typeof e||"string"==typeof e)&&(o[t]=e)},l=(t,o)=>(e,n)=>{("number"==typeof n||"string"==typeof n)&&(e[t]=o(n))},p=(t,o)=>(e,n)=>{n&&(e[t]=o)},a=(t,o,e)=>(n,i)=>{if("number"==typeof i||"string"==typeof i)for(let r=0;r<e.length;r++)n[t+e[r]]=o(i)},g=t=>(o,e)=>{i(e)||(o[t]=e)},f={align:r("textAlign"),backgroundColor:g("backgroundColor"),bottom:l("bottom",e),color:g("color"),fontFamily:r("fontFamily"),fontSize:l("fontSize",e),fontWeight:r("fontWeight"),g:l("gap",n),gc:l("columnGap",n),gr:l("rowGap",n),height:l("height",e),left:l("left",e),lineHeight:(t,o)=>{"number"==typeof o?t.lineHeight=o:"string"==typeof o&&(t.lineHeight=e(o))},m:a("margin",n,["Top","Bottom","Left","Right"]),maxHeight:l("maxHeight",e),maxWidth:l("maxWidth",e),mb:l("marginBottom",n),minHeight:l("minHeight",e),minWidth:l("minWidth",e),ml:l("marginLeft",n),mr:l("marginRight",n),mt:l("marginTop",n),mx:a("margin",n,["Left","Right"]),my:a("margin",n,["Top","Bottom"]),opacity:r("opacity"),overflow:r("overflow"),overflowX:r("overflowX"),overflowY:r("overflowY"),p:a("padding",n,["Top","Bottom","Left","Right"]),pb:l("paddingBottom",n),pl:l("paddingLeft",n),position:r("position"),pr:l("paddingRight",n),pt:l("paddingTop",n),px:a("padding",n,["Left","Right"]),py:a("padding",n,["Top","Bottom"]),right:l("right",e),textAlign:r("textAlign"),textColor:g("color"),top:l("top",e),verticalAlign:r("verticalAlign"),width:l("width",e)},m={bold:p("fontWeight","bold"),fillPositionedParent:(t,o)=>{o&&(t.position="absolute",t.top=0,t.bottom=0,t.left=0,t.right=0)},inline:p("display","inline-block"),italic:p("fontStyle","italic"),nowrap:p("whiteSpace","nowrap"),preserveWhitespace:p("whiteSpace","pre-wrap")};function s(t){let o={},e={};for(let n in t){if("style"===n)continue;let i=t[n],r=f[n]||m[n];r?r(e,i):o[n]=i}return o.style={...e,...t.style},o}function u(t){let e=t.textColor||t.color,{backgroundColor:n}=t;return o([i(e)&&`color-${e}`,i(n)&&`color-bg-${n}`])}function c(t){let o={};if(!t)return o;for(let e of t.split(" ")){let[t,n]=e.split("-");if(t)if(t in f){if(""===n)continue;let e=Number(n);!Number.isNaN(e)&&Number.isFinite(e)?o[t]=e:o[t]=n}else t in m?o[t]=!0:console.warn(`Unknown prop ${t}`)}return o}let h=["onClick","onAuxClick","onContextMenu","onDoubleClick","onKeyDown","onKeyUp","onMouseDown","onMouseEnter","onMouseLeave","onMouseMove","onMouseOver","onMouseUp","onScroll","onWheel","onDrag","onDragEnd","onDragEnter","onDragExit","onDragLeave","onDragOver","onDragStart","onDrop"];export{m as booleanStyleMap,u as computeBoxClassName,s as computeBoxProps,c as computeTwClass,h as eventHandlers,n as halfUnit,f as stringStyleMap,e as unit};
@@ -1 +1 @@
1
- import{jsx as r}from"react/jsx-runtime";import{clamp as t,isSafeNumber as n,toFixed as e}from"../common/math.js";import{useEffect as l,useRef as u,useState as c}from"react";let i=1e3/60;function m(m){let o,{format:a,initial:f,value:p}=m,s=u(null),[h,d]=c(void 0!==f&&n(f)?f:n(p)?p:0);l(()=>(h!==p&&null===s.current&&(s.current=setInterval(v,i)),()=>g()),[p]),l(()=>()=>g(),[]);function g(){null!==s.current&&(clearInterval(s.current),s.current=null)}function v(){n(p)?d(r=>{let t=.8333*r+.16669999999999996*p;return Math.abs(p-t)<Math.max(.001,.001*p)?(g(),p):t}):g()}return r("span",{children:n(p)?a?a(h):e(h,t((o=String(p).split(".")[1])?o.length:0,0,8)):String(p)})}export{m as AnimatedNumber};
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};
@@ -21,6 +21,8 @@ type Props = {
21
21
  } & Partial<{
22
22
  /** Animates the value if it was changed externally. */
23
23
  animated: boolean;
24
+ /** Disables the control. */
25
+ disabled: boolean;
24
26
  /** The matrix to use for the drag. */
25
27
  dragMatrix: [number, number];
26
28
  /** onChange also fires when you drag the input. */
@@ -1 +1 @@
1
- import{Fragment as e,jsx as r,jsxs as t}from"react/jsx-runtime";import{KEY as n,isEscape as u}from"../common/keys.js";import{clamp as o}from"../common/math.js";import{useEffect as l,useRef as c,useState as i}from"react";import{AnimatedNumber as a}from"./AnimatedNumber.js";function s(e,r){return e.screenX*r[0]+e.screenY*r[1]}function m(m){let{animated:f,children:v,dragMatrix:p=[1,0],tickWhileDragging:d,format:h,maxValue:y=1/0,minValue:g=-1/0,onChange:E,step:b=1,stepPixelSize:N,unclamped:w,unit:T,updateRate:j=400,fontSize:x,height:L,lineHeight:S}=m,[k,z]=i(m.value),[D,I]=i(!1),F=c(!1),M=c(m.value),O=c(0),$=c(0),_=c(null),A=c(null),B=c(null),C=c(null);function H(e){let r=$.current;if(null===r)throw Error("Origin is unset.");let t=s(e,p),n=_.current;if(null===n)throw Error("Final step pixel size has not been computed.");let u=O.current;if(null===u)throw Error("Original value is unset.");let l=o(Math.floor(u/b)*b+Math.trunc((t-r)/n)*b,g,y);M.current=l,z(l)}function K(e){document.body.style["pointer-events"]="auto",B.current&&clearInterval(B.current),$.current=null,_.current=null,O.current=null,document.removeEventListener("mousemove",H),document.removeEventListener("mouseup",K),F.current&&(E?.(e,M.current),F.current=!1)}l(()=>{m.value!==M.current&&(M.current=m.value,z(m.value))},[m.value]);let P=m.value;F.current&&(P=M.current);let U=t(e,{children:[f&&!F.current?r(a,{format:h,value:P}):h?h(P):P,T?` ${T}`:""]}),W=r("input",{className:"NumberInput__input",onBlur:function(e){let r=Number.parseFloat(e.currentTarget.value);(w||(r=o(r,g,y)),Number.isNaN(r))?I(!1):(M.current=r,z(r),E?.(e.nativeEvent,r),D&&I(!1))},onKeyDown:function(e){(e.key===n.Enter||u(e.key))&&I(!1)},ref:A,style:{display:D?void 0:"none",fontSize:x,height:L,lineHeight:S}});return v({displayElement:U,displayValue:P,dragging:F.current,editing:D,handleDragStart:function(e){if(!D){if("number"!=typeof N){let r=e.currentTarget.offsetWidth/((y-g)/b);if(void 0===N)_.current=r;else if("function"==typeof N)_.current=N(r);else throw Error(`Unsupported value for stepPixelSize of type ${typeof N}`)}else _.current=N;document.body.style["pointer-events"]="none",$.current=s(e.nativeEvent,p),O.current=m.value,F.current=!0,document.addEventListener("mouseup",K),C.current=setTimeout(()=>{var r=e.nativeEvent;if(F.current)document.addEventListener("mousemove",H),B.current=setInterval(()=>{F.current&&d&&E?.(r,M.current)},j);else if(I(!0),A.current){let e=A.current;e.value=M.current.toString(),setTimeout(()=>{e.focus(),e.select()},10)}C.current&&clearTimeout(C.current)},100)}},inputElement:W})}export{m as DraggableControl};
1
+ import{Fragment as e,jsx as r,jsxs as t}from"react/jsx-runtime";import{KEY as n,isEscape as u}from"../common/keys.js";import{clamp as o}from"../common/math.js";import{useEffect as l,useRef as c,useState as i}from"react";import{AnimatedNumber as a}from"./AnimatedNumber.js";function s(e,r){return e.screenX*r[0]+e.screenY*r[1]}function m(m){let{animated:f,disabled:v,children:p,dragMatrix:d=[1,0],tickWhileDragging:y,format:h,maxValue:g=1/0,minValue:E=-1/0,onChange:b,step:N=1,stepPixelSize:w,unclamped:T,unit:j,updateRate:x=400,fontSize:L,height:S,lineHeight:k}=m,[z,D]=i(m.value),[I,O]=i(!1),F=c(!1),M=c(m.value),$=c(0),_=c(0),A=c(null),B=c(null),C=c(null),H=c(null);function K(e){let r=_.current;if(null===r)throw Error("Origin is unset.");let t=s(e,d),n=A.current;if(null===n)throw Error("Final step pixel size has not been computed.");let u=$.current;if(null===u)throw Error("Original value is unset.");let l=o(Math.floor(u/N)*N+Math.trunc((t-r)/n)*N,E,g);M.current=l,D(l)}function P(e){document.body.style["pointer-events"]="auto",C.current&&clearInterval(C.current),_.current=null,A.current=null,$.current=null,document.removeEventListener("mousemove",K),document.removeEventListener("mouseup",P),F.current&&(b?.(e,M.current),F.current=!1)}l(()=>{m.value!==M.current&&(M.current=m.value,D(m.value))},[m.value]);let U=m.value;F.current&&(U=M.current);let W=t(e,{children:[f&&!F.current?r(a,{format:h,value:U}):h?h(U):U,j?` ${j}`:""]}),X=r("input",{className:"NumberInput__input",onBlur:function(e){let r=Number.parseFloat(e.currentTarget.value);(T||(r=o(r,E,g)),Number.isNaN(r))?O(!1):(M.current=r,D(r),b?.(e.nativeEvent,r),I&&O(!1))},onKeyDown:function(e){(e.key===n.Enter||u(e.key))&&O(!1)},ref:B,readOnly:v,style:{display:I?void 0:"none",fontSize:L,height:S,lineHeight:k}});return p({displayElement:W,displayValue:U,dragging:F.current,editing:I,handleDragStart:function(e){if(!I&&!v){if("number"!=typeof w){let r=e.currentTarget.offsetWidth/((g-E)/N);if(void 0===w)A.current=r;else if("function"==typeof w)A.current=w(r);else throw Error(`Unsupported value for stepPixelSize of type ${typeof w}`)}else A.current=w;document.body.style["pointer-events"]="none",_.current=s(e.nativeEvent,d),$.current=m.value,F.current=!0,document.addEventListener("mouseup",P),H.current=setTimeout(()=>{var r=e.nativeEvent;if(F.current)document.addEventListener("mousemove",K),C.current=setInterval(()=>{F.current&&y&&b?.(r,M.current)},x);else if(O(!0),B.current){let e=B.current;e.value=M.current.toString(),setTimeout(()=>{e.focus(),e.select()},10)}H.current&&clearTimeout(H.current)},100)}},inputElement:X})}export{m as DraggableControl};
@@ -42,6 +42,8 @@ type Props = {
42
42
  fluid: boolean;
43
43
  /** Text to show when nothing has been selected. */
44
44
  placeholder: string;
45
+ /** Turns the dropdown button into a search textbox. Incompatible with Tiny */
46
+ searchInput: boolean;
45
47
  /** @deprecated If you want to allow dropdown breaks layout, set width 100% */
46
48
  clipSelectedText: boolean;
47
49
  /** Called when dropdown button is clicked */
@@ -1 +1 @@
1
- import{Fragment as o,jsx as n,jsxs as e}from"react/jsx-runtime";import{KEY as t}from"../common/keys.js";import{classes as r}from"../common/react.js";import{unit as l}from"../common/ui.js";import{useRef as i,useState as c}from"react";import{Button as d}from"./Button.js";import{Floating as s}from"./Floating.js";import{Icon as a}from"./Icon.js";function m(o){return"string"==typeof o?o:o.value}function p(p){let{autoScroll:u=!0,buttons:_,className:w,color:f="default",disabled:h,displayText:D,icon:y,iconRotation:v,iconSpin:N,iconOnly:g,menuWidth:b,noChevron:x,onClick:j,onSelected:k,options:C=[],over:B,placeholder:I="Select...",selected:T,fluid:A,width:E=15}=p,[K,O]=c(!1),S=i(null),$=C.findIndex(o=>m(o)===T)||0;function F(o){let n=o;n=o<$?o<2?0:o-2:o>C.length-3?C.length-1:o-2;let e=S.current,t=e?.children[n];e&&t&&(e.scrollTop=t.offsetTop)}function M(o){let n;if(C.length<1||h)return;let e=C.length-1;n=$<0?"next"===o?e:0:"next"===o?$===e?0:$+1:0===$?e:$-1,K&&u&&F(n),k?.(m(C[n]))}let W=B?"top":"bottom";return g&&(W=`${W}-start`),e("div",{className:r(["Dropdown",A&&"Dropdown--fluid"]),children:[n(s,{allowedOutsideClasses:".Dropdown__button",closeAfterInteract:!0,content:n("div",{className:"Dropdown__menu",ref:S,children:0===C.length?n("div",{className:"Dropdown__menu--entry",children:"No options"}):C.map(o=>{let e=m(o);return n("div",{className:r(["Dropdown__menu--entry",T===e&&"selected"]),onClick:()=>{k?.(e)},onKeyDown:o=>{o.key===t.Enter&&k?.(e)},children:"string"==typeof o?o:o.displayText},e)})}),contentAutoWidth:!b,contentClasses:"Dropdown__menu--wrapper",contentStyles:{width:b?l(b):void 0},disabled:h,onMounted:()=>{K&&u&&-1!==$&&F($)},onOpenChange:O,placement:W,children:e("div",{className:r(["Dropdown__control",`Button--color--${f}`,h&&"Button--disabled",g&&"Dropdown__control--icon-only",w]),onClick:o=>{(!h||K)&&j?.(o)},onKeyDown:o=>{o.key!==t.Enter||h||j?.(o)},style:{width:l(E)},children:[y&&n(a,{className:"Dropdown__icon",name:y,rotation:v,spin:N}),!g&&e(o,{children:[n("span",{className:"Dropdown__selected-text",children:D||T&&m(T)||I}),!x&&n(a,{className:r(["Dropdown__icon","Dropdown__icon--arrow",B&&"over",K&&"open"]),name:"chevron-down"})]})]})}),_&&e(o,{children:[n(d,{className:"Dropdown__button",disabled:h,icon:"chevron-left",onClick:()=>{M("previous")}}),n(d,{className:"Dropdown__button",disabled:h,icon:"chevron-right",onClick:()=>{M("next")}})]})]})}export{p as Dropdown};
1
+ import{Fragment as o,jsx as n,jsxs as e}from"react/jsx-runtime";import{KEY as t}from"../common/keys.js";import{classes as r}from"../common/react.js";import{unit as l}from"../common/ui.js";import{useRef as i,useState as s}from"react";import{Button as c}from"./Button.js";import{Floating as d}from"./Floating.js";import{Icon as a}from"./Icon.js";import{Input as p}from"./Input.js";function m(o){return"string"==typeof o?o:o.value}function u(u){let{autoScroll:w=!0,buttons:_,className:f,color:h="default",disabled:D,displayText:y,icon:g,iconRotation:v,iconSpin:N,iconOnly:C,menuWidth:b,noChevron:x,onClick:j,onSelected:k,options:I=[],over:S,placeholder:T="Select...",searchInput:B,selected:A,fluid:E,width:K=15}=u,[L,O]=s(!1),[$,F]=s(""),M=i(null),U=I.findIndex(o=>m(o)===A)||0;function W(o){let n=o;n=o<U?o<2?0:o-2:o>I.length-3?I.length-1:o-2;let e=M.current,t=e?.children[n];e&&t&&(e.scrollTop=t.offsetTop)}function q(o){let n;if(I.length<1||D)return;let e=I.length-1;n=U<0?"next"===o?e:0:"next"===o?U===e?0:U+1:0===U?e:U-1,L&&w&&W(n),k?.(m(I[n]))}let z=$?I.filter(o=>("string"==typeof o?o:o.displayText||m(o)).toString().toLowerCase().includes($.toLowerCase())):I,G=S?"top":"bottom";return C&&(G=`${G}-start`),e("div",{className:r(["Dropdown",E&&"Dropdown--fluid"]),children:[n(d,{allowedOutsideClasses:".Dropdown__button",closeAfterInteract:!0,content:n("div",{className:"Dropdown__menu",ref:M,children:0===z.length?n("div",{className:"Dropdown__menu--entry",children:"No options"}):z.map(o=>{let e=m(o);return n("div",{className:r(["Dropdown__menu--entry",A===e&&"selected"]),onClick:()=>{k?.(e),F("")},onKeyDown:o=>{o.key===t.Enter&&(k?.(e),F(""))},children:"string"==typeof o?o:o.displayText},e)})}),contentAutoWidth:!b,contentClasses:"Dropdown__menu--wrapper",contentStyles:{width:b?l(b):void 0},disabled:D,onMounted:()=>{L&&w&&-1!==U&&W(U)},onOpenChange:O,placement:G,children:B?n(p,{className:r(["Dropdown__input",f]),placeholder:y?.toString()||T,disabled:D,value:$,alwaysUpdate:!0,onChange:F}):e("div",{className:r(["Dropdown__control",`Button--color--${h}`,D&&"Button--disabled",C&&"Dropdown__control--icon-only",f]),onClick:o=>{(!D||L)&&j?.(o)},onKeyDown:o=>{o.key!==t.Enter||D||j?.(o)},style:{width:l(K)},children:[g&&n(a,{className:"Dropdown__icon",name:g,rotation:v,spin:N}),!C&&e(o,{children:[n("span",{className:"Dropdown__selected-text",children:y||A&&m(A)||T}),!x&&n(a,{className:r(["Dropdown__icon","Dropdown__icon--arrow",S&&"over",L&&"open"]),name:"chevron-down"})]})]})}),_&&e(o,{children:[n(c,{className:"Dropdown__button",disabled:D,icon:"chevron-left",onClick:()=>{q("previous")}}),n(c,{className:"Dropdown__button",disabled:D,icon:"chevron-right",onClick:()=>{q("next")}})]})]})}export{u as Dropdown};
@@ -16,13 +16,16 @@ export type BaseInputProps<TElement = HTMLInputElement, TInput = string> = Parti
16
16
  * Do this if it's performing expensive ops on each input, like filtering or
17
17
  * sending the value immediate to Byond (via act).
18
18
  *
19
- * 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
20
21
  */
21
- expensive: boolean;
22
+ expensive: boolean | number;
22
23
  /** Fills the parent container */
23
24
  fluid: boolean;
24
25
  /** Mark this if you want to use a monospace font */
25
26
  monospace: boolean;
27
+ /** Will force an update when value changes even if the input isn't currently highlighted */
28
+ alwaysUpdate: boolean;
26
29
  /** Fires each time focus leaves the input, including if Esc or Enter are pressed */
27
30
  onBlur: (value: TInput) => void;
28
31
  /**
@@ -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{debounce 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";let i=u(e=>e(),250);function p(u){let{autoFocus:p,autoSelect:f,className:s,disabled:d,expensive:g,fluid:v,maxLength:T,monospace:j,onBlur:y,onChange:I,onEnter:b,onEscape:h,onKeyDown:k,placeholder:x,ref:C,selfClear:D,spellcheck:E=!1,value:w,...B}=u,K=l(null),L=C??K,[N,q]=a(w??"");c(()=>{let e;return(p||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",j&&"Input--monospace",o(B),s]);return e("input",{...z,autoComplete:"off",className:A,disabled:d,maxLength:T,onBlur:()=>y?.(N),onChange:function(e){let t=e.currentTarget.value;q(t),g?i(()=>I?.(t,e)):I?.(t,e)},onKeyDown:function(e){if(k?.(e),e.key===t.Enter){e.preventDefault(),b?.(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};
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,alwaysUpdate:E,spellcheck:w=!1,value:B,...K}=p,L=l(null),N=C??L,[q,z]=a(B??"");c(()=>{let e;return(i||f)&&(e=setTimeout(()=>{N.current?.focus(),f&&N.current?.select()},1)),()=>clearTimeout(e)},[]),c(()=>{(N.current&&document.activeElement!==N.current&&B!==q||E)&&z(B??"")},[B]);let A=m(K),F=n(["Input",d&&"Input--disabled",v&&"Input--fluid",y&&"Input--monospace",o(K),s]);return e("input",{...A,autoComplete:"off",className:F,disabled:d,maxLength:T,onBlur:()=>b?.(q),onChange:function(e){let t=e.currentTarget.value;z(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&&z(""),e.currentTarget.blur();return}r(e.key)&&(e.preventDefault(),h?.(e.currentTarget.value,e),e.currentTarget.blur())},placeholder:x,ref:N,spellCheck:w,type:"text",value:q})}export{p as Input};
@@ -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{debounce 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";let a=u(e=>e(),250);function f(u){let{allowFloats:f,autoFocus:p,autoSelect:s,className:d,disabled:v,expensive:y,fluid:I,maxValue:b=1e4,minValue:j=0,monospace:k,onBlur:D,onChange:x,onEnter:C,onEscape:R,onKeyDown:g,onValidationChange:h,value:E,...N}=u,T=c(null),[w,B]=l(E??j),[K,M]=l(!0);function q(e,t){x&&(y?a(()=>x?.(e,t)):x(e,t))}m(()=>{let e;return(p||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",I&&"Input--fluid",k&&"Input--monospace",o(N),d,!K&&"RestrictedInput--invalid"]);return e("input",{...z,autoComplete:"off",className:A,disabled:v,max:b,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:f?"any":"1",type:"number",value:w})}export{f as RestrictedInput};
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 +1 @@
1
- import{jsx as r,jsxs as e}from"react/jsx-runtime";import{clamp01 as i,keyOfMatchingRange as s,scale as l}from"../common/math.js";import{classes as a}from"../common/react.js";import{computeBoxClassName as o,computeBoxProps as t}from"../common/ui.js";import{DraggableControl as m}from"./DraggableControl.js";function d(d){let{animated:c,tickWhileDragging:n,format:_,maxValue:f,minValue:h,onChange:u,step:g,stepPixelSize:p,unit:v,value:B,className:N,fillValue:P,color:S,ranges:j={},children:w,...x}=d,y=void 0!==w;return r(m,{dragMatrix:[1,0],animated:c,tickWhileDragging:n,format:_,maxValue:f,minValue:h,onChange:u,step:g,stepPixelSize:p,unit:v,value:B,children:m=>{let{displayElement:d,displayValue:c,dragging:n,editing:_,handleDragStart:u,inputElement:g}=m,p=null!=P,v=i(l(P??c,h,f)),M=i(l(c,h,f)),$=S||s(P??B,j)||"default";return e("div",{className:a(["Slider",_&&"Slider--editing","ProgressBar",`ProgressBar--color--${$}`,N,o(x)]),...t(x),onMouseDown:u,children:[r("div",{className:a(["ProgressBar__fill",p&&!n&&"ProgressBar__fill--animated"]),style:{opacity:.4,width:`${100*Math.max(v,M)}%`}}),r("div",{className:a(["ProgressBar__fill",!n&&"ProgressBar__fill--animated"]),style:{width:`${100*Math.min(v,M)}%`}}),r("div",{className:"Slider__cursorOffset",style:{width:`${100*M}%`},children:r("div",{className:"Slider__cursor",children:n&&r("div",{className:"Slider__popupValue",children:d})})}),r("div",{className:"ProgressBar__content",children:y?w:d}),g]})}})}export{d as Slider};
1
+ import{jsx as r,jsxs as e}from"react/jsx-runtime";import{clamp01 as i,keyOfMatchingRange as l,scale as s}from"../common/math.js";import{classes as a}from"../common/react.js";import{computeBoxClassName as o,computeBoxProps as t}from"../common/ui.js";import{DraggableControl as d}from"./DraggableControl.js";function m(m){let{animated:c,disabled:n,tickWhileDragging:_,format:f,maxValue:h,minValue:u,onChange:g,step:p,stepPixelSize:v,unit:B,value:N,className:P,fillValue:S,color:j,ranges:w={},children:x,...y}=m,M=void 0!==x;return r(d,{dragMatrix:[1,0],animated:c,disabled:n,tickWhileDragging:_,format:f,maxValue:h,minValue:u,onChange:g,step:p,stepPixelSize:v,unit:B,value:N,children:d=>{let{displayElement:m,displayValue:c,dragging:_,editing:f,handleDragStart:g,inputElement:p}=d,v=null!=S,B=i(s(S??c,u,h)),$=i(s(c,u,h)),b=j||l(S??N,w)||"default";return e("div",{className:a(["Slider",n&&"Slider--disabled",f&&"Slider--editing","ProgressBar",`ProgressBar--color--${b}`,P,o(y)]),...t(y),onMouseDown:g,children:[r("div",{className:a(["ProgressBar__fill",v&&!_&&"ProgressBar__fill--animated"]),style:{opacity:.4,width:`${100*Math.max(B,$)}%`}}),r("div",{className:a(["ProgressBar__fill",!_&&"ProgressBar__fill--animated"]),style:{width:`${100*Math.min(B,$)}%`}}),r("div",{className:"Slider__cursorOffset",style:{width:`${100*$}%`},children:r("div",{className:"Slider__cursor",children:_&&r("div",{className:"Slider__popupValue",children:m})})}),r("div",{className:"ProgressBar__content",children:M?x:m}),p]})}})}export{m as Slider};
@@ -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{computeBoxClassName as u,computeBoxProps as o}from"../common/ui.js";import{debounce as a}from"../common/timer.js";import{useEffect as c,useRef as l,useState as m}from"react";let i=a(e=>e(),250);function s(a){let{autoFocus:s,autoSelect:f,className:g,disabled:p,dontUseTabForIndent:T,expensive:v,fluid:y,maxLength:b,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}=a,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",y&&"Input--fluid",d&&"Input--monospace",p&&"Input--disabled",u(w),g]);return e("textarea",{...z,autoComplete:"off",className:F,maxLength:b,onBlur:function(e){k?.(N)},onChange:function(e){let t=e.currentTarget.value;q(t),$&&(v?i(()=>$?.(t,e)):$(t,e))},onKeyDown:function(e){if(j?.(e),e.key===t.Enter&&!e.shiftKey){e.preventDefault(),h?.(e.currentTarget.value,e),I&&q(""),e.currentTarget.blur();return}if(r(e.key)){x?.(e.currentTarget.value,e),e.currentTarget.blur();return}if(!T&&e.key===t.Tab){e.preventDefault();let{value:t,selectionStart:r,selectionEnd:n}=e.currentTarget;q(`${t.substring(0,r)} ${t.substring(n)}`),e.currentTarget.selectionEnd=r+1,$?.(e.currentTarget.value,e);return}if(C&&(e.ctrlKey||e.metaKey)&&C[e.key]){e.preventDefault();let{selectionStart:t,selectionEnd:r,value:n}=e.currentTarget,u=C[e.key];q(`${n.substring(0,t)}${u}${n.substring(t,r)}${u}${n.substring(r)}`),e.currentTarget.selectionEnd=r+2*u.length,$?.(e.currentTarget.value,e);return}},placeholder:D,ref:L,spellCheck:K,value:N})}export{s as TextArea};
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
@@ -71,5 +71,5 @@
71
71
  "test": "bun test"
72
72
  },
73
73
  "type": "module",
74
- "version": "5.8.0"
74
+ "version": "5.10.0"
75
75
  }
@@ -5,6 +5,7 @@
5
5
  @include meta.load-css("./atomic/centered-image.scss");
6
6
  @include meta.load-css("./atomic/color.scss");
7
7
  @include meta.load-css("./atomic/debug-layout.scss");
8
+ @include meta.load-css("./atomic/helpers.scss");
8
9
  @include meta.load-css("./atomic/fit-text.scss");
9
10
  @include meta.load-css("./atomic/links.scss");
10
11
  @include meta.load-css("./atomic/outline.scss");
@@ -0,0 +1,19 @@
1
+ .dragging {
2
+ pointer-events: none;
3
+ }
4
+
5
+ .moving {
6
+ cursor: var(--cursor-grab);
7
+ }
8
+
9
+ .resizing-x {
10
+ cursor: var(--cursor-e-resize);
11
+ }
12
+
13
+ .resizing-y {
14
+ cursor: var(--cursor-n-resize);
15
+ }
16
+
17
+ .resizing-both {
18
+ cursor: var(--cursor-se-resize);
19
+ }
@@ -24,6 +24,7 @@
24
24
  width: 100%;
25
25
  }
26
26
 
27
+ &__input,
27
28
  &__control {
28
29
  display: flex;
29
30
  overflow: hidden;
@@ -33,6 +34,9 @@
33
34
  line-height: base.em(16px);
34
35
  height: base.em(22px);
35
36
  border-radius: var(--button-border-radius);
37
+ }
38
+
39
+ &__control {
36
40
  @include button.button-color();
37
41
  }
38
42
 
@@ -10,6 +10,15 @@
10
10
  }
11
11
  }
12
12
 
13
+ &--disabled {
14
+ cursor: default;
15
+ opacity: var(--slider-disabled-opacity);
16
+
17
+ .Slider__cursor:before {
18
+ display: none;
19
+ }
20
+ }
21
+
13
22
  &__cursor {
14
23
  position: absolute;
15
24
  inset: 0 calc(-1 * var(--space-xxs));
@@ -165,6 +165,7 @@
165
165
  --slider-popup-color: var(--tooltip-color);
166
166
  --slider-popup-border-radius: var(--tooltip-border-radius);
167
167
  --slider-popup-blur: var(--tooltip-blur);
168
+ --slider-disabled-opacity: 0.5;
168
169
 
169
170
  /* Tooltip */
170
171
  --tooltip-color: var(--color-text);
@@ -102,6 +102,7 @@
102
102
  /* Cursors */
103
103
  --cursor-default: default;
104
104
  --cursor-pointer: pointer;
105
+ --cursor-grab: grab;
105
106
  --cursor-disabled: var(--cursor-default);
106
107
  --cursor-n-resize: n-resize;
107
108
  --cursor-s-resize: s-resize;