@photonix/basic 3.0.0 → 3.1.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.
package/dist/index.js CHANGED
@@ -80,6 +80,8 @@ __export(index_exports, {
80
80
  CheckSmallFilled: () => CheckSmallFilled,
81
81
  CheckSmallOutline: () => CheckSmallOutline,
82
82
  Checkbox: () => Checkbox,
83
+ CheckboxGroup: () => CheckboxGroup,
84
+ CheckboxGroupContext: () => CheckboxGroupContext,
83
85
  ChevronDownFilled: () => ChevronDownFilled,
84
86
  ChevronDownOutline: () => ChevronDownOutline,
85
87
  ChevronDownSmallFilled: () => ChevronDownSmallFilled,
@@ -123,6 +125,7 @@ __export(index_exports, {
123
125
  CreditCardFilled: () => CreditCardFilled,
124
126
  CreditCardOutline: () => CreditCardOutline,
125
127
  CustomScrollbar: () => CustomScrollbar,
128
+ DataList: () => DataList,
126
129
  DayFilled: () => DayFilled,
127
130
  DayOutline: () => DayOutline,
128
131
  Divider: () => Divider,
@@ -134,6 +137,7 @@ __export(index_exports, {
134
137
  DraftOutline: () => DraftOutline,
135
138
  DuplicateFilled: () => DuplicateFilled,
136
139
  DuplicateOutline: () => DuplicateOutline,
140
+ Empty: () => Empty,
137
141
  ExitFilled: () => ExitFilled,
138
142
  ExitOutline: () => ExitOutline,
139
143
  EyeDropperFilled: () => EyeDropperFilled,
@@ -142,6 +146,7 @@ __export(index_exports, {
142
146
  EyeOffFilled: () => EyeOffFilled,
143
147
  EyeOffOutline: () => EyeOffOutline,
144
148
  EyeOutline: () => EyeOutline,
149
+ Fieldset: () => Fieldset,
145
150
  Flex: () => Flex,
146
151
  FolderFilled: () => FolderFilled,
147
152
  FolderOutline: () => FolderOutline,
@@ -183,10 +188,13 @@ __export(index_exports, {
183
188
  MoreVerticalOutline: () => MoreVerticalOutline,
184
189
  MusicNoteFilled: () => MusicNoteFilled,
185
190
  MusicNoteOutline: () => MusicNoteOutline,
191
+ NumberField: () => NumberField,
192
+ OTP: () => OTP,
186
193
  OpenWithFilled: () => OpenWithFilled,
187
194
  OpenWithOutline: () => OpenWithOutline,
188
195
  OptionFilled: () => OptionFilled,
189
196
  OptionOutline: () => OptionOutline,
197
+ PIN: () => PIN,
190
198
  PenFilled: () => PenFilled,
191
199
  PenOutline: () => PenOutline,
192
200
  PersonalBookFilled: () => PersonalBookFilled,
@@ -198,11 +206,14 @@ __export(index_exports, {
198
206
  Portal: () => Portal,
199
207
  Radio: () => Radio,
200
208
  RadioFilled: () => RadioFilled,
209
+ RadioGroup: () => RadioGroup,
201
210
  RadioOutline: () => RadioOutline,
202
211
  RainFilled: () => RainFilled,
203
212
  RainOutline: () => RainOutline,
213
+ Rating: () => Rating,
204
214
  RectangleFilled: () => RectangleFilled,
205
215
  RectangleOutline: () => RectangleOutline,
216
+ Result: () => Result,
206
217
  RouterFilled: () => RouterFilled,
207
218
  RouterOutline: () => RouterOutline,
208
219
  ScheduleFilled: () => ScheduleFilled,
@@ -5134,11 +5145,16 @@ var Text_default = {};
5134
5145
 
5135
5146
  // ../ultimate/src/components/text/Text.tsx
5136
5147
  var import_jsx_runtime201 = require("react/jsx-runtime");
5137
- var getVariantVars = (value) => {
5148
+ var getVariantVars = (value, weight) => {
5138
5149
  if (!value) return {};
5139
5150
  const vars = {};
5140
5151
  const breakpoints = ["base", "sm", "md", "lg", "xl", "2xl"];
5141
- const getWeightToken = (variant) => variant.startsWith("title-") || variant.startsWith("label-") ? `var(--${variant}-weight-emphasize)` : `var(--${variant}-weight)`;
5152
+ const getWeightToken = (variant) => {
5153
+ if (weight === "regular") return `var(--${variant}-weight, var(--body-md-weight))`;
5154
+ if (weight === "medium") return `var(--${variant}-weight-emphasize, var(--label-md-weight-emphasize))`;
5155
+ if (weight === "bold") return "var(--display-lg-weight)";
5156
+ return variant.startsWith("title-") || variant.startsWith("label-") ? `var(--${variant}-weight-emphasize)` : `var(--${variant}-weight)`;
5157
+ };
5142
5158
  if (typeof value === "object" && value !== null) {
5143
5159
  breakpoints.forEach((bp) => {
5144
5160
  const v = value[bp];
@@ -5208,7 +5224,7 @@ var Text = React202.forwardRef(
5208
5224
  ].filter(Boolean).join(" ");
5209
5225
  const inlineStyles = {
5210
5226
  ...style,
5211
- ...getVariantVars(variant),
5227
+ ...getVariantVars(variant, weight),
5212
5228
  ...getAlignVars(align),
5213
5229
  ...typeof truncate === "number" && {
5214
5230
  "--line-clamp": truncate
@@ -5297,6 +5313,10 @@ function getElementRef(element) {
5297
5313
  }
5298
5314
  function mergeProps(slotProps, childProps) {
5299
5315
  const mergedProps = { ...childProps, ...slotProps };
5316
+ if (childProps.disabled === true) mergedProps.disabled = true;
5317
+ if (childProps["aria-disabled"] === true || childProps["aria-disabled"] === "true") {
5318
+ mergedProps["aria-disabled"] = childProps["aria-disabled"];
5319
+ }
5300
5320
  Object.keys(childProps).forEach((propName) => {
5301
5321
  const childPropValue = childProps[propName];
5302
5322
  const slotPropValue = slotProps[propName];
@@ -5304,7 +5324,7 @@ function mergeProps(slotProps, childProps) {
5304
5324
  if (isEventHandler && typeof childPropValue === "function" && typeof slotPropValue === "function") {
5305
5325
  mergedProps[propName] = (...args) => {
5306
5326
  childPropValue(...args);
5307
- slotPropValue(...args);
5327
+ if (!args[0]?.defaultPrevented) slotPropValue(...args);
5308
5328
  };
5309
5329
  } else if (propName === "className") {
5310
5330
  mergedProps[propName] = [childPropValue, slotPropValue].filter(Boolean).join(" ");
@@ -5325,6 +5345,20 @@ var Slot = React204.forwardRef(
5325
5345
  }
5326
5346
  const childRef = getElementRef(child);
5327
5347
  const props = mergeProps(slotProps, child.props);
5348
+ if (props.disabled || props["aria-disabled"] === true || props["aria-disabled"] === "true") {
5349
+ const block = (event) => {
5350
+ event.preventDefault();
5351
+ event.stopPropagation();
5352
+ };
5353
+ const onKeyDown = props.onKeyDown;
5354
+ props.onClick = block;
5355
+ props.onAuxClick = block;
5356
+ props.onKeyDown = (event) => {
5357
+ if (event.key === "Enter" || event.key === " ") block(event);
5358
+ else onKeyDown?.(event);
5359
+ };
5360
+ props.tabIndex = -1;
5361
+ }
5328
5362
  if (childRef || forwardedRef) {
5329
5363
  props.ref = composeRefs(childRef, forwardedRef);
5330
5364
  }
@@ -5496,6 +5530,7 @@ var Button = React207.forwardRef(
5496
5530
  {
5497
5531
  className: buttonClasses,
5498
5532
  ref,
5533
+ disabled: disabled || isLoading,
5499
5534
  "aria-disabled": isLoading || disabled || void 0,
5500
5535
  "data-loading": isLoading || void 0,
5501
5536
  ...rest,
@@ -5532,7 +5567,7 @@ var Button = React207.forwardRef(
5532
5567
  {
5533
5568
  className: buttonClasses,
5534
5569
  ref,
5535
- disabled,
5570
+ disabled: disabled || isLoading,
5536
5571
  "aria-disabled": isLoading || disabled || void 0,
5537
5572
  "data-loading": isLoading || void 0,
5538
5573
  ...rest,
@@ -5602,7 +5637,7 @@ var IconButton = React208.forwardRef(
5602
5637
  {
5603
5638
  className: buttonClasses,
5604
5639
  ref,
5605
- disabled,
5640
+ disabled: disabled || isLoading,
5606
5641
  "aria-disabled": isLoading || disabled || void 0,
5607
5642
  "data-loading": isLoading || void 0,
5608
5643
  ...rest,
@@ -5615,7 +5650,7 @@ var IconButton = React208.forwardRef(
5615
5650
  {
5616
5651
  className: buttonClasses,
5617
5652
  ref,
5618
- disabled,
5653
+ disabled: disabled || isLoading,
5619
5654
  "aria-disabled": isLoading || disabled || void 0,
5620
5655
  "data-loading": isLoading || void 0,
5621
5656
  ...rest,
@@ -5627,14 +5662,276 @@ var IconButton = React208.forwardRef(
5627
5662
  IconButton.displayName = "IconButton";
5628
5663
 
5629
5664
  // ../ultimate/src/components/checkbox/Checkbox.tsx
5665
+ var React214 = __toESM(require("react"));
5666
+
5667
+ // ../ultimate/src/internal/form/NativeSelectionInput.tsx
5630
5668
  var React209 = __toESM(require("react"));
5631
5669
 
5670
+ // ../ultimate/src/hooks/useCallbackRef.ts
5671
+ var import_react2 = require("react");
5672
+ function useCallbackRef(callback) {
5673
+ const callbackRef = (0, import_react2.useRef)(callback);
5674
+ (0, import_react2.useEffect)(() => {
5675
+ callbackRef.current = callback;
5676
+ });
5677
+ return (0, import_react2.useMemo)(() => ((...args) => callbackRef.current?.(...args)), []);
5678
+ }
5679
+
5680
+ // ../ultimate/src/internal/form/NativeSelectionInput.tsx
5681
+ var import_jsx_runtime207 = require("react/jsx-runtime");
5682
+ var visuallyHiddenInputStyle = {
5683
+ position: "absolute",
5684
+ width: 1,
5685
+ height: 1,
5686
+ padding: 0,
5687
+ margin: -1,
5688
+ overflow: "hidden",
5689
+ clipPath: "inset(50%)",
5690
+ whiteSpace: "nowrap",
5691
+ border: 0
5692
+ };
5693
+ function NativeSelectionInput({
5694
+ checked,
5695
+ defaultChecked,
5696
+ controlled,
5697
+ onReset,
5698
+ controlRef,
5699
+ ...props
5700
+ }) {
5701
+ const inputRef = React209.useRef(null);
5702
+ const reset = useCallbackRef((event) => {
5703
+ queueMicrotask(() => {
5704
+ if (event.defaultPrevented || !inputRef.current) return;
5705
+ const next = controlled ? checked : defaultChecked;
5706
+ inputRef.current.checked = next;
5707
+ if (!controlled) onReset(next);
5708
+ });
5709
+ });
5710
+ React209.useEffect(() => {
5711
+ const form = inputRef.current?.form;
5712
+ form?.addEventListener("reset", reset);
5713
+ return () => form?.removeEventListener("reset", reset);
5714
+ }, [props.form, reset]);
5715
+ return /* @__PURE__ */ (0, import_jsx_runtime207.jsx)(
5716
+ "input",
5717
+ {
5718
+ ...props,
5719
+ ref: inputRef,
5720
+ checked,
5721
+ onChange: () => {
5722
+ },
5723
+ tabIndex: -1,
5724
+ "aria-hidden": "true",
5725
+ style: visuallyHiddenInputStyle,
5726
+ onInvalid: (event) => {
5727
+ event.preventDefault();
5728
+ controlRef.current?.focus();
5729
+ }
5730
+ }
5731
+ );
5732
+ }
5733
+
5734
+ // ../ultimate/src/components/checkbox-group/CheckboxGroup.tsx
5735
+ var React213 = __toESM(require("react"));
5736
+
5737
+ // ../ultimate/src/hooks/useControllableState.ts
5738
+ var React210 = __toESM(require("react"));
5739
+ function useControllableState({
5740
+ value: valueProp,
5741
+ defaultValue,
5742
+ onChange
5743
+ }) {
5744
+ const [uncontrolledValue, setUncontrolledValue] = React210.useState(() => typeof defaultValue === "function" ? defaultValue() : defaultValue);
5745
+ const isControlledRef = React210.useRef(valueProp !== void 0);
5746
+ const isControlled = isControlledRef.current;
5747
+ const value = isControlled ? valueProp : uncontrolledValue;
5748
+ const handleChange = useCallbackRef(onChange);
5749
+ const previousUncontrolledValueRef = React210.useRef(uncontrolledValue);
5750
+ React210.useEffect(() => {
5751
+ if (isControlled) return;
5752
+ if (previousUncontrolledValueRef.current === uncontrolledValue) return;
5753
+ previousUncontrolledValueRef.current = uncontrolledValue;
5754
+ handleChange(uncontrolledValue);
5755
+ }, [isControlled, uncontrolledValue, handleChange]);
5756
+ const setValue = React210.useCallback(
5757
+ (nextValue) => {
5758
+ if (isControlled) {
5759
+ const setter = nextValue;
5760
+ const valueToEmit = typeof nextValue === "function" ? setter(valueProp) : nextValue;
5761
+ handleChange(valueToEmit);
5762
+ } else {
5763
+ setUncontrolledValue((prev) => {
5764
+ const setter = nextValue;
5765
+ return typeof nextValue === "function" ? setter(prev) : nextValue;
5766
+ });
5767
+ }
5768
+ },
5769
+ [isControlled, valueProp, handleChange]
5770
+ );
5771
+ const reset = React210.useCallback(() => {
5772
+ if (isControlled) return;
5773
+ const next = typeof defaultValue === "function" ? defaultValue() : defaultValue;
5774
+ previousUncontrolledValueRef.current = next;
5775
+ setUncontrolledValue(next);
5776
+ }, [isControlled, defaultValue]);
5777
+ return [value, setValue, reset];
5778
+ }
5779
+
5780
+ // ../ultimate/src/internal/form/SelectionGroup.tsx
5781
+ var React212 = __toESM(require("react"));
5782
+
5783
+ // ../ultimate/src/components/fieldset/Fieldset.tsx
5784
+ var React211 = __toESM(require("react"));
5785
+
5786
+ // ../ultimate/src/utils/aria.utils.ts
5787
+ function mergeAriaIds(...values) {
5788
+ const ids = values.filter((value) => Boolean(value)).flatMap((value) => value.split(/\s+/));
5789
+ return [...new Set(ids)].join(" ") || void 0;
5790
+ }
5791
+
5792
+ // ../ultimate/src/components/fieldset/Fieldset.tsx
5793
+ var import_jsx_runtime208 = require("react/jsx-runtime");
5794
+ var Fieldset = React211.forwardRef(
5795
+ ({ legend, description, error, children, className, ...props }, ref) => {
5796
+ const id = React211.useId();
5797
+ return /* @__PURE__ */ (0, import_jsx_runtime208.jsxs)(
5798
+ Box,
5799
+ {
5800
+ as: "fieldset",
5801
+ border: "none",
5802
+ p: "none",
5803
+ m: "none",
5804
+ minW: 0,
5805
+ ...props,
5806
+ ref,
5807
+ className,
5808
+ "aria-describedby": mergeAriaIds(
5809
+ props["aria-describedby"],
5810
+ description ? `${id}-description` : void 0,
5811
+ error ? `${id}-error` : void 0
5812
+ ),
5813
+ "aria-invalid": error ? true : props["aria-invalid"],
5814
+ children: [
5815
+ legend != null && /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(Box, { as: "legend", p: "none", mb: "2xs", children: /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(Text, { as: "span", variant: "title-md", children: legend }) }),
5816
+ /* @__PURE__ */ (0, import_jsx_runtime208.jsxs)(VStack, { gap: "2xs", children: [
5817
+ description && /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(
5818
+ Text,
5819
+ {
5820
+ as: "div",
5821
+ variant: "body-md",
5822
+ color: "secondary",
5823
+ id: `${id}-description`,
5824
+ children: description
5825
+ }
5826
+ ),
5827
+ children,
5828
+ error && /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(Text, { as: "div", variant: "body-md", color: "red", id: `${id}-error`, children: error })
5829
+ ] })
5830
+ ]
5831
+ }
5832
+ );
5833
+ }
5834
+ );
5835
+ Fieldset.displayName = "Fieldset";
5836
+
5837
+ // ../ultimate/src/internal/form/SelectionGroup.tsx
5838
+ var import_jsx_runtime209 = require("react/jsx-runtime");
5839
+ var SelectionGroupFrame = React212.forwardRef(({ label, description, error, orientation = "vertical", disabled, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime209.jsx)(Fieldset, { ref, legend: label, description, error, disabled, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime209.jsx)(Stack, { direction: orientation === "horizontal" ? "row" : "column", gap: "2xs", wrap: true, children }) }));
5840
+ SelectionGroupFrame.displayName = "SelectionGroupFrame";
5841
+ function useGroupFormReset(rootRef, form, reset) {
5842
+ const onReset = useCallbackRef((event) => {
5843
+ queueMicrotask(() => {
5844
+ if (!event.defaultPrevented) reset();
5845
+ });
5846
+ });
5847
+ React212.useEffect(() => {
5848
+ const owner = form ? document.getElementById(form) : rootRef.current?.closest("form");
5849
+ owner?.addEventListener("reset", onReset);
5850
+ return () => owner?.removeEventListener("reset", onReset);
5851
+ }, [form, rootRef, onReset]);
5852
+ }
5853
+ function assignRef(ref, node) {
5854
+ if (typeof ref === "function") ref(node);
5855
+ else if (ref) ref.current = node;
5856
+ }
5857
+
5858
+ // ../ultimate/src/components/checkbox-group/CheckboxGroup.tsx
5859
+ var import_jsx_runtime210 = require("react/jsx-runtime");
5860
+ var CheckboxGroupContext = React213.createContext(null);
5861
+ var EMPTY = [];
5862
+ var CheckboxGroup = React213.forwardRef(({
5863
+ value,
5864
+ defaultValue = EMPTY,
5865
+ onChange,
5866
+ name,
5867
+ form,
5868
+ disabled,
5869
+ required,
5870
+ requiredMessage = "Select at least one option.",
5871
+ children,
5872
+ ...props
5873
+ }, forwardedRef) => {
5874
+ const [selected = EMPTY, setSelected, reset] = useControllableState({ value, defaultValue, onChange });
5875
+ const rootRef = React213.useRef(null);
5876
+ const validationRef = React213.useRef(null);
5877
+ useGroupFormReset(rootRef, form, reset);
5878
+ const missing = Boolean(required) && selected.length === 0;
5879
+ React213.useLayoutEffect(() => {
5880
+ const input = validationRef.current;
5881
+ input.checked = !missing;
5882
+ input.setCustomValidity(missing ? requiredMessage : "");
5883
+ }, [missing, requiredMessage]);
5884
+ const context = React213.useMemo(() => ({
5885
+ value: selected,
5886
+ name,
5887
+ form,
5888
+ disabled,
5889
+ toggle: (option, checked) => setSelected(
5890
+ checked ? [...selected.filter((item) => item !== option), option] : selected.filter((item) => item !== option)
5891
+ )
5892
+ }), [selected, name, form, disabled, setSelected]);
5893
+ return /* @__PURE__ */ (0, import_jsx_runtime210.jsxs)(CheckboxGroupContext.Provider, { value: context, children: [
5894
+ /* @__PURE__ */ (0, import_jsx_runtime210.jsx)(
5895
+ SelectionGroupFrame,
5896
+ {
5897
+ ...props,
5898
+ ref: (node) => {
5899
+ rootRef.current = node;
5900
+ assignRef(forwardedRef, node);
5901
+ },
5902
+ disabled,
5903
+ "aria-required": required || void 0,
5904
+ children
5905
+ }
5906
+ ),
5907
+ /* @__PURE__ */ (0, import_jsx_runtime210.jsx)(
5908
+ "input",
5909
+ {
5910
+ ref: validationRef,
5911
+ type: "checkbox",
5912
+ form,
5913
+ required,
5914
+ defaultChecked: !missing,
5915
+ disabled,
5916
+ tabIndex: -1,
5917
+ "aria-hidden": "true",
5918
+ style: visuallyHiddenInputStyle,
5919
+ onInvalid: (event) => {
5920
+ event.preventDefault();
5921
+ rootRef.current?.querySelector('[role="checkbox"]:not(:disabled)')?.focus();
5922
+ }
5923
+ }
5924
+ )
5925
+ ] });
5926
+ });
5927
+ CheckboxGroup.displayName = "CheckboxGroup";
5928
+
5632
5929
  // ../ultimate/src/components/checkbox/Checkbox.module.css
5633
5930
  var Checkbox_default = {};
5634
5931
 
5635
5932
  // ../ultimate/src/components/checkbox/Checkbox.tsx
5636
- var import_jsx_runtime207 = require("react/jsx-runtime");
5637
- var Checkbox = React209.forwardRef(
5933
+ var import_jsx_runtime211 = require("react/jsx-runtime");
5934
+ var Checkbox = React214.forwardRef(
5638
5935
  ({
5639
5936
  className,
5640
5937
  style,
@@ -5646,18 +5943,33 @@ var Checkbox = React209.forwardRef(
5646
5943
  disabled,
5647
5944
  onChange,
5648
5945
  onClick,
5946
+ name,
5947
+ value,
5948
+ form,
5949
+ required,
5649
5950
  ...rest
5650
5951
  }, ref) => {
5952
+ const group = React214.useContext(CheckboxGroupContext);
5953
+ const inGroup = Boolean(group) && value !== void 0;
5954
+ const optionValue = String(value);
5955
+ if (inGroup) {
5956
+ controlledChecked = group.value.includes(optionValue);
5957
+ name = group.name ?? name;
5958
+ form = group.form ?? form;
5959
+ disabled = disabled || group.disabled;
5960
+ }
5651
5961
  const isControlled = controlledChecked !== void 0;
5652
- const [internalChecked, setInternalChecked] = React209.useState(defaultChecked);
5653
- const [rippleActive, setRippleActive] = React209.useState(false);
5654
- const rippleTimeoutRef = React209.useRef(null);
5655
- const checked = isControlled ? controlledChecked : internalChecked;
5962
+ const [internalChecked, setInternalChecked] = React214.useState(defaultChecked);
5963
+ const [rippleActive, setRippleActive] = React214.useState(false);
5964
+ const rippleTimeoutRef = React214.useRef(null);
5965
+ const checked = isControlled ? Boolean(controlledChecked) : internalChecked;
5966
+ const controlRef = React214.useRef(null);
5656
5967
  const isIndeterminate = indeterminate;
5657
5968
  const isChecked = !indeterminate && checked;
5658
5969
  const isUnchecked = !indeterminate && !checked;
5659
5970
  const iconSize = size === "small" ? 20 : 24;
5660
5971
  const handleClick = (e) => {
5972
+ e.preventDefault();
5661
5973
  if (disabled) return;
5662
5974
  if (rippleTimeoutRef.current) {
5663
5975
  clearTimeout(rippleTimeoutRef.current);
@@ -5670,6 +5982,7 @@ var Checkbox = React209.forwardRef(
5670
5982
  if (!isControlled) {
5671
5983
  setInternalChecked(nextChecked);
5672
5984
  }
5985
+ if (inGroup) group.toggle(optionValue, nextChecked);
5673
5986
  if (onChange) {
5674
5987
  onChange(nextChecked);
5675
5988
  }
@@ -5677,7 +5990,7 @@ var Checkbox = React209.forwardRef(
5677
5990
  onClick(e);
5678
5991
  }
5679
5992
  };
5680
- React209.useEffect(() => {
5993
+ React214.useEffect(() => {
5681
5994
  return () => {
5682
5995
  if (rippleTimeoutRef.current) {
5683
5996
  clearTimeout(rippleTimeoutRef.current);
@@ -5697,11 +6010,18 @@ var Checkbox = React209.forwardRef(
5697
6010
  disabled && Checkbox_default.disabled,
5698
6011
  label && className
5699
6012
  ].filter(Boolean).join(" ");
5700
- const checkboxContent = /* @__PURE__ */ (0, import_jsx_runtime207.jsx)(
6013
+ const checkboxContent = /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
5701
6014
  "button",
5702
6015
  {
5703
- ref,
6016
+ ref: (node) => {
6017
+ controlRef.current = node;
6018
+ if (typeof ref === "function") ref(node);
6019
+ else if (ref) ref.current = node;
6020
+ },
5704
6021
  type: "button",
6022
+ form,
6023
+ value,
6024
+ "aria-required": required || void 0,
5705
6025
  role: "checkbox",
5706
6026
  "aria-checked": indeterminate ? "mixed" : checked,
5707
6027
  className: checkboxClasses,
@@ -5709,35 +6029,137 @@ var Checkbox = React209.forwardRef(
5709
6029
  onClick: handleClick,
5710
6030
  style: !label ? style : void 0,
5711
6031
  ...rest,
5712
- children: /* @__PURE__ */ (0, import_jsx_runtime207.jsxs)("span", { className: Checkbox_default.checkboxIcon, children: [
5713
- /* @__PURE__ */ (0, import_jsx_runtime207.jsx)("span", { className: Checkbox_default.checkboxBase, children: isUnchecked ? /* @__PURE__ */ (0, import_jsx_runtime207.jsx)(RectangleOutline, { size: iconSize }) : /* @__PURE__ */ (0, import_jsx_runtime207.jsx)(RectangleFilled, { size: iconSize }) }),
5714
- (isChecked || isIndeterminate) && /* @__PURE__ */ (0, import_jsx_runtime207.jsxs)("span", { className: Checkbox_default.checkboxOverlay, children: [
5715
- isChecked && /* @__PURE__ */ (0, import_jsx_runtime207.jsx)(CheckSmallOutline, { size: iconSize }),
5716
- isIndeterminate && /* @__PURE__ */ (0, import_jsx_runtime207.jsx)(IndeterminateSmallOutline, { size: iconSize })
6032
+ children: /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)("span", { className: Checkbox_default.checkboxIcon, children: [
6033
+ /* @__PURE__ */ (0, import_jsx_runtime211.jsx)("span", { className: Checkbox_default.checkboxBase, children: isUnchecked ? /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(RectangleOutline, { size: iconSize }) : /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(RectangleFilled, { size: iconSize }) }),
6034
+ (isChecked || isIndeterminate) && /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)("span", { className: Checkbox_default.checkboxOverlay, children: [
6035
+ isChecked && /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(CheckSmallOutline, { size: iconSize }),
6036
+ isIndeterminate && /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(IndeterminateSmallOutline, { size: iconSize })
5717
6037
  ] })
5718
6038
  ] })
5719
6039
  }
5720
6040
  );
6041
+ const formInput = /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
6042
+ NativeSelectionInput,
6043
+ {
6044
+ type: "checkbox",
6045
+ name,
6046
+ value,
6047
+ form,
6048
+ required,
6049
+ disabled,
6050
+ checked,
6051
+ defaultChecked,
6052
+ controlled: isControlled,
6053
+ controlRef,
6054
+ onReset: setInternalChecked
6055
+ }
6056
+ );
5721
6057
  if (label) {
5722
- return /* @__PURE__ */ (0, import_jsx_runtime207.jsxs)("label", { className: containerClasses, style, children: [
5723
- checkboxContent,
5724
- /* @__PURE__ */ (0, import_jsx_runtime207.jsx)("span", { className: Checkbox_default.checkboxLabel, children: label })
6058
+ return /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)(import_jsx_runtime211.Fragment, { children: [
6059
+ formInput,
6060
+ /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)("label", { className: containerClasses, style, children: [
6061
+ checkboxContent,
6062
+ /* @__PURE__ */ (0, import_jsx_runtime211.jsx)("span", { className: Checkbox_default.checkboxLabel, children: label })
6063
+ ] })
5725
6064
  ] });
5726
6065
  }
5727
- return checkboxContent;
6066
+ return /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)(import_jsx_runtime211.Fragment, { children: [
6067
+ formInput,
6068
+ checkboxContent
6069
+ ] });
5728
6070
  }
5729
6071
  );
5730
6072
  Checkbox.displayName = "Checkbox";
5731
6073
 
5732
6074
  // ../ultimate/src/components/radio/Radio.tsx
5733
- var React210 = __toESM(require("react"));
6075
+ var React216 = __toESM(require("react"));
6076
+
6077
+ // ../ultimate/src/components/radio/RadioGroup.tsx
6078
+ var React215 = __toESM(require("react"));
6079
+ var import_jsx_runtime212 = require("react/jsx-runtime");
6080
+ var RadioGroupContext = React215.createContext(null);
6081
+ var NAVIGATION_KEYS = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End"];
6082
+ var RadioGroup = React215.forwardRef(
6083
+ ({
6084
+ value,
6085
+ defaultValue,
6086
+ onChange,
6087
+ name,
6088
+ form,
6089
+ disabled,
6090
+ required,
6091
+ onKeyDown,
6092
+ children,
6093
+ ...props
6094
+ }, forwardedRef) => {
6095
+ const generatedName = React215.useId();
6096
+ const [currentValue, setValue, reset] = useControllableState({
6097
+ value,
6098
+ defaultValue,
6099
+ onChange
6100
+ });
6101
+ const rootRef = React215.useRef(null);
6102
+ useGroupFormReset(rootRef, form, reset);
6103
+ const ownRadios = (root) => Array.from(root.querySelectorAll('[role="radio"]:not(:disabled)')).filter(
6104
+ (item) => item.closest('[role="radiogroup"]') === root
6105
+ );
6106
+ React215.useLayoutEffect(() => {
6107
+ if (!rootRef.current) return;
6108
+ const items = ownRadios(rootRef.current);
6109
+ const selected = items.find((item) => item.getAttribute("aria-checked") === "true") ?? items[0];
6110
+ items.forEach((item) => {
6111
+ item.tabIndex = item === selected ? 0 : -1;
6112
+ });
6113
+ }, [currentValue, children, disabled]);
6114
+ const context = React215.useMemo(
6115
+ () => ({
6116
+ value: currentValue,
6117
+ name: name ?? generatedName,
6118
+ form,
6119
+ disabled,
6120
+ required,
6121
+ onChange: (next) => setValue(next)
6122
+ }),
6123
+ [currentValue, name, generatedName, form, disabled, required, setValue]
6124
+ );
6125
+ return /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(RadioGroupContext.Provider, { value: context, children: /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
6126
+ SelectionGroupFrame,
6127
+ {
6128
+ ...props,
6129
+ ref: (node) => {
6130
+ rootRef.current = node;
6131
+ assignRef(forwardedRef, node);
6132
+ },
6133
+ disabled,
6134
+ role: "radiogroup",
6135
+ "aria-required": required || void 0,
6136
+ onKeyDown: (event) => {
6137
+ onKeyDown?.(event);
6138
+ if (event.defaultPrevented || event.nativeEvent.isComposing || disabled || !NAVIGATION_KEYS.includes(event.key))
6139
+ return;
6140
+ const items = ownRadios(event.currentTarget);
6141
+ const index = items.indexOf(event.target);
6142
+ if (index < 0) return;
6143
+ event.preventDefault();
6144
+ const rtl = getComputedStyle(event.currentTarget).direction === "rtl";
6145
+ const previous = event.key === "ArrowUp" || event.key === (rtl ? "ArrowRight" : "ArrowLeft");
6146
+ const next = event.key === "Home" ? 0 : event.key === "End" ? items.length - 1 : (index + (previous ? -1 : 1) + items.length) % items.length;
6147
+ items[next]?.focus();
6148
+ items[next]?.click();
6149
+ },
6150
+ children
6151
+ }
6152
+ ) });
6153
+ }
6154
+ );
6155
+ RadioGroup.displayName = "RadioGroup";
5734
6156
 
5735
6157
  // ../ultimate/src/components/radio/Radio.module.css
5736
6158
  var Radio_default = {};
5737
6159
 
5738
6160
  // ../ultimate/src/components/radio/Radio.tsx
5739
- var import_jsx_runtime208 = require("react/jsx-runtime");
5740
- var Radio = React210.forwardRef(
6161
+ var import_jsx_runtime213 = require("react/jsx-runtime");
6162
+ var Radio = React216.forwardRef(
5741
6163
  ({
5742
6164
  className,
5743
6165
  style,
@@ -5748,16 +6170,35 @@ var Radio = React210.forwardRef(
5748
6170
  disabled,
5749
6171
  onChange,
5750
6172
  onClick,
6173
+ name,
6174
+ value,
6175
+ form,
6176
+ required,
5751
6177
  ...rest
5752
6178
  }, ref) => {
5753
- const isControlled = controlledChecked !== void 0;
5754
- const [internalChecked, setInternalChecked] = React210.useState(defaultChecked);
5755
- const [pressed, setPressed] = React210.useState(false);
5756
- const timeoutRef = React210.useRef(null);
5757
- const checked = isControlled ? controlledChecked : internalChecked;
6179
+ const group = React216.useContext(RadioGroupContext);
6180
+ const optionValue = value === void 0 ? "on" : String(value);
6181
+ const effectiveChecked = group ? group.value === optionValue : controlledChecked;
6182
+ const isControlled = effectiveChecked !== void 0 || Boolean(group);
6183
+ disabled = disabled || group?.disabled;
6184
+ name = group?.name ?? name;
6185
+ form = group?.form ?? form;
6186
+ required = required || group?.required;
6187
+ const [internalChecked, setInternalChecked] = React216.useState(defaultChecked);
6188
+ const [pressed, setPressed] = React216.useState(false);
6189
+ const timeoutRef = React216.useRef(null);
6190
+ const checked = isControlled ? Boolean(effectiveChecked) : internalChecked;
6191
+ const controlRef = React216.useRef(null);
5758
6192
  const iconSize = size === "small" ? 20 : 24;
5759
6193
  const handleClick = (e) => {
6194
+ e.preventDefault();
5760
6195
  if (disabled) return;
6196
+ if (name && !checked) {
6197
+ controlRef.current?.dispatchEvent(new CustomEvent("photonix-radio-select", {
6198
+ bubbles: true,
6199
+ detail: { name, form: controlRef.current.form }
6200
+ }));
6201
+ }
5761
6202
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5762
6203
  setPressed(true);
5763
6204
  timeoutRef.current = setTimeout(() => setPressed(false), 350);
@@ -5765,6 +6206,7 @@ var Radio = React210.forwardRef(
5765
6206
  if (!isControlled) {
5766
6207
  setInternalChecked(true);
5767
6208
  }
6209
+ group?.onChange(optionValue);
5768
6210
  if (onChange) {
5769
6211
  onChange(true);
5770
6212
  }
@@ -5773,11 +6215,22 @@ var Radio = React210.forwardRef(
5773
6215
  onClick(e);
5774
6216
  }
5775
6217
  };
5776
- React210.useEffect(() => {
6218
+ React216.useEffect(() => {
5777
6219
  return () => {
5778
6220
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5779
6221
  };
5780
6222
  }, []);
6223
+ React216.useEffect(() => {
6224
+ if (isControlled || !name) return;
6225
+ const clearSibling = (event) => {
6226
+ const selection = event;
6227
+ if (selection.target !== controlRef.current && selection.detail.name === name && selection.detail.form === controlRef.current?.form) {
6228
+ setInternalChecked(false);
6229
+ }
6230
+ };
6231
+ document.addEventListener("photonix-radio-select", clearSibling);
6232
+ return () => document.removeEventListener("photonix-radio-select", clearSibling);
6233
+ }, [isControlled, name]);
5781
6234
  const radioClasses = [
5782
6235
  "phx-radio",
5783
6236
  Radio_default.radioRoot,
@@ -5791,41 +6244,71 @@ var Radio = React210.forwardRef(
5791
6244
  disabled && Radio_default.disabled,
5792
6245
  label && className
5793
6246
  ].filter(Boolean).join(" ");
5794
- const radioContent = /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(
6247
+ const radioContent = /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(
5795
6248
  "button",
5796
6249
  {
5797
- ref,
6250
+ ref: (node) => {
6251
+ controlRef.current = node;
6252
+ if (typeof ref === "function") ref(node);
6253
+ else if (ref) ref.current = node;
6254
+ },
5798
6255
  type: "button",
6256
+ form,
6257
+ value,
6258
+ "aria-required": required || void 0,
5799
6259
  role: "radio",
5800
6260
  "aria-checked": checked,
5801
6261
  className: radioClasses,
5802
6262
  disabled,
5803
6263
  onClick: handleClick,
5804
6264
  style: !label ? style : void 0,
6265
+ tabIndex: group ? checked || group.value === void 0 ? 0 : -1 : void 0,
5805
6266
  ...rest,
5806
- children: /* @__PURE__ */ (0, import_jsx_runtime208.jsx)("span", { className: Radio_default.radioIcon, children: checked ? /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(RadioOutline, { size: iconSize }) : /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(CircleOutline, { size: iconSize }) })
6267
+ children: /* @__PURE__ */ (0, import_jsx_runtime213.jsx)("span", { className: Radio_default.radioIcon, children: checked ? /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(RadioOutline, { size: iconSize }) : /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(CircleOutline, { size: iconSize }) })
6268
+ }
6269
+ );
6270
+ const formInput = /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(
6271
+ NativeSelectionInput,
6272
+ {
6273
+ type: "radio",
6274
+ name,
6275
+ value,
6276
+ form,
6277
+ required,
6278
+ disabled,
6279
+ checked,
6280
+ defaultChecked,
6281
+ controlled: isControlled,
6282
+ controlRef,
6283
+ onReset: setInternalChecked
5807
6284
  }
5808
6285
  );
5809
6286
  if (label) {
5810
- return /* @__PURE__ */ (0, import_jsx_runtime208.jsxs)("label", { className: containerClasses, style, children: [
5811
- radioContent,
5812
- /* @__PURE__ */ (0, import_jsx_runtime208.jsx)("span", { className: Radio_default.radioLabel, children: label })
6287
+ return /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)(import_jsx_runtime213.Fragment, { children: [
6288
+ formInput,
6289
+ /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)("label", { className: containerClasses, style, children: [
6290
+ radioContent,
6291
+ /* @__PURE__ */ (0, import_jsx_runtime213.jsx)("span", { className: Radio_default.radioLabel, children: label })
6292
+ ] })
5813
6293
  ] });
5814
6294
  }
5815
- return radioContent;
6295
+ return /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)(import_jsx_runtime213.Fragment, { children: [
6296
+ formInput,
6297
+ radioContent
6298
+ ] });
5816
6299
  }
5817
6300
  );
5818
6301
  Radio.displayName = "Radio";
5819
6302
 
5820
6303
  // ../ultimate/src/components/switch/Switch.tsx
5821
- var React211 = __toESM(require("react"));
6304
+ var React217 = __toESM(require("react"));
5822
6305
 
5823
6306
  // ../ultimate/src/components/switch/Switch.module.css
5824
6307
  var Switch_default = {};
5825
6308
 
5826
6309
  // ../ultimate/src/components/switch/Switch.tsx
5827
- var import_jsx_runtime209 = require("react/jsx-runtime");
5828
- var Switch = React211.forwardRef(
6310
+ var import_jsx_runtime214 = require("react/jsx-runtime");
6311
+ var Switch = React217.forwardRef(
5829
6312
  ({
5830
6313
  className,
5831
6314
  checked: controlledChecked,
@@ -5835,14 +6318,19 @@ var Switch = React211.forwardRef(
5835
6318
  disabled,
5836
6319
  onChange,
5837
6320
  onClick,
6321
+ name,
6322
+ value,
6323
+ form,
6324
+ required,
5838
6325
  ...rest
5839
6326
  }, ref) => {
5840
6327
  const isControlled = controlledChecked !== void 0;
5841
- const [internalChecked, setInternalChecked] = React211.useState(defaultChecked);
5842
- const [pressed, setPressed] = React211.useState(false);
5843
- const timeoutRef = React211.useRef(null);
6328
+ const [internalChecked, setInternalChecked] = React217.useState(defaultChecked);
6329
+ const [pressed, setPressed] = React217.useState(false);
6330
+ const timeoutRef = React217.useRef(null);
5844
6331
  const checked = isControlled ? controlledChecked : internalChecked;
5845
6332
  const handleClick = (e) => {
6333
+ e.preventDefault();
5846
6334
  if (disabled) return;
5847
6335
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5848
6336
  setPressed(true);
@@ -5858,7 +6346,7 @@ var Switch = React211.forwardRef(
5858
6346
  onClick(e);
5859
6347
  }
5860
6348
  };
5861
- React211.useEffect(() => {
6349
+ React217.useEffect(() => {
5862
6350
  return () => {
5863
6351
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5864
6352
  };
@@ -5876,45 +6364,75 @@ var Switch = React211.forwardRef(
5876
6364
  Switch_default[size],
5877
6365
  disabled && Switch_default.disabled
5878
6366
  ].filter(Boolean).join(" ");
6367
+ const controlRef = React217.useRef(null);
5879
6368
  const iconSize = size === "small" ? 16 : 24;
5880
- const switchContent = /* @__PURE__ */ (0, import_jsx_runtime209.jsx)(
6369
+ const switchContent = /* @__PURE__ */ (0, import_jsx_runtime214.jsx)(
5881
6370
  "button",
5882
6371
  {
5883
- ref,
6372
+ ref: (node) => {
6373
+ controlRef.current = node;
6374
+ if (typeof ref === "function") ref(node);
6375
+ else if (ref) ref.current = node;
6376
+ },
5884
6377
  type: "button",
6378
+ form,
6379
+ value,
6380
+ "aria-required": required || void 0,
5885
6381
  role: "switch",
5886
6382
  "aria-checked": checked,
5887
6383
  className: switchClasses,
5888
6384
  disabled,
5889
6385
  onClick: handleClick,
5890
6386
  ...rest,
5891
- children: /* @__PURE__ */ (0, import_jsx_runtime209.jsx)("span", { className: Switch_default.switchTrack, children: /* @__PURE__ */ (0, import_jsx_runtime209.jsx)("span", { className: Switch_default.switchThumb, children: /* @__PURE__ */ (0, import_jsx_runtime209.jsx)("span", { className: Switch_default.switchThumbInner, children: checked && /* @__PURE__ */ (0, import_jsx_runtime209.jsx)("span", { className: Switch_default.switchIcon, children: /* @__PURE__ */ (0, import_jsx_runtime209.jsx)(CheckSmallOutline, { size: iconSize }) }) }) }) })
6387
+ children: /* @__PURE__ */ (0, import_jsx_runtime214.jsx)("span", { className: Switch_default.switchTrack, children: /* @__PURE__ */ (0, import_jsx_runtime214.jsx)("span", { className: Switch_default.switchThumb, children: /* @__PURE__ */ (0, import_jsx_runtime214.jsx)("span", { className: Switch_default.switchThumbInner, children: checked && /* @__PURE__ */ (0, import_jsx_runtime214.jsx)("span", { className: Switch_default.switchIcon, children: /* @__PURE__ */ (0, import_jsx_runtime214.jsx)(CheckSmallOutline, { size: iconSize }) }) }) }) })
6388
+ }
6389
+ );
6390
+ const formInput = /* @__PURE__ */ (0, import_jsx_runtime214.jsx)(
6391
+ NativeSelectionInput,
6392
+ {
6393
+ type: "checkbox",
6394
+ name,
6395
+ value,
6396
+ form,
6397
+ required,
6398
+ disabled,
6399
+ checked,
6400
+ defaultChecked,
6401
+ controlled: isControlled,
6402
+ controlRef,
6403
+ onReset: setInternalChecked
5892
6404
  }
5893
6405
  );
5894
6406
  if (label) {
5895
- return /* @__PURE__ */ (0, import_jsx_runtime209.jsxs)("label", { className: containerClasses, children: [
5896
- switchContent,
5897
- /* @__PURE__ */ (0, import_jsx_runtime209.jsx)("span", { className: Switch_default.switchLabel, children: label })
6407
+ return /* @__PURE__ */ (0, import_jsx_runtime214.jsxs)(import_jsx_runtime214.Fragment, { children: [
6408
+ formInput,
6409
+ /* @__PURE__ */ (0, import_jsx_runtime214.jsxs)("label", { className: containerClasses, children: [
6410
+ switchContent,
6411
+ /* @__PURE__ */ (0, import_jsx_runtime214.jsx)("span", { className: Switch_default.switchLabel, children: label })
6412
+ ] })
5898
6413
  ] });
5899
6414
  }
5900
- return switchContent;
6415
+ return /* @__PURE__ */ (0, import_jsx_runtime214.jsxs)(import_jsx_runtime214.Fragment, { children: [
6416
+ formInput,
6417
+ switchContent
6418
+ ] });
5901
6419
  }
5902
6420
  );
5903
6421
  Switch.displayName = "Switch";
5904
6422
 
5905
6423
  // ../ultimate/src/components/text-field/TextField.tsx
5906
- var React221 = __toESM(require("react"));
6424
+ var React228 = __toESM(require("react"));
5907
6425
  var import_react_dom2 = require("react-dom");
5908
6426
 
5909
6427
  // ../ultimate/src/components/divider/Divider.tsx
5910
- var React212 = __toESM(require("react"));
6428
+ var React218 = __toESM(require("react"));
5911
6429
 
5912
6430
  // ../ultimate/src/components/divider/Divider.module.css
5913
6431
  var Divider_default = {};
5914
6432
 
5915
6433
  // ../ultimate/src/components/divider/Divider.tsx
5916
- var import_jsx_runtime210 = require("react/jsx-runtime");
5917
- var Divider = React212.forwardRef(
6434
+ var import_jsx_runtime215 = require("react/jsx-runtime");
6435
+ var Divider = React218.forwardRef(
5918
6436
  ({
5919
6437
  orientation = "horizontal",
5920
6438
  variant = "solid",
@@ -5930,7 +6448,7 @@ var Divider = React212.forwardRef(
5930
6448
  Divider_default[`divider${variant.charAt(0).toUpperCase() + variant.slice(1)}${thicknessKey}`],
5931
6449
  className
5932
6450
  ].filter(Boolean).join(" ");
5933
- return /* @__PURE__ */ (0, import_jsx_runtime210.jsx)(
6451
+ return /* @__PURE__ */ (0, import_jsx_runtime215.jsx)(
5934
6452
  "hr",
5935
6453
  {
5936
6454
  ref,
@@ -5945,23 +6463,13 @@ var Divider = React212.forwardRef(
5945
6463
  Divider.displayName = "Divider";
5946
6464
 
5947
6465
  // ../ultimate/src/components/dropdown-list/DropdownList.tsx
5948
- var React220 = __toESM(require("react"));
6466
+ var React226 = __toESM(require("react"));
5949
6467
 
5950
6468
  // ../ultimate/src/components/search-field/SearchField.tsx
5951
- var React219 = __toESM(require("react"));
6469
+ var React225 = __toESM(require("react"));
5952
6470
 
5953
6471
  // ../ultimate/src/hooks/useComposedRefs.ts
5954
- var import_react2 = require("react");
5955
-
5956
- // ../ultimate/src/hooks/useCallbackRef.ts
5957
6472
  var import_react3 = require("react");
5958
- function useCallbackRef(callback) {
5959
- const callbackRef = (0, import_react3.useRef)(callback);
5960
- (0, import_react3.useEffect)(() => {
5961
- callbackRef.current = callback;
5962
- });
5963
- return (0, import_react3.useMemo)(() => ((...args) => callbackRef.current?.(...args)), []);
5964
- }
5965
6473
 
5966
6474
  // ../ultimate/src/hooks/useIsomorphicLayoutEffect.ts
5967
6475
  var import_react4 = require("react");
@@ -5994,69 +6502,56 @@ function useClickOutside(ref, handler, enabled = true, ignoredRefs = []) {
5994
6502
  }
5995
6503
 
5996
6504
  // ../ultimate/src/hooks/useBottomNavElevation.ts
5997
- var React213 = __toESM(require("react"));
5998
-
5999
- // ../ultimate/src/hooks/useControllableState.ts
6000
- var React214 = __toESM(require("react"));
6001
- function useControllableState({
6002
- value: valueProp,
6003
- defaultValue,
6004
- onChange
6005
- }) {
6006
- const [uncontrolledValue, setUncontrolledValue] = React214.useState(() => typeof defaultValue === "function" ? defaultValue() : defaultValue);
6007
- const isControlledRef = React214.useRef(valueProp !== void 0);
6008
- const isControlled = isControlledRef.current;
6009
- const value = isControlled ? valueProp : uncontrolledValue;
6010
- const handleChange = useCallbackRef(onChange);
6011
- const previousUncontrolledValueRef = React214.useRef(uncontrolledValue);
6012
- React214.useEffect(() => {
6013
- if (isControlled) return;
6014
- if (previousUncontrolledValueRef.current === uncontrolledValue) return;
6015
- previousUncontrolledValueRef.current = uncontrolledValue;
6016
- handleChange(uncontrolledValue);
6017
- }, [isControlled, uncontrolledValue, handleChange]);
6018
- const setValue = React214.useCallback(
6019
- (nextValue) => {
6020
- if (isControlled) {
6021
- const setter = nextValue;
6022
- const valueToEmit = typeof nextValue === "function" ? setter(valueProp) : nextValue;
6023
- handleChange(valueToEmit);
6024
- } else {
6025
- setUncontrolledValue((prev) => {
6026
- const setter = nextValue;
6027
- return typeof nextValue === "function" ? setter(prev) : nextValue;
6028
- });
6029
- }
6030
- },
6031
- [isControlled, valueProp, handleChange]
6032
- );
6033
- return [value, setValue];
6034
- }
6505
+ var React219 = __toESM(require("react"));
6035
6506
 
6036
6507
  // ../ultimate/src/hooks/useEscapeKeydown.ts
6037
6508
  var import_react6 = require("react");
6509
+
6510
+ // ../ultimate/src/internal/overlay/OverlayScope.tsx
6511
+ var React220 = __toESM(require("react"));
6512
+ var import_jsx_runtime216 = require("react/jsx-runtime");
6513
+ var OverlayDepthContext = React220.createContext(0);
6514
+
6515
+ // ../ultimate/src/hooks/useEscapeKeydown.ts
6516
+ var layersByDocument = /* @__PURE__ */ new WeakMap();
6038
6517
  function useEscapeKeydown(handler, enabled = true) {
6039
6518
  const handleEscape = useCallbackRef(handler);
6519
+ const depth = (0, import_react6.useContext)(OverlayDepthContext);
6040
6520
  (0, import_react6.useEffect)(() => {
6041
6521
  if (!enabled) return;
6522
+ const owner = document;
6523
+ let layers = layersByDocument.get(owner);
6524
+ if (!layers) {
6525
+ layers = [];
6526
+ layersByDocument.set(owner, layers);
6527
+ }
6528
+ const layer = { depth, handler: handleEscape };
6529
+ layers.push(layer);
6042
6530
  const onKeydown = (event) => {
6043
- if (event.key === "Escape") {
6044
- handleEscape(event);
6045
- }
6531
+ if (event.key !== "Escape" || event.isComposing || event.defaultPrevented) return;
6532
+ const top = layers.reduce((candidate, item) => !candidate || item.depth >= candidate.depth ? item : candidate, void 0);
6533
+ if (top !== layer) return;
6534
+ event.preventDefault();
6535
+ event.stopPropagation();
6536
+ layer.handler(event);
6046
6537
  };
6047
- document.addEventListener("keydown", onKeydown);
6048
- return () => document.removeEventListener("keydown", onKeydown);
6049
- }, [enabled, handleEscape]);
6538
+ owner.addEventListener("keydown", onKeydown);
6539
+ return () => {
6540
+ const index = layers.indexOf(layer);
6541
+ if (index >= 0) layers.splice(index, 1);
6542
+ owner.removeEventListener("keydown", onKeydown);
6543
+ };
6544
+ }, [enabled, handleEscape, depth]);
6050
6545
  }
6051
6546
 
6052
6547
  // ../ultimate/src/hooks/useFocusTrap.ts
6053
- var React215 = __toESM(require("react"));
6548
+ var React221 = __toESM(require("react"));
6054
6549
 
6055
6550
  // ../ultimate/src/hooks/useId.ts
6056
- var React216 = __toESM(require("react"));
6551
+ var React222 = __toESM(require("react"));
6057
6552
 
6058
6553
  // ../ultimate/src/hooks/useMediaQuery.ts
6059
- var React217 = __toESM(require("react"));
6554
+ var React223 = __toESM(require("react"));
6060
6555
 
6061
6556
  // ../ultimate/src/hooks/usePopoverPosition.ts
6062
6557
  var import_react7 = require("react");
@@ -6213,7 +6708,7 @@ var import_react10 = require("react");
6213
6708
  var import_react11 = require("react");
6214
6709
 
6215
6710
  // ../ultimate/src/hooks/useSubHeaderStickyState.ts
6216
- var React218 = __toESM(require("react"));
6711
+ var React224 = __toESM(require("react"));
6217
6712
 
6218
6713
  // ../ultimate/src/hooks/useVirtualList.ts
6219
6714
  var import_react12 = require("react");
@@ -6272,18 +6767,18 @@ var FOCUSABLE_SELECTOR = [
6272
6767
  ].join(", ");
6273
6768
  var isFocusable = (element) => {
6274
6769
  if (element.hasAttribute("disabled")) return false;
6275
- if (element.getAttribute("aria-hidden") === "true") return false;
6770
+ if (element.closest('[aria-hidden="true"], [inert], [hidden]')) return false;
6276
6771
  if (element.tabIndex < 0) return false;
6277
6772
  const style = window.getComputedStyle(element);
6278
6773
  if (style.display === "none" || style.visibility === "hidden") return false;
6279
6774
  return true;
6280
6775
  };
6281
- var focusNextElement = (currentElement) => {
6776
+ var focusNextElement = (currentElement, backwards = false) => {
6282
6777
  if (typeof document === "undefined") return;
6283
6778
  const focusableElements = Array.from(document.querySelectorAll(FOCUSABLE_SELECTOR)).filter(isFocusable);
6284
6779
  const currentIndex = focusableElements.indexOf(currentElement);
6285
6780
  if (currentIndex === -1) return;
6286
- const nextElement = focusableElements[currentIndex + 1];
6781
+ const nextElement = focusableElements[currentIndex + (backwards ? -1 : 1)];
6287
6782
  nextElement?.focus();
6288
6783
  };
6289
6784
 
@@ -6291,8 +6786,8 @@ var focusNextElement = (currentElement) => {
6291
6786
  var SearchField_default = {};
6292
6787
 
6293
6788
  // ../ultimate/src/components/search-field/SearchField.tsx
6294
- var import_jsx_runtime211 = require("react/jsx-runtime");
6295
- var SearchField = React219.forwardRef(
6789
+ var import_jsx_runtime217 = require("react/jsx-runtime");
6790
+ var SearchField = React225.forwardRef(
6296
6791
  ({
6297
6792
  placeholder = "Search",
6298
6793
  variant = "default",
@@ -6301,6 +6796,7 @@ var SearchField = React219.forwardRef(
6301
6796
  showClear = true,
6302
6797
  onClear,
6303
6798
  disabled,
6799
+ readOnly,
6304
6800
  className,
6305
6801
  style,
6306
6802
  onFocus,
@@ -6313,17 +6809,17 @@ var SearchField = React219.forwardRef(
6313
6809
  width,
6314
6810
  ...props
6315
6811
  }, ref) => {
6316
- const [focused, setFocused] = React219.useState(false);
6812
+ const [focused, setFocused] = React225.useState(false);
6317
6813
  const [valueState, setValueState] = useControllableState({
6318
6814
  value,
6319
6815
  defaultValue: defaultValue || "",
6320
6816
  onChange
6321
6817
  });
6322
- const inputRef = React219.useRef(null);
6323
- React219.useEffect(() => {
6818
+ const inputRef = React225.useRef(null);
6819
+ React225.useEffect(() => {
6324
6820
  if (!shortcutHint || disabled) return;
6325
6821
  const handleGlobalKeyDown = (e) => {
6326
- if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
6822
+ if (!e.isComposing && !e.defaultPrevented && (e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
6327
6823
  e.preventDefault();
6328
6824
  inputRef.current?.focus();
6329
6825
  }
@@ -6331,7 +6827,7 @@ var SearchField = React219.forwardRef(
6331
6827
  window.addEventListener("keydown", handleGlobalKeyDown);
6332
6828
  return () => window.removeEventListener("keydown", handleGlobalKeyDown);
6333
6829
  }, [shortcutHint, disabled]);
6334
- React219.useImperativeHandle(ref, () => inputRef.current);
6830
+ React225.useImperativeHandle(ref, () => inputRef.current);
6335
6831
  const currentValue = valueState;
6336
6832
  const handleFocus = (e) => {
6337
6833
  setFocused(true);
@@ -6342,6 +6838,7 @@ var SearchField = React219.forwardRef(
6342
6838
  onBlur?.(e);
6343
6839
  };
6344
6840
  const handleChange = (e) => {
6841
+ if (disabled || readOnly) return;
6345
6842
  setValueState(e.target.value);
6346
6843
  };
6347
6844
  const handleDoubleClick = (e) => {
@@ -6351,6 +6848,7 @@ var SearchField = React219.forwardRef(
6351
6848
  }
6352
6849
  };
6353
6850
  const handleClear = (e) => {
6851
+ if (disabled || readOnly) return;
6354
6852
  e.preventDefault();
6355
6853
  e.stopPropagation();
6356
6854
  setValueState("");
@@ -6358,12 +6856,13 @@ var SearchField = React219.forwardRef(
6358
6856
  inputRef.current?.focus();
6359
6857
  };
6360
6858
  const handleKeyDown = (e) => {
6859
+ if (disabled || e.nativeEvent.isComposing) return;
6361
6860
  if (e.key === "Enter") {
6362
6861
  e.preventDefault();
6363
6862
  focusNextElement(e.currentTarget);
6364
6863
  }
6365
6864
  };
6366
- return /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)(
6865
+ return /* @__PURE__ */ (0, import_jsx_runtime217.jsxs)(
6367
6866
  "div",
6368
6867
  {
6369
6868
  className: [
@@ -6379,13 +6878,14 @@ var SearchField = React219.forwardRef(
6379
6878
  style: { ...style, width },
6380
6879
  onClick: () => !disabled && inputRef.current?.focus(),
6381
6880
  children: [
6382
- /* @__PURE__ */ (0, import_jsx_runtime211.jsx)("span", { className: SearchField_default.searchFieldIcon, children: /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(SearchOutline, { size: size === "large" ? 24 : 20 }) }),
6383
- /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
6881
+ /* @__PURE__ */ (0, import_jsx_runtime217.jsx)("span", { className: SearchField_default.searchFieldIcon, children: /* @__PURE__ */ (0, import_jsx_runtime217.jsx)(SearchOutline, { size: size === "large" ? 24 : 20 }) }),
6882
+ /* @__PURE__ */ (0, import_jsx_runtime217.jsx)(
6384
6883
  "input",
6385
6884
  {
6386
6885
  ref: inputRef,
6387
6886
  className: SearchField_default.searchFieldInput,
6388
6887
  disabled,
6888
+ readOnly,
6389
6889
  onFocus: handleFocus,
6390
6890
  onBlur: handleBlur,
6391
6891
  onDoubleClick: handleDoubleClick,
@@ -6397,8 +6897,8 @@ var SearchField = React219.forwardRef(
6397
6897
  ...props
6398
6898
  }
6399
6899
  ),
6400
- /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)("div", { className: SearchField_default.searchFieldTrailingGroup, children: [
6401
- shortcutHint && (!focused || !currentValue) && /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
6900
+ /* @__PURE__ */ (0, import_jsx_runtime217.jsxs)("div", { className: SearchField_default.searchFieldTrailingGroup, children: [
6901
+ shortcutHint && (!focused || !currentValue) && /* @__PURE__ */ (0, import_jsx_runtime217.jsx)(
6402
6902
  Badge,
6403
6903
  {
6404
6904
  variant: "secondary",
@@ -6407,12 +6907,12 @@ var SearchField = React219.forwardRef(
6407
6907
  label: shortcutHint
6408
6908
  }
6409
6909
  ),
6410
- showClear && focused && currentValue && !disabled && /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
6910
+ showClear && focused && currentValue && !disabled && !readOnly && /* @__PURE__ */ (0, import_jsx_runtime217.jsx)(
6411
6911
  IconButton,
6412
6912
  {
6413
6913
  variant: "primary",
6414
6914
  shape: "pill",
6415
- icon: /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(CloseSmallOutline, {}),
6915
+ icon: /* @__PURE__ */ (0, import_jsx_runtime217.jsx)(CloseSmallOutline, {}),
6416
6916
  onMouseDown: (e) => e.preventDefault(),
6417
6917
  onClick: handleClear,
6418
6918
  tabIndex: -1,
@@ -6431,11 +6931,21 @@ SearchField.displayName = "SearchField";
6431
6931
  // ../ultimate/src/components/dropdown-list/DropdownList.module.css
6432
6932
  var DropdownList_default = {};
6433
6933
 
6934
+ // ../ultimate/src/internal/collection/getItemId.ts
6935
+ function getItemId(collectionId, part, key) {
6936
+ const escaped = key.replace(/[^A-Za-z0-9-]/g, (char) => `_${char.charCodeAt(0).toString(16)}_`);
6937
+ return `${collectionId}-${part}-${escaped}`;
6938
+ }
6939
+
6434
6940
  // ../ultimate/src/components/dropdown-list/DropdownList.tsx
6435
- var import_jsx_runtime212 = require("react/jsx-runtime");
6436
- var DropdownList = React220.forwardRef(
6941
+ var import_jsx_runtime218 = require("react/jsx-runtime");
6942
+ var DropdownList = React226.forwardRef(
6437
6943
  ({
6438
6944
  items,
6945
+ role = "listbox",
6946
+ id,
6947
+ "aria-label": ariaLabel,
6948
+ "aria-labelledby": ariaLabelledBy,
6439
6949
  value = [],
6440
6950
  size = "md",
6441
6951
  mode = "single",
@@ -6447,29 +6957,32 @@ var DropdownList = React220.forwardRef(
6447
6957
  className,
6448
6958
  style
6449
6959
  }, ref) => {
6450
- const [searchQuery, setSearchQuery] = React220.useState("");
6451
- const showSearch = items.length >= 10;
6452
- const selectedValues = React220.useMemo(() => {
6960
+ const typeaheadRef = React226.useRef({ text: "", time: 0 });
6961
+ const [searchQuery, setSearchQuery] = React226.useState("");
6962
+ const showSearch = role === "listbox" && items.length >= 10;
6963
+ const instanceId = React226.useId();
6964
+ const itemId = (value2) => value2 === void 0 ? void 0 : getItemId(instanceId, "item", value2);
6965
+ const selectedValues = React226.useMemo(() => {
6453
6966
  if (Array.isArray(value)) return value;
6454
6967
  return value ? [value] : [];
6455
6968
  }, [value]);
6456
- const filteredItems = React220.useMemo(() => {
6969
+ const filteredItems = React226.useMemo(() => {
6457
6970
  if (!searchQuery.trim()) return items;
6458
6971
  const query = searchQuery.toLowerCase();
6459
6972
  return items.filter(
6460
6973
  (item) => item.label.toLowerCase().includes(query)
6461
6974
  );
6462
6975
  }, [items, searchQuery]);
6463
- const selectableFilteredValues = React220.useMemo(() => filteredItems.filter((item) => !item.disabled).map((item) => item.value), [filteredItems]);
6976
+ const selectableFilteredValues = React226.useMemo(() => filteredItems.filter((item) => !item.disabled).map((item) => item.value), [filteredItems]);
6464
6977
  const showSelectAll = mode === "multi" && Boolean(selectAllLabel) && selectableFilteredValues.length > 0;
6465
6978
  const allFilteredSelected = showSelectAll && selectableFilteredValues.every((itemValue) => selectedValues.includes(itemValue));
6466
6979
  const someFilteredSelected = showSelectAll && !allFilteredSelected && selectableFilteredValues.some((itemValue) => selectedValues.includes(itemValue));
6467
- const handleSelectAllClick = React220.useCallback(() => {
6980
+ const handleSelectAllClick = React226.useCallback(() => {
6468
6981
  if (!showSelectAll) return;
6469
6982
  const nextValues = allFilteredSelected ? selectedValues.filter((itemValue) => !selectableFilteredValues.includes(itemValue)) : Array.from(/* @__PURE__ */ new Set([...selectedValues, ...selectableFilteredValues]));
6470
6983
  onChange?.(nextValues);
6471
6984
  }, [allFilteredSelected, onChange, selectableFilteredValues, selectedValues, showSelectAll]);
6472
- const displayItems = React220.useMemo(() => {
6985
+ const displayItems = React226.useMemo(() => {
6473
6986
  if (!showSelectAll || !selectAllLabel) return filteredItems;
6474
6987
  return [
6475
6988
  { value: "__phx_select_all__", label: selectAllLabel, __selectAll: true },
@@ -6492,10 +7005,10 @@ var DropdownList = React220.forwardRef(
6492
7005
  const isSelected = (itemValue) => {
6493
7006
  return selectedValues.includes(itemValue);
6494
7007
  };
6495
- const [showTopGradient, setShowTopGradient] = React220.useState(false);
6496
- const [showBottomGradient, setShowBottomGradient] = React220.useState(false);
6497
- const listRef = React220.useRef(null);
6498
- const handleScroll = React220.useCallback(() => {
7008
+ const [showTopGradient, setShowTopGradient] = React226.useState(false);
7009
+ const [showBottomGradient, setShowBottomGradient] = React226.useState(false);
7010
+ const listRef = React226.useRef(null);
7011
+ const handleScroll = React226.useCallback(() => {
6499
7012
  const el = listRef.current;
6500
7013
  if (!el) return;
6501
7014
  const scrollTop = el.scrollTop;
@@ -6504,7 +7017,7 @@ var DropdownList = React220.forwardRef(
6504
7017
  setShowTopGradient(scrollTop > 10);
6505
7018
  setShowBottomGradient(scrollTop + clientHeight < scrollHeight - 10);
6506
7019
  }, []);
6507
- React220.useEffect(() => {
7020
+ React226.useEffect(() => {
6508
7021
  handleScroll();
6509
7022
  }, [displayItems, handleScroll]);
6510
7023
  const ITEM_HEIGHT = size === "sm" ? 32 : 48;
@@ -6514,9 +7027,9 @@ var DropdownList = React220.forwardRef(
6514
7027
  itemHeight: ITEM_HEIGHT,
6515
7028
  containerHeight: parsedMaxHeight
6516
7029
  });
6517
- const [focusedIndex, setFocusedIndex] = React220.useState(-1);
6518
- const [isKeyboardMode, setIsKeyboardMode] = React220.useState(false);
6519
- React220.useEffect(() => {
7030
+ const [focusedIndex, setFocusedIndex] = React226.useState(-1);
7031
+ const [isKeyboardMode, setIsKeyboardMode] = React226.useState(false);
7032
+ React226.useEffect(() => {
6520
7033
  if (displayItems.length === 0) {
6521
7034
  setFocusedIndex(-1);
6522
7035
  return;
@@ -6533,7 +7046,7 @@ var DropdownList = React220.forwardRef(
6533
7046
  return prev;
6534
7047
  });
6535
7048
  }, [displayItems, value, mode]);
6536
- React220.useEffect(() => {
7049
+ React226.useEffect(() => {
6537
7050
  if (focusedIndex !== -1 && listRef.current) {
6538
7051
  const itemTop = focusedIndex * ITEM_HEIGHT;
6539
7052
  const itemBottom = itemTop + ITEM_HEIGHT;
@@ -6547,22 +7060,34 @@ var DropdownList = React220.forwardRef(
6547
7060
  }
6548
7061
  }
6549
7062
  }, [focusedIndex, ITEM_HEIGHT]);
6550
- const handleListScroll = React220.useCallback((e) => {
7063
+ const handleListScroll = React226.useCallback((e) => {
6551
7064
  handleScroll();
6552
7065
  if (isVirtual) onVirtualScroll(e);
6553
7066
  }, [handleScroll, isVirtual, onVirtualScroll]);
6554
7067
  const handleKeyDown = (e) => {
6555
- if (displayItems.length === 0) return;
7068
+ if (e.nativeEvent.isComposing || e.defaultPrevented || displayItems.length === 0) return;
6556
7069
  if (["ArrowDown", "ArrowUp", "Home", "End", "Enter", " "].includes(e.key)) {
6557
7070
  setIsKeyboardMode(true);
6558
7071
  }
6559
7072
  const isSearchFocus = e.target.tagName === "INPUT";
6560
7073
  if (e.key === "ArrowDown") {
6561
7074
  e.preventDefault();
6562
- setFocusedIndex((prev) => Math.min(prev + 1, displayItems.length - 1));
7075
+ setFocusedIndex((prev) => {
7076
+ for (let offset = 1; offset <= displayItems.length; offset++) {
7077
+ const next = (prev + offset + displayItems.length) % displayItems.length;
7078
+ if (displayItems[next] && !displayItems[next].disabled) return next;
7079
+ }
7080
+ return -1;
7081
+ });
6563
7082
  } else if (e.key === "ArrowUp") {
6564
7083
  e.preventDefault();
6565
- setFocusedIndex((prev) => prev <= 0 ? displayItems.length - 1 : prev - 1);
7084
+ setFocusedIndex((prev) => {
7085
+ for (let offset = 1; offset <= displayItems.length; offset++) {
7086
+ const next = ((prev < 0 ? 0 : prev) - offset + displayItems.length) % displayItems.length;
7087
+ if (displayItems[next] && !displayItems[next].disabled) return next;
7088
+ }
7089
+ return -1;
7090
+ });
6566
7091
  } else if (e.key === "Enter") {
6567
7092
  e.preventDefault();
6568
7093
  if (focusedIndex !== -1) {
@@ -6584,16 +7109,32 @@ var DropdownList = React220.forwardRef(
6584
7109
  } else if (e.key === "Home") {
6585
7110
  if (!isSearchFocus) {
6586
7111
  e.preventDefault();
6587
- setFocusedIndex(0);
7112
+ setFocusedIndex(displayItems.findIndex((item) => !item.disabled));
6588
7113
  }
6589
7114
  } else if (e.key === "End") {
6590
7115
  if (!isSearchFocus) {
6591
7116
  e.preventDefault();
6592
- setFocusedIndex(displayItems.length - 1);
7117
+ setFocusedIndex(displayItems.map((item) => !item.disabled).lastIndexOf(true));
7118
+ }
7119
+ } else if (!isSearchFocus && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
7120
+ const now = Date.now();
7121
+ const previous = typeaheadRef.current;
7122
+ const text = `${now - previous.time < 600 ? previous.text : ""}${e.key.toLocaleLowerCase()}`;
7123
+ typeaheadRef.current = { text, time: now };
7124
+ const query = [...text].every((character) => character === text[0]) ? text[0] : text;
7125
+ for (let offset = 1; offset <= displayItems.length; offset++) {
7126
+ const next = (focusedIndex + offset + displayItems.length) % displayItems.length;
7127
+ const item = displayItems[next];
7128
+ if (item && !item.disabled && item.label.toLocaleLowerCase().startsWith(query)) {
7129
+ e.preventDefault();
7130
+ setIsKeyboardMode(true);
7131
+ setFocusedIndex(next);
7132
+ break;
7133
+ }
6593
7134
  }
6594
7135
  }
6595
7136
  };
6596
- return /* @__PURE__ */ (0, import_jsx_runtime212.jsxs)(
7137
+ return /* @__PURE__ */ (0, import_jsx_runtime218.jsxs)(
6597
7138
  "div",
6598
7139
  {
6599
7140
  ref,
@@ -6602,38 +7143,43 @@ var DropdownList = React220.forwardRef(
6602
7143
  onKeyDown: handleKeyDown,
6603
7144
  onMouseMove: () => setIsKeyboardMode(false),
6604
7145
  children: [
6605
- showSearch && /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("div", { className: DropdownList_default.dropdownListSearchWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
7146
+ showSearch && /* @__PURE__ */ (0, import_jsx_runtime218.jsx)("div", { className: DropdownList_default.dropdownListSearchWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime218.jsx)(
6606
7147
  SearchField,
6607
7148
  {
6608
7149
  placeholder: searchPlaceholder,
6609
7150
  value: searchQuery,
6610
7151
  onChange: setSearchQuery,
6611
- shortcutHint: "Ctrl + /"
7152
+ shortcutHint: "Ctrl + /",
7153
+ onKeyDown: () => {
7154
+ }
6612
7155
  }
6613
7156
  ) }),
6614
- /* @__PURE__ */ (0, import_jsx_runtime212.jsxs)("div", { className: DropdownList_default.dropdownListItemsListContainer, children: [
6615
- /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("div", { className: [
7157
+ /* @__PURE__ */ (0, import_jsx_runtime218.jsxs)("div", { className: DropdownList_default.dropdownListItemsListContainer, children: [
7158
+ /* @__PURE__ */ (0, import_jsx_runtime218.jsx)("div", { className: [
6616
7159
  DropdownList_default.dropdownListGradient,
6617
7160
  DropdownList_default.dropdownListGradientTop,
6618
7161
  showTopGradient && DropdownList_default.dropdownListGradientVisible
6619
7162
  ].filter(Boolean).join(" ") }),
6620
- /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
7163
+ /* @__PURE__ */ (0, import_jsx_runtime218.jsx)(
6621
7164
  "div",
6622
7165
  {
6623
7166
  ref: listRef,
6624
7167
  className: `${DropdownList_default.dropdownListItemsList} scrollbarSm`,
6625
7168
  style: { maxHeight },
6626
- role: "listbox",
7169
+ role,
7170
+ id,
7171
+ "aria-label": ariaLabel,
7172
+ "aria-labelledby": ariaLabelledBy,
6627
7173
  tabIndex: 0,
6628
- "aria-multiselectable": mode === "multi" ? true : void 0,
6629
- "aria-activedescendant": focusedIndex !== -1 ? `dropdown-item-${displayItems[focusedIndex]?.value}` : void 0,
7174
+ "aria-multiselectable": role === "listbox" && mode === "multi" ? true : void 0,
7175
+ "aria-activedescendant": focusedIndex !== -1 ? itemId(displayItems[focusedIndex]?.value) : void 0,
6630
7176
  onScroll: handleListScroll,
6631
- children: displayItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("div", { className: DropdownList_default.dropdownListEmptyState, children: "No results found" }) : isVirtual ? /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("div", { style: { height: totalHeight, position: "relative" }, children: virtualItems.map(({ index, style: style2 }) => {
7177
+ children: displayItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime218.jsx)("div", { className: DropdownList_default.dropdownListEmptyState, children: "No results found" }) : isVirtual ? /* @__PURE__ */ (0, import_jsx_runtime218.jsx)("div", { style: { height: totalHeight, position: "relative" }, children: virtualItems.map(({ index, style: style2 }) => {
6632
7178
  const item = displayItems[index];
6633
7179
  if (!item) return null;
6634
7180
  const isFocused = index === focusedIndex;
6635
7181
  const isSelectAllItem = Boolean(item.__selectAll);
6636
- return /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("div", { style: style2, children: /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
7182
+ return /* @__PURE__ */ (0, import_jsx_runtime218.jsx)("div", { style: style2, children: /* @__PURE__ */ (0, import_jsx_runtime218.jsx)(
6637
7183
  "div",
6638
7184
  {
6639
7185
  className: [
@@ -6641,10 +7187,10 @@ var DropdownList = React220.forwardRef(
6641
7187
  showDividers && DropdownList_default.dropdownListItemWrapperWithDivider,
6642
7188
  item.divider && DropdownList_default.dropdownListItemWrapperWithBottomDivider
6643
7189
  ].filter(Boolean).join(" "),
6644
- children: /* @__PURE__ */ (0, import_jsx_runtime212.jsxs)(
7190
+ children: /* @__PURE__ */ (0, import_jsx_runtime218.jsxs)(
6645
7191
  "div",
6646
7192
  {
6647
- id: `dropdown-item-${item.value}`,
7193
+ id: itemId(item.value),
6648
7194
  className: [
6649
7195
  DropdownList_default.dropdownListItem,
6650
7196
  size === "sm" && DropdownList_default.dropdownListItemSm,
@@ -6653,11 +7199,11 @@ var DropdownList = React220.forwardRef(
6653
7199
  item.disabled && DropdownList_default.dropdownListItemDisabled
6654
7200
  ].filter(Boolean).join(" "),
6655
7201
  onClick: () => handleItemClick(item.value, item.disabled, isSelectAllItem),
6656
- role: "option",
6657
- "aria-selected": isSelectAllItem ? allFilteredSelected : isSelected(item.value),
7202
+ role: role === "menu" ? "menuitem" : "option",
7203
+ "aria-selected": role === "listbox" ? isSelectAllItem ? allFilteredSelected : isSelected(item.value) : void 0,
6658
7204
  "aria-disabled": item.disabled,
6659
7205
  children: [
6660
- mode === "multi" && /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
7206
+ mode === "multi" && /* @__PURE__ */ (0, import_jsx_runtime218.jsx)(
6661
7207
  Checkbox,
6662
7208
  {
6663
7209
  checked: isSelectAllItem ? allFilteredSelected : isSelected(item.value),
@@ -6669,9 +7215,9 @@ var DropdownList = React220.forwardRef(
6669
7215
  tabIndex: -1
6670
7216
  }
6671
7217
  ),
6672
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("span", { className: DropdownList_default.dropdownListItemIcon, children: React220.isValidElement(item.icon) ? React220.cloneElement(item.icon, { size: size === "sm" ? 20 : 24 }) : item.icon }),
6673
- /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("span", { className: DropdownList_default.dropdownListItemLabel, children: item.label }),
6674
- mode === "single" && isSelected(item.value) && /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("span", { className: DropdownList_default.dropdownListCheckmark, children: /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(CheckSmallOutline, { size: size === "sm" ? 20 : 24 }) })
7218
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime218.jsx)("span", { className: DropdownList_default.dropdownListItemIcon, children: React226.isValidElement(item.icon) ? React226.cloneElement(item.icon, { size: size === "sm" ? 20 : 24 }) : item.icon }),
7219
+ /* @__PURE__ */ (0, import_jsx_runtime218.jsx)("span", { className: DropdownList_default.dropdownListItemLabel, children: item.label }),
7220
+ mode === "single" && isSelected(item.value) && /* @__PURE__ */ (0, import_jsx_runtime218.jsx)("span", { className: DropdownList_default.dropdownListCheckmark, children: /* @__PURE__ */ (0, import_jsx_runtime218.jsx)(CheckSmallOutline, { size: size === "sm" ? 20 : 24 }) })
6675
7221
  ]
6676
7222
  }
6677
7223
  )
@@ -6680,7 +7226,7 @@ var DropdownList = React220.forwardRef(
6680
7226
  }) }) : displayItems.map((item, index) => {
6681
7227
  const isFocused = index === focusedIndex;
6682
7228
  const isSelectAllItem = Boolean(item.__selectAll);
6683
- return /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
7229
+ return /* @__PURE__ */ (0, import_jsx_runtime218.jsx)(
6684
7230
  "div",
6685
7231
  {
6686
7232
  className: [
@@ -6688,10 +7234,10 @@ var DropdownList = React220.forwardRef(
6688
7234
  showDividers && DropdownList_default.dropdownListItemWrapperWithDivider,
6689
7235
  item.divider && DropdownList_default.dropdownListItemWrapperWithBottomDivider
6690
7236
  ].filter(Boolean).join(" "),
6691
- children: /* @__PURE__ */ (0, import_jsx_runtime212.jsxs)(
7237
+ children: /* @__PURE__ */ (0, import_jsx_runtime218.jsxs)(
6692
7238
  "div",
6693
7239
  {
6694
- id: `dropdown-item-${item.value}`,
7240
+ id: itemId(item.value),
6695
7241
  className: [
6696
7242
  DropdownList_default.dropdownListItem,
6697
7243
  size === "sm" && DropdownList_default.dropdownListItemSm,
@@ -6700,11 +7246,11 @@ var DropdownList = React220.forwardRef(
6700
7246
  item.disabled && DropdownList_default.dropdownListItemDisabled
6701
7247
  ].filter(Boolean).join(" "),
6702
7248
  onClick: () => handleItemClick(item.value, item.disabled, isSelectAllItem),
6703
- role: "option",
6704
- "aria-selected": isSelectAllItem ? allFilteredSelected : isSelected(item.value),
7249
+ role: role === "menu" ? "menuitem" : "option",
7250
+ "aria-selected": role === "listbox" ? isSelectAllItem ? allFilteredSelected : isSelected(item.value) : void 0,
6705
7251
  "aria-disabled": item.disabled,
6706
7252
  children: [
6707
- mode === "multi" && /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
7253
+ mode === "multi" && /* @__PURE__ */ (0, import_jsx_runtime218.jsx)(
6708
7254
  Checkbox,
6709
7255
  {
6710
7256
  checked: isSelectAllItem ? allFilteredSelected : isSelected(item.value),
@@ -6716,9 +7262,9 @@ var DropdownList = React220.forwardRef(
6716
7262
  tabIndex: -1
6717
7263
  }
6718
7264
  ),
6719
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("span", { className: DropdownList_default.dropdownListItemIcon, children: React220.isValidElement(item.icon) ? React220.cloneElement(item.icon, { size: size === "sm" ? 20 : 24 }) : item.icon }),
6720
- /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("span", { className: DropdownList_default.dropdownListItemLabel, children: item.label }),
6721
- mode === "single" && isSelected(item.value) && /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("span", { className: DropdownList_default.dropdownListCheckmark, children: /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(CheckSmallOutline, { size: size === "sm" ? 20 : 24 }) })
7265
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime218.jsx)("span", { className: DropdownList_default.dropdownListItemIcon, children: React226.isValidElement(item.icon) ? React226.cloneElement(item.icon, { size: size === "sm" ? 20 : 24 }) : item.icon }),
7266
+ /* @__PURE__ */ (0, import_jsx_runtime218.jsx)("span", { className: DropdownList_default.dropdownListItemLabel, children: item.label }),
7267
+ mode === "single" && isSelected(item.value) && /* @__PURE__ */ (0, import_jsx_runtime218.jsx)("span", { className: DropdownList_default.dropdownListCheckmark, children: /* @__PURE__ */ (0, import_jsx_runtime218.jsx)(CheckSmallOutline, { size: size === "sm" ? 20 : 24 }) })
6722
7268
  ]
6723
7269
  }
6724
7270
  )
@@ -6728,7 +7274,7 @@ var DropdownList = React220.forwardRef(
6728
7274
  })
6729
7275
  }
6730
7276
  ),
6731
- /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("div", { className: [
7277
+ /* @__PURE__ */ (0, import_jsx_runtime218.jsx)("div", { className: [
6732
7278
  DropdownList_default.dropdownListGradient,
6733
7279
  DropdownList_default.dropdownListGradientBottom,
6734
7280
  showBottomGradient && DropdownList_default.dropdownListGradientVisible
@@ -6801,9 +7347,26 @@ var calculateCursorPosition = (prevValue, nextValue, prevCursorPos) => {
6801
7347
  // ../ultimate/src/components/text-field/TextField.module.css
6802
7348
  var TextField_default = {};
6803
7349
 
7350
+ // ../ultimate/src/internal/form/useNativeFieldReset.ts
7351
+ var React227 = __toESM(require("react"));
7352
+ function useNativeFieldReset(ref, resetState, resetValue, formId) {
7353
+ const reset = useCallbackRef((event) => {
7354
+ queueMicrotask(() => {
7355
+ if (event.defaultPrevented || !ref.current) return;
7356
+ resetState();
7357
+ ref.current.value = resetValue;
7358
+ });
7359
+ });
7360
+ React227.useEffect(() => {
7361
+ const form = ref.current?.form;
7362
+ form?.addEventListener("reset", reset);
7363
+ return () => form?.removeEventListener("reset", reset);
7364
+ }, [formId, ref, reset]);
7365
+ }
7366
+
6804
7367
  // ../ultimate/src/components/text-field/TextField.tsx
6805
- var import_jsx_runtime213 = require("react/jsx-runtime");
6806
- var TextField = React221.forwardRef(
7368
+ var import_jsx_runtime219 = require("react/jsx-runtime");
7369
+ var TextField = React228.forwardRef(
6807
7370
  ({
6808
7371
  label,
6809
7372
  labelStyle = "outside",
@@ -6830,6 +7393,7 @@ var TextField = React221.forwardRef(
6830
7393
  readOnly,
6831
7394
  className,
6832
7395
  style,
7396
+ inputStyle,
6833
7397
  onFocus,
6834
7398
  onBlur,
6835
7399
  onChange,
@@ -6844,23 +7408,32 @@ var TextField = React221.forwardRef(
6844
7408
  selectOnFocus = false,
6845
7409
  ...props
6846
7410
  }, ref) => {
6847
- const [focused, setFocused] = React221.useState(false);
6848
- const [isDropdownOpen, setIsDropdownOpen] = React221.useState(false);
6849
- const [passwordVisible, setPasswordVisible] = React221.useState(false);
6850
- const inputRef = React221.useRef(null);
6851
- const [valueState, setValueState] = useControllableState({
7411
+ const generatedId = React228.useId();
7412
+ const inputId = props.id ?? generatedId;
7413
+ const helperId = `${inputId}-help`;
7414
+ const [focused, setFocused] = React228.useState(false);
7415
+ const [isDropdownOpen, setIsDropdownOpen] = React228.useState(false);
7416
+ const [passwordVisible, setPasswordVisible] = React228.useState(false);
7417
+ const inputRef = React228.useRef(null);
7418
+ const [valueState, setValueState, resetValueState] = useControllableState({
6852
7419
  value,
6853
7420
  defaultValue: defaultValue || "",
6854
7421
  onChange
6855
7422
  });
6856
7423
  const currentValue = valueState;
7424
+ useNativeFieldReset(
7425
+ inputRef,
7426
+ resetValueState,
7427
+ String(value === void 0 ? defaultValue ?? "" : currentValue ?? ""),
7428
+ props.form
7429
+ );
6857
7430
  const [dropdownValueState, setDropdownValueState] = useControllableState({
6858
7431
  value: trailingDropdownValue,
6859
7432
  defaultValue: defaultTrailingDropdownValue || "",
6860
7433
  onChange: onTrailingDropdownChange
6861
7434
  });
6862
- const triggerWrapperRef = React221.useRef(null);
6863
- const popoverRef = React221.useRef(null);
7435
+ const triggerWrapperRef = React228.useRef(null);
7436
+ const popoverRef = React228.useRef(null);
6864
7437
  const { style: popoverStyle } = usePopoverPosition(triggerWrapperRef, popoverRef, isDropdownOpen, {
6865
7438
  margin: 8,
6866
7439
  strategy: portal ? "fixed" : "absolute",
@@ -6873,7 +7446,7 @@ var TextField = React221.forwardRef(
6873
7446
  [triggerWrapperRef]
6874
7447
  );
6875
7448
  useEscapeKeydown(() => setIsDropdownOpen(false), isDropdownOpen);
6876
- const keepSelectionOnMouseUpRef = React221.useRef(false);
7449
+ const keepSelectionOnMouseUpRef = React228.useRef(false);
6877
7450
  const handleFocus = (e) => {
6878
7451
  setFocused(true);
6879
7452
  if (selectOnFocus) e.currentTarget.select();
@@ -6890,7 +7463,7 @@ var TextField = React221.forwardRef(
6890
7463
  }
6891
7464
  props.onMouseUp?.(e);
6892
7465
  };
6893
- const isPhoneFormat = React221.useMemo(() => {
7466
+ const isPhoneFormat = React228.useMemo(() => {
6894
7467
  if (inputFormat) return false;
6895
7468
  if (!leadingText) return false;
6896
7469
  return (leadingText.startsWith("+") || /^\d+$/.test(leadingText.replace(/[\s()]/g, ""))) && !leadingText.includes("://");
@@ -6900,7 +7473,7 @@ var TextField = React221.forwardRef(
6900
7473
  const separator = formatOptions?.separator ?? ",";
6901
7474
  const allowDecimal = formatOptions?.allowDecimal ?? true;
6902
7475
  const maxDigits = formatOptions?.maxDigits;
6903
- const applyFormat = React221.useCallback((raw) => {
7476
+ const applyFormat = React228.useCallback((raw) => {
6904
7477
  switch (activeFormat) {
6905
7478
  case "currency": {
6906
7479
  let cleaned = raw;
@@ -6936,7 +7509,7 @@ var TextField = React221.forwardRef(
6936
7509
  }
6937
7510
  onBlur?.(e);
6938
7511
  };
6939
- React221.useEffect(() => {
7512
+ React228.useEffect(() => {
6940
7513
  if (activeFormat && currentValue) {
6941
7514
  const formatted = applyFormat(String(currentValue));
6942
7515
  if (currentValue !== formatted) {
@@ -7035,7 +7608,7 @@ var TextField = React221.forwardRef(
7035
7608
  displayedDropdownLabel = selectedOption.label;
7036
7609
  }
7037
7610
  }
7038
- const dropdownMenu = isDropdownOpen && dropdownListItems && /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(
7611
+ const dropdownMenu = isDropdownOpen && dropdownListItems && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
7039
7612
  "div",
7040
7613
  {
7041
7614
  ref: popoverRef,
@@ -7044,7 +7617,7 @@ var TextField = React221.forwardRef(
7044
7617
  ...popoverStyle,
7045
7618
  minWidth: triggerWrapperRef.current?.offsetWidth || 120
7046
7619
  },
7047
- children: /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(
7620
+ children: /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
7048
7621
  DropdownList,
7049
7622
  {
7050
7623
  items: dropdownListItems,
@@ -7057,7 +7630,7 @@ var TextField = React221.forwardRef(
7057
7630
  )
7058
7631
  }
7059
7632
  );
7060
- return /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)(
7633
+ return /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)(
7061
7634
  "div",
7062
7635
  {
7063
7636
  className: [
@@ -7069,16 +7642,16 @@ var TextField = React221.forwardRef(
7069
7642
  ].filter(Boolean).join(" "),
7070
7643
  style: { ...style, width },
7071
7644
  children: [
7072
- shouldShowLabelOutside && /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)("label", { className: [
7645
+ shouldShowLabelOutside && /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("label", { htmlFor: inputId, className: [
7073
7646
  TextField_default.textFieldLabel,
7074
7647
  TextField_default.outsideLabel,
7075
7648
  size === "medium" && TextField_default.outsideLabelMedium,
7076
7649
  size === "small" && TextField_default.outsideLabelSmall
7077
7650
  ].filter(Boolean).join(" "), children: [
7078
7651
  label,
7079
- required && /* @__PURE__ */ (0, import_jsx_runtime213.jsx)("span", { className: TextField_default.textFieldRequiredIndicator, children: " *" })
7652
+ required && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { "aria-hidden": "true", className: TextField_default.textFieldRequiredIndicator, children: " *" })
7080
7653
  ] }),
7081
- /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)(
7654
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)(
7082
7655
  "div",
7083
7656
  {
7084
7657
  className: [
@@ -7094,26 +7667,32 @@ var TextField = React221.forwardRef(
7094
7667
  ].filter(Boolean).join(" "),
7095
7668
  onClick: () => !disabled && !readOnly && !focused && inputRef.current?.focus(),
7096
7669
  children: [
7097
- !shouldShowLabelInside && leadingIcon && /* @__PURE__ */ (0, import_jsx_runtime213.jsx)("span", { className: TextField_default.textFieldLeadingIcon, children: leadingIcon }),
7098
- !shouldShowLabelInside && leadingText && /* @__PURE__ */ (0, import_jsx_runtime213.jsx)("span", { className: TextField_default.textFieldLeadingText, children: leadingText }),
7099
- /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)("div", { className: TextField_default.textFieldInputWrapper, children: [
7100
- shouldShowLabelInside && /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)(
7101
- "span",
7670
+ !shouldShowLabelInside && leadingIcon && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: TextField_default.textFieldLeadingIcon, children: leadingIcon }),
7671
+ !shouldShowLabelInside && leadingText && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: TextField_default.textFieldLeadingText, children: leadingText }),
7672
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: TextField_default.textFieldInputWrapper, children: [
7673
+ shouldShowLabelInside && /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)(
7674
+ "label",
7102
7675
  {
7676
+ htmlFor: inputId,
7103
7677
  className: [
7104
7678
  TextField_default.textFieldInlineLabel,
7105
7679
  (focused || currentValue) && TextField_default.shrunk
7106
7680
  ].filter(Boolean).join(" "),
7107
7681
  children: [
7108
7682
  label,
7109
- required && /* @__PURE__ */ (0, import_jsx_runtime213.jsx)("span", { className: TextField_default.textFieldRequiredIndicator, children: " *" })
7683
+ required && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { "aria-hidden": "true", className: TextField_default.textFieldRequiredIndicator, children: " *" })
7110
7684
  ]
7111
7685
  }
7112
7686
  ),
7113
- /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(
7687
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
7114
7688
  "input",
7115
7689
  {
7690
+ style: inputStyle,
7116
7691
  ...props,
7692
+ id: inputId,
7693
+ required,
7694
+ "aria-invalid": error || props["aria-invalid"],
7695
+ "aria-describedby": mergeAriaIds(props["aria-describedby"], helperText ? helperId : void 0),
7117
7696
  ref: (node) => {
7118
7697
  inputRef.current = node;
7119
7698
  if (typeof ref === "function") ref(node);
@@ -7144,8 +7723,8 @@ var TextField = React221.forwardRef(
7144
7723
  }
7145
7724
  )
7146
7725
  ] }),
7147
- /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)("div", { className: TextField_default.textFieldTrailingGroup, children: [
7148
- shortcutHint && !focused && /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(
7726
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: TextField_default.textFieldTrailingGroup, children: [
7727
+ shortcutHint && !focused && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
7149
7728
  Badge,
7150
7729
  {
7151
7730
  variant: "secondary",
@@ -7154,12 +7733,12 @@ var TextField = React221.forwardRef(
7154
7733
  label: shortcutHint
7155
7734
  }
7156
7735
  ),
7157
- showClear && focused && currentValue && !disabled && !readOnly && /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(
7736
+ showClear && focused && currentValue && !disabled && !readOnly && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
7158
7737
  IconButton,
7159
7738
  {
7160
7739
  variant: "primary",
7161
7740
  shape: "pill",
7162
- icon: /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(CloseSmallOutline, {}),
7741
+ icon: /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(CloseSmallOutline, {}),
7163
7742
  onMouseDown: (e) => e.preventDefault(),
7164
7743
  onClick: handleClear,
7165
7744
  tabIndex: -1,
@@ -7167,13 +7746,13 @@ var TextField = React221.forwardRef(
7167
7746
  className: TextField_default.textFieldClearButton
7168
7747
  }
7169
7748
  ),
7170
- (trailingDropdownLabel || trailingDropdownOptions) && /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)(
7749
+ (trailingDropdownLabel || trailingDropdownOptions) && /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)(
7171
7750
  "div",
7172
7751
  {
7173
7752
  ref: triggerWrapperRef,
7174
7753
  className: TextField_default.textFieldTrailingDropdownWrapper,
7175
7754
  children: [
7176
- /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)(
7755
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)(
7177
7756
  "div",
7178
7757
  {
7179
7758
  className: [
@@ -7182,12 +7761,12 @@ var TextField = React221.forwardRef(
7182
7761
  ].filter(Boolean).join(" "),
7183
7762
  onClick: handleDropdownClick,
7184
7763
  children: [
7185
- /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(Divider, { orientation: "vertical", className: TextField_default.textFieldSuffixDivider }),
7186
- /* @__PURE__ */ (0, import_jsx_runtime213.jsx)("span", { children: displayedDropdownLabel }),
7187
- /* @__PURE__ */ (0, import_jsx_runtime213.jsx)("span", { className: [
7764
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(Divider, { orientation: "vertical", className: TextField_default.textFieldSuffixDivider }),
7765
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { children: displayedDropdownLabel }),
7766
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: [
7188
7767
  TextField_default.textFieldChevronIcon,
7189
7768
  isDropdownOpen && TextField_default.rotated
7190
- ].filter(Boolean).join(" "), children: /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(ChevronDownSmallOutline, { size: 20 }) })
7769
+ ].filter(Boolean).join(" "), children: /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(ChevronDownSmallOutline, { size: 20 }) })
7191
7770
  ]
7192
7771
  }
7193
7772
  ),
@@ -7195,7 +7774,7 @@ var TextField = React221.forwardRef(
7195
7774
  ]
7196
7775
  }
7197
7776
  ),
7198
- activeFormat === "password" && /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(
7777
+ activeFormat === "password" && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
7199
7778
  "div",
7200
7779
  {
7201
7780
  className: [TextField_default.textFieldTrailingIconWrapper, TextField_default.textFieldPasswordToggleButton].join(" "),
@@ -7206,12 +7785,20 @@ var TextField = React221.forwardRef(
7206
7785
  }
7207
7786
  },
7208
7787
  role: "button",
7209
- tabIndex: -1,
7788
+ tabIndex: disabled ? -1 : 0,
7789
+ "aria-disabled": disabled || void 0,
7790
+ onKeyDown: (e) => {
7791
+ if (!disabled && (e.key === "Enter" || e.key === " ")) {
7792
+ e.preventDefault();
7793
+ e.stopPropagation();
7794
+ togglePasswordVisibility(e);
7795
+ }
7796
+ },
7210
7797
  "aria-label": passwordVisible ? "Hide password" : "Show password",
7211
- children: /* @__PURE__ */ (0, import_jsx_runtime213.jsx)("span", { className: TextField_default.textFieldPasswordToggle, children: passwordVisible ? /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(EyeOffOutline, {}) : /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(EyeOutline, {}) })
7798
+ children: /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: TextField_default.textFieldPasswordToggle, children: passwordVisible ? /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(EyeOffOutline, {}) : /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(EyeOutline, {}) })
7212
7799
  }
7213
7800
  ),
7214
- trailingIcon && activeFormat !== "password" && /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)(
7801
+ trailingIcon && activeFormat !== "password" && /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)(
7215
7802
  "div",
7216
7803
  {
7217
7804
  className: TextField_default.textFieldTrailingIconWrapper,
@@ -7222,7 +7809,7 @@ var TextField = React221.forwardRef(
7222
7809
  }
7223
7810
  },
7224
7811
  children: [
7225
- /* @__PURE__ */ (0, import_jsx_runtime213.jsx)(Divider, { orientation: "vertical", className: TextField_default.textFieldSuffixDivider }),
7812
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(Divider, { orientation: "vertical", className: TextField_default.textFieldSuffixDivider }),
7226
7813
  trailingIcon
7227
7814
  ]
7228
7815
  }
@@ -7231,12 +7818,12 @@ var TextField = React221.forwardRef(
7231
7818
  ]
7232
7819
  }
7233
7820
  ),
7234
- (helperText || showCharacterCount && maxLength) && /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)("div", { className: TextField_default.textFieldFooter, children: [
7235
- helperText && /* @__PURE__ */ (0, import_jsx_runtime213.jsx)("span", { className: [
7821
+ (helperText || showCharacterCount && maxLength) && /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: TextField_default.textFieldFooter, children: [
7822
+ helperText && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { id: helperId, className: [
7236
7823
  TextField_default.textFieldHelperText,
7237
7824
  error && TextField_default.errorText
7238
7825
  ].filter(Boolean).join(" "), children: helperText }),
7239
- showCharacterCount && maxLength && /* @__PURE__ */ (0, import_jsx_runtime213.jsxs)("span", { className: TextField_default.textFieldCharacterCount, children: [
7826
+ showCharacterCount && maxLength && /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("span", { className: TextField_default.textFieldCharacterCount, children: [
7240
7827
  String(currentValue || "").length,
7241
7828
  "/",
7242
7829
  maxLength
@@ -7250,14 +7837,14 @@ var TextField = React221.forwardRef(
7250
7837
  TextField.displayName = "TextField";
7251
7838
 
7252
7839
  // ../ultimate/src/components/text-area/TextArea.tsx
7253
- var React222 = __toESM(require("react"));
7840
+ var React229 = __toESM(require("react"));
7254
7841
 
7255
7842
  // ../ultimate/src/components/text-area/TextArea.module.css
7256
7843
  var TextArea_default = {};
7257
7844
 
7258
7845
  // ../ultimate/src/components/text-area/TextArea.tsx
7259
- var import_jsx_runtime214 = require("react/jsx-runtime");
7260
- var TextArea = React222.forwardRef(
7846
+ var import_jsx_runtime220 = require("react/jsx-runtime");
7847
+ var TextArea = React229.forwardRef(
7261
7848
  ({
7262
7849
  label,
7263
7850
  labelStyle = "outside",
@@ -7283,13 +7870,20 @@ var TextArea = React222.forwardRef(
7283
7870
  fullWidth = true,
7284
7871
  ...props
7285
7872
  }, ref) => {
7286
- const [focused, setFocused] = React222.useState(false);
7287
- const [valueState, setValueState] = useControllableState({
7873
+ const [focused, setFocused] = React229.useState(false);
7874
+ const textareaRef = React229.useRef(null);
7875
+ const [valueState, setValueState, resetValueState] = useControllableState({
7288
7876
  value,
7289
7877
  defaultValue: defaultValue || "",
7290
7878
  onChange
7291
7879
  });
7292
7880
  const currentValue = valueState;
7881
+ useNativeFieldReset(
7882
+ textareaRef,
7883
+ resetValueState,
7884
+ String(value === void 0 ? defaultValue ?? "" : currentValue ?? ""),
7885
+ props.form
7886
+ );
7293
7887
  const charCount = currentValue?.length || 0;
7294
7888
  const shouldShowCount = showCount ?? maxLength !== void 0;
7295
7889
  const handleFocus = (e) => {
@@ -7307,11 +7901,12 @@ var TextArea = React222.forwardRef(
7307
7901
  }
7308
7902
  setValueState(newValue);
7309
7903
  };
7310
- const generatedId = React222.useId();
7904
+ const generatedId = React229.useId();
7311
7905
  const shouldShowLabelOutside = label && labelStyle === "outside";
7312
7906
  const shouldShowLabelInside = label && labelStyle === "inside";
7313
7907
  const textareaId = id ?? generatedId;
7314
- return /* @__PURE__ */ (0, import_jsx_runtime214.jsxs)(
7908
+ const helperId = `${textareaId}-help`;
7909
+ return /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)(
7315
7910
  "div",
7316
7911
  {
7317
7912
  className: [
@@ -7323,12 +7918,12 @@ var TextArea = React222.forwardRef(
7323
7918
  ].filter(Boolean).join(" "),
7324
7919
  style: { ...style, width },
7325
7920
  children: [
7326
- shouldShowLabelOutside && /* @__PURE__ */ (0, import_jsx_runtime214.jsxs)("label", { className: TextArea_default.textAreaOutsideLabel, children: [
7921
+ shouldShowLabelOutside && /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("label", { htmlFor: textareaId, className: TextArea_default.textAreaOutsideLabel, children: [
7327
7922
  label,
7328
- required && /* @__PURE__ */ (0, import_jsx_runtime214.jsx)("span", { className: TextArea_default.textAreaRequiredIndicator, children: " *" })
7923
+ required && /* @__PURE__ */ (0, import_jsx_runtime220.jsx)("span", { "aria-hidden": "true", className: TextArea_default.textAreaRequiredIndicator, children: " *" })
7329
7924
  ] }),
7330
- /* @__PURE__ */ (0, import_jsx_runtime214.jsxs)("div", { className: TextArea_default.textAreaInputWrapper, children: [
7331
- shouldShowLabelInside && /* @__PURE__ */ (0, import_jsx_runtime214.jsxs)(
7925
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: TextArea_default.textAreaInputWrapper, children: [
7926
+ shouldShowLabelInside && /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)(
7332
7927
  "label",
7333
7928
  {
7334
7929
  className: [
@@ -7338,14 +7933,18 @@ var TextArea = React222.forwardRef(
7338
7933
  htmlFor: textareaId,
7339
7934
  children: [
7340
7935
  label,
7341
- required && /* @__PURE__ */ (0, import_jsx_runtime214.jsx)("span", { className: TextArea_default.textAreaRequiredIndicator, children: " *" })
7936
+ required && /* @__PURE__ */ (0, import_jsx_runtime220.jsx)("span", { "aria-hidden": "true", className: TextArea_default.textAreaRequiredIndicator, children: " *" })
7342
7937
  ]
7343
7938
  }
7344
7939
  ),
7345
- /* @__PURE__ */ (0, import_jsx_runtime214.jsx)(
7940
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
7346
7941
  "textarea",
7347
7942
  {
7348
- ref,
7943
+ ref: (node) => {
7944
+ textareaRef.current = node;
7945
+ if (typeof ref === "function") ref(node);
7946
+ else if (ref) ref.current = node;
7947
+ },
7349
7948
  id: textareaId,
7350
7949
  className: [
7351
7950
  TextArea_default.textAreaInput,
@@ -7365,16 +7964,19 @@ var TextArea = React222.forwardRef(
7365
7964
  rows,
7366
7965
  style: { resize },
7367
7966
  maxLength: maxLength ?? void 0,
7368
- ...props
7967
+ ...props,
7968
+ required,
7969
+ "aria-invalid": error || props["aria-invalid"],
7970
+ "aria-describedby": mergeAriaIds(props["aria-describedby"], helperText ? helperId : void 0)
7369
7971
  }
7370
7972
  )
7371
7973
  ] }),
7372
- (helperText || shouldShowCount) && /* @__PURE__ */ (0, import_jsx_runtime214.jsxs)("div", { className: TextArea_default.textAreaFooter, children: [
7373
- helperText && /* @__PURE__ */ (0, import_jsx_runtime214.jsx)("span", { className: [
7974
+ (helperText || shouldShowCount) && /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: TextArea_default.textAreaFooter, children: [
7975
+ helperText && /* @__PURE__ */ (0, import_jsx_runtime220.jsx)("span", { id: helperId, className: [
7374
7976
  TextArea_default.textAreaHelperText,
7375
7977
  error && TextArea_default.textAreaErrorText
7376
7978
  ].filter(Boolean).join(" "), children: helperText }),
7377
- shouldShowCount && /* @__PURE__ */ (0, import_jsx_runtime214.jsxs)("span", { className: TextArea_default.textAreaCharCount, children: [
7979
+ shouldShowCount && /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("span", { className: TextArea_default.textAreaCharCount, children: [
7378
7980
  charCount,
7379
7981
  maxLength !== void 0 ? `/${maxLength}` : ""
7380
7982
  ] })
@@ -7387,16 +7989,16 @@ var TextArea = React222.forwardRef(
7387
7989
  TextArea.displayName = "TextArea";
7388
7990
 
7389
7991
  // ../ultimate/src/components/avatar/Avatar.tsx
7390
- var React223 = __toESM(require("react"));
7992
+ var React230 = __toESM(require("react"));
7391
7993
 
7392
7994
  // ../ultimate/src/components/avatar/Avatar.module.css
7393
7995
  var Avatar_default = {};
7394
7996
 
7395
7997
  // ../ultimate/src/components/avatar/Avatar.tsx
7396
- var import_jsx_runtime215 = require("react/jsx-runtime");
7397
- var Avatar = React223.forwardRef(
7998
+ var import_jsx_runtime221 = require("react/jsx-runtime");
7999
+ var Avatar = React230.forwardRef(
7398
8000
  ({ src, alt, name, icon, size = "40", status, stroke, className, onClick, ...rest }, ref) => {
7399
- const [hasError, setHasError] = React223.useState(false);
8001
+ const [hasError, setHasError] = React230.useState(false);
7400
8002
  const isInteractive = !!onClick;
7401
8003
  const Component = isInteractive ? "button" : "div";
7402
8004
  const getInitials = (userName) => {
@@ -7405,7 +8007,7 @@ var Avatar = React223.forwardRef(
7405
8007
  };
7406
8008
  const renderContent = () => {
7407
8009
  if (src && !hasError) {
7408
- return /* @__PURE__ */ (0, import_jsx_runtime215.jsx)(
8010
+ return /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(
7409
8011
  "img",
7410
8012
  {
7411
8013
  src,
@@ -7416,9 +8018,9 @@ var Avatar = React223.forwardRef(
7416
8018
  );
7417
8019
  }
7418
8020
  if (name) {
7419
- return /* @__PURE__ */ (0, import_jsx_runtime215.jsx)("span", { className: Avatar_default.avatarInitials, children: getInitials(name) });
8021
+ return /* @__PURE__ */ (0, import_jsx_runtime221.jsx)("span", { className: Avatar_default.avatarInitials, children: getInitials(name) });
7420
8022
  }
7421
- return /* @__PURE__ */ (0, import_jsx_runtime215.jsx)("span", { className: Avatar_default.avatarIcon, children: icon || /* @__PURE__ */ (0, import_jsx_runtime215.jsx)(UserOutline, {}) });
8023
+ return /* @__PURE__ */ (0, import_jsx_runtime221.jsx)("span", { className: Avatar_default.avatarIcon, children: icon || /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(UserOutline, {}) });
7422
8024
  };
7423
8025
  const avatarClasses = [
7424
8026
  "phx-avatar",
@@ -7428,7 +8030,7 @@ var Avatar = React223.forwardRef(
7428
8030
  isInteractive && Avatar_default.interactive,
7429
8031
  className
7430
8032
  ].filter(Boolean).join(" ");
7431
- return /* @__PURE__ */ (0, import_jsx_runtime215.jsxs)(
8033
+ return /* @__PURE__ */ (0, import_jsx_runtime221.jsxs)(
7432
8034
  Component,
7433
8035
  {
7434
8036
  ref,
@@ -7437,8 +8039,8 @@ var Avatar = React223.forwardRef(
7437
8039
  ...isInteractive ? { type: "button" } : {},
7438
8040
  ...rest,
7439
8041
  children: [
7440
- /* @__PURE__ */ (0, import_jsx_runtime215.jsx)("div", { className: Avatar_default.avatarContent, children: renderContent() }),
7441
- status && /* @__PURE__ */ (0, import_jsx_runtime215.jsx)(
8042
+ /* @__PURE__ */ (0, import_jsx_runtime221.jsx)("div", { className: Avatar_default.avatarContent, children: renderContent() }),
8043
+ status && /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(
7442
8044
  Badge,
7443
8045
  {
7444
8046
  className: ["phx-avatar-status", Avatar_default.avatarStatus].filter(Boolean).join(" "),
@@ -7454,16 +8056,16 @@ var Avatar = React223.forwardRef(
7454
8056
  Avatar.displayName = "Avatar";
7455
8057
 
7456
8058
  // ../ultimate/src/components/avatar/AvatarGroup.tsx
7457
- var React224 = __toESM(require("react"));
8059
+ var React231 = __toESM(require("react"));
7458
8060
 
7459
8061
  // ../ultimate/src/components/avatar/AvatarGroup.module.css
7460
8062
  var AvatarGroup_default = {};
7461
8063
 
7462
8064
  // ../ultimate/src/components/avatar/AvatarGroup.tsx
7463
- var import_jsx_runtime216 = require("react/jsx-runtime");
7464
- var AvatarGroup = React224.forwardRef(
8065
+ var import_jsx_runtime222 = require("react/jsx-runtime");
8066
+ var AvatarGroup = React231.forwardRef(
7465
8067
  ({ children, size = "40", max = 5, showStatus = false, className, ...rest }, ref) => {
7466
- const childrenArray = React224.Children.toArray(children);
8068
+ const childrenArray = React231.Children.toArray(children);
7467
8069
  const hasOverflow = childrenArray.length > max;
7468
8070
  const visibleCount = hasOverflow ? max - 1 : childrenArray.length;
7469
8071
  const visibleChildren = childrenArray.slice(0, visibleCount);
@@ -7474,10 +8076,10 @@ var AvatarGroup = React224.forwardRef(
7474
8076
  AvatarGroup_default[`size${size}`],
7475
8077
  className
7476
8078
  ].filter(Boolean).join(" ");
7477
- return /* @__PURE__ */ (0, import_jsx_runtime216.jsxs)("div", { ref, className: groupClasses, ...rest, children: [
8079
+ return /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)("div", { ref, className: groupClasses, ...rest, children: [
7478
8080
  visibleChildren.map((child, index) => {
7479
- if (React224.isValidElement(child)) {
7480
- return React224.cloneElement(child, {
8081
+ if (React231.isValidElement(child)) {
8082
+ return React231.cloneElement(child, {
7481
8083
  size,
7482
8084
  stroke: true,
7483
8085
  key: index,
@@ -7491,7 +8093,7 @@ var AvatarGroup = React224.forwardRef(
7491
8093
  }
7492
8094
  return child;
7493
8095
  }),
7494
- hasOverflow && /* @__PURE__ */ (0, import_jsx_runtime216.jsx)(
8096
+ hasOverflow && /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
7495
8097
  Avatar,
7496
8098
  {
7497
8099
  size,
@@ -7507,7 +8109,7 @@ var AvatarGroup = React224.forwardRef(
7507
8109
  AvatarGroup.displayName = "AvatarGroup";
7508
8110
 
7509
8111
  // ../ultimate/src/components/avatar/AvatarTemplate.tsx
7510
- var React225 = __toESM(require("react"));
8112
+ var React232 = __toESM(require("react"));
7511
8113
 
7512
8114
  // ../ultimate/src/img/Image=1.png
7513
8115
  var Image_1_default = "./Image=1-LTDZFXMH.png";
@@ -7528,7 +8130,7 @@ var Image_5_default = "./Image=5-7WFTKF52.png";
7528
8130
  var Image_6_default = "./Image=6-U5HZ7K2N.png";
7529
8131
 
7530
8132
  // ../ultimate/src/components/avatar/AvatarTemplate.tsx
7531
- var import_jsx_runtime217 = require("react/jsx-runtime");
8133
+ var import_jsx_runtime223 = require("react/jsx-runtime");
7532
8134
  var toImageSrc = (image) => {
7533
8135
  if (typeof image === "string") {
7534
8136
  return image;
@@ -7539,10 +8141,10 @@ var toImageSrc = (image) => {
7539
8141
  return image.default;
7540
8142
  };
7541
8143
  var AVATAR_IMAGES = [Image_1_default, Image_2_default, Image_3_default, Image_4_default, Image_5_default, Image_6_default].map(toImageSrc);
7542
- var AvatarTemplate = React225.forwardRef(
8144
+ var AvatarTemplate = React232.forwardRef(
7543
8145
  ({ templateId = 1, ...rest }, ref) => {
7544
8146
  const src = AVATAR_IMAGES[templateId - 1];
7545
- return /* @__PURE__ */ (0, import_jsx_runtime217.jsx)(Avatar, { ref, src, className: ["phx-avatar-template", rest.className].filter(Boolean).join(" "), ...rest });
8147
+ return /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(Avatar, { ref, src, className: ["phx-avatar-template", rest.className].filter(Boolean).join(" "), ...rest });
7546
8148
  }
7547
8149
  );
7548
8150
  AvatarTemplate.displayName = "AvatarTemplate";
@@ -7551,7 +8153,7 @@ AvatarTemplate.displayName = "AvatarTemplate";
7551
8153
  var Image_default = {};
7552
8154
 
7553
8155
  // ../ultimate/src/components/image/Image.tsx
7554
- var import_jsx_runtime218 = require("react/jsx-runtime");
8156
+ var import_jsx_runtime224 = require("react/jsx-runtime");
7555
8157
  var Image = ({
7556
8158
  src,
7557
8159
  alt,
@@ -7561,7 +8163,7 @@ var Image = ({
7561
8163
  style
7562
8164
  }) => {
7563
8165
  const ratioClass = aspectRatio.replace(":", "");
7564
- return /* @__PURE__ */ (0, import_jsx_runtime218.jsx)(
8166
+ return /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
7565
8167
  "div",
7566
8168
  {
7567
8169
  className: [
@@ -7571,7 +8173,7 @@ var Image = ({
7571
8173
  className
7572
8174
  ].filter(Boolean).join(" "),
7573
8175
  style,
7574
- children: /* @__PURE__ */ (0, import_jsx_runtime218.jsx)(
8176
+ children: /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
7575
8177
  "img",
7576
8178
  {
7577
8179
  src,
@@ -7585,14 +8187,14 @@ var Image = ({
7585
8187
  };
7586
8188
 
7587
8189
  // ../ultimate/src/components/skeleton/Skeleton.tsx
7588
- var React226 = __toESM(require("react"));
8190
+ var React233 = __toESM(require("react"));
7589
8191
 
7590
8192
  // ../ultimate/src/components/skeleton/Skeleton.module.css
7591
8193
  var Skeleton_default = {};
7592
8194
 
7593
8195
  // ../ultimate/src/components/skeleton/Skeleton.tsx
7594
- var import_jsx_runtime219 = require("react/jsx-runtime");
7595
- var Skeleton = React226.forwardRef(
8196
+ var import_jsx_runtime225 = require("react/jsx-runtime");
8197
+ var Skeleton = React233.forwardRef(
7596
8198
  ({ variant = "text", width, height, rounded, className, style, ...rest }, ref) => {
7597
8199
  const skeletonClasses = [
7598
8200
  "phx-skeleton",
@@ -7606,7 +8208,7 @@ var Skeleton = React226.forwardRef(
7606
8208
  ...height !== void 0 && { height: typeof height === "number" ? `${height}px` : height },
7607
8209
  ...style
7608
8210
  };
7609
- return /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
8211
+ return /* @__PURE__ */ (0, import_jsx_runtime225.jsx)(
7610
8212
  "div",
7611
8213
  {
7612
8214
  ref,
@@ -7622,14 +8224,14 @@ var Skeleton = React226.forwardRef(
7622
8224
  Skeleton.displayName = "Skeleton";
7623
8225
 
7624
8226
  // ../ultimate/src/components/chip/Chip.tsx
7625
- var React227 = __toESM(require("react"));
8227
+ var React234 = __toESM(require("react"));
7626
8228
 
7627
8229
  // ../ultimate/src/components/chip/Chip.module.css
7628
8230
  var Chip_default = {};
7629
8231
 
7630
8232
  // ../ultimate/src/components/chip/Chip.tsx
7631
- var import_jsx_runtime220 = require("react/jsx-runtime");
7632
- var Chip = React227.forwardRef(
8233
+ var import_jsx_runtime226 = require("react/jsx-runtime");
8234
+ var Chip = React234.forwardRef(
7633
8235
  ({
7634
8236
  label,
7635
8237
  icon,
@@ -7637,9 +8239,12 @@ var Chip = React227.forwardRef(
7637
8239
  badge,
7638
8240
  variant = "outline",
7639
8241
  size = "large",
8242
+ shape = "pill",
7640
8243
  disabled,
7641
8244
  hasDropdown,
7642
8245
  onClear,
8246
+ onRemove,
8247
+ removeLabel,
7643
8248
  actionIcon,
7644
8249
  onAction,
7645
8250
  actionLabel,
@@ -7655,6 +8260,7 @@ var Chip = React227.forwardRef(
7655
8260
  Chip_default.chipRoot,
7656
8261
  Chip_default[variant],
7657
8262
  Chip_default[size],
8263
+ shape === "rounded" && Chip_default.rounded,
7658
8264
  disabled && Chip_default.disabled,
7659
8265
  isClickable && Chip_default.clickable,
7660
8266
  avatar && Chip_default.hasAvatar,
@@ -7663,28 +8269,30 @@ var Chip = React227.forwardRef(
7663
8269
  ].filter(Boolean).join(" ");
7664
8270
  const badgeColor = variant === "filled" ? "white" : "black";
7665
8271
  const trailingIconSize = size === "large" ? 20 : 16;
8272
+ const renderCloseButton = (onPress, ariaLabel) => /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(
8273
+ "button",
8274
+ {
8275
+ type: "button",
8276
+ className: Chip_default.chipDelete,
8277
+ onClick: (e) => {
8278
+ e.stopPropagation();
8279
+ if (!disabled) onPress?.(e);
8280
+ },
8281
+ disabled,
8282
+ "aria-label": ariaLabel,
8283
+ children: /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(CancelFilled, { size: trailingIconSize })
8284
+ }
8285
+ );
7666
8286
  const renderTrailing = () => {
8287
+ if (onRemove) return renderCloseButton(onRemove, removeLabel ?? `Remove ${label}`);
7667
8288
  const hasAction = Boolean(actionIcon && onAction);
7668
8289
  if (!hasDropdown && !hasAction) return null;
7669
8290
  if (variant === "filled" && hasDropdown && !hasAction) {
7670
- return /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
7671
- "button",
7672
- {
7673
- type: "button",
7674
- className: Chip_default.chipDelete,
7675
- onClick: (e) => {
7676
- e.stopPropagation();
7677
- if (!disabled && onClear) onClear(e);
7678
- },
7679
- disabled,
7680
- "aria-label": `Clear ${label}`,
7681
- children: /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(CancelFilled, { size: trailingIconSize })
7682
- }
7683
- );
8291
+ return renderCloseButton(onClear, `Clear ${label}`);
7684
8292
  }
7685
- return /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("span", { className: Chip_default.chipTrailing, children: [
7686
- hasDropdown && /* @__PURE__ */ (0, import_jsx_runtime220.jsx)("span", { className: Chip_default.chipTrailingIcon, children: /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(ChevronDownSmallOutline, { size: trailingIconSize }) }),
7687
- hasAction && /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
8293
+ return /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)("span", { className: Chip_default.chipTrailing, children: [
8294
+ hasDropdown && /* @__PURE__ */ (0, import_jsx_runtime226.jsx)("span", { className: Chip_default.chipTrailingIcon, children: /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(ChevronDownSmallOutline, { size: trailingIconSize }) }),
8295
+ hasAction && /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(
7688
8296
  "button",
7689
8297
  {
7690
8298
  type: "button",
@@ -7700,7 +8308,7 @@ var Chip = React227.forwardRef(
7700
8308
  )
7701
8309
  ] });
7702
8310
  };
7703
- return /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
8311
+ return /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(
7704
8312
  "div",
7705
8313
  {
7706
8314
  ref,
@@ -7709,15 +8317,22 @@ var Chip = React227.forwardRef(
7709
8317
  role: isClickable ? "button" : void 0,
7710
8318
  tabIndex: isClickable ? 0 : void 0,
7711
8319
  ...rest,
7712
- children: /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: Chip_default.chipContainer, children: [
7713
- avatar && /* @__PURE__ */ (0, import_jsx_runtime220.jsx)("div", { className: Chip_default.chipAvatar, children: React227.isValidElement(avatar) ? React227.cloneElement(avatar, {
8320
+ onKeyDown: (event) => {
8321
+ rest.onKeyDown?.(event);
8322
+ if (!event.defaultPrevented && event.target === event.currentTarget && isClickable && (event.key === "Enter" || event.key === " ")) {
8323
+ event.preventDefault();
8324
+ event.currentTarget.click();
8325
+ }
8326
+ },
8327
+ children: /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)("div", { className: Chip_default.chipContainer, children: [
8328
+ avatar && /* @__PURE__ */ (0, import_jsx_runtime226.jsx)("div", { className: Chip_default.chipAvatar, children: React234.isValidElement(avatar) ? React234.cloneElement(avatar, {
7714
8329
  size: size === "large" ? "32" : "24",
7715
8330
  stroke: variant === "filled" || avatar.props.stroke
7716
8331
  }) : avatar }),
7717
- !avatar && icon && /* @__PURE__ */ (0, import_jsx_runtime220.jsx)("span", { className: Chip_default.chipIcon, children: icon }),
7718
- /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("span", { className: Chip_default.chipContent, children: [
7719
- /* @__PURE__ */ (0, import_jsx_runtime220.jsx)("span", { className: Chip_default.chipLabel, children: label }),
7720
- shouldShowBadge && /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
8332
+ !avatar && icon && /* @__PURE__ */ (0, import_jsx_runtime226.jsx)("span", { className: Chip_default.chipIcon, children: icon }),
8333
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)("span", { className: Chip_default.chipContent, children: [
8334
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsx)("span", { className: Chip_default.chipLabel, children: label }),
8335
+ shouldShowBadge && /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(
7721
8336
  Badge,
7722
8337
  {
7723
8338
  count: typeof badge === "number" ? badge : void 0,
@@ -7737,16 +8352,16 @@ var Chip = React227.forwardRef(
7737
8352
  Chip.displayName = "Chip";
7738
8353
 
7739
8354
  // ../ultimate/src/components/chip-bar/ChipBar.tsx
7740
- var React228 = __toESM(require("react"));
8355
+ var React235 = __toESM(require("react"));
7741
8356
 
7742
8357
  // ../ultimate/src/components/chip-bar/ChipBar.module.css
7743
8358
  var ChipBar_default = {};
7744
8359
 
7745
8360
  // ../ultimate/src/components/chip-bar/ChipBar.tsx
7746
- var import_jsx_runtime221 = require("react/jsx-runtime");
8361
+ var import_jsx_runtime227 = require("react/jsx-runtime");
7747
8362
  var OVERFLOW_BUTTON_SIZE = 32;
7748
8363
  var MASK_FADE_SIZE = 44;
7749
- var ChipBar = React228.forwardRef(
8364
+ var ChipBar = React235.forwardRef(
7750
8365
  ({
7751
8366
  leading,
7752
8367
  children,
@@ -7758,13 +8373,13 @@ var ChipBar = React228.forwardRef(
7758
8373
  className,
7759
8374
  ...rest
7760
8375
  }, ref) => {
7761
- const [showLeftGradient, setShowLeftGradient] = React228.useState(false);
7762
- const [showRightGradient, setShowRightGradient] = React228.useState(false);
7763
- const [internalIsStuck, setInternalIsStuck] = React228.useState(false);
8376
+ const [showLeftGradient, setShowLeftGradient] = React235.useState(false);
8377
+ const [showRightGradient, setShowRightGradient] = React235.useState(false);
8378
+ const [internalIsStuck, setInternalIsStuck] = React235.useState(false);
7764
8379
  const isStuck = stuck !== void 0 ? stuck : internalIsStuck;
7765
- const listRef = React228.useRef(null);
7766
- const containerRef = React228.useRef(null);
7767
- const updateScrollGradients = React228.useCallback(() => {
8380
+ const listRef = React235.useRef(null);
8381
+ const containerRef = React235.useRef(null);
8382
+ const updateScrollGradients = React235.useCallback(() => {
7768
8383
  const el = listRef.current;
7769
8384
  if (el) {
7770
8385
  const { scrollLeft, scrollWidth, clientWidth } = el;
@@ -7772,7 +8387,7 @@ var ChipBar = React228.forwardRef(
7772
8387
  setShowRightGradient(Math.ceil(scrollLeft + clientWidth) < scrollWidth);
7773
8388
  }
7774
8389
  }, []);
7775
- React228.useEffect(() => {
8390
+ React235.useEffect(() => {
7776
8391
  const el = listRef.current;
7777
8392
  if (el) {
7778
8393
  updateScrollGradients();
@@ -7799,7 +8414,7 @@ var ChipBar = React228.forwardRef(
7799
8414
  });
7800
8415
  }
7801
8416
  };
7802
- React228.useEffect(() => {
8417
+ React235.useEffect(() => {
7803
8418
  if (!sticky) return;
7804
8419
  const container = containerRef.current;
7805
8420
  if (!container) return;
@@ -7831,7 +8446,7 @@ var ChipBar = React228.forwardRef(
7831
8446
  window.removeEventListener("resize", checkStuck);
7832
8447
  };
7833
8448
  }, [sticky]);
7834
- const setRefs = React228.useCallback((node) => {
8449
+ const setRefs = React235.useCallback((node) => {
7835
8450
  containerRef.current = node;
7836
8451
  if (typeof ref === "function") {
7837
8452
  ref(node);
@@ -7845,7 +8460,7 @@ var ChipBar = React228.forwardRef(
7845
8460
  "--chip-bar-left-button-offset": showLeftGradient ? `${OVERFLOW_BUTTON_SIZE}px` : "0px",
7846
8461
  "--chip-bar-right-button-offset": showRightGradient ? `${OVERFLOW_BUTTON_SIZE}px` : "0px"
7847
8462
  };
7848
- return /* @__PURE__ */ (0, import_jsx_runtime221.jsxs)(
8463
+ return /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)(
7849
8464
  "div",
7850
8465
  {
7851
8466
  ref: setRefs,
@@ -7864,14 +8479,14 @@ var ChipBar = React228.forwardRef(
7864
8479
  },
7865
8480
  ...rest,
7866
8481
  children: [
7867
- leading && /* @__PURE__ */ (0, import_jsx_runtime221.jsxs)("div", { className: ChipBar_default.chipBarLeading, children: [
7868
- React228.isValidElement(leading) ? React228.cloneElement(leading, {
8482
+ leading && /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: ChipBar_default.chipBarLeading, children: [
8483
+ React235.isValidElement(leading) ? React235.cloneElement(leading, {
7869
8484
  size: size === "large" ? "large" : "medium"
7870
8485
  }) : leading,
7871
- showDivider && /* @__PURE__ */ (0, import_jsx_runtime221.jsx)("div", { className: ChipBar_default.chipBarDivider })
8486
+ showDivider && /* @__PURE__ */ (0, import_jsx_runtime227.jsx)("div", { className: ChipBar_default.chipBarDivider })
7872
8487
  ] }),
7873
- /* @__PURE__ */ (0, import_jsx_runtime221.jsxs)("div", { className: ChipBar_default.chipBarScrollOuter, children: [
7874
- /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(
8488
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: ChipBar_default.chipBarScrollOuter, children: [
8489
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
7875
8490
  "div",
7876
8491
  {
7877
8492
  className: [
@@ -7880,7 +8495,7 @@ var ChipBar = React228.forwardRef(
7880
8495
  showLeftGradient && ChipBar_default.chipBarGradientVisible,
7881
8496
  "phx-nav-slot-left"
7882
8497
  ].filter(Boolean).join(" "),
7883
- children: /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(
8498
+ children: /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
7884
8499
  IconButton,
7885
8500
  {
7886
8501
  type: "button",
@@ -7890,12 +8505,12 @@ var ChipBar = React228.forwardRef(
7890
8505
  className: ChipBar_default.chipBarNavButton,
7891
8506
  onClick: () => handleScrollAction("left"),
7892
8507
  "aria-label": "Scroll left",
7893
- icon: /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(ChevronLeftOutline, {})
8508
+ icon: /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(ChevronLeftOutline, {})
7894
8509
  }
7895
8510
  )
7896
8511
  }
7897
8512
  ),
7898
- /* @__PURE__ */ (0, import_jsx_runtime221.jsx)("div", { className: ChipBar_default.chipBarScrollArea, style: chipBarMaskStyle, children: /* @__PURE__ */ (0, import_jsx_runtime221.jsx)("div", { className: ChipBar_default.chipBarMaskWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(
8513
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)("div", { className: ChipBar_default.chipBarScrollArea, style: chipBarMaskStyle, children: /* @__PURE__ */ (0, import_jsx_runtime227.jsx)("div", { className: ChipBar_default.chipBarMaskWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
7899
8514
  "div",
7900
8515
  {
7901
8516
  ref: listRef,
@@ -7905,9 +8520,9 @@ var ChipBar = React228.forwardRef(
7905
8520
  "scrollbarHidden",
7906
8521
  "phx-chip-bar-list"
7907
8522
  ].filter(Boolean).join(" "),
7908
- children: React228.Children.map(children, (child) => {
7909
- if (React228.isValidElement(child)) {
7910
- return React228.cloneElement(child, {
8523
+ children: React235.Children.map(children, (child) => {
8524
+ if (React235.isValidElement(child)) {
8525
+ return React235.cloneElement(child, {
7911
8526
  size: size === "large" ? "large" : "medium"
7912
8527
  });
7913
8528
  }
@@ -7915,7 +8530,7 @@ var ChipBar = React228.forwardRef(
7915
8530
  })
7916
8531
  }
7917
8532
  ) }) }),
7918
- /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(
8533
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
7919
8534
  "div",
7920
8535
  {
7921
8536
  className: [
@@ -7924,7 +8539,7 @@ var ChipBar = React228.forwardRef(
7924
8539
  showRightGradient && ChipBar_default.chipBarGradientVisible,
7925
8540
  "phx-nav-slot-right"
7926
8541
  ].filter(Boolean).join(" "),
7927
- children: /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(
8542
+ children: /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
7928
8543
  IconButton,
7929
8544
  {
7930
8545
  type: "button",
@@ -7934,7 +8549,7 @@ var ChipBar = React228.forwardRef(
7934
8549
  className: ChipBar_default.chipBarNavButton,
7935
8550
  onClick: () => handleScrollAction("right"),
7936
8551
  "aria-label": "Scroll right",
7937
- icon: /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(ChevronRightOutline, {})
8552
+ icon: /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(ChevronRightOutline, {})
7938
8553
  }
7939
8554
  )
7940
8555
  }
@@ -7948,12 +8563,12 @@ var ChipBar = React228.forwardRef(
7948
8563
  ChipBar.displayName = "ChipBar";
7949
8564
 
7950
8565
  // ../ultimate/src/components/visually-hidden/VisuallyHidden.tsx
7951
- var React229 = __toESM(require("react"));
7952
- var import_jsx_runtime222 = require("react/jsx-runtime");
7953
- var VisuallyHidden = React229.forwardRef(
8566
+ var React236 = __toESM(require("react"));
8567
+ var import_jsx_runtime228 = require("react/jsx-runtime");
8568
+ var VisuallyHidden = React236.forwardRef(
7954
8569
  ({ as, children, className, style, ...props }, ref) => {
7955
8570
  const Component = as || "span";
7956
- return /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
8571
+ return /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
7957
8572
  Component,
7958
8573
  {
7959
8574
  ref,
@@ -7980,21 +8595,923 @@ var VisuallyHidden = React229.forwardRef(
7980
8595
  VisuallyHidden.displayName = "VisuallyHidden";
7981
8596
 
7982
8597
  // ../ultimate/src/components/layout-context/LayoutContext.tsx
7983
- var React230 = __toESM(require("react"));
7984
- var import_jsx_runtime223 = require("react/jsx-runtime");
7985
- var LayoutContext = React230.createContext(null);
8598
+ var React237 = __toESM(require("react"));
8599
+ var import_jsx_runtime229 = require("react/jsx-runtime");
8600
+ var LayoutContext = React237.createContext(null);
7986
8601
  var LayoutProvider = ({ children }) => {
7987
- const [drawerCount, setDrawerCount] = React230.useState(0);
7988
- const value = React230.useMemo(() => ({
8602
+ const [drawerCount, setDrawerCount] = React237.useState(0);
8603
+ const registerDrawer = React237.useCallback(() => setDrawerCount((count) => count + 1), []);
8604
+ const unregisterDrawer = React237.useCallback(() => setDrawerCount((count) => Math.max(0, count - 1)), []);
8605
+ const value = React237.useMemo(() => ({
7989
8606
  hasDrawer: drawerCount > 0,
7990
- registerDrawer: () => setDrawerCount((c) => c + 1),
7991
- unregisterDrawer: () => setDrawerCount((c) => Math.max(0, c - 1))
7992
- }), [drawerCount]);
7993
- return /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(LayoutContext.Provider, { value, children });
8607
+ registerDrawer,
8608
+ unregisterDrawer
8609
+ }), [drawerCount, registerDrawer, unregisterDrawer]);
8610
+ return /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(LayoutContext.Provider, { value, children });
7994
8611
  };
7995
8612
  var useLayout = () => {
7996
- return React230.useContext(LayoutContext);
8613
+ return React237.useContext(LayoutContext);
8614
+ };
8615
+
8616
+ // ../ultimate/src/components/number-field/NumberField.tsx
8617
+ var React238 = __toESM(require("react"));
8618
+ var import_jsx_runtime230 = require("react/jsx-runtime");
8619
+ var parseNumber = (text) => {
8620
+ const normalized = text.trim().replace(",", ".");
8621
+ if (normalized === "") return null;
8622
+ if (!/^-?\d*\.?\d*$/.test(normalized) || !/\d/.test(normalized)) return void 0;
8623
+ return Number(normalized);
8624
+ };
8625
+ function NumberField({
8626
+ label,
8627
+ size = "large",
8628
+ inputWidth = 64,
8629
+ value,
8630
+ defaultValue = null,
8631
+ onChange,
8632
+ min = -Infinity,
8633
+ max = Infinity,
8634
+ step = 1,
8635
+ error,
8636
+ description,
8637
+ disabled,
8638
+ readOnly,
8639
+ name,
8640
+ decreaseLabel = `Decrease ${label}`,
8641
+ increaseLabel = `Increase ${label}`,
8642
+ ...props
8643
+ }) {
8644
+ const [current, setCurrent, reset] = useControllableState({
8645
+ value,
8646
+ defaultValue,
8647
+ onChange
8648
+ });
8649
+ const ref = React238.useRef(null);
8650
+ const [draft, setDraft] = React238.useState(null);
8651
+ const display = draft ?? (current == null ? "" : String(current));
8652
+ const resetValue = String((value !== void 0 ? current : defaultValue) ?? "");
8653
+ useNativeFieldReset(
8654
+ ref,
8655
+ () => {
8656
+ reset();
8657
+ setDraft(null);
8658
+ },
8659
+ resetValue,
8660
+ props.form
8661
+ );
8662
+ const bounded = (number) => Math.min(Math.max(min, max), Math.max(min, number));
8663
+ const stepSize = Math.abs(step || 1);
8664
+ const editable = !disabled && !readOnly;
8665
+ const commit = (next) => {
8666
+ setDraft(null);
8667
+ if (next !== current) setCurrent(next);
8668
+ };
8669
+ const increment = (direction) => {
8670
+ if (!editable) return;
8671
+ const base = parseNumber(display) ?? current;
8672
+ commit(
8673
+ bounded(
8674
+ Number(
8675
+ ((base ?? (Number.isFinite(min) ? min : 0)) + direction * stepSize).toFixed(10)
8676
+ )
8677
+ )
8678
+ );
8679
+ };
8680
+ const generatedId = React238.useId();
8681
+ const inputId = props.id ?? generatedId;
8682
+ const descriptionId = description ? `${inputId}-description` : void 0;
8683
+ const errorId = error ? `${inputId}-error` : void 0;
8684
+ const buttonSize = size === "large" ? "medium" : "small";
8685
+ const allowNegative = min < 0;
8686
+ const integerOnly = Number.isInteger(stepSize) && (!Number.isFinite(min) || Number.isInteger(min));
8687
+ return /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(Box, { w: "fit-content", maxW: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)(VStack, { gap: "5xs", children: [
8688
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)(Text, { as: "label", variant: "title-md", htmlFor: inputId, children: [
8689
+ label,
8690
+ props.required && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { "aria-hidden": "true", children: " *" })
8691
+ ] }),
8692
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)(HStack, { gap: "2xs", align: "center", wrap: false, children: [
8693
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
8694
+ IconButton,
8695
+ {
8696
+ variant: "secondary",
8697
+ size: buttonSize,
8698
+ icon: /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(IndeterminateSmallOutline, {}),
8699
+ "aria-label": decreaseLabel,
8700
+ "aria-controls": inputId,
8701
+ disabled: disabled || readOnly || current != null && current <= min,
8702
+ onClick: () => increment(-1)
8703
+ }
8704
+ ),
8705
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
8706
+ TextField,
8707
+ {
8708
+ ...props,
8709
+ id: inputId,
8710
+ showClear: false,
8711
+ size,
8712
+ width: inputWidth,
8713
+ fullWidth: false,
8714
+ ref,
8715
+ type: "text",
8716
+ role: "spinbutton",
8717
+ inputMode: integerOnly && !allowNegative ? "numeric" : "decimal",
8718
+ autoComplete: "off",
8719
+ "aria-valuenow": current ?? void 0,
8720
+ "aria-valuemin": Number.isFinite(min) ? min : void 0,
8721
+ "aria-valuemax": Number.isFinite(max) ? max : void 0,
8722
+ disabled,
8723
+ error: !!error,
8724
+ "aria-describedby": mergeAriaIds(props["aria-describedby"], descriptionId, errorId),
8725
+ inputStyle: {
8726
+ textAlign: "center",
8727
+ fontVariantNumeric: "tabular-nums"
8728
+ },
8729
+ value: display,
8730
+ readOnly,
8731
+ onChange: (next) => {
8732
+ const text = next.trim();
8733
+ if (!/^-?\d*[.,]?\d*$/.test(text)) return;
8734
+ setDraft(text);
8735
+ const parsed = parseNumber(text);
8736
+ if (parsed !== void 0 && parsed !== current) setCurrent(parsed);
8737
+ },
8738
+ onKeyDown: (event) => {
8739
+ props.onKeyDown?.(event);
8740
+ if (event.defaultPrevented || event.nativeEvent.isComposing) return;
8741
+ let direction = 0;
8742
+ if (event.key === "ArrowUp") direction = 1;
8743
+ else if (event.key === "ArrowDown") direction = -1;
8744
+ else if (event.key === "PageUp") direction = 10;
8745
+ else if (event.key === "PageDown") direction = -10;
8746
+ if (direction) {
8747
+ event.preventDefault();
8748
+ increment(direction);
8749
+ } else if (event.key === "Home" && Number.isFinite(min)) {
8750
+ event.preventDefault();
8751
+ if (editable) commit(min);
8752
+ } else if (event.key === "End" && Number.isFinite(max)) {
8753
+ event.preventDefault();
8754
+ if (editable) commit(max);
8755
+ }
8756
+ },
8757
+ onBlur: (event) => {
8758
+ if (editable) {
8759
+ const parsed = parseNumber(display);
8760
+ commit(parsed === void 0 ? current ?? null : parsed === null ? null : bounded(parsed));
8761
+ }
8762
+ props.onBlur?.(event);
8763
+ }
8764
+ }
8765
+ ),
8766
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
8767
+ IconButton,
8768
+ {
8769
+ variant: "secondary",
8770
+ size: buttonSize,
8771
+ icon: /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(AddOutline, {}),
8772
+ "aria-label": increaseLabel,
8773
+ "aria-controls": inputId,
8774
+ disabled: disabled || readOnly || current != null && current >= max,
8775
+ onClick: () => increment(1)
8776
+ }
8777
+ )
8778
+ ] }),
8779
+ name && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
8780
+ "input",
8781
+ {
8782
+ type: "hidden",
8783
+ name,
8784
+ form: props.form,
8785
+ value: current == null ? "" : String(current),
8786
+ disabled
8787
+ }
8788
+ ),
8789
+ description && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(Text, { as: "div", variant: "body-md", color: "secondary", id: descriptionId, children: description }),
8790
+ error && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(Text, { as: "div", variant: "body-md", color: "red", id: errorId, children: error })
8791
+ ] }) });
8792
+ }
8793
+
8794
+ // ../ultimate/src/components/rating/Rating.tsx
8795
+ var React240 = __toESM(require("react"));
8796
+
8797
+ // ../ultimate/src/components/star/Star.tsx
8798
+ var React239 = __toESM(require("react"));
8799
+
8800
+ // ../ultimate/src/components/star/Star.module.css
8801
+ var Star_default = {};
8802
+
8803
+ // ../ultimate/src/components/star/Star.tsx
8804
+ var import_jsx_runtime231 = require("react/jsx-runtime");
8805
+ var Star = React239.forwardRef(
8806
+ ({
8807
+ className,
8808
+ checked = false,
8809
+ size = "medium",
8810
+ variant = "default",
8811
+ disabled,
8812
+ onChange,
8813
+ onClick,
8814
+ ...rest
8815
+ }, ref) => {
8816
+ const [pressed, setPressed] = React239.useState(false);
8817
+ const timeoutRef = React239.useRef(null);
8818
+ const iconSize = size === "small" ? 20 : 24;
8819
+ const handleClick = (e) => {
8820
+ if (disabled) return;
8821
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
8822
+ setPressed(true);
8823
+ timeoutRef.current = setTimeout(() => setPressed(false), 350);
8824
+ if (onChange) {
8825
+ onChange(!checked);
8826
+ }
8827
+ if (onClick) {
8828
+ onClick(e);
8829
+ }
8830
+ };
8831
+ React239.useEffect(() => {
8832
+ return () => {
8833
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
8834
+ };
8835
+ }, []);
8836
+ const starClasses = [
8837
+ "phx-star",
8838
+ Star_default.starRoot,
8839
+ Star_default[`starSize${size.charAt(0).toUpperCase() + size.slice(1)}`],
8840
+ Star_default[`starVariant${variant.charAt(0).toUpperCase() + variant.slice(1)}`],
8841
+ checked && Star_default.starStateChecked,
8842
+ pressed && Star_default.starStatePressed,
8843
+ className
8844
+ ].filter(Boolean).join(" ");
8845
+ return /* @__PURE__ */ (0, import_jsx_runtime231.jsx)(
8846
+ "button",
8847
+ {
8848
+ ref,
8849
+ type: "button",
8850
+ className: starClasses,
8851
+ disabled,
8852
+ onClick: handleClick,
8853
+ "aria-pressed": checked,
8854
+ "aria-label": "Favorite",
8855
+ ...rest,
8856
+ children: /* @__PURE__ */ (0, import_jsx_runtime231.jsx)("span", { className: Star_default.starIconWrapper, children: checked ? /* @__PURE__ */ (0, import_jsx_runtime231.jsx)(StarFilled, { size: iconSize }) : /* @__PURE__ */ (0, import_jsx_runtime231.jsx)(StarOutline, { size: iconSize }) })
8857
+ }
8858
+ );
8859
+ }
8860
+ );
8861
+ Star.displayName = "Star";
8862
+
8863
+ // ../ultimate/src/components/rating/Rating.tsx
8864
+ var import_jsx_runtime232 = require("react/jsx-runtime");
8865
+ function Rating({
8866
+ label,
8867
+ value,
8868
+ defaultValue = 0,
8869
+ max = 5,
8870
+ onChange,
8871
+ disabled,
8872
+ readOnly,
8873
+ name,
8874
+ form,
8875
+ clearable = false,
8876
+ clearText = "Clear",
8877
+ clearLabel = `Clear ${label}`,
8878
+ getStarLabel = (star, total) => `${star} of ${total} stars`
8879
+ }) {
8880
+ const count = Math.max(1, Math.min(100, Math.floor(max) || 5));
8881
+ const [current = 0, setCurrent, reset] = useControllableState({
8882
+ value,
8883
+ defaultValue,
8884
+ onChange
8885
+ });
8886
+ const hidden = React240.useRef(null);
8887
+ const normalize = (rating) => Number.isFinite(rating) ? Math.max(0, Math.min(count, Math.round(rating))) : 0;
8888
+ const selected = normalize(current);
8889
+ useNativeFieldReset(
8890
+ hidden,
8891
+ reset,
8892
+ String(value !== void 0 ? selected : normalize(defaultValue)),
8893
+ form
8894
+ );
8895
+ return /* @__PURE__ */ (0, import_jsx_runtime232.jsxs)(HStack, { gap: "2xs", align: "center", wrap: true, children: [
8896
+ /* @__PURE__ */ (0, import_jsx_runtime232.jsx)(
8897
+ HStack,
8898
+ {
8899
+ gap: "none",
8900
+ align: "center",
8901
+ role: "radiogroup",
8902
+ "aria-label": label,
8903
+ "aria-readonly": readOnly || void 0,
8904
+ onKeyDown: (event) => {
8905
+ if (disabled || readOnly || event.nativeEvent.isComposing) return;
8906
+ const rtl = getComputedStyle(event.currentTarget).direction === "rtl";
8907
+ const forward = rtl ? "ArrowLeft" : "ArrowRight";
8908
+ const backward = rtl ? "ArrowRight" : "ArrowLeft";
8909
+ let next;
8910
+ if (event.key === forward || event.key === "ArrowUp")
8911
+ next = selected >= count ? 1 : selected + 1;
8912
+ else if (event.key === backward || event.key === "ArrowDown")
8913
+ next = selected <= 1 ? count : selected - 1;
8914
+ else if (event.key === "Home") next = 1;
8915
+ else if (event.key === "End") next = count;
8916
+ else return;
8917
+ event.preventDefault();
8918
+ setCurrent(next);
8919
+ event.currentTarget.querySelectorAll('[role="radio"]')[next - 1]?.focus();
8920
+ },
8921
+ children: Array.from({ length: count }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime232.jsx)(
8922
+ Star,
8923
+ {
8924
+ checked: index < selected,
8925
+ "aria-pressed": void 0,
8926
+ type: "button",
8927
+ role: "radio",
8928
+ "aria-label": getStarLabel(index + 1, count),
8929
+ "aria-checked": selected === index + 1,
8930
+ disabled,
8931
+ tabIndex: selected === index + 1 || !selected && index === 0 ? 0 : -1,
8932
+ onClick: () => {
8933
+ if (!disabled && !readOnly) setCurrent(index + 1);
8934
+ }
8935
+ },
8936
+ index
8937
+ ))
8938
+ }
8939
+ ),
8940
+ clearable && /* @__PURE__ */ (0, import_jsx_runtime232.jsx)(
8941
+ Button,
8942
+ {
8943
+ variant: "secondary",
8944
+ size: "small",
8945
+ type: "button",
8946
+ "aria-label": clearLabel,
8947
+ disabled: disabled || readOnly || !selected,
8948
+ onClick: () => setCurrent(0),
8949
+ children: clearText
8950
+ }
8951
+ ),
8952
+ /* @__PURE__ */ (0, import_jsx_runtime232.jsx)(
8953
+ "input",
8954
+ {
8955
+ ref: hidden,
8956
+ type: "hidden",
8957
+ name,
8958
+ form,
8959
+ value: selected,
8960
+ disabled
8961
+ }
8962
+ )
8963
+ ] });
8964
+ }
8965
+
8966
+ // ../ultimate/src/components/otp/OTP.tsx
8967
+ var React241 = __toESM(require("react"));
8968
+ var import_react_dom3 = require("react-dom");
8969
+
8970
+ // ../ultimate/src/components/otp/OTP.module.css
8971
+ var OTP_default = {};
8972
+
8973
+ // ../ultimate/src/components/otp/OTP.tsx
8974
+ var import_jsx_runtime233 = require("react/jsx-runtime");
8975
+ function OTP({
8976
+ label,
8977
+ length = 6,
8978
+ groupSize,
8979
+ masked = false,
8980
+ hideLabel = false,
8981
+ dotFields = false,
8982
+ size = "large",
8983
+ value,
8984
+ defaultValue = "",
8985
+ onChange,
8986
+ onComplete,
8987
+ disabled,
8988
+ readOnly,
8989
+ required,
8990
+ name,
8991
+ form,
8992
+ helperText,
8993
+ error,
8994
+ getCellLabel = (name2, position, total) => `${name2}, digit ${position} of ${total}`,
8995
+ sequential = false,
8996
+ autoFocus = false
8997
+ }) {
8998
+ const count = Number.isFinite(length) ? Math.max(1, Math.min(32, Math.floor(length))) : 6;
8999
+ const normalize = (text) => text.replace(/\D/g, "").slice(0, count);
9000
+ const split = (text) => Array.from({ length: count }, (_, index) => normalize(text)[index] ?? "");
9001
+ const [code = "", setCode, reset] = useControllableState({
9002
+ value,
9003
+ defaultValue: normalize(defaultValue),
9004
+ onChange
9005
+ });
9006
+ const [local, setLocal] = React241.useState(() => split(value ?? defaultValue));
9007
+ const pending = React241.useRef(null);
9008
+ const digits = value === void 0 ? Array.from({ length: count }, (_, index) => local[index] ?? "") : pending.current?.code === normalize(code) ? Array.from(
9009
+ { length: count },
9010
+ (_, index) => pending.current.digits[index] ?? ""
9011
+ ) : split(code);
9012
+ const currentDigits = React241.useRef(digits);
9013
+ currentDigits.current = digits;
9014
+ const composing = React241.useRef(null);
9015
+ const inputs = React241.useRef([]);
9016
+ const first = React241.useRef(null);
9017
+ const previousReadOnly = React241.useRef(readOnly);
9018
+ React241.useEffect(() => {
9019
+ if (readOnly && !previousReadOnly.current) {
9020
+ const active = inputs.current.find((input) => input === document.activeElement);
9021
+ active?.blur();
9022
+ }
9023
+ previousReadOnly.current = readOnly;
9024
+ }, [readOnly]);
9025
+ const id = React241.useId();
9026
+ const supportingText = error || helperText;
9027
+ const supportingId = error ? `${id}-error` : helperText ? `${id}-helper` : void 0;
9028
+ const focus = (index) => inputs.current[index]?.focus({ preventScroll: true });
9029
+ const nextCell = (from) => {
9030
+ const empty = from.findIndex((digit) => !digit);
9031
+ return empty === -1 ? count - 1 : empty;
9032
+ };
9033
+ const commit = (next) => {
9034
+ const nextCode = next.join("");
9035
+ pending.current = { code: nextCode, digits: next };
9036
+ currentDigits.current = next;
9037
+ setLocal(next);
9038
+ setCode(nextCode);
9039
+ if (next.every(Boolean) && nextCode !== normalize(code))
9040
+ onComplete?.(nextCode);
9041
+ };
9042
+ const enter = (cell, raw) => {
9043
+ if (disabled || readOnly) return;
9044
+ if (sequential && raw && currentDigits.current.every(Boolean)) return;
9045
+ const index = sequential ? nextCell(currentDigits.current) : cell;
9046
+ const text = normalize(raw);
9047
+ if (raw && !text) return;
9048
+ const start = text.length === count ? 0 : index;
9049
+ const next = [...currentDigits.current];
9050
+ if (!text) next[index] = "";
9051
+ else
9052
+ [...text].forEach((digit, offset) => {
9053
+ if (start + offset < count) next[start + offset] = digit;
9054
+ });
9055
+ (0, import_react_dom3.flushSync)(() => commit(next));
9056
+ const nextIndex = sequential ? nextCell(next) : Math.min(count - 1, start + text.length);
9057
+ if (text && !inputs.current[nextIndex]?.readOnly) focus(nextIndex);
9058
+ };
9059
+ React241.useEffect(() => {
9060
+ if (autoFocus && !disabled && !readOnly) focus(sequential ? nextCell(currentDigits.current) : 0);
9061
+ }, []);
9062
+ React241.useEffect(() => {
9063
+ const cleanups = inputs.current.slice(0, count).map((input, index) => {
9064
+ if (!input) return () => {
9065
+ };
9066
+ const beforeInput = (event) => {
9067
+ if (disabled || readOnly || !event.cancelable || !event.data) return;
9068
+ if (!event.inputType.startsWith("insert") || !/^[0-9]+$/.test(event.data)) return;
9069
+ event.preventDefault();
9070
+ composing.current = null;
9071
+ enter(index, event.data);
9072
+ };
9073
+ input.addEventListener("beforeinput", beforeInput);
9074
+ return () => input.removeEventListener("beforeinput", beforeInput);
9075
+ });
9076
+ return () => cleanups.forEach((cleanup) => cleanup());
9077
+ });
9078
+ const resetCode = value === void 0 ? normalize(defaultValue) : normalize(code);
9079
+ useNativeFieldReset(
9080
+ first,
9081
+ () => {
9082
+ reset();
9083
+ const next = split(resetCode);
9084
+ pending.current = { code: resetCode, digits: next };
9085
+ setLocal(next);
9086
+ composing.current = null;
9087
+ inputs.current.forEach((input, index) => {
9088
+ if (input) input.value = next[index] ?? "";
9089
+ });
9090
+ },
9091
+ resetCode[0] ?? "",
9092
+ form
9093
+ );
9094
+ const columns = Math.min(count, 6);
9095
+ const cellWidth = dotFields ? 16 : size === "large" ? 44 : size === "medium" ? 36 : 28;
9096
+ const grouping = groupSize !== void 0 && Number.isFinite(groupSize) && groupSize >= 1 ? Math.floor(groupSize) : 0;
9097
+ const separates = (index) => grouping > 0 && index > 0 && index % grouping === 0 && index % columns !== 0;
9098
+ const tracks = Array.from(
9099
+ { length: columns },
9100
+ (_, index) => `${separates(index) ? "var(--dimensions-12) " : ""}minmax(0, 1fr)`
9101
+ ).join(" ");
9102
+ const separatorCount = Array.from({ length: columns }, (_, index) => separates(index)).filter(Boolean).length;
9103
+ return /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)(VStack, { gap: "5xs", align: "start", maxW: "100%", children: [
9104
+ !hideLabel && /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)(Text, { as: "span", id: `${id}-label`, variant: size === "large" ? "title-md" : size === "medium" ? "title-sm" : "label-md", children: [
9105
+ label,
9106
+ required && /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("span", { "aria-hidden": "true", children: " *" })
9107
+ ] }),
9108
+ /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(
9109
+ Grid,
9110
+ {
9111
+ role: "group",
9112
+ dir: "ltr",
9113
+ "aria-labelledby": hideLabel ? void 0 : `${id}-label`,
9114
+ "aria-label": hideLabel ? label : void 0,
9115
+ "aria-describedby": supportingId,
9116
+ templateColumns: tracks,
9117
+ gap: dotFields ? "md" : "4xs",
9118
+ maxW: "100%",
9119
+ w: `calc(${columns} * ${cellWidth}px + ${columns - 1 + separatorCount} * var(${dotFields ? "--space-md" : "--space-4xs"}) + ${separatorCount} * var(--dimensions-12))`,
9120
+ children: Array.from({ length: count }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)(React241.Fragment, { children: [
9121
+ separates(index % columns) && /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(Text, { as: "span", "aria-hidden": "true", className: OTP_default.separator, children: "-" }),
9122
+ /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)(Text, { as: "span", className: `${OTP_default.cellSlot} ${OTP_default[size]} ${dotFields ? OTP_default.dotField : ""}`, variant: size === "large" ? "headline-sm" : size === "medium" ? "title-lg" : "title-md", weight: "medium", children: [
9123
+ /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(
9124
+ "input",
9125
+ {
9126
+ id: `${id}-${index}`,
9127
+ className: `${OTP_default.cell} ${masked ? OTP_default.masked : ""} ${dotFields ? OTP_default.dotFieldInput : ""}`,
9128
+ "data-filled": dotFields ? !!digits[index] : void 0,
9129
+ ref: (node) => {
9130
+ inputs.current[index] = node;
9131
+ if (index === 0) first.current = node;
9132
+ },
9133
+ "aria-label": getCellLabel(label, index + 1, count),
9134
+ "aria-describedby": supportingId,
9135
+ "aria-invalid": error ? true : void 0,
9136
+ type: masked ? "password" : "text",
9137
+ inputMode: "numeric",
9138
+ autoComplete: masked ? "off" : index === 0 ? "one-time-code" : "off",
9139
+ pattern: "[0-9]",
9140
+ maxLength: 1,
9141
+ required: required || digits.some(Boolean),
9142
+ disabled,
9143
+ readOnly,
9144
+ form,
9145
+ value: digits[index] ?? "",
9146
+ tabIndex: sequential && index !== nextCell(digits) ? -1 : void 0,
9147
+ onMouseDown: (event) => {
9148
+ if (!sequential || disabled || readOnly) return;
9149
+ event.preventDefault();
9150
+ focus(nextCell(currentDigits.current));
9151
+ },
9152
+ onFocus: (event) => {
9153
+ const target = nextCell(currentDigits.current);
9154
+ if (sequential && index !== target && !readOnly) {
9155
+ focus(target);
9156
+ return;
9157
+ }
9158
+ event.currentTarget.setSelectionRange(0, event.currentTarget.value.length);
9159
+ },
9160
+ onCopy: (event) => {
9161
+ if (masked) {
9162
+ event.preventDefault();
9163
+ return;
9164
+ }
9165
+ if (!readOnly) return;
9166
+ event.preventDefault();
9167
+ event.clipboardData.setData("text/plain", normalize(code));
9168
+ },
9169
+ onChange: () => {
9170
+ },
9171
+ onInput: (event) => {
9172
+ if (disabled || readOnly) return;
9173
+ const next = event.currentTarget.value;
9174
+ event.currentTarget.value = normalize(next).slice(0, 1) || (digits[index] ?? "");
9175
+ if (composing.current === index && next && !/^[0-9]+$/.test(next)) return;
9176
+ composing.current = null;
9177
+ enter(index, next);
9178
+ },
9179
+ onPaste: (event) => {
9180
+ event.preventDefault();
9181
+ enter(index, event.clipboardData.getData("text"));
9182
+ },
9183
+ onCompositionStart: () => {
9184
+ if (disabled || readOnly) return;
9185
+ composing.current = index;
9186
+ },
9187
+ onCompositionEnd: (event) => {
9188
+ if (disabled || readOnly) return;
9189
+ const text = event.data || event.currentTarget.value;
9190
+ event.currentTarget.value = currentDigits.current[index] ?? "";
9191
+ if (composing.current !== index) return;
9192
+ composing.current = null;
9193
+ enter(index, text);
9194
+ },
9195
+ onKeyDown: (event) => {
9196
+ if (event.nativeEvent.isComposing || composing.current !== null || disabled)
9197
+ return;
9198
+ if (event.key === "Backspace" || event.key === "Delete") {
9199
+ event.preventDefault();
9200
+ if (readOnly) return;
9201
+ if (sequential) {
9202
+ const next2 = [...currentDigits.current];
9203
+ const last = next2.map(Boolean).lastIndexOf(true);
9204
+ if (last >= 0) next2[last] = "";
9205
+ (0, import_react_dom3.flushSync)(() => commit(next2));
9206
+ focus(nextCell(next2));
9207
+ return;
9208
+ }
9209
+ const target = event.key === "Backspace" && !digits[index] ? Math.max(0, index - 1) : index;
9210
+ const next = [...currentDigits.current];
9211
+ next[target] = "";
9212
+ commit(next);
9213
+ focus(target);
9214
+ } else if (["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) {
9215
+ event.preventDefault();
9216
+ if (sequential) return;
9217
+ focus(
9218
+ event.key === "Home" ? 0 : event.key === "End" ? count - 1 : Math.max(
9219
+ 0,
9220
+ Math.min(
9221
+ count - 1,
9222
+ index + (event.key === "ArrowRight" ? 1 : -1)
9223
+ )
9224
+ )
9225
+ );
9226
+ }
9227
+ }
9228
+ }
9229
+ ),
9230
+ masked && !dotFields && digits[index] && /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("span", { className: OTP_default.dot, "aria-hidden": "true" })
9231
+ ] })
9232
+ ] }, index))
9233
+ }
9234
+ ),
9235
+ name && /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(
9236
+ "input",
9237
+ {
9238
+ type: "hidden",
9239
+ name,
9240
+ form,
9241
+ value: normalize(code),
9242
+ disabled
9243
+ }
9244
+ ),
9245
+ supportingText && /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(Text, { as: "div", id: supportingId, variant: "body-md", color: error ? "red" : "secondary", role: error ? "alert" : void 0, children: supportingText })
9246
+ ] });
9247
+ }
9248
+
9249
+ // ../ultimate/src/components/pin/PIN.tsx
9250
+ var import_jsx_runtime234 = require("react/jsx-runtime");
9251
+ function PIN({ length = 4, "aria-label": accessibleLabel = "PIN", autoFocus = true, ...props }) {
9252
+ return /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(OTP, { ...props, label: accessibleLabel, length, size: "large", masked: true, hideLabel: true, dotFields: true, readOnly: false, sequential: true, autoFocus });
9253
+ }
9254
+
9255
+ // ../ultimate/src/components/empty/Empty.tsx
9256
+ var React242 = __toESM(require("react"));
9257
+ var import_jsx_runtime235 = require("react/jsx-runtime");
9258
+ function Empty({
9259
+ title = "No results",
9260
+ description,
9261
+ icon,
9262
+ action
9263
+ }) {
9264
+ const titleId = React242.useId();
9265
+ return /* @__PURE__ */ (0, import_jsx_runtime235.jsxs)(
9266
+ VStack,
9267
+ {
9268
+ as: "section",
9269
+ gap: "sm",
9270
+ p: "xl",
9271
+ align: "center",
9272
+ textAlign: "center",
9273
+ "aria-labelledby": titleId,
9274
+ children: [
9275
+ icon && /* @__PURE__ */ (0, import_jsx_runtime235.jsx)("span", { "aria-hidden": "true", children: icon }),
9276
+ /* @__PURE__ */ (0, import_jsx_runtime235.jsxs)(VStack, { gap: "4xs", align: "center", children: [
9277
+ /* @__PURE__ */ (0, import_jsx_runtime235.jsx)(Heading, { as: "h3", size: "title-lg", id: titleId, children: title }),
9278
+ description && /* @__PURE__ */ (0, import_jsx_runtime235.jsx)(Text, { as: "div", color: "secondary", children: description })
9279
+ ] }),
9280
+ action
9281
+ ]
9282
+ }
9283
+ );
9284
+ }
9285
+
9286
+ // ../ultimate/src/components/result/Result.tsx
9287
+ var React243 = __toESM(require("react"));
9288
+ var import_illustrations = require("@photonix/illustrations");
9289
+ var import_jsx_runtime236 = require("react/jsx-runtime");
9290
+ var STATUS_ILLUSTRATION = {
9291
+ success: import_illustrations.CheckCircle,
9292
+ error: import_illustrations.Cancel,
9293
+ warning: import_illustrations.Warning,
9294
+ info: import_illustrations.Information
7997
9295
  };
9296
+ function Result({ status, title, description, action }) {
9297
+ const titleId = React243.useId();
9298
+ const StatusIllustration = STATUS_ILLUSTRATION[status];
9299
+ return /* @__PURE__ */ (0, import_jsx_runtime236.jsxs)(
9300
+ VStack,
9301
+ {
9302
+ as: "section",
9303
+ gap: "sm",
9304
+ p: "xl",
9305
+ align: "center",
9306
+ textAlign: "center",
9307
+ "aria-labelledby": titleId,
9308
+ "data-status": status,
9309
+ children: [
9310
+ /* @__PURE__ */ (0, import_jsx_runtime236.jsx)("span", { "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime236.jsx)(StatusIllustration, { tone: "accent" }) }),
9311
+ /* @__PURE__ */ (0, import_jsx_runtime236.jsxs)(
9312
+ VStack,
9313
+ {
9314
+ gap: "4xs",
9315
+ align: "center",
9316
+ role: status === "error" ? "alert" : "status",
9317
+ children: [
9318
+ /* @__PURE__ */ (0, import_jsx_runtime236.jsx)(Heading, { as: "h3", size: "title-lg", id: titleId, children: title }),
9319
+ description && /* @__PURE__ */ (0, import_jsx_runtime236.jsx)(Text, { as: "div", color: "secondary", children: description })
9320
+ ]
9321
+ }
9322
+ ),
9323
+ action
9324
+ ]
9325
+ }
9326
+ );
9327
+ }
9328
+
9329
+ // ../ultimate/src/components/data-list/DataList.tsx
9330
+ var import_jsx_runtime237 = require("react/jsx-runtime");
9331
+ var DOTS = [0, 1, 2, 3, 4, 5];
9332
+ function Action({ children, slot }) {
9333
+ return /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(
9334
+ Box,
9335
+ {
9336
+ display: "flex",
9337
+ alignItems: "center",
9338
+ justifyContent: "center",
9339
+ flexShrink: 0,
9340
+ h: slot ? "var(--body-lg-line-height)" : void 0,
9341
+ w: slot ? "var(--dimensions-20)" : void 0,
9342
+ children
9343
+ }
9344
+ );
9345
+ }
9346
+ function DataList({
9347
+ items,
9348
+ label = "Details",
9349
+ layout,
9350
+ labelSize,
9351
+ orientation = "horizontal"
9352
+ }) {
9353
+ const resolvedLayout = layout ?? (orientation === "vertical" ? "stack" : "inline");
9354
+ const resolvedLabelSize = labelSize ?? (resolvedLayout === "stack" ? "sm" : "lg");
9355
+ return /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(VStack, { as: "dl", "aria-label": label, gap: "md", m: "none", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(
9356
+ DataListRow,
9357
+ {
9358
+ item,
9359
+ layout: resolvedLayout,
9360
+ labelSize: resolvedLabelSize
9361
+ },
9362
+ item.id
9363
+ )) });
9364
+ }
9365
+ function DataListRow({
9366
+ item,
9367
+ layout,
9368
+ labelSize
9369
+ }) {
9370
+ const variant = item.variant ?? "normal";
9371
+ const isStack = layout === "stack";
9372
+ const isInline = layout === "inline";
9373
+ const isTotal = variant === "total";
9374
+ const isHero = isStack && variant === "hero";
9375
+ const isComplex = isStack && variant === "complex";
9376
+ const isFlexible = !isStack && variant === "flexible";
9377
+ const emphasizeValue = variant === "emphasize" || isTotal || isStack && variant === "normal";
9378
+ const labelEmphasized = item.labelEmphasized ?? isTotal;
9379
+ const labelVariant = labelSize === "lg" ? "title-md" : "title-sm";
9380
+ const labelWeight = labelEmphasized ? "medium" : "regular";
9381
+ const badgeBelow = item.badgePlacement === "below";
9382
+ const description = isHero ? void 0 : item.description;
9383
+ const term = /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(Box, { as: "dt", display: "flex", alignItems: "baseline", gap: "4xs", minW: 0, children: [
9384
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(Box, { display: "flex", alignItems: "center", gap: "4xs", flex: "1 1 0", minW: 0, children: [
9385
+ item.labelIcon && /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Box, { display: "flex", flexShrink: 0, children: item.labelIcon }),
9386
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(
9387
+ Text,
9388
+ {
9389
+ as: "div",
9390
+ variant: labelVariant,
9391
+ color: item.labelLead || !labelEmphasized ? "secondary" : "primary",
9392
+ weight: labelWeight,
9393
+ children: [
9394
+ item.labelLead && /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(Text, { as: "span", variant: labelVariant, color: "primary", weight: labelWeight, children: [
9395
+ item.labelLead,
9396
+ " "
9397
+ ] }),
9398
+ item.label
9399
+ ]
9400
+ }
9401
+ )
9402
+ ] }),
9403
+ item.labelTrailing && /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Box, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Text, { as: "div", variant: "body-md", color: "secondary", align: "right", children: item.labelTrailing }) })
9404
+ ] });
9405
+ const figure = isHero && item.masked ? /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(
9406
+ Box,
9407
+ {
9408
+ display: "flex",
9409
+ alignItems: "center",
9410
+ gap: "2xs",
9411
+ h: "var(--headline-lg-line-height)",
9412
+ role: "img",
9413
+ "aria-label": "Hidden",
9414
+ children: DOTS.map((dot) => /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(
9415
+ Box,
9416
+ {
9417
+ w: "10px",
9418
+ h: "10px",
9419
+ borderRadius: "full",
9420
+ flexShrink: 0,
9421
+ style: { backgroundColor: "var(--foreground-neutral-primary)" }
9422
+ },
9423
+ dot
9424
+ ))
9425
+ }
9426
+ ) : /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(
9427
+ Text,
9428
+ {
9429
+ as: "div",
9430
+ variant: isHero ? "headline-lg" : "body-lg",
9431
+ weight: emphasizeValue && !isHero ? "medium" : void 0,
9432
+ align: isInline ? "right" : void 0,
9433
+ children: item.value
9434
+ }
9435
+ );
9436
+ const valueRow = isComplex ? /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(Box, { display: "flex", alignItems: "center", gap: "xs", w: "100%", minW: 0, children: [
9437
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Box, { flex: "1 1 0", minW: 0, children: item.value }),
9438
+ item.action && /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Action, { slot: false, children: item.action })
9439
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(
9440
+ Box,
9441
+ {
9442
+ display: "flex",
9443
+ alignItems: "center",
9444
+ gap: "4xs",
9445
+ minW: 0,
9446
+ justifyContent: isInline ? "end" : void 0,
9447
+ children: [
9448
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Box, { display: "flex", flexShrink: 0, children: item.icon }),
9449
+ item.valuePrefix && /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Box, { alignSelf: "baseline", flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Text, { as: "span", variant: isHero ? "headline-lg" : "body-lg", color: "secondary", children: item.valuePrefix }) }),
9450
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Box, { alignSelf: "baseline", minW: 0, children: figure }),
9451
+ item.action && /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Action, { slot: !isHero, children: item.action })
9452
+ ]
9453
+ }
9454
+ );
9455
+ const badge = item.badge ? /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Box, { display: "flex", flexShrink: 0, children: item.badge }) : null;
9456
+ const firstLine = badge && !badgeBelow ? /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(
9457
+ Box,
9458
+ {
9459
+ display: "flex",
9460
+ alignItems: "center",
9461
+ gap: "2xs",
9462
+ w: "100%",
9463
+ minW: 0,
9464
+ justifyContent: isInline ? "end" : void 0,
9465
+ children: [
9466
+ valueRow,
9467
+ badge
9468
+ ]
9469
+ }
9470
+ ) : valueRow;
9471
+ const definition = /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(
9472
+ Box,
9473
+ {
9474
+ as: "dd",
9475
+ m: "none",
9476
+ display: "flex",
9477
+ flexDirection: "column",
9478
+ alignItems: isInline ? "end" : "stretch",
9479
+ gap: badge && badgeBelow && !description ? "4xs" : "5xs",
9480
+ minW: 0,
9481
+ children: [
9482
+ firstLine,
9483
+ description && /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Text, { as: "div", variant: "body-md", color: "secondary", align: isInline ? "right" : void 0, children: description }),
9484
+ badgeBelow && badge
9485
+ ]
9486
+ }
9487
+ );
9488
+ if (isStack) {
9489
+ return /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(VStack, { gap: "4xs", align: "stretch", children: [
9490
+ term,
9491
+ definition,
9492
+ isHero && item.description && /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Text, { as: "div", variant: "body-md", color: "secondary", children: item.description })
9493
+ ] });
9494
+ }
9495
+ if (layout === "column") {
9496
+ return /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(
9497
+ Grid,
9498
+ {
9499
+ columns: isFlexible ? void 0 : 5,
9500
+ templateColumns: isFlexible ? "auto minmax(0, 1fr)" : void 0,
9501
+ columnGap: "2xs",
9502
+ alignItems: "baseline",
9503
+ children: [
9504
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(GridItem, { colSpan: isFlexible ? void 0 : 2, minW: 0, children: term }),
9505
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(GridItem, { colSpan: isFlexible ? void 0 : 3, minW: 0, children: definition })
9506
+ ]
9507
+ }
9508
+ );
9509
+ }
9510
+ return /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(HStack, { gap: "2xs", align: "baseline", children: [
9511
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Box, { flex: isFlexible ? "0 1 auto" : "1 1 0", minW: 0, children: term }),
9512
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(Box, { flex: "1 1 0", minW: 0, children: definition })
9513
+ ] });
9514
+ }
7998
9515
  // Annotate the CommonJS export names for ESM import in node:
7999
9516
  0 && (module.exports = {
8000
9517
  AVATAR_IMAGES,
@@ -8047,6 +9564,8 @@ var useLayout = () => {
8047
9564
  CheckSmallFilled,
8048
9565
  CheckSmallOutline,
8049
9566
  Checkbox,
9567
+ CheckboxGroup,
9568
+ CheckboxGroupContext,
8050
9569
  ChevronDownFilled,
8051
9570
  ChevronDownOutline,
8052
9571
  ChevronDownSmallFilled,
@@ -8090,6 +9609,7 @@ var useLayout = () => {
8090
9609
  CreditCardFilled,
8091
9610
  CreditCardOutline,
8092
9611
  CustomScrollbar,
9612
+ DataList,
8093
9613
  DayFilled,
8094
9614
  DayOutline,
8095
9615
  Divider,
@@ -8101,6 +9621,7 @@ var useLayout = () => {
8101
9621
  DraftOutline,
8102
9622
  DuplicateFilled,
8103
9623
  DuplicateOutline,
9624
+ Empty,
8104
9625
  ExitFilled,
8105
9626
  ExitOutline,
8106
9627
  EyeDropperFilled,
@@ -8109,6 +9630,7 @@ var useLayout = () => {
8109
9630
  EyeOffFilled,
8110
9631
  EyeOffOutline,
8111
9632
  EyeOutline,
9633
+ Fieldset,
8112
9634
  Flex,
8113
9635
  FolderFilled,
8114
9636
  FolderOutline,
@@ -8150,10 +9672,13 @@ var useLayout = () => {
8150
9672
  MoreVerticalOutline,
8151
9673
  MusicNoteFilled,
8152
9674
  MusicNoteOutline,
9675
+ NumberField,
9676
+ OTP,
8153
9677
  OpenWithFilled,
8154
9678
  OpenWithOutline,
8155
9679
  OptionFilled,
8156
9680
  OptionOutline,
9681
+ PIN,
8157
9682
  PenFilled,
8158
9683
  PenOutline,
8159
9684
  PersonalBookFilled,
@@ -8165,11 +9690,14 @@ var useLayout = () => {
8165
9690
  Portal,
8166
9691
  Radio,
8167
9692
  RadioFilled,
9693
+ RadioGroup,
8168
9694
  RadioOutline,
8169
9695
  RainFilled,
8170
9696
  RainOutline,
9697
+ Rating,
8171
9698
  RectangleFilled,
8172
9699
  RectangleOutline,
9700
+ Result,
8173
9701
  RouterFilled,
8174
9702
  RouterOutline,
8175
9703
  ScheduleFilled,