lexgui 0.6.11 → 0.6.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/lexgui.js CHANGED
@@ -14,7 +14,7 @@ console.warn( 'Script _build/lexgui.js_ is depracated and will be removed soon.
14
14
  */
15
15
 
16
16
  const LX = {
17
- version: "0.6.11",
17
+ version: "0.6.12",
18
18
  ready: false,
19
19
  components: [], // Specific pre-build components
20
20
  signals: {}, // Events and triggers
@@ -879,6 +879,58 @@ class Popover {
879
879
  }
880
880
  LX.Popover = Popover;
881
881
 
882
+ /**
883
+ * @class PopConfirm
884
+ */
885
+
886
+ class PopConfirm {
887
+
888
+ constructor( reference, options = {} ) {
889
+
890
+ const okText = options.confirmText ?? "Yes";
891
+ const cancelText = options.cancelText ?? "No";
892
+ const title = options.title ?? "Confirm";
893
+ const content = options.content ?? "Are you sure you want to proceed?";
894
+ const onConfirm = options.onConfirm;
895
+ const onCancel = options.onCancel;
896
+
897
+ const popoverContainer = LX.makeContainer( ["auto", "auto"], "tour-step-container" );
898
+
899
+ {
900
+ const headerDiv = LX.makeContainer( ["100%", "auto"], "flex flex-row", "", popoverContainer );
901
+ LX.makeContainer( ["100%", "auto"], "p-1 font-medium text-md", title, headerDiv );
902
+ }
903
+
904
+ LX.makeContainer( ["100%", "auto"], "p-1 text-md", content, popoverContainer, { maxWidth: "400px" } );
905
+ const footer = LX.makeContainer( ["100%", "auto"], "flex flex-row text-md", "", popoverContainer );
906
+ const footerButtons = LX.makeContainer( ["100%", "auto"], "text-md", "", footer );
907
+ const footerPanel = new LX.Panel();
908
+ footerButtons.appendChild( footerPanel.root );
909
+
910
+ footerPanel.sameLine( 2, "justify-end" );
911
+ footerPanel.addButton( null, cancelText, () => {
912
+ if( onCancel ) onCancel();
913
+ this._popover?.destroy();
914
+ }, { xbuttonClass: "contrast" } );
915
+ footerPanel.addButton( null, okText, () => {
916
+ if( onConfirm ) onConfirm();
917
+ this._popover?.destroy();
918
+ }, { buttonClass: "accent" } );
919
+
920
+ this._popover?.destroy();
921
+ this._popover = new LX.Popover( null, [ popoverContainer ], {
922
+ reference,
923
+ side: options.side ?? "top",
924
+ align: options.align,
925
+ sideOffset: options.sideOffset,
926
+ alignOffset: options.alignOffset,
927
+ } );
928
+
929
+ }
930
+ }
931
+
932
+ LX.PopConfirm = PopConfirm;
933
+
882
934
  /**
883
935
  * @class Sheet
884
936
  */
@@ -1674,8 +1726,15 @@ class Calendar {
1674
1726
  this.root = LX.makeContainer( ["256px", "auto"], "p-1 text-md" );
1675
1727
 
1676
1728
  this.onChange = options.onChange;
1729
+ this.onPreviousMonth = options.onPreviousMonth;
1730
+ this.onNextMonth = options.onNextMonth;
1731
+
1677
1732
  this.untilToday = options.untilToday;
1678
1733
  this.fromToday = options.fromToday;
1734
+ this.range = options.range;
1735
+
1736
+ this.skipPrevMonth = options.skipPrevMonth;
1737
+ this.skipNextMonth = options.skipNextMonth;
1679
1738
 
1680
1739
  if( dateString )
1681
1740
  {
@@ -1699,7 +1758,7 @@ class Calendar {
1699
1758
  }
1700
1759
  }
1701
1760
 
1702
- _previousMonth() {
1761
+ _previousMonth( skipCallback ) {
1703
1762
 
1704
1763
  this.month = Math.max( 0, this.month - 1 );
1705
1764
 
@@ -1710,9 +1769,14 @@ class Calendar {
1710
1769
  }
1711
1770
 
1712
1771
  this.fromMonthYear( this.month, this.year );
1772
+
1773
+ if( !skipCallback && this.onPreviousMonth )
1774
+ {
1775
+ this.onPreviousMonth( this.currentDate );
1776
+ }
1713
1777
  }
1714
1778
 
1715
- _nextMonth() {
1779
+ _nextMonth( skipCallback ) {
1716
1780
 
1717
1781
  this.month = Math.min( this.month + 1, 12 );
1718
1782
 
@@ -1723,6 +1787,11 @@ class Calendar {
1723
1787
  }
1724
1788
 
1725
1789
  this.fromMonthYear( this.month, this.year );
1790
+
1791
+ if( !skipCallback && this.onNextMonth )
1792
+ {
1793
+ this.onNextMonth( this.currentDate );
1794
+ }
1726
1795
  }
1727
1796
 
1728
1797
  refresh() {
@@ -1733,19 +1802,25 @@ class Calendar {
1733
1802
  {
1734
1803
  const header = LX.makeContainer( ["100%", "auto"], "flex flex-row p-1", "", this.root );
1735
1804
 
1736
- const prevMonthIcon = LX.makeIcon( "Left", { title: "Previous Month", iconClass: "border p-1 rounded hover:bg-secondary", svgClass: "sm" } );
1737
- header.appendChild( prevMonthIcon );
1738
- prevMonthIcon.addEventListener( "click", () => {
1739
- this._previousMonth();
1740
- } );
1805
+ if( !this.skipPrevMonth )
1806
+ {
1807
+ const prevMonthIcon = LX.makeIcon( "Left", { title: "Previous Month", iconClass: "border p-1 rounded hover:bg-secondary", svgClass: "sm" } );
1808
+ header.appendChild( prevMonthIcon );
1809
+ prevMonthIcon.addEventListener( "click", () => {
1810
+ this._previousMonth();
1811
+ } );
1812
+ }
1741
1813
 
1742
1814
  LX.makeContainer( ["100%", "auto"], "text-center font-medium select-none", `${ this.monthName } ${ this.year }`, header );
1743
1815
 
1744
- const nextMonthIcon = LX.makeIcon( "Right", { title: "Next Month", iconClass: "border p-1 rounded hover:bg-secondary", svgClass: "sm" } );
1745
- header.appendChild( nextMonthIcon );
1746
- nextMonthIcon.addEventListener( "click", () => {
1747
- this._nextMonth();
1748
- } );
1816
+ if( !this.skipNextMonth )
1817
+ {
1818
+ const nextMonthIcon = LX.makeIcon( "Right", { title: "Next Month", iconClass: "border p-1 rounded hover:bg-secondary", svgClass: "sm" } );
1819
+ header.appendChild( nextMonthIcon );
1820
+ nextMonthIcon.addEventListener( "click", () => {
1821
+ this._nextMonth();
1822
+ } );
1823
+ }
1749
1824
  }
1750
1825
 
1751
1826
  // Body
@@ -1777,6 +1852,11 @@ class Calendar {
1777
1852
  const body = document.createElement( 'tbody' );
1778
1853
  daysTable.appendChild( body );
1779
1854
 
1855
+ let fromRangeDate = this.range ? LX.dateFromDateString( this.range[ 0 ] ) : null;
1856
+ let toRangeDate = this.range ? LX.dateFromDateString( this.range[ 1 ] ) : null;
1857
+
1858
+ this.currentDate ? new Date( `${ this.currentDate.month }/${ this.currentDate.day }/${ this.currentDate.year }` ) : null;
1859
+
1780
1860
  for( let week = 0; week < 6; week++ )
1781
1861
  {
1782
1862
  const hrow = document.createElement( 'tr' );
@@ -1789,15 +1869,28 @@ class Calendar {
1789
1869
 
1790
1870
  const dayDate = new Date( `${ this.month }/${ dayData.day }/${ this.year }` );
1791
1871
  const date = new Date();
1872
+ // today inclusives
1792
1873
  const beforeToday = this.untilToday ? ( dayDate.getTime() < date.getTime() ) : true;
1793
- const afterToday = this.fromToday ? ( dayDate.getTime() > date.getTime() ) : true;
1874
+ const afterToday = this.fromToday ? ( dayDate.getFullYear() > date.getFullYear() ||
1875
+ (dayDate.getFullYear() === date.getFullYear() && dayDate.getMonth() > date.getMonth()) ||
1876
+ (dayDate.getFullYear() === date.getFullYear() && dayDate.getMonth() === date.getMonth() && dayDate.getDate() >= date.getDate())
1877
+ ) : true;
1794
1878
  const selectable = dayData.currentMonth && beforeToday && afterToday;
1795
-
1796
- if( this.currentDate && ( dayData.day == this.currentDate.day ) && ( this.month == this.currentDate.month )
1797
- && ( this.year == this.currentDate.year ) && dayData.currentMonth )
1879
+ const currentDay = this.currentDate && ( dayData.day == this.currentDate.day ) && ( this.month == this.currentDate.month )
1880
+ && ( this.year == this.currentDate.year ) && dayData.currentMonth;
1881
+ const currentFromRange = selectable && fromRangeDate && ( dayData.day == fromRangeDate.getDate() ) && ( this.month == ( fromRangeDate.getMonth() + 1 ) )
1882
+ && ( this.year == fromRangeDate.getFullYear() );
1883
+ const currentToRange = selectable && toRangeDate && ( dayData.day == toRangeDate.getDate() ) && ( this.month == ( toRangeDate.getMonth() + 1 ) )
1884
+ && ( this.year == toRangeDate.getFullYear() );
1885
+
1886
+ if( ( !this.range && currentDay ) || this.range && ( currentFromRange || currentToRange ) )
1798
1887
  {
1799
1888
  th.className += ` bg-contrast fg-contrast`;
1800
1889
  }
1890
+ else if( this.range && selectable && ( dayDate > fromRangeDate ) && ( dayDate < toRangeDate ) )
1891
+ {
1892
+ th.className += ` bg-accent fg-contrast`;
1893
+ }
1801
1894
  else
1802
1895
  {
1803
1896
  th.className += ` ${ selectable ? "fg-primary" : "fg-tertiary" } hover:bg-secondary`;
@@ -1817,6 +1910,20 @@ class Calendar {
1817
1910
  }
1818
1911
  } );
1819
1912
  }
1913
+ // This event should only be applied in non current month days
1914
+ else if( this.range === undefined && !dayData.currentMonth )
1915
+ {
1916
+ th.addEventListener( "click", () => {
1917
+ if( dayData?.prevMonth )
1918
+ {
1919
+ this._previousMonth();
1920
+ }
1921
+ else
1922
+ {
1923
+ this._nextMonth();
1924
+ }
1925
+ } );
1926
+ }
1820
1927
  }
1821
1928
 
1822
1929
  body.appendChild( hrow );
@@ -1831,6 +1938,7 @@ class Calendar {
1831
1938
 
1832
1939
  this.day = parseInt( tokens[ 0 ] );
1833
1940
  this.month = parseInt( tokens[ 1 ] );
1941
+ this.monthName = this.getMonthName( this.month - 1 );
1834
1942
  this.year = parseInt( tokens[ 2 ] );
1835
1943
 
1836
1944
  this.currentDate = this._getCurrentDate();
@@ -1860,7 +1968,7 @@ class Calendar {
1860
1968
  // Fill in days from previous month
1861
1969
  for( let i = firstDay - 1; i >= 0; i--)
1862
1970
  {
1863
- calendarDays.push( { day: daysInPrevMonth - i, currentMonth: false } );
1971
+ calendarDays.push( { day: daysInPrevMonth - i, currentMonth: false, prevMonth: true } );
1864
1972
  }
1865
1973
 
1866
1974
  // Fill in current month days
@@ -1873,7 +1981,7 @@ class Calendar {
1873
1981
  const remaining = 42 - calendarDays.length;
1874
1982
  for( let i = 1; i <= remaining; i++ )
1875
1983
  {
1876
- calendarDays.push( { day: i, currentMonth: false } );
1984
+ calendarDays.push( { day: i, currentMonth: false, nextMonth: true } );
1877
1985
  }
1878
1986
 
1879
1987
  this.monthName = this.getMonthName( month );
@@ -1889,8 +1997,14 @@ class Calendar {
1889
1997
  return formatter.format( new Date( 2000, monthIndex, 1 ) );
1890
1998
  }
1891
1999
 
1892
- getFullDate() {
1893
- return `${ this.monthName } ${ this.day }${ this._getOrdinalSuffix( this.day ) }, ${ this.year }`;
2000
+ getFullDate( monthName, day, year ) {
2001
+ return `${ monthName ?? this.monthName } ${ day ?? this.day }${ this._getOrdinalSuffix( day ?? this.day ) }, ${ year ?? this.year }`;
2002
+ }
2003
+
2004
+ setRange( range ) {
2005
+ console.assert( range.constructor === Array, "Date Range must be in Array format" );
2006
+ this.range = range;
2007
+ this.refresh();
1894
2008
  }
1895
2009
 
1896
2010
  _getOrdinalSuffix( day ) {
@@ -1907,6 +2021,110 @@ class Calendar {
1907
2021
 
1908
2022
  LX.Calendar = Calendar;
1909
2023
 
2024
+ class CalendarRange {
2025
+
2026
+ /**
2027
+ * @constructor CalendarRange
2028
+ * @param {Array} range ["DD/MM/YYYY", "DD/MM/YYYY"]
2029
+ * @param {Object} options
2030
+ */
2031
+
2032
+ constructor( range, options = {} ) {
2033
+
2034
+ this.root = LX.makeContainer( ["auto", "auto"], "flex flex-row" );
2035
+
2036
+ console.assert( range && range.constructor === Array, "Range cannot be empty and has to be an Array!" );
2037
+
2038
+ let mustAdvanceMonth = false;
2039
+
2040
+ // Fix any issues with date range picking
2041
+ {
2042
+ const t0 = LX.dateFromDateString( range[ 0 ] );
2043
+ const t1 = LX.dateFromDateString( range[ 1 ] );
2044
+
2045
+ if( t0 > t1 )
2046
+ {
2047
+ const tmp = range[ 0 ];
2048
+ range[ 0 ] = range[ 1 ];
2049
+ range[ 1 ] = tmp;
2050
+ }
2051
+
2052
+ mustAdvanceMonth = ( t0.getMonth() == t1.getMonth() ) && ( t0.getFullYear() == t1.getFullYear() );
2053
+ }
2054
+
2055
+ this.from = range[ 0 ];
2056
+ this.to = range[ 1 ];
2057
+
2058
+ this._selectingRange = false;
2059
+
2060
+ const onChange = ( date ) => {
2061
+
2062
+ const newDateString = `${ date.day }/${ date.month }/${ date.year }`;
2063
+
2064
+ if( !this._selectingRange )
2065
+ {
2066
+ this.from = this.to = newDateString;
2067
+ this._selectingRange = true;
2068
+ }
2069
+ else
2070
+ {
2071
+ this.to = newDateString;
2072
+ this._selectingRange = false;
2073
+ }
2074
+
2075
+ const newRange = [ this.from, this.to ];
2076
+
2077
+ this.fromCalendar.setRange( newRange );
2078
+ this.toCalendar.setRange( newRange );
2079
+
2080
+ if( options.onChange )
2081
+ {
2082
+ options.onChange( newRange );
2083
+ }
2084
+
2085
+ };
2086
+
2087
+ this.fromCalendar = new LX.Calendar( this.from, {
2088
+ skipNextMonth: true,
2089
+ onChange,
2090
+ onPreviousMonth: () => {
2091
+ this.toCalendar._previousMonth();
2092
+ },
2093
+ range
2094
+ });
2095
+
2096
+ this.toCalendar = new LX.Calendar( this.to, {
2097
+ skipPrevMonth: true,
2098
+ onChange,
2099
+ onNextMonth: () => {
2100
+ this.fromCalendar._nextMonth();
2101
+ },
2102
+ range
2103
+ });
2104
+
2105
+ if( mustAdvanceMonth )
2106
+ {
2107
+ this.toCalendar._nextMonth( true );
2108
+ }
2109
+
2110
+ this.root.appendChild( this.fromCalendar.root );
2111
+ this.root.appendChild( this.toCalendar.root );
2112
+ }
2113
+
2114
+ getFullDate() {
2115
+
2116
+ const d0 = LX.dateFromDateString( this.from );
2117
+ const d0Month = this.fromCalendar.getMonthName( d0.getMonth() );
2118
+
2119
+ const d1 = LX.dateFromDateString( this.to );
2120
+ const d1Month = this.toCalendar.getMonthName( d1.getMonth() );
2121
+
2122
+ return `${ this.fromCalendar.getFullDate( d0Month, d0.getDate(), d0.getFullYear() ) } to ${ this.toCalendar.getFullDate( d1Month, d1.getDate(), d1.getFullYear() ) }`;
2123
+ }
2124
+ }
2125
+
2126
+ LX.CalendarRange = CalendarRange;
2127
+
1910
2128
  /**
1911
2129
  * @class Tabs
1912
2130
  */
@@ -4757,6 +4975,22 @@ function hsvToRgb( hsv )
4757
4975
 
4758
4976
  LX.hsvToRgb = hsvToRgb;
4759
4977
 
4978
+ /**
4979
+ * @method dateFromDateString
4980
+ * @description Get an instance of Date() from a Date in String format (DD/MM/YYYY)
4981
+ * @param {String} dateString
4982
+ */
4983
+ function dateFromDateString( dateString )
4984
+ {
4985
+ const tokens = dateString.split( '/' );
4986
+ const day = parseInt( tokens[ 0 ] );
4987
+ const month = parseInt( tokens[ 1 ] );
4988
+ const year = parseInt( tokens[ 2 ] );
4989
+ return new Date( `${ month }/${ day }/${ year }` );
4990
+ }
4991
+
4992
+ LX.dateFromDateString = dateFromDateString;
4993
+
4760
4994
  /**
4761
4995
  * @method measureRealWidth
4762
4996
  * @description Measure the pixel width of a text
@@ -8688,6 +8922,20 @@ class Button extends Widget {
8688
8922
  {
8689
8923
  wValue.querySelector( ".file-input" ).click();
8690
8924
  }
8925
+ else if( options.mustConfirm )
8926
+ {
8927
+ new LX.PopConfirm( wValue, {
8928
+ onConfirm: () => {
8929
+ this._trigger( new LX.IEvent( name, value, e ), callback );
8930
+ },
8931
+ side: options.confirmSide,
8932
+ align: options.confirmAlign,
8933
+ confirmText: options.confirmText,
8934
+ cancelText: options.confirmCancelText,
8935
+ title: options.confirmTitle,
8936
+ content: options.confirmContent
8937
+ } );
8938
+ }
8691
8939
  else
8692
8940
  {
8693
8941
  const swapInput = wValue.querySelector( "input" );
@@ -12443,25 +12691,30 @@ LX.Table = Table;
12443
12691
 
12444
12692
  class DatePicker extends Widget {
12445
12693
 
12446
- constructor( name, dateString, callback, options = { } ) {
12694
+ constructor( name, dateValue, callback, options = { } ) {
12447
12695
 
12448
12696
  super( Widget.DATE, name, null, options );
12449
12697
 
12450
- if( options.today )
12698
+ const dateAsRange = ( dateValue?.constructor === Array );
12699
+
12700
+ if( !dateAsRange && options.today )
12451
12701
  {
12452
12702
  const date = new Date();
12453
- dateString = `${ date.getDate() }/${ date.getMonth() + 1 }/${ date.getFullYear() }`;
12703
+ dateValue = `${ date.getDate() }/${ date.getMonth() + 1 }/${ date.getFullYear() }`;
12454
12704
  }
12455
12705
 
12456
12706
  this.onGetValue = () => {
12457
- return dateString;
12707
+ return dateValue;
12458
12708
  };
12459
12709
 
12460
12710
  this.onSetValue = ( newValue, skipCallback, event ) => {
12461
12711
 
12462
- dateString = newValue;
12712
+ if( !dateAsRange )
12713
+ {
12714
+ this.calendar.fromDateString( newValue );
12715
+ }
12463
12716
 
12464
- this.calendar.fromDateString( newValue );
12717
+ dateValue = newValue;
12465
12718
 
12466
12719
  refresh( this.calendar.getFullDate() );
12467
12720
 
@@ -12476,26 +12729,80 @@ class DatePicker extends Widget {
12476
12729
  container.style.width = `calc( 100% - ${ realNameWidth })`;
12477
12730
  };
12478
12731
 
12479
- const container = document.createElement('div');
12480
- container.className = "lexdate";
12732
+ const container = LX.makeContainer( [ "auto", "auto" ], "lexdate flex flex-row" );
12481
12733
  this.root.appendChild( container );
12482
12734
 
12483
- this.calendar = new LX.Calendar( dateString, { onChange: ( date ) => {
12484
- this.set( `${ date.day }/${ date.month }/${ date.year }` );
12485
- }, ...options });
12735
+ if( !dateAsRange )
12736
+ {
12737
+ this.calendar = new LX.Calendar( dateValue, {
12738
+ onChange: ( date ) => {
12739
+ const newDateString = `${ date.day }/${ date.month }/${ date.year }`;
12740
+ this.set( newDateString );
12741
+ },
12742
+ ...options
12743
+ });
12744
+ }
12745
+ else
12746
+ {
12747
+ this.calendar = new LX.CalendarRange( dateValue, {
12748
+ onChange: ( dateRange ) => {
12749
+ this.set( dateRange );
12750
+ },
12751
+ ...options
12752
+ });
12753
+ }
12486
12754
 
12487
12755
  const refresh = ( currentDate ) => {
12756
+
12757
+ const emptyDate = !!currentDate;
12758
+
12488
12759
  container.innerHTML = "";
12760
+
12761
+ currentDate = currentDate ?? "Pick a date";
12762
+
12763
+ const dts = currentDate.split( " to " );
12764
+ const d0 = dateAsRange ? dts[ 0 ] : currentDate;
12765
+
12489
12766
  const calendarIcon = LX.makeIcon( "Calendar" );
12490
- const calendarButton = new LX.Button( null, currentDate ?? "Pick a date", () => {
12767
+ const calendarButton = new LX.Button( null, d0, () => {
12491
12768
  this._popover = new LX.Popover( calendarButton.root, [ this.calendar ] );
12492
- }, { buttonClass: `flex flex-row px-3 ${ currentDate ? "" : "fg-tertiary" } justify-between` } );
12493
-
12769
+ if( dateAsRange )
12770
+ {
12771
+ Object.assign( this._popover.root.style, { display: "flex", width: "auto" } );
12772
+ }
12773
+ }, { buttonClass: `flex flex-row px-3 ${ emptyDate ? "" : "fg-tertiary" } justify-between` } );
12494
12774
  calendarButton.root.querySelector( "button" ).appendChild( calendarIcon );
12775
+ calendarButton.root.style.width = "100%";
12495
12776
  container.appendChild( calendarButton.root );
12777
+
12778
+ if( dateAsRange )
12779
+ {
12780
+ const arrowRightIcon = LX.makeIcon( "ArrowRight" );
12781
+ LX.makeContainer( ["32px", "auto"], "content-center", arrowRightIcon.innerHTML, container );
12782
+
12783
+ const d1 = dts[ 1 ];
12784
+ const calendarIcon = LX.makeIcon( "Calendar" );
12785
+ const calendarButton = new LX.Button( null, d1, () => {
12786
+ this._popover = new LX.Popover( calendarButton.root, [ this.calendar ] );
12787
+ if( dateAsRange )
12788
+ {
12789
+ Object.assign( this._popover.root.style, { display: "flex", width: "auto" } );
12790
+ }
12791
+ }, { buttonClass: `flex flex-row px-3 ${ emptyDate ? "" : "fg-tertiary" } justify-between` } );
12792
+ calendarButton.root.querySelector( "button" ).appendChild( calendarIcon );
12793
+ calendarButton.root.style.width = "100%";
12794
+ container.appendChild( calendarButton.root );
12795
+ }
12496
12796
  };
12497
12797
 
12498
- refresh( dateString ? this.calendar.getFullDate(): null );
12798
+ if( dateValue )
12799
+ {
12800
+ refresh( this.calendar.getFullDate() );
12801
+ }
12802
+ else
12803
+ {
12804
+ refresh();
12805
+ }
12499
12806
 
12500
12807
  LX.doAsync( this.onResize.bind( this ) );
12501
12808
  }
@@ -13161,6 +13468,7 @@ class Panel {
13161
13468
  * img: Path to image to show as button value
13162
13469
  * title: Text to show in native Element title
13163
13470
  * buttonClass: Class to add to the native button element
13471
+ * mustConfirm: User must confirm trigger in a popover
13164
13472
  */
13165
13473
 
13166
13474
  addButton( name, value, callback, options = {} ) {
@@ -13706,7 +14014,7 @@ class Panel {
13706
14014
  /**
13707
14015
  * @method addDate
13708
14016
  * @param {String} name Widget name
13709
- * @param {String} dateString
14017
+ * @param {String} dateValue
13710
14018
  * @param {Function} callback
13711
14019
  * @param {Object} options:
13712
14020
  * hideName: Don't use name as label [false]
@@ -13715,8 +14023,8 @@ class Panel {
13715
14023
  * fromToday: Allow dates only from current day
13716
14024
  */
13717
14025
 
13718
- addDate( name, dateString, callback, options = { } ) {
13719
- const widget = new LX.DatePicker( name, dateString, callback, options );
14026
+ addDate( name, dateValue, callback, options = { } ) {
14027
+ const widget = new LX.DatePicker( name, dateValue, callback, options );
13720
14028
  return this._attachWidget( widget );
13721
14029
  }
13722
14030
 
@@ -15855,6 +16163,8 @@ LX.AssetView = AssetView;
15855
16163
 
15856
16164
  class Tour {
15857
16165
 
16166
+ static ACTIVE_TOURS = [];
16167
+
15858
16168
  /**
15859
16169
  * @constructor Tour
15860
16170
  * @param {Array} steps
@@ -15877,11 +16187,21 @@ class Tour {
15877
16187
  this.verticalOffset = options.verticalOffset;
15878
16188
  this.radius = options.radius ?? 12;
15879
16189
 
15880
- this.tourContainer = LX.makeContainer( ["100%", "100%"], "tour-container" );
15881
- this.tourContainer.style.display = "none";
15882
- document.body.appendChild( this.tourContainer );
16190
+ this.tourContainer = document.querySelector( ".tour-container" );
16191
+ if( !this.tourContainer )
16192
+ {
16193
+ this.tourContainer = LX.makeContainer( ["100%", "100%"], "tour-container" );
16194
+ this.tourContainer.style.display = "none";
16195
+ document.body.appendChild( this.tourContainer );
15883
16196
 
15884
- this.tourMask = LX.makeContainer( ["100%", "100%"], "tour-mask" );
16197
+ window.addEventListener( "resize", () => {
16198
+
16199
+ for( const tour of Tour.ACTIVE_TOURS )
16200
+ {
16201
+ tour._showStep( 0 );
16202
+ }
16203
+ } );
16204
+ }
15885
16205
  }
15886
16206
 
15887
16207
  /**
@@ -15892,14 +16212,10 @@ class Tour {
15892
16212
 
15893
16213
  this.currentStep = 0;
15894
16214
 
15895
- if ( this.useModal )
15896
- {
15897
- this.tourMask.style.display = "block";
15898
- this.tourContainer.appendChild( this.tourMask );
15899
- }
15900
-
15901
16215
  this.tourContainer.style.display = "block";
15902
16216
 
16217
+ Tour.ACTIVE_TOURS.push( this );
16218
+
15903
16219
  this._showStep( 0 );
15904
16220
  }
15905
16221
 
@@ -15911,12 +16227,19 @@ class Tour {
15911
16227
 
15912
16228
  if( this.useModal )
15913
16229
  {
15914
- this.tourMask.style.display = "none";
15915
- this.tourContainer.removeChild( this.tourMask );
16230
+ this.tourMask.remove();
16231
+ this.tourMask = undefined;
15916
16232
  }
15917
16233
 
15918
16234
  this._popover?.destroy();
15919
16235
 
16236
+ const index = Tour.ACTIVE_TOURS.indexOf( this );
16237
+ if( index !== -1 )
16238
+ {
16239
+ Tour.ACTIVE_TOURS.splice( index, 1 );
16240
+ }
16241
+
16242
+ this.tourContainer.innerHTML = "";
15920
16243
  this.tourContainer.style.display = "none";
15921
16244
  }
15922
16245
 
@@ -15934,7 +16257,11 @@ class Tour {
15934
16257
  const prevStep = this.steps[ this.currentStep - 1 ];
15935
16258
  const nextStep = this.steps[ this.currentStep + 1 ];
15936
16259
 
15937
- this._generateMask( step.reference );
16260
+ if( this.useModal )
16261
+ {
16262
+ this._generateMask( step.reference );
16263
+ }
16264
+
15938
16265
  this._createHighlight( step, prevStep, nextStep );
15939
16266
  }
15940
16267
 
@@ -15942,7 +16269,10 @@ class Tour {
15942
16269
  // using a fullscreen SVG with "rect" elements
15943
16270
  _generateMask( reference ) {
15944
16271
 
15945
- this.tourMask.innerHTML = ""; // Clear previous content
16272
+ this.tourContainer.innerHTML = ""; // Clear previous content
16273
+
16274
+ this.tourMask = LX.makeContainer( ["100%", "100%"], "tour-mask" );
16275
+ this.tourContainer.appendChild( this.tourMask );
15946
16276
 
15947
16277
  const svg = document.createElementNS( "http://www.w3.org/2000/svg", "svg" );
15948
16278
  svg.style.width = "100%";
@@ -15972,7 +16302,7 @@ class Tour {
15972
16302
  const rect = document.createElementNS( "http://www.w3.org/2000/svg", "rect" );
15973
16303
  rect.setAttribute( "x", 0 );
15974
16304
  rect.setAttribute( "y", 0 );
15975
- rect.setAttribute( "width", boundingX - hOffset );
16305
+ rect.setAttribute( "width", Math.max( 0, boundingX - hOffset ) );
15976
16306
  rect.setAttribute( "height", window.innerHeight );
15977
16307
  rect.setAttribute( "stroke", "none" );
15978
16308
  clipPath.appendChild( rect );
@@ -15983,8 +16313,8 @@ class Tour {
15983
16313
  const rect = document.createElementNS( "http://www.w3.org/2000/svg", "rect" );
15984
16314
  rect.setAttribute( "x", boundingX - hOffset );
15985
16315
  rect.setAttribute( "y", 0 );
15986
- rect.setAttribute( "width", boundingWidth + hOffset * 2 );
15987
- rect.setAttribute( "height", boundingY - vOffset );
16316
+ rect.setAttribute( "width", Math.max( 0, boundingWidth + hOffset * 2 ) );
16317
+ rect.setAttribute( "height", Math.max( 0, boundingY - vOffset ) );
15988
16318
  rect.setAttribute( "stroke", "none" );
15989
16319
  clipPath.appendChild( rect );
15990
16320
  }
@@ -15994,8 +16324,8 @@ class Tour {
15994
16324
  const rect = document.createElementNS( "http://www.w3.org/2000/svg", "rect" );
15995
16325
  rect.setAttribute( "x", boundingX - hOffset );
15996
16326
  rect.setAttribute( "y", boundingY + boundingHeight + vOffset );
15997
- rect.setAttribute( "width", boundingWidth + hOffset * 2 );
15998
- rect.setAttribute( "height", window.innerHeight - boundingY - boundingHeight - vOffset );
16327
+ rect.setAttribute( "width", Math.max( 0, boundingWidth + hOffset * 2 ) );
16328
+ rect.setAttribute( "height", Math.max( 0, window.innerHeight - boundingY - boundingHeight - vOffset ) );
15999
16329
  rect.setAttribute( "stroke", "none" );
16000
16330
  clipPath.appendChild( rect );
16001
16331
  }
@@ -16005,8 +16335,8 @@ class Tour {
16005
16335
  const rect = document.createElementNS( "http://www.w3.org/2000/svg", "rect" );
16006
16336
  rect.setAttribute( "x", boundingX + boundingWidth + hOffset );
16007
16337
  rect.setAttribute( "y", 0 );
16008
- rect.setAttribute( "width", window.innerWidth - boundingX - boundingWidth );
16009
- rect.setAttribute( "height", window.innerHeight );
16338
+ rect.setAttribute( "width", Math.max( 0, window.innerWidth - boundingX - boundingWidth ) );
16339
+ rect.setAttribute( "height", Math.max( 0, window.innerHeight ) );
16010
16340
  rect.setAttribute( "stroke", "none" );
16011
16341
  clipPath.appendChild( rect );
16012
16342
  }