@emuanalytics/flow-rdf-ui 0.0.25 → 0.0.26

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/dist/index.mjs CHANGED
@@ -7,16 +7,7 @@ import { html as html$1, literal } from 'lit/static-html.js';
7
7
  import { autoUpdate, offset, size, flip, shift, arrow, platform, computePosition } from '@floating-ui/dom';
8
8
  import { offsetParent } from 'composed-offset-position';
9
9
  import * as animations from '@shoelace-style/animations';
10
- import dayjs from 'dayjs';
11
- export { default as dayjs } from 'dayjs';
12
- import utc from 'dayjs/plugin/utc';
13
- import timezone from 'dayjs/plugin/timezone';
14
- import localeData from 'dayjs/plugin/localeData';
15
- import AdvancedFormat from 'dayjs/plugin/advancedFormat';
16
- import QuarterOfYear from 'dayjs/plugin/quarterOfYear';
17
- import LocalizedFormat from 'dayjs/plugin/localizedFormat';
18
- import CustomParseFormat from 'dayjs/plugin/customParseFormat';
19
- import isoWeek from 'dayjs/plugin/isoWeek';
10
+ import { DateTime, Info, Settings } from 'luxon';
20
11
  import { map } from 'lit/directives/map.js';
21
12
  import { range } from 'lit/directives/range.js';
22
13
  import { _adapters, DoughnutController, PolarAreaController, Scale, LinearScale, Chart, BarController, LineController, ScatterController, LineElement, PointElement, BarElement, CategoryScale, LogarithmicScale, TimeScale, TimeSeriesScale, Legend, Tooltip, Title, Interaction } from 'chart.js';
@@ -24,12 +15,14 @@ export { Chart as ChartJs } from 'chart.js';
24
15
  import { createRef, ref } from 'lit/directives/ref.js';
25
16
  import { MatrixController, MatrixElement } from 'chartjs-chart-matrix';
26
17
  import AnnotationPlugin from 'chartjs-plugin-annotation';
18
+ import { isNumber as isNumber$1 } from 'chart.js/helpers';
27
19
  import { scaleSymlog } from 'd3-scale';
28
20
  import { live } from 'lit/directives/live.js';
29
21
  import { TinyColor } from '@ctrl/tinycolor';
30
22
  import { styleMap } from 'lit/directives/style-map.js';
31
23
  import { format, formatLocale } from 'd3-format';
32
24
  import { OverlayScrollbars } from 'overlayscrollbars';
25
+ import { unsafeHTML } from 'lit/directives/unsafe-html.js';
33
26
  import { when } from 'lit/directives/when.js';
34
27
  import { choose } from 'lit/directives/choose.js';
35
28
 
