@utahdts/utah-design-system 1.15.5 → 1.16.0

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.
Files changed (33) hide show
  1. package/css/1-settings/_spacing.scss +16 -0
  2. package/css/6-components/_components-index.scss +1 -0
  3. package/css/6-components/base-components/forms/_combo-box-input.scss +5 -0
  4. package/css/6-components/base-components/forms/_time-input.scss +28 -0
  5. package/css/6-components/base-components/navigation/_menu-item.scss +35 -0
  6. package/css/6-components/base-components/navigation/_side-panel-navigation.scss +6 -1
  7. package/css/6-components/base-components/navigation/_vertical-menu.scss +45 -1
  8. package/dist/style.css +297 -9
  9. package/dist/utah-design-system.es.js +434 -86
  10. package/dist/utah-design-system.umd.js +433 -85
  11. package/index.js +2 -0
  12. package/package.json +12 -12
  13. package/react/components/forms/ComboBox/ComboBox.jsx +9 -5
  14. package/react/components/forms/ComboBox/ComboBoxOption.jsx +10 -0
  15. package/react/components/forms/ComboBox/context/ComboBoxContextProvider.jsx +10 -0
  16. package/react/components/forms/ComboBox/internal/CombBoxListBox.jsx +6 -4
  17. package/react/components/forms/ComboBox/internal/ComboBoxTextInput.jsx +11 -1
  18. package/react/components/forms/FormContext/useFormContextInputValue.js +4 -1
  19. package/react/components/forms/MultiSelect/MultiSelect.jsx +6 -0
  20. package/react/components/forms/MultiSelect/MultiSelectComboBox.jsx +6 -0
  21. package/react/components/forms/PlainText.jsx +7 -2
  22. package/react/components/forms/Select.jsx +3 -3
  23. package/react/components/forms/TextArea.jsx +3 -3
  24. package/react/components/forms/TextInput.jsx +3 -3
  25. package/react/components/forms/TimeInput.jsx +166 -0
  26. package/react/components/navigation/HorizontalMenu.jsx +2 -2
  27. package/react/components/navigation/VerticalMenu.jsx +45 -8
  28. package/react/components/navigation/items/MenuItemFlyout.jsx +119 -0
  29. package/react/components/navigation/{MenuItem.jsx → items/MenuItemInline.jsx} +24 -8
  30. package/react/components/navigation/items/MenuItemPlain.jsx +63 -0
  31. package/react/enums/menuTypes.js +7 -0
  32. package/react/hooks/useDebounceFunc.js +1 -1
  33. package/react/hooks/useGlobalKeyEvent.js +1 -1
@@ -23,7 +23,7 @@ var __privateSet = (obj, member, value, setter) => {
23
23
  return value;
24
24
  };
25
25
  var _popupTimeoutId, _noPopupTimeoutId, _isImmediatePopup;
26
- import { getUtahHeaderSettings, setUtahHeaderSettings } from "@utahdts/utah-design-system-header";
26
+ import { childrenMenuTypes, getUtahHeaderSettings, setUtahHeaderSettings } from "@utahdts/utah-design-system-header";
27
27
  import { events, renderDOMSingle } from "@utahdts/utah-design-system-header";
28
28
  import * as React from "react";
29
29
  import React__default, { useRef, useState, useEffect, createContext, useCallback, useContext, useId, useMemo, useLayoutEffect } from "react";
@@ -31,7 +31,7 @@ import { useLocation, NavLink } from "react-router-dom";
31
31
  const name = "@utahdts/utah-design-system";
32
32
  const description = "Utah Design System React Library";
33
33
  const displayName = "Utah Design System React Library";
