tgui-core 4.0.4 → 4.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.
Files changed (51) hide show
  1. package/dist/common/constants.d.ts +1 -1
  2. package/dist/common/constants.js +1 -1
  3. package/dist/common/events.js +1 -1
  4. package/dist/common/hotkeys.js +1 -1
  5. package/dist/common/uuid.js +1 -1
  6. package/dist/components/AnimatedNumber.d.ts +2 -42
  7. package/dist/components/AnimatedNumber.js +1 -1
  8. package/dist/components/Button.js +1 -1
  9. package/dist/components/DraggableControl.d.ts +4 -1
  10. package/dist/components/Flex.d.ts +1 -1
  11. package/dist/components/Flex.js +1 -1
  12. package/dist/components/Floating.d.ts +1 -0
  13. package/dist/components/Floating.js +1 -1
  14. package/dist/components/Input.js +1 -1
  15. package/dist/components/Knob.d.ts +4 -4
  16. package/dist/components/Modal.d.ts +2 -3
  17. package/dist/components/NumberInput.d.ts +2 -2
  18. package/dist/components/Slider.d.ts +4 -4
  19. package/dist/components/Slider.js +1 -1
  20. package/dist/components/Tabs.js +1 -1
  21. package/package.json +3 -3
  22. package/styles/atomic/candystripe.scss +8 -0
  23. package/styles/atomic/centered-image.scss +7 -0
  24. package/styles/atomic/color.scss +17 -0
  25. package/styles/atomic/debug-layout.scss +12 -0
  26. package/styles/atomic/fit-text.scss +15 -0
  27. package/styles/atomic/links.scss +21 -0
  28. package/styles/atomic/outline.scss +43 -0
  29. package/styles/atomic/text.scss +39 -0
  30. package/styles/atomic.scss +11 -0
  31. package/styles/components/BlockQuote.scss +0 -2
  32. package/styles/components/Button.scss +83 -85
  33. package/styles/components/Dimmer.scss +0 -2
  34. package/styles/components/Divider.scss +0 -5
  35. package/styles/components/Dropdown.scss +2 -0
  36. package/styles/components/ImageButton.scss +104 -102
  37. package/styles/components/Input.scss +3 -0
  38. package/styles/components/Knob.scss +5 -21
  39. package/styles/components/LabeledList.scss +0 -2
  40. package/styles/components/NoticeBox.scss +15 -21
  41. package/styles/components/NumberInput.scss +1 -9
  42. package/styles/components/ProgressBar.scss +27 -48
  43. package/styles/components/RestrictedInput.scss +3 -0
  44. package/styles/components/RoundGauge.scss +8 -13
  45. package/styles/components/Section.scss +0 -7
  46. package/styles/components/Slider.scss +49 -42
  47. package/styles/components/Tabs.scss +1 -12
  48. package/styles/components/TextArea.scss +3 -0
  49. package/styles/components/Tooltip.scss +0 -4
  50. package/styles/main.scss +0 -1
  51. package/styles/vars-components.scss +5 -2
@@ -101,6 +101,6 @@ export declare function getGasFromId(gasId: string): Gas | undefined;
101
101
  export declare function getGasFromPath(gasPath: string): Gas | undefined;
102
102
  export declare const COMPONENT_COLORS: {
103
103
  readonly spectrum: readonly ["red", "orange", "yellow", "olive", "green", "teal", "blue", "violet", "purple", "pink", "brown", "grey", "gold"];
104
- readonly states: readonly ["", "good", "average", "bad", "black", "white"];
104
+ readonly states: readonly ["default", "good", "average", "bad", "black", "white", "transparent"];
105
105
  };
106
106
  export {};