@@ -651,10 +644,8 @@ __decorateClass$$([
651
644
  let FlowIcon = _FlowIcon;
652
645
 
653
646
  const styles$Z = css`
654
- ${componentStyles}
655
-
656
647
  :host {
657
- --arrow-color: var(--flow-ui-color-neutral-1000);
648
+ --arrow-color: var(--sl-color-neutral-1000);
658
649
  --arrow-size: 6px;
659
650
 
660
651
  /*
@@ -690,6 +681,26 @@ const styles$Z = css`
690
681
  background: var(--arrow-color);
691
682
  z-index: -1;
692
683
  }
684
+
685
+ /* Hover bridge */
686
+ .popup-hover-bridge:not(.popup-hover-bridge--visible) {
687
+ display: none;
688
+ }
689
+
690
+ .popup-hover-bridge {
691
+ position: fixed;
692
+ z-index: calc(var(--sl-z-index-dropdown) - 1);
693
+ top: 0;
694
+ right: 0;
695
+ bottom: 0;
696
+ left: 0;
697
+ clip-path: polygon(
698
+ var(--hover-bridge-top-left-x, 0) var(--hover-bridge-top-left-y, 0),
699
+ var(--hover-bridge-top-right-x, 0) var(--hover-bridge-top-right-y, 0),
700
+ var(--hover-bridge-bottom-right-x, 0) var(--hover-bridge-bottom-right-y, 0),
701
+ var(--hover-bridge-bottom-left-x, 0) var(--hover-bridge-bottom-left-y, 0)
702
+ );
703
+ }
693
704
  `;
694
705
 
695
706
  var __defProp$_ = Object.defineProperty;
@@ -703,7 +714,10 @@ var __decorateClass$_ = (decorators, target, key, kind) => {
703
714
  __defProp$_(target, key, result);
704
715
  return result;
705
716
  };
706
- let FlowPopup = class extends FlowRdfElement {
717
+ function isVirtualElement(e) {
718
+ return e !== null && typeof e === "object" && "getBoundingClientRect" in e && ("contextElement" in e ? e instanceof Element : true);
719
+ }
720
+ class SlPopup extends FlowRdfElement {
707
721
  constructor() {
708
722
  super(...arguments);
709
723
  this.active = false;
@@ -721,6 +735,71 @@ let FlowPopup = class extends FlowRdfElement {
721
735
  this.shift = false;
722
736
  this.shiftPadding = 0;
723
737
  this.autoSizePadding = 0;
738
+ this.hoverBridge = false;
739
+ this.updateHoverBridge = () => {
740
+ if (this.hoverBridge && this.anchorEl) {
741
+ const anchorRect = this.anchorEl.getBoundingClientRect();
742
+ const popupRect = this.popup.getBoundingClientRect();
743
+ const isVertical = this.placement.includes("top") || this.placement.includes("bottom");
744
+ let topLeftX = 0;
745
+ let topLeftY = 0;
746
+ let topRightX = 0;
747
+ let topRightY = 0;
748
+ let bottomLeftX = 0;
749
+ let bottomLeftY = 0;
750
+ let bottomRightX = 0;
751
+ let bottomRightY = 0;
752
+ if (isVertical) {
753
+ if (anchorRect.top < popupRect.top) {
754
+ topLeftX = anchorRect.left;
755
+ topLeftY = anchorRect.bottom;
756
+ topRightX = anchorRect.right;
757
+ topRightY = anchorRect.bottom;
758
+ bottomLeftX = popupRect.left;
759
+ bottomLeftY = popupRect.top;
760
+ bottomRightX = popupRect.right;
761
+ bottomRightY = popupRect.top;
762
+ } else {
763
+ topLeftX = popupRect.left;
764
+ topLeftY = popupRect.bottom;
765
+ topRightX = popupRect.right;
766
+ topRightY = popupRect.bottom;
767
+ bottomLeftX = anchorRect.left;
768
+ bottomLeftY = anchorRect.top;
769
+ bottomRightX = anchorRect.right;
770
+ bottomRightY = anchorRect.top;
771
+ }
772
+ } else {
773
+ if (anchorRect.left < popupRect.left) {
774
+ topLeftX = anchorRect.right;
775
+ topLeftY = anchorRect.top;
776
+ topRightX = popupRect.left;
777
+ topRightY = popupRect.top;
778
+ bottomLeftX = anchorRect.right;
779
+ bottomLeftY = anchorRect.bottom;
780
+ bottomRightX = popupRect.left;
781
+ bottomRightY = popupRect.bottom;
782
+ } else {
783
+ topLeftX = popupRect.right;
784
+ topLeftY = popupRect.top;
785
+ topRightX = anchorRect.left;
786
+ topRightY = anchorRect.top;
787
+ bottomLeftX = popupRect.right;
788
+ bottomLeftY = popupRect.bottom;
789
+ bottomRightX = anchorRect.left;
790
+ bottomRightY = anchorRect.bottom;
791
+ }
792
+ }
793
+ this.style.setProperty("--hover-bridge-top-left-x", `${topLeftX}px`);
794
+ this.style.setProperty("--hover-bridge-top-left-y", `${topLeftY}px`);
795
+ this.style.setProperty("--hover-bridge-top-right-x", `${topRightX}px`);
796
+ this.style.setProperty("--hover-bridge-top-right-y", `${topRightY}px`);
797
+ this.style.setProperty("--hover-bridge-bottom-left-x", `${bottomLeftX}px`);
798
+ this.style.setProperty("--hover-bridge-bottom-left-y", `${bottomLeftY}px`);
799
+ this.style.setProperty("--hover-bridge-bottom-right-x", `${bottomRightX}px`);
800
+ this.style.setProperty("--hover-bridge-bottom-right-y", `${bottomRightY}px`);
801
+ }
802
+ };
724
803
  }
725
804
  async connectedCallback() {
726
805
  super.connectedCallback();
@@ -728,6 +807,7 @@ let FlowPopup = class extends FlowRdfElement {
728
807
  this.start();
729
808
  }
730
809
  disconnectedCallback() {
810
+ super.disconnectedCallback();
731
811
  this.stop();
732
812
  }
733
813
  async updated(changedProps) {
@@ -752,7 +832,7 @@ let FlowPopup = class extends FlowRdfElement {
752
832
  if (this.anchor && typeof this.anchor === "string") {
753
833
  const root = this.getRootNode();
754
834
  this.anchorEl = root.getElementById(this.anchor);
755
- } else if (this.anchor instanceof Element) {
835
+ } else if (this.anchor instanceof Element || isVirtualElement(this.anchor)) {
756
836
  this.anchorEl = this.anchor;
757
837
  } else {
758
838
  this.anchorEl = this.querySelector('[slot="anchor"]');
@@ -760,12 +840,9 @@ let FlowPopup = class extends FlowRdfElement {
760
840
  if (this.anchorEl instanceof HTMLSlotElement) {
761
841
  this.anchorEl = this.anchorEl.assignedElements({ flatten: true })[0];
762
842
  }
763
- if (!this.anchorEl) {
764
- throw new Error(
765
- "Invalid anchor element: no anchor could be found using the anchor slot or the anchor attribute."
766
- );
843
+ if (this.anchorEl) {
844
+ this.start();
767
845
  }
768
- this.start();
769
846
  }
770
847
  start() {
771
848
  if (!this.anchorEl) {
@@ -873,7 +950,7 @@ let FlowPopup = class extends FlowRdfElement {
873
950
  getOffsetParent
874
951
  }
875
952
  }).then(({ x, y, middlewareData, placement }) => {
876
- const isRtl = getComputedStyle(this).direction === "rtl";
953
+ const isRtl = this.matches(":dir(rtl)");
877
954
  const staticSide = { top: "bottom", right: "left", bottom: "top", left: "right" }[placement.split("-")[0]];
878
955
  this.setAttribute("data-current-placement", placement);
879
956
  Object.assign(this.popup.style, {
@@ -913,12 +990,21 @@ let FlowPopup = class extends FlowRdfElement {
913
990
  });
914
991
  }
915
992
  });
993
+ requestAnimationFrame(() => this.updateHoverBridge());
916
994
  this.emit("flow-ui-reposition");
917
995
  }
918
996
  render() {
919
997
  return html`
920
998
  <slot name="anchor" @slotchange=${this.handleAnchorChange}></slot>
921
999
 
1000
+ <span
1001
+ part="hover-bridge"
1002
+ class=${classMap({
1003
+ "popup-hover-bridge": true,
1004
+ "popup-hover-bridge--visible": this.hoverBridge && this.active
1005
+ })}
1006
+ ></span>
1007
+
922
1008
  <div
923
1009
  part="popup"
924
1010
  class=${classMap({
@@ -929,48 +1015,50 @@ let FlowPopup = class extends FlowRdfElement {
929
1015
  })}
930
1016
  >
931
1017
  <slot></slot>
932
- ${this.arrow ? html`<div part="arrow" class="popup__arrow" role="presentation"></div>` : ""}
1018
+ ${this.arrow ? html`
1019
+ <div part="arrow" class="popup__arrow" role="presentation"></div>
1020
+ ` : ""}
933
1021
  </div>
934
1022
  `;
935
1023
  }
936
- };
937
- FlowPopup.styles = styles$Z;
1024
+ }
1025
+ SlPopup.styles = [componentStyles, styles$Z];
938
1026
  __decorateClass$_([
939
1027
  query(".popup")
940
- ], FlowPopup.prototype, "popup", 2);
1028
+ ], SlPopup.prototype, "popup", 2);
941
1029
  __decorateClass$_([
942
1030
  query(".popup__arrow")
943
- ], FlowPopup.prototype, "arrowEl", 2);
1031
+ ], SlPopup.prototype, "arrowEl", 2);
944
1032
  __decorateClass$_([
945
1033
  property()
946
- ], FlowPopup.prototype, "anchor", 2);
1034
+ ], SlPopup.prototype, "anchor", 2);
947
1035
  __decorateClass$_([
948
1036
  property({ type: Boolean, reflect: true })
949
- ], FlowPopup.prototype, "active", 2);
1037
+ ], SlPopup.prototype, "active", 2);
950
1038
  __decorateClass$_([
951
1039
  property({ reflect: true })
952
- ], FlowPopup.prototype, "placement", 2);
1040
+ ], SlPopup.prototype, "placement", 2);
953
1041
  __decorateClass$_([
954
1042
  property({ reflect: true })
955
- ], FlowPopup.prototype, "strategy", 2);
1043
+ ], SlPopup.prototype, "strategy", 2);
956
1044
  __decorateClass$_([
957
1045
  property({ type: Number })
958
- ], FlowPopup.prototype, "distance", 2);
1046
+ ], SlPopup.prototype, "distance", 2);
959
1047
  __decorateClass$_([
960
1048
  property({ type: Number })
961
- ], FlowPopup.prototype, "skidding", 2);
1049
+ ], SlPopup.prototype, "skidding", 2);
962
1050
  __decorateClass$_([
963
1051
  property({ type: Boolean })
964
- ], FlowPopup.prototype, "arrow", 2);
1052
+ ], SlPopup.prototype, "arrow", 2);
965
1053
  __decorateClass$_([
966
1054
  property({ attribute: "arrow-placement" })
967
- ], FlowPopup.prototype, "arrowPlacement", 2);
1055
+ ], SlPopup.prototype, "arrowPlacement", 2);
968
1056
  __decorateClass$_([
969
1057
  property({ attribute: "arrow-padding", type: Number })
970
- ], FlowPopup.prototype, "arrowPadding", 2);
1058
+ ], SlPopup.prototype, "arrowPadding", 2);
971
1059
  __decorateClass$_([
972
1060
  property({ type: Boolean })
973
- ], FlowPopup.prototype, "flip", 2);
1061
+ ], SlPopup.prototype, "flip", 2);
974
1062
  __decorateClass$_([
975
1063
  property({
976
1064
  attribute: "flip-fallback-placements",
@@ -983,40 +1071,42 @@ __decorateClass$_([
983
1071
  }
984
1072
  }
985
1073
  })
986
- ], FlowPopup.prototype, "flipFallbackPlacements", 2);
1074
+ ], SlPopup.prototype, "flipFallbackPlacements", 2);
987
1075
  __decorateClass$_([
988
1076
  property({ attribute: "flip-fallback-strategy" })
989
- ], FlowPopup.prototype, "flipFallbackStrategy", 2);
1077
+ ], SlPopup.prototype, "flipFallbackStrategy", 2);
990
1078
  __decorateClass$_([
991
1079
  property({ type: Object })
992
- ], FlowPopup.prototype, "flipBoundary", 2);
1080
+ ], SlPopup.prototype, "flipBoundary", 2);
993
1081
  __decorateClass$_([
994
1082
  property({ attribute: "flip-padding", type: Number })
995
- ], FlowPopup.prototype, "flipPadding", 2);
1083
+ ], SlPopup.prototype, "flipPadding", 2);
996
1084
  __decorateClass$_([
997
1085
  property({ type: Boolean })
998
- ], FlowPopup.prototype, "shift", 2);
1086
+ ], SlPopup.prototype, "shift", 2);
999
1087
  __decorateClass$_([
1000
1088
  property({ type: Object })
1001
- ], FlowPopup.prototype, "shiftBoundary", 2);
1089
+ ], SlPopup.prototype, "shiftBoundary", 2);
1002
1090
  __decorateClass$_([
1003
1091
  property({ attribute: "shift-padding", type: Number })
1004
- ], FlowPopup.prototype, "shiftPadding", 2);
1092
+ ], SlPopup.prototype, "shiftPadding", 2);
1005
1093
  __decorateClass$_([
1006
1094
  property({ attribute: "auto-size" })
1007
- ], FlowPopup.prototype, "autoSize", 2);
1095
+ ], SlPopup.prototype, "autoSize", 2);
1008
1096
  __decorateClass$_([
1009
1097
  property()
1010
- ], FlowPopup.prototype, "sync", 2);
1098
+ ], SlPopup.prototype, "sync", 2);
1011
1099
  __decorateClass$_([
1012
1100
  property({ type: Object })
1013
- ], FlowPopup.prototype, "autoSizeBoundary", 2);
1101
+ ], SlPopup.prototype, "autoSizeBoundary", 2);
1014
1102
  __decorateClass$_([
1015
1103
  property({ attribute: "auto-size-padding", type: Number })
1016
- ], FlowPopup.prototype, "autoSizePadding", 2);
1017
- FlowPopup = __decorateClass$_([
1018
- customElement("flow-ui-popup")
1019
- ], FlowPopup);
1104
+ ], SlPopup.prototype, "autoSizePadding", 2);
1105
+ __decorateClass$_([
1106
+ property({ attribute: "hover-bridge", type: Boolean })
1107
+ ], SlPopup.prototype, "hoverBridge", 2);
1108
+
1109
+ SlPopup.define("flow-ui-popup");
1020
1110
 
1021
1111
  const styles$Y = css`
1022
1112
  ${componentStyles}
@@ -4047,15 +4137,6 @@ FlowButton = __decorateClass$P([
4047
4137
  customElement("flow-ui-button")
4048
4138
  ], FlowButton);
4049
4139
 
4050
- dayjs.extend(utc);
4051
- dayjs.extend(timezone);
4052
- dayjs.extend(localeData);
4053
- dayjs.extend(AdvancedFormat);
4054
- dayjs.extend(QuarterOfYear);
4055
- dayjs.extend(LocalizedFormat);
4056
- dayjs.extend(CustomParseFormat);
4057
- dayjs.extend(isoWeek);
4058
-
4059
4140
  const isUndefined = (val) => typeof val === "undefined";
4060
4141
  const isNull = (val) => val === null;
4061
4142
  const isNil = (val) => isUndefined(val) || isNull(val);
@@ -4215,12 +4296,10 @@ var __decorateClass$O = (decorators, target, key, kind) => {
4215
4296
  __defProp$O(target, key, result);
4216
4297
  return result;
4217
4298
  };
4218
- dayjs.locale("en");
4219
4299
  class FlowCalendar extends FlowRdfElement {
4220
4300
  constructor() {
4221
4301
  super(...arguments);
4222
4302
  this.displayMode = "date";
4223
- this.timezone = "";
4224
4303
  this.size = "medium";
4225
4304
  }
4226
4305
  connectedCallback() {
@@ -4231,7 +4310,7 @@ class FlowCalendar extends FlowRdfElement {
4231
4310
  super.disconnectedCallback();
4232
4311
  }
4233
4312
  handleValueChange() {
4234
- this._selectedDate = this.makeDate(this.value)?.millisecond(0);
4313
+ this._selectedDate = this.makeDate(this.value)?.set({ millisecond: 0 });
4235
4314
  if (this._selectedDate) {
4236
4315
  if (this.displayMode === "date") {
4237
4316
  this._selectedDate = this._selectedDate.startOf("day");
@@ -4241,44 +4320,65 @@ class FlowCalendar extends FlowRdfElement {
4241
4320
  this._displayDate = this.makeDate().startOf("month");
4242
4321
  }
4243
4322
  }
4323
+ handleTimezoneChange() {
4324
+ this.handleValueChange();
4325
+ this.updateValue();
4326
+ }
4244
4327
  dateClicked(val) {
4245
4328
  const date = this.makeDate(val);
4246
- if (date) {
4247
- if (this._selectedDate) {
4248
- this._selectedDate = this._selectedDate.year(date.year()).month(date.month()).date(date.date());
4249
- } else {
4250
- this._selectedDate = date;
4251
- }
4252
- this.updateValue();
4329
+ if (this._selectedDate) {
4330
+ this._selectedDate = date.set({
4331
+ hour: this._selectedDate.hour,
4332
+ minute: this._selectedDate.minute,
4333
+ second: this._selectedDate.second
4334
+ });
4335
+ } else {
4336
+ this._selectedDate = date;
4253
4337
  }
4338
+ this.updateValue();
4254
4339
  }
4255
- stepDisplayDate(value, unit) {
4256
- this._displayDate = this._displayDate.add(value, unit);
4340
+ stepDisplayDate(duration) {
4341
+ this._displayDate = this._displayDate.plus(duration);
4257
4342
  }
4343
+ /**
4344
+ * Generate a list of years for the year select dropdown
4345
+ */
4258
4346
  yearOptionsForDate(date) {
4259
4347
  const years = [];
4260
- for (let y = date.year() + 1; y >= date.year() - 6; y--) {
4348
+ for (let y = date.year + 1; y >= date.year - 6; y--) {
4261
4349
  years.push(y);
4262
4350
  }
4263
4351
  return years;
4264
4352
  }
4265
4353
  makeDate(d) {
4266
4354
  try {
4267
- const date = dayjs(d).tz(isStringFull(this.timezone) ? this.timezone : void 0);
4268
- return date.isValid() ? date : void 0;
4355
+ let date;
4356
+ const zone = isStringFull(this.timezone) ? this.timezone : void 0;
4357
+ const locale = isStringFull(this.locale) ? this.locale : void 0;
4358
+ if (isStringFull(d)) {
4359
+ date = DateTime.fromISO(d, { zone, locale });
4360
+ } else {
4361
+ date = DateTime.local({ zone, locale });
4362
+ }
4363
+ return date.isValid ? date : void 0;
4269
4364
  } catch (e) {
4365
+ console.error(`Invalid date in makeDate: ${d} (${this.timezone})`);
4270
4366
  return void 0;
4271
4367
  }
4272
4368
  }
4273
4369
  updateValue(emitEvents = true) {
4274
- this.value = this._selectedDate ? this._selectedDate.toISOString() : "";
4370
+ const iso = this._selectedDate?.toISO();
4371
+ this.value = isDefined(iso) ? iso : "";
4275
4372
  if (emitEvents) {
4276
4373
  this.emit("flow-ui-change");
4277
4374
  }
4278
4375
  }
4279
4376
  handleHeaderSelectChange(ev) {
4280
4377
  ev.stopPropagation();
4281
- this._displayDate = this.makeDate().year(+this._yearSelect.value).month(+this._monthSelect.value).startOf("month");
4378
+ this._displayDate = this.makeDate().set({
4379
+ year: +this._yearSelect.value,
4380
+ month: +this._monthSelect.value
4381
+ }).startOf("month");
4282
4382
  }
4283
4383
  handleTimeChange(ev) {
4284
4384
  ev.stopPropagation();
@@ -4287,34 +4387,36 @@ class FlowCalendar extends FlowRdfElement {
4287
4387
  }
4288
4388
  const target = ev.target;
4289
4389
  const unit = target.getAttribute("name");
4290
- this._selectedDate = this._selectedDate.set(unit, +target.value);
4390
+ this._selectedDate = this._selectedDate.set({ [unit]: +target.value });
4291
4391
  this.updateValue();
4292
4392
  }
4293
4393
  calendarHeaderTemplate() {
4394
+ const locale = isStringFull(this.locale) ? this.locale : void 0;
4395
+ const monthsShort = Info.months("short", { locale });
4294
4396
  return html`
4295
4397
  <div class="calendar__header">
4296
4398
  <flow-ui-icon-button
4297
4399
  name="chevron-left"
4298
4400
  library="system"
4299
- @click=${() => this.stepDisplayDate(-1, "month")}
4401
+ @click=${() => this.stepDisplayDate({ month: -1 })}
4300
4402
  ></flow-ui-icon-button>
4301
4403
  <flow-ui-select
4302
4404
  class="calendar__month-select calendar__header-select"
4303
- value=${this._displayDate.month()}
4405
+ value=${this._displayDate.month}
4304
4406
  @flow-ui-change=${this.handleHeaderSelectChange}
4305
4407
  >
4306
- ${dayjs.monthsShort().map(
4408
+ ${monthsShort.map(
4307
4409
  (month, index) => html`
4308
- <flow-ui-option value=${index}>${month}</flow-ui-option>
4410
+ <flow-ui-option value=${index + 1}>${month}</flow-ui-option>
4309
4411
  `
4310
4412
  )}
4311
4413
  </flow-ui-select>
4312
4414
  <flow-ui-select
4313
4415
  class="calendar__year-select calendar__header-select"
4314
- value=${this._displayDate.year()}
4416
+ value=${this._displayDate.year}
4315
4417
  @flow-ui-change=${this.handleHeaderSelectChange}
4316
4418
  >
4317
- ${this.yearOptionsForDate(dayjs()).map(
4419
+ ${this.yearOptionsForDate(DateTime.now()).map(
4318
4420
  (year) => html`
4319
4421
  <flow-ui-option value=${year}>${year}</flow-ui-option>
4320
4422
  `
@@ -4323,13 +4425,14 @@ class FlowCalendar extends FlowRdfElement {
4323
4425
  <flow-ui-icon-button
4324
4426
  name="chevron-right"
4325
4427
  library="system"
4326
- @click=${() => this.stepDisplayDate(1, "month")}
4428
+ @click=${() => this.stepDisplayDate({ month: 1 })}
4327
4429
  ></flow-ui-icon-button>
4328
4430
  </div>
4329
4431
  `;
4330
4432
  }
4331
4433
  dayOfWeekGridTemplate() {
4332
- const days = dayjs.weekdaysMin(true);
4434
+ const locale = isStringFull(this.locale) ? this.locale : void 0;
4435
+ const days = Info.weekdays("narrow", { locale });
4333
4436
  return html`
4334
4437
  ${days.map(
4335
4438
  (day) => html`
@@ -4344,34 +4447,34 @@ class FlowCalendar extends FlowRdfElement {
4344
4447
  const endOfMonth = this._displayDate.endOf("month");
4345
4448
  const calendarStart = startOfMonth.startOf("week");
4346
4449
  const calendarEnd = endOfMonth.endOf("week");
4347
- const daysInMonth = this._displayDate.daysInMonth();
4450
+ const daysInMonth = this._displayDate.daysInMonth;
4348
4451
  const days = [];
4349
- for (let date = calendarStart; date.isBefore(startOfMonth); date = date.add(1, "day")) {
4452
+ for (let date = calendarStart; date < startOfMonth; date = date.plus({ day: 1 })) {
4350
4453
  days.push({
4351
- day: date.date(),
4352
- date: date.toISOString(),
4454
+ day: date.toFormat("d"),
4455
+ date: date.toISO(),
4353
4456
  isFiller: true,
4354
- today: date.isSame(today, "day"),
4355
- selected: !!this._selectedDate && date.isSame(this._selectedDate, "day")
4457
+ today: date === today,
4458
+ selected: !!this._selectedDate && date.startOf("day").equals(this._selectedDate.startOf("day"))
4356
4459
  });
4357
4460
  }
4358
4461
  for (let day = 1; day <= daysInMonth; day++) {
4359
- const date = startOfMonth.add(day - 1, "day");
4462
+ const date = startOfMonth.plus({ days: day - 1 }).startOf("day");
4360
4463
  days.push({
4361
- day,
4362
- date: date.toISOString(),
4464
+ day: date.toFormat("d"),
4465
+ date: date.toISO(),
4363
4466
  isFiller: false,
4364
- today: date.isSame(today, "day"),
4365
- selected: !!this._selectedDate && date.isSame(this._selectedDate, "day")
4467
+ today: date.startOf("day").equals(today.startOf("day")),
4468
+ selected: !!this._selectedDate && date.startOf("day").equals(this._selectedDate.startOf("day"))
4366
4469
  });
4367
4470
  }
4368
- for (let date = endOfMonth.add(1, "day"); !date.isAfter(calendarEnd); date = date.add(1, "day")) {
4471
+ for (let date = endOfMonth.plus({ day: 1 }).startOf("day"); date < calendarEnd; date = date.plus({ day: 1 })) {
4369
4472
  days.push({
4370
- day: date.date(),
4371
- date: date.toISOString(),
4473
+ day: date.toFormat("d"),
4474
+ date: date.toISO(),
4372
4475
  isFiller: true,
4373
- today: date.isSame(today, "day"),
4374
- selected: !!this._selectedDate && date.isSame(this._selectedDate, "day")
4476
+ today: date.startOf("day").equals(today.startOf("day")),
4477
+ selected: !!this._selectedDate && date.startOf("day").equals(this._selectedDate.startOf("day"))
4375
4478
  });
4376
4479
  }
4377
4480
  return html`
@@ -4403,7 +4506,7 @@ class FlowCalendar extends FlowRdfElement {
4403
4506
  max="23"
4404
4507
  format="02"
4405
4508
  class="calendar__time-input"
4406
- value=${this._selectedDate ? this._selectedDate.hour() : 0}
4509
+ value=${this._selectedDate ? this._selectedDate.hour : 0}
4407
4510
  @flow-ui-change=${this.handleTimeChange}
4408
4511
  ></flow-ui-number-stepper>
4409
4512
  <span class="calendar__time-separator">:</span>
@@ -4414,7 +4517,7 @@ class FlowCalendar extends FlowRdfElement {
4414
4517
  max="59"
4415
4518
  format="02"
4416
4519
  class="calendar__time-input"
4417
- value=${this._selectedDate ? this._selectedDate.minute() : 0}
4520
+ value=${this._selectedDate ? this._selectedDate.minute : 0}
4418
4521
  @flow-ui-change=${this.handleTimeChange}
4419
4522
  ></flow-ui-number-stepper>
4420
4523
  <span class="calendar__time-separator">:</span>
@@ -4425,7 +4528,7 @@ class FlowCalendar extends FlowRdfElement {
4425
4528
  max="59"
4426
4529
  format="02"
4427
4530
  class="calendar__time-input"
4428
- value=${this._selectedDate ? this._selectedDate.second() : 0}
4531
+ value=${this._selectedDate ? this._selectedDate.second : 0}
4429
4532
  @flow-ui-change=${this.handleTimeChange}
4430
4533
  ></flow-ui-number-stepper>
4431
4534
  </div>
@@ -4467,7 +4570,7 @@ __decorateClass$O([
4467
4570
  state()
4468
4571
  ], FlowCalendar.prototype, "_selectedDate", 2);
4469
4572
  __decorateClass$O([
4470
- property()
4573
+ property({ reflect: true })
4471
4574
  ], FlowCalendar.prototype, "value", 2);
4472
4575
  __decorateClass$O([
4473
4576
  property({ attribute: "display-mode" })
@@ -4475,12 +4578,18 @@ __decorateClass$O([
4475
4578
  __decorateClass$O([
4476
4579
  property()
4477
4580
  ], FlowCalendar.prototype, "timezone", 2);
4581
+ __decorateClass$O([
4582
+ property()
4583
+ ], FlowCalendar.prototype, "locale", 2);
4478
4584
  __decorateClass$O([
4479
4585
  property()
4480
4586
  ], FlowCalendar.prototype, "size", 2);
4481
4587
  __decorateClass$O([
4482
- watch(["value", "timezone"])
4588
+ watch("value")
4483
4589
  ], FlowCalendar.prototype, "handleValueChange", 1);
4590
+ __decorateClass$O([
4591
+ watch(["timezone"])
4592
+ ], FlowCalendar.prototype, "handleTimezoneChange", 1);
4484
4593
 
4485
4594
  FlowCalendar.define("flow-ui-calendar");
4486
4595
 
@@ -5489,62 +5598,73 @@ const styles$K = css`
5489
5598
  `;
5490
5599
 
5491
5600
  const FORMATS = {
5492
- datetime: "MMM D, YYYY, HH:mm:ss",
5493
- millisecond: "HH:mm:ss.SSS",
5494
- second: "HH:mm:ss",
5495
- minute: "HH:mm",
5496
- hour: "HH",
5497
- day: "MMM D",
5498
- week: "ll",
5499
- month: "MMM YYYY",
5500
- quarter: "[Q]Q - YYYY",
5501
- year: "YYYY"
5601
+ datetime: DateTime.DATETIME_MED_WITH_SECONDS,
5602
+ millisecond: "h:mm:ss.SSS a",
5603
+ second: DateTime.TIME_WITH_SECONDS,
5604
+ minute: DateTime.TIME_SIMPLE,
5605
+ hour: { hour: "numeric" },
5606
+ day: { day: "numeric", month: "short" },
5607
+ week: "DD",
5608
+ month: { month: "short", year: "numeric" },
5609
+ quarter: "'Q'q - yyyy",
5610
+ year: { year: "numeric" }
5502
5611
  };
5503
- function createDate(value, format, options) {
5504
- if (isUndefined(options)) {
5505
- options = format;
5506
- format = void 0;
5507
- }
5508
- if (options.utc) {
5509
- return dayjs.utc(value, format);
5510
- }
5511
- return dayjs(value, format);
5612
+ function create(time, options) {
5613
+ return DateTime.fromMillis(time, options);
5512
5614
  }
5513
5615
  _adapters._date.override({
5514
- // _id: 'dayjs', // DEBUG
5616
+ // _id: 'luxon', // DEBUG
5617
+ init(chartOptions) {
5618
+ if (!this.options.locale) {
5619
+ this.options.locale = chartOptions.locale;
5620
+ }
5621
+ },
5515
5622
  formats: function() {
5516
5623
  return FORMATS;
5517
5624
  },
5518
5625
  parse: function(value, format) {
5519
- const valueType = typeof value;
5520
- if (value === null || valueType === "undefined") {
5626
+ const options = this.options;
5627
+ const type = typeof value;
5628
+ if (value === null || type === "undefined") {
5521
5629
  return null;
5522
5630
  }
5523
- if (valueType === "string" && typeof format === "string") {
5524
- return createDate(value, format, this.options).isValid() ? createDate(value, format, this.options).valueOf() : null;
5525
- } else if (!(value instanceof dayjs)) {
5526
- return createDate(value, this.options).isValid() ? createDate(value, this.options).valueOf() : null;
5631
+ if (typeof value === "number") {
5632
+ value = create(value);
5633
+ } else if (typeof value === "string") {
5634
+ if (typeof format === "string") {
5635
+ value = DateTime.fromFormat(value, format, options);
5636
+ } else {
5637
+ value = DateTime.fromISO(value, options);
5638
+ }
5639
+ } else if (value instanceof Date) {
5640
+ value = DateTime.fromJSDate(value, options);
5641
+ } else if (typeof value === "object" && !(value instanceof DateTime)) {
5642
+ value = DateTime.fromObject(value, options);
5527
5643
  }
5528
- return null;
5644
+ return value instanceof DateTime && value.isValid ? value.valueOf() : null;
5529
5645
  },
5530
5646
  format: function(time, format) {
5531
- return createDate(time, this.options).format(format);
5647
+ const datetime = create(time, this.options);
5648
+ return typeof format === "string" ? datetime.toFormat(format) : datetime.toLocaleString(format);
5532
5649
  },
5533
5650
  add: function(time, amount, unit) {
5534
- return createDate(time, this.options).add(amount, unit).valueOf();
5651
+ const args = {};
5652
+ args[unit] = amount;
5653
+ return create(time).plus(args).valueOf();
5535
5654
  },
5536
5655
  diff: function(max, min, unit) {
5537
- return createDate(max, this.options).diff(createDate(min, this.options), unit);
5656
+ return create(max).diff(create(min)).as(unit).valueOf();
5538
5657
  },
5539
5658
  startOf: function(time, unit, weekday) {
5540
- if (unit === "isoWeek") {
5541
- const validatedWeekday = typeof weekday === "number" && weekday > 0 && weekday < 7 ? weekday : 1;
5542
- return createDate(time, this.options).isoWeekday(validatedWeekday).startOf("day").valueOf();
5659
+ if (unit === "isoWeek" && isNumber$1(weekday)) {
5660
+ weekday = Math.trunc(Math.min(Math.max(0, weekday), 6));
5661
+ const dateTime = create(time);
5662
+ return dateTime.minus({ days: (dateTime.weekday - weekday + 7) % 7 }).startOf("day").valueOf();
5543
5663
  }
5544
- return createDate(time, this.options).startOf(unit).valueOf();
5664
+ return unit ? create(time).startOf(unit).valueOf() : time;
5545
5665
  },
5546
5666
  endOf: function(time, unit) {
5547
- return createDate(time, this.options).endOf(unit).valueOf();
5667
+ return create(time).endOf(unit).valueOf();
5548
5668
  }
5549
5669
  });
5550
5670
 
@@ -8943,7 +9063,7 @@ var __decorateClass$D = (decorators, target, key, kind) => {
8943
9063
  __defProp$D(target, key, result);
8944
9064
  return result;
8945
9065
  };
8946
- let FlowTag = class extends FlowRdfElement {
9066
+ class FlowTag extends FlowRdfElement {
8947
9067
  constructor() {
8948
9068
  super(...arguments);
8949
9069
  this.localize = new LocalizeController(this);
@@ -8994,8 +9114,9 @@ let FlowTag = class extends FlowRdfElement {
8994
9114
  </span>
8995
9115
  `;
8996
9116
  }
8997
- };
9117
+ }
8998
9118
  FlowTag.styles = styles$E;
9119
+ FlowTag.dependencies = { "flow-icon-button": FlowIconButton };
8999
9120
  __decorateClass$D([
9000
9121
  property({ reflect: true })
9001
9122
  ], FlowTag.prototype, "variant", 2);
@@ -9008,9 +9129,8 @@ __decorateClass$D([
9008
9129
  __decorateClass$D([
9009
9130
  property({ type: Boolean })
9010
9131
  ], FlowTag.prototype, "removable", 2);
9011
- FlowTag = __decorateClass$D([
9012
- customElement("flow-ui-tag")
9013
- ], FlowTag);
9132
+
9133
+ FlowTag.define("flow-ui-tag");
9014
9134
 
9015
9135
  const styles$D = css`
9016
9136
  ${componentStyles}
@@ -9296,8 +9416,7 @@ class FlowDatetimePicker extends FlowRdfElement {
9296
9416
  this.name = "";
9297
9417
  this.value = "";
9298
9418
  this.displayMode = "datetime";
9299
- this.format = "LLL";
9300
- this.timezone = "";
9419
+ this.format = "FFF";
9301
9420
  this.defaultValue = "";
9302
9421
  this.size = "medium";
9303
9422
  this.placeholder = "";
@@ -9341,7 +9460,9 @@ class FlowDatetimePicker extends FlowRdfElement {
9341
9460
  updateDisplayLabel() {
9342
9461
  try {
9343
9462
  if (isStringFull(this.value)) {
9344
- this.displayLabel = dayjs(this.value).tz(isStringFull(this.timezone) ? this.timezone : void 0).format(this.format);
9463
+ const zone = isStringFull(this.timezone) ? this.timezone : void 0;
9464
+ const locale = isStringFull(this.locale) ? this.locale : void 0;
9465
+ this.displayLabel = DateTime.fromISO(this.value, { zone, locale }).toFormat(this.format);
9345
9466
  } else {
9346
9467
  this.displayLabel = "";
9347
9468
  }
@@ -9645,7 +9766,8 @@ class FlowDatetimePicker extends FlowRdfElement {
9645
9766
  value=${this.value}
9646
9767
  display-mode=${this.displayMode}
9647
9768
  size=${this.size}
9648
- timezone=${this.timezone}
9769
+ timezone=${ifDefined(this.timezone)}
9770
+ locale=${ifDefined(this.locale)}
9649
9771
  @flow-ui-change=${this.handleCalendarChange}
9650
9772
  ></flow-ui-calendar>
9651
9773
  ` : nothing}
@@ -9692,7 +9814,7 @@ __decorateClass$C([
9692
9814
  property()
9693
9815
  ], FlowDatetimePicker.prototype, "name", 2);
9694
9816
  __decorateClass$C([
9695
- property()
9817
+ property({ reflect: true })
9696
9818
  ], FlowDatetimePicker.prototype, "value", 2);
9697
9819
  __decorateClass$C([
9698
9820
  property({ attribute: "display-mode" })
@@ -9703,6 +9825,9 @@ __decorateClass$C([
9703
9825
  __decorateClass$C([
9704
9826
  property()
9705
9827
  ], FlowDatetimePicker.prototype, "timezone", 2);
9828
+ __decorateClass$C([
9829
+ property()
9830
+ ], FlowDatetimePicker.prototype, "locale", 2);
9706
9831
  __decorateClass$C([
9707
9832
  defaultValue()
9708
9833
  ], FlowDatetimePicker.prototype, "defaultValue", 2);
@@ -9746,7 +9871,7 @@ __decorateClass$C([
9746
9871
  property({ type: Boolean, reflect: true })
9747
9872
  ], FlowDatetimePicker.prototype, "required", 2);
9748
9873
  __decorateClass$C([
9749
- watch(["value", "format", "timezone"])
9874
+ watch(["value", "format", "timezone", "locale"])
9750
9875
  ], FlowDatetimePicker.prototype, "updateDisplayLabel", 1);
9751
9876
  __decorateClass$C([
9752
9877
  watch("disabled", { waitUntilFirstUpdate: true })
@@ -12148,7 +12273,7 @@ var __decorateClass$r = (decorators, target, key, kind) => {
12148
12273
  __defProp$r(target, key, result);
12149
12274
  return result;
12150
12275
  };
12151
- let FlowOption = class extends FlowRdfElement {
12276
+ class FlowOption extends FlowRdfElement {
12152
12277
  constructor() {
12153
12278
  super(...arguments);
12154
12279
  // @ts-expect-error - Controller is currently unused
@@ -12198,7 +12323,19 @@ let FlowOption = class extends FlowRdfElement {
12198
12323
  }
12199
12324
  /** Returns a plain text label based on the option's content. */
12200
12325
  getTextLabel() {
12201
- return (this.textContent ?? "").trim();
12326
+ const nodes = this.childNodes;
12327
+ let label = "";
12328
+ [...nodes].forEach((node) => {
12329
+ if (node.nodeType === Node.ELEMENT_NODE) {
12330
+ if (!node.hasAttribute("slot")) {
12331
+ label += node.textContent;
12332
+ }
12333
+ }
12334
+ if (node.nodeType === Node.TEXT_NODE) {
12335
+ label += node.textContent;
12336
+ }
12337
+ });
12338
+ return label.trim();
12202
12339
  }
12203
12340
  render() {
12204
12341
  return html`
@@ -12227,8 +12364,9 @@ let FlowOption = class extends FlowRdfElement {
12227
12364
  </div>
12228
12365
  `;
12229
12366
  }
12230
- };
12367
+ }
12231
12368
  FlowOption.styles = styles$s;
12369
+ FlowOption.dependencies = { "flow-ui-icon": FlowIcon };
12232
12370
  __decorateClass$r([
12233
12371
  query(".option__label")
12234
12372
  ], FlowOption.prototype, "defaultSlot", 2);
@@ -12256,9 +12394,8 @@ __decorateClass$r([
12256
12394
  __decorateClass$r([
12257
12395
  watch("value")
12258
12396
  ], FlowOption.prototype, "handleValueChange", 1);
12259
- FlowOption = __decorateClass$r([
12260
- customElement("flow-ui-option")
12261
- ], FlowOption);
12397
+
12398
+ FlowOption.define("flow-ui-option");
12262
12399
 
12263
12400
  const styles$r = css`
12264
12401
  ${componentStyles}
@@ -14878,9 +15015,6 @@ __decorateClass$i([
14878
15015
  FlowScrollView.define("flow-ui-scroll-view");
14879
15016
 
14880
15017
  const styles$i = css`
14881
- ${componentStyles}
14882
- ${formControlStyles}
14883
-
14884
15018
  :host {
14885
15019
  display: block;
14886
15020
  }
@@ -14921,8 +15055,11 @@ const styles$i = css`
14921
15055
  vertical-align: middle;
14922
15056
  overflow: hidden;
14923
15057
  cursor: pointer;
14924
- transition: var(--flow-ui-transition-fast) color, var(--flow-ui-transition-fast) border,
14925
- var(--flow-ui-transition-fast) box-shadow, var(--flow-ui-transition-fast) background-color;
15058
+ transition:
15059
+ var(--flow-ui-transition-fast) color,
15060
+ var(--flow-ui-transition-fast) border,
15061
+ var(--flow-ui-transition-fast) box-shadow,
15062
+ var(--flow-ui-transition-fast) background-color;
14926
15063
  }
14927
15064
 
14928
15065
  .select__display-input {
@@ -14939,6 +15076,10 @@ const styles$i = css`
14939
15076
  -webkit-appearance: none;
14940
15077
  }
14941
15078
 
15079
+ .select__display-input::placeholder {
15080
+ color: var(--flow-ui-input-placeholder-color);
15081
+ }
15082
+
14942
15083
  .select:not(.select--disabled):hover .select__display-input {
14943
15084
  color: var(--flow-ui-input-color-hover);
14944
15085
  }
@@ -15129,6 +15270,14 @@ const styles$i = css`
15129
15270
  color: var(--flow-ui-input-placeholder-color);
15130
15271
  }
15131
15272
 
15273
+ /* Suffix */
15274
+ .select__suffix {
15275
+ flex: 0;
15276
+ display: inline-flex;
15277
+ align-items: center;
15278
+ color: var(--flow-ui-input-placeholder-color);
15279
+ }
15280
+
15132
15281
  /* Clear button */
15133
15282
  .select__clear {
15134
15283
  display: inline-flex;
@@ -15191,10 +15340,11 @@ const styles$i = css`
15191
15340
  }
15192
15341
 
15193
15342
  .select__listbox ::slotted(small) {
15343
+ display: block;
15194
15344
  font-size: var(--flow-ui-font-size-small);
15195
15345
  font-weight: var(--flow-ui-font-weight-semibold);
15196
15346
  color: var(--flow-ui-color-neutral-500);
15197
- padding-block: var(--flow-ui-spacing-x-small);
15347
+ padding-block: var(--flow-ui-spacing-2x-small);
15198
15348
  padding-inline: var(--flow-ui-spacing-x-large);
15199
15349
  }
15200
15350
  `;
@@ -15210,7 +15360,7 @@ var __decorateClass$h = (decorators, target, key, kind) => {
15210
15360
  __defProp$h(target, key, result);
15211
15361
  return result;
15212
15362
  };
15213
- let FlowSelect = class extends FlowRdfElement {
15363
+ class FlowSelect extends FlowRdfElement {
15214
15364
  constructor() {
15215
15365
  super(...arguments);
15216
15366
  this.formControlController = new FormControlController(this, {
@@ -15219,7 +15369,6 @@ let FlowSelect = class extends FlowRdfElement {
15219
15369
  this.hasSlotController = new HasSlotController(this, "help-text", "label");
15220
15370
  this.localize = new LocalizeController(this);
15221
15371
  this.typeToSelectString = "";
15222
- this.pendingValue = null;
15223
15372
  this.hasFocus = false;
15224
15373
  this.displayLabel = "";
15225
15374
  this.selectedOptions = [];
@@ -15241,6 +15390,129 @@ let FlowSelect = class extends FlowRdfElement {
15241
15390
  this.helpText = "";
15242
15391
  this.form = "";
15243
15392
  this.required = false;
15393
+ this.getTag = (option) => {
15394
+ return html`
15395
+ <flow-ui-tag
15396
+ part="tag"
15397
+ exportparts="
15398
+ base:tag__base,
15399
+ content:tag__content,
15400
+ remove-button:tag__remove-button,
15401
+ remove-button__base:tag__remove-button__base
15402
+ "
15403
+ ?pill=${this.pill}
15404
+ size=${this.size}
15405
+ removable
15406
+ @flow-ui-remove=${(event) => this.handleTagRemove(event, option)}
15407
+ >
15408
+ ${option.getTextLabel()}
15409
+ </flow-ui-tag>
15410
+ `;
15411
+ };
15412
+ this.handleDocumentFocusIn = (event) => {
15413
+ const path = event.composedPath();
15414
+ if (this && !path.includes(this)) {
15415
+ this.hide();
15416
+ }
15417
+ };
15418
+ this.handleDocumentKeyDown = (event) => {
15419
+ const target = event.target;
15420
+ const isClearButton = target.closest(".select__clear") !== null;
15421
+ const isIconButton = target.closest("flow-ui-icon-button") !== null;
15422
+ if (isClearButton || isIconButton) {
15423
+ return;
15424
+ }
15425
+ if (event.key === "Escape" && this.open && !this.closeWatcher) {
15426
+ event.preventDefault();
15427
+ event.stopPropagation();
15428
+ this.hide();
15429
+ this.displayInput.focus({ preventScroll: true });
15430
+ }
15431
+ if (event.key === "Enter" || event.key === " " && this.typeToSelectString === "") {
15432
+ event.preventDefault();
15433
+ event.stopImmediatePropagation();
15434
+ if (!this.open) {
15435
+ this.show();
15436
+ return;
15437
+ }
15438
+ if (this.currentOption && !this.currentOption.disabled) {
15439
+ if (this.multiple) {
15440
+ this.toggleOptionSelection(this.currentOption);
15441
+ } else {
15442
+ this.setSelectedOptions(this.currentOption);
15443
+ }
15444
+ this.updateComplete.then(() => {
15445
+ this.emit("flow-ui-input");
15446
+ this.emit("flow-ui-change");
15447
+ });
15448
+ if (!this.multiple) {
15449
+ this.hide();
15450
+ this.displayInput.focus({ preventScroll: true });
15451
+ }
15452
+ }
15453
+ return;
15454
+ }
15455
+ if (["ArrowUp", "ArrowDown", "Home", "End"].includes(event.key)) {
15456
+ const allOptions = this.getAllOptions();
15457
+ const currentIndex = allOptions.indexOf(this.currentOption);
15458
+ let newIndex = Math.max(0, currentIndex);
15459
+ event.preventDefault();
15460
+ if (!this.open) {
15461
+ this.show();
15462
+ if (this.currentOption) {
15463
+ return;
15464
+ }
15465
+ }
15466
+ if (event.key === "ArrowDown") {
15467
+ newIndex = currentIndex + 1;
15468
+ if (newIndex > allOptions.length - 1)
15469
+ newIndex = 0;
15470
+ } else if (event.key === "ArrowUp") {
15471
+ newIndex = currentIndex - 1;
15472
+ if (newIndex < 0)
15473
+ newIndex = allOptions.length - 1;
15474
+ } else if (event.key === "Home") {
15475
+ newIndex = 0;
15476
+ } else if (event.key === "End") {
15477
+ newIndex = allOptions.length - 1;
15478
+ }
15479
+ this.setCurrentOption(allOptions[newIndex]);
15480
+ }
15481
+ if (event.key.length === 1 || event.key === "Backspace") {
15482
+ const allOptions = this.getAllOptions();
15483
+ if (event.metaKey || event.ctrlKey || event.altKey) {
15484
+ return;
15485
+ }
15486
+ if (!this.open) {
15487
+ if (event.key === "Backspace") {
15488
+ return;
15489
+ }
15490
+ this.show();
15491
+ }
15492
+ event.stopPropagation();
15493
+ event.preventDefault();
15494
+ clearTimeout(this.typeToSelectTimeout);
15495
+ this.typeToSelectTimeout = window.setTimeout(() => this.typeToSelectString = "", 1e3);
15496
+ if (event.key === "Backspace") {
15497
+ this.typeToSelectString = this.typeToSelectString.slice(0, -1);
15498
+ } else {
15499
+ this.typeToSelectString += event.key.toLowerCase();
15500
+ }
15501
+ for (const option of allOptions) {
15502
+ const label = option.getTextLabel().toLowerCase();
15503
+ if (label.startsWith(this.typeToSelectString)) {
15504
+ this.setCurrentOption(option);
15505
+ break;
15506
+ }
15507
+ }
15508
+ }
15509
+ };
15510
+ this.handleDocumentMouseDown = (event) => {
15511
+ const path = event.composedPath();
15512
+ if (this && !path.includes(this)) {
15513
+ this.hide();
15514
+ }
15515
+ };
15244
15516
  }
15245
15517
  /** Gets the validity state object */
15246
15518
  get validity() {
@@ -15252,20 +15524,49 @@ let FlowSelect = class extends FlowRdfElement {
15252
15524
  }
15253
15525
  connectedCallback() {
15254
15526
  super.connectedCallback();
15255
- this.handleDocumentFocusIn = this.handleDocumentFocusIn.bind(this);
15256
- this.handleDocumentKeyDown = this.handleDocumentKeyDown.bind(this);
15257
- this.handleDocumentMouseDown = this.handleDocumentMouseDown.bind(this);
15258
15527
  this.open = false;
15528
+ this.mutationObserver = new MutationObserver(() => {
15529
+ this.updateComplete.then(() => {
15530
+ this.selectionChanged();
15531
+ });
15532
+ });
15533
+ this.mutationObserver.observe(this, {
15534
+ attributes: true,
15535
+ attributeFilter: ["value"],
15536
+ characterData: true,
15537
+ subtree: true
15538
+ });
15539
+ }
15540
+ disconnectedCallback() {
15541
+ super.disconnectedCallback();
15542
+ this.mutationObserver?.disconnect();
15259
15543
  }
15260
15544
  addOpenListeners() {
15261
15545
  document.addEventListener("focusin", this.handleDocumentFocusIn);
15262
15546
  document.addEventListener("keydown", this.handleDocumentKeyDown);
15263
15547
  document.addEventListener("mousedown", this.handleDocumentMouseDown);
15548
+ if (this.getRootNode() !== document) {
15549
+ this.getRootNode().addEventListener("focusin", this.handleDocumentFocusIn);
15550
+ }
15551
+ if ("CloseWatcher" in window) {
15552
+ this.closeWatcher?.destroy();
15553
+ this.closeWatcher = new CloseWatcher();
15554
+ this.closeWatcher.onclose = () => {
15555
+ if (this.open) {
15556
+ this.hide();
15557
+ this.displayInput.focus({ preventScroll: true });
15558
+ }
15559
+ };
15560
+ }
15264
15561
  }
15265
15562
  removeOpenListeners() {
15266
15563
  document.removeEventListener("focusin", this.handleDocumentFocusIn);
15267
15564
  document.removeEventListener("keydown", this.handleDocumentKeyDown);
15268
15565
  document.removeEventListener("mousedown", this.handleDocumentMouseDown);
15566
+ if (this.getRootNode() !== document) {
15567
+ this.getRootNode().removeEventListener("focusin", this.handleDocumentFocusIn);
15568
+ }
15569
+ this.closeWatcher?.destroy();
15269
15570
  }
15270
15571
  handleFocus() {
15271
15572
  this.hasFocus = true;
@@ -15276,110 +15577,6 @@ let FlowSelect = class extends FlowRdfElement {
15276
15577
  this.hasFocus = false;
15277
15578
  this.emit("flow-ui-blur");
15278
15579
  }
15279
- handleDocumentFocusIn(event) {
15280
- const path = event.composedPath();
15281
- if (this && !path.includes(this)) {
15282
- this.hide();
15283
- }
15284
- }
15285
- handleDocumentKeyDown(event) {
15286
- const target = event.target;
15287
- const isClearButton = target.closest(".select__clear") !== null;
15288
- const isIconButton = target.closest("flow-ui-icon-button") !== null;
15289
- if (isClearButton || isIconButton) {
15290
- return;
15291
- }
15292
- if (event.key === "Escape" && this.open) {
15293
- event.preventDefault();
15294
- event.stopPropagation();
15295
- this.hide();
15296
- this.displayInput.focus({ preventScroll: true });
15297
- }
15298
- if (event.key === "Enter" || event.key === " " && this.typeToSelectString === "") {
15299
- event.preventDefault();
15300
- event.stopImmediatePropagation();
15301
- if (!this.open) {
15302
- this.show();
15303
- return;
15304
- }
15305
- if (this.currentOption && !this.currentOption.disabled) {
15306
- if (this.multiple) {
15307
- this.toggleOptionSelection(this.currentOption);
15308
- } else {
15309
- this.setSelectedOptions(this.currentOption);
15310
- }
15311
- this.updateComplete.then(() => {
15312
- this.emit("flow-ui-input");
15313
- this.emit("flow-ui-change");
15314
- });
15315
- if (!this.multiple) {
15316
- this.hide();
15317
- this.displayInput.focus({ preventScroll: true });
15318
- }
15319
- }
15320
- return;
15321
- }
15322
- if (["ArrowUp", "ArrowDown", "Home", "End"].includes(event.key)) {
15323
- const allOptions = this.getAllOptions();
15324
- const currentIndex = allOptions.indexOf(this.currentOption);
15325
- let newIndex = Math.max(0, currentIndex);
15326
- event.preventDefault();
15327
- if (!this.open) {
15328
- this.show();
15329
- if (this.currentOption) {
15330
- return;
15331
- }
15332
- }
15333
- if (event.key === "ArrowDown") {
15334
- newIndex = currentIndex + 1;
15335
- if (newIndex > allOptions.length - 1)
15336
- newIndex = 0;
15337
- } else if (event.key === "ArrowUp") {
15338
- newIndex = currentIndex - 1;
15339
- if (newIndex < 0)
15340
- newIndex = allOptions.length - 1;
15341
- } else if (event.key === "Home") {
15342
- newIndex = 0;
15343
- } else if (event.key === "End") {
15344
- newIndex = allOptions.length - 1;
15345
- }
15346
- this.setCurrentOption(allOptions[newIndex]);
15347
- }
15348
- if (event.key.length === 1 || event.key === "Backspace") {
15349
- const allOptions = this.getAllOptions();
15350
- if (event.metaKey || event.ctrlKey || event.altKey) {
15351
- return;
15352
- }
15353
- if (!this.open) {
15354
- if (event.key === "Backspace") {
15355
- return;
15356
- }
15357
- this.show();
15358
- }
15359
- event.stopPropagation();
15360
- event.preventDefault();
15361
- clearTimeout(this.typeToSelectTimeout);
15362
- this.typeToSelectTimeout = window.setTimeout(() => this.typeToSelectString = "", 1e3);
15363
- if (event.key === "Backspace") {
15364
- this.typeToSelectString = this.typeToSelectString.slice(0, -1);
15365
- } else {
15366
- this.typeToSelectString += event.key.toLowerCase();
15367
- }
15368
- for (const option of allOptions) {
15369
- const label = option.getTextLabel().toLowerCase();
15370
- if (label.startsWith(this.typeToSelectString)) {
15371
- this.setCurrentOption(option);
15372
- break;
15373
- }
15374
- }
15375
- }
15376
- }
15377
- handleDocumentMouseDown(event) {
15378
- const path = event.composedPath();
15379
- if (this && !path.includes(this)) {
15380
- this.hide();
15381
- }
15382
- }
15383
15580
  handleLabelClick() {
15384
15581
  this.displayInput.focus();
15385
15582
  }
@@ -15394,6 +15591,9 @@ let FlowSelect = class extends FlowRdfElement {
15394
15591
  this.open = !this.open;
15395
15592
  }
15396
15593
  handleComboboxKeyDown(event) {
15594
+ if (event.key === "Tab") {
15595
+ return;
15596
+ }
15397
15597
  event.stopPropagation();
15398
15598
  this.handleDocumentKeyDown(event);
15399
15599
  }
@@ -15438,13 +15638,7 @@ let FlowSelect = class extends FlowRdfElement {
15438
15638
  }
15439
15639
  handleDefaultSlotChange() {
15440
15640
  const allOptions = this.getAllOptions();
15441
- let value;
15442
- if (allOptions.length && this.pendingValue) {
15443
- value = this.pendingValue;
15444
- this.pendingValue = null;
15445
- } else {
15446
- value = Array.isArray(this.value) ? this.value : [this.value];
15447
- }
15641
+ const value = Array.isArray(this.value) ? this.value : [this.value];
15448
15642
  const values = [];
15449
15643
  if (customElements.get("flow-ui-option")) {
15450
15644
  allOptions.forEach((option) => values.push(option.value));
@@ -15524,6 +15718,23 @@ let FlowSelect = class extends FlowRdfElement {
15524
15718
  this.formControlController.updateValidity();
15525
15719
  });
15526
15720
  }
15721
+ get tags() {
15722
+ return this.selectedOptions.map((option, index) => {
15723
+ if (index < this.maxOptionsVisible || this.maxOptionsVisible <= 0) {
15724
+ const tag = this.getTag(option, index);
15725
+ return html`
15726
+ <div @flow-ui-remove=${(e) => this.handleTagRemove(e, option)}>
15727
+ ${typeof tag === "string" ? unsafeHTML(tag) : tag}
15728
+ </div>
15729
+ `;
15730
+ } else if (index === this.maxOptionsVisible) {
15731
+ return html`
15732
+ <flow-ui-tag size=${this.size}>+${this.selectedOptions.length - index}</flow-ui-tag>
15733
+ `;
15734
+ }
15735
+ return html``;
15736
+ });
15737
+ }
15527
15738
  handleInvalid(event) {
15528
15739
  this.formControlController.setValidity(false);
15529
15740
  this.formControlController.emitInvalidEvent(event);
@@ -15537,9 +15748,6 @@ let FlowSelect = class extends FlowRdfElement {
15537
15748
  handleValueChange() {
15538
15749
  const allOptions = this.getAllOptions();
15539
15750
  const value = Array.isArray(this.value) ? this.value : [this.value];
15540
- if (allOptions.length === 0) {
15541
- this.pendingValue = value;
15542
- }
15543
15751
  this.setSelectedOptions(allOptions.filter((el) => value.includes(el.value)));
15544
15752
  }
15545
15753
  async handleOpenChange() {
@@ -15701,35 +15909,7 @@ let FlowSelect = class extends FlowRdfElement {
15701
15909
  />
15702
15910
 
15703
15911
  ${this.multiple ? html`
15704
- <div part="tags" class="select__tags">
15705
- ${this.selectedOptions.map((option, index) => {
15706
- if (index < this.maxOptionsVisible || this.maxOptionsVisible <= 0) {
15707
- return html`
15708
- <flow-ui-tag
15709
- part="tag"
15710
- exportparts="
15711
- base:tag__base,
15712
- content:tag__content,
15713
- remove-button:tag__remove-button,
15714
- remove-button__base:tag__remove-button__base
15715
- "
15716
- ?pill=${this.pill}
15717
- size=${this.size}
15718
- removable
15719
- @flow-ui-remove=${(event) => this.handleTagRemove(event, option)}
15720
- >
15721
- ${option.getTextLabel()}
15722
- </flow-ui-tag>
15723
- `;
15724
- } else if (index === this.maxOptionsVisible) {
15725
- return html`
15726
- <flow-ui-tag size=${this.size}>+${this.selectedOptions.length - index}</flow-ui-tag>
15727
- `;
15728
- } else {
15729
- return null;
15730
- }
15731
- })}
15732
- </div>
15912
+ <div part="tags" class="select__tags">${this.tags}</div>
15733
15913
  ` : ""}
15734
15914
 
15735
15915
  <input
@@ -15760,6 +15940,8 @@ let FlowSelect = class extends FlowRdfElement {
15760
15940
  </button>
15761
15941
  ` : ""}
15762
15942
 
15943
+ <slot name="suffix" part="suffix" class="select__suffix"></slot>
15944
+
15763
15945
  <slot name="expand-icon" part="expand-icon" class="select__expand-icon">
15764
15946
  <flow-ui-icon library="system" name="chevron-down"></flow-ui-icon>
15765
15947
  </slot>
@@ -15782,20 +15964,24 @@ let FlowSelect = class extends FlowRdfElement {
15782
15964
  </flow-ui-popup>
15783
15965
  </div>
15784
15966
 
15785
- <slot
15786
- name="help-text"
15967
+ <div
15787
15968
  part="form-control-help-text"
15788
15969
  id="help-text"
15789
15970
  class="form-control__help-text"
15790
15971
  aria-hidden=${hasHelpText ? "false" : "true"}
15791
15972
  >
15792
- ${this.helpText}
15793
- </slot>
15973
+ <slot name="help-text">${this.helpText}</slot>
15974
+ </div>
15794
15975
  </div>
15795
15976
  `;
15796
15977
  }
15978
+ }
15979
+ FlowSelect.styles = [componentStyles, formControlStyles, styles$i];
15980
+ FlowSelect.dependencies = {
15981
+ "flow-icon": FlowIcon,
15982
+ "flow-popup": SlPopup,
15983
+ "flow-tag": FlowTag
15797
15984
  };
15798
- FlowSelect.styles = styles$i;
15799
15985
  __decorateClass$h([
15800
15986
  query(".select")
15801
15987
  ], FlowSelect.prototype, "popup", 2);
@@ -15882,6 +16068,9 @@ __decorateClass$h([
15882
16068
  __decorateClass$h([
15883
16069
  property({ type: Boolean, reflect: true })
15884
16070
  ], FlowSelect.prototype, "required", 2);
16071
+ __decorateClass$h([
16072
+ property()
16073
+ ], FlowSelect.prototype, "getTag", 2);
15885
16074
  __decorateClass$h([
15886
16075
  watch("disabled", { waitUntilFirstUpdate: true })
15887
16076
  ], FlowSelect.prototype, "handleDisabledChange", 1);
@@ -15891,9 +16080,6 @@ __decorateClass$h([
15891
16080
  __decorateClass$h([
15892
16081
  watch("open", { waitUntilFirstUpdate: true })
15893
16082
  ], FlowSelect.prototype, "handleOpenChange", 1);
15894
- FlowSelect = __decorateClass$h([
15895
- customElement("flow-ui-select")
15896
- ], FlowSelect);
15897
16083
  setDefaultAnimation("select.show", {
15898
16084
  keyframes: [
15899
16085
  { opacity: 0, scale: 0.9 },
@@ -15909,6 +16095,8 @@ setDefaultAnimation("select.hide", {
15909
16095
  options: { duration: 100, easing: "ease" }
15910
16096
  });
15911
16097
 
16098
+ FlowSelect.define("flow-ui-select");
16099
+
15912
16100
  const styles$h = css`
15913
16101
  ${componentStyles}
15914
16102
 
@@ -19176,7 +19364,6 @@ const styles$6 = css`
19176
19364
  }
19177
19365
  `;
19178
19366
 
19179
- dayjs.locale("en");
19180
19367
  class FlowTimer extends FlowRdfElement {
19181
19368
  connectedCallback() {
19182
19369
  super.connectedCallback();
@@ -21552,6 +21739,13 @@ function getBasePath(subpath = "") {
21552
21739
  return basePath.replace(/\/$/, "") + (subpath ? `/${subpath.replace(/^\//, "")}` : ``);
21553
21740
  }
21554
21741
 
21742
+ function setDefaultLocale(locale) {
21743
+ Settings.defaultLocale = locale;
21744
+ }
21745
+ function setDefaultTimeZone(timeZone) {
21746
+ Settings.defaultZone = timeZone;
21747
+ }
21748
+
21555
21749
  const translation = {
21556
21750
  $code: "en",
21557
21751
  $name: "English",
@@ -21585,7 +21779,7 @@ const translation = {
21585
21779
  };
21586
21780
  registerTranslation(translation);
21587
21781
 
21588
- const version = "0.0.25";
21782
+ const version = "0.0.26";
21589
21783
 
21590
21784
  const CONSOLE_HIGHLIGHT_STYLE = `
21591
21785
  padding: 2px 4px;
@@ -21598,4 +21792,4 @@ function announce() {
21598
21792
 
21599
21793
  announce();
21600
21794
 
21601
- export { FlowAlert, FlowAnimation, FlowAvatar, FlowBadge, FlowBreadcrumb, FlowBreadcrumbItem, FlowButton, FlowButtonGroup, FlowCalendar, FlowCard, FlowCarousel, FlowCarouselItem, FlowChart, FlowCheckbox, FlowColorMapper, FlowColorPicker, FlowColorStopComponent as FlowColorStop, FlowDatetimePicker as FlowDateTimePicker, FlowDetails, FlowDialog, FlowDivider, FlowDrawer, FlowDropdown, FlowGauge, FlowIcon, FlowIconButton, FlowInput, FlowMenu, FlowMenuItem, FlowMenuLabel, FlowMutationObserver, FlowNumberStepper, FlowOption, FlowSplitViewPanel as FlowPanel, FlowPanelHeader, FlowPopup, FlowProgressBar, FlowProgressRing, FlowRadio, FlowRadioGroup, FlowRange, FlowResizeObserver, FlowScrollView, FlowSelect, FlowSpinner, FlowSplitView, FlowPanelDivider as FlowSplitViewDivider, FlowSplitViewPane, FlowSplitViewToggleButton, FlowStepper, FlowStepperPanel, FlowSwitch, FlowTab, FlowTabGroup, FlowTabPanel, FlowTag, FlowTextarea, FlowTimer, FlowToolButton, FlowToolButtonGroup, FlowTooltip, FlowTree, FlowTreeItem, FlowVisuallyHidden, addIcons, colorMapperValueToMaplibreExpression, escapeMaplibreString, getAnimationNames, getBasePath, getEasingNames, initializeChartJs, registerChartComponent, registerIconLibrary, setBasePath, unregisterIconLibrary };
21795
+ export { FlowAlert, FlowAnimation, FlowAvatar, FlowBadge, FlowBreadcrumb, FlowBreadcrumbItem, FlowButton, FlowButtonGroup, FlowCalendar, FlowCard, FlowCarousel, FlowCarouselItem, FlowChart, FlowCheckbox, FlowColorMapper, FlowColorPicker, FlowColorStopComponent as FlowColorStop, FlowDatetimePicker as FlowDateTimePicker, FlowDetails, FlowDialog, FlowDivider, FlowDrawer, FlowDropdown, FlowGauge, FlowIcon, FlowIconButton, FlowInput, FlowMenu, FlowMenuItem, FlowMenuLabel, FlowMutationObserver, FlowNumberStepper, FlowOption, FlowSplitViewPanel as FlowPanel, FlowPanelHeader, SlPopup as FlowPopup, FlowProgressBar, FlowProgressRing, FlowRadio, FlowRadioGroup, FlowRange, FlowResizeObserver, FlowScrollView, FlowSelect, FlowSpinner, FlowSplitView, FlowPanelDivider as FlowSplitViewDivider, FlowSplitViewPane, FlowSplitViewToggleButton, FlowStepper, FlowStepperPanel, FlowSwitch, FlowTab, FlowTabGroup, FlowTabPanel, FlowTag, FlowTextarea, FlowTimer, FlowToolButton, FlowToolButtonGroup, FlowTooltip, FlowTree, FlowTreeItem, FlowVisuallyHidden, addIcons, colorMapperValueToMaplibreExpression, escapeMaplibreString, getAnimationNames, getBasePath, getEasingNames, initializeChartJs, registerChartComponent, registerIconLibrary, setBasePath, setDefaultLocale, setDefaultTimeZone, unregisterIconLibrary };