tgui-core 3.0.4 → 3.1.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.
@@ -1 +1 @@
1
- import*as o from"react";import*as e from"../common/ui.js";function m(m){let{as:t="div",className:s,children:a,tw:r,...c}=m,p=s?`${s} ${(0,e.computeBoxClassName)(c)}`:(0,e.computeBoxClassName)(c),u=(0,e.computeBoxProps)({...c,...(0,e.computeTwClass)(r)});return(0,o.createElement)(t,{...u,className:p},a)}export{m as Box};
1
+ import*as e from"react";import*as o from"../common/ui.js";function m(m){let{as:s="div",className:t,children:a,tw:r,...c}=m,u=(0,e.useMemo)(()=>t?`${t} ${(0,o.computeBoxClassName)(c)}`:(0,o.computeBoxClassName)(c),[t,c]),p=(0,e.useMemo)(()=>(0,o.computeBoxProps)({...c,...(0,o.computeTwClass)(r)}),[c,r]);return(0,e.createElement)(s,{...p,className:u},a)}export{m as Box};
@@ -1,5 +1,5 @@
1
1
  import type { Placement } from '@floating-ui/react';
2
- import { type ReactNode } from 'react';
2
+ import { type ReactNode, type RefObject } from 'react';
3
3
  import { type BooleanLike } from '../common/react';
4
4
  import { type BoxProps } from './Box';
5
5
  /**
@@ -68,11 +68,18 @@ type ConfirmProps = Partial<{
68
68
  }> & Props;
69
69
  declare function ButtonConfirm(props: ConfirmProps): import("react/jsx-runtime").JSX.Element;
70
70
  type InputProps = Partial<{
71
- currentValue: string;
72
- defaultValue: string;
71
+ /** Use the value prop. This is done to be uniform with other inputs. */
72
+ children: never;
73
+ /** Max length of the input */
73
74
  maxLength: number;
74
- onCommit: (e: any, value: string) => void;
75
+ /** Action on enter key press */
76
+ onEnter: (value: string) => void;
77
+ /** Text to display when the input is empty */
75
78
  placeholder: string;
79
+ /** Reference to the inner input */
80
+ ref: RefObject<HTMLInputElement | null>;
81
+ /** The value of the input */
82
+ value: string;
76
83
  }> & Props;
77
84
  declare function ButtonInput(props: InputProps): import("react/jsx-runtime").JSX.Element;
