@deephaven/components 0.15.7-beta.0 → 0.15.7-beta.3

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,8 +1,8 @@
1
1
  import React, { Component } from 'react';
2
2
  import { PopperOptions } from 'popper.js';
3
3
  import { IconDefinition } from '@deephaven/icons';
4
+ import { TimeInputElement } from './TimeInput';
4
5
  import './CustomTimeSelect.scss';
5
- import './context-actions/ContextActions.scss';
6
6
  declare enum MENU_NAVIGATION_DIRECTION {
7
7
  UP = "UP",
8
8
  DOWN = "DOWN"
@@ -40,7 +40,7 @@ declare class CustomTimeSelect extends Component<CustomTimeSelectProps, CustomTi
40
40
  csContainer: React.RefObject<HTMLDivElement>;
41
41
  menuContainer: React.RefObject<HTMLDivElement>;
42
42
  button: React.RefObject<HTMLButtonElement>;
43
- input: React.RefObject<HTMLInputElement>;
43
+ input: React.RefObject<TimeInputElement>;
44
44
  getSelectedText(): string;
45
45
  setInputWidth(): void;
46
46
  focus(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"CustomTimeSelect.d.ts","sourceRoot":"","sources":["../src/CustomTimeSelect.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CustomTimeSelect.d.ts","sourceRoot":"","sources":["../src/CustomTimeSelect.tsx"],"names":[],"mappings":"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"}
@@ -12,7 +12,6 @@ import classNames from 'classnames';
12
12
  import TimeInput from "./TimeInput.js";
13
13
  import DropdownMenu from "./menu-actions/DropdownMenu.js";
14
14
  import "./CustomTimeSelect.css";
15
- import "./context-actions/ContextActions.css";
16
15
  var CUSTOM_OPTION = -1;
17
16
  var MENU_NAVIGATION_DIRECTION;
18
17
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/CustomTimeSelect.tsx"],"names":["React","Component","FontAwesomeIcon","vsCheck","dhSort","TimeUtils","classNames","TimeInput","DropdownMenu","CUSTOM_OPTION","MENU_NAVIGATION_DIRECTION","CustomTimeSelect","constructor","props","value","valueToTime","toggleMenu","bind","handleMenuKeyDown","closeMenu","handleOptionClick","handleOptionFocus","handleMenuOpened","handleMenuExited","handleCustomInput","csContainer","createRef","menuContainer","button","input","state","keyboardOptionIndex","menuIsOpen","inputWidth","customTime","inputFocused","getSelectedText","options","placeholder","i","length","option","title","formatTime","setInputWidth","current","setState","getBoundingClientRect","width","focus","updateInputValue","onChange","handleResize","event","key","updateFromCustom","stopPropagation","preventDefault","shiftKey","handleMenuNavigation","UP","DOWN","direction","menuOptionsLength","newKeyboardOptionIndex","focusInput","focusOption","scrollOptionIntoView","optionIndex","Number","currentTarget","timeToValue","update","updateAndClose","target","activeOption","querySelector","HTMLElement","valueIndex","map","indexOf","index","children","item","openMenu","updateKeyboardIndex","focusButton","offsetTop","DROP_DOWN_MENU_HEIGHT","scrollTop","renderMenuElement","renderOptions","icon","customText","matchFound","optionArray","push","render","disabled","invalid","dataTestId","popperOptions","placement","modifiers","preventOverflow","enabled","menuElement","maxWidth","Math","round","time","undefined"],"mappings":";;;;;;AAAA,OAAOA,KAAP,IAAgBC,SAAhB,QAAiC,OAAjC;AAEA,SAASC,eAAT,QAAgC,gCAAhC;AACA,SAASC,OAAT,EAAkBC,MAAlB,QAAgD,kBAAhD;AACA,SAASC,SAAT,QAA0B,kBAA1B;AACA,OAAOC,UAAP,MAAuB,YAAvB;OACOC,S;OACAC,Y;;;AAIP,IAAMC,aAAa,GAAG,CAAC,CAAvB;IAEKC,yB;;WAAAA,yB;AAAAA,EAAAA,yB;AAAAA,EAAAA,yB;GAAAA,yB,KAAAA,yB;;AAgCL,MAAMC,gBAAN,SAA+BV,SAA/B,CAGE;AAqBAW,EAAAA,WAAW,CAACC,KAAD,EAA+B;AACxC,UAAMA,KAAN;;AADwC;;AAAA;;AAAA;;AAAA;;AAGxC,QAAM;AAAEC,MAAAA,KAAF;AAASC,MAAAA;AAAT,QAAyBF,KAA/B;AAEA,SAAKG,UAAL,GAAkB,KAAKA,UAAL,CAAgBC,IAAhB,CAAqB,IAArB,CAAlB;AACA,SAAKC,iBAAL,GAAyB,KAAKA,iBAAL,CAAuBD,IAAvB,CAA4B,IAA5B,CAAzB;AACA,SAAKE,SAAL,GAAiB,KAAKA,SAAL,CAAeF,IAAf,CAAoB,IAApB,CAAjB;AAEA,SAAKG,iBAAL,GAAyB,KAAKA,iBAAL,CAAuBH,IAAvB,CAA4B,IAA5B,CAAzB;AACA,SAAKI,iBAAL,GAAyB,KAAKA,iBAAL,CAAuBJ,IAAvB,CAA4B,IAA5B,CAAzB;AAEA,SAAKK,gBAAL,GAAwB,KAAKA,gBAAL,CAAsBL,IAAtB,CAA2B,IAA3B,CAAxB;AACA,SAAKM,gBAAL,GAAwB,KAAKA,gBAAL,CAAsBN,IAAtB,CAA2B,IAA3B,CAAxB;AACA,SAAKO,iBAAL,GAAyB,KAAKA,iBAAL,CAAuBP,IAAvB,CAA4B,IAA5B,CAAzB;AAEA,SAAKQ,WAAL,gBAAmBzB,KAAK,CAAC0B,SAAN,EAAnB;AACA,SAAKC,aAAL,gBAAqB3B,KAAK,CAAC0B,SAAN,EAArB;AACA,SAAKE,MAAL,gBAAc5B,KAAK,CAAC0B,SAAN,EAAd;AACA,SAAKG,KAAL,gBAAa7B,KAAK,CAAC0B,SAAN,EAAb;AAEA,SAAKI,KAAL,GAAa;AACXC,MAAAA,mBAAmB,EAAE,CADV;AAEXC,MAAAA,UAAU,EAAE,KAFD;AAGXC,MAAAA,UAAU,EAAE,GAHD;AAIXC,MAAAA,UAAU,EAAEnB,WAAW,CAACD,KAAD,CAJZ;AAKXqB,MAAAA,YAAY,EAAE;AALH,KAAb;AAOD;;AAUDC,EAAAA,eAAe,GAAW;AACxB,QAAM;AAAEC,MAAAA,OAAF;AAAWvB,MAAAA,KAAX;AAAkBwB,MAAAA;AAAlB,QAAkC,KAAKzB,KAA7C;AACA,QAAM;AAAEqB,MAAAA;AAAF,QAAiB,KAAKJ,KAA5B;;AAEA,QAAIhB,KAAK,KAAK,IAAd,EAAoB;AAClB,aAAOwB,WAAP;AACD;;AAED,SAAK,IAAIC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGF,OAAO,CAACG,MAA5B,EAAoCD,CAAC,IAAI,CAAzC,EAA4C;AAC1C,UAAME,MAAM,GAAGJ,OAAO,CAACE,CAAD,CAAtB;;AACA,UAAIE,MAAM,CAAC3B,KAAP,KAAiBA,KAArB,EAA4B;AAC1B,eAAO2B,MAAM,CAACC,KAAd;AACD;AACF;;AAED,WAAOrC,SAAS,CAACsC,UAAV,CAAqBT,UAArB,CAAP;AACD;;AAEDU,EAAAA,aAAa,GAAS;AACpB,QAAI,KAAKnB,WAAL,CAAiBoB,OAArB,EAA8B;AAC5B,WAAKC,QAAL,CAAc;AACZb,QAAAA,UAAU,EAAE,KAAKR,WAAL,CAAiBoB,OAAjB,CAAyBE,qBAAzB,GAAiDC;AADjD,OAAd;AAGD;AACF;;AAEDC,EAAAA,KAAK,GAAS;AAAA;;AACZ,iCAAKrB,MAAL,CAAYiB,OAAZ,8EAAqBI,KAArB;AACD;;AAEDC,EAAAA,gBAAgB,CAACpC,KAAD,EAAsB;AACpC,QAAM;AAAEqC,MAAAA;AAAF,QAAe,KAAKtC,KAA1B;AACAsC,IAAAA,QAAQ,CAACrC,KAAD,CAAR;AACD;;AAEDsC,EAAAA,YAAY,GAAS;AACnB,SAAKR,aAAL;AACD;;AAED1B,EAAAA,iBAAiB,CAACmC,KAAD,EAAmD;AAAA;;AAClE,QAAM;AAAEtB,MAAAA,mBAAF;AAAuBI,MAAAA;AAAvB,QAAwC,KAAKL,KAAnD;AACA,QAAM;AAAEO,MAAAA;AAAF,QAAc,KAAKxB,KAAzB;;AAEA,YAAQwC,KAAK,CAACC,GAAd;AACE,WAAK,OAAL;AACA,WAAK,GAAL;AAAU;AACR,YAAInB,YAAJ,EAAkB;AAChB,eAAKoB,gBAAL;AACD,SAFD,MAEO;AACL,eAAKL,gBAAL,CAAsBb,OAAO,CAACN,mBAAD,CAAP,CAA6BjB,KAAnD;AACD;;AACD,aAAKK,SAAL;AACA,sCAAKS,MAAL,CAAYiB,OAAZ,gFAAqBI,KAArB;AACAI,QAAAA,KAAK,CAACG,eAAN;AACAH,QAAAA,KAAK,CAACI,cAAN;AACA;;AACF,WAAK,KAAL;AACE,YAAIJ,KAAK,CAACK,QAAV,EAAoB;AAClB,eAAKC,oBAAL,CACEhD,gBAAgB,CAACD,yBAAjB,CAA2CkD,EAD7C;AAGD,SAJD,MAIO;AACL,eAAKD,oBAAL,CACEhD,gBAAgB,CAACD,yBAAjB,CAA2CmD,IAD7C;AAGD;;AACDR,QAAAA,KAAK,CAACG,eAAN;AACAH,QAAAA,KAAK,CAACI,cAAN;AACA;;AACF,WAAK,SAAL;AACE,aAAKE,oBAAL,CACEhD,gBAAgB,CAACD,yBAAjB,CAA2CkD,EAD7C;AAGAP,QAAAA,KAAK,CAACG,eAAN;AACAH,QAAAA,KAAK,CAACI,cAAN;AACA;;AACF,WAAK,WAAL;AACE,aAAKE,oBAAL,CACEhD,gBAAgB,CAACD,yBAAjB,CAA2CmD,IAD7C;AAGAR,QAAAA,KAAK,CAACG,eAAN;AACAH,QAAAA,KAAK,CAACI,cAAN;AACA;;AACF,WAAK,QAAL;AACE,aAAKtC,SAAL;AACA;;AACF;AACE;AA5CJ;AA8CD;;AAEDwC,EAAAA,oBAAoB,CAACG,SAAD,EAA6C;AAC/D,QAAM;AAAE/B,MAAAA,mBAAF;AAAuBI,MAAAA;AAAvB,QAAwC,KAAKL,KAAnD;AACA,QAAM;AAAEO,MAAAA;AAAF,QAAc,KAAKxB,KAAzB;AACA,QAAMkD,iBAAiB,GAAG1B,OAAO,CAACG,MAAlC;AACA,QAAIwB,sBAAsB,GAAGjC,mBAA7B;;AACA,YAAQ+B,SAAR;AACE,WAAKnD,gBAAgB,CAACD,yBAAjB,CAA2CkD,EAAhD;AACE,YAAI,CAACzB,YAAD,IAAiBJ,mBAAmB,KAAK,CAA7C,EAAgD;AAC9C,eAAKkC,UAAL;AACA;AACD,SAHD,MAGO,IAAI9B,YAAJ,EAAkB;AACvB,eAAK+B,WAAL,CAAiBnC,mBAAjB;AACD;;AAED,YAAIA,mBAAmB,GAAG,CAAtB,IAA2B,CAACI,YAAhC,EAA8C;AAC5C6B,UAAAA,sBAAsB,GACpB,CAACA,sBAAsB,GAAG,CAA1B,IAA+BD,iBADjC;AAEA,eAAKjB,QAAL,CAAc;AACZf,YAAAA,mBAAmB,EAAEiC;AADT,WAAd;AAGD,SAND,MAMO,IAAIjC,mBAAmB,KAAK,CAA5B,EAA+B;AACpCiC,UAAAA,sBAAsB,GAAGD,iBAAiB,GAAG,CAA7C;AACA,eAAKjB,QAAL,CAAc;AACZf,YAAAA,mBAAmB,EAAEiC;AADT,WAAd;AAGD;;AACD,aAAKG,oBAAL,CAA0BH,sBAA1B;AACA;;AACF,WAAKrD,gBAAgB,CAACD,yBAAjB,CAA2CmD,IAAhD;AACE,YAAI,CAAC1B,YAAD,IAAiBJ,mBAAmB,KAAKgC,iBAAiB,GAAG,CAAjE,EAAoE;AAClE,eAAKE,UAAL;AACA;AACD,SAHD,MAGO,IAAI9B,YAAJ,EAAkB;AACvB,eAAK+B,WAAL,CAAiBnC,mBAAjB;AACD;;AAED,YACEA,mBAAmB,GAAGgC,iBAAtB,IACA,EAAE5B,YAAY,IAAIJ,mBAAmB,KAAK,CAA1C,CAFF,EAGE;AACAiC,UAAAA,sBAAsB,GACpB,CAACA,sBAAsB,GAAG,CAA1B,IAA+BD,iBADjC;AAEA,eAAKjB,QAAL,CAAc;AACZf,YAAAA,mBAAmB,EAAEiC;AADT,WAAd;AAGD;;AACD,aAAKG,oBAAL,CAA0BH,sBAA1B;AACA;;AACF;AACE;AA5CJ;AA8CD;;AAED5C,EAAAA,iBAAiB,CAACiC,KAAD,EAAmD;AAClE,QAAMe,WAAW,GAAGC,MAAM,CAAChB,KAAK,CAACiB,aAAN,CAAoBxD,KAArB,CAA1B;AACA,QAAM;AAAEuB,MAAAA,OAAF;AAAWkC,MAAAA;AAAX,QAA2B,KAAK1D,KAAtC;AACA,QAAM;AAAEqB,MAAAA;AAAF,QAAiB,KAAKJ,KAA5B;;AAEA,QAAIsC,WAAW,KAAK3D,aAApB,EAAmC;AACjC,UAAM+D,MAAM,GAAGD,WAAW,CAACrC,UAAD,CAA1B;AACA,WAAKuC,cAAL,CAAoBD,MAApB;AACD,KAHD,MAGO;AACL,WAAKC,cAAL,CAAoBpC,OAAO,CAAC+B,WAAD,CAAP,CAAqBtD,KAAzC;AACD;AACF;;AAED2D,EAAAA,cAAc,CAACD,MAAD,EAAuB;AAAA;;AACnC,SAAKtB,gBAAL,CAAsBsB,MAAtB;AACA,SAAKrD,SAAL;AACA,kCAAKS,MAAL,CAAYiB,OAAZ,gFAAqBI,KAArB;AACD;;AAED5B,EAAAA,iBAAiB,CAACgC,KAAD,EAAmD;AAClE,SAAKP,QAAL,CAAc;AAAEf,MAAAA,mBAAmB,EAAEsC,MAAM,CAAChB,KAAK,CAACqB,MAAN,CAAa5D,KAAd;AAA7B,KAAd;AACD;;AAEDQ,EAAAA,gBAAgB,GAAS;AAAA;;AACvB,QAAM;AAAEe,MAAAA,OAAF;AAAWvB,MAAAA;AAAX,QAAqB,KAAKD,KAAhC;AACA,QAAM;AAAEkB,MAAAA;AAAF,QAA0B,KAAKD,KAArC;AACA,SAAKqC,oBAAL,CAA0BpC,mBAA1B;AACA,QAAM4C,YAAY,4BAAG,KAAKhD,aAAL,CAAmBkB,OAAtB,0DAAG,sBAA4B+B,aAA5B,CACnB,gCADmB,CAArB;;AAGA,QAAID,YAAY,YAAYE,WAA5B,EAAyC;AACvCF,MAAAA,YAAY,CAAC1B,KAAb;AACD;;AAED,QAAInC,KAAK,KAAK,IAAd,EAAoB;AAClB;AACD;;AACD,QAAMgE,UAAU,GAAGzC,OAAO,CAAC0C,GAAR,CAAYtC,MAAM,IAAIA,MAAM,CAAC3B,KAA7B,EAAoCkE,OAApC,CAA4ClE,KAA5C,CAAnB;;AACA,QAAIgE,UAAU,GAAG,CAAjB,EAAoB;AAClB;AACA,WAAKb,UAAL;AACD;AACF;;AAEDA,EAAAA,UAAU,GAAS;AAAA;;AACjB,gCAAKpC,KAAL,CAAWgB,OAAX,4EAAoBI,KAApB;AACD;;AAEDiB,EAAAA,WAAW,CAACe,KAAD,EAAsB;AAAA;;AAC/B,QAAM5C,OAAO,6BAAG,KAAKV,aAAL,CAAmBkB,OAAtB,2DAAG,uBAA4B+B,aAA5B,CAA0C,aAA1C,CAAhB;;AACA,QAAIvC,OAAO,IAAIA,OAAO,CAAC6C,QAAvB,EAAiC;AAC/B,UAAMzC,MAAM,GAAGJ,OAAO,CAAC6C,QAAR,CAAiBC,IAAjB,CAAsBF,KAAtB,CAAf;;AACA,UAAIxC,MAAM,YAAYoC,WAAtB,EAAmC;AACjCpC,QAAAA,MAAM,CAACQ,KAAP;AACD;AACF;AACF;;AAED1B,EAAAA,gBAAgB,GAAS;AACvB,QAAM;AAAES,MAAAA;AAAF,QAAiB,KAAKF,KAA5B;;AACA,QAAIE,UAAJ,EAAgB;AACd,WAAKc,QAAL,CAAc;AAAEd,QAAAA,UAAU,EAAE,KAAd;AAAqBD,QAAAA,mBAAmB,EAAE;AAA1C,OAAd;AACD;AACF;;AAEDP,EAAAA,iBAAiB,CAACV,KAAD,EAAsB;AACrC,QAAM;AAAEyD,MAAAA;AAAF,QAAkB,KAAK1D,KAA7B;AAEA,QAAM2D,MAAM,GAAGD,WAAW,CAACzD,KAAD,CAA1B;AACA,SAAKoC,gBAAL,CAAsBsB,MAAtB;AACA,SAAK1B,QAAL,CAAc;AACZZ,MAAAA,UAAU,EAAEpB;AADA,KAAd;AAGD;;AAEDyC,EAAAA,gBAAgB,GAAS;AACvB,QAAM;AAAEgB,MAAAA;AAAF,QAAkB,KAAK1D,KAA7B;AACA,QAAM;AAAEqB,MAAAA;AAAF,QAAiB,KAAKJ,KAA5B;AAEA,QAAM0C,MAAM,GAAGD,WAAW,CAACrC,UAAD,CAA1B;AACA,SAAKgB,gBAAL,CAAsBsB,MAAtB;AACD;;AAEDxD,EAAAA,UAAU,CAACqC,KAAD,EAAmD;AAC3D,QAAM;AAAErB,MAAAA;AAAF,QAAiB,KAAKF,KAA5B;;AACA,QAAIE,UAAJ,EAAgB;AACd,WAAKb,SAAL;AACD,KAFD,MAEO;AACL,WAAKiE,QAAL;AACD;;AACD/B,IAAAA,KAAK,CAACG,eAAN;AACD;;AAED4B,EAAAA,QAAQ,GAAS;AACf,SAAKC,mBAAL;AACA,SAAKzC,aAAL;AACA,SAAKE,QAAL,CAAc;AAAEd,MAAAA,UAAU,EAAE;AAAd,KAAd;AACD;;AAEDb,EAAAA,SAAS,GAA2B;AAAA,QAA1BmE,WAA0B,uEAAZ,IAAY;AAClC,SAAKxC,QAAL,CAAc;AAAEd,MAAAA,UAAU,EAAE;AAAd,KAAd;;AACA,QAAIsD,WAAJ,EAAiB;AAAA;;AACf,oCAAK1D,MAAL,CAAYiB,OAAZ,gFAAqBI,KAArB;AACD;AACF;;AAEDoC,EAAAA,mBAAmB,GAAS;AAC1B,QAAM;AAAEhD,MAAAA,OAAF;AAAWvB,MAAAA;AAAX,QAAqB,KAAKD,KAAhC;;AACA,QAAIC,KAAK,KAAK,IAAd,EAAoB;AAClB;AACD;;AACD,QAAMgE,UAAU,GAAGzC,OAAO,CAAC0C,GAAR,CAAYtC,MAAM,IAAIA,MAAM,CAAC3B,KAA7B,EAAoCkE,OAApC,CAA4ClE,KAA5C,CAAnB;;AACA,QAAIgE,UAAU,GAAG,CAAjB,EAAoB;AAClB,WAAKhC,QAAL,CAAc;AAAEf,QAAAA,mBAAmB,EAAE+C;AAAvB,OAAd;AACD;AACF;;AAEDX,EAAAA,oBAAoB,CAACc,KAAD,EAAsB;AAAA;;AACxC,QAAM5C,OAAO,6BAAG,KAAKV,aAAL,CAAmBkB,OAAtB,2DAAG,uBAA4B+B,aAA5B,CAA0C,aAA1C,CAAhB;;AACA,QAAIvC,OAAO,IAAIA,OAAO,CAAC6C,QAAvB,EAAiC;AAC/B,UAAMP,YAAY,GAAGtC,OAAO,CAAC6C,QAAR,CAAiBC,IAAjB,CAAsBF,KAAtB,CAArB;;AACA,UACEN,YAAY,YAAYE,WAAxB,IACAF,YAAY,CAACY,SAAb,GAAyB5E,gBAAgB,CAAC6E,qBAF5C,EAGE;AACAnD,QAAAA,OAAO,CAACoD,SAAR,GACEd,YAAY,CAACY,SAAb,GAAyB5E,gBAAgB,CAAC6E,qBAD5C;AAED,OAND,MAMO,IACJb,YAAY,YAAYE,WAAxB,IAAuCF,YAAY,CAACY,SAAb,GAAyB,CAAjE,IACAN,KAAK,KAAK,CAFL,EAGL;AACA5C,QAAAA,OAAO,CAACoD,SAAR,GAAoB,CAApB;AACD;AACF;AACF;;AAEDC,EAAAA,iBAAiB,GAAgB;AAC/B,QAAM;AAAEzD,MAAAA;AAAF,QAAiB,KAAKH,KAA5B;AACA,wBACE;AACE,MAAA,SAAS,EAAC,mBADZ;AAEE,MAAA,GAAG,EAAE,KAAKH,aAFZ;AAGE,MAAA,IAAI,EAAC,cAHP;AAIE,MAAA,SAAS,EAAE,KAAKT,iBAJlB;AAKE,MAAA,OAAO,EAAEmC,KAAK,IAAI;AAChBA,QAAAA,KAAK,CAACG,eAAN;AACD,OAPH;AAQE,MAAA,KAAK,EAAE;AAAER,QAAAA,KAAK,EAAEf;AAAT;AART,oBAUE;AAAK,MAAA,SAAS,EAAC;AAAf,oBACE;AAAK,MAAA,SAAS,EAAC;AAAf,OAA6B,KAAK0D,aAAL,EAA7B,CADF,CAVF,CADF;AAgBD;;AAEDA,EAAAA,aAAa,GAAoB;AAC/B,QAAM;AAAEtD,MAAAA,OAAF;AAAWvB,MAAAA,KAAX;AAAkB8E,MAAAA,IAAlB;AAAwBC,MAAAA;AAAxB,QAAuC,KAAKhF,KAAlD;AACA,QAAM;AAAEkB,MAAAA,mBAAF;AAAuBG,MAAAA,UAAvB;AAAmCC,MAAAA;AAAnC,QAAoD,KAAKL,KAA/D;AAEA,QAAIgE,UAAU,GAAG,KAAjB;AACA,QAAMC,WAA0B,GAAG,EAAnC;;AACA,SAAK,IAAId,KAAK,GAAG,CAAjB,EAAoBA,KAAK,GAAG5C,OAAO,CAACG,MAApC,EAA4CyC,KAAK,IAAI,CAArD,EAAwD;AACtD,UAAMxC,MAAM,GAAGJ,OAAO,CAAC4C,KAAD,CAAtB;AACA,UAAM3B,GAAG,oBAAa2B,KAAb,cAAsBxC,MAAM,CAAC3B,KAA7B,CAAT;AACAgF,MAAAA,UAAU,GAAGA,UAAU,IAAIrD,MAAM,CAAC3B,KAAP,KAAiBA,KAA5C;AACAiF,MAAAA,WAAW,CAACC,IAAZ,eACE;AACE,QAAA,GAAG,EAAE1C,GADP;AAEE,QAAA,IAAI,EAAC,QAFP;AAGE,QAAA,KAAK,EAAE2B,KAHT;AAIE,QAAA,SAAS,EAAE3E,UAAU,CAAC,eAAD,EAAkB;AACrC,6BAAmByB,mBAAmB,KAAKkD,KAAxB,IAAiC,CAAC9C;AADhB,SAAlB,CAJvB;AAOE,QAAA,OAAO,EAAE,KAAKf,iBAPhB;AAQE,QAAA,OAAO,EAAE,KAAKC;AARhB,SAUGoB,MAAM,CAAC3B,KAAP,KAAiBA,KAAjB,iBACC,oBAAC,eAAD;AAAiB,QAAA,IAAI,EAAE8E,IAAvB;AAA6B,QAAA,SAAS,EAAC;AAAvC,QAXJ,EAaGnD,MAAM,CAAC3B,KAAP,KAAiBA,KAAjB,iBAA0B;AAAM,QAAA,SAAS,EAAC;AAAhB,QAb7B,EAcG2B,MAAM,CAACC,KAdV,CADF;AAkBD;;AAEDqD,IAAAA,WAAW,CAACC,IAAZ,eAAiB;AAAI,MAAA,SAAS,EAAC,YAAd;AAA2B,MAAA,GAAG,EAAC;AAA/B,MAAjB;AAEAD,IAAAA,WAAW,CAACC,IAAZ,eACE;AACE,MAAA,GAAG,EAAC,qBADN;AAEE,MAAA,IAAI,EAAC,QAFP;AAGE,MAAA,KAAK,EAAEvF,aAHT;AAIE,MAAA,SAAS,EAAEH,UAAU,CAAC,eAAD,EAAkB;AACrC,2BAAmB6B;AADkB,OAAlB,CAJvB;AAOE,MAAA,OAAO,EAAE,KAAKf,iBAPhB;AAQE,MAAA,OAAO,EAAE,KAAKC;AARhB,OAUG,CAACyE,UAAD,IAAehF,KAAK,KAAK,IAAzB,gBACC,oBAAC,eAAD;AAAiB,MAAA,IAAI,EAAE8E,IAAvB;AAA6B,MAAA,SAAS,EAAC;AAAvC,MADD,gBAGC;AAAM,MAAA,SAAS,EAAC;AAAhB,MAbJ,EAeGC,UAfH,CADF;AAoBAE,IAAAA,WAAW,CAACC,IAAZ,eACE;AAAK,MAAA,GAAG,EAAC,qBAAT;AAA+B,MAAA,SAAS,EAAC;AAAzC,oBACE;AAAM,MAAA,SAAS,EAAC;AAAhB,MADF,eAEE,oBAAC,SAAD;AACE,MAAA,GAAG,EAAC,cADN;AAEE,MAAA,GAAG,EAAE,KAAKnE,KAFZ;AAGE,MAAA,QAAQ,EAAE,KAAKL,iBAHjB;AAIE,MAAA,KAAK,EAAEU,UAJT;AAKE,MAAA,OAAO,EAAE,MAAM,KAAKY,QAAL,CAAc;AAAEX,QAAAA,YAAY,EAAE;AAAhB,OAAd,CALjB;AAME,MAAA,MAAM,EAAE,MAAM,KAAKW,QAAL,CAAc;AAAEX,QAAAA,YAAY,EAAE;AAAhB,OAAd;AANhB,MAFF,eAUE;AAAM,MAAA,SAAS,EAAC;AAAhB,MAVF,CADF;AAeA4D,IAAAA,WAAW,CAACC,IAAZ,eAAiB;AAAI,MAAA,GAAG,EAAC,YAAR;AAAqB,MAAA,SAAS,EAAC;AAA/B,MAAjB;AAEA,WAAOD,WAAP;AACD;;AAEDE,EAAAA,MAAM,GAAgB;AACpB,QAAM;AAAEC,MAAAA,QAAF;AAAYC,MAAAA,OAAZ;AAAqBrF,MAAAA,KAArB;AAA4B,qBAAesF;AAA3C,QAA0D,KAAKvF,KAArE;AACA,QAAM;AAAEmB,MAAAA;AAAF,QAAiB,KAAKF,KAA5B;AACA,QAAI;AAAEuE,MAAAA;AAAF,QAAoB,KAAKxF,KAA7B;AACAwF,IAAAA,aAAa;AACXC,MAAAA,SAAS,EAAE,YADA;AAEXC,MAAAA,SAAS,EAAE;AACTC,QAAAA,eAAe,EAAE;AAAEC,UAAAA,OAAO,EAAE;AAAX;AADR;AAFA,OAKRJ,aALQ,CAAb;AAQA,wBACE;AACE,MAAA,SAAS,EAAC,uCADZ;AAEE,MAAA,GAAG,EAAE,KAAK5E,WAFZ;AAGE,qBAAa2E;AAHf,oBAKE;AACE,MAAA,SAAS,EAAE9F,UAAU,CAAC,gCAAD,EAAmC;AACtD,+BAAuB6F;AAD+B,OAAnC;AADvB,oBAKE;AACE,MAAA,IAAI,EAAC,QADP;AAEE,MAAA,SAAS,EAAE7F,UAAU,CAAC,yBAAD,EAA4B;AAC/C,0BAAkB6F;AAD6B,OAA5B,CAFvB;AAKE,MAAA,GAAG,EAAE,KAAKvE,MALZ;AAME,MAAA,OAAO,EAAE,KAAKZ,UANhB;AAOE,MAAA,QAAQ,EAAEkF;AAPZ,oBASE;AACE,MAAA,SAAS,EAAE5F,UAAU,CAAC;AACpB,sBAAcQ,KAAK,KAAK;AADJ,OAAD;AADvB,OAKG,KAAKsB,eAAL,EALH,CATF,eAgBE,+CACE,oBAAC,eAAD;AAAiB,MAAA,IAAI,EAAEhC,MAAvB;AAA+B,MAAA,SAAS,EAAC;AAAzC,MADF,CAhBF,eAmBE,oBAAC,YAAD;AACE,MAAA,OAAO,EAAE4B,UADX;AAEE,MAAA,OAAO,EAAE;AAAE0E,QAAAA,WAAW,EAAE,KAAKhB,iBAAL;AAAf,OAFX;AAGE,MAAA,aAAa,EAAEW,aAHjB;AAIE,MAAA,eAAe,EAAC,kBAJlB;AAKE,MAAA,YAAY,EAAE,KAAK/E,gBALrB;AAME,MAAA,YAAY,EAAE,KAAKC,gBANrB;AAOE,MAAA,SAAS,EAAE;AAAEoF,QAAAA,QAAQ,EAAE;AAAZ;AAPb,MAnBF,CALF,CALF,CADF;AA2CD;;AAteD;;gBAHIhG,gB,+BAI+BD,yB;;gBAJ/BC,gB,2BAM2B,G;;gBAN3BA,gB,kBAQkD;AACpDwC,EAAAA,QAAQ,GAAS,CACf;AACD,GAHmD;;AAIpDrC,EAAAA,KAAK,EAAE,IAJ6C;AAKpDoF,EAAAA,QAAQ,EAAE,KAL0C;AAMpDG,EAAAA,aAAa,EAAE,EANqC;AAOpDT,EAAAA,IAAI,EAAEzF,OAP8C;AAQpD0F,EAAAA,UAAU,EAAE,QARwC;AASpDvD,EAAAA,WAAW,EAAE,eATuC;AAUpDvB,EAAAA,WAAW,EAAED,KAAK,IAAKA,KAAK,KAAK,IAAV,GAAiB,CAAjB,GAAqB8F,IAAI,CAACC,KAAL,CAAW/F,KAAK,GAAG,IAAnB,CAVQ;AAWpDyD,EAAAA,WAAW,EAAEuC,IAAI,IAAIA,IAAI,GAAG,IAXwB;AAYpDX,EAAAA,OAAO,EAAE,KAZ2C;AAapD,iBAAeY;AAbqC,C;;AAoexD,eAAepG,gBAAf","sourcesContent":["import React, { Component } from 'react';\nimport { PopperOptions } from 'popper.js';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { vsCheck, dhSort, IconDefinition } from '@deephaven/icons';\nimport { TimeUtils } from '@deephaven/utils';\nimport classNames from 'classnames';\nimport TimeInput from './TimeInput';\nimport DropdownMenu from './menu-actions/DropdownMenu';\nimport './CustomTimeSelect.scss';\nimport './context-actions/ContextActions.scss';\n\nconst CUSTOM_OPTION = -1;\n\nenum MENU_NAVIGATION_DIRECTION {\n UP = 'UP',\n DOWN = 'DOWN',\n}\n\ntype CustomTimeSelectProps = {\n options: { title: string; value: number }[];\n popperOptions: PopperOptions;\n value: number | null;\n onChange(value: number): void;\n disabled: boolean;\n icon: IconDefinition;\n placeholder: string;\n customText: string;\n // Defaults to converting the value in milliseconds to time in seconds\n valueToTime(val: number | null): number;\n // Defaults to converting the time in seconds to value in milliseconds\n timeToValue(time: number): number;\n invalid: boolean;\n 'data-testid'?: string;\n};\n\ntype TimeInSeconds = number;\n\ntype CustomTimeSelectState = {\n keyboardOptionIndex: number;\n menuIsOpen: boolean;\n inputWidth: number;\n customTime: TimeInSeconds;\n inputFocused: boolean;\n};\n\nclass CustomTimeSelect extends Component<\n CustomTimeSelectProps,\n CustomTimeSelectState\n> {\n static MENU_NAVIGATION_DIRECTION = MENU_NAVIGATION_DIRECTION;\n\n static DROP_DOWN_MENU_HEIGHT = 125;\n\n static defaultProps: Partial<CustomTimeSelectProps> = {\n onChange(): void {\n // no-op\n },\n value: null,\n disabled: false,\n popperOptions: {},\n icon: vsCheck,\n customText: 'Custom',\n placeholder: 'Select a time',\n valueToTime: value => (value === null ? 0 : Math.round(value / 1000)),\n timeToValue: time => time * 1000,\n invalid: false,\n 'data-testid': undefined,\n };\n\n constructor(props: CustomTimeSelectProps) {\n super(props);\n\n const { value, valueToTime } = props;\n\n this.toggleMenu = this.toggleMenu.bind(this);\n this.handleMenuKeyDown = this.handleMenuKeyDown.bind(this);\n this.closeMenu = this.closeMenu.bind(this);\n\n this.handleOptionClick = this.handleOptionClick.bind(this);\n this.handleOptionFocus = this.handleOptionFocus.bind(this);\n\n this.handleMenuOpened = this.handleMenuOpened.bind(this);\n this.handleMenuExited = this.handleMenuExited.bind(this);\n this.handleCustomInput = this.handleCustomInput.bind(this);\n\n this.csContainer = React.createRef();\n this.menuContainer = React.createRef();\n this.button = React.createRef();\n this.input = React.createRef();\n\n this.state = {\n keyboardOptionIndex: 0,\n menuIsOpen: false,\n inputWidth: 100,\n customTime: valueToTime(value),\n inputFocused: false,\n };\n }\n\n csContainer: React.RefObject<HTMLDivElement>;\n\n menuContainer: React.RefObject<HTMLDivElement>;\n\n button: React.RefObject<HTMLButtonElement>;\n\n input: React.RefObject<HTMLInputElement>;\n\n getSelectedText(): string {\n const { options, value, placeholder } = this.props;\n const { customTime } = this.state;\n\n if (value === null) {\n return placeholder;\n }\n\n for (let i = 0; i < options.length; i += 1) {\n const option = options[i];\n if (option.value === value) {\n return option.title;\n }\n }\n\n return TimeUtils.formatTime(customTime);\n }\n\n setInputWidth(): void {\n if (this.csContainer.current) {\n this.setState({\n inputWidth: this.csContainer.current.getBoundingClientRect().width,\n });\n }\n }\n\n focus(): void {\n this.button.current?.focus();\n }\n\n updateInputValue(value: number): void {\n const { onChange } = this.props;\n onChange(value);\n }\n\n handleResize(): void {\n this.setInputWidth();\n }\n\n handleMenuKeyDown(event: React.KeyboardEvent<HTMLDivElement>): void {\n const { keyboardOptionIndex, inputFocused } = this.state;\n const { options } = this.props;\n\n switch (event.key) {\n case 'Enter':\n case ' ': // Space Bar\n if (inputFocused) {\n this.updateFromCustom();\n } else {\n this.updateInputValue(options[keyboardOptionIndex].value);\n }\n this.closeMenu();\n this.button.current?.focus();\n event.stopPropagation();\n event.preventDefault();\n break;\n case 'Tab':\n if (event.shiftKey) {\n this.handleMenuNavigation(\n CustomTimeSelect.MENU_NAVIGATION_DIRECTION.UP\n );\n } else {\n this.handleMenuNavigation(\n CustomTimeSelect.MENU_NAVIGATION_DIRECTION.DOWN\n );\n }\n event.stopPropagation();\n event.preventDefault();\n break;\n case 'ArrowUp':\n this.handleMenuNavigation(\n CustomTimeSelect.MENU_NAVIGATION_DIRECTION.UP\n );\n event.stopPropagation();\n event.preventDefault();\n break;\n case 'ArrowDown':\n this.handleMenuNavigation(\n CustomTimeSelect.MENU_NAVIGATION_DIRECTION.DOWN\n );\n event.stopPropagation();\n event.preventDefault();\n break;\n case 'Escape':\n this.closeMenu();\n break;\n default:\n break;\n }\n }\n\n handleMenuNavigation(direction: MENU_NAVIGATION_DIRECTION): void {\n const { keyboardOptionIndex, inputFocused } = this.state;\n const { options } = this.props;\n const menuOptionsLength = options.length;\n let newKeyboardOptionIndex = keyboardOptionIndex;\n switch (direction) {\n case CustomTimeSelect.MENU_NAVIGATION_DIRECTION.UP:\n if (!inputFocused && keyboardOptionIndex === 0) {\n this.focusInput();\n break;\n } else if (inputFocused) {\n this.focusOption(keyboardOptionIndex);\n }\n\n if (keyboardOptionIndex > 0 && !inputFocused) {\n newKeyboardOptionIndex =\n (newKeyboardOptionIndex - 1) % menuOptionsLength;\n this.setState({\n keyboardOptionIndex: newKeyboardOptionIndex,\n });\n } else if (keyboardOptionIndex === 0) {\n newKeyboardOptionIndex = menuOptionsLength - 1;\n this.setState({\n keyboardOptionIndex: newKeyboardOptionIndex,\n });\n }\n this.scrollOptionIntoView(newKeyboardOptionIndex);\n break;\n case CustomTimeSelect.MENU_NAVIGATION_DIRECTION.DOWN:\n if (!inputFocused && keyboardOptionIndex === menuOptionsLength - 1) {\n this.focusInput();\n break;\n } else if (inputFocused) {\n this.focusOption(keyboardOptionIndex);\n }\n\n if (\n keyboardOptionIndex < menuOptionsLength &&\n !(inputFocused && keyboardOptionIndex === 0)\n ) {\n newKeyboardOptionIndex =\n (newKeyboardOptionIndex + 1) % menuOptionsLength;\n this.setState({\n keyboardOptionIndex: newKeyboardOptionIndex,\n });\n }\n this.scrollOptionIntoView(newKeyboardOptionIndex);\n break;\n default:\n break;\n }\n }\n\n handleOptionClick(event: React.MouseEvent<HTMLButtonElement>): void {\n const optionIndex = Number(event.currentTarget.value);\n const { options, timeToValue } = this.props;\n const { customTime } = this.state;\n\n if (optionIndex === CUSTOM_OPTION) {\n const update = timeToValue(customTime);\n this.updateAndClose(update);\n } else {\n this.updateAndClose(options[optionIndex].value);\n }\n }\n\n updateAndClose(update: number): void {\n this.updateInputValue(update);\n this.closeMenu();\n this.button.current?.focus();\n }\n\n handleOptionFocus(event: React.FocusEvent<HTMLButtonElement>): void {\n this.setState({ keyboardOptionIndex: Number(event.target.value) });\n }\n\n handleMenuOpened(): void {\n const { options, value } = this.props;\n const { keyboardOptionIndex } = this.state;\n this.scrollOptionIntoView(keyboardOptionIndex);\n const activeOption = this.menuContainer.current?.querySelector(\n '.cs-option-btn.keyboard-active'\n );\n if (activeOption instanceof HTMLElement) {\n activeOption.focus();\n }\n\n if (value === null) {\n return;\n }\n const valueIndex = options.map(option => option.value).indexOf(value);\n if (valueIndex < 0) {\n // The custom option should be selected\n this.focusInput();\n }\n }\n\n focusInput(): void {\n this.input.current?.focus();\n }\n\n focusOption(index: number): void {\n const options = this.menuContainer.current?.querySelector('.cs-options');\n if (options && options.children) {\n const option = options.children.item(index);\n if (option instanceof HTMLElement) {\n option.focus();\n }\n }\n }\n\n handleMenuExited(): void {\n const { menuIsOpen } = this.state;\n if (menuIsOpen) {\n this.setState({ menuIsOpen: false, keyboardOptionIndex: 0 });\n }\n }\n\n handleCustomInput(value: number): void {\n const { timeToValue } = this.props;\n\n const update = timeToValue(value);\n this.updateInputValue(update);\n this.setState({\n customTime: value,\n });\n }\n\n updateFromCustom(): void {\n const { timeToValue } = this.props;\n const { customTime } = this.state;\n\n const update = timeToValue(customTime);\n this.updateInputValue(update);\n }\n\n toggleMenu(event: React.MouseEvent<HTMLButtonElement>): void {\n const { menuIsOpen } = this.state;\n if (menuIsOpen) {\n this.closeMenu();\n } else {\n this.openMenu();\n }\n event.stopPropagation();\n }\n\n openMenu(): void {\n this.updateKeyboardIndex();\n this.setInputWidth();\n this.setState({ menuIsOpen: true });\n }\n\n closeMenu(focusButton = true): void {\n this.setState({ menuIsOpen: false });\n if (focusButton) {\n this.button.current?.focus();\n }\n }\n\n updateKeyboardIndex(): void {\n const { options, value } = this.props;\n if (value === null) {\n return;\n }\n const valueIndex = options.map(option => option.value).indexOf(value);\n if (valueIndex > 0) {\n this.setState({ keyboardOptionIndex: valueIndex });\n }\n }\n\n scrollOptionIntoView(index: number): void {\n const options = this.menuContainer.current?.querySelector('.cs-options');\n if (options && options.children) {\n const activeOption = options.children.item(index);\n if (\n activeOption instanceof HTMLElement &&\n activeOption.offsetTop > CustomTimeSelect.DROP_DOWN_MENU_HEIGHT\n ) {\n options.scrollTop =\n activeOption.offsetTop - CustomTimeSelect.DROP_DOWN_MENU_HEIGHT;\n } else if (\n (activeOption instanceof HTMLElement && activeOption.offsetTop < 0) ||\n index === 0\n ) {\n options.scrollTop = 0;\n }\n }\n }\n\n renderMenuElement(): JSX.Element {\n const { inputWidth } = this.state;\n return (\n <div\n className=\"cs-menu-container\"\n ref={this.menuContainer}\n role=\"presentation\"\n onKeyDown={this.handleMenuKeyDown}\n onClick={event => {\n event.stopPropagation();\n }}\n style={{ width: inputWidth }}\n >\n <div className=\"cs-options-container\">\n <div className=\"cs-options\">{this.renderOptions()}</div>\n </div>\n </div>\n );\n }\n\n renderOptions(): React.ReactNode {\n const { options, value, icon, customText } = this.props;\n const { keyboardOptionIndex, customTime, inputFocused } = this.state;\n\n let matchFound = false;\n const optionArray: JSX.Element[] = [];\n for (let index = 0; index < options.length; index += 1) {\n const option = options[index];\n const key = `option-${index}-${option.value}`;\n matchFound = matchFound || option.value === value;\n optionArray.push(\n <button\n key={key}\n type=\"button\"\n value={index}\n className={classNames('cs-option-btn', {\n 'keyboard-active': keyboardOptionIndex === index && !inputFocused,\n })}\n onClick={this.handleOptionClick}\n onFocus={this.handleOptionFocus}\n >\n {option.value === value && (\n <FontAwesomeIcon icon={icon} className=\"mr-2\" />\n )}\n {option.value !== value && <span className=\"mr-4\" />}\n {option.title}\n </button>\n );\n }\n\n optionArray.push(<hr className=\"cs-divider\" key=\"option-divider\" />);\n\n optionArray.push(\n <button\n key=\"option-custom-label\"\n type=\"button\"\n value={CUSTOM_OPTION}\n className={classNames('cs-option-btn', {\n 'keyboard-active': inputFocused,\n })}\n onClick={this.handleOptionClick}\n onFocus={this.handleOptionFocus}\n >\n {!matchFound && value !== null ? (\n <FontAwesomeIcon icon={icon} className=\"mr-2\" />\n ) : (\n <span className=\"mr-4\" />\n )}\n {customText}\n </button>\n );\n\n optionArray.push(\n <div key=\"cs-custom-container\" className=\"cs-custom-container\">\n <span className=\"mr-2\" />\n <TimeInput\n key=\"option-input\"\n ref={this.input}\n onChange={this.handleCustomInput}\n value={customTime}\n onFocus={() => this.setState({ inputFocused: true })}\n onBlur={() => this.setState({ inputFocused: false })}\n />\n <span className=\"ml-2\" />\n </div>\n );\n\n optionArray.push(<hr key=\"option-end\" className=\"mb-2\" />);\n\n return optionArray;\n }\n\n render(): JSX.Element {\n const { disabled, invalid, value, 'data-testid': dataTestId } = this.props;\n const { menuIsOpen } = this.state;\n let { popperOptions } = this.props;\n popperOptions = {\n placement: 'bottom-end',\n modifiers: {\n preventOverflow: { enabled: false },\n },\n ...popperOptions,\n };\n\n return (\n <div\n className=\"input-group cs-container context-menu\"\n ref={this.csContainer}\n data-testid={dataTestId}\n >\n <div\n className={classNames('input-group-append cs-dropdown', {\n 'cs-dropdown-invalid': invalid,\n })}\n >\n <button\n type=\"button\"\n className={classNames('btn cs-btn form-control', {\n 'cs-btn-invalid': invalid,\n })}\n ref={this.button}\n onClick={this.toggleMenu}\n disabled={disabled}\n >\n <span\n className={classNames({\n 'text-muted': value === null,\n })}\n >\n {this.getSelectedText()}\n </span>\n <span>\n <FontAwesomeIcon icon={dhSort} className=\"cs-caret\" />\n </span>\n <DropdownMenu\n isShown={menuIsOpen}\n actions={{ menuElement: this.renderMenuElement() }}\n popperOptions={popperOptions}\n popperClassName=\"CustomTimeSelect\"\n onMenuOpened={this.handleMenuOpened}\n onMenuClosed={this.handleMenuExited}\n menuStyle={{ maxWidth: '100rem' }}\n />\n </button>\n </div>\n </div>\n );\n }\n}\n\nexport default CustomTimeSelect;\n"],"file":"CustomTimeSelect.js"}
1
+ {"version":3,"sources":["../src/CustomTimeSelect.tsx"],"names":["React","Component","FontAwesomeIcon","vsCheck","dhSort","TimeUtils","classNames","TimeInput","DropdownMenu","CUSTOM_OPTION","MENU_NAVIGATION_DIRECTION","CustomTimeSelect","constructor","props","value","valueToTime","toggleMenu","bind","handleMenuKeyDown","closeMenu","handleOptionClick","handleOptionFocus","handleMenuOpened","handleMenuExited","handleCustomInput","csContainer","createRef","menuContainer","button","input","state","keyboardOptionIndex","menuIsOpen","inputWidth","customTime","inputFocused","getSelectedText","options","placeholder","i","length","option","title","formatTime","setInputWidth","current","setState","getBoundingClientRect","width","focus","updateInputValue","onChange","handleResize","event","key","updateFromCustom","stopPropagation","preventDefault","shiftKey","handleMenuNavigation","UP","DOWN","direction","menuOptionsLength","newKeyboardOptionIndex","focusInput","focusOption","scrollOptionIntoView","optionIndex","Number","currentTarget","timeToValue","update","updateAndClose","target","activeOption","querySelector","HTMLElement","valueIndex","map","indexOf","index","children","item","openMenu","updateKeyboardIndex","focusButton","offsetTop","DROP_DOWN_MENU_HEIGHT","scrollTop","renderMenuElement","renderOptions","icon","customText","matchFound","optionArray","push","render","disabled","invalid","dataTestId","popperOptions","placement","modifiers","preventOverflow","enabled","menuElement","maxWidth","Math","round","time","undefined"],"mappings":"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","sourcesContent":["import React, { Component } from 'react';\nimport { PopperOptions } from 'popper.js';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { vsCheck, dhSort, IconDefinition } from '@deephaven/icons';\nimport { TimeUtils } from '@deephaven/utils';\nimport classNames from 'classnames';\nimport TimeInput, { TimeInputElement } from './TimeInput';\nimport DropdownMenu from './menu-actions/DropdownMenu';\nimport './CustomTimeSelect.scss';\n\nconst CUSTOM_OPTION = -1;\n\nenum MENU_NAVIGATION_DIRECTION {\n UP = 'UP',\n DOWN = 'DOWN',\n}\n\ntype CustomTimeSelectProps = {\n options: { title: string; value: number }[];\n popperOptions: PopperOptions;\n value: number | null;\n onChange(value: number): void;\n disabled: boolean;\n icon: IconDefinition;\n placeholder: string;\n customText: string;\n // Defaults to converting the value in milliseconds to time in seconds\n valueToTime(val: number | null): number;\n // Defaults to converting the time in seconds to value in milliseconds\n timeToValue(time: number): number;\n invalid: boolean;\n 'data-testid'?: string;\n};\n\ntype TimeInSeconds = number;\n\ntype CustomTimeSelectState = {\n keyboardOptionIndex: number;\n menuIsOpen: boolean;\n inputWidth: number;\n customTime: TimeInSeconds;\n inputFocused: boolean;\n};\n\nclass CustomTimeSelect extends Component<\n CustomTimeSelectProps,\n CustomTimeSelectState\n> {\n static MENU_NAVIGATION_DIRECTION = MENU_NAVIGATION_DIRECTION;\n\n static DROP_DOWN_MENU_HEIGHT = 125;\n\n static defaultProps: Partial<CustomTimeSelectProps> = {\n onChange(): void {\n // no-op\n },\n value: null,\n disabled: false,\n popperOptions: {},\n icon: vsCheck,\n customText: 'Custom',\n placeholder: 'Select a time',\n valueToTime: value => (value === null ? 0 : Math.round(value / 1000)),\n timeToValue: time => time * 1000,\n invalid: false,\n 'data-testid': undefined,\n };\n\n constructor(props: CustomTimeSelectProps) {\n super(props);\n\n const { value, valueToTime } = props;\n\n this.toggleMenu = this.toggleMenu.bind(this);\n this.handleMenuKeyDown = this.handleMenuKeyDown.bind(this);\n this.closeMenu = this.closeMenu.bind(this);\n\n this.handleOptionClick = this.handleOptionClick.bind(this);\n this.handleOptionFocus = this.handleOptionFocus.bind(this);\n\n this.handleMenuOpened = this.handleMenuOpened.bind(this);\n this.handleMenuExited = this.handleMenuExited.bind(this);\n this.handleCustomInput = this.handleCustomInput.bind(this);\n\n this.csContainer = React.createRef();\n this.menuContainer = React.createRef();\n this.button = React.createRef();\n this.input = React.createRef();\n\n this.state = {\n keyboardOptionIndex: 0,\n menuIsOpen: false,\n inputWidth: 100,\n customTime: valueToTime(value),\n inputFocused: false,\n };\n }\n\n csContainer: React.RefObject<HTMLDivElement>;\n\n menuContainer: React.RefObject<HTMLDivElement>;\n\n button: React.RefObject<HTMLButtonElement>;\n\n input: React.RefObject<TimeInputElement>;\n\n getSelectedText(): string {\n const { options, value, placeholder } = this.props;\n const { customTime } = this.state;\n\n if (value === null) {\n return placeholder;\n }\n\n for (let i = 0; i < options.length; i += 1) {\n const option = options[i];\n if (option.value === value) {\n return option.title;\n }\n }\n\n return TimeUtils.formatTime(customTime);\n }\n\n setInputWidth(): void {\n if (this.csContainer.current) {\n this.setState({\n inputWidth: this.csContainer.current.getBoundingClientRect().width,\n });\n }\n }\n\n focus(): void {\n this.button.current?.focus();\n }\n\n updateInputValue(value: number): void {\n const { onChange } = this.props;\n onChange(value);\n }\n\n handleResize(): void {\n this.setInputWidth();\n }\n\n handleMenuKeyDown(event: React.KeyboardEvent<HTMLDivElement>): void {\n const { keyboardOptionIndex, inputFocused } = this.state;\n const { options } = this.props;\n\n switch (event.key) {\n case 'Enter':\n case ' ': // Space Bar\n if (inputFocused) {\n this.updateFromCustom();\n } else {\n this.updateInputValue(options[keyboardOptionIndex].value);\n }\n this.closeMenu();\n this.button.current?.focus();\n event.stopPropagation();\n event.preventDefault();\n break;\n case 'Tab':\n if (event.shiftKey) {\n this.handleMenuNavigation(\n CustomTimeSelect.MENU_NAVIGATION_DIRECTION.UP\n );\n } else {\n this.handleMenuNavigation(\n CustomTimeSelect.MENU_NAVIGATION_DIRECTION.DOWN\n );\n }\n event.stopPropagation();\n event.preventDefault();\n break;\n case 'ArrowUp':\n this.handleMenuNavigation(\n CustomTimeSelect.MENU_NAVIGATION_DIRECTION.UP\n );\n event.stopPropagation();\n event.preventDefault();\n break;\n case 'ArrowDown':\n this.handleMenuNavigation(\n CustomTimeSelect.MENU_NAVIGATION_DIRECTION.DOWN\n );\n event.stopPropagation();\n event.preventDefault();\n break;\n case 'Escape':\n this.closeMenu();\n break;\n default:\n break;\n }\n }\n\n handleMenuNavigation(direction: MENU_NAVIGATION_DIRECTION): void {\n const { keyboardOptionIndex, inputFocused } = this.state;\n const { options } = this.props;\n const menuOptionsLength = options.length;\n let newKeyboardOptionIndex = keyboardOptionIndex;\n switch (direction) {\n case CustomTimeSelect.MENU_NAVIGATION_DIRECTION.UP:\n if (!inputFocused && keyboardOptionIndex === 0) {\n this.focusInput();\n break;\n } else if (inputFocused) {\n this.focusOption(keyboardOptionIndex);\n }\n\n if (keyboardOptionIndex > 0 && !inputFocused) {\n newKeyboardOptionIndex =\n (newKeyboardOptionIndex - 1) % menuOptionsLength;\n this.setState({\n keyboardOptionIndex: newKeyboardOptionIndex,\n });\n } else if (keyboardOptionIndex === 0) {\n newKeyboardOptionIndex = menuOptionsLength - 1;\n this.setState({\n keyboardOptionIndex: newKeyboardOptionIndex,\n });\n }\n this.scrollOptionIntoView(newKeyboardOptionIndex);\n break;\n case CustomTimeSelect.MENU_NAVIGATION_DIRECTION.DOWN:\n if (!inputFocused && keyboardOptionIndex === menuOptionsLength - 1) {\n this.focusInput();\n break;\n } else if (inputFocused) {\n this.focusOption(keyboardOptionIndex);\n }\n\n if (\n keyboardOptionIndex < menuOptionsLength &&\n !(inputFocused && keyboardOptionIndex === 0)\n ) {\n newKeyboardOptionIndex =\n (newKeyboardOptionIndex + 1) % menuOptionsLength;\n this.setState({\n keyboardOptionIndex: newKeyboardOptionIndex,\n });\n }\n this.scrollOptionIntoView(newKeyboardOptionIndex);\n break;\n default:\n break;\n }\n }\n\n handleOptionClick(event: React.MouseEvent<HTMLButtonElement>): void {\n const optionIndex = Number(event.currentTarget.value);\n const { options, timeToValue } = this.props;\n const { customTime } = this.state;\n\n if (optionIndex === CUSTOM_OPTION) {\n const update = timeToValue(customTime);\n this.updateAndClose(update);\n } else {\n this.updateAndClose(options[optionIndex].value);\n }\n }\n\n updateAndClose(update: number): void {\n this.updateInputValue(update);\n this.closeMenu();\n this.button.current?.focus();\n }\n\n handleOptionFocus(event: React.FocusEvent<HTMLButtonElement>): void {\n this.setState({ keyboardOptionIndex: Number(event.target.value) });\n }\n\n handleMenuOpened(): void {\n const { options, value } = this.props;\n const { keyboardOptionIndex } = this.state;\n this.scrollOptionIntoView(keyboardOptionIndex);\n const activeOption = this.menuContainer.current?.querySelector(\n '.cs-option-btn.keyboard-active'\n );\n if (activeOption instanceof HTMLElement) {\n activeOption.focus();\n }\n\n if (value === null) {\n return;\n }\n const valueIndex = options.map(option => option.value).indexOf(value);\n if (valueIndex < 0) {\n // The custom option should be selected\n this.focusInput();\n }\n }\n\n focusInput(): void {\n this.input.current?.focus();\n }\n\n focusOption(index: number): void {\n const options = this.menuContainer.current?.querySelector('.cs-options');\n if (options && options.children) {\n const option = options.children.item(index);\n if (option instanceof HTMLElement) {\n option.focus();\n }\n }\n }\n\n handleMenuExited(): void {\n const { menuIsOpen } = this.state;\n if (menuIsOpen) {\n this.setState({ menuIsOpen: false, keyboardOptionIndex: 0 });\n }\n }\n\n handleCustomInput(value: number): void {\n const { timeToValue } = this.props;\n\n const update = timeToValue(value);\n this.updateInputValue(update);\n this.setState({\n customTime: value,\n });\n }\n\n updateFromCustom(): void {\n const { timeToValue } = this.props;\n const { customTime } = this.state;\n\n const update = timeToValue(customTime);\n this.updateInputValue(update);\n }\n\n toggleMenu(event: React.MouseEvent<HTMLButtonElement>): void {\n const { menuIsOpen } = this.state;\n if (menuIsOpen) {\n this.closeMenu();\n } else {\n this.openMenu();\n }\n event.stopPropagation();\n }\n\n openMenu(): void {\n this.updateKeyboardIndex();\n this.setInputWidth();\n this.setState({ menuIsOpen: true });\n }\n\n closeMenu(focusButton = true): void {\n this.setState({ menuIsOpen: false });\n if (focusButton) {\n this.button.current?.focus();\n }\n }\n\n updateKeyboardIndex(): void {\n const { options, value } = this.props;\n if (value === null) {\n return;\n }\n const valueIndex = options.map(option => option.value).indexOf(value);\n if (valueIndex > 0) {\n this.setState({ keyboardOptionIndex: valueIndex });\n }\n }\n\n scrollOptionIntoView(index: number): void {\n const options = this.menuContainer.current?.querySelector('.cs-options');\n if (options && options.children) {\n const activeOption = options.children.item(index);\n if (\n activeOption instanceof HTMLElement &&\n activeOption.offsetTop > CustomTimeSelect.DROP_DOWN_MENU_HEIGHT\n ) {\n options.scrollTop =\n activeOption.offsetTop - CustomTimeSelect.DROP_DOWN_MENU_HEIGHT;\n } else if (\n (activeOption instanceof HTMLElement && activeOption.offsetTop < 0) ||\n index === 0\n ) {\n options.scrollTop = 0;\n }\n }\n }\n\n renderMenuElement(): JSX.Element {\n const { inputWidth } = this.state;\n return (\n <div\n className=\"cs-menu-container\"\n ref={this.menuContainer}\n role=\"presentation\"\n onKeyDown={this.handleMenuKeyDown}\n onClick={event => {\n event.stopPropagation();\n }}\n style={{ width: inputWidth }}\n >\n <div className=\"cs-options-container\">\n <div className=\"cs-options\">{this.renderOptions()}</div>\n </div>\n </div>\n );\n }\n\n renderOptions(): React.ReactNode {\n const { options, value, icon, customText } = this.props;\n const { keyboardOptionIndex, customTime, inputFocused } = this.state;\n\n let matchFound = false;\n const optionArray: JSX.Element[] = [];\n for (let index = 0; index < options.length; index += 1) {\n const option = options[index];\n const key = `option-${index}-${option.value}`;\n matchFound = matchFound || option.value === value;\n optionArray.push(\n <button\n key={key}\n type=\"button\"\n value={index}\n className={classNames('cs-option-btn', {\n 'keyboard-active': keyboardOptionIndex === index && !inputFocused,\n })}\n onClick={this.handleOptionClick}\n onFocus={this.handleOptionFocus}\n >\n {option.value === value && (\n <FontAwesomeIcon icon={icon} className=\"mr-2\" />\n )}\n {option.value !== value && <span className=\"mr-4\" />}\n {option.title}\n </button>\n );\n }\n\n optionArray.push(<hr className=\"cs-divider\" key=\"option-divider\" />);\n\n optionArray.push(\n <button\n key=\"option-custom-label\"\n type=\"button\"\n value={CUSTOM_OPTION}\n className={classNames('cs-option-btn', {\n 'keyboard-active': inputFocused,\n })}\n onClick={this.handleOptionClick}\n onFocus={this.handleOptionFocus}\n >\n {!matchFound && value !== null ? (\n <FontAwesomeIcon icon={icon} className=\"mr-2\" />\n ) : (\n <span className=\"mr-4\" />\n )}\n {customText}\n </button>\n );\n\n optionArray.push(\n <div key=\"cs-custom-container\" className=\"cs-custom-container\">\n <span className=\"mr-2\" />\n <TimeInput\n key=\"option-input\"\n ref={this.input}\n onChange={this.handleCustomInput}\n value={customTime}\n onFocus={() => this.setState({ inputFocused: true })}\n onBlur={() => this.setState({ inputFocused: false })}\n />\n <span className=\"ml-2\" />\n </div>\n );\n\n optionArray.push(<hr key=\"option-end\" className=\"mb-2\" />);\n\n return optionArray;\n }\n\n render(): JSX.Element {\n const { disabled, invalid, value, 'data-testid': dataTestId } = this.props;\n const { menuIsOpen } = this.state;\n let { popperOptions } = this.props;\n popperOptions = {\n placement: 'bottom-end',\n modifiers: {\n preventOverflow: { enabled: false },\n },\n ...popperOptions,\n };\n\n return (\n <div\n className=\"input-group cs-container context-menu\"\n ref={this.csContainer}\n data-testid={dataTestId}\n >\n <div\n className={classNames('input-group-append cs-dropdown', {\n 'cs-dropdown-invalid': invalid,\n })}\n >\n <button\n type=\"button\"\n className={classNames('btn cs-btn form-control', {\n 'cs-btn-invalid': invalid,\n })}\n ref={this.button}\n onClick={this.toggleMenu}\n disabled={disabled}\n >\n <span\n className={classNames({\n 'text-muted': value === null,\n })}\n >\n {this.getSelectedText()}\n </span>\n <span>\n <FontAwesomeIcon icon={dhSort} className=\"cs-caret\" />\n </span>\n <DropdownMenu\n isShown={menuIsOpen}\n actions={{ menuElement: this.renderMenuElement() }}\n popperOptions={popperOptions}\n popperClassName=\"CustomTimeSelect\"\n onMenuOpened={this.handleMenuOpened}\n onMenuClosed={this.handleMenuExited}\n menuStyle={{ maxWidth: '100rem' }}\n />\n </button>\n </div>\n </div>\n );\n }\n}\n\nexport default CustomTimeSelect;\n"],"file":"CustomTimeSelect.js"}
@@ -1 +1 @@
1
- {"version":3,"file":"MaskedInput.d.ts","sourceRoot":"","sources":["../src/MaskedInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6B,MAAM,OAAO,CAAC;AAIlD,OAAO,oBAAoB,CAAC;AAI5B,QAAA,MAAM,mBAAmB;;;;CAIf,CAAC;AAQX,wBAAgB,wCAAwC,CACtD,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,MAAM,CAMR;AAED,oBAAY,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,mBAAmB,CAAC,MAAM,OAAO,mBAAmB,CAAC,CAAC;CACnF,CAAC;AAEF,aAAK,gBAAgB,GAAG;IACtB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,2IAA2I;IAC3I,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,iDAAiD;IACjD,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,oCAAoC;IACpC,QAAQ,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC3C,qDAAqD;IACrD,mBAAmB,CAAC,CAClB,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,GACZ,MAAM,CAAC;IACV,6BAA6B,CAAC,CAC5B,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,GACnB,MAAM,CAAC;IACV,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAClC,MAAM,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAEjC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;GAGG;AAIH,QAAA,MAAM,WAAW,2FAiahB,CAAC;AAsBF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"MaskedInput.d.ts","sourceRoot":"","sources":["../src/MaskedInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA0C,MAAM,OAAO,CAAC;AAI/D,OAAO,oBAAoB,CAAC;AAI5B,QAAA,MAAM,mBAAmB;;;;CAIf,CAAC;AAQX,wBAAgB,wCAAwC,CACtD,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,MAAM,CAMR;AAED,oBAAY,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,mBAAmB,CAAC,MAAM,OAAO,mBAAmB,CAAC,CAAC;CACnF,CAAC;AAEF,aAAK,gBAAgB,GAAG;IACtB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,2IAA2I;IAC3I,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,iDAAiD;IACjD,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,oCAAoC;IACpC,QAAQ,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC3C,qDAAqD;IACrD,mBAAmB,CAAC,CAClB,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,GACZ,MAAM,CAAC;IACV,6BAA6B,CAAC,CAC5B,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,GACnB,MAAM,CAAC;IACV,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAClC,MAAM,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAEjC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;GAGG;AAIH,QAAA,MAAM,WAAW,2FAubhB,CAAC;AAsBF,eAAe,WAAW,CAAC"}
@@ -1,4 +1,10 @@
1
- import React, { useMemo, useEffect } from 'react';
1
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
+
3
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
+
5
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+
7
+ import React, { useMemo, useEffect, useCallback } from 'react';
2
8
  import classNames from 'classnames';
3
9
  import Log from '@deephaven/log';
4
10
  import { useForwardedRef } from '@deephaven/react-hooks';
@@ -62,7 +68,7 @@ var MaskedInput = /*#__PURE__*/React.forwardRef((props, ref) => {
62
68
  * @param cursorPosition The current position of the cursor
63
69
  */
64
70
 
65
- function getSegment(cursorPosition) {
71
+ var getSegment = useCallback(cursorPosition => {
66
72
  var selectionStart = cursorPosition;
67
73
  var selectionEnd = cursorPosition;
68
74
  var testValue = examples.length > 0 ? examples[0] : value;
@@ -89,7 +95,7 @@ var MaskedInput = /*#__PURE__*/React.forwardRef((props, ref) => {
89
95
  selectionEnd,
90
96
  selectionDirection
91
97
  };
92
- }
98
+ }, [examples, value]);
93
99
  /**
94
100
  * Replaces all blank spaces and everything after the current cursor position with the example value
95
101
  * @param checkValue The value to check/fill in
@@ -98,7 +104,6 @@ var MaskedInput = /*#__PURE__*/React.forwardRef((props, ref) => {
98
104
  * @returns The filled in value
99
105
  */
100
106
 
101
-
102
107
  function fillValue(checkValue, exampleValue) {
103
108
  var cursorPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : checkValue.length;
104
109
  var filledValue = '';
@@ -187,7 +192,7 @@ var MaskedInput = /*#__PURE__*/React.forwardRef((props, ref) => {
187
192
  }
188
193
  }
189
194
 
190
- function handleSelect(event) {
195
+ var handleSelect = useCallback(event => {
191
196
  var {
192
197
  selectionStart = 0,
193
198
  selectionEnd = 0,
@@ -205,6 +210,15 @@ var MaskedInput = /*#__PURE__*/React.forwardRef((props, ref) => {
205
210
  return;
206
211
  }
207
212
 
213
+ if (selection != null && selectionStart === value.length && selectionEnd === value.length && event.nativeEvent.type !== 'mouseup') {
214
+ // React triggers onSelect event with the cursor at the end of the input content
215
+ // when the component is rendered at a different location in the DOM,
216
+ // i.e. when start/end times switch places in the TimeSlider.
217
+ // Ignore this event and reset the selection to its previous state.
218
+ onSelect(_objectSpread({}, selection));
219
+ return;
220
+ }
221
+
208
222
  if (selectionStart === selectionEnd) {
209
223
  var newSelection = getSegment(selectionStart);
210
224
  log.debug('Selection segment from ', selectionStart, selectionEnd, '=>', newSelection);
@@ -216,9 +230,8 @@ var MaskedInput = /*#__PURE__*/React.forwardRef((props, ref) => {
216
230
  selectionDirection
217
231
  });
218
232
  }
219
- }
220
-
221
- function handleSelectCapture(event) {
233
+ }, [getSegment, onSelect, selection, value]);
234
+ var handleSelectCapture = useCallback(event => {
222
235
  if (!input.current) {
223
236
  return;
224
237
  }
@@ -230,7 +243,7 @@ var MaskedInput = /*#__PURE__*/React.forwardRef((props, ref) => {
230
243
  event.preventDefault();
231
244
  event.stopPropagation();
232
245
  }
233
- }
246
+ }, [input, selection, value]);
234
247
 
235
248
  function handleArrowKey(event) {
236
249
  event.preventDefault();
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/MaskedInput.tsx"],"names":["React","useMemo","useEffect","classNames","Log","useForwardedRef","log","module","SELECTION_DIRECTION","FORWARD","BACKWARD","NONE","FIXED_WIDTH_SPACE","DEFAULT_GET_PREFERRED_REPLACEMENT_STRING","value","replaceIndex","newChar","substring","MaskedInput","forwardRef","props","ref","className","example","getNextSegmentValue","range","delta","segmentValue","getPreferredReplacementString","onChange","onSelect","pattern","selection","onFocus","onBlur","dataTestId","input","examples","Array","isArray","setSelectedSegment","debug","selectionStart","selectionEnd","selectionDirection","current","setSelectionRange","getSegment","cursorPosition","testValue","length","i","test","charAt","fillValue","checkValue","exampleValue","filledValue","concat","isValid","patternRegex","RegExp","nextSegment","position","currentSegment","nextPosition","previousSegment","previousPosition","nextSegmentValue","segment","newSegmentValue","newValue","handleSelect","event","target","error","debug2","newSelection","handleSelectCapture","preventDefault","stopPropagation","handleArrowKey","key","handleKeyDown","startsWith","replace","altKey","metaKey","ctrlKey","newChars","from","Set","toUpperCase","toLowerCase","maxReplaceIndex","newSelectionStart","nextSegmentSelection","undefined","defaultProps"],"mappings":"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","sourcesContent":["import React, { useMemo, useEffect } from 'react';\nimport classNames from 'classnames';\nimport Log from '@deephaven/log';\nimport { useForwardedRef } from '@deephaven/react-hooks';\nimport './MaskedInput.scss';\n\nconst log = Log.module('MaskedInput');\n\nconst SELECTION_DIRECTION = {\n FORWARD: 'forward',\n BACKWARD: 'backward',\n NONE: 'none',\n} as const;\n\n/**\n * Special space character that's the same size as tabular numbers\n * https://www.fileformat.info/info/unicode/char/2007/index.htm\n */\nconst FIXED_WIDTH_SPACE = '\\u2007';\n\nexport function DEFAULT_GET_PREFERRED_REPLACEMENT_STRING(\n value: string,\n replaceIndex: number,\n newChar: string\n): string {\n return (\n value.substring(0, replaceIndex) +\n newChar +\n value.substring(replaceIndex + 1)\n );\n}\n\nexport type SelectionSegment = {\n selectionStart: number;\n selectionEnd: number;\n selectionDirection?: typeof SELECTION_DIRECTION[keyof typeof SELECTION_DIRECTION];\n};\n\ntype MaskedInputProps = {\n /** An extra class name to add to the component */\n className?: string;\n /** The regex pattern this masked input must match */\n pattern: string;\n /** The current value to display */\n value: string;\n /** One or more examples of valid values. Used when deciding if next keystroke is valid (as rest of the current value may be incomplete) */\n example: string | string[];\n /** The current selection to use for the input */\n selection?: SelectionSegment;\n /** Called when the value changes. Note the value may still be incomplete. */\n onChange?(value: string): void;\n /** Called when selection changes */\n onSelect?(segment: SelectionSegment): void;\n /** Retrieve the next value for a provided segment */\n getNextSegmentValue?(\n segment: SelectionSegment,\n delta: number,\n segmentValue: string,\n value: string\n ): string;\n getPreferredReplacementString?(\n value: string,\n replaceIndex: number,\n replaceChar: string,\n selectionStart: number,\n selectionEnd: number\n ): string;\n onFocus?: React.FocusEventHandler;\n onBlur?: React.FocusEventHandler;\n\n 'data-testid'?: string;\n};\n\n/**\n * A masked input for entering data from a template.\n * Won't work by itself, must use within another component and handle updating the value/selection.\n */\n// Forward ref causes a false positive for display-name in eslint:\n// https://github.com/yannickcr/eslint-plugin-react/issues/2269\n// eslint-disable-next-line react/display-name\nconst MaskedInput = React.forwardRef<HTMLInputElement, MaskedInputProps>(\n (props: MaskedInputProps, ref) => {\n const {\n className,\n example,\n getNextSegmentValue = (range, delta, segmentValue) => segmentValue,\n getPreferredReplacementString = DEFAULT_GET_PREFERRED_REPLACEMENT_STRING,\n onChange = () => false,\n onSelect = () => false,\n pattern,\n selection,\n value,\n onFocus = () => false,\n onBlur = () => false,\n 'data-testid': dataTestId,\n } = props;\n const input = useForwardedRef(ref);\n const examples = useMemo(\n () => (Array.isArray(example) ? example : [example]),\n [example]\n );\n\n useEffect(\n function setSelectedSegment() {\n if (selection != null) {\n log.debug('setting selection...', selection);\n const {\n selectionStart,\n selectionEnd,\n selectionDirection,\n } = selection;\n input.current?.setSelectionRange(\n selectionStart,\n selectionEnd,\n selectionDirection\n );\n log.debug('selection set!');\n }\n },\n [selection, input]\n );\n\n /**\n * Returns the selection range for the segment at the given cursor position\n * @param cursorPosition The current position of the cursor\n */\n function getSegment(cursorPosition: number) {\n let selectionStart = cursorPosition;\n let selectionEnd = cursorPosition;\n const testValue = examples.length > 0 ? examples[0] : value;\n\n for (let i = selectionStart - 1; i >= 0; i -= 1) {\n if (!/[a-zA-Z0-9]/g.test(testValue.charAt(i))) {\n break;\n }\n\n selectionStart = i;\n }\n\n for (let i = selectionEnd; i < testValue.length; i += 1) {\n if (!/[a-zA-Z0-9]/g.test(testValue.charAt(i))) {\n break;\n }\n\n selectionEnd = i + 1;\n }\n\n const selectionDirection =\n selectionStart === selectionEnd\n ? SELECTION_DIRECTION.NONE\n : SELECTION_DIRECTION.BACKWARD;\n\n return {\n selectionStart,\n selectionEnd,\n selectionDirection,\n };\n }\n\n /**\n * Replaces all blank spaces and everything after the current cursor position with the example value\n * @param checkValue The value to check/fill in\n * @param exampleValue The example to fill in the value from\n * @param cursorPosition The cursor position\n * @returns The filled in value\n */\n function fillValue(\n checkValue: string,\n exampleValue: string,\n cursorPosition = checkValue.length\n ): string {\n let filledValue = '';\n for (let i = 0; i < cursorPosition; i += 1) {\n if (checkValue.charAt(i) !== FIXED_WIDTH_SPACE) {\n filledValue = filledValue.concat(checkValue[i]);\n } else {\n filledValue = filledValue.concat(exampleValue[i]);\n }\n }\n filledValue = filledValue.concat(exampleValue.substring(cursorPosition));\n\n return filledValue;\n }\n\n /**\n * Checks if a given `value` is valid up until the `cursorPosition`.\n * Uses the examples to build the rest of the string\n * @param checkValue The value to check validity of\n * @param cursorPosition The position of the cursor to check up to\n */\n function isValid(\n checkValue: string,\n cursorPosition = checkValue.length\n ): boolean {\n const patternRegex = new RegExp(pattern);\n if (patternRegex.test(checkValue)) {\n return true;\n }\n\n for (let i = 0; i < examples.length; i += 1) {\n const filledValue = fillValue(checkValue, examples[i], cursorPosition);\n if (patternRegex.test(filledValue)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Returns the next segment after the given position\n * @param position The cursor position to start at\n * @returns The new selection range\n */\n function nextSegment(position: number): SelectionSegment {\n const currentSegment = getSegment(position);\n const nextPosition = currentSegment.selectionEnd + 1;\n if (nextPosition >= value.length) {\n return currentSegment;\n }\n\n return getSegment(nextPosition);\n }\n\n /**\n * Returns the previous segment before the given position\n * @param position The cursor position to start at\n * @returns The new selection range\n */\n function previousSegment(position: number): SelectionSegment {\n const currentSegment = getSegment(position);\n const previousPosition = currentSegment.selectionStart - 1;\n if (previousPosition <= 0) {\n return currentSegment;\n }\n\n return getSegment(previousPosition);\n }\n\n function nextSegmentValue(position: number, delta: number): void {\n const segment = getSegment(position);\n const segmentValue = value.substring(\n segment.selectionStart,\n segment.selectionEnd\n );\n const newSegmentValue = getNextSegmentValue(\n segment,\n delta,\n segmentValue,\n value\n );\n const newValue =\n value.substring(0, segment.selectionStart) +\n newSegmentValue +\n value.substring(segment.selectionEnd);\n if (isValid(newValue, segment.selectionEnd)) {\n onChange(newValue);\n onSelect(segment);\n }\n }\n\n function handleSelect(event: React.UIEvent<HTMLInputElement>) {\n const {\n selectionStart = 0,\n selectionEnd = 0,\n selectionDirection = 'none',\n } = event.target as HTMLInputElement;\n\n if (\n selectionStart === null ||\n selectionEnd === null ||\n selectionDirection === null\n ) {\n log.error(\n 'Selection attempted on non-text input element',\n event.target\n );\n return;\n }\n\n log.debug2(\n 'handleSelect',\n selectionStart,\n selectionEnd,\n selectionDirection\n );\n if (\n selection != null &&\n selectionStart === selection.selectionStart &&\n selectionEnd === selection.selectionEnd\n ) {\n return;\n }\n if (selectionStart === selectionEnd) {\n const newSelection = getSegment(selectionStart);\n log.debug(\n 'Selection segment from ',\n selectionStart,\n selectionEnd,\n '=>',\n newSelection\n );\n onSelect(newSelection);\n } else {\n onSelect({ selectionStart, selectionEnd, selectionDirection });\n }\n }\n\n function handleSelectCapture(event: React.UIEvent<HTMLInputElement>) {\n if (!input.current) {\n return;\n }\n log.debug('handleSelectCapture', event);\n const selectionStart = input.current.selectionStart || 0;\n if (\n selectionStart === value.length &&\n selection != null &&\n selectionStart !== selection.selectionStart\n ) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n\n function handleArrowKey(event: React.KeyboardEvent<HTMLInputElement>) {\n event.preventDefault();\n event.stopPropagation();\n\n if (!input.current) {\n return;\n }\n\n const { key } = event;\n const { selectionStart = 0, selectionEnd = 0 } = input.current;\n if (selectionStart === null || selectionEnd === null) {\n log.error(\n 'Selection arrow nvaigation attempted on non-text input element',\n event.target\n );\n return;\n }\n\n if (key === 'ArrowLeft') {\n onSelect(previousSegment(selectionStart));\n } else if (key === 'ArrowRight') {\n onSelect(nextSegment(selectionEnd));\n } else if (key === 'ArrowUp') {\n nextSegmentValue(selectionStart, -1);\n } else if (key === 'ArrowDown') {\n nextSegmentValue(selectionStart, 1);\n }\n }\n\n function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>) {\n if (!input.current) {\n return;\n }\n log.debug('handleKeyDown', event);\n const { key } = event;\n const { selectionStart = 0, selectionEnd = 0 } = input.current;\n if (selectionStart === null || selectionEnd === null) {\n log.error(\n 'Selection key event on non-text input element',\n event.target\n );\n return;\n }\n\n if (key.startsWith('Arrow')) {\n handleArrowKey(event);\n return;\n }\n\n if (key === 'Delete' || key === 'Backspace') {\n event.preventDefault();\n event.stopPropagation();\n\n if (selectionStart !== selectionEnd) {\n // Replace all non-masked characters with blanks, set selection to start\n const newValue =\n value.substring(0, selectionStart) +\n value\n .substring(selectionStart, selectionEnd)\n .replace(/[a-zA-Z0-9]/g, FIXED_WIDTH_SPACE) +\n value.substring(selectionEnd);\n log.debug(\n 'Range ',\n selectionStart,\n selectionEnd,\n 'deleted, setting value',\n newValue\n );\n\n onChange(newValue);\n onSelect({\n selectionStart,\n selectionEnd: selectionStart,\n selectionDirection: SELECTION_DIRECTION.NONE,\n });\n } else if (selectionStart > 0) {\n for (let i = selectionStart - 1; i >= 0; i -= 1) {\n // Only replace non placeholder text\n const newValue =\n value.substring(0, i) +\n value\n .substring(i, selectionStart)\n .replace(/[a-zA-Z0-9]/g, FIXED_WIDTH_SPACE) +\n value.substring(selectionStart);\n\n if (newValue !== value) {\n onChange(newValue);\n onSelect({\n selectionStart: i,\n selectionEnd: i,\n selectionDirection: SELECTION_DIRECTION.NONE,\n });\n return;\n }\n }\n }\n\n return;\n }\n\n if (event.altKey || event.metaKey || event.ctrlKey || key.length > 1) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n // Get the different permutations of the character they entered, remove duplicates\n const newChars = Array.from(\n new Set([key, key.toUpperCase(), key.toLowerCase()])\n );\n for (let i = 0; i < newChars.length; i += 1) {\n const newChar = newChars[i];\n\n // If they're typing an alphanumeric character, be smart and allow it to jump ahead\n const maxReplaceIndex = /[a-zA-Z0-9]/g.test(newChar)\n ? value.length - 1\n : selectionStart;\n for (\n let replaceIndex = selectionStart;\n replaceIndex <= maxReplaceIndex;\n replaceIndex += 1\n ) {\n const newValue = getPreferredReplacementString(\n value,\n replaceIndex,\n newChar,\n selectionStart,\n selectionEnd\n );\n if (isValid(newValue, replaceIndex + 1)) {\n const currentSegment = getSegment(replaceIndex);\n const newSelectionStart = replaceIndex + 1;\n let newSelection: SelectionSegment = {\n selectionStart: newSelectionStart,\n selectionEnd: newSelectionStart,\n selectionDirection: SELECTION_DIRECTION.NONE,\n };\n if (newSelectionStart >= currentSegment.selectionEnd) {\n const nextSegmentSelection = nextSegment(replaceIndex);\n if (\n nextSegmentSelection.selectionStart !==\n currentSegment.selectionStart\n ) {\n newSelection = nextSegmentSelection;\n }\n }\n log.debug('handleKeyDown', key, '=>', newValue, newSelection);\n onChange(newValue);\n onSelect(newSelection);\n return;\n }\n }\n }\n }\n\n // Need to use \"text\" type so we can apply a pattern and make selection properly\n return (\n <input\n ref={input}\n className={classNames('form-control masked-input', className)}\n type=\"text\"\n pattern={pattern}\n value={value}\n onChange={() => undefined}\n onKeyDown={handleKeyDown}\n onSelect={handleSelect}\n onSelectCapture={handleSelectCapture}\n onFocus={onFocus}\n onBlur={onBlur}\n data-testid={dataTestId}\n />\n );\n }\n);\n\nMaskedInput.defaultProps = {\n className: '',\n onChange(): void {\n // no-op\n },\n onSelect(): void {\n // no-op\n },\n getNextSegmentValue: (range, delta, segmentValue) => segmentValue,\n getPreferredReplacementString: DEFAULT_GET_PREFERRED_REPLACEMENT_STRING,\n selection: undefined,\n onFocus(): void {\n // no-op\n },\n onBlur(): void {\n // no-op\n },\n 'data-testid': undefined,\n};\n\nexport default MaskedInput;\n"],"file":"MaskedInput.js"}
1
+ {"version":3,"sources":["../src/MaskedInput.tsx"],"names":["React","useMemo","useEffect","useCallback","classNames","Log","useForwardedRef","log","module","SELECTION_DIRECTION","FORWARD","BACKWARD","NONE","FIXED_WIDTH_SPACE","DEFAULT_GET_PREFERRED_REPLACEMENT_STRING","value","replaceIndex","newChar","substring","MaskedInput","forwardRef","props","ref","className","example","getNextSegmentValue","range","delta","segmentValue","getPreferredReplacementString","onChange","onSelect","pattern","selection","onFocus","onBlur","dataTestId","input","examples","Array","isArray","setSelectedSegment","debug","selectionStart","selectionEnd","selectionDirection","current","setSelectionRange","getSegment","cursorPosition","testValue","length","i","test","charAt","fillValue","checkValue","exampleValue","filledValue","concat","isValid","patternRegex","RegExp","nextSegment","position","currentSegment","nextPosition","previousSegment","previousPosition","nextSegmentValue","segment","newSegmentValue","newValue","handleSelect","event","target","error","debug2","nativeEvent","type","newSelection","handleSelectCapture","preventDefault","stopPropagation","handleArrowKey","key","handleKeyDown","startsWith","replace","altKey","metaKey","ctrlKey","newChars","from","Set","toUpperCase","toLowerCase","maxReplaceIndex","newSelectionStart","nextSegmentSelection","undefined","defaultProps"],"mappings":"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","sourcesContent":["import React, { useMemo, useEffect, useCallback } from 'react';\nimport classNames from 'classnames';\nimport Log from '@deephaven/log';\nimport { useForwardedRef } from '@deephaven/react-hooks';\nimport './MaskedInput.scss';\n\nconst log = Log.module('MaskedInput');\n\nconst SELECTION_DIRECTION = {\n FORWARD: 'forward',\n BACKWARD: 'backward',\n NONE: 'none',\n} as const;\n\n/**\n * Special space character that's the same size as tabular numbers\n * https://www.fileformat.info/info/unicode/char/2007/index.htm\n */\nconst FIXED_WIDTH_SPACE = '\\u2007';\n\nexport function DEFAULT_GET_PREFERRED_REPLACEMENT_STRING(\n value: string,\n replaceIndex: number,\n newChar: string\n): string {\n return (\n value.substring(0, replaceIndex) +\n newChar +\n value.substring(replaceIndex + 1)\n );\n}\n\nexport type SelectionSegment = {\n selectionStart: number;\n selectionEnd: number;\n selectionDirection?: typeof SELECTION_DIRECTION[keyof typeof SELECTION_DIRECTION];\n};\n\ntype MaskedInputProps = {\n /** An extra class name to add to the component */\n className?: string;\n /** The regex pattern this masked input must match */\n pattern: string;\n /** The current value to display */\n value: string;\n /** One or more examples of valid values. Used when deciding if next keystroke is valid (as rest of the current value may be incomplete) */\n example: string | string[];\n /** The current selection to use for the input */\n selection?: SelectionSegment;\n /** Called when the value changes. Note the value may still be incomplete. */\n onChange?(value: string): void;\n /** Called when selection changes */\n onSelect?(segment: SelectionSegment): void;\n /** Retrieve the next value for a provided segment */\n getNextSegmentValue?(\n segment: SelectionSegment,\n delta: number,\n segmentValue: string,\n value: string\n ): string;\n getPreferredReplacementString?(\n value: string,\n replaceIndex: number,\n replaceChar: string,\n selectionStart: number,\n selectionEnd: number\n ): string;\n onFocus?: React.FocusEventHandler;\n onBlur?: React.FocusEventHandler;\n\n 'data-testid'?: string;\n};\n\n/**\n * A masked input for entering data from a template.\n * Won't work by itself, must use within another component and handle updating the value/selection.\n */\n// Forward ref causes a false positive for display-name in eslint:\n// https://github.com/yannickcr/eslint-plugin-react/issues/2269\n// eslint-disable-next-line react/display-name\nconst MaskedInput = React.forwardRef<HTMLInputElement, MaskedInputProps>(\n (props: MaskedInputProps, ref) => {\n const {\n className,\n example,\n getNextSegmentValue = (range, delta, segmentValue) => segmentValue,\n getPreferredReplacementString = DEFAULT_GET_PREFERRED_REPLACEMENT_STRING,\n onChange = () => false,\n onSelect = () => false,\n pattern,\n selection,\n value,\n onFocus = () => false,\n onBlur = () => false,\n 'data-testid': dataTestId,\n } = props;\n const input = useForwardedRef(ref);\n const examples = useMemo(\n () => (Array.isArray(example) ? example : [example]),\n [example]\n );\n\n useEffect(\n function setSelectedSegment() {\n if (selection != null) {\n log.debug('setting selection...', selection);\n const {\n selectionStart,\n selectionEnd,\n selectionDirection,\n } = selection;\n input.current?.setSelectionRange(\n selectionStart,\n selectionEnd,\n selectionDirection\n );\n log.debug('selection set!');\n }\n },\n [selection, input]\n );\n\n /**\n * Returns the selection range for the segment at the given cursor position\n * @param cursorPosition The current position of the cursor\n */\n const getSegment = useCallback(\n (cursorPosition: number) => {\n let selectionStart = cursorPosition;\n let selectionEnd = cursorPosition;\n const testValue = examples.length > 0 ? examples[0] : value;\n\n for (let i = selectionStart - 1; i >= 0; i -= 1) {\n if (!/[a-zA-Z0-9]/g.test(testValue.charAt(i))) {\n break;\n }\n\n selectionStart = i;\n }\n\n for (let i = selectionEnd; i < testValue.length; i += 1) {\n if (!/[a-zA-Z0-9]/g.test(testValue.charAt(i))) {\n break;\n }\n\n selectionEnd = i + 1;\n }\n\n const selectionDirection =\n selectionStart === selectionEnd\n ? SELECTION_DIRECTION.NONE\n : SELECTION_DIRECTION.BACKWARD;\n\n return {\n selectionStart,\n selectionEnd,\n selectionDirection,\n };\n },\n [examples, value]\n );\n\n /**\n * Replaces all blank spaces and everything after the current cursor position with the example value\n * @param checkValue The value to check/fill in\n * @param exampleValue The example to fill in the value from\n * @param cursorPosition The cursor position\n * @returns The filled in value\n */\n function fillValue(\n checkValue: string,\n exampleValue: string,\n cursorPosition = checkValue.length\n ): string {\n let filledValue = '';\n for (let i = 0; i < cursorPosition; i += 1) {\n if (checkValue.charAt(i) !== FIXED_WIDTH_SPACE) {\n filledValue = filledValue.concat(checkValue[i]);\n } else {\n filledValue = filledValue.concat(exampleValue[i]);\n }\n }\n filledValue = filledValue.concat(exampleValue.substring(cursorPosition));\n\n return filledValue;\n }\n\n /**\n * Checks if a given `value` is valid up until the `cursorPosition`.\n * Uses the examples to build the rest of the string\n * @param checkValue The value to check validity of\n * @param cursorPosition The position of the cursor to check up to\n */\n function isValid(\n checkValue: string,\n cursorPosition = checkValue.length\n ): boolean {\n const patternRegex = new RegExp(pattern);\n if (patternRegex.test(checkValue)) {\n return true;\n }\n\n for (let i = 0; i < examples.length; i += 1) {\n const filledValue = fillValue(checkValue, examples[i], cursorPosition);\n if (patternRegex.test(filledValue)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Returns the next segment after the given position\n * @param position The cursor position to start at\n * @returns The new selection range\n */\n function nextSegment(position: number): SelectionSegment {\n const currentSegment = getSegment(position);\n const nextPosition = currentSegment.selectionEnd + 1;\n if (nextPosition >= value.length) {\n return currentSegment;\n }\n\n return getSegment(nextPosition);\n }\n\n /**\n * Returns the previous segment before the given position\n * @param position The cursor position to start at\n * @returns The new selection range\n */\n function previousSegment(position: number): SelectionSegment {\n const currentSegment = getSegment(position);\n const previousPosition = currentSegment.selectionStart - 1;\n if (previousPosition <= 0) {\n return currentSegment;\n }\n\n return getSegment(previousPosition);\n }\n\n function nextSegmentValue(position: number, delta: number): void {\n const segment = getSegment(position);\n const segmentValue = value.substring(\n segment.selectionStart,\n segment.selectionEnd\n );\n const newSegmentValue = getNextSegmentValue(\n segment,\n delta,\n segmentValue,\n value\n );\n const newValue =\n value.substring(0, segment.selectionStart) +\n newSegmentValue +\n value.substring(segment.selectionEnd);\n if (isValid(newValue, segment.selectionEnd)) {\n onChange(newValue);\n onSelect(segment);\n }\n }\n\n const handleSelect = useCallback(\n (event: React.UIEvent<HTMLInputElement>) => {\n const {\n selectionStart = 0,\n selectionEnd = 0,\n selectionDirection = 'none',\n } = event.target as HTMLInputElement;\n\n if (\n selectionStart === null ||\n selectionEnd === null ||\n selectionDirection === null\n ) {\n log.error(\n 'Selection attempted on non-text input element',\n event.target\n );\n return;\n }\n\n log.debug2(\n 'handleSelect',\n selectionStart,\n selectionEnd,\n selectionDirection\n );\n if (\n selection != null &&\n selectionStart === selection.selectionStart &&\n selectionEnd === selection.selectionEnd\n ) {\n return;\n }\n if (\n selection != null &&\n selectionStart === value.length &&\n selectionEnd === value.length &&\n event.nativeEvent.type !== 'mouseup'\n ) {\n // React triggers onSelect event with the cursor at the end of the input content\n // when the component is rendered at a different location in the DOM,\n // i.e. when start/end times switch places in the TimeSlider.\n // Ignore this event and reset the selection to its previous state.\n onSelect({ ...selection });\n return;\n }\n if (selectionStart === selectionEnd) {\n const newSelection = getSegment(selectionStart);\n log.debug(\n 'Selection segment from ',\n selectionStart,\n selectionEnd,\n '=>',\n newSelection\n );\n onSelect(newSelection);\n } else {\n onSelect({ selectionStart, selectionEnd, selectionDirection });\n }\n },\n [getSegment, onSelect, selection, value]\n );\n\n const handleSelectCapture = useCallback(\n (event: React.UIEvent<HTMLInputElement>) => {\n if (!input.current) {\n return;\n }\n log.debug('handleSelectCapture', event);\n const selectionStart = input.current.selectionStart || 0;\n if (\n selectionStart === value.length &&\n selection != null &&\n selectionStart !== selection.selectionStart\n ) {\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [input, selection, value]\n );\n\n function handleArrowKey(event: React.KeyboardEvent<HTMLInputElement>) {\n event.preventDefault();\n event.stopPropagation();\n\n if (!input.current) {\n return;\n }\n\n const { key } = event;\n const { selectionStart = 0, selectionEnd = 0 } = input.current;\n if (selectionStart === null || selectionEnd === null) {\n log.error(\n 'Selection arrow nvaigation attempted on non-text input element',\n event.target\n );\n return;\n }\n\n if (key === 'ArrowLeft') {\n onSelect(previousSegment(selectionStart));\n } else if (key === 'ArrowRight') {\n onSelect(nextSegment(selectionEnd));\n } else if (key === 'ArrowUp') {\n nextSegmentValue(selectionStart, -1);\n } else if (key === 'ArrowDown') {\n nextSegmentValue(selectionStart, 1);\n }\n }\n\n function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>) {\n if (!input.current) {\n return;\n }\n log.debug('handleKeyDown', event);\n const { key } = event;\n const { selectionStart = 0, selectionEnd = 0 } = input.current;\n if (selectionStart === null || selectionEnd === null) {\n log.error(\n 'Selection key event on non-text input element',\n event.target\n );\n return;\n }\n\n if (key.startsWith('Arrow')) {\n handleArrowKey(event);\n return;\n }\n\n if (key === 'Delete' || key === 'Backspace') {\n event.preventDefault();\n event.stopPropagation();\n\n if (selectionStart !== selectionEnd) {\n // Replace all non-masked characters with blanks, set selection to start\n const newValue =\n value.substring(0, selectionStart) +\n value\n .substring(selectionStart, selectionEnd)\n .replace(/[a-zA-Z0-9]/g, FIXED_WIDTH_SPACE) +\n value.substring(selectionEnd);\n log.debug(\n 'Range ',\n selectionStart,\n selectionEnd,\n 'deleted, setting value',\n newValue\n );\n\n onChange(newValue);\n onSelect({\n selectionStart,\n selectionEnd: selectionStart,\n selectionDirection: SELECTION_DIRECTION.NONE,\n });\n } else if (selectionStart > 0) {\n for (let i = selectionStart - 1; i >= 0; i -= 1) {\n // Only replace non placeholder text\n const newValue =\n value.substring(0, i) +\n value\n .substring(i, selectionStart)\n .replace(/[a-zA-Z0-9]/g, FIXED_WIDTH_SPACE) +\n value.substring(selectionStart);\n\n if (newValue !== value) {\n onChange(newValue);\n onSelect({\n selectionStart: i,\n selectionEnd: i,\n selectionDirection: SELECTION_DIRECTION.NONE,\n });\n return;\n }\n }\n }\n\n return;\n }\n\n if (event.altKey || event.metaKey || event.ctrlKey || key.length > 1) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n // Get the different permutations of the character they entered, remove duplicates\n const newChars = Array.from(\n new Set([key, key.toUpperCase(), key.toLowerCase()])\n );\n for (let i = 0; i < newChars.length; i += 1) {\n const newChar = newChars[i];\n\n // If they're typing an alphanumeric character, be smart and allow it to jump ahead\n const maxReplaceIndex = /[a-zA-Z0-9]/g.test(newChar)\n ? value.length - 1\n : selectionStart;\n for (\n let replaceIndex = selectionStart;\n replaceIndex <= maxReplaceIndex;\n replaceIndex += 1\n ) {\n const newValue = getPreferredReplacementString(\n value,\n replaceIndex,\n newChar,\n selectionStart,\n selectionEnd\n );\n if (isValid(newValue, replaceIndex + 1)) {\n const currentSegment = getSegment(replaceIndex);\n const newSelectionStart = replaceIndex + 1;\n let newSelection: SelectionSegment = {\n selectionStart: newSelectionStart,\n selectionEnd: newSelectionStart,\n selectionDirection: SELECTION_DIRECTION.NONE,\n };\n if (newSelectionStart >= currentSegment.selectionEnd) {\n const nextSegmentSelection = nextSegment(replaceIndex);\n if (\n nextSegmentSelection.selectionStart !==\n currentSegment.selectionStart\n ) {\n newSelection = nextSegmentSelection;\n }\n }\n log.debug('handleKeyDown', key, '=>', newValue, newSelection);\n onChange(newValue);\n onSelect(newSelection);\n return;\n }\n }\n }\n }\n\n // Need to use \"text\" type so we can apply a pattern and make selection properly\n return (\n <input\n ref={input}\n className={classNames('form-control masked-input', className)}\n type=\"text\"\n pattern={pattern}\n value={value}\n onChange={() => undefined}\n onKeyDown={handleKeyDown}\n onSelect={handleSelect}\n onSelectCapture={handleSelectCapture}\n onFocus={onFocus}\n onBlur={onBlur}\n data-testid={dataTestId}\n />\n );\n }\n);\n\nMaskedInput.defaultProps = {\n className: '',\n onChange(): void {\n // no-op\n },\n onSelect(): void {\n // no-op\n },\n getNextSegmentValue: (range, delta, segmentValue) => segmentValue,\n getPreferredReplacementString: DEFAULT_GET_PREFERRED_REPLACEMENT_STRING,\n selection: undefined,\n onFocus(): void {\n // no-op\n },\n onBlur(): void {\n // no-op\n },\n 'data-testid': undefined,\n};\n\nexport default MaskedInput;\n"],"file":"MaskedInput.js"}
@@ -1,13 +1,20 @@
1
1
  import React from 'react';
2
+ import { SelectionSegment } from './MaskedInput';
3
+ export type { SelectionSegment } from './MaskedInput';
2
4
  declare type TimeInputProps = {
3
5
  allowValueWrapping?: boolean;
4
6
  className?: string;
5
7
  onChange?(timeInSec: number): void;
8
+ onSelect?(selection: SelectionSegment): void;
6
9
  value?: number;
7
10
  onFocus?(): void;
8
11
  onBlur?(): void;
9
12
  'data-testid'?: string;
10
13
  };
11
- declare const TimeInput: React.ForwardRefExoticComponent<TimeInputProps & React.RefAttributes<HTMLInputElement>>;
14
+ export declare type TimeInputElement = {
15
+ focus: () => void;
16
+ setSelection: (newSelection: SelectionSegment) => void;
17
+ };
18
+ declare const TimeInput: React.ForwardRefExoticComponent<TimeInputProps & React.RefAttributes<TimeInputElement>>;
12
19
  export default TimeInput;
13
20
  //# sourceMappingURL=TimeInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TimeInput.d.ts","sourceRoot":"","sources":["../src/TimeInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAanD,aAAK,cAAc,GAAG;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,IAAI,IAAI,CAAC;IACjB,MAAM,CAAC,IAAI,IAAI,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAKF,QAAA,MAAM,SAAS,yFA8Fd,CAAC;AAYF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"TimeInput.d.ts","sourceRoot":"","sources":["../src/TimeInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AAGf,OAAoB,EAElB,gBAAgB,EACjB,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAOtD,aAAK,cAAc,GAAG;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,IAAI,IAAI,CAAC;IACjB,MAAM,CAAC,IAAI,IAAI,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,oBAAY,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,YAAY,EAAE,CAAC,YAAY,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACxD,CAAC;AAKF,QAAA,MAAM,SAAS,yFAmHd,CAAC;AAaF,eAAe,SAAS,CAAC"}
package/dist/TimeInput.js CHANGED
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
2
2
  import Log from '@deephaven/log';
3
3
  import { TimeUtils } from '@deephaven/utils';
4
4
  import MaskedInput, { DEFAULT_GET_PREFERRED_REPLACEMENT_STRING } from "./MaskedInput.js";
@@ -16,10 +16,26 @@ var TimeInput = /*#__PURE__*/React.forwardRef((props, ref) => {
16
16
  value: propsValue = 0,
17
17
  onFocus = () => false,
18
18
  onBlur = () => false,
19
+ onSelect = () => false,
19
20
  'data-testid': dataTestId
20
21
  } = props;
21
22
  var [value, setValue] = useState(TimeUtils.formatTime(propsValue));
22
- var [selection, setSelection] = useState();
23
+ var [selection, _setSelection] = useState();
24
+ var inputRef = useRef(null);
25
+ useImperativeHandle(ref, () => ({
26
+ focus: () => {
27
+ var _inputRef$current;
28
+
29
+ (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.focus();
30
+ },
31
+ setSelection: newSelection => {
32
+ var _inputRef$current2;
33
+
34
+ (_inputRef$current2 = inputRef.current) === null || _inputRef$current2 === void 0 ? void 0 : _inputRef$current2.focus();
35
+
36
+ _setSelection(newSelection);
37
+ }
38
+ }), []);
23
39
  useEffect(function setFormattedTime() {
24
40
  setValue(TimeUtils.formatTime(propsValue));
25
41
  }, [propsValue]);
@@ -59,12 +75,13 @@ var TimeInput = /*#__PURE__*/React.forwardRef((props, ref) => {
59
75
  }
60
76
  }
61
77
 
62
- function handleSelect(newSelection) {
63
- setSelection(newSelection);
64
- }
78
+ var handleSelect = useCallback(newSelection => {
79
+ _setSelection(newSelection);
65
80
 
81
+ onSelect(newSelection);
82
+ }, [onSelect]);
66
83
  return /*#__PURE__*/React.createElement(MaskedInput, {
67
- ref: ref,
84
+ ref: inputRef,
68
85
  className: className,
69
86
  example: EXAMPLES,
70
87
  getNextSegmentValue: getNextSegmentValue,
@@ -83,6 +100,7 @@ TimeInput.defaultProps = {
83
100
  allowValueWrapping: true,
84
101
  className: '',
85
102
  onChange: () => false,
103
+ onSelect: () => false,
86
104
  value: 0,
87
105
  onFocus: () => false,
88
106
  onBlur: () => false,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/TimeInput.tsx"],"names":["React","useEffect","useState","Log","TimeUtils","MaskedInput","DEFAULT_GET_PREFERRED_REPLACEMENT_STRING","log","module","TIME_PATTERN","EXAMPLES","TimeInput","forwardRef","props","ref","allowValueWrapping","className","onChange","value","propsValue","onFocus","onBlur","dataTestId","setValue","formatTime","selection","setSelection","setFormattedTime","getNextSegmentValue","range","delta","segmentValue","maxValue","selectionStart","newSegmentValue","parseInt","Number","isNaN","Math","min","max","padStart","getPreferredReplacementString","replaceValue","replaceIndex","newChar","selectionEnd","substring","handleChange","newValue","debug","isTimeString","parseTime","handleSelect","newSelection","defaultProps","undefined"],"mappings":"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","sourcesContent":["import React, { useEffect, useState } from 'react';\nimport Log from '@deephaven/log';\nimport { TimeUtils } from '@deephaven/utils';\nimport MaskedInput, {\n DEFAULT_GET_PREFERRED_REPLACEMENT_STRING,\n SelectionSegment,\n} from './MaskedInput';\n\nconst log = Log.module('TimeInput');\n\nconst TIME_PATTERN = '([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]';\nconst EXAMPLES = ['00:00:00', '12:34:56', '23:59:59'];\n\ntype TimeInputProps = {\n allowValueWrapping?: boolean;\n className?: string;\n onChange?(timeInSec: number): void;\n value?: number;\n onFocus?(): void;\n onBlur?(): void;\n 'data-testid'?: string;\n};\n\n// Forward ref causes a false positive for display-name in eslint:\n// https://github.com/yannickcr/eslint-plugin-react/issues/2269\n// eslint-disable-next-line react/display-name\nconst TimeInput = React.forwardRef<HTMLInputElement, TimeInputProps>(\n (props: TimeInputProps, ref) => {\n const {\n allowValueWrapping = true,\n className = '',\n onChange = () => false,\n value: propsValue = 0,\n onFocus = () => false,\n onBlur = () => false,\n 'data-testid': dataTestId,\n } = props;\n const [value, setValue] = useState(TimeUtils.formatTime(propsValue));\n const [selection, setSelection] = useState<SelectionSegment>();\n useEffect(\n function setFormattedTime() {\n setValue(TimeUtils.formatTime(propsValue));\n },\n [propsValue]\n );\n\n function getNextSegmentValue(\n range: SelectionSegment,\n delta: number,\n segmentValue: string\n ): string {\n // Delta is backward because negative Y is up\n const maxValue = range.selectionStart === 0 ? 24 : 60;\n let newSegmentValue = parseInt(segmentValue, 10) - delta;\n if (Number.isNaN(newSegmentValue)) {\n newSegmentValue = 0;\n } else if (allowValueWrapping) {\n // Add max value and re-mod so we don't get negative values after mod\n newSegmentValue = ((newSegmentValue % maxValue) + maxValue) % maxValue;\n } else {\n newSegmentValue = Math.min(Math.max(0, newSegmentValue), maxValue - 1);\n }\n return `${newSegmentValue}`.padStart(2, '0');\n }\n\n function getPreferredReplacementString(\n replaceValue: string,\n replaceIndex: number,\n newChar: string,\n selectionStart: number,\n selectionEnd: number\n ) {\n if (\n selectionStart === 0 &&\n selectionEnd === 2 &&\n replaceIndex === 1 &&\n parseInt(newChar, 10) > 1\n ) {\n // DH-10082 Special case for when typing `3` when it's already 12\n return `0${newChar}${replaceValue.substring(2)}`;\n }\n return DEFAULT_GET_PREFERRED_REPLACEMENT_STRING(\n replaceValue,\n replaceIndex,\n newChar\n );\n }\n\n function handleChange(newValue: string): void {\n log.debug('handleChange', newValue);\n setValue(newValue);\n\n // Only send a change if the value is actually valid\n if (TimeUtils.isTimeString(newValue)) {\n onChange(TimeUtils.parseTime(newValue));\n }\n }\n\n function handleSelect(newSelection: SelectionSegment) {\n setSelection(newSelection);\n }\n\n return (\n <MaskedInput\n ref={ref}\n className={className}\n example={EXAMPLES}\n getNextSegmentValue={getNextSegmentValue}\n getPreferredReplacementString={getPreferredReplacementString}\n onChange={handleChange}\n onSelect={handleSelect}\n pattern={TIME_PATTERN}\n selection={selection}\n value={value}\n onFocus={onFocus}\n onBlur={onBlur}\n data-testid={dataTestId}\n />\n );\n }\n);\n\nTimeInput.defaultProps = {\n allowValueWrapping: true,\n className: '',\n onChange: () => false,\n value: 0,\n onFocus: () => false,\n onBlur: () => false,\n 'data-testid': undefined,\n};\n\nexport default TimeInput;\n"],"file":"TimeInput.js"}
1
+ {"version":3,"sources":["../src/TimeInput.tsx"],"names":["React","useCallback","useEffect","useImperativeHandle","useRef","useState","Log","TimeUtils","MaskedInput","DEFAULT_GET_PREFERRED_REPLACEMENT_STRING","log","module","TIME_PATTERN","EXAMPLES","TimeInput","forwardRef","props","ref","allowValueWrapping","className","onChange","value","propsValue","onFocus","onBlur","onSelect","dataTestId","setValue","formatTime","selection","setSelection","inputRef","focus","current","newSelection","setFormattedTime","getNextSegmentValue","range","delta","segmentValue","maxValue","selectionStart","newSegmentValue","parseInt","Number","isNaN","Math","min","max","padStart","getPreferredReplacementString","replaceValue","replaceIndex","newChar","selectionEnd","substring","handleChange","newValue","debug","isTimeString","parseTime","handleSelect","defaultProps","undefined"],"mappings":"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","sourcesContent":["import React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\nimport Log from '@deephaven/log';\nimport { TimeUtils } from '@deephaven/utils';\nimport MaskedInput, {\n DEFAULT_GET_PREFERRED_REPLACEMENT_STRING,\n SelectionSegment,\n} from './MaskedInput';\n\nexport type { SelectionSegment } from './MaskedInput';\n\nconst log = Log.module('TimeInput');\n\nconst TIME_PATTERN = '([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]';\nconst EXAMPLES = ['00:00:00', '12:34:56', '23:59:59'];\n\ntype TimeInputProps = {\n allowValueWrapping?: boolean;\n className?: string;\n onChange?(timeInSec: number): void;\n onSelect?(selection: SelectionSegment): void;\n value?: number;\n onFocus?(): void;\n onBlur?(): void;\n 'data-testid'?: string;\n};\n\nexport type TimeInputElement = {\n focus: () => void;\n setSelection: (newSelection: SelectionSegment) => void;\n};\n\n// Forward ref causes a false positive for display-name in eslint:\n// https://github.com/yannickcr/eslint-plugin-react/issues/2269\n// eslint-disable-next-line react/display-name\nconst TimeInput = React.forwardRef<TimeInputElement, TimeInputProps>(\n (props: TimeInputProps, ref) => {\n const {\n allowValueWrapping = true,\n className = '',\n onChange = () => false,\n value: propsValue = 0,\n onFocus = () => false,\n onBlur = () => false,\n onSelect = () => false,\n 'data-testid': dataTestId,\n } = props;\n const [value, setValue] = useState(TimeUtils.formatTime(propsValue));\n const [selection, setSelection] = useState<SelectionSegment>();\n const inputRef = useRef<HTMLInputElement>(null);\n\n useImperativeHandle(\n ref,\n () => ({\n focus: () => {\n inputRef.current?.focus();\n },\n setSelection: newSelection => {\n inputRef.current?.focus();\n setSelection(newSelection);\n },\n }),\n []\n );\n\n useEffect(\n function setFormattedTime() {\n setValue(TimeUtils.formatTime(propsValue));\n },\n [propsValue]\n );\n\n function getNextSegmentValue(\n range: SelectionSegment,\n delta: number,\n segmentValue: string\n ): string {\n // Delta is backward because negative Y is up\n const maxValue = range.selectionStart === 0 ? 24 : 60;\n let newSegmentValue = parseInt(segmentValue, 10) - delta;\n if (Number.isNaN(newSegmentValue)) {\n newSegmentValue = 0;\n } else if (allowValueWrapping) {\n // Add max value and re-mod so we don't get negative values after mod\n newSegmentValue = ((newSegmentValue % maxValue) + maxValue) % maxValue;\n } else {\n newSegmentValue = Math.min(Math.max(0, newSegmentValue), maxValue - 1);\n }\n return `${newSegmentValue}`.padStart(2, '0');\n }\n\n function getPreferredReplacementString(\n replaceValue: string,\n replaceIndex: number,\n newChar: string,\n selectionStart: number,\n selectionEnd: number\n ) {\n if (\n selectionStart === 0 &&\n selectionEnd === 2 &&\n replaceIndex === 1 &&\n parseInt(newChar, 10) > 1\n ) {\n // DH-10082 Special case for when typing `3` when it's already 12\n return `0${newChar}${replaceValue.substring(2)}`;\n }\n return DEFAULT_GET_PREFERRED_REPLACEMENT_STRING(\n replaceValue,\n replaceIndex,\n newChar\n );\n }\n\n function handleChange(newValue: string): void {\n log.debug('handleChange', newValue);\n setValue(newValue);\n\n // Only send a change if the value is actually valid\n if (TimeUtils.isTimeString(newValue)) {\n onChange(TimeUtils.parseTime(newValue));\n }\n }\n\n const handleSelect = useCallback(\n (newSelection: SelectionSegment) => {\n setSelection(newSelection);\n onSelect(newSelection);\n },\n [onSelect]\n );\n\n return (\n <MaskedInput\n ref={inputRef}\n className={className}\n example={EXAMPLES}\n getNextSegmentValue={getNextSegmentValue}\n getPreferredReplacementString={getPreferredReplacementString}\n onChange={handleChange}\n onSelect={handleSelect}\n pattern={TIME_PATTERN}\n selection={selection}\n value={value}\n onFocus={onFocus}\n onBlur={onBlur}\n data-testid={dataTestId}\n />\n );\n }\n);\n\nTimeInput.defaultProps = {\n allowValueWrapping: true,\n className: '',\n onChange: () => false,\n onSelect: () => false,\n value: 0,\n onFocus: () => false,\n onBlur: () => false,\n 'data-testid': undefined,\n};\n\nexport default TimeInput;\n"],"file":"TimeInput.js"}
@@ -1 +1 @@
1
- {"version":3,"file":"TimeSlider.d.ts","sourceRoot":"","sources":["../src/TimeSlider.tsx"],"names":[],"mappings":";AAaA,OAAO,mBAAmB,CAAC;AAO3B,aAAK,eAAe,GAAG;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,QAAA,MAAM,UAAU,6HAOb,eAAe,KAAG,WAuFpB,CAAC;AAuQF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"TimeSlider.d.ts","sourceRoot":"","sources":["../src/TimeSlider.tsx"],"names":[],"mappings":";AAaA,OAAO,mBAAmB,CAAC;AAO3B,aAAK,eAAe,GAAG;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,QAAA,MAAM,UAAU,6HAOb,eAAe,KAAG,WAuFpB,CAAC;AAoSF,eAAe,UAAU,CAAC"}
@@ -109,12 +109,31 @@ var PopOvers = props => {
109
109
  isEndModified,
110
110
  'data-testid': dataTestId
111
111
  } = props;
112
- var [firstTime, setFirstTime] = useState(startTime > endTime ? endTime : startTime);
113
- var [secondTime, setSecondTime] = useState(startTime > endTime ? startTime : endTime);
112
+ var swapTimes = startTime > endTime;
113
+ var [firstTime, setFirstTime] = useState(swapTimes ? endTime : startTime);
114
+ var [secondTime, setSecondTime] = useState(swapTimes ? startTime : endTime);
115
+ var firstTimeRef = useRef(null);
116
+ var secondTimeRef = useRef(null); // Keep track of selection in both time inputs
117
+
118
+ var firstTimeSelectionRef = useRef(null);
119
+ var secondTimeSelectionRef = useRef(null);
114
120
  useEffect(function setTimeOnPropTimeChange() {
115
121
  setFirstTime(startTime > endTime ? endTime : startTime);
116
122
  setSecondTime(startTime > endTime ? startTime : endTime);
117
123
  }, [startTime, endTime]);
124
+ useEffect(function setFocusOnSwapTimesChange() {
125
+ if (firstTimeSelectionRef.current !== null) {
126
+ var _secondTimeRef$curren;
127
+
128
+ (_secondTimeRef$curren = secondTimeRef.current) === null || _secondTimeRef$curren === void 0 ? void 0 : _secondTimeRef$curren.setSelection(firstTimeSelectionRef.current);
129
+ }
130
+
131
+ if (secondTimeSelectionRef.current !== null) {
132
+ var _firstTimeRef$current;
133
+
134
+ (_firstTimeRef$current = firstTimeRef.current) === null || _firstTimeRef$current === void 0 ? void 0 : _firstTimeRef$current.setSelection(secondTimeSelectionRef.current);
135
+ }
136
+ }, [swapTimes]);
118
137
 
119
138
  function onFirstTimeChange(value) {
120
139
  if (startTime <= endTime) {
@@ -132,6 +151,14 @@ var PopOvers = props => {
132
151
  }
133
152
  }
134
153
 
154
+ var onFirstTimeSelect = useCallback(selection => {
155
+ firstTimeSelectionRef.current = selection;
156
+ secondTimeSelectionRef.current = null;
157
+ }, []);
158
+ var onSecondTimeSelect = useCallback(selection => {
159
+ firstTimeSelectionRef.current = null;
160
+ secondTimeSelectionRef.current = selection;
161
+ }, []);
135
162
  return /*#__PURE__*/React.createElement("div", {
136
163
  className: "time-slider-popovers"
137
164
  }, /*#__PURE__*/React.createElement("div", {
@@ -143,12 +170,14 @@ var PopOvers = props => {
143
170
  className: "handle-popper"
144
171
  }, /*#__PURE__*/React.createElement("label", {
145
172
  className: classNames({
146
- modified: startTime < endTime ? isStartModified : isEndModified
173
+ modified: swapTimes ? isEndModified : isStartModified
147
174
  })
148
- }, startTime <= endTime ? 'Start Time' : 'End Time'), /*#__PURE__*/React.createElement(TimeInput, {
175
+ }, swapTimes ? 'End Time' : 'Start Time'), /*#__PURE__*/React.createElement(TimeInput, {
176
+ ref: firstTimeRef,
149
177
  allowValueWrapping: false,
150
178
  value: firstTime,
151
179
  onChange: onFirstTimeChange,
180
+ onSelect: onFirstTimeSelect,
152
181
  "data-testid": dataTestId ? "".concat(dataTestId, "-input-1") : undefined
153
182
  })), /*#__PURE__*/React.createElement("div", {
154
183
  className: "flex-spacer"
@@ -156,12 +185,14 @@ var PopOvers = props => {
156
185
  className: "handle-popper"
157
186
  }, /*#__PURE__*/React.createElement("label", {
158
187
  className: classNames({
159
- modified: startTime > endTime ? isStartModified : isEndModified
188
+ modified: swapTimes ? isStartModified : isEndModified
160
189
  })
161
- }, startTime > endTime ? 'Start Time' : 'End Time'), /*#__PURE__*/React.createElement(TimeInput, {
190
+ }, swapTimes ? 'Start Time' : 'End Time'), /*#__PURE__*/React.createElement(TimeInput, {
191
+ ref: secondTimeRef,
162
192
  allowValueWrapping: false,
163
193
  value: secondTime,
164
194
  onChange: onSecondTimeChange,
195
+ onSelect: onSecondTimeSelect,
165
196
  "data-testid": dataTestId ? "".concat(dataTestId, "-input-2") : undefined
166
197
  })), /*#__PURE__*/React.createElement("div", {
167
198
  className: "flex",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/TimeSlider.tsx"],"names":["React","useCallback","useMemo","useRef","useState","useEffect","classNames","TimeInput","StyleExports","HANDLE_SIZE","parseInt","POPOVER_WIDTH","SECONDS_IN_DAY","SNAP_NEAREST_MINUTES","TimeSlider","startTime","propStartTime","endTime","propEndTime","onChange","isStartModified","isEndModified","dataTestId","setStartTime","setEndTime","track","setTimeOnPropTimeChange","updateTime","newStartTime","newEndTime","start","end","handleStartTimeChange","handleEndTimeChange","Array","fill","map","value","index","PopOvers","props","onStartTimeChange","onEndTimeChange","firstTime","setFirstTime","secondTime","setSecondTime","onFirstTimeChange","onSecondTimeChange","flexBasis","modified","undefined","TrackFills","transform","Handle","time","setTime","ONE_HOUR","handleOffset","calculatePositionAsTime","clientX","current","trackRect","getBoundingClientRect","leftEdge","Math","max","left","preciseTime","min","width","roundedTime","round","limitMax","handleMouseMove","handleMouseUp","window","removeEventListener","document","documentElement","classList","remove","startDragListening","addEventListener","add","stopDragListening","handleMouseDown","removeListenersOnUnmount"],"mappings":"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","sourcesContent":["/* eslint-disable react/no-array-index-key */\n// array maps being used are static, this is fine.\n\nimport React, {\n useCallback,\n useMemo,\n useRef,\n useState,\n useEffect,\n} from 'react';\nimport classNames from 'classnames';\nimport TimeInput from './TimeInput';\nimport StyleExports from './TimeSlider.module.scss';\nimport './TimeSlider.scss';\n\nconst HANDLE_SIZE = parseInt(StyleExports['handle-size'], 10);\nconst POPOVER_WIDTH = parseInt(StyleExports['popover-width'], 10);\nconst SECONDS_IN_DAY = 24 * 60 * 60 - 1; // Max is actually 23:59:59\nconst SNAP_NEAREST_MINUTES = 5 * 60; // rounds in 5 minute intervals\n\ntype TimeSliderProps = {\n startTime: number;\n endTime: number;\n onChange(value: { startTime: number; endTime: number }): void;\n isStartModified?: boolean;\n isEndModified?: boolean;\n 'data-testid'?: string;\n};\n\n/**\n * Creates a time slider for setting a start and end time, that can also run overnight\n * @param props takes times in seconds 0 - 86399 and a callback\n */\nconst TimeSlider = ({\n startTime: propStartTime,\n endTime: propEndTime,\n onChange,\n isStartModified = false,\n isEndModified = false,\n 'data-testid': dataTestId,\n}: TimeSliderProps): JSX.Element => {\n const [startTime, setStartTime] = useState(propStartTime);\n const [endTime, setEndTime] = useState(propEndTime);\n\n const track = useRef<HTMLDivElement>(null); // we need the track width while calulculating time from handle drag\n\n // updates state if props change\n useEffect(\n function setTimeOnPropTimeChange() {\n setStartTime(propStartTime);\n setEndTime(propEndTime);\n },\n [propStartTime, propEndTime]\n );\n\n const updateTime = useCallback(\n (newStartTime: number, newEndTime: number) => {\n let start = newStartTime;\n let end = newEndTime;\n if (start === end) {\n if (end < SECONDS_IN_DAY) {\n end += 1;\n } else {\n start -= 1;\n }\n }\n\n setStartTime(start);\n setEndTime(end);\n onChange({ startTime: start, endTime: end });\n },\n [setStartTime, setEndTime, onChange]\n );\n\n const handleStartTimeChange = useCallback(\n (newStartTime: number) => {\n updateTime(newStartTime, endTime);\n },\n [updateTime, endTime]\n );\n\n const handleEndTimeChange = useCallback(\n (newEndTime: number) => {\n updateTime(startTime, newEndTime);\n },\n [updateTime, startTime]\n );\n\n return (\n <div className=\"time-slider\" data-testid={dataTestId}>\n <PopOvers\n startTime={startTime}\n endTime={endTime}\n onStartTimeChange={handleStartTimeChange}\n onEndTimeChange={handleEndTimeChange}\n isStartModified={isStartModified}\n isEndModified={isEndModified}\n />\n <div className=\"track\" ref={track}>\n <TrackFills startTime={startTime} endTime={endTime} />\n <div className=\"ticks\">\n {Array(24)\n .fill(null)\n .map((value, index) => (\n <div className=\"tick\" key={index} />\n ))}\n </div>\n <Handle\n track={track}\n time={startTime}\n setTime={handleStartTimeChange}\n />\n <Handle track={track} time={endTime} setTime={handleEndTimeChange} />\n </div>\n\n <div className=\"tick-labels\">\n <div className=\"tick-label\">0:00</div>\n <div className=\"tick-label-wrapper\">\n {Array(24)\n .fill(null)\n .map((value, index) => (\n <div className=\"tick-label\" key={index}>{`${index + 1}:00`}</div>\n ))}\n </div>\n </div>\n </div>\n );\n};\n\ntype PopOversProps = {\n startTime: number;\n endTime: number;\n onStartTimeChange(time: number): void;\n onEndTimeChange(time: number): void;\n isStartModified: boolean;\n isEndModified: boolean;\n 'data-testid'?: string;\n};\n\nconst PopOvers = (props: PopOversProps): JSX.Element => {\n const {\n startTime,\n endTime,\n onStartTimeChange,\n onEndTimeChange,\n isStartModified,\n isEndModified,\n 'data-testid': dataTestId,\n } = props;\n\n const [firstTime, setFirstTime] = useState(\n startTime > endTime ? endTime : startTime\n );\n const [secondTime, setSecondTime] = useState(\n startTime > endTime ? startTime : endTime\n );\n\n useEffect(\n function setTimeOnPropTimeChange() {\n setFirstTime(startTime > endTime ? endTime : startTime);\n setSecondTime(startTime > endTime ? startTime : endTime);\n },\n [startTime, endTime]\n );\n\n function onFirstTimeChange(value: number) {\n if (startTime <= endTime) {\n onStartTimeChange(value);\n } else {\n onEndTimeChange(value);\n }\n }\n\n function onSecondTimeChange(value: number) {\n if (startTime <= endTime) {\n onEndTimeChange(value);\n } else {\n onStartTimeChange(value);\n }\n }\n\n return (\n <div className=\"time-slider-popovers\">\n <div\n className=\"flex\"\n style={{\n flexBasis: `calc(${(firstTime / SECONDS_IN_DAY) * 100}% - ${\n POPOVER_WIDTH / 2\n }px)`,\n }}\n />\n <div className=\"handle-popper\">\n <label\n className={classNames({\n modified: startTime < endTime ? isStartModified : isEndModified,\n })}\n >\n {startTime <= endTime ? 'Start Time' : 'End Time'}\n </label>\n <TimeInput\n allowValueWrapping={false}\n value={firstTime}\n onChange={onFirstTimeChange}\n data-testid={dataTestId ? `${dataTestId}-input-1` : undefined}\n />\n </div>\n <div className=\"flex-spacer\" />\n <div className=\"handle-popper\">\n <label\n className={classNames({\n modified: startTime > endTime ? isStartModified : isEndModified,\n })}\n >\n {startTime > endTime ? 'Start Time' : 'End Time'}\n </label>\n <TimeInput\n allowValueWrapping={false}\n value={secondTime}\n onChange={onSecondTimeChange}\n data-testid={dataTestId ? `${dataTestId}-input-2` : undefined}\n />\n </div>\n <div\n className=\"flex\"\n style={{\n flexBasis: `calc(${\n ((SECONDS_IN_DAY - secondTime) / SECONDS_IN_DAY) * 100\n }% - ${POPOVER_WIDTH / 2}px)`,\n }}\n />\n </div>\n );\n};\n\ntype TrackFillsProps = {\n startTime: number;\n endTime: number;\n 'data-testid'?: string;\n};\n\n/**\n * Shades the area between or outside of handles according to if start or endtime is greater.\n */\nconst TrackFills = (props: TrackFillsProps): JSX.Element => {\n const { startTime, endTime, 'data-testid': dataTestId } = props;\n return (\n <div className=\"track-fills\" data-testid={dataTestId}>\n {startTime > endTime && (\n <>\n <div\n className=\"track-fill track-fill-start\"\n style={{ transform: `scaleX(${endTime / SECONDS_IN_DAY})` }}\n />\n <div\n className=\"track-fill track-fill-end\"\n style={{\n transform: `scaleX(${\n (SECONDS_IN_DAY - startTime) / SECONDS_IN_DAY\n })`,\n }}\n />\n </>\n )}\n {startTime < endTime && (\n <div\n className=\"track-fill track-fill-middle\"\n style={{\n transform: `translateX(${\n (startTime / SECONDS_IN_DAY) * 100\n }%) scaleX(${(endTime - startTime) / SECONDS_IN_DAY})`,\n }}\n />\n )}\n </div>\n );\n};\n\ntype HandleProps = {\n track: React.RefObject<HTMLDivElement>;\n time: number;\n setTime(time: number): void;\n 'data-testid'?: string;\n};\n\n/**\n * Creates a draggable handle the sets the time\n */\nconst Handle = (props: HandleProps): JSX.Element => {\n const { track, time, setTime, 'data-testid': dataTestId } = props;\n\n /**\n * Takes the time and generate our translation string taking into account handle offset.\n * The handle offset changes for the first and last tick range dynmaically. Normally,\n * the center of the handle (size/2) is the selection origin, but at edges, it becomes either\n * end of the handle, requireing a relative offset range of 0 - 0.5, and 0.5 - 1 of handle size.\n * @param t time in seconds\n */\n const transform = useMemo(() => {\n const ONE_HOUR = 60 * 60;\n let handleOffset = HANDLE_SIZE / 2;\n if (time < ONE_HOUR) {\n handleOffset = (time / ONE_HOUR) * (HANDLE_SIZE / 2); // 0 - 0.5 Handle size\n } else if (time > 23 * ONE_HOUR) {\n handleOffset =\n HANDLE_SIZE / 2 +\n (1 / (SECONDS_IN_DAY - 23 * ONE_HOUR)) *\n (time - 23 * ONE_HOUR) *\n (HANDLE_SIZE / 2); // 0.5 - 1 Handle size\n }\n return `translateX(calc(${\n (time / SECONDS_IN_DAY) * 100\n }% - ${handleOffset}px))`;\n }, [time]);\n\n const calculatePositionAsTime = useCallback(\n (clientX: number) => {\n if (!track.current) {\n return 0;\n }\n const trackRect = track.current.getBoundingClientRect();\n const leftEdge = Math.max(clientX - trackRect.left, 0);\n // get position as 0-1 on slider and mulitply by seconds in a day to convert to time\n const preciseTime =\n SECONDS_IN_DAY * Math.min(1, leftEdge / trackRect.width);\n // snap to nearest N(5) minute interval\n const roundedTime =\n SNAP_NEAREST_MINUTES * Math.round(preciseTime / SNAP_NEAREST_MINUTES);\n // prevent over-rounding to 24:00:00\n const limitMax = Math.min(SECONDS_IN_DAY, roundedTime);\n return limitMax;\n },\n [track]\n );\n\n const handleMouseMove = useCallback(\n ({ clientX }: MouseEvent) => {\n setTime(calculatePositionAsTime(clientX));\n },\n [setTime, calculatePositionAsTime]\n );\n\n const handleMouseUp = useCallback(\n ({ clientX }: MouseEvent) => {\n setTime(calculatePositionAsTime(clientX));\n\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n document.documentElement.classList.remove('drag-pointer-events-none');\n },\n [setTime, calculatePositionAsTime, handleMouseMove]\n );\n\n const startDragListening = useCallback(() => {\n window.addEventListener('mousemove', handleMouseMove);\n window.addEventListener('mouseup', handleMouseUp);\n document.documentElement.classList.add('drag-pointer-events-none');\n }, [handleMouseMove, handleMouseUp]);\n\n const stopDragListening = useCallback(() => {\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n document.documentElement.classList.remove('drag-pointer-events-none');\n }, [handleMouseMove, handleMouseUp]);\n\n const handleMouseDown = useCallback(() => {\n startDragListening();\n }, [startDragListening]);\n\n useEffect(\n function removeListenersOnUnmount() {\n return () => {\n stopDragListening();\n };\n },\n [stopDragListening]\n );\n\n return (\n <div className=\"handle-track\" style={{ transform }}>\n <button\n className=\"handle\"\n type=\"button\"\n aria-label=\"Change time\"\n onMouseDown={handleMouseDown}\n data-testid={dataTestId}\n />\n </div>\n );\n};\n\nexport default TimeSlider;\n"],"file":"TimeSlider.js"}
1
+ {"version":3,"sources":["../src/TimeSlider.tsx"],"names":["React","useCallback","useMemo","useRef","useState","useEffect","classNames","TimeInput","StyleExports","HANDLE_SIZE","parseInt","POPOVER_WIDTH","SECONDS_IN_DAY","SNAP_NEAREST_MINUTES","TimeSlider","startTime","propStartTime","endTime","propEndTime","onChange","isStartModified","isEndModified","dataTestId","setStartTime","setEndTime","track","setTimeOnPropTimeChange","updateTime","newStartTime","newEndTime","start","end","handleStartTimeChange","handleEndTimeChange","Array","fill","map","value","index","PopOvers","props","onStartTimeChange","onEndTimeChange","swapTimes","firstTime","setFirstTime","secondTime","setSecondTime","firstTimeRef","secondTimeRef","firstTimeSelectionRef","secondTimeSelectionRef","setFocusOnSwapTimesChange","current","setSelection","onFirstTimeChange","onSecondTimeChange","onFirstTimeSelect","selection","onSecondTimeSelect","flexBasis","modified","undefined","TrackFills","transform","Handle","time","setTime","ONE_HOUR","handleOffset","calculatePositionAsTime","clientX","trackRect","getBoundingClientRect","leftEdge","Math","max","left","preciseTime","min","width","roundedTime","round","limitMax","handleMouseMove","handleMouseUp","window","removeEventListener","document","documentElement","classList","remove","startDragListening","addEventListener","add","stopDragListening","handleMouseDown","removeListenersOnUnmount"],"mappings":"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","sourcesContent":["/* eslint-disable react/no-array-index-key */\n// array maps being used are static, this is fine.\n\nimport React, {\n useCallback,\n useMemo,\n useRef,\n useState,\n useEffect,\n} from 'react';\nimport classNames from 'classnames';\nimport TimeInput, { SelectionSegment, TimeInputElement } from './TimeInput';\nimport StyleExports from './TimeSlider.module.scss';\nimport './TimeSlider.scss';\n\nconst HANDLE_SIZE = parseInt(StyleExports['handle-size'], 10);\nconst POPOVER_WIDTH = parseInt(StyleExports['popover-width'], 10);\nconst SECONDS_IN_DAY = 24 * 60 * 60 - 1; // Max is actually 23:59:59\nconst SNAP_NEAREST_MINUTES = 5 * 60; // rounds in 5 minute intervals\n\ntype TimeSliderProps = {\n startTime: number;\n endTime: number;\n onChange(value: { startTime: number; endTime: number }): void;\n isStartModified?: boolean;\n isEndModified?: boolean;\n 'data-testid'?: string;\n};\n\n/**\n * Creates a time slider for setting a start and end time, that can also run overnight\n * @param props takes times in seconds 0 - 86399 and a callback\n */\nconst TimeSlider = ({\n startTime: propStartTime,\n endTime: propEndTime,\n onChange,\n isStartModified = false,\n isEndModified = false,\n 'data-testid': dataTestId,\n}: TimeSliderProps): JSX.Element => {\n const [startTime, setStartTime] = useState(propStartTime);\n const [endTime, setEndTime] = useState(propEndTime);\n\n const track = useRef<HTMLDivElement>(null); // we need the track width while calulculating time from handle drag\n\n // updates state if props change\n useEffect(\n function setTimeOnPropTimeChange() {\n setStartTime(propStartTime);\n setEndTime(propEndTime);\n },\n [propStartTime, propEndTime]\n );\n\n const updateTime = useCallback(\n (newStartTime: number, newEndTime: number) => {\n let start = newStartTime;\n let end = newEndTime;\n if (start === end) {\n if (end < SECONDS_IN_DAY) {\n end += 1;\n } else {\n start -= 1;\n }\n }\n\n setStartTime(start);\n setEndTime(end);\n onChange({ startTime: start, endTime: end });\n },\n [setStartTime, setEndTime, onChange]\n );\n\n const handleStartTimeChange = useCallback(\n (newStartTime: number) => {\n updateTime(newStartTime, endTime);\n },\n [updateTime, endTime]\n );\n\n const handleEndTimeChange = useCallback(\n (newEndTime: number) => {\n updateTime(startTime, newEndTime);\n },\n [updateTime, startTime]\n );\n\n return (\n <div className=\"time-slider\" data-testid={dataTestId}>\n <PopOvers\n startTime={startTime}\n endTime={endTime}\n onStartTimeChange={handleStartTimeChange}\n onEndTimeChange={handleEndTimeChange}\n isStartModified={isStartModified}\n isEndModified={isEndModified}\n />\n <div className=\"track\" ref={track}>\n <TrackFills startTime={startTime} endTime={endTime} />\n <div className=\"ticks\">\n {Array(24)\n .fill(null)\n .map((value, index) => (\n <div className=\"tick\" key={index} />\n ))}\n </div>\n <Handle\n track={track}\n time={startTime}\n setTime={handleStartTimeChange}\n />\n <Handle track={track} time={endTime} setTime={handleEndTimeChange} />\n </div>\n\n <div className=\"tick-labels\">\n <div className=\"tick-label\">0:00</div>\n <div className=\"tick-label-wrapper\">\n {Array(24)\n .fill(null)\n .map((value, index) => (\n <div className=\"tick-label\" key={index}>{`${index + 1}:00`}</div>\n ))}\n </div>\n </div>\n </div>\n );\n};\n\ntype PopOversProps = {\n startTime: number;\n endTime: number;\n onStartTimeChange(time: number): void;\n onEndTimeChange(time: number): void;\n isStartModified: boolean;\n isEndModified: boolean;\n 'data-testid'?: string;\n};\n\nconst PopOvers = (props: PopOversProps): JSX.Element => {\n const {\n startTime,\n endTime,\n onStartTimeChange,\n onEndTimeChange,\n isStartModified,\n isEndModified,\n 'data-testid': dataTestId,\n } = props;\n\n const swapTimes = startTime > endTime;\n\n const [firstTime, setFirstTime] = useState(swapTimes ? endTime : startTime);\n const [secondTime, setSecondTime] = useState(swapTimes ? startTime : endTime);\n const firstTimeRef = useRef<TimeInputElement>(null);\n const secondTimeRef = useRef<TimeInputElement>(null);\n // Keep track of selection in both time inputs\n const firstTimeSelectionRef = useRef<SelectionSegment | null>(null);\n const secondTimeSelectionRef = useRef<SelectionSegment | null>(null);\n\n useEffect(\n function setTimeOnPropTimeChange() {\n setFirstTime(startTime > endTime ? endTime : startTime);\n setSecondTime(startTime > endTime ? startTime : endTime);\n },\n [startTime, endTime]\n );\n\n useEffect(\n function setFocusOnSwapTimesChange() {\n if (firstTimeSelectionRef.current !== null) {\n secondTimeRef.current?.setSelection(firstTimeSelectionRef.current);\n }\n if (secondTimeSelectionRef.current !== null) {\n firstTimeRef.current?.setSelection(secondTimeSelectionRef.current);\n }\n },\n [swapTimes]\n );\n\n function onFirstTimeChange(value: number) {\n if (startTime <= endTime) {\n onStartTimeChange(value);\n } else {\n onEndTimeChange(value);\n }\n }\n\n function onSecondTimeChange(value: number) {\n if (startTime <= endTime) {\n onEndTimeChange(value);\n } else {\n onStartTimeChange(value);\n }\n }\n\n const onFirstTimeSelect = useCallback(selection => {\n firstTimeSelectionRef.current = selection;\n secondTimeSelectionRef.current = null;\n }, []);\n\n const onSecondTimeSelect = useCallback(selection => {\n firstTimeSelectionRef.current = null;\n secondTimeSelectionRef.current = selection;\n }, []);\n\n return (\n <div className=\"time-slider-popovers\">\n <div\n className=\"flex\"\n style={{\n flexBasis: `calc(${(firstTime / SECONDS_IN_DAY) * 100}% - ${\n POPOVER_WIDTH / 2\n }px)`,\n }}\n />\n <div className=\"handle-popper\">\n <label\n className={classNames({\n modified: swapTimes ? isEndModified : isStartModified,\n })}\n >\n {swapTimes ? 'End Time' : 'Start Time'}\n </label>\n <TimeInput\n ref={firstTimeRef}\n allowValueWrapping={false}\n value={firstTime}\n onChange={onFirstTimeChange}\n onSelect={onFirstTimeSelect}\n data-testid={dataTestId ? `${dataTestId}-input-1` : undefined}\n />\n </div>\n <div className=\"flex-spacer\" />\n <div className=\"handle-popper\">\n <label\n className={classNames({\n modified: swapTimes ? isStartModified : isEndModified,\n })}\n >\n {swapTimes ? 'Start Time' : 'End Time'}\n </label>\n <TimeInput\n ref={secondTimeRef}\n allowValueWrapping={false}\n value={secondTime}\n onChange={onSecondTimeChange}\n onSelect={onSecondTimeSelect}\n data-testid={dataTestId ? `${dataTestId}-input-2` : undefined}\n />\n </div>\n <div\n className=\"flex\"\n style={{\n flexBasis: `calc(${\n ((SECONDS_IN_DAY - secondTime) / SECONDS_IN_DAY) * 100\n }% - ${POPOVER_WIDTH / 2}px)`,\n }}\n />\n </div>\n );\n};\n\ntype TrackFillsProps = {\n startTime: number;\n endTime: number;\n 'data-testid'?: string;\n};\n\n/**\n * Shades the area between or outside of handles according to if start or endtime is greater.\n */\nconst TrackFills = (props: TrackFillsProps): JSX.Element => {\n const { startTime, endTime, 'data-testid': dataTestId } = props;\n return (\n <div className=\"track-fills\" data-testid={dataTestId}>\n {startTime > endTime && (\n <>\n <div\n className=\"track-fill track-fill-start\"\n style={{ transform: `scaleX(${endTime / SECONDS_IN_DAY})` }}\n />\n <div\n className=\"track-fill track-fill-end\"\n style={{\n transform: `scaleX(${\n (SECONDS_IN_DAY - startTime) / SECONDS_IN_DAY\n })`,\n }}\n />\n </>\n )}\n {startTime < endTime && (\n <div\n className=\"track-fill track-fill-middle\"\n style={{\n transform: `translateX(${\n (startTime / SECONDS_IN_DAY) * 100\n }%) scaleX(${(endTime - startTime) / SECONDS_IN_DAY})`,\n }}\n />\n )}\n </div>\n );\n};\n\ntype HandleProps = {\n track: React.RefObject<HTMLDivElement>;\n time: number;\n setTime(time: number): void;\n 'data-testid'?: string;\n};\n\n/**\n * Creates a draggable handle the sets the time\n */\nconst Handle = (props: HandleProps): JSX.Element => {\n const { track, time, setTime, 'data-testid': dataTestId } = props;\n\n /**\n * Takes the time and generate our translation string taking into account handle offset.\n * The handle offset changes for the first and last tick range dynmaically. Normally,\n * the center of the handle (size/2) is the selection origin, but at edges, it becomes either\n * end of the handle, requireing a relative offset range of 0 - 0.5, and 0.5 - 1 of handle size.\n * @param t time in seconds\n */\n const transform = useMemo(() => {\n const ONE_HOUR = 60 * 60;\n let handleOffset = HANDLE_SIZE / 2;\n if (time < ONE_HOUR) {\n handleOffset = (time / ONE_HOUR) * (HANDLE_SIZE / 2); // 0 - 0.5 Handle size\n } else if (time > 23 * ONE_HOUR) {\n handleOffset =\n HANDLE_SIZE / 2 +\n (1 / (SECONDS_IN_DAY - 23 * ONE_HOUR)) *\n (time - 23 * ONE_HOUR) *\n (HANDLE_SIZE / 2); // 0.5 - 1 Handle size\n }\n return `translateX(calc(${\n (time / SECONDS_IN_DAY) * 100\n }% - ${handleOffset}px))`;\n }, [time]);\n\n const calculatePositionAsTime = useCallback(\n (clientX: number) => {\n if (!track.current) {\n return 0;\n }\n const trackRect = track.current.getBoundingClientRect();\n const leftEdge = Math.max(clientX - trackRect.left, 0);\n // get position as 0-1 on slider and mulitply by seconds in a day to convert to time\n const preciseTime =\n SECONDS_IN_DAY * Math.min(1, leftEdge / trackRect.width);\n // snap to nearest N(5) minute interval\n const roundedTime =\n SNAP_NEAREST_MINUTES * Math.round(preciseTime / SNAP_NEAREST_MINUTES);\n // prevent over-rounding to 24:00:00\n const limitMax = Math.min(SECONDS_IN_DAY, roundedTime);\n return limitMax;\n },\n [track]\n );\n\n const handleMouseMove = useCallback(\n ({ clientX }: MouseEvent) => {\n setTime(calculatePositionAsTime(clientX));\n },\n [setTime, calculatePositionAsTime]\n );\n\n const handleMouseUp = useCallback(\n ({ clientX }: MouseEvent) => {\n setTime(calculatePositionAsTime(clientX));\n\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n document.documentElement.classList.remove('drag-pointer-events-none');\n },\n [setTime, calculatePositionAsTime, handleMouseMove]\n );\n\n const startDragListening = useCallback(() => {\n window.addEventListener('mousemove', handleMouseMove);\n window.addEventListener('mouseup', handleMouseUp);\n document.documentElement.classList.add('drag-pointer-events-none');\n }, [handleMouseMove, handleMouseUp]);\n\n const stopDragListening = useCallback(() => {\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n document.documentElement.classList.remove('drag-pointer-events-none');\n }, [handleMouseMove, handleMouseUp]);\n\n const handleMouseDown = useCallback(() => {\n startDragListening();\n }, [startDragListening]);\n\n useEffect(\n function removeListenersOnUnmount() {\n return () => {\n stopDragListening();\n };\n },\n [stopDragListening]\n );\n\n return (\n <div className=\"handle-track\" style={{ transform }}>\n <button\n className=\"handle\"\n type=\"button\"\n aria-label=\"Change time\"\n onMouseDown={handleMouseDown}\n data-testid={dataTestId}\n />\n </div>\n );\n};\n\nexport default TimeSlider;\n"],"file":"TimeSlider.js"}
@@ -0,0 +1,8 @@
1
+ .validate-label {
2
+ padding-right: 0.5rem;
3
+ }
4
+ .validate-label.modified {
5
+ color: #fde38d;
6
+ }
7
+
8
+ /*# sourceMappingURL=ValidateLabelInput.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sourceRoot":"","sources":["../src/ValidateLabelInput.scss","../scss/new_variables.scss"],"names":[],"mappings":"AAIA;EACE,eCFS;;ADGT;EACE,OALO","file":"ValidateLabelInput.css"}
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import './ValidateLabelInput.scss';
3
+ export declare type ValidateLabelInputProps = {
4
+ /** Element to add label to */
5
+ children: React.ReactNode;
6
+ /** Any classnames to add */
7
+ className?: string | string[];
8
+ /** Text for this validation label */
9
+ labelText?: string;
10
+ /** Small hint text next to the main label */
11
+ hintText?: string;
12
+ /** Show a modified state. Defaults to false. */
13
+ isModified?: boolean;
14
+ /** Validation error that has occurred */
15
+ validationError?: string;
16
+ /** Show the validation error if it exists. Default to true. */
17
+ showValidationError?: boolean;
18
+ /** ID to use. Auto-generates if not provided */
19
+ id?: string;
20
+ /** data-testid to apply to the label */
21
+ 'data-testid'?: string;
22
+ };
23
+ /**
24
+ * Takes a child and add a label and validaton error
25
+ */
26
+ export declare function ValidateLabelInput(props: ValidateLabelInputProps): React.ReactElement;
27
+ export default ValidateLabelInput;
28
+ //# sourceMappingURL=ValidateLabelInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidateLabelInput.d.ts","sourceRoot":"","sources":["../src/ValidateLabelInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAGtC,OAAO,2BAA2B,CAAC;AAEnC,oBAAY,uBAAuB,GAAG;IACpC,8BAA8B;IAC9B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE9B,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,gDAAgD;IAChD,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,yCAAyC;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B,gDAAgD;IAChD,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ,wCAAwC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,uBAAuB,GAC7B,KAAK,CAAC,YAAY,CA4CpB;AAED,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,50 @@
1
+ import React, { useRef } from 'react';
2
+ import classNames from 'classnames';
3
+ import shortid from 'shortid';
4
+ import "./ValidateLabelInput.css";
5
+
6
+ /**
7
+ * Takes a child and add a label and validaton error
8
+ */
9
+ export function ValidateLabelInput(props) {
10
+ var {
11
+ children,
12
+ className,
13
+ labelText,
14
+ hintText,
15
+ isModified,
16
+ validationError,
17
+ showValidationError = true,
18
+ 'data-testid': dataTestId,
19
+ id: idProp
20
+ } = props;
21
+ var {
22
+ current: id
23
+ } = useRef(idProp !== null && idProp !== void 0 ? idProp : shortid());
24
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", {
25
+ className: classNames('validate-label', className, {
26
+ modified: isModified
27
+ }),
28
+ htmlFor: id,
29
+ "data-testid": dataTestId
30
+ }, labelText), React.Children.toArray(children).map(child => {
31
+ if (! /*#__PURE__*/React.isValidElement(child)) {
32
+ return /*#__PURE__*/React.createElement("div", {
33
+ className: classNames(className)
34
+ }, child);
35
+ } // toArray strips null children
36
+
37
+
38
+ return /*#__PURE__*/React.cloneElement(child, {
39
+ className: classNames(child.props.className, {
40
+ 'is-invalid': validationError
41
+ })
42
+ });
43
+ }), hintText && /*#__PURE__*/React.createElement("small", {
44
+ className: "form-text text-muted"
45
+ }, hintText), validationError && showValidationError && /*#__PURE__*/React.createElement("p", {
46
+ className: "validate-label-error text-danger"
47
+ }, validationError));
48
+ }
49
+ export default ValidateLabelInput;
50
+ //# sourceMappingURL=ValidateLabelInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ValidateLabelInput.tsx"],"names":["React","useRef","classNames","shortid","ValidateLabelInput","props","children","className","labelText","hintText","isModified","validationError","showValidationError","dataTestId","id","idProp","current","modified","Children","toArray","map","child","isValidElement","cloneElement"],"mappings":"AAAA,OAAOA,KAAP,IAAgBC,MAAhB,QAA8B,OAA9B;AACA,OAAOC,UAAP,MAAuB,YAAvB;AACA,OAAOC,OAAP,MAAoB,SAApB;;;AAgCA;AACA;AACA;AACA,OAAO,SAASC,kBAAT,CACLC,KADK,EAEe;AACpB,MAAM;AACJC,IAAAA,QADI;AAEJC,IAAAA,SAFI;AAGJC,IAAAA,SAHI;AAIJC,IAAAA,QAJI;AAKJC,IAAAA,UALI;AAMJC,IAAAA,eANI;AAOJC,IAAAA,mBAAmB,GAAG,IAPlB;AAQJ,mBAAeC,UARX;AASJC,IAAAA,EAAE,EAAEC;AATA,MAUFV,KAVJ;AAYA,MAAM;AAAEW,IAAAA,OAAO,EAAEF;AAAX,MAAkBb,MAAM,CAACc,MAAD,aAACA,MAAD,cAACA,MAAD,GAAWZ,OAAO,EAAlB,CAA9B;AAEA,sBACE,uDACE;AACE,IAAA,SAAS,EAAED,UAAU,CAAC,gBAAD,EAAmBK,SAAnB,EAA8B;AACjDU,MAAAA,QAAQ,EAAEP;AADuC,KAA9B,CADvB;AAIE,IAAA,OAAO,EAAEI,EAJX;AAKE,mBAAaD;AALf,KAOGL,SAPH,CADF,EAUGR,KAAK,CAACkB,QAAN,CAAeC,OAAf,CAAuBb,QAAvB,EAAiCc,GAAjC,CAAqCC,KAAK,IAAI;AAC7C,QAAI,eAACrB,KAAK,CAACsB,cAAN,CAAqBD,KAArB,CAAL,EAAkC;AAChC,0BAAO;AAAK,QAAA,SAAS,EAAEnB,UAAU,CAACK,SAAD;AAA1B,SAAwCc,KAAxC,CAAP;AACD,KAH4C,CAK7C;;;AACA,wBAAOrB,KAAK,CAACuB,YAAN,CAAmBF,KAAnB,EAA0B;AAC/Bd,MAAAA,SAAS,EAAEL,UAAU,CAACmB,KAAK,CAAChB,KAAN,CAAYE,SAAb,EAAwB;AAC3C,sBAAcI;AAD6B,OAAxB;AADU,KAA1B,CAAP;AAKD,GAXA,CAVH,EAsBGF,QAAQ,iBAAI;AAAO,IAAA,SAAS,EAAC;AAAjB,KAAyCA,QAAzC,CAtBf,EAuBGE,eAAe,IAAIC,mBAAnB,iBACC;AAAG,IAAA,SAAS,EAAC;AAAb,KAAiDD,eAAjD,CAxBJ,CADF;AA6BD;AAED,eAAeP,kBAAf","sourcesContent":["import React, { useRef } from 'react';\nimport classNames from 'classnames';\nimport shortid from 'shortid';\nimport './ValidateLabelInput.scss';\n\nexport type ValidateLabelInputProps = {\n /** Element to add label to */\n children: React.ReactNode;\n\n /** Any classnames to add */\n className?: string | string[];\n\n /** Text for this validation label */\n labelText?: string;\n\n /** Small hint text next to the main label */\n hintText?: string;\n\n /** Show a modified state. Defaults to false. */\n isModified?: boolean;\n\n /** Validation error that has occurred */\n validationError?: string;\n\n /** Show the validation error if it exists. Default to true. */\n showValidationError?: boolean;\n\n /** ID to use. Auto-generates if not provided */\n id?: string;\n\n /** data-testid to apply to the label */\n 'data-testid'?: string;\n};\n\n/**\n * Takes a child and add a label and validaton error\n */\nexport function ValidateLabelInput(\n props: ValidateLabelInputProps\n): React.ReactElement {\n const {\n children,\n className,\n labelText,\n hintText,\n isModified,\n validationError,\n showValidationError = true,\n 'data-testid': dataTestId,\n id: idProp,\n } = props;\n\n const { current: id } = useRef(idProp ?? shortid());\n\n return (\n <>\n <label\n className={classNames('validate-label', className, {\n modified: isModified,\n })}\n htmlFor={id}\n data-testid={dataTestId}\n >\n {labelText}\n </label>\n {React.Children.toArray(children).map(child => {\n if (!React.isValidElement(child)) {\n return <div className={classNames(className)}>{child}</div>;\n }\n\n // toArray strips null children\n return React.cloneElement(child, {\n className: classNames(child.props.className, {\n 'is-invalid': validationError,\n }),\n });\n })}\n {hintText && <small className=\"form-text text-muted\">{hintText}</small>}\n {validationError && showValidationError && (\n <p className=\"validate-label-error text-danger\">{validationError}</p>\n )}\n </>\n );\n}\n\nexport default ValidateLabelInput;\n"],"file":"ValidateLabelInput.js"}
package/dist/index.d.ts CHANGED
@@ -51,4 +51,5 @@ export { default as TimeInput } from './TimeInput';
51
51
  export { default as TimeSlider } from './TimeSlider';
52
52
  export { default as ToastNotification } from './ToastNotification';
53
53
  export { default as UISwitch } from './UISwitch';
54
+ export { default as ValidateLabelInput } from './ValidateLabelInput';
54
55
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -46,4 +46,5 @@ export { default as TimeInput } from "./TimeInput.js";
46
46
  export { default as TimeSlider } from "./TimeSlider.js";
47
47
  export { default as ToastNotification } from "./ToastNotification.js";
48
48
  export { default as UISwitch } from "./UISwitch.js";
49
+ export { default as ValidateLabelInput } from "./ValidateLabelInput.js";
49
50
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["$","window","jQuery","default","AutoCompleteInput","AutoResizeTextarea","BasicModal","Button","ButtonGroup","ButtonOld","CardFlip","Collapse","Checkbox","ComboBox","CustomTimeSelect","DebouncedSearchInput","DeephavenSpinner","DraggableItemList","DragUtils","HierarchicalCheckboxMenu","ItemListItem","LoadingOverlay","LoadingSpinner","DropdownMenu","MaskedInput","Option","RadioGroup","RadioItem","Select","SearchInput","SelectValueList","SocketedButton","ThemeExport","TimeInput","TimeSlider","ToastNotification","UISwitch"],"mappings":"AAAA;AACA,OAAO,KAAKA,CAAZ,MAAmB,QAAnB;AASAC,MAAM,CAACD,CAAP,GAAWA,CAAX;AACAC,MAAM,CAACC,MAAP,GAAgBF,CAAhB;SAGSG,OAAO,IAAIC,iB;SACXD,OAAO,IAAIE,kB;SACXF,OAAO,IAAIG,U;SACXH,OAAO,IAAII,M;SACXJ,OAAO,IAAIK,W;SACXL,OAAO,IAAIM,S;SACXN,OAAO,IAAIO,Q;;SAEXP,OAAO,IAAIQ,Q;SACXR,OAAO,IAAIS,Q;SACXT,OAAO,IAAIU,Q;SACXV,OAAO,IAAIW,gB;SACXX,OAAO,IAAIY,oB;SACXZ,OAAO,IAAIa,gB;SACXb,OAAO,IAAIc,iB;;SAEXd,OAAO,IAAIe,S;SACXf,OAAO,IAAIgB,wB;;;SAGXhB,OAAO,IAAIiB,Y;SACXjB,OAAO,IAAIkB,c;SACXlB,OAAO,IAAImB,c;SACXnB,OAAO,IAAIoB,Y;;SAEXpB,OAAO,IAAIqB,W;;;SAGXrB,OAAO,IAAIsB,M;;;SAGXtB,OAAO,IAAIuB,U;SACXvB,OAAO,IAAIwB,S;SACXxB,OAAO,IAAIyB,M;SACXzB,OAAO,IAAI0B,W;SACX1B,OAAO,IAAI2B,e;;;SAGX3B,OAAO,IAAI4B,c;SACX5B,OAAO,IAAI6B,W;SACX7B,OAAO,IAAI8B,S;SACX9B,OAAO,IAAI+B,U;SACX/B,OAAO,IAAIgC,iB;SACXhC,OAAO,IAAIiC,Q","sourcesContent":["/** Shim for using jquery in frameworks included by react (such as bootstrap) */\nimport * as $ from 'jquery';\n\ndeclare global {\n interface Window {\n $: typeof $;\n jQuery: typeof $;\n }\n}\n\nwindow.$ = $;\nwindow.jQuery = $;\n\nexport type { Range } from '@deephaven/utils';\nexport { default as AutoCompleteInput } from './AutoCompleteInput';\nexport { default as AutoResizeTextarea } from './AutoResizeTextarea';\nexport { default as BasicModal } from './BasicModal';\nexport { default as Button } from './Button';\nexport { default as ButtonGroup } from './ButtonGroup';\nexport { default as ButtonOld } from './ButtonOld';\nexport { default as CardFlip } from './CardFlip';\nexport * from './context-actions';\nexport { default as Collapse } from './Collapse';\nexport { default as Checkbox } from './Checkbox';\nexport { default as ComboBox } from './ComboBox';\nexport { default as CustomTimeSelect } from './CustomTimeSelect';\nexport { default as DebouncedSearchInput } from './DebouncedSearchInput';\nexport { default as DeephavenSpinner } from './DeephavenSpinner';\nexport { default as DraggableItemList } from './DraggableItemList';\nexport * from './DraggableItemList';\nexport { default as DragUtils } from './DragUtils';\nexport { default as HierarchicalCheckboxMenu } from './HierarchicalCheckboxMenu';\nexport * from './HierarchicalCheckboxMenu';\nexport * from './ItemList';\nexport { default as ItemListItem } from './ItemListItem';\nexport { default as LoadingOverlay } from './LoadingOverlay';\nexport { default as LoadingSpinner } from './LoadingSpinner';\nexport { default as DropdownMenu } from './menu-actions';\nexport * from './menu-actions';\nexport { default as MaskedInput } from './MaskedInput';\nexport * from './MaskedInput';\nexport * from './navigation';\nexport { default as Option } from './Option';\nexport * from './popper';\nexport * from './modal';\nexport { default as RadioGroup } from './RadioGroup';\nexport { default as RadioItem } from './RadioItem';\nexport { default as Select } from './Select';\nexport { default as SearchInput } from './SearchInput';\nexport { default as SelectValueList } from './SelectValueList';\nexport * from './SelectValueList';\nexport * from './shortcuts';\nexport { default as SocketedButton } from './SocketedButton';\nexport { default as ThemeExport } from './ThemeExport';\nexport { default as TimeInput } from './TimeInput';\nexport { default as TimeSlider } from './TimeSlider';\nexport { default as ToastNotification } from './ToastNotification';\nexport { default as UISwitch } from './UISwitch';\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["$","window","jQuery","default","AutoCompleteInput","AutoResizeTextarea","BasicModal","Button","ButtonGroup","ButtonOld","CardFlip","Collapse","Checkbox","ComboBox","CustomTimeSelect","DebouncedSearchInput","DeephavenSpinner","DraggableItemList","DragUtils","HierarchicalCheckboxMenu","ItemListItem","LoadingOverlay","LoadingSpinner","DropdownMenu","MaskedInput","Option","RadioGroup","RadioItem","Select","SearchInput","SelectValueList","SocketedButton","ThemeExport","TimeInput","TimeSlider","ToastNotification","UISwitch","ValidateLabelInput"],"mappings":"AAAA;AACA,OAAO,KAAKA,CAAZ,MAAmB,QAAnB;AASAC,MAAM,CAACD,CAAP,GAAWA,CAAX;AACAC,MAAM,CAACC,MAAP,GAAgBF,CAAhB;SAGSG,OAAO,IAAIC,iB;SACXD,OAAO,IAAIE,kB;SACXF,OAAO,IAAIG,U;SACXH,OAAO,IAAII,M;SACXJ,OAAO,IAAIK,W;SACXL,OAAO,IAAIM,S;SACXN,OAAO,IAAIO,Q;;SAEXP,OAAO,IAAIQ,Q;SACXR,OAAO,IAAIS,Q;SACXT,OAAO,IAAIU,Q;SACXV,OAAO,IAAIW,gB;SACXX,OAAO,IAAIY,oB;SACXZ,OAAO,IAAIa,gB;SACXb,OAAO,IAAIc,iB;;SAEXd,OAAO,IAAIe,S;SACXf,OAAO,IAAIgB,wB;;;SAGXhB,OAAO,IAAIiB,Y;SACXjB,OAAO,IAAIkB,c;SACXlB,OAAO,IAAImB,c;SACXnB,OAAO,IAAIoB,Y;;SAEXpB,OAAO,IAAIqB,W;;;SAGXrB,OAAO,IAAIsB,M;;;SAGXtB,OAAO,IAAIuB,U;SACXvB,OAAO,IAAIwB,S;SACXxB,OAAO,IAAIyB,M;SACXzB,OAAO,IAAI0B,W;SACX1B,OAAO,IAAI2B,e;;;SAGX3B,OAAO,IAAI4B,c;SACX5B,OAAO,IAAI6B,W;SACX7B,OAAO,IAAI8B,S;SACX9B,OAAO,IAAI+B,U;SACX/B,OAAO,IAAIgC,iB;SACXhC,OAAO,IAAIiC,Q;SACXjC,OAAO,IAAIkC,kB","sourcesContent":["/** Shim for using jquery in frameworks included by react (such as bootstrap) */\nimport * as $ from 'jquery';\n\ndeclare global {\n interface Window {\n $: typeof $;\n jQuery: typeof $;\n }\n}\n\nwindow.$ = $;\nwindow.jQuery = $;\n\nexport type { Range } from '@deephaven/utils';\nexport { default as AutoCompleteInput } from './AutoCompleteInput';\nexport { default as AutoResizeTextarea } from './AutoResizeTextarea';\nexport { default as BasicModal } from './BasicModal';\nexport { default as Button } from './Button';\nexport { default as ButtonGroup } from './ButtonGroup';\nexport { default as ButtonOld } from './ButtonOld';\nexport { default as CardFlip } from './CardFlip';\nexport * from './context-actions';\nexport { default as Collapse } from './Collapse';\nexport { default as Checkbox } from './Checkbox';\nexport { default as ComboBox } from './ComboBox';\nexport { default as CustomTimeSelect } from './CustomTimeSelect';\nexport { default as DebouncedSearchInput } from './DebouncedSearchInput';\nexport { default as DeephavenSpinner } from './DeephavenSpinner';\nexport { default as DraggableItemList } from './DraggableItemList';\nexport * from './DraggableItemList';\nexport { default as DragUtils } from './DragUtils';\nexport { default as HierarchicalCheckboxMenu } from './HierarchicalCheckboxMenu';\nexport * from './HierarchicalCheckboxMenu';\nexport * from './ItemList';\nexport { default as ItemListItem } from './ItemListItem';\nexport { default as LoadingOverlay } from './LoadingOverlay';\nexport { default as LoadingSpinner } from './LoadingSpinner';\nexport { default as DropdownMenu } from './menu-actions';\nexport * from './menu-actions';\nexport { default as MaskedInput } from './MaskedInput';\nexport * from './MaskedInput';\nexport * from './navigation';\nexport { default as Option } from './Option';\nexport * from './popper';\nexport * from './modal';\nexport { default as RadioGroup } from './RadioGroup';\nexport { default as RadioItem } from './RadioItem';\nexport { default as Select } from './Select';\nexport { default as SearchInput } from './SearchInput';\nexport { default as SelectValueList } from './SelectValueList';\nexport * from './SelectValueList';\nexport * from './shortcuts';\nexport { default as SocketedButton } from './SocketedButton';\nexport { default as ThemeExport } from './ThemeExport';\nexport { default as TimeInput } from './TimeInput';\nexport { default as TimeSlider } from './TimeSlider';\nexport { default as ToastNotification } from './ToastNotification';\nexport { default as UISwitch } from './UISwitch';\nexport { default as ValidateLabelInput } from './ValidateLabelInput';\n"],"file":"index.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deephaven/components",
3
- "version": "0.15.7-beta.0+c54e11a",
3
+ "version": "0.15.7-beta.3+3214155",
4
4
  "description": "Deephaven React component library",
5
5
  "author": "Deephaven Data Labs LLC",
6
6
  "license": "Apache-2.0",
@@ -30,10 +30,10 @@
30
30
  "start": "cross-env NODE_ENV=development npm run watch"
31
31
  },
32
32
  "dependencies": {
33
- "@deephaven/icons": "^0.15.7-beta.0+c54e11a",
34
- "@deephaven/log": "^0.15.7-beta.0+c54e11a",
35
- "@deephaven/react-hooks": "^0.15.7-beta.0+c54e11a",
36
- "@deephaven/utils": "^0.15.7-beta.0+c54e11a",
33
+ "@deephaven/icons": "^0.15.7-beta.3+3214155",
34
+ "@deephaven/log": "^0.15.7-beta.3+3214155",
35
+ "@deephaven/react-hooks": "^0.15.7-beta.3+3214155",
36
+ "@deephaven/utils": "^0.15.7-beta.3+3214155",
37
37
  "@fortawesome/fontawesome-svg-core": "^6.1.1",
38
38
  "@fortawesome/react-fontawesome": "^0.1.18",
39
39
  "bootstrap": "4.6.1",
@@ -57,8 +57,8 @@
57
57
  "react-dom": "^17.x"
58
58
  },
59
59
  "devDependencies": {
60
- "@deephaven/mocks": "^0.15.7-beta.0+c54e11a",
61
- "@deephaven/tsconfig": "^0.15.7-beta.0+c54e11a"
60
+ "@deephaven/mocks": "^0.15.7-beta.3+3214155",
61
+ "@deephaven/tsconfig": "^0.15.7-beta.3+3214155"
62
62
  },
63
63
  "files": [
64
64
  "dist",
@@ -70,5 +70,5 @@
70
70
  "publishConfig": {
71
71
  "access": "public"
72
72
  },
73
- "gitHead": "c54e11a1fe772b855b6bac2a1534857c8cedc8f8"
73
+ "gitHead": "32141554dfc8a60ff2629fd7aa4e65d79dd35c07"
74
74
  }