34
- const version$1 = "1.15.5";
34
+ const version$1 = "1.16.0";
35
35
  const exports = {
36
36
  ".": {
37
37
  "development-local": "./index.js",
@@ -57,7 +57,7 @@ const files = [
57
57
  ];
58
58
  const peerDependencies = {
59
59
  react: "18.x",
60
- "react-router-dom": "6.21.2"
60
+ "react-router-dom": "6.21.3"
61
61
  };
62
62
  const scripts = {
63
63
  build: "vite build",
@@ -94,29 +94,29 @@ const bugs = {
94
94
  };
95
95
  const homepage = "https://github.com/utahdts/utah-design-system";
96
96
  const dependencies = {
97
- "@utahdts/utah-design-system-header": "1.15.5",
97
+ "@utahdts/utah-design-system-header": "1.16.0",
98
98
  "date-fns": "3.3.1",
99
99
  lodash: "4.17.21",
100
100
  "prop-types": "15.8.1",
101
101
  react: "18.x",
102
102
  "react-popper": "2.3.0",
103
- "react-router-dom": "6.21.2",
103
+ "react-router-dom": "6.21.3",
104
104
  "use-immer": "0.9.0",
105
105
  uuid: "9.0.1"
106
106
  };
107
107
  const devDependencies = {
108
108
  "@types/lodash": "4.14.202",
109
- "@types/react": "18.2.48",
109
+ "@types/react": "18.2.79",
110
110
  "@types/react-dom": "18.2.18",
111
- "@types/uuid": "9.0.7",
111
+ "@types/uuid": "9.0.8",
112
112
  "@vitejs/plugin-react": "4.2.1",
113
- "@vitest/coverage-istanbul": "1.2.0",
114
- "@vitest/ui": "1.2.0",
115
- jsdom: "23.2.0",
116
- sass: "1.69.7",
113
+ "@vitest/coverage-istanbul": "1.2.2",
114
+ "@vitest/ui": "1.2.2",
115
+ jsdom: "24.0.0",
116
+ sass: "1.70.0",
117
117
  typescript: "5.3.3",
118
- vite: "5.0.11",
119
- vitest: "1.2.0"
118
+ vite: "5.0.12",
119
+ vitest: "1.2.2"
120
120
  };
121
121
  const type = "module";
122
122
  const packageJson = {
@@ -41771,10 +41771,13 @@ function useFormContextInputValue({
41771
41771
  /** @type {any} */
41772
41772
  onChange ?? (contextOnChange && internalOnChange) ?? setInternalState
41773
41773
  ),
41774
- onClear: (
41775
- /** @type {any} */
41776
- onClear ?? (contextOnChange && internalOnClear)
41777
- ),
41774
+ onClear: () => {
41775
+ (onClear ?? internalOnClear)();
41776
+ setInternalState(
41777
+ /** @type {ValueT} */
41778
+ ""
41779
+ );
41780
+ },
41778
41781
  // direct access to form internals to do whatever you want, though be careful to allow
41779
41782
  // your input's passed in props to trump the form's props
41780
41783
  setState: (
@@ -42493,6 +42496,14 @@ function ComboBoxContextProvider({
42493
42496
  },
42494
42497
  [comboBoxImmer[0].isOptionsExpanded]
42495
42498
  );
42499
+ useEffect(
42500
+ () => {
42501
+ comboBoxImmer[1]((draftContext) => {
42502
+ draftContext.onClear = onClear;
42503
+ });
42504
+ },
42505
+ [onClear]
42506
+ );
42496
42507
  return /* @__PURE__ */ jsxRuntimeExports.jsx(ComboBoxContext.Provider, { value: providerValue, children });
42497
42508
  }
42498
42509
  function useDebounceFunc(func, delay = 1e3) {
@@ -42517,7 +42528,7 @@ function useDebounceFunc(func, delay = 1e3) {
42517
42528
  clearTimeout(timeoutRef.current);
42518
42529
  timeoutRef.current = window.setTimeout(
42519
42530
  () => {
42520
- func(lastVarArgsRef.current);
42531
+ func(...lastVarArgsRef.current || []);
42521
42532
  lastVarArgsRef.current = null;
42522
42533
  lastInvocationRef.current = NaN;
42523
42534
  resolve(varArgs);
@@ -42742,6 +42753,15 @@ function ComboBoxOption({
42742
42753
  },
42743
42754
  [optionValueFocused, value]
42744
42755
  );
42756
+ useEffect(
42757
+ () => {
42758
+ var _a;
42759
+ if (isOptionsExpanded && isSelected) {
42760
+ (_a = optionRef.current) == null ? void 0 : _a.scrollIntoView({ block: "nearest" });
42761
+ }
42762
+ },
42763
+ [isOptionsExpanded, isSelected]
42764
+ );
42745
42765
  return isVisible ? /* @__PURE__ */ jsxRuntimeExports.jsx(
42746
42766
  "li",
42747
42767
  {
@@ -42844,10 +42864,17 @@ function CombBoxListBox({
42844
42864
  ]
42845
42865
  }
42846
42866
  );
42867
+ const lastMessageRef = useRef(
42868
+ /** @type {string | null} */
42869
+ null
42870
+ );
42847
42871
  const addPoliteMessageDebounced = useDebounceFunc(
42848
42872
  useCallback(
42849
42873
  (message2) => {
42850
- addPoliteMessage(message2);
42874
+ if (lastMessageRef.current !== message2) {
42875
+ addPoliteMessage(message2);
42876
+ lastMessageRef.current = message2;
42877
+ }
42851
42878
  },
42852
42879
  [addPoliteMessage]
42853
42880
  ),
@@ -42885,9 +42912,7 @@ function CombBoxListBox({
42885
42912
  if (allowCustomEntry && filterValue && !options.some((option) => option.labelLowerCase === filterValue.toLocaleLowerCase())) {
42886
42913
  message2.push(`Press Enter to add ${filterValue} to the combo box list.`);
42887
42914
  }
42888
- if (!isOptionsExpanded) {
42889
- message2.push("Use the down arrow key to begin selecting.");
42890
- }
42915
+ message2.push("Use the down arrow key to begin selecting.");
42891
42916
  addPoliteMessageDebounced(message2.join(" "));
42892
42917
  }
42893
42918
  },
@@ -42981,7 +43006,7 @@ function TextInput({
42981
43006
  useRef(null)
42982
43007
  );
42983
43008
  const onChangeSetCursorPosition = useRememberCursorPosition(inputRef, value || "");
42984
- const { addAssertiveMessage } = useAriaMessaging();
43009
+ const { addPoliteMessage } = useAriaMessaging();
42985
43010
  const showClearIcon = isShowingClearableIcon ?? !!((isClearable || onClear) && currentValue);
42986
43011
  const clearInput = useCallback(
42987
43012
  /** @param {import('react').UIEvent<HTMLInputElement>} e */
@@ -42992,10 +43017,10 @@ function TextInput({
42992
43017
  } else if (inputRef.current) {
42993
43018
  inputRef.current.value = "";
42994
43019
  }
42995
- addAssertiveMessage(`${label} input was cleared`);
43020
+ addPoliteMessage(`${label} input was cleared`);
42996
43021
  (_a = inputRef.current) == null ? void 0 : _a.focus();
42997
43022
  },
42998
- [addAssertiveMessage, currentOnClear, label]
43023
+ [addPoliteMessage, currentOnClear, label]
42999
43024
  );
43000
43025
  const checkKeyPressed = useCallback(
43001
43026
  /** @param {import('react').KeyboardEvent<HTMLInputElement>} e */
@@ -43069,6 +43094,7 @@ function ComboBoxTextInput({
43069
43094
  className,
43070
43095
  comboBoxListId,
43071
43096
  errorMessage,
43097
+ iconCallback,
43072
43098
  id,
43073
43099
  innerRef: draftInnerRef,
43074
43100
  isClearable,
@@ -43262,7 +43288,13 @@ function ComboBoxTextInput({
43262
43288
  {
43263
43289
  "aria-hidden": "true",
43264
43290
  className: "combo-box-input__chevron icon-button--borderless icon-button--small1x",
43265
- icon: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: isOptionsExpanded ? "utds-icon-before-chevron-up" : "utds-icon-before-chevron-down", "aria-hidden": "true" }),
43291
+ icon: (iconCallback == null ? void 0 : iconCallback(isOptionsExpanded)) ?? /* @__PURE__ */ jsxRuntimeExports.jsx(
43292
+ "span",
43293
+ {
43294
+ "aria-hidden": "true",
43295
+ className: isOptionsExpanded ? "utds-icon-before-chevron-up" : "utds-icon-before-chevron-down"
43296
+ }
43297
+ ),
43266
43298
  isDisabled,
43267
43299
  onClick: (e) => {
43268
43300
  e.stopPropagation();
@@ -43288,6 +43320,7 @@ function ComboBox({
43288
43320
  className,
43289
43321
  defaultValue,
43290
43322
  errorMessage,
43323
+ iconCallback,
43291
43324
  id,
43292
43325
  innerRef: draftInnerRef,
43293
43326
  isClearable,
@@ -43312,8 +43345,8 @@ function ComboBox({
43312
43345
  wrapperClassName,
43313
43346
  ...rest
43314
43347
  }) {
43315
- const comboBoxListId = useId();
43316
- const contentRef = useRef(
43348
+ const comboBoxListId = `${id}__${useId()}`;
43349
+ const [contentRefState, setContentRefState] = useState(
43317
43350
  /** @type {HTMLInputElement | null} */
43318
43351
  null
43319
43352
  );
@@ -43326,9 +43359,10 @@ function ComboBox({
43326
43359
  className: textInputClassName,
43327
43360
  comboBoxListId,
43328
43361
  errorMessage,
43362
+ iconCallback,
43329
43363
  id,
43330
43364
  innerRef: (ref) => {
43331
- contentRef.current = ref;
43365
+ setContentRefState(ref);
43332
43366
  },
43333
43367
  isClearable,
43334
43368
  isShowingClearableIcon,
@@ -43348,7 +43382,7 @@ function ComboBox({
43348
43382
  allowCustomEntry,
43349
43383
  id: comboBoxListId,
43350
43384
  ariaLabelledById: id,
43351
- popperReferenceElement: popperContentRef ?? contentRef.current ?? null,
43385
+ popperReferenceElement: popperContentRef ?? contentRefState ?? null,
43352
43386
  children
43353
43387
  }
43354
43388
  )
@@ -44031,6 +44065,7 @@ function MultiSelectTags({ isDisabled }) {
44031
44065
  });
44032
44066
  }
44033
44067
  function MultiSelectComboBox({
44068
+ allowCustomEntry,
44034
44069
  children,
44035
44070
  className,
44036
44071
  errorMessage,
@@ -44041,6 +44076,7 @@ function MultiSelectComboBox({
44041
44076
  label,
44042
44077
  labelClassName,
44043
44078
  name: name2,
44079
+ onCustomEntry,
44044
44080
  placeholder,
44045
44081
  wrapperClassName,
44046
44082
  ...rest
@@ -44105,6 +44141,7 @@ function MultiSelectComboBox({
44105
44141
  /* @__PURE__ */ jsxRuntimeExports.jsx(
44106
44142
  ComboBox,
44107
44143
  {
44144
+ allowCustomEntry,
44108
44145
  className: "multi-select__combo-box",
44109
44146
  id: multiSelectContextValue.multiSelectId,
44110
44147
  isDisabled,
@@ -44117,6 +44154,7 @@ function MultiSelectComboBox({
44117
44154
  onChange: (newValue) => {
44118
44155
  multiSelectContextValue.onChange(lodashExports.uniq(selectedValuesRef.current.concat(newValue)));
44119
44156
  },
44157
+ onCustomEntry,
44120
44158
  onKeyUp: (e, currentFilter) => {
44121
44159
  let eventIsHandled = false;
44122
44160
  if (!currentFilter && multiSelectContextValueRef.current.selectedValues.length) {
@@ -44248,6 +44286,7 @@ function MultiSelectContextProvider({
44248
44286
  return /* @__PURE__ */ jsxRuntimeExports.jsx(MultiSelectContext.Provider, { value: providerValue, children });
44249
44287
  }
44250
44288
  function MultiSelect({
44289
+ allowCustomEntry,
44251
44290
  children,
44252
44291
  className,
44253
44292
  defaultValues,
@@ -44262,6 +44301,7 @@ function MultiSelect({
44262
44301
  name: name2,
44263
44302
  onChange,
44264
44303
  onClear,
44304
+ onCustomEntry,
44265
44305
  placeholder,
44266
44306
  values,
44267
44307
  wrapperClassName,
@@ -44278,6 +44318,7 @@ function MultiSelect({
44278
44318
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44279
44319
  MultiSelectComboBox,
44280
44320
  {
44321
+ allowCustomEntry,
44281
44322
  className,
44282
44323
  errorMessage,
44283
44324
  innerRef,
@@ -44287,6 +44328,7 @@ function MultiSelect({
44287
44328
  label,
44288
44329
  labelClassName,
44289
44330
  name: name2,
44331
+ onCustomEntry,
44290
44332
  placeholder,
44291
44333
  wrapperClassName,
44292
44334
  ...rest,
@@ -44372,9 +44414,11 @@ function PlainText({
44372
44414
  wrapperClassName,
44373
44415
  ...rest
44374
44416
  }) {
44375
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: joinClassNames("plain-text-wrapper", "plain-text-wrapper--plain-text", wrapperClassName), ref: innerRef, children: [
44417
+ const internalId = useId();
44418
+ const { value: currentValue } = useFormContextInput({ id: id || internalId, value });
44419
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: joinClassNames("input-wrapper", "input-wrapper--plain-text", wrapperClassName), ref: innerRef, children: [
44376
44420
  isLabelSkipped ? null : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: labelClassName ?? void 0, children: label }),
44377
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "plain-text__inner-wrapper", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: joinClassNames(className), id, ...rest, children: value }) })
44421
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "plain-text__inner-wrapper", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: joinClassNames(className), id, ...rest, children: currentValue || /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: " " }) }) })
44378
44422
  ] });
44379
44423
  }
44380
44424
  const RadioButtonGroupContext = (
@@ -44583,16 +44627,16 @@ function Select({
44583
44627
  /** @type {typeof useRef<HTMLSelectElement>} */
44584
44628
  useRef(null)
44585
44629
  );
44586
- const { addAssertiveMessage } = useAriaMessaging();
44630
+ const { addPoliteMessage } = useAriaMessaging();
44587
44631
  const clearInput = useCallback(
44588
44632
  /** @param {import('react').MouseEvent} e */
44589
44633
  (e) => {
44590
44634
  var _a;
44591
44635
  currentOnClear == null ? void 0 : currentOnClear(e);
44592
- addAssertiveMessage(`${label} input was cleared`);
44636
+ addPoliteMessage(`${label} input was cleared`);
44593
44637
  (_a = selectInputRef.current) == null ? void 0 : _a.focus();
44594
44638
  },
44595
- [addAssertiveMessage, currentOnClear, label]
44639
+ [addPoliteMessage, currentOnClear, label]
44596
44640
  );
44597
44641
  const showClearIcon = !!((isClearable || onClear) && currentValue);
44598
44642
  const onChangeCallback = useCallback(
@@ -44802,17 +44846,17 @@ function TextArea({
44802
44846
  useRef(null)
44803
44847
  );
44804
44848
  const onChangeSetCursorPosition = useRememberCursorPosition(inputRef, value || "");
44805
- const { addAssertiveMessage } = useAriaMessaging();
44849
+ const { addPoliteMessage } = useAriaMessaging();
44806
44850
  const showClearIcon = !!((isClearable || onClear) && currentValue);
44807
44851
  const clearInput = useCallback(
44808
44852
  /** @param {import('react').UIEvent} e */
44809
44853
  (e) => {
44810
44854
  var _a;
44811
44855
  currentOnClear == null ? void 0 : currentOnClear(e);
44812
- addAssertiveMessage(`${label} input was cleared`);
44856
+ addPoliteMessage(`${label} input was cleared`);
44813
44857
  (_a = inputRef.current) == null ? void 0 : _a.focus();
44814
44858
  },
44815
- [addAssertiveMessage, currentOnClear, label]
44859
+ [addPoliteMessage, currentOnClear, label]
44816
44860
  );
44817
44861
  const checkKeyPressed = useCallback(
44818
44862
  /** @param {import('react').KeyboardEvent} e */
@@ -44871,6 +44915,111 @@ function TextArea({
44871
44915
  /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorMessage, { errorMessage, id })
44872
44916
  ] });
44873
44917
  }
44918
+ function TimeInput({
44919
+ allowCustomEntry,
44920
+ className,
44921
+ defaultValue,
44922
+ errorMessage,
44923
+ hasTimePopup = true,
44924
+ id,
44925
+ innerRef,
44926
+ isClearable,
44927
+ isDisabled,
44928
+ isRequired,
44929
+ label,
44930
+ labelClassName,
44931
+ name: name2,
44932
+ onChange,
44933
+ onClear,
44934
+ placeholder,
44935
+ timeFormat = "h:mm aaa",
44936
+ timeRangeBegin,
44937
+ timeRangeEnd,
44938
+ timeRangeIncrement = 15,
44939
+ value,
44940
+ wrapperClassName,
44941
+ ...rest
44942
+ }) {
44943
+ const {
44944
+ onChange: currentOnChange,
44945
+ onClear: currentOnClear,
44946
+ value: currentValue
44947
+ } = useFormContextInputValue({
44948
+ defaultValue,
44949
+ id,
44950
+ onChange,
44951
+ onClear,
44952
+ value
44953
+ });
44954
+ const timeOptions = useMemo(
44955
+ () => {
44956
+ const defaultStartDate = new Date((/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0));
44957
+ const defaultEndDate = new Date((/* @__PURE__ */ new Date()).setHours(23, 59, 0, 0));
44958
+ let optionsBeginDate = timeRangeBegin && parse(timeRangeBegin, timeFormat, /* @__PURE__ */ new Date()) || null;
44959
+ optionsBeginDate = optionsBeginDate && isValid(optionsBeginDate) ? optionsBeginDate : defaultStartDate;
44960
+ let optionsEndDate = timeRangeEnd && parse(timeRangeEnd, timeFormat, /* @__PURE__ */ new Date()) || null;
44961
+ optionsEndDate = optionsEndDate && isValid(optionsEndDate) ? optionsEndDate : defaultEndDate;
44962
+ const timeOptionsRet = [];
44963
+ for (let loopDate = optionsBeginDate; loopDate.getTime() <= optionsEndDate.getTime(); loopDate = add(loopDate, { minutes: timeRangeIncrement })) {
44964
+ timeOptionsRet.push(format(loopDate, timeFormat));
44965
+ }
44966
+ return timeOptionsRet;
44967
+ },
44968
+ [timeRangeBegin, timeRangeEnd, timeRangeIncrement]
44969
+ );
44970
+ const clockIcon = useMemo(
44971
+ () => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: joinClassNames("utds-icon-before-clock", "time-input__clock-icon", isDisabled && "time-input__clock-icon--is-disabled", !hasTimePopup && "time-input__clock-icon--static"), "aria-hidden": "true" }),
44972
+ [isDisabled, hasTimePopup]
44973
+ );
44974
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: joinClassNames("time-input__wrapper", wrapperClassName), ref: innerRef, children: hasTimePopup ? /* @__PURE__ */ jsxRuntimeExports.jsx(
44975
+ ComboBox,
44976
+ {
44977
+ className,
44978
+ errorMessage,
44979
+ id,
44980
+ isClearable,
44981
+ isDisabled,
44982
+ isRequired,
44983
+ label,
44984
+ labelClassName,
44985
+ name: name2 || id,
44986
+ onClear: isClearable ? currentOnClear : void 0,
44987
+ placeholder,
44988
+ value: currentValue,
44989
+ allowCustomEntry,
44990
+ iconCallback: () => clockIcon,
44991
+ onChange: currentOnChange,
44992
+ ...rest,
44993
+ children: timeOptions.map((timeOption) => /* @__PURE__ */ jsxRuntimeExports.jsx(
44994
+ ComboBoxOption,
44995
+ {
44996
+ label: timeOption,
44997
+ value: timeOption
44998
+ },
44999
+ `time-input__${id}__${timeOption}`
45000
+ ))
45001
+ }
45002
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
45003
+ TextInput,
45004
+ {
45005
+ className,
45006
+ errorMessage,
45007
+ id,
45008
+ isClearable,
45009
+ isDisabled,
45010
+ isRequired,
45011
+ label,
45012
+ labelClassName,
45013
+ name: name2 || id,
45014
+ onClear: isClearable ? currentOnClear : void 0,
45015
+ placeholder,
45016
+ value: currentValue,
45017
+ onChange: (e) => currentOnChange(e.target.value),
45018
+ rightContent: clockIcon,
45019
+ ...rest
45020
+ }
45021
+ ) });
45022
+ }
44874
45023
  const Icons = {
44875
45024
  IconArrowLeft: (
44876
45025
  /** @type {IconFunc} */
@@ -44931,7 +45080,21 @@ function ExternalLink({ children, href, ...rest }) {
44931
45080
  ] })
44932
45081
  ] });
44933
45082
  }
44934
- function MenuItem({ currentMenuItem, menuItem }) {
45083
+ const menuTypes = {
45084
+ VERTICAL: (
45085
+ /** @type {MenuTypes} */
45086
+ "vertical"
45087
+ ),
45088
+ HORIZONTAL: (
45089
+ /** @type {MenuTypes} */
45090
+ "horizontal"
45091
+ )
45092
+ };
45093
+ function MenuItemInline({
45094
+ currentMenuItem,
45095
+ menuItem,
45096
+ menuType = menuTypes.VERTICAL
45097
+ }) {
44935
45098
  var _a, _b, _c;
44936
45099
  const { pathname } = useLocation();
44937
45100
  const [isChildrenOpen, setIsChildrenOpen] = i(() => {
@@ -44965,7 +45128,7 @@ function MenuItem({ currentMenuItem, menuItem }) {
44965
45128
  if ((!(menuItem == null ? void 0 : menuItem.link) || ((_a = menuItem == null ? void 0 : menuItem.link) == null ? void 0 : _a.includes("::")) || menuItem.children) && !menuItem.id) {
44966
45129
  console.error("A parent MenuItem requires an `id` to empower aria-labelledby", menuItem);
44967
45130
  }
44968
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: "menu-item", children: [
45131
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: menuType === menuTypes.VERTICAL ? "vertical-menu__item" : "menu-item", children: [
44969
45132
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "menu-item__title", children: [
44970
45133
  !(menuItem == null ? void 0 : menuItem.link) || ((_b = menuItem == null ? void 0 : menuItem.link) == null ? void 0 : _b.includes("::")) ? /* @__PURE__ */ jsxRuntimeExports.jsx(
44971
45134
  "button",
@@ -44983,6 +45146,7 @@ function MenuItem({ currentMenuItem, menuItem }) {
44983
45146
  className: (navData) => {
44984
45147
  var _a2, _b2;
44985
45148
  return joinClassNames(
45149
+ "menu-item__link-title",
44986
45150
  (((_a2 = currentMenuItem == null ? void 0 : currentMenuItem.parentLinks) == null ? void 0 : _a2.includes(menuItem.link ?? "")) || navData.isActive) && (((_b2 = currentMenuItem == null ? void 0 : currentMenuItem.children) == null ? void 0 : _b2.length) ? "menu-item--selected_parent" : "menu-item--selected")
44987
45151
  );
44988
45152
  },
@@ -45009,13 +45173,25 @@ function MenuItem({ currentMenuItem, menuItem }) {
45009
45173
  ) : null,
45010
45174
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "menu-chiclet" })
45011
45175
  ] }),
45012
- menuItem.children ? /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: joinClassNames("menu-item__sub-menu", isChildrenOpen ? "menu-item__sub-menu--open" : ""), role: "menu", children: (_c = menuItem.children) == null ? void 0 : _c.map((menuItemChild) => /* @__PURE__ */ jsxRuntimeExports.jsx(
45013
- MenuItem,
45176
+ menuItem.children ? /* @__PURE__ */ jsxRuntimeExports.jsx(
45177
+ "ul",
45014
45178
  {
45015
- menuItem: menuItemChild
45016
- },
45017
- `menu-item__child__${menuItemChild.link}-${menuItemChild.title}}`
45018
- )) }) : null
45179
+ role: "menu",
45180
+ className: joinClassNames(
45181
+ "menu-item__sub-menu",
45182
+ menuType === menuTypes.VERTICAL ? "vertical-menu" : "",
45183
+ isChildrenOpen ? "menu-item__sub-menu--open" : ""
45184
+ ),
45185
+ children: (_c = menuItem.children) == null ? void 0 : _c.map((menuItemChild) => /* @__PURE__ */ jsxRuntimeExports.jsx(
45186
+ MenuItemInline,
45187
+ {
45188
+ menuItem: menuItemChild,
45189
+ menuType
45190
+ },
45191
+ `menu-item__child__${menuItemChild.link}-${menuItemChild.title}}`
45192
+ ))
45193
+ }
45194
+ ) : null
45019
45195
  ] });
45020
45196
  }
45021
45197
  function HorizontalMenu({
@@ -45029,7 +45205,7 @@ function HorizontalMenu({
45029
45205
  var _a;
45030
45206
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("nav", { className: joinClassNames(className, "horizontal-menu"), "aria-labelledby": id, children: [
45031
45207
  /* @__PURE__ */ jsxRuntimeExports.jsx(TitleTagName, { id, className: titleTagClassName, children: "Main Menu" }),
45032
- /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { children: (_a = menu == null ? void 0 : menu.menuItems) == null ? void 0 : _a.map((menuItem) => /* @__PURE__ */ jsxRuntimeExports.jsx(MenuItem, { menuItem, currentMenuItem }, `horizontal-menu__nav-link__${menuItem.link}-${menuItem.title}}`)) })
45208
+ /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { children: (_a = menu == null ? void 0 : menu.menuItems) == null ? void 0 : _a.map((menuItem) => /* @__PURE__ */ jsxRuntimeExports.jsx(MenuItemInline, { menuItem, currentMenuItem }, `horizontal-menu__nav-link__${menuItem.link}-${menuItem.title}}`)) })
45033
45209
  ] });
45034
45210
  }
45035
45211
  function LinkCallback({
@@ -45122,20 +45298,224 @@ function OnThisPage({ contentRef }) {
45122
45298
  /* @__PURE__ */ jsxRuntimeExports.jsx(OnThisPageHeadersLevel, { headersLevel: headersTree })
45123
45299
  ] }) : null });
45124
45300
  }
45125
- function VerticalMenu({ currentMenuItem, menus }) {
45301
+ function MenuItemPlain({
45302
+ currentMenuItem,
45303
+ menuItem,
45304
+ menuType
45305
+ }) {
45306
+ var _a, _b;
45307
+ const navLinkRef = useRef(
45308
+ /** @type {HTMLAnchorElement | null} */
45309
+ null
45310
+ );
45311
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: menuType === menuTypes.VERTICAL ? "vertical-menu__item" : "menu-item", children: [
45312
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: menuType === menuTypes.VERTICAL ? "vertical-menu__title" : "menu-item__title", children: [
45313
+ !(menuItem == null ? void 0 : menuItem.link) || ((_a = menuItem == null ? void 0 : menuItem.link) == null ? void 0 : _a.includes("::")) ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: menuType === menuTypes.VERTICAL ? "vertical-menu__title__plain" : "menu-item__title__plain", children: menuItem.title }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
45314
+ NavLink,
45315
+ {
45316
+ className: (navData) => {
45317
+ var _a2, _b2;
45318
+ return joinClassNames(
45319
+ menuType === menuTypes.VERTICAL ? "vertical-menu__link-title" : "menu-item__link-title",
45320
+ (((_a2 = currentMenuItem == null ? void 0 : currentMenuItem.parentLinks) == null ? void 0 : _a2.includes(menuItem.link ?? "")) || navData.isActive) && (((_b2 = currentMenuItem == null ? void 0 : currentMenuItem.children) == null ? void 0 : _b2.length) ? "menu-item--selected_parent" : "menu-item--selected")
45321
+ );
45322
+ },
45323
+ end: true,
45324
+ to: menuItem.link,
45325
+ ref: navLinkRef,
45326
+ children: menuItem.title
45327
+ }
45328
+ ),
45329
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "menu-chiclet" })
45330
+ ] }),
45331
+ ((_b = menuItem.children) == null ? void 0 : _b.length) ? /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { role: "menu", className: menuType === menuTypes.VERTICAL ? "vertical-menu" : "", children: menuItem.children.map((menuItemChild) => /* @__PURE__ */ jsxRuntimeExports.jsx(
45332
+ MenuItemPlain,
45333
+ {
45334
+ menuItem: menuItemChild,
45335
+ menuType
45336
+ },
45337
+ `menu-item__child__${menuItemChild.link}-${menuItemChild.title}}`
45338
+ )) }) : null
45339
+ ] });
45340
+ }
45341
+ function useClickOutside(ref, handler, isDisabled = false) {
45342
+ useEffect(
45343
+ () => {
45344
+ let retVal;
45345
+ if (!isDisabled) {
45346
+ let startedInside = false;
45347
+ let startedWhenMounted = false;
45348
+ const listener = (event) => {
45349
+ if (
45350
+ // Do nothing if `mousedown` or `touchstart` started inside ref element
45351
+ !startedInside && startedWhenMounted && (ref.current && !ref.current.contains(event.target))
45352
+ ) {
45353
+ handler(event);
45354
+ }
45355
+ };
45356
+ const validateEventStart = (event) => {
45357
+ var _a, _b;
45358
+ startedWhenMounted = !!ref.current;
45359
+ startedInside = !!((_b = (_a = ref.current) == null ? void 0 : _a.contains) == null ? void 0 : _b.call(_a, event.target));
45360
+ };
45361
+ document.addEventListener("mousedown", validateEventStart);
45362
+ document.addEventListener("touchstart", validateEventStart);
45363
+ document.addEventListener("click", listener);
45364
+ retVal = () => {
45365
+ document.removeEventListener("mousedown", validateEventStart);
45366
+ document.removeEventListener("touchstart", validateEventStart);
45367
+ document.removeEventListener("click", listener);
45368
+ };
45369
+ }
45370
+ return retVal;
45371
+ },
45372
+ [ref.current, handler, isDisabled]
45373
+ );
45374
+ }
45375
+ function MenuItemFlyout({
45376
+ currentMenuItem,
45377
+ menuItem,
45378
+ menuType
45379
+ }) {
45380
+ var _a, _b;
45381
+ const [isChildrenOpen, setIsChildrenOpen] = i(false);
45382
+ const referenceElement = useRef(
45383
+ /** @type {HTMLLIElement | null} */
45384
+ null
45385
+ );
45386
+ const popperRef = useRef(
45387
+ /** @type {HTMLDivElement | null} */
45388
+ null
45389
+ );
45390
+ const { styles, attributes } = usePopper(referenceElement.current, popperRef.current, { placement: "right-start" });
45391
+ const navLinkRef = useRef(
45392
+ /** @type {HTMLAnchorElement | null} */
45393
+ null
45394
+ );
45395
+ useClickOutside(popperRef, () => setIsChildrenOpen(false), !isChildrenOpen);
45396
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: menuType === menuTypes.VERTICAL ? "vertical-menu__item" : "menu-item", ref: referenceElement, children: [
45397
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: menuType === menuTypes.VERTICAL ? "vertical-menu__title" : "menu-item__title", children: [
45398
+ !(menuItem == null ? void 0 : menuItem.link) || ((_a = menuItem == null ? void 0 : menuItem.link) == null ? void 0 : _a.includes("::")) ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
45399
+ "button",
45400
+ {
45401
+ "aria-expanded": isChildrenOpen ? "true" : "false",
45402
+ "aria-controls": `menu-item-${menuItem.id}-${menuItem.link}-popup`,
45403
+ "aria-haspopup": "dialog",
45404
+ className: "menu-item__button-title",
45405
+ id: `menu-item-${menuItem.id}-${menuItem.link}`,
45406
+ onClick: () => setIsChildrenOpen((previouslyOpen) => !previouslyOpen),
45407
+ type: "button",
45408
+ title: menuItem.children ? "Expand sub-menu" : "",
45409
+ children: [
45410
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: menuType === menuTypes.VERTICAL ? "vertical-menu__link-text" : "menu__link-text", children: menuItem.title }),
45411
+ menuItem.children ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "utds-icon-before-chevron-right vertical-menu__chevron is-closed", "aria-hidden": "true" }) : null
45412
+ ]
45413
+ }
45414
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
45415
+ NavLink,
45416
+ {
45417
+ className: (navData) => {
45418
+ var _a2, _b2;
45419
+ return joinClassNames(
45420
+ menuType === menuTypes.VERTICAL ? "vertical-menu__link-title" : "menu-item__link-title",
45421
+ (((_a2 = currentMenuItem == null ? void 0 : currentMenuItem.parentLinks) == null ? void 0 : _a2.includes(menuItem.link ?? "")) || navData.isActive) && (((_b2 = currentMenuItem == null ? void 0 : currentMenuItem.children) == null ? void 0 : _b2.length) ? "menu-item--selected_parent" : "menu-item--selected")
45422
+ );
45423
+ },
45424
+ end: true,
45425
+ to: menuItem.link,
45426
+ ref: navLinkRef,
45427
+ children: menuItem.title
45428
+ }
45429
+ ),
45430
+ menuItem.children && (menuItem == null ? void 0 : menuItem.link) ? /* @__PURE__ */ jsxRuntimeExports.jsx(
45431
+ IconButton,
45432
+ {
45433
+ appearance: ICON_BUTTON_APPEARANCE.BORDERLESS,
45434
+ "aria-labelledby": `menu-item-${menuItem.id}-${menuItem.link}`,
45435
+ "aria-expanded": isChildrenOpen ? "true" : "false",
45436
+ className: "menu-item__chevron",
45437
+ onClick: () => setIsChildrenOpen((previouslyOpen) => !previouslyOpen),
45438
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Icons.IconChevron, {}),
45439
+ title: "Expand sub-menu"
45440
+ }
45441
+ ) : null,
45442
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "menu-chiclet" })
45443
+ ] }),
45444
+ menuItem.children ? /* @__PURE__ */ jsxRuntimeExports.jsx(
45445
+ "div",
45446
+ {
45447
+ "aria-labelledby": `menu-item-${menuItem.id}-${menuItem.link}`,
45448
+ className: joinClassNames(
45449
+ "popup__wrapper",
45450
+ isChildrenOpen ? "popup__wrapper--visible" : "popup__wrapper--hidden"
45451
+ ),
45452
+ id: `menu-item-${menuItem.id}-${menuItem.link}-popup`,
45453
+ ref: popperRef,
45454
+ style: styles.popper,
45455
+ ...attributes.popper,
45456
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "popup__content flyout-menu", children: /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { role: "menu", className: menuType === menuTypes.VERTICAL ? "vertical-menu" : "", children: (_b = menuItem.children) == null ? void 0 : _b.map((menuItemChild) => /* @__PURE__ */ jsxRuntimeExports.jsx(
45457
+ MenuItemFlyout,
45458
+ {
45459
+ menuItem: menuItemChild,
45460
+ menuType
45461
+ },
45462
+ `menu-item__child__${menuItemChild.link}-${menuItemChild.title}}`
45463
+ )) }) })
45464
+ }
45465
+ ) : null
45466
+ ] });
45467
+ }
45468
+ function VerticalMenu({ className, currentMenuItem, menus }) {
45126
45469
  return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: menus.map((menu) => {
45127
45470
  const TitleTagName = menu.titleTagName || "h2";
45128
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("nav", { className: "menu-side-panel", "aria-labelledby": menu.id, children: [
45471
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("nav", { className, "aria-labelledby": menu.id, children: [
45129
45472
  /* @__PURE__ */ jsxRuntimeExports.jsx(
45130
45473
  TitleTagName,
45131
45474
  {
45132
45475
  id: menu.id,
45133
- className: joinClassNames(menu.titleTagClassName, "menu-side-panel__header"),
45476
+ className: joinClassNames(menu.titleTagClassName, "vertical-menu__header"),
45134
45477
  children: menu.header
45135
45478
  }
45136
45479
  ),
45137
- /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { role: "menu", children: menu.menuItems.map((menuItem) => /* @__PURE__ */ jsxRuntimeExports.jsx(MenuItem, { currentMenuItem, menuItem }, `menu-side-panel__menu-item__${menuItem.link}-${menuItem.title}}`)) }, `side-panel-navigation-menu__${menu.id}`)
45138
- ] }, `side-panel-navigation-menu__${menu.id}`);
45480
+ /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { role: "menu", className: "vertical-menu", children: menu.menuItems.map((menuItem) => {
45481
+ let result;
45482
+ switch (menuItem.childrenMenuType) {
45483
+ case childrenMenuTypes.INLINE:
45484
+ result = /* @__PURE__ */ jsxRuntimeExports.jsx(
45485
+ MenuItemInline,
45486
+ {
45487
+ menuType: menuTypes.VERTICAL,
45488
+ currentMenuItem,
45489
+ menuItem
45490
+ },
45491
+ `vertical-menu__menu-item__${menuItem.link}-${menuItem.title}}`
45492
+ );
45493
+ break;
45494
+ case childrenMenuTypes.FLYOUT:
45495
+ result = /* @__PURE__ */ jsxRuntimeExports.jsx(
45496
+ MenuItemFlyout,
45497
+ {
45498
+ menuType: menuTypes.VERTICAL,
45499
+ currentMenuItem,
45500
+ menuItem
45501
+ },
45502
+ `vertical-menu__menu-item__${menuItem.link}-${menuItem.title}}`
45503
+ );
45504
+ break;
45505
+ default:
45506
+ result = /* @__PURE__ */ jsxRuntimeExports.jsx(
45507
+ MenuItemPlain,
45508
+ {
45509
+ menuType: menuTypes.VERTICAL,
45510
+ menuItem,
45511
+ currentMenuItem
45512
+ },
45513
+ `vertical-menu__menu-item__${menuItem.link}-${menuItem.title}}`
45514
+ );
45515
+ }
45516
+ return result;
45517
+ }) }, `vertical-menu__list__${menu.id}`)
45518
+ ] }, `vertical-menu__${menu.id}`);
45139
45519
  }) });
