@helpwave/hightide 0.10.0 → 0.10.2

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
@@ -9148,13 +9148,29 @@ var LocaleProvider = ({
9148
9148
  children,
9149
9149
  locale,
9150
9150
  defaultLocale,
9151
- onChangedLocale
9151
+ defaultTimeZone,
9152
+ defaultIs24HourFormat,
9153
+ timeZone,
9154
+ is24HourFormat,
9155
+ onChangedLocale,
9156
+ onChangedTimeZone,
9157
+ onChangedIs24HourFormat
9152
9158
  }) => {
9153
9159
  const {
9154
9160
  value: storedLocale,
9155
9161
  setValue: setStoredLocale,
9156
9162
  deleteValue: deleteStoredLocale
9157
9163
  } = useStorage({ key: "locale", defaultValue: "system" });
9164
+ const {
9165
+ value: storedTimeZone,
9166
+ setValue: setStoredTimeZone,
9167
+ deleteValue: deleteStoredTimeZone
9168
+ } = useStorage({ key: "timeZone", defaultValue: void 0 });
9169
+ const {
9170
+ value: storedIs24HourFormat,
9171
+ setValue: setStoredIs24HourFormat,
9172
+ deleteValue: deleteStoredIs24HourFormat
9173
+ } = useStorage({ key: "is24HourFormat", defaultValue: void 0 });
9158
9174
  const { config } = useHightideConfig();
9159
9175
  const [localePreference, setLocalePreference] = useState4("system");
9160
9176
  const resolvedLocale = useMemo4(() => {
@@ -9177,10 +9193,32 @@ var LocaleProvider = ({
9177
9193
  setStoredLocale(locale);
9178
9194
  }
9179
9195
  }, [locale, deleteStoredLocale, setStoredLocale]);
9196
+ const resolvedTimeZone = useMemo4(() => {
9197
+ return timeZone ?? storedTimeZone ?? config.locale.defaultTimeZone ?? defaultTimeZone;
9198
+ }, [timeZone, storedTimeZone, config.locale.defaultTimeZone, defaultTimeZone]);
9199
+ useEffect4(() => {
9200
+ if (timeZone === void 0) return;
9201
+ setStoredTimeZone(timeZone);
9202
+ }, [timeZone, setStoredTimeZone]);
9203
+ const resolvedIs24HourFormat = useMemo4(() => {
9204
+ return is24HourFormat ?? storedIs24HourFormat ?? config.locale.defaultIs24HourFormat ?? defaultIs24HourFormat ?? true;
9205
+ }, [is24HourFormat, storedIs24HourFormat, config.locale.defaultIs24HourFormat, defaultIs24HourFormat]);
9206
+ useEffect4(() => {
9207
+ if (is24HourFormat === void 0) return;
9208
+ setStoredIs24HourFormat(is24HourFormat);
9209
+ }, [is24HourFormat, setStoredIs24HourFormat]);
9180
9210
  const onChangeRef = useEventCallbackStabilizer(onChangedLocale);
9181
9211
  useEffect4(() => {
9182
9212
  onChangeRef?.(resolvedLocale);
9183
9213
  }, [resolvedLocale, onChangeRef]);
9214
+ const onChangeTimeZoneRef = useEventCallbackStabilizer(onChangedTimeZone);
9215
+ useEffect4(() => {
9216
+ onChangeTimeZoneRef?.(resolvedTimeZone);
9217
+ }, [resolvedTimeZone, onChangeTimeZoneRef]);
9218
+ const onChangeIs24HourFormatRef = useEventCallbackStabilizer(onChangedIs24HourFormat);
9219
+ useEffect4(() => {
9220
+ onChangeIs24HourFormatRef?.(resolvedIs24HourFormat);
9221
+ }, [resolvedIs24HourFormat, onChangeIs24HourFormatRef]);
9184
9222
  useEffect4(() => {
9185
9223
  const localesToTestAgainst = Object.values(LocalizationUtil.locals);
9186
9224
  const detectLanguage = () => {
@@ -9204,6 +9242,30 @@ var LocaleProvider = ({
9204
9242
  console.warn("LocaleProvider: Attempting to change the locale while setting a fixed locale won't have any effect. Change the locale provided to the LocaleProvider instead.");
9205
9243
  }
9206
9244
  setStoredLocale(newLocale);
9245
+ },
9246
+ timeZone: resolvedTimeZone,
9247
+ setTimeZone: (newTimeZone) => {
9248
+ if (timeZone !== void 0) {
9249
+ console.warn("LocaleProvider: Attempting to change the time zone while setting a fixed time zone won't have any effect. Change the timeZone provided to the LocaleProvider instead.");
9250
+ return;
9251
+ }
9252
+ if (newTimeZone === void 0) {
9253
+ deleteStoredTimeZone();
9254
+ } else {
9255
+ setStoredTimeZone(newTimeZone);
9256
+ }
9257
+ },
9258
+ is24HourFormat: resolvedIs24HourFormat,
9259
+ setIs24HourFormat: (newIs24HourFormat) => {
9260
+ if (is24HourFormat !== void 0) {
9261
+ console.warn("LocaleProvider: Attempting to change the hour format while setting a fixed hour format won't have any effect. Change the is24HourFormat provided to the LocaleProvider instead.");
9262
+ return;
9263
+ }
9264
+ if (newIs24HourFormat === void 0) {
9265
+ deleteStoredIs24HourFormat();
9266
+ } else {
9267
+ setStoredIs24HourFormat(newIs24HourFormat);
9268
+ }
9207
9269
  }
9208
9270
  }, children });
9209
9271
  };
@@ -9214,6 +9276,20 @@ var useLocale = () => {
9214
9276
  }
9215
9277
  return context;
9216
9278
  };
