@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.js CHANGED
@@ -7129,6 +7129,7 @@ __export(index_exports, {
7129
7129
  useComboboxContext: () => useComboboxContext,
7130
7130
  useControlledState: () => useControlledState,
7131
7131
  useCreateForm: () => useCreateForm,
7132
+ useDateTimeFormat: () => useDateTimeFormat,
7132
7133
  useDelay: () => useDelay,
7133
7134
  useDialogContext: () => useDialogContext,
7134
7135
  useDrawerContext: () => useDrawerContext,
@@ -7176,6 +7177,7 @@ __export(index_exports, {
7176
7177
  useTableStateContext: () => useTableStateContext,
7177
7178
  useTableStateWithoutSizingContext: () => useTableStateWithoutSizingContext,
7178
7179
  useTheme: () => useTheme,
7180
+ useTimeZone: () => useTimeZone,
7179
7181
  useTooltip: () => useTooltip,
7180
7182
  useTransitionState: () => useTransitionState,
7181
7183
  useTranslatedValidators: () => useTranslatedValidators,
@@ -9444,13 +9446,29 @@ var LocaleProvider = ({
9444
9446
  children,
9445
9447
  locale,
9446
9448
  defaultLocale,
9447
- onChangedLocale
9449
+ defaultTimeZone,
9450
+ defaultIs24HourFormat,
9451
+ timeZone,
9452
+ is24HourFormat,
9453
+ onChangedLocale,
9454
+ onChangedTimeZone,
9455
+ onChangedIs24HourFormat
9448
9456
  }) => {
9449
9457
  const {
9450
9458
  value: storedLocale,
9451
9459
  setValue: setStoredLocale,
9452
9460
  deleteValue: deleteStoredLocale
9453
9461
  } = useStorage({ key: "locale", defaultValue: "system" });
9462
+ const {
9463
+ value: storedTimeZone,
9464
+ setValue: setStoredTimeZone,
9465
+ deleteValue: deleteStoredTimeZone
9466
+ } = useStorage({ key: "timeZone", defaultValue: void 0 });
9467
+ const {
9468
+ value: storedIs24HourFormat,
9469
+ setValue: setStoredIs24HourFormat,
9470
+ deleteValue: deleteStoredIs24HourFormat
9471
+ } = useStorage({ key: "is24HourFormat", defaultValue: void 0 });
9454
9472
  const { config } = useHightideConfig();
9455
9473
  const [localePreference, setLocalePreference] = (0, import_react8.useState)("system");
9456
9474
  const resolvedLocale = (0, import_react8.useMemo)(() => {
@@ -9473,10 +9491,32 @@ var LocaleProvider = ({
9473
9491
  setStoredLocale(locale);
9474
9492
  }
9475
9493
  }, [locale, deleteStoredLocale, setStoredLocale]);
9494
+ const resolvedTimeZone = (0, import_react8.useMemo)(() => {
9495
+ return timeZone ?? storedTimeZone ?? config.locale.defaultTimeZone ?? defaultTimeZone;
9496
+ }, [timeZone, storedTimeZone, config.locale.defaultTimeZone, defaultTimeZone]);
9497
+ (0, import_react8.useEffect)(() => {
9498
+ if (timeZone === void 0) return;
9499
+ setStoredTimeZone(timeZone);
9500
+ }, [timeZone, setStoredTimeZone]);
9501
+ const resolvedIs24HourFormat = (0, import_react8.useMemo)(() => {
9502
+ return is24HourFormat ?? storedIs24HourFormat ?? config.locale.defaultIs24HourFormat ?? defaultIs24HourFormat ?? true;
9503
+ }, [is24HourFormat, storedIs24HourFormat, config.locale.defaultIs24HourFormat, defaultIs24HourFormat]);
9504
+ (0, import_react8.useEffect)(() => {
9505
+ if (is24HourFormat === void 0) return;
9506
+ setStoredIs24HourFormat(is24HourFormat);
9507
+ }, [is24HourFormat, setStoredIs24HourFormat]);
9476
9508
  const onChangeRef = useEventCallbackStabilizer(onChangedLocale);
9477
9509
  (0, import_react8.useEffect)(() => {
9478
9510
  onChangeRef?.(resolvedLocale);
9479
9511
  }, [resolvedLocale, onChangeRef]);
9512
+ const onChangeTimeZoneRef = useEventCallbackStabilizer(onChangedTimeZone);
9513
+ (0, import_react8.useEffect)(() => {
9514
+ onChangeTimeZoneRef?.(resolvedTimeZone);
9515
+ }, [resolvedTimeZone, onChangeTimeZoneRef]);
9516
+ const onChangeIs24HourFormatRef = useEventCallbackStabilizer(onChangedIs24HourFormat);
9517
+ (0, import_react8.useEffect)(() => {
9518
+ onChangeIs24HourFormatRef?.(resolvedIs24HourFormat);
9519
+ }, [resolvedIs24HourFormat, onChangeIs24HourFormatRef]);
9480
9520
  (0, import_react8.useEffect)(() => {
9481
9521
  const localesToTestAgainst = Object.values(LocalizationUtil.locals);
9482
9522
  const detectLanguage = () => {
@@ -9500,6 +9540,30 @@ var LocaleProvider = ({
9500
9540
  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.");
9501
9541
  }
9502
9542
  setStoredLocale(newLocale);
9543
+ },
9544
+ timeZone: resolvedTimeZone,
9545
+ setTimeZone: (newTimeZone) => {
9546
+ if (timeZone !== void 0) {
9547
+ 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.");
9548
+ return;
9549
+ }
9550
+ if (newTimeZone === void 0) {
9551
+ deleteStoredTimeZone();
9552
+ } else {
9553
+ setStoredTimeZone(newTimeZone);
9554
+ }
9555
+ },
9556
+ is24HourFormat: resolvedIs24HourFormat,
9557
+ setIs24HourFormat: (newIs24HourFormat) => {
9558
+ if (is24HourFormat !== void 0) {
9559
+ 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.");
9560
+ return;
9561
+ }
9562
+ if (newIs24HourFormat === void 0) {
9563
+ deleteStoredIs24HourFormat();
9564
+ } else {
9565
+ setStoredIs24HourFormat(newIs24HourFormat);
9566
+ }
9503
9567
  }
9504
9568
  }, children });
9505
9569
  };
@@ -9510,6 +9574,20 @@ var useLocale = () => {
9510
9574
  }
9511
9575
  return context;
9512
9576
  };
9577
+ var useTimeZone = () => {
9578
+ const context = (0, import_react8.useContext)(LocaleContext);
9579
+ if (!context) {
9580
+ throw new Error("useTimeZone must be used within LocaleContext. Try adding a LocaleProvider around your app.");
9581
+ }
9582
+ return { timeZone: context.timeZone, setTimeZone: context.setTimeZone };
9583
+ };
9584
+ var useDateTimeFormat = () => {
9585
+ const context = (0, import_react8.useContext)(LocaleContext);
9586
+ return {
9587
+ is24HourFormat: context?.is24HourFormat ?? true,
9588
+ timeZone: context?.timeZone
9589
+ };
9590
+ };
9513
9591
  var useLanguage = () => {
9514
9592
  const context = (0, import_react8.useContext)(LocaleContext);
9515
9593
  if (!context) {
@@ -10275,9 +10353,11 @@ var SelectButton = (0, import_react21.forwardRef)(
10275
10353
  return () => unregister();
10276
10354
  }, [registerTrigger]);
10277
10355
  const disabled = !!disabledOverride || !!context.disabled;
10356
+ const readOnly = !!context.readOnly;
10278
10357
  const invalid = context.invalid;
10279
10358
  const hasValue = context.selectedId !== null;
10280
- const selectedOption = context.idToOptionMap[context.selectedId] ?? null;
10359
+ const hasInteractions = !readOnly && !disabled;
10360
+ const selectedOption = context.selectedId ? context.idToOptionMap[context.selectedId] ?? null : null;
10281
10361
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
10282
10362
  "div",
10283
10363
  {
@@ -10285,12 +10365,13 @@ var SelectButton = (0, import_react21.forwardRef)(
10285
10365
  ref: innerRef,
10286
10366
  id: context.config.ids.trigger,
10287
10367
  onClick: (event) => {
10368
+ if (!hasInteractions) return;
10288
10369
  props.onClick?.(event);
10289
10370
  context.toggleIsOpen();
10290
10371
  },
10291
10372
  onKeyDown: (event) => {
10292
10373
  props.onKeyDown?.(event);
10293
- if (disabled) return;
10374
+ if (!hasInteractions) return;
10294
10375
  switch (event.key) {
10295
10376
  case "Enter":
10296
10377
  case " ":
@@ -10313,16 +10394,18 @@ var SelectButton = (0, import_react21.forwardRef)(
10313
10394
  "data-name": props["data-name"] ?? "select-button",
10314
10395
  "data-value": hasValue ? "" : void 0,
10315
10396
  "data-disabled": disabled ? "" : void 0,
10397
+ "data-readonly": readOnly ? "" : void 0,
10316
10398
  "data-invalid": invalid ? "" : void 0,
10317
10399
  tabIndex: disabled ? -1 : 0,
10318
10400
  role: "button",
10319
10401
  "aria-invalid": invalid,
10320
10402
  "aria-disabled": disabled,
10403
+ "aria-readonly": readOnly,
10321
10404
  "aria-haspopup": "dialog",
10322
10405
  "aria-expanded": context.isOpen,
10323
10406
  "aria-controls": context.isOpen ? context.config.ids.content : void 0,
10324
10407
  children: [
10325
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SelectOptionDisplayContext.Provider, { value: "trigger", children: hasValue ? selectedDisplay?.(selectedOption) ?? selectedOption.display : placeholder ?? translation("clickToSelect") }),
10408
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SelectOptionDisplayContext.Provider, { value: "trigger", children: hasValue ? selectedDisplay?.(selectedOption) ?? selectedOption?.display : placeholder ?? translation("clickToSelect") }),
10326
10409
  !hideExpansionIcon && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ExpansionIcon, { isExpanded: context.isOpen })
10327
10410
  ]
10328
10411
  }
@@ -15682,9 +15765,7 @@ var timesInSeconds = {
15682
15765
  day: 86400,
15683
15766
  week: 604800,
15684
15767
  monthImprecise: 2629800,
15685
- // 30.4375 days
15686
15768
  yearImprecise: 31557600
15687
- // 365.25 days
15688
15769
  };
15689
15770
  var monthsList = ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"];
15690
15771
  var weekDayList = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
@@ -15787,6 +15868,73 @@ var withTime = (datePart, timePart) => {
15787
15868
  );
15788
15869
  return out;
15789
15870
  };
15871
+ var zonedPartsFormatterCache = /* @__PURE__ */ new Map();
15872
+ var zonedPartsFormatter = (timeZone) => {
15873
+ let formatter = zonedPartsFormatterCache.get(timeZone);
15874
+ if (!formatter) {
15875
+ formatter = new Intl.DateTimeFormat("en-US", {
15876
+ timeZone,
15877
+ hourCycle: "h23",
15878
+ year: "numeric",
15879
+ month: "2-digit",
15880
+ day: "2-digit",
15881
+ hour: "2-digit",
15882
+ minute: "2-digit",
15883
+ second: "2-digit"
15884
+ });
15885
+ zonedPartsFormatterCache.set(timeZone, formatter);
15886
+ }
15887
+ return formatter;
15888
+ };
15889
+ var zonedParts = (date, timeZone) => {
15890
+ const parts = {};
15891
+ for (const part of zonedPartsFormatter(timeZone).formatToParts(date)) {
15892
+ if (part.type !== "literal") {
15893
+ parts[part.type] = part.value;
15894
+ }
15895
+ }
15896
+ return {
15897
+ year: Number(parts.year),
15898
+ month: Number(parts.month),
15899
+ day: Number(parts.day),
15900
+ hour: Number(parts.hour) % 24,
15901
+ minute: Number(parts.minute),
15902
+ second: Number(parts.second),
15903
+ millisecond: date.getMilliseconds()
15904
+ };
15905
+ };
15906
+ var zoneOffsetMs = (date, timeZone) => {
15907
+ const parts = zonedParts(date, timeZone);
15908
+ const asUtc = Date.UTC(parts.year, parts.month - 1, parts.day, parts.hour, parts.minute, parts.second, parts.millisecond);
15909
+ return asUtc - date.getTime();
15910
+ };
15911
+ function toZonedDate(date, timeZone) {
15912
+ if (!date || !timeZone) {
15913
+ return date;
15914
+ }
15915
+ const parts = zonedParts(date, timeZone);
15916
+ return new Date(parts.year, parts.month - 1, parts.day, parts.hour, parts.minute, parts.second, parts.millisecond);
15917
+ }
15918
+ function fromZonedDate(date, timeZone) {
15919
+ if (!date || !timeZone) {
15920
+ return date;
15921
+ }
15922
+ const asUtc = Date.UTC(
15923
+ date.getFullYear(),
15924
+ date.getMonth(),
15925
+ date.getDate(),
15926
+ date.getHours(),
15927
+ date.getMinutes(),
15928
+ date.getSeconds(),
15929
+ date.getMilliseconds()
15930
+ );
15931
+ let offset = zoneOffsetMs(new Date(asUtc), timeZone);
15932
+ const refined = zoneOffsetMs(new Date(asUtc - offset), timeZone);
15933
+ if (refined !== offset) {
15934
+ offset = refined;
15935
+ }
15936
+ return new Date(asUtc - offset);
15937
+ }
15790
15938
  var weeksForCalenderMonth = (date, weekStart, weeks = 6) => {
15791
15939
  const month = date.getMonth();
15792
15940
  const year = date.getFullYear();
@@ -15804,8 +15952,13 @@ var weeksForCalenderMonth = (date, weekStart, weeks = 6) => {
15804
15952
  }
15805
15953
  return equalSizeGroups(dayList, 7);
15806
15954
  };
15807
- var formatAbsolute = (date, locale, format) => {
15955
+ var formatAbsolute = (date, locale, format, { timeZone, is24HourFormat = true } = {}) => {
15808
15956
  let options;
15957
+ const timeOptions = {
15958
+ hour: "2-digit",
15959
+ minute: "2-digit",
15960
+ hourCycle: is24HourFormat ? "h23" : "h12"
15961
+ };
15809
15962
  switch (format) {
15810
15963
  case "date":
15811
15964
  options = {
@@ -15816,8 +15969,7 @@ var formatAbsolute = (date, locale, format) => {
15816
15969
  break;
15817
15970
  case "time":
15818
15971
  options = {
15819
- hour: "2-digit",
15820
- minute: "2-digit"
15972
+ ...timeOptions
15821
15973
  };
15822
15974
  break;
15823
15975
  case "dateTime":
@@ -15825,12 +15977,11 @@ var formatAbsolute = (date, locale, format) => {
15825
15977
  year: "numeric",
15826
15978
  month: "2-digit",
15827
15979
  day: "2-digit",
15828
- hour: "2-digit",
15829
- minute: "2-digit"
15980
+ ...timeOptions
15830
15981
  };
15831
15982
  break;
15832
15983
  }
15833
- return new Intl.DateTimeFormat(locale, options).format(date);
15984
+ return new Intl.DateTimeFormat(locale, { ...options, timeZone }).format(date);
15834
15985
  };
15835
15986
  var formatRelative = (date, locale) => {
15836
15987
  const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
@@ -15907,6 +16058,9 @@ var DateUtils = {
15907
16058
  daysInMonth,
15908
16059
  sameTime,
15909
16060
  withTime,
16061
+ zonedParts,
16062
+ toZonedDate,
16063
+ fromZonedDate,
15910
16064
  formatAbsolute,
15911
16065
  formatRelative,
15912
16066
  addDuration,
@@ -15917,9 +16071,6 @@ var DateUtils = {
15917
16071
  toInputString,
15918
16072
  tryParseDate,
15919
16073
  toOnlyDate: normalizeToDateOnly,
15920
- /**
15921
- * Normalizes a datetime by removing seconds and milliseconds.
15922
- */
15923
16074
  toDateTimeOnly: normalizeDatetime
15924
16075
  };
15925
16076
 
@@ -16786,13 +16937,15 @@ var TimePicker = ({
16786
16937
  initialValue = /* @__PURE__ */ new Date(),
16787
16938
  onValueChange,
16788
16939
  onEditComplete,
16789
- is24HourFormat = true,
16940
+ is24HourFormat: is24HourFormatOverride,
16790
16941
  minuteIncrement = "5min",
16791
16942
  secondIncrement = "5s",
16792
16943
  millisecondIncrement = "100ms",
16793
16944
  precision = "minute",
16794
16945
  className
16795
16946
  }) => {
16947
+ const { is24HourFormat: contextIs24HourFormat } = useDateTimeFormat();
16948
+ const is24HourFormat = is24HourFormatOverride ?? contextIs24HourFormat;
16796
16949
  const [value, setValue] = useControlledState({
16797
16950
  value: controlledValue,
16798
16951
  onValueChange,
@@ -17789,19 +17942,14 @@ var DateTimeField = (0, import_react79.forwardRef)(function DateTimeField2({
17789
17942
  ...props
17790
17943
  }, forwardedRef) {
17791
17944
  const translation = useHightideTranslation();
17792
- const { locale: contextLocale } = useLocale();
17945
+ const { locale: contextLocale, is24HourFormat: contextIs24HourFormat } = useLocale();
17793
17946
  const locale = localeOverride ?? contextLocale;
17794
17947
  const [value, setValue] = useControlledState({
17795
17948
  value: controlledValue,
17796
17949
  onValueChange,
17797
17950
  defaultValue: initialValue
17798
17951
  });
17799
- const is24Hour = (0, import_react79.useMemo)(() => {
17800
- if (is24HourFormat !== void 0) {
17801
- return is24HourFormat;
17802
- }
17803
- return !new Intl.DateTimeFormat(locale, { hour: "numeric" }).resolvedOptions().hour12;
17804
- }, [is24HourFormat, locale]);
17952
+ const is24Hour = is24HourFormat ?? contextIs24HourFormat ?? true;
17805
17953
  const layout = (0, import_react79.useMemo)(
17806
17954
  () => buildSegmentLayout({ locale, mode, precision, is24HourFormat: is24Hour }),
17807
17955
  [locale, mode, precision, is24Hour]
@@ -17832,6 +17980,9 @@ var DateTimeField = (0, import_react79.forwardRef)(function DateTimeField2({
17832
17980
  return callback;
17833
17981
  };
17834
17982
  (0, import_react79.useEffect)(() => {
17983
+ if (editStateRef.current.buffer) {
17984
+ return;
17985
+ }
17835
17986
  const shown = composeDate(editStateRef.current.values, layout, mode, is24Hour, value ?? void 0);
17836
17987
  if ((shown?.getTime() ?? null) === (value?.getTime() ?? null)) {
17837
17988
  return;
@@ -17843,6 +17994,9 @@ var DateTimeField = (0, import_react79.forwardRef)(function DateTimeField2({
17843
17994
  }, [value, layout, mode, is24Hour]);
17844
17995
  const apply = (next) => {
17845
17996
  setEditState(next);
17997
+ if (next.buffer?.type === "year") {
17998
+ return;
17999
+ }
17846
18000
  const composed = composeDate(next.values, layout, mode, is24Hour, value ?? void 0);
17847
18001
  if (composed) {
17848
18002
  setValue(composed);
@@ -17939,6 +18093,10 @@ var DateTimeField = (0, import_react79.forwardRef)(function DateTimeField2({
17939
18093
  const onFieldBlur = (event) => {
17940
18094
  props.onBlur?.(event);
17941
18095
  const field = event.currentTarget;
18096
+ const nextFocus = event.relatedTarget;
18097
+ if (nextFocus instanceof Node && field.contains(nextFocus)) {
18098
+ return;
18099
+ }
17942
18100
  requestAnimationFrame(() => {
17943
18101
  if (field.contains(document.activeElement)) {
17944
18102
  return;
@@ -17947,6 +18105,9 @@ var DateTimeField = (0, import_react79.forwardRef)(function DateTimeField2({
17947
18105
  const composed = composeDate(editStateRef.current.values, layout, mode, is24Hour, value ?? void 0);
17948
18106
  if (composed) {
17949
18107
  setEditState({ values: decomposeDate(composed, layout, is24Hour), buffer: null });
18108
+ if (composed.getTime() !== (value?.getTime() ?? null)) {
18109
+ setValue(composed);
18110
+ }
17950
18111
  onEditComplete?.(composed);
17951
18112
  } else {
17952
18113
  onEditComplete?.(value ?? null);
@@ -18021,6 +18182,7 @@ var DateTimeInput = (0, import_react80.forwardRef)(function DateTimeInput2({
18021
18182
  allowClear = true,
18022
18183
  containerProps,
18023
18184
  mode = "date",
18185
+ timeZone: timeZoneOverride,
18024
18186
  precision = "minute",
18025
18187
  pickerProps,
18026
18188
  outsideClickCloses = true,
@@ -18041,6 +18203,8 @@ var DateTimeInput = (0, import_react80.forwardRef)(function DateTimeInput2({
18041
18203
  ...props
18042
18204
  }, forwardedRef) {
18043
18205
  const translation = useHightideTranslation();
18206
+ const { timeZone: contextTimeZone } = useLocale();
18207
+ const timeZone = timeZoneOverride ?? contextTimeZone;
18044
18208
  const [isOpen, setIsOpen] = (0, import_react80.useState)(false);
18045
18209
  const [state, setState] = useControlledState({
18046
18210
  value,
@@ -18052,6 +18216,8 @@ var DateTimeInput = (0, import_react80.forwardRef)(function DateTimeInput2({
18052
18216
  onDialogOpeningChange?.(isOpen2);
18053
18217
  setIsOpen(isOpen2);
18054
18218
  }, [onDialogOpeningChange]);
18219
+ const toZoned = (0, import_react80.useCallback)((date) => DateUtils.toZonedDate(date, timeZone), [timeZone]);
18220
+ const fromZoned = (0, import_react80.useCallback)((date) => DateUtils.fromZonedDate(date, timeZone), [timeZone]);
18055
18221
  const generatedId = (0, import_react80.useId)();
18056
18222
  const ids = (0, import_react80.useMemo)(() => ({
18057
18223
  input: inputId ?? `date-time-input-${generatedId}`,
@@ -18098,7 +18264,7 @@ var DateTimeInput = (0, import_react80.forwardRef)(function DateTimeInput2({
18098
18264
  DateTimeField,
18099
18265
  {
18100
18266
  ref: fieldRef,
18101
- value: state,
18267
+ value: toZoned(state),
18102
18268
  mode,
18103
18269
  precision,
18104
18270
  is24HourFormat,
@@ -18106,8 +18272,8 @@ var DateTimeInput = (0, import_react80.forwardRef)(function DateTimeInput2({
18106
18272
  readOnly,
18107
18273
  invalid,
18108
18274
  required,
18109
- onValueChange: setState,
18110
- onEditComplete,
18275
+ onValueChange: (next) => setState(fromZoned(next)),
18276
+ onEditComplete: (next) => onEditComplete?.(fromZoned(next)),
18111
18277
  "aria-labelledby": props["aria-labelledby"],
18112
18278
  "aria-describedby": props["aria-describedby"],
18113
18279
  className: "grow"
@@ -18172,18 +18338,19 @@ var DateTimeInput = (0, import_react80.forwardRef)(function DateTimeInput2({
18172
18338
  children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
18173
18339
  DateTimePickerDialog,
18174
18340
  {
18175
- value: dialogValue,
18341
+ value: toZoned(dialogValue),
18176
18342
  allowRemove,
18177
- onValueChange: setDialogValue,
18343
+ onValueChange: (value2) => setDialogValue(fromZoned(value2)),
18178
18344
  onEditComplete: (value2) => {
18179
- setState(value2);
18180
- onEditComplete?.(value2);
18345
+ const absolute = fromZoned(value2);
18346
+ setState(absolute);
18347
+ onEditComplete?.(absolute);
18181
18348
  changeOpenWrapper(false);
18182
18349
  },
18183
18350
  pickerProps,
18184
18351
  mode,
18185
- start,
18186
- end,
18352
+ start: toZoned(start ?? null) ?? void 0,
18353
+ end: toZoned(end ?? null) ?? void 0,
18187
18354
  weekStart,
18188
18355
  markToday,
18189
18356
  is24HourFormat,
@@ -18705,8 +18872,10 @@ var MultiSelectButton = (0, import_react86.forwardRef)(function MultiSelectButto
18705
18872
  return () => unregister();
18706
18873
  }, [registerTrigger]);
18707
18874
  const disabled = !!disabledOverride || !!context.disabled;
18875
+ const readOnly = !!context.readOnly;
18708
18876
  const invalid = context.invalid;
18709
18877
  const hasValue = context.value.length > 0;
18878
+ const hasInteractions = !readOnly && !disabled;
18710
18879
  const selectedOptions = context.selectedIds.map((id2) => context.idToOptionMap[id2]).filter(Boolean);
18711
18880
  return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
18712
18881
  "div",
@@ -18715,12 +18884,13 @@ var MultiSelectButton = (0, import_react86.forwardRef)(function MultiSelectButto
18715
18884
  ref: innerRef,
18716
18885
  id: context.config.ids.trigger,
18717
18886
  onClick: (event) => {
18887
+ if (!hasInteractions) return;
18718
18888
  props.onClick?.(event);
18719
18889
  context.toggleIsOpen();
18720
18890
  },
18721
18891
  onKeyDown: (event) => {
18722
18892
  props.onKeyDown?.(event);
18723
- if (disabled) return;
18893
+ if (!hasInteractions) return;
18724
18894
  switch (event.key) {
18725
18895
  case "Enter":
18726
18896
  case " ":
@@ -18743,11 +18913,13 @@ var MultiSelectButton = (0, import_react86.forwardRef)(function MultiSelectButto
18743
18913
  "data-name": props["data-name"] ?? "multi-select-button",
18744
18914
  "data-value": hasValue ? "" : void 0,
18745
18915
  "data-disabled": disabled ? "" : void 0,
18916
+ "data-readonly": readOnly ? "" : void 0,
18746
18917
  "data-invalid": invalid ? "" : void 0,
18747
18918
  tabIndex: disabled ? -1 : 0,
18748
18919
  role: "button",
18749
18920
  "aria-invalid": invalid,
18750
18921
  "aria-disabled": disabled,
18922
+ "aria-readonly": readOnly,
18751
18923
  "aria-haspopup": "dialog",
18752
18924
  "aria-expanded": context.isOpen,
18753
18925
  "aria-controls": context.isOpen ? context.config.ids.content : void 0,
@@ -21026,7 +21198,9 @@ var MultiSelectChipDisplayButton = (0, import_react105.forwardRef)(function Mult
21026
21198
  return () => unregister();
21027
21199
  }, [registerTrigger]);
21028
21200
  const disabled = !!props?.disabled || !!context.disabled;
21201
+ const readOnly = !!context.readOnly;
21029
21202
  const invalid = context.invalid;
21203
+ const hasInteractions = !readOnly && !disabled;
21030
21204
  const selectedOptions = context.selectedIds.map((oid) => context.idToOptionMap[oid]).filter(Boolean);
21031
21205
  return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(
21032
21206
  "div",
@@ -21036,14 +21210,17 @@ var MultiSelectChipDisplayButton = (0, import_react105.forwardRef)(function Mult
21036
21210
  onClick: (event) => {
21037
21211
  props.onClick?.(event);
21038
21212
  if (event.defaultPrevented) return;
21213
+ if (!hasInteractions) return;
21039
21214
  context.toggleIsOpen();
21040
21215
  },
21041
21216
  "data-name": props["data-name"] ?? "multi-select-chip-display-button",
21042
21217
  "data-value": context.value.length > 0 ? "" : void 0,
21043
21218
  "data-disabled": disabled ? "" : void 0,
21219
+ "data-readonly": readOnly ? "" : void 0,
21044
21220
  "data-invalid": invalid ? "" : void 0,
21045
21221
  "aria-invalid": invalid,
21046
21222
  "aria-disabled": disabled,
21223
+ "aria-readonly": readOnly,
21047
21224
  children: [
21048
21225
  selectedOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { "data-name": "multi-select-chip-display-chip", children: [
21049
21226
  opt.display,
@@ -21051,6 +21228,7 @@ var MultiSelectChipDisplayButton = (0, import_react105.forwardRef)(function Mult
21051
21228
  IconButton,
21052
21229
  {
21053
21230
  tooltip: translation("remove"),
21231
+ disabled: !hasInteractions,
21054
21232
  onClick: (e) => {
21055
21233
  context.toggleSelection(opt.id, false);
21056
21234
  e.preventDefault();
@@ -21067,11 +21245,14 @@ var MultiSelectChipDisplayButton = (0, import_react105.forwardRef)(function Mult
21067
21245
  IconButton,
21068
21246
  {
21069
21247
  id: context.config.ids.trigger,
21248
+ disabled: !hasInteractions,
21070
21249
  onClick: (event) => {
21071
21250
  event.stopPropagation();
21251
+ if (!hasInteractions) return;
21072
21252
  context.toggleIsOpen();
21073
21253
  },
21074
21254
  onKeyDown: (event) => {
21255
+ if (!hasInteractions) return;
21075
21256
  switch (event.key) {
21076
21257
  case "ArrowDown":
21077
21258
  context.setIsOpen(true, "first");
@@ -21711,10 +21892,18 @@ var SortingList = ({ sorting, onSortingChange, availableItems }) => {
21711
21892
  var import_jsx_runtime104 = require("react/jsx-runtime");
21712
21893
  var TimeDisplay = ({
21713
21894
  date,
21714
- mode = "daysFromToday"
21895
+ mode = "daysFromToday",
21896
+ is24HourFormat: is24HourFormatOverride,
21897
+ timeZone: timeZoneOverride
21715
21898
  }) => {
21716
21899
  const translation = useHightideTranslation();
21717
- const difference = (/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0).valueOf() - new Date(date).setHours(0, 0, 0, 0).valueOf();
21900
+ const { locale } = useLocale();
21901
+ const { is24HourFormat: contextIs24HourFormat, timeZone: contextTimeZone } = useDateTimeFormat();
21902
+ const is24HourFormat = is24HourFormatOverride ?? contextIs24HourFormat;
21903
+ const timeZone = timeZoneOverride ?? contextTimeZone;
21904
+ const zonedDate = DateUtils.toZonedDate(date, timeZone);
21905
+ const zonedNow = DateUtils.toZonedDate(/* @__PURE__ */ new Date(), timeZone);
21906
+ const difference = new Date(zonedNow).setHours(0, 0, 0, 0).valueOf() - new Date(zonedDate).setHours(0, 0, 0, 0).valueOf();
21718
21907
  const isBefore = difference > 0;
21719
21908
  const differenceInDays = Math.floor(Math.abs(difference) / (1e3 * 3600 * 24));
21720
21909
  let displayString;
@@ -21741,9 +21930,15 @@ var TimeDisplay = ({
21741
21930
  };
21742
21931
  let fullString;
21743
21932
  if (mode === "daysFromToday") {
21744
- fullString = `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")} - ${displayString}`;
21933
+ const timeString = new Intl.DateTimeFormat(locale, {
21934
+ hour: "2-digit",
21935
+ minute: "2-digit",
21936
+ hourCycle: is24HourFormat ? "h23" : "h12",
21937
+ timeZone
21938
+ }).format(date);
21939
+ fullString = `${timeString} - ${displayString}`;
21745
21940
  } else {
21746
- fullString = `${date.getDate()}. ${monthToTranslation[date.getMonth()]} ${date.getFullYear()}`;
21941
+ fullString = `${zonedDate.getDate()}. ${monthToTranslation[zonedDate.getMonth()]} ${zonedDate.getFullYear()}`;
21747
21942
  }
21748
21943
  return /* @__PURE__ */ (0, import_jsx_runtime104.jsx)("span", { children: fullString });
21749
21944
  };
@@ -21758,29 +21953,36 @@ var FlexibleDateTimeInput = (0, import_react111.forwardRef)(function FlexibleDat
21758
21953
  initialValue,
21759
21954
  onValueChange,
21760
21955
  fixedTime: fixedTimeOverride,
21956
+ timeZone: timeZoneOverride,
21761
21957
  actions = [],
21762
21958
  ...props
21763
21959
  }, forwardedRef) {
21764
21960
  const translation = useHightideTranslation();
21961
+ const { timeZone: contextTimeZone } = useLocale();
21962
+ const timeZone = timeZoneOverride ?? contextTimeZone;
21765
21963
  const fixedTime = fixedTimeOverride ?? new Date(1970, 0, 1, 23, 59, 59, 999);
21766
21964
  const [value, setValue] = useControlledState({
21767
21965
  value: controlledValue,
21768
21966
  onValueChange,
21769
21967
  defaultValue: initialValue
21770
21968
  });
21969
+ const zoned = (date) => DateUtils.toZonedDate(date, timeZone);
21970
+ const unzoned = (date) => DateUtils.fromZonedDate(date, timeZone);
21971
+ const hasFixedTime = (date) => DateUtils.sameTime(zoned(date), fixedTime, true, true);
21771
21972
  const [mode, setMode] = (0, import_react111.useState)(() => {
21772
- if (value && !DateUtils.sameTime(value, fixedTime, true, true)) {
21973
+ if (value && !hasFixedTime(value)) {
21773
21974
  return "dateTime";
21774
21975
  }
21775
21976
  return defaultMode;
21776
21977
  });
21777
- const toDate = (date) => DateUtils.withTime(date, fixedTime);
21778
- const toDateTime = (date) => DateUtils.sameTime(date, fixedTime, true, true) ? DateUtils.withTime(date, /* @__PURE__ */ new Date()) : date;
21978
+ const toDate = (date) => unzoned(DateUtils.withTime(zoned(date), fixedTime));
21979
+ const toDateTime = (date) => hasFixedTime(date) ? unzoned(DateUtils.withTime(zoned(date), zoned(/* @__PURE__ */ new Date()))) : date;
21779
21980
  return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
21780
21981
  DateTimeInput,
21781
21982
  {
21782
21983
  ...props,
21783
21984
  ref: forwardedRef,
21985
+ timeZone,
21784
21986
  mode,
21785
21987
  value,
21786
21988
  onValueChange: (next) => {
@@ -22119,26 +22321,46 @@ var CheckboxProperty = ({
22119
22321
  var import_lucide_react35 = require("lucide-react");
22120
22322
  var import_jsx_runtime111 = require("react/jsx-runtime");
22121
22323
  var DateProperty = ({
22324
+ name,
22122
22325
  value,
22123
22326
  onValueChange,
22124
22327
  onEditComplete,
22328
+ onRemove,
22329
+ onValueClear,
22330
+ required,
22125
22331
  readOnly,
22332
+ allowClear = true,
22333
+ allowRemove = true,
22126
22334
  type = "dateTime",
22127
- ...baseProps
22335
+ className,
22336
+ ...inputProps
22128
22337
  }) => {
22129
22338
  const hasValue = !!value;
22130
22339
  return /* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
22131
22340
  PropertyBase,
22132
22341
  {
22133
- ...baseProps,
22342
+ name,
22343
+ required,
22344
+ readOnly,
22345
+ allowClear,
22346
+ allowRemove,
22347
+ onRemove,
22348
+ onValueClear: onValueClear ?? (() => {
22349
+ onValueChange?.(null);
22350
+ onEditComplete?.(null);
22351
+ }),
22134
22352
  hasValue,
22135
22353
  icon: /* @__PURE__ */ (0, import_jsx_runtime111.jsx)(import_lucide_react35.CalendarDays, { size: 24 }),
22354
+ className,
22136
22355
  children: ({ invalid }) => /* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
22137
22356
  DateTimeInput,
22138
22357
  {
22358
+ ...inputProps,
22139
22359
  value,
22140
22360
  mode: type,
22361
+ required,
22141
22362
  readOnly,
22363
+ allowClear: false,
22142
22364
  onValueChange,
22143
22365
  onEditComplete,
22144
22366
  "data-name": "property-input",
@@ -22560,21 +22782,23 @@ var useRerender = () => {
22560
22782
 
22561
22783
  // src/hooks/useUpdatingDateString.ts
22562
22784
  var import_react124 = require("react");
22563
- var useUpdatingDateString = ({ absoluteFormat = "dateTime", localeOverride, date }) => {
22564
- const { locale: contextLocale } = useLocale();
22785
+ var useUpdatingDateString = ({ absoluteFormat = "dateTime", localeOverride, is24HourFormat: is24HourFormatOverride, timeZone: timeZoneOverride, date }) => {
22786
+ const { locale: contextLocale, is24HourFormat: contextIs24HourFormat, timeZone: contextTimeZone } = useLocale();
22565
22787
  const locale = localeOverride ?? contextLocale;
22788
+ const is24HourFormat = is24HourFormatOverride ?? contextIs24HourFormat ?? true;
22789
+ const timeZone = timeZoneOverride ?? contextTimeZone;
22566
22790
  const [dateAndTimeStrings, setDateAndTimeStrings] = (0, import_react124.useState)({
22567
22791
  compareDate: date,
22568
- absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat),
22792
+ absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat, { is24HourFormat, timeZone }),
22569
22793
  relative: DateUtils.formatRelative(date, locale)
22570
22794
  });
22571
22795
  (0, import_react124.useEffect)(() => {
22572
22796
  setDateAndTimeStrings({
22573
22797
  compareDate: date,
22574
- absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat),
22798
+ absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat, { is24HourFormat, timeZone }),
22575
22799
  relative: DateUtils.formatRelative(date, locale)
22576
22800
  });
22577
- }, [date, absoluteFormat, locale]);
22801
+ }, [date, absoluteFormat, locale, is24HourFormat, timeZone]);
22578
22802
  (0, import_react124.useEffect)(() => {
22579
22803
  let timeoutId;
22580
22804
  const startTimer = () => {
@@ -22591,14 +22815,14 @@ var useUpdatingDateString = ({ absoluteFormat = "dateTime", localeOverride, date
22591
22815
  timeoutId = setInterval(() => {
22592
22816
  setDateAndTimeStrings({
22593
22817
  compareDate: date,
22594
- absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat),
22818
+ absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat, { is24HourFormat, timeZone }),
22595
22819
  relative: DateUtils.formatRelative(date, locale)
22596
22820
  });
22597
22821
  }, delayInSeconds * 1e3 / 2);
22598
22822
  };
22599
22823
  startTimer();
22600
22824
  return () => clearInterval(timeoutId);
22601
- }, [absoluteFormat, date, locale]);
22825
+ }, [absoluteFormat, date, locale, is24HourFormat, timeZone]);
22602
22826
  return {
22603
22827
  absolute: dateAndTimeStrings.absolute,
22604
22828
  relative: dateAndTimeStrings.relative
@@ -23161,6 +23385,7 @@ var PromiseUtils = {
23161
23385
  useComboboxContext,
23162
23386
  useControlledState,
23163
23387
  useCreateForm,
23388
+ useDateTimeFormat,
23164
23389
  useDelay,
23165
23390
  useDialogContext,
23166
23391
  useDrawerContext,
@@ -23208,6 +23433,7 @@ var PromiseUtils = {
23208
23433
  useTableStateContext,
23209
23434
  useTableStateWithoutSizingContext,
23210
23435
  useTheme,
23436
+ useTimeZone,
23211
23437
  useTooltip,
23212
23438
  useTransitionState,
23213
23439
  useTranslatedValidators,