45140
45520
  }
45141
45521
  function PaginationLink({
@@ -45603,40 +45983,6 @@ function ModalTitle({
45603
45983
  }
45604
45984
  );
45605
45985
  }
45606
- function useClickOutside(ref, handler, isDisabled = false) {
45607
- useEffect(
45608
- () => {
45609
- let retVal;
45610
- if (!isDisabled) {
45611
- let startedInside = false;
45612
- let startedWhenMounted = false;
45613
- const listener = (event) => {
45614
- if (
45615
- // Do nothing if `mousedown` or `touchstart` started inside ref element
45616
- !startedInside && startedWhenMounted && (ref.current && !ref.current.contains(event.target))
45617
- ) {
45618
- handler(event);
45619
- }
45620
- };
45621
- const validateEventStart = (event) => {
45622
- var _a, _b;
45623
- startedWhenMounted = !!ref.current;
45624
- startedInside = !!((_b = (_a = ref.current) == null ? void 0 : _a.contains) == null ? void 0 : _b.call(_a, event.target));
45625
- };
45626
- document.addEventListener("mousedown", validateEventStart);
45627
- document.addEventListener("touchstart", validateEventStart);
45628
- document.addEventListener("click", listener);
45629
- retVal = () => {
45630
- document.removeEventListener("mousedown", validateEventStart);
45631
- document.removeEventListener("touchstart", validateEventStart);
45632
- document.removeEventListener("click", listener);
45633
- };
45634
- }
45635
- return retVal;
45636
- },
45637
- [ref.current, handler, isDisabled]
45638
- );
45639
- }
45640
45986
  function useGlobalKeyEvent({ whichKeyCode, onKeyDown, onKeyUp }) {
45641
45987
  const [keyPressed, setKeyPressed] = useState(false);
45642
45988
  const keydownFuncRef = useRef(
@@ -47323,6 +47669,7 @@ export {
47323
47669
  Tag,
47324
47670
  TextArea,
47325
47671
  TextInput,
47672
+ TimeInput,
47326
47673
  Tooltip,
47327
47674
  UtahDesignSystemContext,
47328
47675
  UtahDesignSystemContextProvider,
@@ -47336,6 +47683,7 @@ export {
47336
47683
  handleEvent,
47337
47684
  handleKeyPress,
47338
47685
  joinClassNames,
47686
+ menuTypes,
47339
47687
  popupPlacement,
47340
47688
  rectContainsPoint,
47341
47689
  renderDOMSingle,