9279
+ var useTimeZone = () => {
9280
+ const context = useContext2(LocaleContext);
9281
+ if (!context) {
9282
+ throw new Error("useTimeZone must be used within LocaleContext. Try adding a LocaleProvider around your app.");
9283
+ }
9284
+ return { timeZone: context.timeZone, setTimeZone: context.setTimeZone };
9285
+ };
9286
+ var useDateTimeFormat = () => {
9287
+ const context = useContext2(LocaleContext);
9288
+ return {
9289
+ is24HourFormat: context?.is24HourFormat ?? true,
9290
+ timeZone: context?.timeZone
9291
+ };
9292
+ };
9217
9293
  var useLanguage = () => {
9218
9294
  const context = useContext2(LocaleContext);
9219
9295
  if (!context) {
@@ -9984,9 +10060,11 @@ var SelectButton = forwardRef3(
9984
10060
  return () => unregister();
9985
10061
  }, [registerTrigger]);
9986
10062
  const disabled = !!disabledOverride || !!context.disabled;
10063
+ const readOnly = !!context.readOnly;
9987
10064
  const invalid = context.invalid;
9988
10065
  const hasValue = context.selectedId !== null;
9989
- const selectedOption = context.idToOptionMap[context.selectedId] ?? null;
10066
+ const hasInteractions = !readOnly && !disabled;
10067
+ const selectedOption = context.selectedId ? context.idToOptionMap[context.selectedId] ?? null : null;
9990
10068
  return /* @__PURE__ */ jsxs9(
9991
10069
  "div",
9992
10070
  {
@@ -9994,12 +10072,13 @@ var SelectButton = forwardRef3(
9994
10072
  ref: innerRef,
9995
10073
  id: context.config.ids.trigger,
9996
10074
  onClick: (event) => {
10075
+ if (!hasInteractions) return;
9997
10076
  props.onClick?.(event);
9998
10077
  context.toggleIsOpen();
9999
10078
  },
10000
10079
  onKeyDown: (event) => {
10001
10080
  props.onKeyDown?.(event);
10002
- if (disabled) return;
10081
+ if (!hasInteractions) return;
10003
10082
  switch (event.key) {
10004
10083
  case "Enter":
10005
10084
  case " ":
@@ -10022,16 +10101,18 @@ var SelectButton = forwardRef3(
10022
10101
  "data-name": props["data-name"] ?? "select-button",
10023
10102
  "data-value": hasValue ? "" : void 0,
10024
10103
  "data-disabled": disabled ? "" : void 0,
10104
+ "data-readonly": readOnly ? "" : void 0,
10025
10105
  "data-invalid": invalid ? "" : void 0,
10026
10106
  tabIndex: disabled ? -1 : 0,
10027
10107
  role: "button",
10028
10108
  "aria-invalid": invalid,
10029
10109
  "aria-disabled": disabled,
10110
+ "aria-readonly": readOnly,
10030
10111
  "aria-haspopup": "dialog",
10031
10112
  "aria-expanded": context.isOpen,
10032
10113
  "aria-controls": context.isOpen ? context.config.ids.content : void 0,
10033
10114
  children: [
10034
- /* @__PURE__ */ jsx17(SelectOptionDisplayContext.Provider, { value: "trigger", children: hasValue ? selectedDisplay?.(selectedOption) ?? selectedOption.display : placeholder ?? translation("clickToSelect") }),
10115
+ /* @__PURE__ */ jsx17(SelectOptionDisplayContext.Provider, { value: "trigger", children: hasValue ? selectedDisplay?.(selectedOption) ?? selectedOption?.display : placeholder ?? translation("clickToSelect") }),
10035
10116
  !hideExpansionIcon && /* @__PURE__ */ jsx17(ExpansionIcon, { isExpanded: context.isOpen })
10036
10117
  ]
10037
10118
  }
@@ -15418,9 +15499,7 @@ var timesInSeconds = {
15418
15499
  day: 86400,
15419
15500
  week: 604800,
15420
15501
  monthImprecise: 2629800,
15421
- // 30.4375 days
15422
15502
  yearImprecise: 31557600
15423
- // 365.25 days
15424
15503
  };
15425
15504
  var monthsList = ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"];
15426
15505
  var weekDayList = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
@@ -15523,6 +15602,73 @@ var withTime = (datePart, timePart) => {
15523
15602
  );
15524
15603
  return out;
15525
15604
  };
15605
+ var zonedPartsFormatterCache = /* @__PURE__ */ new Map();
15606
+ var zonedPartsFormatter = (timeZone) => {
15607
+ let formatter = zonedPartsFormatterCache.get(timeZone);
15608
+ if (!formatter) {
15609
+ formatter = new Intl.DateTimeFormat("en-US", {
15610
+ timeZone,
15611
+ hourCycle: "h23",
15612
+ year: "numeric",
15613
+ month: "2-digit",
15614
+ day: "2-digit",
15615
+ hour: "2-digit",
15616
+ minute: "2-digit",
15617
+ second: "2-digit"
15618
+ });
15619
+ zonedPartsFormatterCache.set(timeZone, formatter);
15620
+ }
15621
+ return formatter;
15622
+ };
15623
+ var zonedParts = (date, timeZone) => {
15624
+ const parts = {};
15625
+ for (const part of zonedPartsFormatter(timeZone).formatToParts(date)) {
15626
+ if (part.type !== "literal") {
15627
+ parts[part.type] = part.value;
15628
+ }
15629
+ }
15630
+ return {
15631
+ year: Number(parts.year),
15632
+ month: Number(parts.month),
15633
+ day: Number(parts.day),
15634
+ hour: Number(parts.hour) % 24,
15635
+ minute: Number(parts.minute),
15636
+ second: Number(parts.second),
15637
+ millisecond: date.getMilliseconds()
15638
+ };
15639
+ };
15640
+ var zoneOffsetMs = (date, timeZone) => {
15641
+ const parts = zonedParts(date, timeZone);
15642
+ const asUtc = Date.UTC(parts.year, parts.month - 1, parts.day, parts.hour, parts.minute, parts.second, parts.millisecond);
15643
+ return asUtc - date.getTime();
15644
+ };
15645
+ function toZonedDate(date, timeZone) {
15646
+ if (!date || !timeZone) {
15647
+ return date;
15648
+ }
15649
+ const parts = zonedParts(date, timeZone);
15650
+ return new Date(parts.year, parts.month - 1, parts.day, parts.hour, parts.minute, parts.second, parts.millisecond);
15651
+ }
15652
+ function fromZonedDate(date, timeZone) {
15653
+ if (!date || !timeZone) {
15654
+ return date;
15655
+ }
15656
+ const asUtc = Date.UTC(
15657
+ date.getFullYear(),
15658
+ date.getMonth(),
15659
+ date.getDate(),
15660
+ date.getHours(),
15661
+ date.getMinutes(),
15662
+ date.getSeconds(),
15663
+ date.getMilliseconds()
15664
+ );
15665
+ let offset = zoneOffsetMs(new Date(asUtc), timeZone);
15666
+ const refined = zoneOffsetMs(new Date(asUtc - offset), timeZone);
15667
+ if (refined !== offset) {
15668
+ offset = refined;
15669
+ }
15670
+ return new Date(asUtc - offset);
15671
+ }
15526
15672
  var weeksForCalenderMonth = (date, weekStart, weeks = 6) => {
15527
15673
  const month = date.getMonth();
15528
15674
  const year = date.getFullYear();
@@ -15540,8 +15686,13 @@ var weeksForCalenderMonth = (date, weekStart, weeks = 6) => {
15540
15686
  }
15541
15687
  return equalSizeGroups(dayList, 7);
15542
15688
  };
15543
- var formatAbsolute = (date, locale, format) => {
15689
+ var formatAbsolute = (date, locale, format, { timeZone, is24HourFormat = true } = {}) => {
15544
15690
  let options;
15691
+ const timeOptions = {
15692
+ hour: "2-digit",
15693
+ minute: "2-digit",
15694
+ hourCycle: is24HourFormat ? "h23" : "h12"
15695
+ };
15545
15696
  switch (format) {
15546
15697
  case "date":
15547
15698
  options = {
@@ -15552,8 +15703,7 @@ var formatAbsolute = (date, locale, format) => {
15552
15703
  break;
15553
15704
  case "time":
15554
15705
  options = {
15555
- hour: "2-digit",
15556
- minute: "2-digit"
15706
+ ...timeOptions
15557
15707
  };
15558
15708
  break;
15559
15709
  case "dateTime":
@@ -15561,12 +15711,11 @@ var formatAbsolute = (date, locale, format) => {
15561
15711
  year: "numeric",
15562
15712
  month: "2-digit",
15563
15713
  day: "2-digit",
15564
- hour: "2-digit",
15565
- minute: "2-digit"
15714
+ ...timeOptions
15566
15715
  };
15567
15716
  break;
15568
15717
  }
15569
- return new Intl.DateTimeFormat(locale, options).format(date);
15718
+ return new Intl.DateTimeFormat(locale, { ...options, timeZone }).format(date);
15570
15719
  };
15571
15720
  var formatRelative = (date, locale) => {
15572
15721
  const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
@@ -15643,6 +15792,9 @@ var DateUtils = {
15643
15792
  daysInMonth,
15644
15793
  sameTime,
15645
15794
  withTime,
15795
+ zonedParts,
15796
+ toZonedDate,
15797
+ fromZonedDate,
15646
15798
  formatAbsolute,
15647
15799
  formatRelative,
15648
15800
  addDuration,
@@ -15653,9 +15805,6 @@ var DateUtils = {
15653
15805
  toInputString,
15654
15806
  tryParseDate,
15655
15807
  toOnlyDate: normalizeToDateOnly,
15656
- /**
15657
- * Normalizes a datetime by removing seconds and milliseconds.
15658
- */
15659
15808
  toDateTimeOnly: normalizeDatetime
15660
15809
  };
15661
15810
 
@@ -16522,13 +16671,15 @@ var TimePicker = ({
16522
16671
  initialValue = /* @__PURE__ */ new Date(),
16523
16672
  onValueChange,
16524
16673
  onEditComplete,
16525
- is24HourFormat = true,
16674
+ is24HourFormat: is24HourFormatOverride,
16526
16675
  minuteIncrement = "5min",
16527
16676
  secondIncrement = "5s",
16528
16677
  millisecondIncrement = "100ms",
16529
16678
  precision = "minute",
16530
16679
  className
16531
16680
  }) => {
16681
+ const { is24HourFormat: contextIs24HourFormat } = useDateTimeFormat();
16682
+ const is24HourFormat = is24HourFormatOverride ?? contextIs24HourFormat;
16532
16683
  const [value, setValue] = useControlledState({
16533
16684
  value: controlledValue,
16534
16685
  onValueChange,
@@ -17525,19 +17676,14 @@ var DateTimeField = forwardRef18(function DateTimeField2({
17525
17676
  ...props
17526
17677
  }, forwardedRef) {
17527
17678
  const translation = useHightideTranslation();
17528
- const { locale: contextLocale } = useLocale();
17679
+ const { locale: contextLocale, is24HourFormat: contextIs24HourFormat } = useLocale();
17529
17680
  const locale = localeOverride ?? contextLocale;
17530
17681
  const [value, setValue] = useControlledState({
17531
17682
  value: controlledValue,
17532
17683
  onValueChange,
17533
17684
  defaultValue: initialValue
17534
17685
  });
17535
- const is24Hour = useMemo30(() => {
17536
- if (is24HourFormat !== void 0) {
17537
- return is24HourFormat;
17538
- }
17539
- return !new Intl.DateTimeFormat(locale, { hour: "numeric" }).resolvedOptions().hour12;
17540
- }, [is24HourFormat, locale]);
17686
+ const is24Hour = is24HourFormat ?? contextIs24HourFormat ?? true;
17541
17687
  const layout = useMemo30(
17542
17688
  () => buildSegmentLayout({ locale, mode, precision, is24HourFormat: is24Hour }),
17543
17689
  [locale, mode, precision, is24Hour]
@@ -17568,6 +17714,9 @@ var DateTimeField = forwardRef18(function DateTimeField2({
17568
17714
  return callback;
17569
17715
  };
17570
17716
  useEffect36(() => {
17717
+ if (editStateRef.current.buffer) {
17718
+ return;
17719
+ }
17571
17720
  const shown = composeDate(editStateRef.current.values, layout, mode, is24Hour, value ?? void 0);
17572
17721
  if ((shown?.getTime() ?? null) === (value?.getTime() ?? null)) {
17573
17722
  return;
@@ -17579,6 +17728,9 @@ var DateTimeField = forwardRef18(function DateTimeField2({
17579
17728
  }, [value, layout, mode, is24Hour]);
17580
17729
  const apply = (next) => {
17581
17730
  setEditState(next);
17731
+ if (next.buffer?.type === "year") {
17732
+ return;
17733
+ }
17582
17734
  const composed = composeDate(next.values, layout, mode, is24Hour, value ?? void 0);
17583
17735
  if (composed) {
17584
17736
  setValue(composed);
@@ -17675,6 +17827,10 @@ var DateTimeField = forwardRef18(function DateTimeField2({
17675
17827
  const onFieldBlur = (event) => {
17676
17828
  props.onBlur?.(event);
17677
17829
  const field = event.currentTarget;
17830
+ const nextFocus = event.relatedTarget;
17831
+ if (nextFocus instanceof Node && field.contains(nextFocus)) {
17832
+ return;
17833
+ }
17678
17834
  requestAnimationFrame(() => {
17679
17835
  if (field.contains(document.activeElement)) {
17680
17836
  return;
@@ -17683,6 +17839,9 @@ var DateTimeField = forwardRef18(function DateTimeField2({
17683
17839
  const composed = composeDate(editStateRef.current.values, layout, mode, is24Hour, value ?? void 0);
17684
17840
  if (composed) {
17685
17841
  setEditState({ values: decomposeDate(composed, layout, is24Hour), buffer: null });
17842
+ if (composed.getTime() !== (value?.getTime() ?? null)) {
17843
+ setValue(composed);
17844
+ }
17686
17845
  onEditComplete?.(composed);
17687
17846
  } else {
17688
17847
  onEditComplete?.(value ?? null);
@@ -17757,6 +17916,7 @@ var DateTimeInput = forwardRef19(function DateTimeInput2({
17757
17916
  allowClear = true,
17758
17917
  containerProps,
17759
17918
  mode = "date",
17919
+ timeZone: timeZoneOverride,
17760
17920
  precision = "minute",
17761
17921
  pickerProps,
17762
17922
  outsideClickCloses = true,
@@ -17777,6 +17937,8 @@ var DateTimeInput = forwardRef19(function DateTimeInput2({
17777
17937
  ...props
17778
17938
  }, forwardedRef) {
17779
17939
  const translation = useHightideTranslation();
17940
+ const { timeZone: contextTimeZone } = useLocale();
17941
+ const timeZone = timeZoneOverride ?? contextTimeZone;
17780
17942
  const [isOpen, setIsOpen] = useState31(false);
17781
17943
  const [state, setState] = useControlledState({
17782
17944
  value,
@@ -17788,6 +17950,8 @@ var DateTimeInput = forwardRef19(function DateTimeInput2({
17788
17950
  onDialogOpeningChange?.(isOpen2);
17789
17951
  setIsOpen(isOpen2);
17790
17952
  }, [onDialogOpeningChange]);
17953
+ const toZoned = useCallback31((date) => DateUtils.toZonedDate(date, timeZone), [timeZone]);
17954
+ const fromZoned = useCallback31((date) => DateUtils.fromZonedDate(date, timeZone), [timeZone]);
17791
17955
  const generatedId = useId16();
17792
17956
  const ids = useMemo31(() => ({
17793
17957
  input: inputId ?? `date-time-input-${generatedId}`,
@@ -17834,7 +17998,7 @@ var DateTimeInput = forwardRef19(function DateTimeInput2({
17834
17998
  DateTimeField,
17835
17999
  {
17836
18000
  ref: fieldRef,
17837
- value: state,
18001
+ value: toZoned(state),
17838
18002
  mode,
17839
18003
  precision,
17840
18004
  is24HourFormat,
@@ -17842,8 +18006,8 @@ var DateTimeInput = forwardRef19(function DateTimeInput2({
17842
18006
  readOnly,
17843
18007
  invalid,
17844
18008
  required,
17845
- onValueChange: setState,
17846
- onEditComplete,
18009
+ onValueChange: (next) => setState(fromZoned(next)),
18010
+ onEditComplete: (next) => onEditComplete?.(fromZoned(next)),
17847
18011
  "aria-labelledby": props["aria-labelledby"],
17848
18012
  "aria-describedby": props["aria-describedby"],
17849
18013
  className: "grow"
@@ -17908,18 +18072,19 @@ var DateTimeInput = forwardRef19(function DateTimeInput2({
17908
18072
  children: /* @__PURE__ */ jsx73(
17909
18073
  DateTimePickerDialog,
17910
18074
  {
17911
- value: dialogValue,
18075
+ value: toZoned(dialogValue),
17912
18076
  allowRemove,
17913
- onValueChange: setDialogValue,
18077
+ onValueChange: (value2) => setDialogValue(fromZoned(value2)),
17914
18078
  onEditComplete: (value2) => {
17915
- setState(value2);
17916
- onEditComplete?.(value2);
18079
+ const absolute = fromZoned(value2);
18080
+ setState(absolute);
18081
+ onEditComplete?.(absolute);
17917
18082
  changeOpenWrapper(false);
17918
18083
  },
17919
18084
  pickerProps,
17920
18085
  mode,
17921
- start,
17922
- end,
18086
+ start: toZoned(start ?? null) ?? void 0,
18087
+ end: toZoned(end ?? null) ?? void 0,
17923
18088
  weekStart,
17924
18089
  markToday,
17925
18090
  is24HourFormat,
@@ -18446,8 +18611,10 @@ var MultiSelectButton = forwardRef21(function MultiSelectButton2({
18446
18611
  return () => unregister();
18447
18612
  }, [registerTrigger]);
18448
18613
  const disabled = !!disabledOverride || !!context.disabled;
18614
+ const readOnly = !!context.readOnly;
18449
18615
  const invalid = context.invalid;
18450
18616
  const hasValue = context.value.length > 0;
18617
+ const hasInteractions = !readOnly && !disabled;
18451
18618
  const selectedOptions = context.selectedIds.map((id2) => context.idToOptionMap[id2]).filter(Boolean);
18452
18619
  return /* @__PURE__ */ jsxs45(
18453
18620
  "div",
@@ -18456,12 +18623,13 @@ var MultiSelectButton = forwardRef21(function MultiSelectButton2({
18456
18623
  ref: innerRef,
18457
18624
  id: context.config.ids.trigger,
18458
18625
  onClick: (event) => {
18626
+ if (!hasInteractions) return;
18459
18627
  props.onClick?.(event);
18460
18628
  context.toggleIsOpen();
18461
18629
  },
18462
18630
  onKeyDown: (event) => {
18463
18631
  props.onKeyDown?.(event);
18464
- if (disabled) return;
18632
+ if (!hasInteractions) return;
18465
18633
  switch (event.key) {
18466
18634
  case "Enter":
18467
18635
  case " ":
@@ -18484,11 +18652,13 @@ var MultiSelectButton = forwardRef21(function MultiSelectButton2({
18484
18652
  "data-name": props["data-name"] ?? "multi-select-button",
18485
18653
  "data-value": hasValue ? "" : void 0,
18486
18654
  "data-disabled": disabled ? "" : void 0,
18655
+ "data-readonly": readOnly ? "" : void 0,
18487
18656
  "data-invalid": invalid ? "" : void 0,
18488
18657
  tabIndex: disabled ? -1 : 0,
18489
18658
  role: "button",
18490
18659
  "aria-invalid": invalid,
18491
18660
  "aria-disabled": disabled,
18661
+ "aria-readonly": readOnly,
18492
18662
  "aria-haspopup": "dialog",
18493
18663
  "aria-expanded": context.isOpen,
18494
18664
  "aria-controls": context.isOpen ? context.config.ids.content : void 0,
@@ -20767,7 +20937,9 @@ var MultiSelectChipDisplayButton = forwardRef29(function MultiSelectChipDisplayB
20767
20937
  return () => unregister();
20768
20938
  }, [registerTrigger]);
20769
20939
  const disabled = !!props?.disabled || !!context.disabled;
20940
+ const readOnly = !!context.readOnly;
20770
20941
  const invalid = context.invalid;
20942
+ const hasInteractions = !readOnly && !disabled;
20771
20943
  const selectedOptions = context.selectedIds.map((oid) => context.idToOptionMap[oid]).filter(Boolean);
20772
20944
  return /* @__PURE__ */ jsxs61(
20773
20945
  "div",
@@ -20777,14 +20949,17 @@ var MultiSelectChipDisplayButton = forwardRef29(function MultiSelectChipDisplayB
20777
20949
  onClick: (event) => {
20778
20950
  props.onClick?.(event);
20779
20951
  if (event.defaultPrevented) return;
20952
+ if (!hasInteractions) return;
20780
20953
  context.toggleIsOpen();
20781
20954
  },
20782
20955
  "data-name": props["data-name"] ?? "multi-select-chip-display-button",
20783
20956
  "data-value": context.value.length > 0 ? "" : void 0,
20784
20957
  "data-disabled": disabled ? "" : void 0,
20958
+ "data-readonly": readOnly ? "" : void 0,
20785
20959
  "data-invalid": invalid ? "" : void 0,
20786
20960
  "aria-invalid": invalid,
20787
20961
  "aria-disabled": disabled,
20962
+ "aria-readonly": readOnly,
20788
20963
  children: [
20789
20964
  selectedOptions.map((opt) => /* @__PURE__ */ jsxs61("div", { "data-name": "multi-select-chip-display-chip", children: [
20790
20965
  opt.display,
@@ -20792,6 +20967,7 @@ var MultiSelectChipDisplayButton = forwardRef29(function MultiSelectChipDisplayB
20792
20967
  IconButton,
20793
20968
  {
20794
20969
  tooltip: translation("remove"),
20970
+ disabled: !hasInteractions,
20795
20971
  onClick: (e) => {
20796
20972
  context.toggleSelection(opt.id, false);
20797
20973
  e.preventDefault();
@@ -20808,11 +20984,14 @@ var MultiSelectChipDisplayButton = forwardRef29(function MultiSelectChipDisplayB
20808
20984
  IconButton,
20809
20985
  {
20810
20986
  id: context.config.ids.trigger,
20987
+ disabled: !hasInteractions,
20811
20988
  onClick: (event) => {
20812
20989
  event.stopPropagation();
20990
+ if (!hasInteractions) return;
20813
20991
  context.toggleIsOpen();
20814
20992
  },
20815
20993
  onKeyDown: (event) => {
20994
+ if (!hasInteractions) return;
20816
20995
  switch (event.key) {
20817
20996
  case "ArrowDown":
20818
20997
  context.setIsOpen(true, "first");
@@ -21452,10 +21631,18 @@ var SortingList = ({ sorting, onSortingChange, availableItems }) => {
21452
21631
  import { jsx as jsx103 } from "react/jsx-runtime";
21453
21632
  var TimeDisplay = ({
21454
21633
  date,
21455
- mode = "daysFromToday"
21634
+ mode = "daysFromToday",
21635
+ is24HourFormat: is24HourFormatOverride,
21636
+ timeZone: timeZoneOverride
21456
21637
  }) => {
21457
21638
  const translation = useHightideTranslation();
21458
- const difference = (/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0).valueOf() - new Date(date).setHours(0, 0, 0, 0).valueOf();
21639
+ const { locale } = useLocale();
21640
+ const { is24HourFormat: contextIs24HourFormat, timeZone: contextTimeZone } = useDateTimeFormat();
21641
+ const is24HourFormat = is24HourFormatOverride ?? contextIs24HourFormat;
21642
+ const timeZone = timeZoneOverride ?? contextTimeZone;
21643
+ const zonedDate = DateUtils.toZonedDate(date, timeZone);
21644
+ const zonedNow = DateUtils.toZonedDate(/* @__PURE__ */ new Date(), timeZone);
21645
+ const difference = new Date(zonedNow).setHours(0, 0, 0, 0).valueOf() - new Date(zonedDate).setHours(0, 0, 0, 0).valueOf();
21459
21646
  const isBefore = difference > 0;
21460
21647
  const differenceInDays = Math.floor(Math.abs(difference) / (1e3 * 3600 * 24));
21461
21648
  let displayString;
@@ -21482,9 +21669,15 @@ var TimeDisplay = ({
21482
21669
  };
21483
21670
  let fullString;
21484
21671
  if (mode === "daysFromToday") {
21485
- fullString = `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")} - ${displayString}`;
21672
+ const timeString = new Intl.DateTimeFormat(locale, {
21673
+ hour: "2-digit",
21674
+ minute: "2-digit",
21675
+ hourCycle: is24HourFormat ? "h23" : "h12",
21676
+ timeZone
21677
+ }).format(date);
21678
+ fullString = `${timeString} - ${displayString}`;
21486
21679
  } else {
21487
- fullString = `${date.getDate()}. ${monthToTranslation[date.getMonth()]} ${date.getFullYear()}`;
21680
+ fullString = `${zonedDate.getDate()}. ${monthToTranslation[zonedDate.getMonth()]} ${zonedDate.getFullYear()}`;
21488
21681
  }
21489
21682
  return /* @__PURE__ */ jsx103("span", { children: fullString });
21490
21683
  };
@@ -21499,29 +21692,36 @@ var FlexibleDateTimeInput = forwardRef31(function FlexibleDateTimeInput2({
21499
21692
  initialValue,
21500
21693
  onValueChange,
21501
21694
  fixedTime: fixedTimeOverride,
21695
+ timeZone: timeZoneOverride,
21502
21696
  actions = [],
21503
21697
  ...props
21504
21698
  }, forwardedRef) {
21505
21699
  const translation = useHightideTranslation();
21700
+ const { timeZone: contextTimeZone } = useLocale();
21701
+ const timeZone = timeZoneOverride ?? contextTimeZone;
21506
21702
  const fixedTime = fixedTimeOverride ?? new Date(1970, 0, 1, 23, 59, 59, 999);
21507
21703
  const [value, setValue] = useControlledState({
21508
21704
  value: controlledValue,
21509
21705
  onValueChange,
21510
21706
  defaultValue: initialValue
21511
21707
  });
21708
+ const zoned = (date) => DateUtils.toZonedDate(date, timeZone);
21709
+ const unzoned = (date) => DateUtils.fromZonedDate(date, timeZone);
21710
+ const hasFixedTime = (date) => DateUtils.sameTime(zoned(date), fixedTime, true, true);
21512
21711
  const [mode, setMode] = useState42(() => {
21513
- if (value && !DateUtils.sameTime(value, fixedTime, true, true)) {
21712
+ if (value && !hasFixedTime(value)) {
21514
21713
  return "dateTime";
21515
21714
  }
21516
21715
  return defaultMode;
21517
21716
  });
21518
- const toDate = (date) => DateUtils.withTime(date, fixedTime);
21519
- const toDateTime = (date) => DateUtils.sameTime(date, fixedTime, true, true) ? DateUtils.withTime(date, /* @__PURE__ */ new Date()) : date;
21717
+ const toDate = (date) => unzoned(DateUtils.withTime(zoned(date), fixedTime));
21718
+ const toDateTime = (date) => hasFixedTime(date) ? unzoned(DateUtils.withTime(zoned(date), zoned(/* @__PURE__ */ new Date()))) : date;
21520
21719
  return /* @__PURE__ */ jsx104(
21521
21720
  DateTimeInput,
21522
21721
  {
21523
21722
  ...props,
21524
21723
  ref: forwardedRef,
21724
+ timeZone,
21525
21725
  mode,
21526
21726
  value,
21527
21727
  onValueChange: (next) => {
@@ -21860,26 +22060,46 @@ var CheckboxProperty = ({
21860
22060
  import { CalendarDays } from "lucide-react";
21861
22061
  import { jsx as jsx110 } from "react/jsx-runtime";
21862
22062
  var DateProperty = ({
22063
+ name,
21863
22064
  value,
21864
22065
  onValueChange,
21865
22066
  onEditComplete,
22067
+ onRemove,
22068
+ onValueClear,
22069
+ required,
21866
22070
  readOnly,
22071
+ allowClear = true,
22072
+ allowRemove = true,
21867
22073
  type = "dateTime",
21868
- ...baseProps
22074
+ className,
22075
+ ...inputProps
21869
22076
  }) => {
21870
22077
  const hasValue = !!value;
21871
22078
  return /* @__PURE__ */ jsx110(
21872
22079
  PropertyBase,
21873
22080
  {
21874
- ...baseProps,
22081
+ name,
22082
+ required,
22083
+ readOnly,
22084
+ allowClear,
22085
+ allowRemove,
22086
+ onRemove,
22087
+ onValueClear: onValueClear ?? (() => {
22088
+ onValueChange?.(null);
22089
+ onEditComplete?.(null);
22090
+ }),
21875
22091
  hasValue,
21876
22092
  icon: /* @__PURE__ */ jsx110(CalendarDays, { size: 24 }),
22093
+ className,
21877
22094
  children: ({ invalid }) => /* @__PURE__ */ jsx110(
21878
22095
  DateTimeInput,
21879
22096
  {
22097
+ ...inputProps,
21880
22098
  value,
21881
22099
  mode: type,
22100
+ required,
21882
22101
  readOnly,
22102
+ allowClear: false,
21883
22103
  onValueChange,
21884
22104
  onEditComplete,
21885
22105
  "data-name": "property-input",
@@ -22301,21 +22521,23 @@ var useRerender = () => {
22301
22521
 
22302
22522
  // src/hooks/useUpdatingDateString.ts
22303
22523
  import { useEffect as useEffect58, useState as useState48 } from "react";
22304
- var useUpdatingDateString = ({ absoluteFormat = "dateTime", localeOverride, date }) => {
22305
- const { locale: contextLocale } = useLocale();
22524
+ var useUpdatingDateString = ({ absoluteFormat = "dateTime", localeOverride, is24HourFormat: is24HourFormatOverride, timeZone: timeZoneOverride, date }) => {
22525
+ const { locale: contextLocale, is24HourFormat: contextIs24HourFormat, timeZone: contextTimeZone } = useLocale();
22306
22526
  const locale = localeOverride ?? contextLocale;
22527
+ const is24HourFormat = is24HourFormatOverride ?? contextIs24HourFormat ?? true;
22528
+ const timeZone = timeZoneOverride ?? contextTimeZone;
22307
22529
  const [dateAndTimeStrings, setDateAndTimeStrings] = useState48({
22308
22530
  compareDate: date,
22309
- absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat),
22531
+ absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat, { is24HourFormat, timeZone }),
22310
22532
  relative: DateUtils.formatRelative(date, locale)
22311
22533
  });
22312
22534
  useEffect58(() => {
22313
22535
  setDateAndTimeStrings({
22314
22536
  compareDate: date,
22315
- absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat),
22537
+ absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat, { is24HourFormat, timeZone }),
22316
22538
  relative: DateUtils.formatRelative(date, locale)
22317
22539
  });
22318
- }, [date, absoluteFormat, locale]);
22540
+ }, [date, absoluteFormat, locale, is24HourFormat, timeZone]);
22319
22541
  useEffect58(() => {
22320
22542
  let timeoutId;
22321
22543
  const startTimer = () => {
@@ -22332,14 +22554,14 @@ var useUpdatingDateString = ({ absoluteFormat = "dateTime", localeOverride, date
22332
22554
  timeoutId = setInterval(() => {
22333
22555
  setDateAndTimeStrings({
22334
22556
  compareDate: date,
22335
- absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat),
22557
+ absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat, { is24HourFormat, timeZone }),
22336
22558
  relative: DateUtils.formatRelative(date, locale)
22337
22559
  });
22338
22560
  }, delayInSeconds * 1e3 / 2);
22339
22561
  };
22340
22562
  startTimer();
22341
22563
  return () => clearInterval(timeoutId);
22342
- }, [absoluteFormat, date, locale]);
22564
+ }, [absoluteFormat, date, locale, is24HourFormat, timeZone]);
22343
22565
  return {
22344
22566
  absolute: dateAndTimeStrings.absolute,
22345
22567
  relative: dateAndTimeStrings.relative
@@ -22901,6 +23123,7 @@ export {
22901
23123
  useComboboxContext,
22902
23124
  useControlledState,
22903
23125
  useCreateForm,
23126
+ useDateTimeFormat,
22904
23127
  useDelay,
22905
23128
  useDialogContext,
22906
23129
  useDrawerContext,
@@ -22948,6 +23171,7 @@ export {
22948
23171
  useTableStateContext,
22949
23172
  useTableStateWithoutSizingContext,
22950
23173
  useTheme,
23174
+ useTimeZone,
22951
23175
  useTooltip,
22952
23176
  useTransitionState,
22953
23177
  useTranslatedValidators,