78
85
  type FileProps = {
@@ -1 +1 @@
1
- var t;import*as e from"react/jsx-runtime";import*as n from"react";import*as o from"../common/keys.js";import*as r from"../common/react.js";import*as s from"../common/ui.js";import*as i from"./Box.js";import*as l from"./Icon.js";import*as c from"./Tooltip.js";function u(t){let{captureKeys:n=!0,children:i,circular:u,className:a,color:f,compact:m,content:p,disabled:d,ellipsis:B,fluid:x,icon:j,iconColor:h,iconPosition:y,iconRotation:k,iconSize:v,iconSpin:C,onClick:g,selected:E,tooltip:N,tooltipPosition:b,verticalAlignContent:_,...w}=t,I=p||i,K=(0,e.jsx)(l.Icon,{className:"Button--icon",name:j||"",color:h,rotation:k,size:v,spin:C}),A=(0,e.jsx)("div",{className:(0,r.classes)(["Button",x&&"Button--fluid",d&&"Button--disabled",E&&"Button--selected",u&&"Button--circular",m&&"Button--compact",!I&&"Button--empty",y&&`Button--icon-${y}`,_&&"Button--flex",_&&x&&"Button--flex--fluid",_&&`Button--verticalAlignContent--${_}`,f&&"string"==typeof f?`Button--color--${f}`:"Button--color--default",a,(0,s.computeBoxClassName)(w)]),tabIndex:d?void 0:0,onClick:t=>{!d&&g&&g(t)},onKeyDown:t=>{if(n){if(t.key===o.KEY.Space||t.key===o.KEY.Enter){t.preventDefault(),!d&&g&&g(t);return}(0,o.isEscape)(t.key)&&t.preventDefault()}},...(0,s.computeBoxProps)(w),children:(0,e.jsxs)("div",{className:(0,r.classes)(["Button__content",B&&"Button__content--ellipsis"]),children:[j&&"right"!==y&&K,B?(0,e.jsx)("span",{className:"Button--ellipsis",children:I}):I,j&&"right"===y&&K]})});return N&&(A=(0,e.jsx)(c.Tooltip,{content:N,position:b,children:A})),A}(t=u||(u={})).Checkbox=function(t){let{checked:n,...o}=t;return(0,e.jsx)(u,{color:"transparent",icon:n?"check-square-o":"square-o",selected:n,...o})},t.Confirm=function(t){let{children:o,color:r,confirmColor:s="bad",confirmContent:i="Confirm?",confirmIcon:l,ellipsis:c=!0,icon:a,onBlur:f,onClick:m,...p}=t,[d,B]=(0,n.useState)(!1);return(0,e.jsx)(u,{icon:d?l:a,color:d?s:r,onBlur:function(t){B(!1),f?.(t)},onClick:function(t){if(!d)return void B(!0);m?.(t),B(!1)},...p,children:d?i:o})},t.Input=function(t){let{children:s,color:u="default",content:a,currentValue:f,defaultValue:m,disabled:p,fluid:d,icon:B,iconRotation:x,iconSpin:j,maxLength:h,onCommit:y=()=>null,placeholder:k,tooltip:v,tooltipPosition:C,...g}=t,[E,N]=(0,n.useState)(!1),b=(0,n.createRef)();function _(t){let e=b.current;e&&(""!==e.value?y(t,e.value):m&&y(t,m))}(0,n.useEffect)(()=>{let t=b.current;if(t&&E){t.value=f||"";try{t.focus(),t.select()}catch{}}},[E,f]);let w=(0,e.jsxs)(i.Box,{className:(0,r.classes)(["Button",d&&"Button--fluid",p&&"Button--disabled",`Button--color--${u}`]),...g,onClick:()=>N(!0),children:[B&&(0,e.jsx)(l.Icon,{name:B,rotation:x,spin:j}),(0,e.jsx)("div",{children:a||s}),(0,e.jsx)("input",{disabled:!!p,ref:b,className:"NumberInput__input",style:{display:E?"":"none",textAlign:"left"},onBlur:t=>{E&&(N(!1),_(t))},onKeyDown:t=>{if(t.key===o.KEY.Enter){N(!1),_(t);return}(0,o.isEscape)(t.key)&&N(!1)}})]});return v&&(w=(0,e.jsx)(c.Tooltip,{content:v,position:C,children:w})),w},t.File=function(t){let{accept:o,multiple:r,onSelectFiles:s,...i}=t,l=(0,n.useRef)(null);async function c(t){let e=Array.from(t).map(t=>{let e=new FileReader;return new Promise(n=>{e.onload=()=>n(e.result),e.readAsText(t)})});return await Promise.all(e)}async function a(t){let e=t.target.files;if(e?.length){let t=await c(e);s(r?t:t[0])}}return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(u,{onClick:()=>l.current?.click(),...i}),(0,e.jsx)("input",{hidden:!0,type:"file",ref:l,accept:o,multiple:r,onChange:a})]})};export{u as Button};
1
+ var t;import*as e from"react/jsx-runtime";import*as n from"react";import*as o from"../common/keys.js";import*as r from"../common/react.js";import*as s from"../common/ui.js";import*as u from"./Box.js";import*as i from"./Icon.js";import*as l from"./Tooltip.js";function c(t){let{captureKeys:n=!0,children:u,circular:c,className:a,color:f,compact:m,content:p,disabled:d,ellipsis:B,fluid:x,icon:j,iconColor:h,iconPosition:y,iconRotation:g,iconSize:k,iconSpin:v,onClick:C,selected:b,tooltip:E,tooltipPosition:N,verticalAlignContent:T,..._}=t,w=p||u,D=(0,e.jsx)(i.Icon,{className:"Button--icon",name:j||"",color:h,rotation:g,size:k,spin:v}),I=(0,e.jsx)("div",{className:(0,r.classes)(["Button",x&&"Button--fluid",d&&"Button--disabled",b&&"Button--selected",c&&"Button--circular",m&&"Button--compact",!w&&"Button--empty",y&&`Button--icon-${y}`,T&&"Button--flex",T&&x&&"Button--flex--fluid",T&&`Button--verticalAlignContent--${T}`,f&&"string"==typeof f?`Button--color--${f}`:"Button--color--default",a,(0,s.computeBoxClassName)(_)]),tabIndex:d?void 0:0,onClick:t=>{!d&&C&&C(t)},onKeyDown:t=>{if(n){if(t.key===o.KEY.Space||t.key===o.KEY.Enter){t.preventDefault(),!d&&C&&C(t);return}(0,o.isEscape)(t.key)&&t.preventDefault()}},...(0,s.computeBoxProps)(_),children:(0,e.jsxs)("div",{className:(0,r.classes)(["Button__content",B&&"Button__content--ellipsis"]),children:[j&&"right"!==y&&D,B?(0,e.jsx)("span",{className:"Button--ellipsis",children:w}):w,j&&"right"===y&&D]})});return E&&(I=(0,e.jsx)(l.Tooltip,{content:E,position:N,children:I})),I}(t=c||(c={})).Checkbox=function(t){let{checked:n,...o}=t;return(0,e.jsx)(c,{color:"transparent",icon:n?"check-square-o":"square-o",selected:n,...o})},t.Confirm=function(t){let{children:o,color:r,confirmColor:s="bad",confirmContent:u="Confirm?",confirmIcon:i,ellipsis:l=!0,icon:a,onBlur:f,onClick:m,...p}=t,[d,B]=(0,n.useState)(!1);return(0,e.jsx)(c,{icon:d?i:a,color:d?s:r,onBlur:function(t){B(!1),f?.(t)},onClick:function(t){if(!d)return void B(!0);m?.(t),B(!1)},...p,children:d?u:o})},t.Input=function(t){let{children:s,color:l="default",disabled:c,fluid:a,icon:f,iconRotation:m,iconSpin:p,maxLength:d,onEnter:B,placeholder:x,ref:j,value:h,...y}=t,[g,k]=(0,n.useState)(h),[v,C]=(0,n.useState)(!1),b=(0,n.createRef)(),E=j??b;return(0,n.useEffect)(()=>{v&&(E.current?.focus(),E.current?.select())},[v]),(0,n.useEffect)(()=>{v||h===g||k(h)},[v,h]),(0,e.jsxs)(u.Box,{className:(0,r.classes)(["Button",a&&"Button--fluid",c&&"Button--disabled",`Button--color--${l}`]),onClick:()=>C(!0),...y,children:[f&&(0,e.jsx)(i.Icon,{name:f,rotation:m,spin:p}),g,(0,e.jsx)("input",{className:"NumberInput__input",disabled:!!c,maxLength:d,onBlur:function(){C(!1)},onChange:function(t){k(t.currentTarget.value)},onKeyDown:function(t){if(t.key===o.KEY.Enter){t.preventDefault(),B?.(t.currentTarget.value),t.currentTarget.blur();return}if((0,o.isEscape)(t.key)){t.preventDefault(),t.currentTarget.blur();return}},placeholder:x,ref:E,spellCheck:"false",style:{display:v?"":"none",textAlign:"left"},type:"text",value:g})]})},t.File=function(t){let{accept:o,multiple:r,onSelectFiles:s,...u}=t,i=(0,n.useRef)(null);async function l(t){let e=Array.from(t).map(t=>{let e=new FileReader;return new Promise(n=>{e.onload=()=>n(e.result),e.readAsText(t)})});return await Promise.all(e)}async function a(t){let e=t.target.files;if(e?.length){let t=await l(e);s(r?t:t[0])}}return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(c,{onClick:()=>i.current?.click(),...u}),(0,e.jsx)("input",{hidden:!0,type:"file",ref:i,accept:o,multiple:r,onChange:a})]})};export{c as Button};
@@ -1 +1 @@
1
- import*as e from"react/jsx-runtime";import*as t from"@floating-ui/react";import*as a from"react";import*as n from"../common/react.js";function o(o){let s,{allowedOutsideClasses:i,animationDuration:r,children:l,closeAfterInteract:c,content:m,contentAutoWidth:d,contentClasses:p,contentOffset:f=6,contentStyles:u,disabled:g,hoverDelay:h,hoverOpen:x,onMounted:F,placement:b,stopChildPropagation:j,onOpenChange:C}=o,[k,v]=(0,a.useState)(!1),{refs:w,floatingStyles:E,context:P}=(0,t.useFloating)({open:k,onOpenChange(e){v(e),C?.(e)},whileElementsMounted:(e,a,n)=>(void 0!==F&&F(),(0,t.autoUpdate)(e,a,n)),placement:b||"bottom",transform:!1,middleware:[(0,t.offset)(f),(0,t.flip)({padding:6,fallbackPlacements:["bottom-start","bottom-end","top","top-start","top-end"]}),d&&(0,t.size)({apply({rects:e,elements:t}){t.floating.style.width=`${e.reference.width}px`}})]}),{isMounted:y,status:S}=(0,t.useTransitionStatus)(P,{duration:r||200}),M=(0,t.useDismiss)(P,{ancestorScroll:!0,outsidePress:e=>!i||e.target instanceof Element&&!e.target.closest(i)}),O=(0,t.useClick)(P,{enabled:!g}),z=(0,t.useHover)(P,{enabled:!g,restMs:h||200}),{getReferenceProps:D,getFloatingProps:H}=(0,t.useInteractions)([M,x?z:O]),I=D({ref:w.setReference,...j&&{onClick:e=>e.stopPropagation()}}),N=H({onClick:()=>{c&&P.onOpenChange(!1)}});return s=(0,a.isValidElement)(l)?(0,a.cloneElement)(l,I):(0,e.jsx)("div",{...I,children:l}),(0,e.jsxs)(e.Fragment,{children:[s,y&&!!m&&(0,e.jsx)(t.FloatingPortal,{children:(0,e.jsx)("div",{ref:w.setFloating,className:(0,n.classes)(["Floating",!r&&"Floating--animated",p]),"data-position":P.placement,"data-transition":S,style:{...E,...u},...N,children:m})})]})}export{o as Floating};
1
+ import*as e from"react/jsx-runtime";import*as t from"@floating-ui/react";import*as n from"react";import*as a from"../common/react.js";function s(s){let o,{allowedOutsideClasses:i,animationDuration:r,children:l,closeAfterInteract:c,content:m,contentAutoWidth:d,contentClasses:p,contentOffset:f=6,contentStyles:u,disabled:g,hoverDelay:h,hoverOpen:x,onMounted:F,placement:j,stopChildPropagation:C,onOpenChange:v}=s,[w,E]=(0,n.useState)(!1),{refs:S,floatingStyles:b,context:k}=(0,t.useFloating)({open:w,onOpenChange(e){E(e),v?.(e)},whileElementsMounted:(e,n,a)=>(void 0!==F&&F(),(0,t.autoUpdate)(e,n,a,{elementResize:!1,ancestorResize:!1,ancestorScroll:!1})),placement:j||"bottom",transform:!1,middleware:[(0,t.offset)(f),(0,t.flip)({padding:6}),d&&(0,t.size)({apply({rects:e,elements:t}){t.floating.style.width=`${e.reference.width}px`}})]}),{isMounted:y,status:z}=(0,t.useTransitionStatus)(k,{duration:r||200}),P=(0,t.useDismiss)(k,{ancestorScroll:!0,outsidePress:e=>!i||e.target instanceof Element&&!e.target.closest(i)}),R=(0,t.useClick)(k,{enabled:!g}),M=(0,t.useHover)(k,{enabled:!g,restMs:h||200}),{getReferenceProps:O,getFloatingProps:D}=(0,t.useInteractions)([P,x?M:R]),H=O({ref:S.setReference,...C&&{onClick:e=>e.stopPropagation()}}),I=D({onClick:()=>{c&&k.onOpenChange(!1)}});return o=(0,n.isValidElement)(l)?(0,n.cloneElement)(l,H):(0,e.jsx)("div",{...H,children:l}),(0,e.jsxs)(e.Fragment,{children:[o,y&&!!m&&(0,e.jsx)(t.FloatingPortal,{children:(0,e.jsx)("div",{ref:S.setFloating,className:(0,a.classes)(["Floating",!r&&"Floating--animated",p]),"data-position":k.placement,"data-transition":z,style:{...b,...u},...I,children:m})})]})}export{s as Floating};
@@ -44,7 +44,7 @@ type Props = Partial<{
44
44
  color: string;
45
45
  /** Makes button disabled and dark red if true. Also disables onClick. */
46
46
  disabled: BooleanLike;
47
- /** Optional. Adds a "stub" when loading DmIcon. */
47
+ /** Optional. Replaces default "stub" when loading DmIcon. */
48
48
  dmFallback: ReactNode;
49
49
  /** Parameter `icon` of component `DmIcon`. */
50
50
  dmIcon: string | null;
@@ -57,6 +57,8 @@ type Props = Partial<{
57
57
  * Allows the use of `title`
58
58
  */
59
59
  fluid: boolean;
60
+ /** Replaces default "question" icon when image missing. */
61
+ fallbackIcon: string;
60
62
  /** Parameter responsible for the size of the image, component and standard "stubs". */
61
63
  imageSize: number;
62
64
  /** Prop `src` of Image component. Example: `imageSrc={resolveAsset(thing.image)}` */
@@ -1 +1 @@
1
- import*as t from"react/jsx-runtime";import*as e from"../common/react.js";import*as s from"../common/ui.js";import*as n from"./DmIcon.js";import*as o from"./Icon.js";import*as a from"./Image.js";import*as i from"./Stack.js";import*as c from"./Tooltip.js";function m(o){let{asset:i,assetSize:m=32,base64:r,buttons:u,buttonsAlt:p,children:x,className:g,color:d,disabled:I,dmFallback:_,dmIcon:h,dmIconState:j,fluid:B,imageSize:f=64,imageSrc:$,onClick:y,onRightClick:N,selected:b,title:v,tooltip:w,tooltipPosition:k,...D}=o,S=(0,t.jsxs)("div",{className:"ImageButton__container",tabIndex:I?void 0:0,onClick:t=>{!I&&y&&y(t)},onKeyDown:t=>{"Enter"===t.key&&!I&&y&&y(t)},onContextMenu:t=>{t.preventDefault(),!I&&N&&N(t)},style:{width:B?"auto":`calc(${f}px + 0.5em + 2px)`},children:[(0,t.jsx)("div",{className:"ImageButton__image",children:r||$?(0,t.jsx)(a.Image,{src:r?`data:image/png;base64,${r}`:$,height:`${f}px`,width:`${f}px`}):h&&j?(0,t.jsx)(n.DmIcon,{icon:h,icon_state:j,fallback:_||(0,t.jsx)(l,{spin:!0,icon:"spinner",size:f}),height:`${f}px`,width:`${f}px`}):i?(0,t.jsx)(a.Image,{className:(0,e.classes)(i||[]),height:`${f}px`,width:`${f}px`,style:{transform:`scale(${f/m})`,transformOrigin:"top left"}}):(0,t.jsx)(l,{icon:"question",size:f})}),B?(0,t.jsxs)("div",{className:"ImageButton__content",children:[v&&(0,t.jsx)("span",{className:(0,e.classes)(["ImageButton__content--title",!!x&&"ImageButton__content--divider"]),children:v}),x&&(0,t.jsx)("span",{className:"ImageButton__content--text",children:x})]}):!!x&&(0,t.jsx)("span",{className:"ImageButton__content",children:x})]});return w&&(S=(0,t.jsx)(c.Tooltip,{content:w,position:k,children:S})),(0,t.jsxs)("div",{className:(0,e.classes)(["ImageButton",B&&"ImageButton--fluid",b&&"ImageButton--selected",I&&"ImageButton--disabled",!x&&"ImageButton--empty",!(y||N)&&"ImageButton--noAction",d&&"string"==typeof d?`ImageButton__color--${d}`:"ImageButton__color--default",g]),...(0,s.computeBoxProps)(D),children:[S,u&&(0,t.jsx)("div",{className:(0,e.classes)(["ImageButton__buttons",!x&&"ImageButton__buttons--empty"]),style:{width:"auto"},children:u}),p&&(0,t.jsx)("div",{className:(0,e.classes)(["ImageButton__buttons","ImageButton__buttons--alt",!x&&"ImageButton__buttons--empty"]),style:{width:`calc(${f}px + ${.5*!B}em)`,maxWidth:B?"auto":`calc(${f}px + 0.5em)`},children:p})]})}function l(e){let{icon:s,spin:n,size:a=64}=e;return(0,t.jsx)(i.Stack,{height:`${a}px`,width:`${a}px`,children:(0,t.jsx)(i.Stack.Item,{grow:!0,textAlign:"center",align:"center",children:(0,t.jsx)(o.Icon,{spin:n,name:s,color:"gray",style:{fontSize:`calc(${a}px * 0.75)`}})})})}export{m as ImageButton};
1
+ import*as t from"react/jsx-runtime";import*as e from"../common/react.js";import*as s from"../common/ui.js";import*as n from"./DmIcon.js";import*as o from"./Icon.js";import*as a from"./Image.js";import*as m from"./Tooltip.js";function i(o){let{asset:i,assetSize:l=32,base64:r,buttons:u,buttonsAlt:p,children:x,className:g,color:d,disabled:_,dmFallback:I,dmIcon:h,dmIconState:j,fluid:B,fallbackIcon:f,imageSize:$=64,imageSrc:y,onClick:N,onRightClick:b,selected:v,title:w,tooltip:k,tooltipPosition:D,...z}=o,C=(0,t.jsxs)("div",{className:"ImageButton__container",tabIndex:_?void 0:0,onClick:t=>{!_&&N&&N(t)},onKeyDown:t=>{"Enter"===t.key&&!_&&N&&N(t)},onContextMenu:t=>{t.preventDefault(),!_&&b&&b(t)},style:{width:B?"auto":`calc(${$}px + 0.5em + 2px)`},children:[(0,t.jsx)("div",{className:"ImageButton__image",children:r||y?(0,t.jsx)(a.Image,{src:r?`data:image/png;base64,${r}`:y,height:`${$}px`,width:`${$}px`}):h&&j?(0,t.jsx)(n.DmIcon,{icon:h,icon_state:j,fallback:I||(0,t.jsx)(c,{spin:!0,icon:"spinner",size:$}),height:`${$}px`,width:`${$}px`}):i?(0,t.jsx)(a.Image,{className:(0,e.classes)(i||[]),height:`${$}px`,width:`${$}px`,style:{transform:`scale(${$/l})`,transformOrigin:"top left"}}):(0,t.jsx)(c,{icon:f||"question",size:$})}),B?(0,t.jsxs)("div",{className:"ImageButton__content",children:[w&&(0,t.jsx)("span",{className:(0,e.classes)(["ImageButton__content--title",!!x&&"ImageButton__content--divider"]),children:w}),x&&(0,t.jsx)("span",{className:"ImageButton__content--text",children:x})]}):!!x&&(0,t.jsx)("span",{className:"ImageButton__content",children:x})]});return k&&(C=(0,t.jsx)(m.Tooltip,{content:k,position:D,children:C})),(0,t.jsxs)("div",{className:(0,e.classes)(["ImageButton",B&&"ImageButton--fluid",v&&"ImageButton--selected",_&&"ImageButton--disabled",!x&&"ImageButton--empty",!(N||b)&&"ImageButton--noAction",d&&"string"==typeof d?`ImageButton__color--${d}`:"ImageButton__color--default",g]),...(0,s.computeBoxProps)(z),children:[C,u&&(0,t.jsx)("div",{className:(0,e.classes)(["ImageButton__buttons",!x&&"ImageButton__buttons--empty"]),style:{width:"auto"},children:u}),p&&(0,t.jsx)("div",{className:(0,e.classes)(["ImageButton__buttons","ImageButton__buttons--alt",!x&&"ImageButton__buttons--empty"]),style:{width:`calc(${$}px + ${.5*!B}em)`,maxWidth:B?"auto":`calc(${$}px + 0.5em)`},children:p})]})}function c(e){let{icon:s,spin:n,size:a=64}=e;return(0,t.jsx)(o.Icon,{className:"ImageButton__image--fallback",height:`${a}px`,width:`${a}px`,spin:n,name:s,style:{fontSize:`${a}px`}})}export{i as ImageButton};
@@ -1 +1 @@
1
- import*as e from"react/jsx-runtime";import*as t from"react";import*as o from"../common/ui.js";import*as n from"./Button.js";import*as i from"./ProgressBar.js";import*as s from"./Stack.js";function r(n){let{backgroundImage:i,children:s,imageWidth:r,initialLeft:u=0,initialTop:c=0,onBackgroundMoved:l,onZoomChange:d,...m}=n,[p,f]=(0,t.useState)(0),[x,h]=(0,t.useState)(0),[j,g]=(0,t.useState)(0),[v,k]=(0,t.useState)(!1),[S,w]=(0,t.useState)(0),[b,M]=(0,t.useState)(1);function $(e){f(e.clientX-j),h(e.clientY-S),k(!0)}function B(e){if(!v)return;let t=e.clientX-p,o=e.clientY-x;l?.(t+u,o+c),g(t),w(o)}function y(){k(!1)}(0,t.useEffect)(()=>(window.addEventListener("mouseup",y),()=>{window.removeEventListener("mouseup",y)}),[]);let I=u+j,P=c+S;return(0,e.jsxs)("div",{...(0,o.computeBoxProps)({...m,style:{...m.style,height:"100%",overflow:"hidden",position:"relative",width:"100%"}}),children:[(0,e.jsx)("div",{onMouseDown:$,onMouseMove:B,style:{backgroundImage:`url("${i}")`,backgroundPosition:`${I}px ${P}px`,backgroundRepeat:"repeat",backgroundSize:`${b*r}px`,height:"100%",inset:0,position:"absolute",width:"100%"}}),(0,e.jsx)("div",{onMouseDown:$,onMouseMove:B,style:{height:"100%",inset:0,pointerEvents:"none",position:"absolute",transform:`translate(${I}px, ${P}px) scale(${b})`,transformOrigin:"top left",width:"100%"},children:s}),(0,e.jsx)(a,{zoom:b,onZoomClick:function(e){if("increase"===e&&b>=1.5||"decrease"===e&&b<=.5)return;let t=Math.round((b+("increase"===e?.1:-.1))*10)/10;M(t),d?.(t)}})]})}function a(t){let{zoom:o,onZoomClick:r}=t;return(0,e.jsx)("div",{style:{position:"absolute",top:5,left:5,right:5},children:(0,e.jsxs)(s.Stack,{children:[(0,e.jsx)(s.Stack.Item,{children:(0,e.jsx)(n.Button,{icon:"minus",disabled:o<=.5,onClick:()=>r("decrease")})}),(0,e.jsx)(s.Stack.Item,{grow:!0,children:(0,e.jsxs)(i.ProgressBar,{minValue:.5,value:o,maxValue:1.5,children:[o,"x"]})}),(0,e.jsx)(s.Stack.Item,{children:(0,e.jsx)(n.Button,{icon:"plus",disabled:o>=1.5,onClick:()=>r("increase")})})]})})}export{r as InfinitePlane};
1
+ import*as e from"react/jsx-runtime";import*as t from"react";import*as o from"../common/ui.js";import*as n from"./Button.js";import*as i from"./ProgressBar.js";import*as s from"./Stack.js";function r(n){let{backgroundImage:i,children:s,imageWidth:r,initialLeft:u=0,initialTop:c=0,onBackgroundMoved:l,onZoomChange:d,...m}=n,[p,f]=(0,t.useState)(0),[x,h]=(0,t.useState)(0),[j,g]=(0,t.useState)(0),[k,v]=(0,t.useState)(!1),[S,w]=(0,t.useState)(0),[b,M]=(0,t.useState)(1);function $(e){f(e.clientX-j),h(e.clientY-S),v(!0)}function B(e){if(!k)return;let t=e.clientX-p,o=e.clientY-x;l?.(t+u,o+c),g(t),w(o)}function y(){v(!1)}(0,t.useEffect)(()=>(window.addEventListener("mouseup",y),()=>{window.removeEventListener("mouseup",y)}),[]);let I=u+j,P=c+S;return(0,e.jsxs)("div",{...(0,o.computeBoxProps)({...m,style:{...m.style,height:"100%",overflow:"hidden",position:"relative",width:"100%"}}),children:[(0,e.jsx)("div",{onMouseDown:$,onMouseMove:B,style:{backgroundImage:`url("${i}")`,backgroundPosition:`${I}px ${P}px`,backgroundRepeat:"repeat",backgroundSize:`${b*r}px`,height:"100%",inset:0,position:"absolute",width:"100%"}}),(0,e.jsx)("div",{onMouseDown:$,onMouseMove:B,style:{height:"100%",inset:0,position:"absolute",transform:`translate(${I}px, ${P}px) scale(${b})`,transformOrigin:"top left",width:"100%"},children:s}),(0,e.jsx)(a,{zoom:b,onZoomClick:function(e){if("increase"===e&&b>=1.5||"decrease"===e&&b<=.5)return;let t=Math.round((b+("increase"===e?.1:-.1))*10)/10;M(t),d?.(t)}})]})}function a(t){let{zoom:o,onZoomClick:r}=t;return(0,e.jsx)("div",{style:{position:"absolute",top:5,left:5,right:5},children:(0,e.jsxs)(s.Stack,{children:[(0,e.jsx)(s.Stack.Item,{children:(0,e.jsx)(n.Button,{icon:"minus",disabled:o<=.5,onClick:()=>r("decrease")})}),(0,e.jsx)(s.Stack.Item,{grow:!0,children:(0,e.jsxs)(i.ProgressBar,{minValue:.5,value:o,maxValue:1.5,children:[o,"x"]})}),(0,e.jsx)(s.Stack.Item,{children:(0,e.jsx)(n.Button,{icon:"plus",disabled:o>=1.5,onClick:()=>r("increase")})})]})})}export{r as InfinitePlane};
@@ -37,11 +37,12 @@ export type TextInputProps = Partial<{
37
37
  /** Clears the input value on enter */
38
38
  selfClear: boolean;
39
39
  /**
40
- * Generally, input can handle its own state value.
40
+ * Generally, input can handle its own state value. You might not NEED this.
41
41
  *
42
42
  * Use this if you want to hold the value in the parent for external
43
- * manipulation.
43
+ * manipulation. For instance:
44
44
  *
45
+ * ### Clearing the input
45
46
  * ```tsx
46
47
  * const [value, setValue] = useState('');
47
48
  *
@@ -50,13 +51,28 @@ export type TextInputProps = Partial<{
50
51
  * <Button onClick={() => act('inputVal', {inputVal: value})}>
51
52
  * Submit
52
53
  * </Button>
53
- * <Input value={value} onChange={setValue} />
54
+ * <Input
55
+ * value={value}
56
+ * onChange={setValue} />
54
57
  * <Button onClick={() => setValue('')}>
55
58
  * Clear
56
59
  * </Button>
57
60
  * </>
58
61
  * )
59
62
  * ```
63
+ *
64
+ * ### Updating the value from the backend
65
+ * ```tsx
66
+ * const { data } = useBackend<Data>();
67
+ * const { valveSetting } = data;
68
+ *
69
+ * return (
70
+ * <Input
71
+ * value={valveSetting}
72
+ * onEnter={(value) => act('submit', { valveSetting: value })}
73
+ * />
74
+ * )
75
+ * ```
60
76
  */
61
77
  value: string;
62
78
  }> & BaseInputProps;
@@ -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 o from"../common/timer.js";import*as n from"../common/ui.js";let a=(0,o.debounce)(e=>e(),250);function s(o){let{autoFocus:s,autoSelect:c,className:m,disabled:l,expensive:p,fluid:f,maxLength:i,monospace:v,onChange:d,onEnter:g,onEscape:T,placeholder:j,ref:x,selfClear:E,...b}=o,y=(0,t.useRef)(null),I=x??y,[h,k]=(0,t.useState)(o.value),C=(0,t.useMemo)(()=>(0,n.computeBoxProps)(b),[b]),D=(0,t.useMemo)(()=>(0,u.classes)(["Input",l&&"Input--disabled",f&&"Input--fluid",v&&"Input--monospace",m]),[m,f,v]);return(0,t.useEffect)(()=>{let e;return(s||c)&&(e=setTimeout(()=>{I.current?.focus(),c&&I.current?.select()},1)),()=>clearTimeout(e)},[]),(0,t.useEffect)(()=>{document.activeElement!==I.current&&o.value!==h&&k(o.value??"")},[o.value]),(0,e.jsx)("input",{...C,autoComplete:"off",className:D,disabled:l,maxLength:i,onChange:function(e){let t=e.currentTarget.value;k(t),p?a(()=>d?.(t)):d?.(t)},onKeyDown:function(e){if(e.key===r.KEY.Enter){e.preventDefault(),g?.(e.currentTarget.value),E&&k(""),e.currentTarget.blur();return}(0,r.isEscape)(e.key)&&(e.preventDefault(),T?.(e.currentTarget.value),e.currentTarget.blur())},placeholder:j,ref:I,type:"text",value:h,spellCheck:!1})}export{s as Input};
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 o from"../common/timer.js";import*as n from"../common/ui.js";let a=(0,o.debounce)(e=>e(),250);function c(o){let{autoFocus:c,autoSelect:s,className:m,disabled:l,expensive:p,fluid:f,maxLength:i,monospace:d,onChange:g,onEnter:v,onEscape:x,placeholder:T,ref:j,selfClear:E,value:b,...y}=o,I=(0,t.useRef)(null),h=j??I,[k,C]=(0,t.useState)(b);(0,t.useEffect)(()=>{let e;return(c||s)&&(e=setTimeout(()=>{h.current?.focus(),s&&h.current?.select()},1)),()=>clearTimeout(e)},[]),(0,t.useEffect)(()=>{h.current&&document.activeElement!==h.current&&b!==k&&C(b??"")},[b]);let D=(0,n.computeBoxProps)(y),B=(0,u.classes)(["Input",l&&"Input--disabled",f&&"Input--fluid",d&&"Input--monospace",(0,n.computeBoxClassName)(y),m]);return(0,e.jsx)("input",{...D,autoComplete:"off",className:B,disabled:l,maxLength:i,onChange:function(e){let t=e.currentTarget.value;C(t),p?a(()=>g?.(t)):g?.(t)},onKeyDown:function(e){if(e.key===r.KEY.Enter){e.preventDefault(),v?.(e.currentTarget.value),E&&C(""),e.currentTarget.blur();return}(0,r.isEscape)(e.key)&&(e.preventDefault(),x?.(e.currentTarget.value),e.currentTarget.blur())},placeholder:T,ref:h,spellCheck:!1,type:"text",value:k})}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 u from"../common/ui.js";import*as n from"react";import*as o from"../common/keys.js";let s=(0,r.debounce)(e=>e(),250);function a(r){let{allowFloats:a,autoFocus:c,autoSelect:m,className:i,disabled:l,expensive:f,fluid:p,maxValue:d=1e4,minValue:v=0,monospace:y,onChange:E,onEnter:b,onEscape:I,onValidationChange:j,...k}=r,x=(0,n.useRef)(null),[D,R]=(0,n.useState)(r.value??v),[C,K]=(0,n.useState)(!0),M=(0,n.useMemo)(()=>(0,u.computeBoxProps)(k),[k]),g=(0,n.useMemo)(()=>(0,t.classes)(["Input","RestrictedInput",l&&"Input--disabled",p&&"Input--fluid",y&&"Input--monospace",i,!C&&"RestrictedInput--invalid"]),[i,l,p,C,y]);return(0,n.useEffect)(()=>{let e;return(c||m)&&(e=setTimeout(()=>{x.current?.focus(),m&&x.current?.select()},1)),()=>clearTimeout(e)},[]),(0,n.useEffect)(()=>{if(x.current){let e=x.current.validity.valid;C!==e&&(K(e),j?.(e))}},[D]),(0,n.useEffect)(()=>{x.current&&document.activeElement!==x.current&&r.value!==D&&R(r.value??v)},[r.value]),(0,e.jsx)("input",{...M,autoComplete:"off",className:g,disabled:l,max:d,min:v,onChange:function(e){let t=Number(e.target.value);R(t),E&&(f?s(()=>E(t)):E(t))},onKeyDown:function(e){if(e.key===o.KEY.Enter){e.preventDefault(),b?.(D),x.current?.blur();return}if((0,o.isEscape)(e.key)){e.preventDefault(),I?.(D),x.current?.blur();return}if(e.key===o.KEY.Minus){e.preventDefault(),R(-1*D);return}},ref:x,spellCheck:!1,step:a?"any":"1",type:"number",value:D})}export{a as RestrictedInput};
1
+ import*as e from"react/jsx-runtime";import*as t from"../common/react.js";import*as r from"../common/timer.js";import*as u from"../common/ui.js";import*as n from"react";import*as o from"../common/keys.js";let s=(0,r.debounce)(e=>e(),250);function c(r){let{allowFloats:c,autoFocus:m,autoSelect:a,className:i,disabled:l,expensive:f,fluid:p,maxValue:d=1e4,minValue:v=0,monospace:y,onChange:E,onEnter:b,onEscape:I,onValidationChange:j,value:x,...k}=r,C=(0,n.useRef)(null),[D,R]=(0,n.useState)(x??v),[K,N]=(0,n.useState)(!0);function g(e){E&&(f?s(()=>E(e)):E(e))}(0,n.useEffect)(()=>{let e;return(m||a)&&(e=setTimeout(()=>{C.current?.focus(),a&&C.current?.select()},1)),()=>clearTimeout(e)},[]),(0,n.useEffect)(()=>{if(C.current){let e=C.current.validity.valid;K!==e&&(N(e),j?.(e))}},[D]),(0,n.useEffect)(()=>{C.current&&document.activeElement!==C.current&&x!==D&&R(x??v)},[x]);let h=(0,u.computeBoxProps)(k),B=(0,t.classes)(["Input","RestrictedInput",l&&"Input--disabled",p&&"Input--fluid",y&&"Input--monospace",(0,u.computeBoxClassName)(k),i,!K&&"RestrictedInput--invalid"]);return(0,e.jsx)("input",{...h,autoComplete:"off",className:B,disabled:l,max:d,min:v,onChange:function(e){let t=Number(e.target.value);R(t),g(t)},onKeyDown:function(e){if(e.key===o.KEY.Enter){e.preventDefault(),b?.(D),C.current?.blur();return}if((0,o.isEscape)(e.key)){e.preventDefault(),I?.(D),C.current?.blur();return}if(e.key===o.KEY.Minus){e.preventDefault(),R(-1*D),g(D);return}},ref:C,spellCheck:!1,step:c?"any":"1",type:"number",value:D})}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 u from"../common/keys.js";import*as n from"../common/react.js";import*as a from"../common/ui.js";let s=(0,t.debounce)(e=>e(),250);function o(t){let{autoFocus:o,autoSelect:c,disabled:l,dontUseTabForIndent:m,expensive:i,fluid:f,maxLength:p,monospace:g,onChange:T,onEnter:v,onEscape:b,placeholder:y,ref:E,selfClear:d,userMarkup:x,...k}=t,$=(0,r.useRef)(null),h=E??$,[j,K]=(0,r.useState)(t.value??""),D=(0,r.useMemo)(()=>(0,a.computeBoxProps)(k),[k]),I=(0,r.useMemo)(()=>(0,n.classes)(["Input","TextArea",f&&"Input--fluid",g&&"Input--monospace",l&&"Input--disabled"]),[l,f,g]);return(0,r.useEffect)(()=>{(o||c)&&setTimeout(()=>{h.current?.focus(),c&&h.current?.select()},1)},[]),(0,r.useEffect)(()=>{document.activeElement!==h.current&&t.value!==j&&K(t.value??"")},[t.value]),(0,e.jsx)("textarea",{...D,autoComplete:"off",className:I,maxLength:p,onChange:function(e){let t=e.currentTarget.value;K(t),T&&(i?s(()=>T(t)):T(t))},onKeyDown:function(e){if(e.key===u.KEY.Enter&&!e.shiftKey){e.preventDefault(),v?.(e.currentTarget.value),d&&K(""),e.currentTarget.blur();return}if((0,u.isEscape)(e.key)){b?.(e.currentTarget.value),e.currentTarget.blur();return}if(!m&&e.key===u.KEY.Tab){e.preventDefault();let{value:t,selectionStart:r,selectionEnd:u}=e.currentTarget;K(`${t.substring(0,r)} ${t.substring(u)}`),e.currentTarget.selectionEnd=r+1,T?.(e.currentTarget.value);return}if(x&&(e.ctrlKey||e.metaKey)&&x[e.key]){e.preventDefault();let{selectionStart:t,selectionEnd:r,value:u}=e.currentTarget,n=x[e.key];K(`${u.substring(0,t)}${n}${u.substring(t,r)}${n}${u.substring(r)}`),e.currentTarget.selectionEnd=r+2*n.length,T?.(e.currentTarget.value);return}},placeholder:y,ref:h,spellCheck:!1,value:j})}export{o as TextArea};
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 s=(0,t.debounce)(e=>e(),250);function o(t){let{autoFocus:o,autoSelect:c,className:l,disabled:m,dontUseTabForIndent:i,expensive:f,fluid:p,maxLength:g,monospace:T,onChange:b,onEnter:v,onEscape:y,placeholder:x,ref:E,selfClear:d,userMarkup:k,value:$,...h}=t,j=(0,r.useRef)(null),K=E??j,[C,D]=(0,r.useState)($??"");(0,r.useEffect)(()=>{(o||c)&&setTimeout(()=>{K.current?.focus(),c&&K.current?.select()},1)},[]),(0,r.useEffect)(()=>{K.current&&document.activeElement!==K.current&&$!==C&&D($??"")},[$]);let I=(0,a.computeBoxProps)(h),A=(0,u.classes)(["Input","TextArea",p&&"Input--fluid",T&&"Input--monospace",m&&"Input--disabled",(0,a.computeBoxClassName)(h),l]);return(0,e.jsx)("textarea",{...I,autoComplete:"off",className:A,maxLength:g,onChange:function(e){let t=e.currentTarget.value;D(t),b&&(f?s(()=>b(t)):b(t))},onKeyDown:function(e){if(e.key===n.KEY.Enter&&!e.shiftKey){e.preventDefault(),v?.(e.currentTarget.value),d&&D(""),e.currentTarget.blur();return}if((0,n.isEscape)(e.key)){y?.(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;D(`${t.substring(0,r)} ${t.substring(n)}`),e.currentTarget.selectionEnd=r+1,b?.(e.currentTarget.value);return}if(k&&(e.ctrlKey||e.metaKey)&&k[e.key]){e.preventDefault();let{selectionStart:t,selectionEnd:r,value:n}=e.currentTarget,u=k[e.key];D(`${n.substring(0,t)}${u}${n.substring(t,r)}${u}${n.substring(r)}`),e.currentTarget.selectionEnd=r+2*u.length,b?.(e.currentTarget.value);return}},placeholder:x,ref:K,spellCheck:!1,value:C})}export{o as TextArea};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tgui-core",
3
- "version": "3.0.4",
3
+ "version": "3.1.0",
4
4
  "description": "TGUI core component library",
5
5
  "keywords": ["TGUI", "library", "typescript"],
6
6
  "files": ["dist", "styles"],
@@ -62,10 +62,12 @@ $low-contrast-color-map: ("yellow", "white");
62
62
  // Color names for which to generate a color map
63
63
  $color-map-keys: map.keys($_gen_map) !default;
64
64
  @each $color-name in $color-map-keys {
65
- // prettier-ignore
66
- $color-map: map.merge($color-map, (
67
- $color-name: map.get($_gen_map, $color-name),
68
- ));
65
+ $color-map: map.merge(
66
+ $color-map,
67
+ (
68
+ $color-name: map.get($_gen_map, $color-name),
69
+ )
70
+ );
69
71
  }
70
72
 
71
73
  /**
@@ -131,6 +131,18 @@ $bg-map: colors.$color-map !default;
131
131
  border-bottom: none;
132
132
  border-color: inherit;
133
133
  border-radius: var(--border-radius-medium) var(--border-radius-medium) 0 0;
134
+
135
+ &--fallback {
136
+ text-align: center;
137
+ align-content: center;
138
+ color: var(--color-text-translucent);
139
+
140
+ &:before {
141
+ display: table;
142
+ width: 100%;
143
+ zoom: 0.75;
144
+ }
145
+ }
134
146
  }
135
147
 
136
148
  &__content {
@@ -30,23 +30,3 @@
30
30
  .Input--monospace {
31
31
  font-family: var(--input-font-family-mono);
32
32
  }
33
-
34
- .RestrictedInput {
35
- border-color: var(--restricted-input-border-color);
36
- text-align: right;
37
- &:focus-within {
38
- border-color: var(--restricted-input-border-color-focus);
39
- }
40
- &::-webkit-inner-spin-button,
41
- &::-webkit-outer-spin-button {
42
- -webkit-appearance: none;
43
- margin: 0;
44
- }
45
- }
46
-
47
- .RestrictedInput--invalid {
48
- border-color: var(--restricted-input-border-color-invalid);
49
- &:focus-within {
50
- border-color: var(--restricted-input-border-color-invalid);
51
- }
52
- }
@@ -0,0 +1,19 @@
1
+ .RestrictedInput {
2
+ border-color: var(--restricted-input-border-color);
3
+ text-align: right;
4
+ &:focus-within {
5
+ border-color: var(--restricted-input-border-color-focus);
6
+ }
7
+ &::-webkit-inner-spin-button,
8
+ &::-webkit-outer-spin-button {
9
+ -webkit-appearance: none;
10
+ margin: 0;
11
+ }
12
+ }
13
+
14
+ .RestrictedInput--invalid {
15
+ border-color: var(--restricted-input-border-color-invalid);
16
+ &:focus-within {
17
+ border-color: var(--restricted-input-border-color-invalid);
18
+ }
19
+ }
@@ -14,5 +14,4 @@ $border-radius: 0 !default;
14
14
  padding: var(--space-m) var(--space-l);
15
15
  pointer-events: none;
16
16
  text-align: left;
17
- width: max-content;
18
17
  }
package/styles/main.scss CHANGED
@@ -9,6 +9,7 @@
9
9
  @include meta.load-css("./reset.scss");
10
10
 
11
11
  // Components
12
+
12
13
  @include meta.load-css("./components/BlockQuote.scss");
13
14
  @include meta.load-css("./components/Button.scss");
14
15
  @include meta.load-css("./components/ColorBox.scss");
@@ -28,6 +29,7 @@
28
29
  @include meta.load-css("./components/NoticeBox.scss");
29
30
  @include meta.load-css("./components/NumberInput.scss");
30
31
  @include meta.load-css("./components/ProgressBar.scss");
32
+ @include meta.load-css("./components/RestrictedInput.scss");
31
33
  @include meta.load-css("./components/RoundGauge.scss");
32
34
  @include meta.load-css("./components/Section.scss");
33
35
  @include meta.load-css("./components/Slider.scss");
@@ -74,8 +74,11 @@
74
74
  --primary-hue: 210;
75
75
  --primary-saturation: 37.5%;
76
76
  --primary-lightness: 45%;
77
- /* prettier-ignore */
78
- --color-primary: hsl(var(--primary-hue), var(--primary-saturation), var(--primary-lightness));
77
+ --color-primary: hsl(
78
+ var(--primary-hue),
79
+ var(--primary-saturation),
80
+ var(--primary-lightness)
81
+ );
79
82
  --color-good: hsl(95, 62.5%, 40%);
80
83
  --color-average: hsl(32.5, 90%, 50%);
81
84
  --color-bad: hsl(0, 72.5%, 50%);