@@ -1 +1 @@
1
- let e=2,a=1,o=0,r=-1,l={damageType:{brute:"#e74c3c",burn:"#e67e22",oxy:"#3498db",toxin:"#2ecc71"},department:{captain:"#c06616",cargo:"#f39c12",centcom:"#00c100",engineering:"#f1c40f",medbay:"#3498db",other:"#c38312",science:"#9b59b6",security:"#e74c3c",service:"#7cc46a"},reagent:{acidicbuffer:"#fbc314",basicbuffer:"#3853a4"}},t=["average","bad","black","blue","brown","good","green","grey","label","olive","orange","pink","purple","red","teal","transparent","violet","white","yellow"],i=[{color:"#8f4a4b",freq:1213,name:"Syndicate"},{color:"#ff4444",freq:1215,name:"Red Team"},{color:"#3434fd",freq:1217,name:"Blue Team"},{color:"#34fd34",freq:1219,name:"Green Team"},{color:"#fdfd34",freq:1221,name:"Yellow Team"},{color:"#2681a5",freq:1337,name:"CentCom"},{color:"#b88646",freq:1347,name:"Supply"},{color:"#6ca729",freq:1349,name:"Service"},{color:"#c68cfa",freq:1351,name:"Science"},{color:"#fcdf03",freq:1353,name:"Command"},{color:"#57b8f0",freq:1355,name:"Medical"},{color:"#f37746",freq:1357,name:"Engineering"},{color:"#dd3535",freq:1359,name:"Security"},{color:"#d65d95",freq:1447,name:"AI Private"},{color:"#1ecc43",freq:1459,name:"Common"}],n=[{color:"blue",id:"o2",label:"O₂",name:"Oxygen",path:"/datum/gas/oxygen"},{color:"yellow",id:"n2",label:"N₂",name:"Nitrogen",path:"/datum/gas/nitrogen"},{color:"grey",id:"co2",label:"CO₂",name:"Carbon Dioxide",path:"/datum/gas/carbon_dioxide"},{color:"pink",id:"plasma",label:"Plasma",name:"Plasma",path:"/datum/gas/plasma"},{color:"lightsteelblue",id:"water_vapor",label:"H₂O",name:"Water Vapor",path:"/datum/gas/water_vapor"},{color:"teal",id:"hypernoblium",label:"Hyper-nob",name:"Hyper-noblium",path:"/datum/gas/hypernoblium"},{color:"bisque",id:"n2o",label:"N₂O",name:"Nitrous Oxide",path:"/datum/gas/nitrous_oxide"},{color:"brown",id:"no2",label:"Nitrium",name:"Nitrium",path:"/datum/gas/nitrium"},{color:"limegreen",id:"tritium",label:"Tritium",name:"Tritium",path:"/datum/gas/tritium"},{color:"mediumpurple",id:"bz",label:"BZ",name:"BZ",path:"/datum/gas/bz"},{color:"mediumslateblue",id:"pluoxium",label:"Pluoxium",name:"Pluoxium",path:"/datum/gas/pluoxium"},{color:"olive",id:"miasma",label:"Miasma",name:"Miasma",path:"/datum/gas/miasma"},{color:"paleturquoise",id:"freon",label:"Freon",name:"Freon",path:"/datum/gas/freon"},{color:"white",id:"hydrogen",label:"H₂",name:"Hydrogen",path:"/datum/gas/hydrogen"},{color:"salmon",id:"healium",label:"Healium",name:"Healium",path:"/datum/gas/healium"},{color:"greenyellow",id:"proto_nitrate",label:"Proto-Nitrate",name:"Proto Nitrate",path:"/datum/gas/proto_nitrate"},{color:"darkgreen",id:"zauker",label:"Zauker",name:"Zauker",path:"/datum/gas/zauker"},{color:"purple",id:"halon",label:"Halon",name:"Halon",path:"/datum/gas/halon"},{color:"aliceblue",id:"helium",label:"He",name:"Helium",path:"/datum/gas/helium"},{color:"maroon",id:"antinoblium",label:"Anti-Noblium",name:"Antinoblium",path:"/datum/gas/antinoblium"},{color:"brown",id:"nitrium",label:"Nitrium",name:"Nitrium",path:"/datum/gas/nitrium"}];function m(e,a){if(!e)return a||"None";let o=e.toLowerCase();for(let e=0;e<n.length;e++)if(n[e].id===o)return n[e].label;return a||"None"}function u(e){if(!e)return"black";let a=e.toLowerCase();for(let e=0;e<n.length;e++)if(n[e].id===a)return n[e].color;return"black"}function c(e){if(!e)return;let a=e.toLowerCase();for(let e=0;e<n.length;e++)if(n[e].id===a)return n[e]}function d(e){if(e){for(let a=0;a<n.length;a++)if(n[a].path===e)return n[a]}}let b={spectrum:["red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey","gold"],states:["","good","average","bad","black","white"]};export{l as COLORS,b as COMPONENT_COLORS,t as CSS_COLORS,i as RADIO_CHANNELS,r as UI_CLOSE,o as UI_DISABLED,e as UI_INTERACTIVE,a as UI_UPDATE,u as getGasColor,c as getGasFromId,d as getGasFromPath,m as getGasLabel};
1
+ let e=2,a=1,o=0,r=-1,l={damageType:{brute:"#e74c3c",burn:"#e67e22",oxy:"#3498db",toxin:"#2ecc71"},department:{captain:"#c06616",cargo:"#f39c12",centcom:"#00c100",engineering:"#f1c40f",medbay:"#3498db",other:"#c38312",science:"#9b59b6",security:"#e74c3c",service:"#7cc46a"},reagent:{acidicbuffer:"#fbc314",basicbuffer:"#3853a4"}},t=["average","bad","black","blue","brown","good","green","grey","label","olive","orange","pink","purple","red","teal","transparent","violet","white","yellow"],n=[{color:"#8f4a4b",freq:1213,name:"Syndicate"},{color:"#ff4444",freq:1215,name:"Red Team"},{color:"#3434fd",freq:1217,name:"Blue Team"},{color:"#34fd34",freq:1219,name:"Green Team"},{color:"#fdfd34",freq:1221,name:"Yellow Team"},{color:"#2681a5",freq:1337,name:"CentCom"},{color:"#b88646",freq:1347,name:"Supply"},{color:"#6ca729",freq:1349,name:"Service"},{color:"#c68cfa",freq:1351,name:"Science"},{color:"#fcdf03",freq:1353,name:"Command"},{color:"#57b8f0",freq:1355,name:"Medical"},{color:"#f37746",freq:1357,name:"Engineering"},{color:"#dd3535",freq:1359,name:"Security"},{color:"#d65d95",freq:1447,name:"AI Private"},{color:"#1ecc43",freq:1459,name:"Common"}],i=[{color:"blue",id:"o2",label:"O₂",name:"Oxygen",path:"/datum/gas/oxygen"},{color:"yellow",id:"n2",label:"N₂",name:"Nitrogen",path:"/datum/gas/nitrogen"},{color:"grey",id:"co2",label:"CO₂",name:"Carbon Dioxide",path:"/datum/gas/carbon_dioxide"},{color:"pink",id:"plasma",label:"Plasma",name:"Plasma",path:"/datum/gas/plasma"},{color:"lightsteelblue",id:"water_vapor",label:"H₂O",name:"Water Vapor",path:"/datum/gas/water_vapor"},{color:"teal",id:"hypernoblium",label:"Hyper-nob",name:"Hyper-noblium",path:"/datum/gas/hypernoblium"},{color:"bisque",id:"n2o",label:"N₂O",name:"Nitrous Oxide",path:"/datum/gas/nitrous_oxide"},{color:"brown",id:"no2",label:"Nitrium",name:"Nitrium",path:"/datum/gas/nitrium"},{color:"limegreen",id:"tritium",label:"Tritium",name:"Tritium",path:"/datum/gas/tritium"},{color:"mediumpurple",id:"bz",label:"BZ",name:"BZ",path:"/datum/gas/bz"},{color:"mediumslateblue",id:"pluoxium",label:"Pluoxium",name:"Pluoxium",path:"/datum/gas/pluoxium"},{color:"olive",id:"miasma",label:"Miasma",name:"Miasma",path:"/datum/gas/miasma"},{color:"paleturquoise",id:"freon",label:"Freon",name:"Freon",path:"/datum/gas/freon"},{color:"white",id:"hydrogen",label:"H₂",name:"Hydrogen",path:"/datum/gas/hydrogen"},{color:"salmon",id:"healium",label:"Healium",name:"Healium",path:"/datum/gas/healium"},{color:"greenyellow",id:"proto_nitrate",label:"Proto-Nitrate",name:"Proto Nitrate",path:"/datum/gas/proto_nitrate"},{color:"darkgreen",id:"zauker",label:"Zauker",name:"Zauker",path:"/datum/gas/zauker"},{color:"purple",id:"halon",label:"Halon",name:"Halon",path:"/datum/gas/halon"},{color:"aliceblue",id:"helium",label:"He",name:"Helium",path:"/datum/gas/helium"},{color:"maroon",id:"antinoblium",label:"Anti-Noblium",name:"Antinoblium",path:"/datum/gas/antinoblium"},{color:"brown",id:"nitrium",label:"Nitrium",name:"Nitrium",path:"/datum/gas/nitrium"}];function m(e,a){if(!e)return a||"None";let o=e.toLowerCase();for(let e=0;e<i.length;e++)if(i[e].id===o)return i[e].label;return a||"None"}function u(e){if(!e)return"black";let a=e.toLowerCase();for(let e=0;e<i.length;e++)if(i[e].id===a)return i[e].color;return"black"}function c(e){if(!e)return;let a=e.toLowerCase();for(let e=0;e<i.length;e++)if(i[e].id===a)return i[e]}function d(e){if(e){for(let a=0;a<i.length;a++)if(i[a].path===e)return i[a]}}let b={spectrum:["red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey","gold"],states:["default","good","average","bad","black","white","transparent"]};export{l as COLORS,b as COMPONENT_COLORS,t as CSS_COLORS,n as RADIO_CHANNELS,r as UI_CLOSE,o as UI_DISABLED,e as UI_INTERACTIVE,a as UI_UPDATE,u as getGasColor,c as getGasFromId,d as getGasFromPath,m as getGasLabel};
@@ -1 +1 @@
1
- let t;import{KEY_ALT as e,KEY_CTRL as i,KEY_F1 as s,KEY_F12 as r,KEY_SHIFT as n}from"./keycodes.js";class o{listeners;constructor(){this.listeners={}}on(t,e){this.listeners[t]=this.listeners[t]||[],this.listeners[t].push(e)}off(t,e){let i=this.listeners[t];if(!i)throw Error(`There is no listeners for "${t}"`);this.listeners[t]=i.filter(t=>t!==e)}emit(t,...e){let i=this.listeners[t];if(i)for(let t=0,s=i.length;t<s;t+=1)(0,i[t])(...e)}clear(){this.listeners={}}}let l=new o,d=!1,u=(t={})=>{d=!!t.ignoreWindowFocus},h=!0;function c(e,i){if(d){h=!0;return}if(t&&(clearTimeout(t),t=null),i){t=setTimeout(()=>c(e));return}h!==e&&(h=e,l.emit(e?"window-focus":"window-blur"),l.emit("window-focus-change",e))}let a=null;function f(t){let e=String(t.tagName).toLowerCase();return"input"===e||"textarea"===e}function w(){a&&(a.removeEventListener("blur",w),a=null)}let y=null,m=null,p=[];function v(t){p.push(t)}function E(t){let e=p.indexOf(t);e>=0&&p.splice(e,1)}window.addEventListener("mousemove",t=>{let e=t.target;e!==m&&(m=e,function(t){if(a||!h)return;let e=document.body;for(;t&&t!==e;){if(p.includes(t)){if(t.contains(y))return;y=t,t.focus();return}t=t.parentElement}}(e))}),window.addEventListener("focusin",t=>{var e;m=null,y=t.target,c(!0),f(t.target)&&(e=t.target,w(),(a=e).addEventListener("blur",w))}),window.addEventListener("focusout",()=>{m=null,c(!1,!0)}),window.addEventListener("blur",()=>{m=null,c(!1,!0)}),window.addEventListener("beforeunload",()=>{c(!1)});let g={};class k{event;type;code;ctrl;shift;alt;repeat;_str;constructor(t,e,i){this.event=t,this.type=e,this.code=t.keyCode,this.ctrl=t.ctrlKey,this.shift=t.shiftKey,this.alt=t.altKey,this.repeat=!!i}hasModifierKeys(){return this.ctrl||this.alt||this.shift}isModifierKey(){return this.code===i||this.code===n||this.code===e}isDown(){return"keydown"===this.type}isUp(){return"keyup"===this.type}toString(){return this._str||(this._str="",this.ctrl&&(this._str+="Ctrl+"),this.alt&&(this._str+="Alt+"),this.shift&&(this._str+="Shift+"),this.code>=48&&this.code<=90?this._str+=String.fromCharCode(this.code):this.code>=s&&this.code<=r?this._str+=`F${this.code-111}`:this._str+=`[${this.code}]`),this._str}}document.addEventListener("keydown",t=>{if(f(t.target))return;let e=t.keyCode,i=new k(t,"keydown",g[e]);l.emit("keydown",i),l.emit("key",i),g[e]=!0}),document.addEventListener("keyup",t=>{if(f(t.target))return;let e=t.keyCode,i=new k(t,"keyup");l.emit("keyup",i),l.emit("key",i),g[e]=!1});export{o as EventEmitter,k as KeyEvent,v as addScrollableNode,f as canStealFocus,l as globalEvents,E as removeScrollableNode,u as setupGlobalEvents};
1
+ let t;import{KEY_ALT as e,KEY_CTRL as i,KEY_F1 as s,KEY_F12 as n,KEY_SHIFT as r}from"./keycodes.js";class o{listeners;constructor(){this.listeners={}}on(t,e){this.listeners[t]=this.listeners[t]||[],this.listeners[t].push(e)}off(t,e){let i=this.listeners[t];if(!i)throw Error(`There is no listeners for "${t}"`);this.listeners[t]=i.filter(t=>t!==e)}emit(t,...e){let i=this.listeners[t];if(i)for(let t=0,s=i.length;t<s;t+=1)(0,i[t])(...e)}clear(){this.listeners={}}}let l=new o,u=!1,d=(t={})=>{u=!!t.ignoreWindowFocus},h=!0;function c(e,i){if(u){h=!0;return}if(t&&(clearTimeout(t),t=null),i){t=setTimeout(()=>c(e));return}h!==e&&(h=e,l.emit(e?"window-focus":"window-blur"),l.emit("window-focus-change",e))}let a=null;function f(t){let e=String(t.tagName).toLowerCase();return"input"===e||"textarea"===e}function m(){a&&(a.removeEventListener("blur",m),a=null,l.emit("input-blur"))}let w=null,y=null,p=[];function v(t){p.push(t)}function E(t){let e=p.indexOf(t);e>=0&&p.splice(e,1)}window.addEventListener("mousemove",t=>{let e=t.target;e!==y&&(y=e,function(t){if(a||!h)return;let e=document.body;for(;t&&t!==e;){if(p.includes(t)){if(t.contains(w))return;w=t,t.focus();return}t=t.parentElement}}(e))}),document.addEventListener("focus",t=>{var e;if(!(t.target instanceof Element)){y=null,w=null;return}y=null,w=t.target,f(t.target)&&(e=t.target,m(),(a=e).addEventListener("blur",m),l.emit("input-focus"))},!0),document.addEventListener("blur",()=>{y=null},!0),window.addEventListener("focus",()=>{c(!0)}),window.addEventListener("blur",()=>{y=null,c(!1,!0)}),window.addEventListener("close",()=>{c(!1)});let g={};class k{event;type;code;ctrl;shift;alt;repeat;_str;constructor(t,e,i){this.event=t,this.type=e,this.code=t.keyCode,this.ctrl=t.ctrlKey,this.shift=t.shiftKey,this.alt=t.altKey,this.repeat=!!i}hasModifierKeys(){return this.ctrl||this.alt||this.shift}isModifierKey(){return this.code===i||this.code===r||this.code===e}isDown(){return"keydown"===this.type}isUp(){return"keyup"===this.type}toString(){return this._str||(this._str="",this.ctrl&&(this._str+="Ctrl+"),this.alt&&(this._str+="Alt+"),this.shift&&(this._str+="Shift+"),this.code>=48&&this.code<=90?this._str+=String.fromCharCode(this.code):this.code>=s&&this.code<=n?this._str+=`F${this.code-111}`:this._str+=`[${this.code}]`),this._str}}document.addEventListener("keydown",t=>{if(f(t.target))return;let e=t.keyCode,i=new k(t,"keydown",g[e]);l.emit("keydown",i),l.emit("key",i),g[e]=!0}),document.addEventListener("keyup",t=>{if(f(t.target))return;let e=t.keyCode,i=new k(t,"keyup");l.emit("keyup",i),l.emit("key",i),g[e]=!1});export{o as EventEmitter,k as KeyEvent,v as addScrollableNode,f as canStealFocus,l as globalEvents,E as removeScrollableNode,d as setupGlobalEvents};
@@ -1 +1 @@
1
- import{globalEvents as e}from"./events.js";import{KEY_CTRL as t,KEY_DOWN as n,KEY_ENTER as r,KEY_ESCAPE as o,KEY_F5 as i,KEY_LEFT as s,KEY_RIGHT as l,KEY_SHIFT as f,KEY_SPACE as u,KEY_TAB as a,KEY_UP as d}from"./keycodes.js";let c={},y=[o,r,u,a,t,f,d,n,s,l,i],m={},p=[];function h(e){y.push(e)}function b(e){let t=y.indexOf(e);t>=0&&y.splice(t,1)}function v(){for(let e in m)m[e]&&(m[e]=!1,Byond.command(K.verbParamsFn(K.keyUpVerb,e)))}let K={keyDownVerb:"KeyDown",keyUpVerb:"KeyUp",verbParamsFn:(e,t)=>`${e} "${t}"`};function w(t){t&&(K=t),Byond.winget("default.*").then(e=>{let t={};for(let n in e){let r=n.split("."),o=r[1],i=r[2];o&&i&&(t[o]||(t[o]={}),t[o][i]=e[n])}let n=/\\"/g;function r(e){return e.substring(1,e.length-1).replace(n,'"')}for(let e in t){let n=t[e];c[r(n.name)]=r(n.command)}}),e.on("window-blur",()=>{v()}),g()}function g(){e.on("key",F)}function k(){e.off("key",F)}function F(e){for(let t of p)t(e);!function(e){var t;let n=String(e);if("Ctrl+F5"===n||"Ctrl+R"===n)return location.reload();if("Ctrl+F"===n||e.event.defaultPrevented||e.isModifierKey()||y.includes(e.code))return;let r=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(!r)return;let o=c[r];if(o)return Byond.command(o);if(e.isDown()&&!m[r]){m[r]=!0;let e=K.verbParamsFn(K.keyDownVerb,r);return Byond.command(e)}if(e.isUp()&&m[r]){m[r]=!1;let e=K.verbParamsFn(K.keyUpVerb,r);Byond.command(e)}}(e)}function P(e){p.push(e);let t=!1;return()=>{t||(t=!0,p.splice(p.indexOf(e),1))}}export{h as acquireHotKey,P as listenForKeyEvents,v as releaseHeldKeys,b as releaseHotKey,w as setupHotKeys,g as startKeyPassthrough,k as stopKeyPassthrough};
1
+ import{globalEvents as e}from"./events.js";import{KEY_CTRL as t,KEY_DOWN as n,KEY_ENTER as o,KEY_ESCAPE as r,KEY_F5 as i,KEY_LEFT as s,KEY_RIGHT as l,KEY_SHIFT as u,KEY_SPACE as f,KEY_TAB as a,KEY_UP as d}from"./keycodes.js";let c={},y=[r,o,f,a,t,u,d,n,s,l,i],m={},p=[];function h(e){y.push(e)}function b(e){let t=y.indexOf(e);t>=0&&y.splice(t,1)}function v(){for(let e in m)m[e]&&(m[e]=!1,Byond.command(K.verbParamsFn(K.keyUpVerb,e)))}let K={keyDownVerb:"KeyDown",keyUpVerb:"KeyUp",verbParamsFn:(e,t)=>`${e} "${t}"`};function w(t){t&&(K=t),Byond.winget("default.*").then(e=>{let t={};for(let n in e){let o=n.split("."),r=o[1],i=o[2];r&&i&&(t[r]||(t[r]={}),t[r][i]=e[n])}let n=/\\"/g;function o(e){return e.substring(1,e.length-1).replace(n,'"')}for(let e in t){let n=t[e];c[o(n.name)]=o(n.command)}}),e.on("window-blur",()=>{v()}),e.on("input-focus",()=>{v()}),g()}function g(){e.on("key",F)}function k(){e.off("key",F)}function F(e){for(let t of p)t(e);!function(e){var t;let n=String(e);if("Ctrl+F5"===n||"Ctrl+R"===n)return location.reload();if("Ctrl+F"===n||e.event.defaultPrevented||e.isModifierKey()||y.includes(e.code))return;let o=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(!o)return;let r=c[o];if(r)return Byond.command(r);if(e.isDown()&&!m[o]){m[o]=!0;let e=K.verbParamsFn(K.keyDownVerb,o);return Byond.command(e)}if(e.isUp()&&m[o]){m[o]=!1;let e=K.verbParamsFn(K.keyUpVerb,o);Byond.command(e)}}(e)}function P(e){p.push(e);let t=!1;return()=>{t||(t=!0,p.splice(p.indexOf(e),1))}}export{h as acquireHotKey,P as listenForKeyEvents,v as releaseHeldKeys,b as releaseHotKey,w as setupHotKeys,g as startKeyPassthrough,k as stopKeyPassthrough};
@@ -1 +1 @@
1
- function x(){let x=new Date().getTime();return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=(x+16*Math.random())%16|0;return x=Math.floor(x/16),("x"===e?t:3&t|8).toString(16)})}export{x as createUuid};
1
+ function x(){let x=Date.now();return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{let e=(x+16*Math.random())%16|0;return x=Math.floor(x/16),("x"===t?e:3&e|8).toString(16)})}export{x as createUuid};
@@ -1,8 +1,5 @@
1
- import { Component } from 'react';
2
1
  type Props = {
3
- /**
4
- * The target value to approach.
5
- */
2
+ /** The target value to approach. */
6
3
  value: number;
7
4
  } & Partial<{
8
5
  /**
@@ -22,43 +19,6 @@ type Props = {
22
19
  *
23
20
  * An animated number label. Shows a number, formatted with an optionally
24
21
  * provided function, and animates it towards its target value.
25
- *
26
- * - [View documentation on tgui core](https://tgstation.github.io/tgui-core/?path=/docs/components-animatednumber--docs)
27
22
  */
28
- export declare class AnimatedNumber extends Component<Props> {
29
- /**
30
- * The inner `<span/>` being updated sixty times per second.
31
- */
32
- ref: import("react").RefObject<HTMLSpanElement | null>;
33
- /**
34
- * The interval being used to update the inner span.
35
- */
36
- interval?: NodeJS.Timeout;
37
- /**
38
- * The current value. This values approaches the target value.
39
- */
40
- currentValue: number;
41
- constructor(props: Props);
42
- componentDidMount(): void;
43
- componentWillUnmount(): void;
44
- shouldComponentUpdate(newProps: Props): boolean;
45
- /**
46
- * Starts animating the inner span. If the inner span is already animating,
47
- * this is a no-op.
48
- */
49
- startTicking(): void;
50
- /**
51
- * Stops animating the inner span.
52
- */
53
- stopTicking(): void;
54
- /**
55
- * Steps forward one frame.
56
- */
57
- tick(): void;
58
- /**
59
- * Gets the inner text of the span.
60
- */
61
- getText(): string;
62
- render(): import("react/jsx-runtime").JSX.Element;
63
- }
23
+ export declare function AnimatedNumber(props: Props): import("react/jsx-runtime").JSX.Element;
64
24
  export {};
@@ -1 +1 @@
1
- import{jsx as t}from"react/jsx-runtime";import{clamp as e,isSafeNumber as r,toFixed as i}from"../common/math.js";import{Component as n,createRef as s}from"react";let a=1e3/60;class h extends n{ref=s();interval;currentValue=0;constructor(t){super(t);let{initial:e,value:i}=t;void 0!==e&&r(e)?this.currentValue=e:r(i)&&(this.currentValue=i)}componentDidMount(){this.currentValue!==this.props.value&&this.startTicking()}componentWillUnmount(){this.stopTicking()}shouldComponentUpdate(t){return t.value!==this.props.value&&this.startTicking(),!1}startTicking(){void 0===this.interval&&(this.interval=setInterval(()=>this.tick(),a))}stopTicking(){void 0!==this.interval&&(clearInterval(this.interval),this.interval=void 0)}tick(){let{currentValue:t}=this,{value:e}=this.props;r(e)?this.currentValue=.8333*t+.16669999999999996*e:this.stopTicking(),Math.abs(e-this.currentValue)<Math.max(.001,.001*e)&&(this.currentValue=e,this.stopTicking()),this.ref.current&&(this.ref.current.textContent=this.getText())}getText(){let{props:t,currentValue:n}=this,{format:s,value:a}=t;if(!r(a))return String(a);if(s)return s(this.currentValue);let h=String(a).split(".")[1];return i(n,e(h?h.length:0,0,8))}render(){return t("span",{ref:this.ref,children:this.getText()})}}export{h as AnimatedNumber};
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 u,useRef as l,useState as i}from"react";let o=1e3/60;function c(c){let{format:m,initial:a,value:f}=c,p=l(null),[s,h]=i(void 0!==a&&n(a)?a:n(f)?f:0);function d(){null!==p.current&&(clearInterval(p.current),p.current=null)}function v(){if(!n(f))return void d();h(r=>{let t=.8333*r+.16669999999999996*f;return Math.abs(f-t)<Math.max(.001,.001*f)?(d(),f):t})}return u(()=>{s!==f&&null===p.current&&(p.current=setInterval(v,o))},[f]),u(()=>()=>d(),[]),r("span",{children:n(f)?m?m(s):function(){let r=String(f).split(".")[1];return e(s,t(r?r.length:0,0,8))}():String(f)})}export{c as AnimatedNumber};
@@ -1 +1 @@
1
- var t;import{Fragment as n,jsx as e,jsxs as o}from"react/jsx-runtime";import{KEY as r,isEscape as i}from"../common/keys.js";import{classes as u}from"../common/react.js";import{computeBoxClassName as l,computeBoxProps as c}from"../common/ui.js";import{createRef as a,useEffect as s,useRef as f,useState as m}from"react";import{Box as p}from"./Box.js";import{Icon as d}from"./Icon.js";import{Tooltip as B}from"./Tooltip.js";function h(t){let{captureKeys:n=!0,children:a,circular:s,className:f,color:m,compact:p,content:h,disabled:y,ellipsis:k,fluid:g,icon:v,iconColor:x,iconPosition:C,iconRotation:b,iconSize:j,iconSpin:N,onClick:_,selected:w,tooltip:D,tooltipPosition:T,verticalAlignContent:A,...I}=t,$=h||a,q=e(d,{className:"Button--icon",color:x,name:v||"",rotation:b,size:j,spin:N}),E=e("div",{className:u(["Button",g&&"Button--fluid",y&&"Button--disabled",w&&"Button--selected",s&&"Button--circular",p&&"Button--compact",!$&&"Button--empty",C&&`Button--icon-${C}`,A&&"Button--flex",A&&g&&"Button--flex--fluid",A&&`Button--verticalAlignContent--${A}`,m&&"string"==typeof m?`Button--color--${m}`:"Button--color--default",f,l(I)]),onClick:t=>{!y&&_&&_(t)},onKeyDown:t=>{if(n){if(t.key===r.Space||t.key===r.Enter){t.preventDefault(),!y&&_&&_(t);return}i(t.key)&&t.preventDefault()}},tabIndex:y?void 0:0,...c(I),children:o("div",{className:u(["Button__content",k&&"Button__content--ellipsis"]),children:[v&&"right"!==C&&q,k?e("span",{className:"Button--ellipsis",children:$}):$,v&&"right"===C&&q]})});return D&&(E=e(B,{content:D,position:T,children:E})),E}(t=h||(h={})).Checkbox=function(t){let{checked:n,...o}=t;return e(h,{color:"transparent",icon:n?"check-square-o":"square-o",selected:n,...o})},t.Confirm=function(t){let{children:n,color:o,confirmColor:r="bad",confirmContent:i="Confirm?",confirmIcon:u,ellipsis:l=!0,icon:c,onBlur:a,onClick:s,...f}=t,[p,d]=m(!1);return e(h,{color:p?r:o,icon:p?u:c,onBlur:function(t){d(!1),a?.(t)},onClick:function(t){if(!p)return void d(!0);s?.(t),d(!1)},...f,children:p?i:n})},t.Input=function(t){let{buttonText:n,children:l,color:c="default",disabled:B,fluid:h,icon:y,iconRotation:k,iconSpin:g,maxLength:v,onCommit:x,ref:C,value:b="",...j}=t,[N,_]=m(b),[w,D]=m(!1),T=f(!1),A=a(),I=C??A;return s(()=>{w&&(I.current?.focus(),I.current?.select())},[w]),s(()=>{w||b===N||_(b)},[w,b]),o(p,{className:u(["Button",h&&"Button--fluid",B&&"Button--disabled",`Button--color--${c}`]),onClick:()=>D(!0),...j,children:[y&&e(d,{name:y,rotation:k,spin:g}),n??N,e("input",{className:"NumberInput__input",disabled:!!B,maxLength:v,onBlur:function(){T.current||b===N||(x?.(N),T.current=!1),D(!1)},onChange:function(t){_(t.currentTarget.value)},onKeyDown:function(t){if(t.key===r.Enter){t.preventDefault(),t.currentTarget.blur();return}if(i(t.key)){t.preventDefault(),T.current=!0,t.currentTarget.blur();return}},ref:I,spellCheck:"false",style:{display:w?"":"none",textAlign:"left"},type:"text",value:N})]})},t.File=function(t){let{accept:r,multiple:i,onSelectFiles:u,...l}=t,c=f(null);async function a(t){let n=Array.from(t).map(t=>{let n=new FileReader;return new Promise(e=>{n.onload=()=>e(n.result),n.readAsText(t)})});return await Promise.all(n)}async function s(t){let n=t.target.files;if(n?.length){let t=await a(n);u(i?t:t[0])}}return o(n,{children:[e(h,{onClick:()=>c.current?.click(),...l}),e("input",{accept:r,hidden:!0,multiple:i,onChange:s,ref:c,type:"file"})]})};export{h as Button};
1
+ var t;import{Fragment as n,jsx as e,jsxs as o}from"react/jsx-runtime";import{KEY as r,isEscape as i}from"../common/keys.js";import{classes as u}from"../common/react.js";import{computeBoxClassName as l,computeBoxProps as c}from"../common/ui.js";import{createRef as a,useEffect as s,useRef as f,useState as m}from"react";import{Box as p}from"./Box.js";import{Icon as d}from"./Icon.js";import{Tooltip as B}from"./Tooltip.js";function h(t){let{captureKeys:n=!0,children:a,circular:s,className:f,color:m="default",compact:p,content:h,disabled:y,ellipsis:k,fluid:g,icon:v,iconColor:x,iconPosition:C,iconRotation:b,iconSize:j,iconSpin:N,onClick:_,selected:w,tooltip:D,tooltipPosition:I,verticalAlignContent:T,...A}=t,$=h||a,q=e(d,{className:"Button--icon",color:x,name:v||"",rotation:b,size:j,spin:N}),E=e("div",{className:u(["Button",g&&"Button--fluid",y&&"Button--disabled",w&&"Button--selected",s&&"Button--circular",p&&"Button--compact",!$&&"Button--empty",v&&"Button--hasIcon",C&&`Button--icon-${C}`,T&&"Button--flex",T&&g&&"Button--flex--fluid",T&&`Button--verticalAlignContent--${T}`,m&&"string"==typeof m&&`Button--color--${m}`,f,l(A)]),onClick:t=>{!y&&_&&_(t)},onKeyDown:t=>{if(n){if(t.key===r.Space||t.key===r.Enter){t.preventDefault(),!y&&_&&_(t);return}i(t.key)&&t.preventDefault()}},tabIndex:y?void 0:0,...c(A),children:o("div",{className:u(["Button__content",k&&"Button__content--ellipsis"]),children:[v&&"right"!==C&&q,k?e("span",{className:"Button--ellipsis",children:$}):$,v&&"right"===C&&q]})});return D&&(E=e(B,{content:D,position:I,children:E})),E}(t=h||(h={})).Checkbox=function(t){let{checked:n,...o}=t;return e(h,{color:"transparent",icon:n?"check-square-o":"square-o",selected:n,...o})},t.Confirm=function(t){let{children:n,color:o,confirmColor:r="bad",confirmContent:i="Confirm?",confirmIcon:u,ellipsis:l=!0,icon:c,onBlur:a,onClick:s,...f}=t,[p,d]=m(!1);return e(h,{color:p?r:o,icon:p?u:c,onBlur:function(t){d(!1),a?.(t)},onClick:function(t){if(!p)return void d(!0);s?.(t),d(!1)},...f,children:p?i:n})},t.Input=function(t){let{buttonText:n,children:l,color:c="default",disabled:B,fluid:h,icon:y,iconRotation:k,iconSpin:g,maxLength:v,onCommit:x,ref:C,value:b="",...j}=t,[N,_]=m(b),[w,D]=m(!1),I=f(!1),T=a(),A=C??T;return s(()=>{w&&(A.current?.focus(),A.current?.select())},[w]),s(()=>{w||b===N||_(b)},[w,b]),o(p,{className:u(["Button",h&&"Button--fluid",B&&"Button--disabled",`Button--color--${c}`]),onClick:()=>D(!0),...j,children:[y&&e(d,{name:y,rotation:k,spin:g}),n??N,e("input",{className:"NumberInput__input",disabled:!!B,maxLength:v,onBlur:function(){I.current||b===N||(x?.(N),I.current=!1),D(!1)},onChange:function(t){_(t.currentTarget.value)},onKeyDown:function(t){if(t.key===r.Enter){t.preventDefault(),t.currentTarget.blur();return}if(i(t.key)){t.preventDefault(),I.current=!0,t.currentTarget.blur();return}},ref:A,spellCheck:"false",style:{display:w?"":"none",textAlign:"left"},type:"text",value:N})]})},t.File=function(t){let{accept:r,multiple:i,onSelectFiles:u,...l}=t,c=f(null);async function a(t){let n=Array.from(t).map(t=>{let n=new FileReader;return new Promise(e=>{n.onload=()=>e(n.result),n.readAsText(t)})});return await Promise.all(n)}async function s(t){let n=t.target.files;if(n?.length){let t=await a(n);u(i?t:t[0])}}return o(n,{children:[e(h,{onClick:()=>c.current?.click(),...l}),e("input",{accept:r,hidden:!0,multiple:i,onChange:s,ref:c,type:"file"})]})};export{h as Button};
@@ -29,7 +29,10 @@ type Props = {
29
29
  maxValue: number;
30
30
  /** The minimum value. */
31
31
  minValue: number;
32
- /** An event which fires when you release the input, or successfully enter a number. */
32
+ /**
33
+ * An event which fires when you release the input or successfully enter a
34
+ * number. This is the default value event for controls.
35
+ */
33
36
  onChange: (event: Event, value: number) => void;
34
37
  /** An event which fires when you drag the input. */
35
38
  onDrag: (event: MouseEvent, value: number) => void;
@@ -95,7 +95,7 @@ export declare function Flex(props: any): import("react/jsx-runtime").JSX.Elemen
95
95
  export declare namespace Flex {
96
96
  var Item: typeof FlexItem;
97
97
  }
98
- export declare const computeFlexItemClassName: (props: FlexItemProps) => string;
98
+ export declare function computeFlexItemClassName(props: FlexItemProps): string;
99
99
  export type FlexItemProps = Partial<{
100
100
  /** This allows the default alignment (or the one specified by align-items) to be overridden for individual flex items. */
101
101
  align: string | boolean;
@@ -1 +1 @@
1
- import{jsx as e}from"react/jsx-runtime";import{classes as t}from"../common/react.js";import{computeBoxClassName as l,computeBoxProps as r,unit as o}from"../common/ui.js";function i(e){return t(["Flex",e.inlineFlex&&"Flex--inline",l(e)])}function n(e){let{direction:t,wrap:l,align:o,justify:i,...n}=e;return r({style:{...n.style,alignItems:o,flexDirection:t,flexWrap:!0===l?"wrap":l,justifyContent:i},...n})}function m(l){let{className:r,...o}=l;return e("div",{className:t([r,i(o)]),...n(o)})}let s=e=>t(["Flex__item",l(e)]);function u(e){let{style:t,grow:l,order:i,shrink:n,basis:m,align:s,...u}=e,c=m??e.width??(void 0!==l?0:void 0);return r({style:{...t,alignSelf:s,flexBasis:o(c),flexGrow:void 0!==l&&Number(l),flexShrink:void 0!==n&&Number(n),order:i},...u})}m.Item=function(l){let{className:r,...o}=l;return e("div",{className:t([r,s(l)]),...u(o)})};export{m as Flex,i as computeFlexClassName,s as computeFlexItemClassName,u as computeFlexItemProps,n as computeFlexProps};
1
+ import{jsx as e}from"react/jsx-runtime";import{classes as t}from"../common/react.js";import{computeBoxClassName as r,computeBoxProps as n,unit as o}from"../common/ui.js";function i(e){return t(["Flex",e.inlineFlex&&"Flex--inline",r(e)])}function l(e){let{direction:t,wrap:r,align:o,justify:i,...l}=e;return n({style:{...l.style,alignItems:o,flexDirection:t,flexWrap:!0===r?"wrap":r,justifyContent:i},...l})}function m(r){let{className:n,...o}=r;return e("div",{className:t([n,i(o)]),...l(o)})}function u(e){return t(["Flex__item",r(e)])}function s(e){let{style:t,grow:r,order:i,shrink:l,basis:m,align:u,...s}=e,c=m??e.width??(void 0!==r?0:void 0);return n({style:{...t,alignSelf:u,flexBasis:o(c),flexGrow:void 0!==r&&Number(r),flexShrink:void 0!==l&&Number(l),order:i},...s})}m.Item=function(r){let{className:n,...o}=r;return e("div",{className:t([n,u(r)]),...s(o)})};export{m as Flex,i as computeFlexClassName,u as computeFlexItemClassName,s as computeFlexItemProps,l as computeFlexProps};
@@ -74,6 +74,7 @@ type Props = {
74
74
  * ## Floating
75
75
  *
76
76
  * Floating lets you position elements so that they don't go out of the bounds of the window.
77
+ *
77
78
  * - [Documentation](https://floating-ui.com/docs/react) for more information.
78
79
  */
79
80
  export declare function Floating(props: Props): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- import{Fragment as e,jsx as t,jsxs as n}from"react/jsx-runtime";import{classes as o}from"../common/react.js";import{FloatingPortal as i,autoUpdate as r,flip as a,offset as l,shift as s,size as c,useClick as d,useDismiss as m,useFloating as p,useHover as g,useInteractions as f,useTransitionStatus as h}from"@floating-ui/react";import{cloneElement as u,isValidElement as C,useEffect as v,useState as w}from"react";function F(F){let b,{allowedOutsideClasses:x,animationDuration:y,children:O,closeAfterInteract:R,content:j,contentAutoWidth:k,contentClasses:z,contentOffset:E=6,contentStyles:M,disabled:P,hoverDelay:S,hoverOpen:N,handleOpen:$,onMounted:q,placement:A,preventPortal:B,stopChildPropagation:D,onOpenChange:G}=F,[H,I]=w(!1),{refs:J,floatingStyles:K,context:L}=p({middleware:[l(E),a({padding:6}),s(),k&&c({apply({rects:e,elements:t}){t.floating.style.width=`${e.reference.width}px`}})],onOpenChange(e){I(e),G?.(e)},open:H,placement:A||"bottom",transform:!1,whileElementsMounted:(e,t,n)=>(void 0!==q&&q(),r(e,t,n,{ancestorResize:!1,ancestorScroll:!1,elementResize:!k}))}),{isMounted:Q,status:T}=h(L,{duration:y||200}),U=m(L,{ancestorScroll:!0,outsidePress:e=>!x||e.target instanceof Element&&!e.target.closest(x)}),V=d(L,{enabled:!P}),W=g(L,{enabled:!P,restMs:S||200}),X=void 0!==$,{getReferenceProps:Y,getFloatingProps:Z}=f(X?[]:[U,N?W:V]),_=Y({ref:J.setReference,...D&&{onClick:e=>e.stopPropagation()}}),ee=Z({onClick:()=>{R&&L.onOpenChange(!1)},ref:J.setFloating});v(()=>{X&&L.onOpenChange($)},[$]),b=C(O)?u(O,_):t("div",{..._,children:O});let et=t("div",{className:o(["Floating",!y&&"Floating--animated",z]),"data-position":L.placement,"data-transition":T,style:{...K,...M},...ee,children:j});return n(e,{children:[b,Q&&!!j&&(B?et:t(i,{id:"tgui-root",children:et}))]})}export{F as Floating};
1
+ import{Fragment as e,jsx as t,jsxs as n}from"react/jsx-runtime";import{classes as o}from"../common/react.js";import{FloatingPortal as i,autoUpdate as r,flip as a,offset as l,shift as s,size as c,useClick as d,useDismiss as m,useFloating as p,useHover as f,useInteractions as g,useTransitionStatus as h}from"@floating-ui/react";import{cloneElement as u,isValidElement as C,useEffect as v,useId as w,useState as F}from"react";function b(b){let x,{allowedOutsideClasses:y,animationDuration:O,children:R,closeAfterInteract:j,content:k,contentAutoWidth:z,contentClasses:E,contentOffset:M=6,contentStyles:P,disabled:S,hoverDelay:N,hoverOpen:$,handleOpen:q,onMounted:A,placement:B,preventPortal:D,stopChildPropagation:G,onOpenChange:H}=b,I=w(),[J,K]=F(!1),{refs:L,floatingStyles:Q,context:T}=p({middleware:[l(M),a({padding:6}),s(),z&&c({apply({rects:e,elements:t}){t.floating.style.width=`${e.reference.width}px`}})],onOpenChange(e){K(e),H?.(e)},open:J,placement:B||"bottom",transform:!1,whileElementsMounted:(e,t,n)=>(void 0!==A&&A(),r(e,t,n,{ancestorResize:!1,ancestorScroll:!1,elementResize:!z}))}),{isMounted:U,status:V}=h(T,{duration:O||200}),W=m(T,{ancestorScroll:!0,outsidePress:e=>!y||e.target instanceof Element&&!e.target.closest(y)}),X=d(T,{enabled:!S}),Y=f(T,{enabled:!S,restMs:N||200}),Z=void 0!==q,{getReferenceProps:_,getFloatingProps:ee}=g(Z?[]:[W,$?Y:X]),et=_({ref:L.setReference,...G&&{onClick:e=>e.stopPropagation()}}),en=ee({onClick:()=>{j&&T.onOpenChange(!1)},ref:L.setFloating});v(()=>{Z&&T.onOpenChange(q)},[q]),x=C(R)?u(R,et):t("div",{...et,children:R});let eo=t("div",{className:o(["Floating",!O&&"Floating--animated",E]),"data-position":T.placement,"data-transition":V,style:{...Q,...P},...en,children:k});return n(e,{children:[x,U&&!!k&&(D?eo:t(i,{id:I,children:eo}))]})}export{b as Floating};
@@ -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,value:E,...w}=u,B=l(null),K=C??B,[L,N]=a(E??"");c(()=>{let e;return(p||f)&&(e=setTimeout(()=>{K.current?.focus(),f&&K.current?.select()},1)),()=>clearTimeout(e)},[]),c(()=>{K.current&&document.activeElement!==K.current&&E!==L&&N(E??"")},[E]);let q=m(w),z=n(["Input",d&&"Input--disabled",v&&"Input--fluid",j&&"Input--monospace",o(w),s]);return e("input",{...q,autoComplete:"off",className:z,disabled:d,maxLength:T,onBlur:function(e){y?.(L)},onChange:function(e){let t=e.currentTarget.value;N(t),g?i(()=>I?.(t)):I?.(t)},onKeyDown:function(e){if(k?.(e),e.key===t.Enter){e.preventDefault(),b?.(e.currentTarget.value),D&&N(""),e.currentTarget.blur();return}r(e.key)&&(e.preventDefault(),h?.(e.currentTarget.value),e.currentTarget.blur())},placeholder:x,ref:K,spellCheck:!1,type:"text",value:L})}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{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,value:E,...w}=u,B=l(null),K=C??B,[L,N]=a(E??"");c(()=>{let e;return(p||f)&&(e=setTimeout(()=>{K.current?.focus(),f&&K.current?.select()},1)),()=>clearTimeout(e)},[]),c(()=>{K.current&&document.activeElement!==K.current&&E!==L&&N(E??"")},[E]);let q=m(w),z=n(["Input",d&&"Input--disabled",v&&"Input--fluid",j&&"Input--monospace",o(w),s]);return e("input",{...q,autoComplete:"off",className:z,disabled:d,maxLength:T,onBlur:()=>y?.(L),onChange:function(e){let t=e.currentTarget.value;N(t),g?i(()=>I?.(t)):I?.(t)},onKeyDown:function(e){if(k?.(e),e.key===t.Enter){e.preventDefault(),b?.(e.currentTarget.value),D&&N(""),e.currentTarget.blur();return}r(e.key)&&(e.preventDefault(),h?.(e.currentTarget.value),e.currentTarget.blur())},placeholder:x,ref:K,spellCheck:!1,type:"text",value:L})}export{p as Input};
@@ -22,12 +22,12 @@ type Props = {
22
22
  maxValue: number;
23
23
  /** Lowest possible value. */
24
24
  minValue: number;
25
- /** Adjust value by this amount when dragging the input. */
26
- onChange: (event: Event, value: number) => void;
27
25
  /**
28
- * An event, which fires about every 500ms when you drag the input up and
29
- * down, on release and on manual editing.
26
+ * An event which fires when release the knob or enter a number. This is the
27
+ * default value event for controls.
30
28
  */
29
+ onChange: (event: Event, value: number) => void;
30
+ /** An event which fires about every 500ms while dragging the input */
31
31
  onDrag: (event: Event, value: number) => void;
32
32
  /**
33
33
  * Applies a `color` to the outer ring around the knob based on whether the
@@ -1,10 +1,9 @@
1
- import type { KeyboardEvent } from 'react';
2
1
  import type { BoxProps } from './Box';
3
2
  export type ModalProps = Partial<{
4
3
  /** Fires once the enter key is pressed */
5
- onEnter: (e: KeyboardEvent<HTMLInputElement>) => void;
4
+ onEnter: (e: React.KeyboardEvent<HTMLInputElement>) => void;
6
5
  /** Fires once the escape key is pressed */
7
- onEscape: (e: KeyboardEvent<HTMLInputElement>) => void;
6
+ onEscape: (e: React.KeyboardEvent<HTMLInputElement>) => void;
8
7
  }> & BoxProps;
9
8
  /**
10
9
  * ## Modal
@@ -1,5 +1,5 @@
1
1
  import { type BooleanLike } from '../common/react.ts';
2
- import { Component, type FocusEventHandler, type KeyboardEventHandler, type MouseEventHandler } from 'react';
2
+ import { Component, type FocusEventHandler, type KeyboardEventHandler } from 'react';
3
3
  import { type BoxProps } from './Box';
4
4
  type Props = Required<{
5
5
  /** Highest possible value. */
@@ -49,7 +49,7 @@ export declare class NumberInput extends Component<Props, State> {
49
49
  dragInterval: NodeJS.Timeout;
50
50
  state: State;
51
51
  componentDidMount(): void;
52
- handleDragStart: MouseEventHandler<HTMLDivElement>;
52
+ handleDragStart: React.MouseEventHandler<HTMLDivElement>;
53
53
  handleDragMove: (event: MouseEvent) => void;
54
54
  handleDragEnd: (_event: MouseEvent) => void;
55
55
  handleBlur: FocusEventHandler<HTMLInputElement>;
@@ -23,12 +23,12 @@ type Props = {
23
23
  fillValue: number;
24
24
  /** Format value using this function before displaying it. */
25
25
  format: (value: number) => string;
26
- /** Adjust value by this amount when dragging the input. */
27
- onChange: (event: Event, value: number) => void;
28
26
  /**
29
- * An event which fires when you release the input or successfully enter
30
- * a number.
27
+ * An event which fires when you release the slider or enter a number. This is
28
+ * the default value event for controls.
31
29
  */
30
+ onChange: (event: Event, value: number) => void;
31
+ /** An event which fires only while dragging the slider. */
32
32
  onDrag: (event: Event, value: number) => void;
33
33
  /**
34
34
  * Applies a `color` to the slider based on whether the value lands in the
@@ -1 +1 @@
1
- import{jsx as r,jsxs as e}from"react/jsx-runtime";import{clamp01 as s,keyOfMatchingRange as i,scale as o}from"../common/math.js";import{classes as l}from"../common/react.js";import{computeBoxClassName as a,computeBoxProps as t}from"../common/ui.js";import{DraggableControl as m}from"./DraggableControl.js";function d(d){let{animated:c,format:n,maxValue:_,minValue:f,onChange:u,onDrag:p,step:h,stepPixelSize:g,unit:v,value:N,className:B,fillValue:P,color:S,ranges:j={},children:w,...y}=d,$=void 0!==w;return r(m,{dragMatrix:[1,0],animated:c,format:n,maxValue:_,minValue:f,onChange:u,onDrag:p,step:h,stepPixelSize:g,unit:v,value:N,children:m=>{let{displayElement:d,displayValue:c,dragging:n,handleDragStart:u,inputElement:p}=m,h=null!=P,g=o(P??c,f,_),v=o(c,f,_),x=S||i(P??N,j)||"default";return e("div",{className:l(["Slider","ProgressBar",`ProgressBar--color--${x}`,B,a(y)]),...t(y),onMouseDown:u,children:[r("div",{className:l(["ProgressBar__fill",h&&"ProgressBar__fill--animated"]),style:{opacity:.4,width:`${100*s(g)}%`}}),r("div",{className:"ProgressBar__fill",style:{width:`${100*s(Math.min(g,v))}%`}}),e("div",{className:"Slider__cursorOffset",style:{width:`${100*s(v)}%`},children:[r("div",{className:"Slider__cursor"}),r("div",{className:"Slider__pointer"}),n&&r("div",{className:"Slider__popupValue",children:d})]}),r("div",{className:"ProgressBar__content",children:$?w:d}),p]})}})}export{d as Slider};
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,format:n,maxValue:_,minValue:f,onChange:h,onDrag: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,format:n,maxValue:_,minValue:f,onChange:h,onDrag:u,step:g,stepPixelSize:p,unit:v,value:B,children:m=>{let{displayElement:d,displayValue:c,dragging:n,editing:h,handleDragStart:u,inputElement:g}=m,p=null!=P,v=i(l(P??c,f,_)),M=i(l(c,f,_)),$=S||s(P??B,j)||"default";return e("div",{className:a(["Slider",h&&"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 +1 @@
1
- import{jsx as a,jsxs as e}from"react/jsx-runtime";import{canRender as i,classes as s}from"../common/react.js";import{computeBoxClassName as r,computeBoxProps as c}from"../common/ui.js";import{Icon as l}from"./Icon.js";function t(e){let{className:i,vertical:l,fill:t,fluid:n,children:o,...m}=e;return a("div",{className:s(["Tabs",l?"Tabs--vertical":"Tabs--horizontal",t&&"Tabs--fill",n&&"Tabs--fluid",i,r(m)]),...c(m),children:o})}(t||(t={})).Tab=function(t){let{className:n,selected:o,color:m,icon:b,iconSpin:T,leftSlot:d,rightSlot:f,children:_,onClick:h,...u}=t;return e("div",{className:s(["Tab","Tabs__Tab",`Tab--color--${m}`,o&&"Tab--selected",n,r(u)]),onClick:function(a){h&&h(a)},...c(u),children:[i(d)&&a("div",{className:"Tab__left",children:d})||!!b&&a("div",{className:"Tab__left",children:a(l,{name:b,spin:T})}),a("div",{className:"Tab__text",children:_}),i(f)&&a("div",{className:"Tab__right",children:f})]})};export{t as Tabs};
1
+ import{jsx as a,jsxs as e}from"react/jsx-runtime";import{canRender as s,classes as i}from"../common/react.js";import{computeBoxClassName as r,computeBoxProps as l}from"../common/ui.js";import{Icon as c}from"./Icon.js";function t(e){let{className:s,vertical:c,fill:t,fluid:o,children:m,...n}=e;return a("div",{className:i(["Tabs",c?"Tabs--vertical":"Tabs--horizontal",t&&"Tabs--fill",o&&"Tabs--fluid",s,r(n)]),...l(n),children:m})}(t||(t={})).Tab=function(t){let{className:o,selected:m,color:n,icon:b,iconSpin:T,leftSlot:d,rightSlot:_,children:f,onClick:h,...u}=t;return e("div",{className:i(["Tab","Tabs__Tab",`Tab--color--${n}`,m&&"Tab--selected",o,r(u)]),onClick:a=>h?.(a),...l(u),children:[s(d)&&a("div",{className:"Tab__left",children:d})||!!b&&a("div",{className:"Tab__left",children:a(c,{name:b,spin:T})}),a("div",{className:"Tab__text",children:f}),s(_)&&a("div",{className:"Tab__right",children:_})]})};export{t as Tabs};
package/package.json CHANGED
@@ -11,13 +11,13 @@
11
11
  "@rsbuild/plugin-react": "^1.3.2",
12
12
  "@rsbuild/plugin-sass": "^1.3.2",
13
13
  "@rslib/core": "^0.9.2",
14
- "@storybook/addon-docs": "^9.0.6",
14
+ "@storybook/addon-docs": "^9.0.9",
15
15
  "@types/bun": "^1.2.15",
16
16
  "@types/react": "^19.1.7",
17
17
  "@types/react-dom": "^19.1.6",
18
18
  "prettier": "^3.5.3",
19
19
  "sass": "^1.89.2",
20
- "storybook": "^9.0.6",
20
+ "storybook": "^9.0.9",
21
21
  "storybook-addon-sass-postcss": "^0.3.2",
22
22
  "storybook-react-rsbuild": "^2.0.1",
23
23
  "typescript": "^5.8.3"
@@ -68,5 +68,5 @@
68
68
  "test": "bun test"
69
69
  },
70
70
  "type": "module",
71
- "version": "4.0.4"
71
+ "version": "4.1.0"
72
72
  }
@@ -0,0 +1,8 @@
1
+ /* Using :where for 0 specificity - https://developer.mozilla.org/en-US/docs/Web/CSS/:where */
2
+ :where(.candystripe:nth-child(odd)) {
3
+ background-color: var(--candystripe-odd);
4
+ }
5
+
6
+ :where(.candystripe:nth-child(even)) {
7
+ background-color: var(--candystripe-even);
8
+ }
@@ -0,0 +1,7 @@
1
+ .centered-image {
2
+ position: absolute;
3
+ height: 100%;
4
+ left: 50%;
5
+ top: 50%;
6
+ transform: translateX(-50%) translateY(-50%);
7
+ }
@@ -0,0 +1,17 @@
1
+ @use "../colors.scss";
2
+
3
+ $map-keys: colors.$color-map !default;
4
+
5
+ @each $color-name, $color-value in $map-keys {
6
+ .color-#{$color-name} {
7
+ color: hsl(from $color-value h s calc(l + var(--adjust-color))) !important;
8
+ }
9
+ }
10
+
11
+ @each $color-name, $color-value in $map-keys {
12
+ .color-bg-#{$color-name} {
13
+ background-color: hsl(
14
+ from $color-value h s calc(l - var(--adjust-color))
15
+ ) !important;
16
+ }
17
+ }
@@ -0,0 +1,12 @@
1
+ .debug-layout,
2
+ .debug-layout *:not(g):not(path) {
3
+ color: hsla(0, 0%, 100%, 0.9) !important;
4
+ background: transparent !important;
5
+ outline: 1px solid hsla(0, 0%, 100%, 0.5) !important;
6
+ box-shadow: none !important;
7
+ filter: none !important;
8
+
9
+ &:hover {
10
+ outline-color: hsla(0, 0%, 100%, 0.8) !important;
11
+ }
12
+ }
@@ -0,0 +1,15 @@
1
+ $mqIterations: 19;
2
+ @mixin fontResize($iterations) {
3
+ $i: 1;
4
+ @while $i <= $iterations {
5
+ $minWidth: 100px * $i;
6
+ @media all and (min-width: $minWidth) {
7
+ .fit-text {
8
+ font-size: 0.1em * $i;
9
+ }
10
+ }
11
+ $i: $i + 1;
12
+ }
13
+ }
14
+
15
+ @include fontResize($mqIterations);
@@ -0,0 +1,21 @@
1
+ a {
2
+ cursor: var(--cursor-pointer);
3
+ color: var(--color-hyperlink);
4
+ transition: color var(--transition-time-medium);
5
+
6
+ &:hover,
7
+ &:active {
8
+ color: hsl(from var(--color-hyperlink) h s calc(l + var(--adjust-hover)));
9
+ }
10
+
11
+ &:visited {
12
+ color: var(--color-hyperlink-visited);
13
+
14
+ &:hover,
15
+ &:active {
16
+ color: hsl(
17
+ from var(--color-hyperlink-visited) h s calc(l + var(--adjust-hover))
18
+ );
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,43 @@
1
+ @use "../colors.scss";
2
+
3
+ .outline-dotted {
4
+ outline-style: dotted !important;
5
+ }
6
+
7
+ .outline-dashed {
8
+ outline-style: dashed !important;
9
+ }
10
+
11
+ .outline-solid {
12
+ outline-style: solid !important;
13
+ }
14
+
15
+ .outline-double {
16
+ outline-style: double !important;
17
+ }
18
+
19
+ .outline-groove {
20
+ outline-style: groove !important;
21
+ }
22
+
23
+ .outline-ridge {
24
+ outline-style: ridge !important;
25
+ }
26
+
27
+ .outline-inset {
28
+ outline-style: inset !important;
29
+ }
30
+
31
+ .outline-outset {
32
+ outline-style: outset !important;
33
+ }
34
+
35
+ $map-keys: colors.$color-map !default;
36
+
37
+ @each $color-name, $color-value in $map-keys {
38
+ .outline-color-#{$color-name} {
39
+ outline: var(--border-thickness-small)
40
+ solid
41
+ hsl(from $color-value h s calc(l + var(--adjust-color))) !important;
42
+ }
43
+ }
@@ -0,0 +1,39 @@
1
+ .text-left {
2
+ text-align: left;
3
+ }
4
+
5
+ .text-center {
6
+ text-align: center;
7
+ }
8
+
9
+ .text-right {
10
+ text-align: right;
11
+ }
12
+
13
+ .text-baseline {
14
+ text-align: baseline;
15
+ }
16
+
17
+ .text-justify {
18
+ text-align: justify;
19
+ }
20
+
21
+ .text-nowrap {
22
+ white-space: nowrap;
23
+ }
24
+
25
+ .text-pre {
26
+ white-space: pre;
27
+ }
28
+
29
+ .text-bold {
30
+ font-weight: bold;
31
+ }
32
+
33
+ .text-italic {
34
+ font-style: italic;
35
+ }
36
+
37
+ .text-underline {
38
+ text-decoration: underline;
39
+ }
@@ -0,0 +1,11 @@
1
+ @use "sass:meta";
2
+
3
+ // Loads in all atomic styles
4
+ @include meta.load-css("./atomic/candystripe.scss");
5
+ @include meta.load-css("./atomic/centered-image.scss");
6
+ @include meta.load-css("./atomic/color.scss");
7
+ @include meta.load-css("./atomic/debug-layout.scss");
8
+ @include meta.load-css("./atomic/fit-text.scss");
9
+ @include meta.load-css("./atomic/links.scss");
10
+ @include meta.load-css("./atomic/outline.scss");
11
+ @include meta.load-css("./atomic/text.scss");
@@ -1,5 +1,3 @@
1
- $color-default: 0 !default;
2
-
3
1
  .BlockQuote {
4
2
  color: var(--blockquote-color);
5
3
  border-left: var(--blockquote-border);