@orianatech/pire 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -704,158 +704,19 @@ function FormField({ label, htmlFor, isRequired, hint, error, layout = "stacked"
704
704
  }
705
705
 
706
706
  // src/components/forms/Input.tsx
707
- import { TextField, Label, Input as AriaInput, Group, Text as Text2, FieldError } from "react-aria-components";
708
- import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
709
- function Input({
710
- label,
711
- icon,
712
- suffix,
713
- description,
714
- errorMessage,
715
- size = "md",
716
- numeric,
717
- fullWidth = true,
718
- className,
719
- style,
720
- inputRef,
721
- onChange,
722
- ...rest
723
- }) {
724
- return /* @__PURE__ */ jsxs10(
725
- TextField,
726
- {
727
- className: cx("pire-field", className),
728
- style,
729
- onChange,
730
- validationBehavior: "aria",
731
- ...rest,
732
- children: [
733
- label ? /* @__PURE__ */ jsxs10(Label, { className: "pire-field-label", children: [
734
- label,
735
- rest.isRequired ? /* @__PURE__ */ jsx16("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
736
- ] }) : null,
737
- /* @__PURE__ */ jsxs10(
738
- Group,
739
- {
740
- className: "pire-control",
741
- "data-size": size,
742
- "data-full-width": String(fullWidth),
743
- "data-invalid": rest.isInvalid ? "true" : void 0,
744
- "data-readonly": rest.isReadOnly ? "true" : void 0,
745
- children: [
746
- icon ? /* @__PURE__ */ jsx16(Icon, { name: icon, size: 16, className: "pire-leading-icon" }) : null,
747
- /* @__PURE__ */ jsx16(AriaInput, { ref: inputRef, className: "pire-input", "data-numeric": numeric ? "true" : void 0 }),
748
- suffix ? /* @__PURE__ */ jsx16("span", { className: "pire-affix", children: suffix }) : null
749
- ]
750
- }
751
- ),
752
- description ? /* @__PURE__ */ jsx16(Text2, { slot: "description", className: "pire-field-hint", children: description }) : null,
753
- /* @__PURE__ */ jsx16(FieldError, { className: "pire-field-error", children: errorMessage })
754
- ]
755
- }
756
- );
757
- }
758
-
759
- // src/components/forms/TextArea.tsx
760
- import * as React5 from "react";
761
- import { TextField as TextField2, Label as Label2, TextArea as AriaTextArea, Group as Group2, Text as Text3, FieldError as FieldError2 } from "react-aria-components";
762
- import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
763
- var useIsomorphicLayoutEffect = typeof document === "undefined" ? React5.useEffect : React5.useLayoutEffect;
764
- function TextArea({
765
- label,
766
- description,
767
- errorMessage,
768
- size = "md",
769
- rows = 3,
770
- autoGrow,
771
- maxRows,
772
- fullWidth = true,
773
- className,
774
- style,
775
- textAreaRef,
776
- onChange,
777
- ...rest
778
- }) {
779
- const innerRef = React5.useRef(null);
780
- const ref = React5.useCallback((node) => {
781
- innerRef.current = node;
782
- if (typeof textAreaRef === "function") textAreaRef(node);
783
- else if (textAreaRef) textAreaRef.current = node;
784
- }, [textAreaRef]);
785
- const grow = React5.useCallback(() => {
786
- const el = innerRef.current;
787
- if (!el || !autoGrow) return;
788
- const styles = getComputedStyle(el);
789
- const lineHeight = Number.parseFloat(styles.lineHeight) || Number.parseFloat(styles.fontSize) * 1.5;
790
- const chrome = el.offsetHeight - el.clientHeight;
791
- el.style.height = "auto";
792
- const wanted = maxRows ? Math.min(el.scrollHeight, Math.ceil(lineHeight * maxRows)) : el.scrollHeight;
793
- const next = `${wanted + chrome}px`;
794
- if (el.style.height !== next) el.style.height = next;
795
- }, [autoGrow, maxRows]);
796
- useIsomorphicLayoutEffect(() => {
797
- if (!autoGrow) {
798
- if (innerRef.current) innerRef.current.style.height = "";
799
- return;
800
- }
801
- grow();
802
- }, [autoGrow, grow, rest.value]);
803
- return /* @__PURE__ */ jsxs11(
804
- TextField2,
805
- {
806
- className: cx("pire-field", className),
807
- style,
808
- onChange,
809
- validationBehavior: "aria",
810
- ...rest,
811
- children: [
812
- label ? /* @__PURE__ */ jsxs11(Label2, { className: "pire-field-label", children: [
813
- label,
814
- rest.isRequired ? /* @__PURE__ */ jsx17("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
815
- ] }) : null,
816
- /* @__PURE__ */ jsx17(
817
- Group2,
818
- {
819
- className: "pire-control",
820
- "data-size": size,
821
- "data-full-width": String(fullWidth),
822
- "data-multiline": "true",
823
- "data-invalid": rest.isInvalid ? "true" : void 0,
824
- "data-readonly": rest.isReadOnly ? "true" : void 0,
825
- children: /* @__PURE__ */ jsx17(
826
- AriaTextArea,
827
- {
828
- ref,
829
- rows,
830
- onInput: autoGrow ? grow : void 0,
831
- className: cx("pire-input", "pire-textarea"),
832
- "data-auto-grow": autoGrow ? "true" : void 0
833
- }
834
- )
835
- }
836
- ),
837
- description ? /* @__PURE__ */ jsx17(Text3, { slot: "description", className: "pire-field-hint", children: description }) : null,
838
- /* @__PURE__ */ jsx17(FieldError2, { className: "pire-field-error", children: errorMessage })
839
- ]
840
- }
841
- );
842
- }
843
-
844
- // src/components/forms/Select.tsx
707
+ import * as React6 from "react";
845
708
  import {
846
- Select as AriaSelect,
847
- Label as Label3,
848
- Button as AriaButton4,
849
- SelectValue,
850
- Popover,
851
- ListBox,
852
- ListBoxItem,
853
- Text as Text4,
854
- FieldError as FieldError3
709
+ TextField,
710
+ Label,
711
+ Input as AriaInput,
712
+ Group,
713
+ Text as Text2,
714
+ FieldError,
715
+ Button as AriaButton4
855
716
  } from "react-aria-components";
856
717
 
857
718
  // src/i18n/PireIntlProvider.tsx
858
- import * as React6 from "react";
719
+ import * as React5 from "react";
859
720
 
860
721
  // src/i18n/messages.ts
861
722
  var enMessages = {
@@ -879,6 +740,7 @@ var enMessages = {
879
740
  dateRangePresetsLabel: "Date range shortcuts",
880
741
  numberFieldIncrease: "Increase",
881
742
  numberFieldDecrease: "Decrease",
743
+ inputClear: "Clear",
882
744
  valueHelpFieldPlaceholder: "Not selected",
883
745
  valueHelpFieldClear: "Clear selection",
884
746
  valueHelpFieldOpenNamed: "Select {label}",
@@ -933,6 +795,7 @@ var esMessages = {
933
795
  dateRangePresetsLabel: "Atajos de rango de fechas",
934
796
  numberFieldIncrease: "Aumentar",
935
797
  numberFieldDecrease: "Disminuir",
798
+ inputClear: "Limpiar",
936
799
  valueHelpFieldPlaceholder: "Sin seleccionar",
937
800
  valueHelpFieldClear: "Limpiar selecci\xF3n",
938
801
  valueHelpFieldOpenNamed: "Seleccionar {label}",
@@ -968,24 +831,187 @@ var esMessages = {
968
831
  };
969
832
 
970
833
  // src/i18n/PireIntlProvider.tsx
971
- import { jsx as jsx18 } from "react/jsx-runtime";
972
- var MessagesContext = React6.createContext(enMessages);
834
+ import { jsx as jsx16 } from "react/jsx-runtime";
835
+ var MessagesContext = React5.createContext(enMessages);
973
836
  function PireIntlProvider({ messages, children }) {
974
- const value = React6.useMemo(
837
+ const value = React5.useMemo(
975
838
  () => messages ? { ...enMessages, ...messages } : enMessages,
976
839
  [messages]
977
840
  );
978
- return /* @__PURE__ */ jsx18(MessagesContext.Provider, { value, children });
841
+ return /* @__PURE__ */ jsx16(MessagesContext.Provider, { value, children });
979
842
  }
980
843
  function usePireMessages() {
981
- return React6.useContext(MessagesContext);
844
+ return React5.useContext(MessagesContext);
982
845
  }
983
846
  function useMessage(key, override) {
984
- const messages = React6.useContext(MessagesContext);
847
+ const messages = React5.useContext(MessagesContext);
985
848
  return override ?? messages[key];
986
849
  }
987
850
 
851
+ // src/components/forms/Input.tsx
852
+ import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
853
+ function Input({
854
+ label,
855
+ icon,
856
+ suffix,
857
+ description,
858
+ errorMessage,
859
+ size = "md",
860
+ numeric,
861
+ isClearable,
862
+ clearLabel,
863
+ fullWidth = true,
864
+ className,
865
+ style,
866
+ inputRef,
867
+ onChange,
868
+ ...rest
869
+ }) {
870
+ const msg = usePireMessages();
871
+ const isControlled = rest.value !== void 0;
872
+ const [ownValue, setOwnValue] = React6.useState(rest.defaultValue ?? "");
873
+ const currentValue = isControlled ? rest.value : ownValue;
874
+ const handleChange = (next) => {
875
+ setOwnValue(next);
876
+ onChange?.(next);
877
+ };
878
+ const takesOverValue = isClearable && !isControlled;
879
+ const valueProps = takesOverValue ? { value: ownValue, defaultValue: void 0 } : {};
880
+ const showsClear = isClearable && currentValue !== "" && !rest.isDisabled && !rest.isReadOnly;
881
+ return /* @__PURE__ */ jsxs10(
882
+ TextField,
883
+ {
884
+ className: cx("pire-field", className),
885
+ style,
886
+ onChange: handleChange,
887
+ validationBehavior: "aria",
888
+ ...rest,
889
+ ...valueProps,
890
+ children: [
891
+ label ? /* @__PURE__ */ jsxs10(Label, { className: "pire-field-label", children: [
892
+ label,
893
+ rest.isRequired ? /* @__PURE__ */ jsx17("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
894
+ ] }) : null,
895
+ /* @__PURE__ */ jsxs10(
896
+ Group,
897
+ {
898
+ className: "pire-control",
899
+ "data-size": size,
900
+ "data-full-width": String(fullWidth),
901
+ "data-invalid": rest.isInvalid ? "true" : void 0,
902
+ "data-readonly": rest.isReadOnly ? "true" : void 0,
903
+ children: [
904
+ icon ? /* @__PURE__ */ jsx17(Icon, { name: icon, size: 16, className: "pire-leading-icon" }) : null,
905
+ /* @__PURE__ */ jsx17(AriaInput, { ref: inputRef, className: "pire-input", "data-numeric": numeric ? "true" : void 0 }),
906
+ showsClear ? /* @__PURE__ */ jsx17(AriaButton4, { className: "pire-input-clear", onPress: () => handleChange(""), children: clearLabel ?? msg.inputClear }) : null,
907
+ suffix ? /* @__PURE__ */ jsx17("span", { className: "pire-affix", children: suffix }) : null
908
+ ]
909
+ }
910
+ ),
911
+ description ? /* @__PURE__ */ jsx17(Text2, { slot: "description", className: "pire-field-hint", children: description }) : null,
912
+ /* @__PURE__ */ jsx17(FieldError, { className: "pire-field-error", children: errorMessage })
913
+ ]
914
+ }
915
+ );
916
+ }
917
+
918
+ // src/components/forms/TextArea.tsx
919
+ import * as React7 from "react";
920
+ import { TextField as TextField2, Label as Label2, TextArea as AriaTextArea, Group as Group2, Text as Text3, FieldError as FieldError2 } from "react-aria-components";
921
+ import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
922
+ var useIsomorphicLayoutEffect = typeof document === "undefined" ? React7.useEffect : React7.useLayoutEffect;
923
+ function TextArea({
924
+ label,
925
+ description,
926
+ errorMessage,
927
+ size = "md",
928
+ rows = 3,
929
+ autoGrow,
930
+ maxRows,
931
+ fullWidth = true,
932
+ className,
933
+ style,
934
+ textAreaRef,
935
+ onChange,
936
+ ...rest
937
+ }) {
938
+ const innerRef = React7.useRef(null);
939
+ const ref = React7.useCallback((node) => {
940
+ innerRef.current = node;
941
+ if (typeof textAreaRef === "function") textAreaRef(node);
942
+ else if (textAreaRef) textAreaRef.current = node;
943
+ }, [textAreaRef]);
944
+ const grow = React7.useCallback(() => {
945
+ const el = innerRef.current;
946
+ if (!el || !autoGrow) return;
947
+ const styles = getComputedStyle(el);
948
+ const lineHeight = Number.parseFloat(styles.lineHeight) || Number.parseFloat(styles.fontSize) * 1.5;
949
+ const chrome = el.offsetHeight - el.clientHeight;
950
+ el.style.height = "auto";
951
+ const wanted = maxRows ? Math.min(el.scrollHeight, Math.ceil(lineHeight * maxRows)) : el.scrollHeight;
952
+ const next = `${wanted + chrome}px`;
953
+ if (el.style.height !== next) el.style.height = next;
954
+ }, [autoGrow, maxRows]);
955
+ useIsomorphicLayoutEffect(() => {
956
+ if (!autoGrow) {
957
+ if (innerRef.current) innerRef.current.style.height = "";
958
+ return;
959
+ }
960
+ grow();
961
+ }, [autoGrow, grow, rest.value]);
962
+ return /* @__PURE__ */ jsxs11(
963
+ TextField2,
964
+ {
965
+ className: cx("pire-field", className),
966
+ style,
967
+ onChange,
968
+ validationBehavior: "aria",
969
+ ...rest,
970
+ children: [
971
+ label ? /* @__PURE__ */ jsxs11(Label2, { className: "pire-field-label", children: [
972
+ label,
973
+ rest.isRequired ? /* @__PURE__ */ jsx18("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
974
+ ] }) : null,
975
+ /* @__PURE__ */ jsx18(
976
+ Group2,
977
+ {
978
+ className: "pire-control",
979
+ "data-size": size,
980
+ "data-full-width": String(fullWidth),
981
+ "data-multiline": "true",
982
+ "data-invalid": rest.isInvalid ? "true" : void 0,
983
+ "data-readonly": rest.isReadOnly ? "true" : void 0,
984
+ children: /* @__PURE__ */ jsx18(
985
+ AriaTextArea,
986
+ {
987
+ ref,
988
+ rows,
989
+ onInput: autoGrow ? grow : void 0,
990
+ className: cx("pire-input", "pire-textarea"),
991
+ "data-auto-grow": autoGrow ? "true" : void 0
992
+ }
993
+ )
994
+ }
995
+ ),
996
+ description ? /* @__PURE__ */ jsx18(Text3, { slot: "description", className: "pire-field-hint", children: description }) : null,
997
+ /* @__PURE__ */ jsx18(FieldError2, { className: "pire-field-error", children: errorMessage })
998
+ ]
999
+ }
1000
+ );
1001
+ }
1002
+
988
1003
  // src/components/forms/Select.tsx
1004
+ import {
1005
+ Select as AriaSelect,
1006
+ Label as Label3,
1007
+ Button as AriaButton5,
1008
+ SelectValue,
1009
+ Popover,
1010
+ ListBox,
1011
+ ListBoxItem,
1012
+ Text as Text4,
1013
+ FieldError as FieldError3
1014
+ } from "react-aria-components";
989
1015
  import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
990
1016
  var norm = (o) => typeof o === "string" ? { value: o, label: o, isDisabled: false } : o;
991
1017
  function Select({
@@ -1024,7 +1050,7 @@ function Select({
1024
1050
  rest.isRequired ? /* @__PURE__ */ jsx19("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
1025
1051
  ] }) : null,
1026
1052
  /* @__PURE__ */ jsxs12(
1027
- AriaButton4,
1053
+ AriaButton5,
1028
1054
  {
1029
1055
  className: "pire-control",
1030
1056
  "data-size": size,
@@ -1107,7 +1133,7 @@ import {
1107
1133
  ComboBox as AriaComboBox,
1108
1134
  Label as Label5,
1109
1135
  Input as AriaInput2,
1110
- Button as AriaButton5,
1136
+ Button as AriaButton6,
1111
1137
  Group as Group3,
1112
1138
  Popover as Popover2,
1113
1139
  ListBox as ListBox2,
@@ -1175,7 +1201,7 @@ function ComboBox({
1175
1201
  children: [
1176
1202
  /* @__PURE__ */ jsx23(Icon, { name: "search", size: 16, className: "pire-leading-icon" }),
1177
1203
  /* @__PURE__ */ jsx23(AriaInput2, { className: "pire-input", placeholder: rest.placeholder }),
1178
- /* @__PURE__ */ jsx23(AriaButton5, { className: "pire-iconbtn", "data-size": "sm", "aria-label": msg.comboBoxShowSuggestions, style: { width: 20, height: 20 }, children: /* @__PURE__ */ jsx23(Icon, { name: "chevron-down", size: 16 }) })
1204
+ /* @__PURE__ */ jsx23(AriaButton6, { className: "pire-iconbtn", "data-size": "sm", "aria-label": msg.comboBoxShowSuggestions, style: { width: 20, height: 20 }, children: /* @__PURE__ */ jsx23(Icon, { name: "chevron-down", size: 16 }) })
1179
1205
  ]
1180
1206
  }
1181
1207
  ),
@@ -1202,12 +1228,12 @@ function ComboBox({
1202
1228
  }
1203
1229
 
1204
1230
  // src/components/forms/MultiComboBox.tsx
1205
- import * as React7 from "react";
1231
+ import * as React8 from "react";
1206
1232
  import {
1207
1233
  ComboBox as AriaComboBox2,
1208
1234
  Label as Label6,
1209
1235
  Input as AriaInput3,
1210
- Button as AriaButton6,
1236
+ Button as AriaButton7,
1211
1237
  ButtonContext,
1212
1238
  Group as Group4,
1213
1239
  Popover as Popover3,
@@ -1241,15 +1267,15 @@ function MultiComboBox({
1241
1267
  ...rest
1242
1268
  }) {
1243
1269
  const msg = usePireMessages();
1244
- const items = React7.useMemo(() => options.map(norm3), [options]);
1270
+ const items = React8.useMemo(() => options.map(norm3), [options]);
1245
1271
  const collection = isFilteredExternally ? { items } : { defaultItems: items };
1246
1272
  const showsStatus = isLoading || isFilteredExternally && items.length === 0 && emptyLabel != null;
1247
- const [uncontrolled, setUncontrolled] = React7.useState(defaultValue ?? []);
1248
- const [announcement, setAnnouncement] = React7.useState("");
1249
- const inputRef = React7.useRef(null);
1273
+ const [uncontrolled, setUncontrolled] = React8.useState(defaultValue ?? []);
1274
+ const [announcement, setAnnouncement] = React8.useState("");
1275
+ const inputRef = React8.useRef(null);
1250
1276
  const raw = value ?? uncontrolled;
1251
1277
  const contentKey = raw.join("\0");
1252
- const values = React7.useMemo(() => raw, [contentKey]);
1278
+ const values = React8.useMemo(() => raw, [contentKey]);
1253
1279
  const labelOf = (v) => items.find((o) => o.value === v)?.label ?? v;
1254
1280
  const isEditable = !rest.isDisabled && !rest.isReadOnly;
1255
1281
  const commit = (next) => {
@@ -1330,7 +1356,7 @@ function MultiComboBox({
1330
1356
  }
1331
1357
  )
1332
1358
  ] }),
1333
- /* @__PURE__ */ jsx24(AriaButton6, { className: "pire-iconbtn", "data-size": "sm", "aria-label": msg.comboBoxShowSuggestions, style: { width: 20, height: 20 }, children: /* @__PURE__ */ jsx24(Icon, { name: "chevron-down", size: 16 }) })
1359
+ /* @__PURE__ */ jsx24(AriaButton7, { className: "pire-iconbtn", "data-size": "sm", "aria-label": msg.comboBoxShowSuggestions, style: { width: 20, height: 20 }, children: /* @__PURE__ */ jsx24(Icon, { name: "chevron-down", size: 16 }) })
1334
1360
  ]
1335
1361
  }
1336
1362
  ),
@@ -1363,7 +1389,7 @@ import {
1363
1389
  Label as Label7,
1364
1390
  Input as AriaInput4,
1365
1391
  Group as Group5,
1366
- Button as AriaButton7,
1392
+ Button as AriaButton8,
1367
1393
  Text as Text8,
1368
1394
  FieldError as FieldError7
1369
1395
  } from "react-aria-components";
@@ -1398,8 +1424,8 @@ function NumberField({
1398
1424
  /* @__PURE__ */ jsx25(AriaInput4, { className: "pire-input", "data-numeric": "true" }),
1399
1425
  suffix ? /* @__PURE__ */ jsx25("span", { className: "pire-affix", children: suffix }) : null,
1400
1426
  hideStepper ? null : /* @__PURE__ */ jsxs18("span", { className: "pire-stepper", children: [
1401
- /* @__PURE__ */ jsx25(AriaButton7, { slot: "increment", className: "pire-stepper-btn", "aria-label": msg.numberFieldIncrease, children: /* @__PURE__ */ jsx25(Icon, { name: "plus", size: 10 }) }),
1402
- /* @__PURE__ */ jsx25(AriaButton7, { slot: "decrement", className: "pire-stepper-btn", "aria-label": msg.numberFieldDecrease, children: /* @__PURE__ */ jsx25(Icon, { name: "minus", size: 10 }) })
1427
+ /* @__PURE__ */ jsx25(AriaButton8, { slot: "increment", className: "pire-stepper-btn", "aria-label": msg.numberFieldIncrease, children: /* @__PURE__ */ jsx25(Icon, { name: "plus", size: 10 }) }),
1428
+ /* @__PURE__ */ jsx25(AriaButton8, { slot: "decrement", className: "pire-stepper-btn", "aria-label": msg.numberFieldDecrease, children: /* @__PURE__ */ jsx25(Icon, { name: "minus", size: 10 }) })
1403
1429
  ] })
1404
1430
  ]
1405
1431
  }
@@ -1416,7 +1442,7 @@ import {
1416
1442
  Group as Group6,
1417
1443
  DateInput,
1418
1444
  DateSegment,
1419
- Button as AriaButton8,
1445
+ Button as AriaButton9,
1420
1446
  Popover as Popover4,
1421
1447
  Dialog as AriaDialog,
1422
1448
  Calendar,
@@ -1456,7 +1482,7 @@ function DatePicker({
1456
1482
  "data-readonly": rest.isReadOnly ? "true" : void 0,
1457
1483
  children: [
1458
1484
  /* @__PURE__ */ jsx26(DateInput, { className: "pire-datefield", children: (segment) => /* @__PURE__ */ jsx26(DateSegment, { segment, className: "pire-datesegment" }) }),
1459
- /* @__PURE__ */ jsx26(AriaButton8, { className: "pire-iconbtn", "data-size": "sm", "aria-label": msg.datePickerOpenCalendar, style: { width: 24, height: 24 }, children: /* @__PURE__ */ jsx26(Icon, { name: "calendar", size: 16 }) })
1485
+ /* @__PURE__ */ jsx26(AriaButton9, { className: "pire-iconbtn", "data-size": "sm", "aria-label": msg.datePickerOpenCalendar, style: { width: 24, height: 24 }, children: /* @__PURE__ */ jsx26(Icon, { name: "calendar", size: 16 }) })
1460
1486
  ]
1461
1487
  }
1462
1488
  ),
@@ -1464,9 +1490,9 @@ function DatePicker({
1464
1490
  /* @__PURE__ */ jsx26(FieldError8, { className: "pire-field-error", children: errorMessage }),
1465
1491
  /* @__PURE__ */ jsx26(Popover4, { className: "pire-popover", children: /* @__PURE__ */ jsx26(AriaDialog, { children: /* @__PURE__ */ jsxs19(Calendar, { className: "pire-calendar", children: [
1466
1492
  /* @__PURE__ */ jsxs19("header", { className: "pire-calendar-head", children: [
1467
- /* @__PURE__ */ jsx26(AriaButton8, { slot: "previous", className: "pire-iconbtn", "data-size": "sm", "aria-label": msg.datePickerPreviousMonth, children: /* @__PURE__ */ jsx26(Icon, { name: "chevron-left", size: 16 }) }),
1493
+ /* @__PURE__ */ jsx26(AriaButton9, { slot: "previous", className: "pire-iconbtn", "data-size": "sm", "aria-label": msg.datePickerPreviousMonth, children: /* @__PURE__ */ jsx26(Icon, { name: "chevron-left", size: 16 }) }),
1468
1494
  /* @__PURE__ */ jsx26(Heading2, { className: "pire-calendar-title" }),
1469
- /* @__PURE__ */ jsx26(AriaButton8, { slot: "next", className: "pire-iconbtn", "data-size": "sm", "aria-label": msg.datePickerNextMonth, children: /* @__PURE__ */ jsx26(Icon, { name: "chevron-right", size: 16 }) })
1495
+ /* @__PURE__ */ jsx26(AriaButton9, { slot: "next", className: "pire-iconbtn", "data-size": "sm", "aria-label": msg.datePickerNextMonth, children: /* @__PURE__ */ jsx26(Icon, { name: "chevron-right", size: 16 }) })
1470
1496
  ] }),
1471
1497
  /* @__PURE__ */ jsxs19(CalendarGrid, { className: "pire-calendar-grid", children: [
1472
1498
  /* @__PURE__ */ jsx26(CalendarGridHeader, { children: (day) => /* @__PURE__ */ jsx26(CalendarHeaderCell, { children: day }) }),
@@ -1483,7 +1509,7 @@ import {
1483
1509
  Group as Group7,
1484
1510
  DateInput as DateInput2,
1485
1511
  DateSegment as DateSegment2,
1486
- Button as AriaButton9,
1512
+ Button as AriaButton10,
1487
1513
  Popover as Popover5,
1488
1514
  Dialog as AriaDialog2,
1489
1515
  RangeCalendar,
@@ -1545,7 +1571,7 @@ function DateRangePicker({
1545
1571
  /* @__PURE__ */ jsx27("span", { "aria-hidden": "true", className: "pire-daterange-dash", children: "\u2013" }),
1546
1572
  /* @__PURE__ */ jsx27(DateInput2, { slot: "end", className: "pire-datefield", children: (segment) => /* @__PURE__ */ jsx27(DateSegment2, { segment, className: "pire-datesegment" }) }),
1547
1573
  /* @__PURE__ */ jsx27(
1548
- AriaButton9,
1574
+ AriaButton10,
1549
1575
  {
1550
1576
  className: "pire-iconbtn",
1551
1577
  "data-size": "sm",
@@ -1564,7 +1590,7 @@ function DateRangePicker({
1564
1590
  // Before the calendar in the DOM, so keyboard users reach the shortcut without
1565
1591
  // arrowing through a month first.
1566
1592
  /* @__PURE__ */ jsx27("div", { className: "pire-daterange-presets", role: "group", "aria-label": msg.dateRangePresetsLabel, children: presets.map((preset) => /* @__PURE__ */ jsx27(
1567
- AriaButton9,
1593
+ AriaButton10,
1568
1594
  {
1569
1595
  className: "pire-daterange-preset",
1570
1596
  onPress: () => rest.onChange?.(preset.range()),
@@ -1576,7 +1602,7 @@ function DateRangePicker({
1576
1602
  /* @__PURE__ */ jsxs20(RangeCalendar, { className: "pire-calendar", children: [
1577
1603
  /* @__PURE__ */ jsxs20("header", { className: "pire-calendar-head", children: [
1578
1604
  /* @__PURE__ */ jsx27(
1579
- AriaButton9,
1605
+ AriaButton10,
1580
1606
  {
1581
1607
  slot: "previous",
1582
1608
  className: "pire-iconbtn",
@@ -1587,7 +1613,7 @@ function DateRangePicker({
1587
1613
  ),
1588
1614
  /* @__PURE__ */ jsx27(Heading3, { className: "pire-calendar-title" }),
1589
1615
  /* @__PURE__ */ jsx27(
1590
- AriaButton9,
1616
+ AriaButton10,
1591
1617
  {
1592
1618
  slot: "next",
1593
1619
  className: "pire-iconbtn",
@@ -1609,10 +1635,10 @@ function DateRangePicker({
1609
1635
  }
1610
1636
 
1611
1637
  // src/components/forms/ValueHelpField.tsx
1612
- import * as React9 from "react";
1638
+ import * as React10 from "react";
1613
1639
 
1614
1640
  // src/components/patterns/ValueHelpDialog.tsx
1615
- import * as React8 from "react";
1641
+ import * as React9 from "react";
1616
1642
 
1617
1643
  // src/components/feedback/Dialog.tsx
1618
1644
  import { ModalOverlay, Modal, Dialog as AriaDialog3, Heading as Heading4 } from "react-aria-components";
@@ -1842,11 +1868,11 @@ function ValueHelpDialog({
1842
1868
  onClose
1843
1869
  }) {
1844
1870
  const msg = usePireMessages();
1845
- const [query, setQuery] = React8.useState("");
1846
- React8.useEffect(() => {
1871
+ const [query, setQuery] = React9.useState("");
1872
+ React9.useEffect(() => {
1847
1873
  if (isOpen) setQuery("");
1848
1874
  }, [isOpen]);
1849
- const filtered = React8.useMemo(() => {
1875
+ const filtered = React9.useMemo(() => {
1850
1876
  if (isFilteredExternally) return rows;
1851
1877
  const q = query.trim().toLowerCase();
1852
1878
  if (!q) return rows;
@@ -1873,6 +1899,7 @@ function ValueHelpDialog({
1873
1899
  type: "search",
1874
1900
  value: query,
1875
1901
  onChange: handleSearch,
1902
+ isClearable: true,
1876
1903
  placeholder: searchPlaceholder ?? msg.valueHelpDialogSearchPlaceholder,
1877
1904
  autoFocus: true
1878
1905
  }
@@ -1927,7 +1954,7 @@ function ValueHelpField({
1927
1954
  style
1928
1955
  }) {
1929
1956
  const msg = usePireMessages();
1930
- const [open, setOpen] = React9.useState(false);
1957
+ const [open, setOpen] = React10.useState(false);
1931
1958
  return /* @__PURE__ */ jsxs24("div", { className: cx(className), style, children: [
1932
1959
  /* @__PURE__ */ jsx32(
1933
1960
  Input,
@@ -1983,7 +2010,7 @@ function ValueHelpField({
1983
2010
  }
1984
2011
 
1985
2012
  // src/components/forms/FileUpload.tsx
1986
- import * as React10 from "react";
2013
+ import * as React11 from "react";
1987
2014
  import { FileTrigger, Text as Text11 } from "react-aria-components";
1988
2015
 
1989
2016
  // src/components/feedback/ProgressBar.tsx
@@ -2073,10 +2100,10 @@ function FileUpload({
2073
2100
  style
2074
2101
  }) {
2075
2102
  const msg = usePireMessages();
2076
- const [uncontrolled, setUncontrolled] = React10.useState(defaultValue ?? []);
2103
+ const [uncontrolled, setUncontrolled] = React11.useState(defaultValue ?? []);
2077
2104
  const files = value ?? uncontrolled;
2078
- const created = React10.useRef([]);
2079
- React10.useEffect(() => () => {
2105
+ const created = React11.useRef([]);
2106
+ React11.useEffect(() => () => {
2080
2107
  for (const url of created.current) URL.revokeObjectURL(url);
2081
2108
  }, []);
2082
2109
  const commit = (next) => {
@@ -2140,7 +2167,7 @@ function FileUpload({
2140
2167
  }
2141
2168
 
2142
2169
  // src/components/navigation/ShellBar.tsx
2143
- import { MenuTrigger, Button as AriaButton10, Popover as Popover6 } from "react-aria-components";
2170
+ import { MenuTrigger, Button as AriaButton11, Popover as Popover6 } from "react-aria-components";
2144
2171
  import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
2145
2172
  var initials2 = (name) => name.trim().split(/\s+/).slice(0, 2).map((p) => p[0]).join("").toUpperCase();
2146
2173
  function ShellBar({
@@ -2173,7 +2200,7 @@ function ShellBar({
2173
2200
  // rendered here rather than expected from the consumer so the panel keeps shell placement.
2174
2201
  /* @__PURE__ */ jsxs27(MenuTrigger, { children: [
2175
2202
  /* @__PURE__ */ jsx35(
2176
- AriaButton10,
2203
+ AriaButton11,
2177
2204
  {
2178
2205
  className: "pire-avatar pire-avatar-trigger",
2179
2206
  "aria-label": (userMenuLabel ?? msg.shellBarUserMenu).replace("{user}", user),
@@ -2187,9 +2214,9 @@ function ShellBar({
2187
2214
  }
2188
2215
 
2189
2216
  // src/components/navigation/SideNav.tsx
2190
- import * as React11 from "react";
2217
+ import * as React12 from "react";
2191
2218
  import {
2192
- Button as AriaButton11,
2219
+ Button as AriaButton12,
2193
2220
  Disclosure,
2194
2221
  DisclosureGroup,
2195
2222
  DisclosurePanel,
@@ -2287,10 +2314,10 @@ function SideNav({
2287
2314
  const msg = usePireMessages();
2288
2315
  const activeParent = findActiveParent(groups, value);
2289
2316
  const isControlled = expandedIds != null;
2290
- const [ownExpanded, setOwnExpanded] = React11.useState(
2317
+ const [ownExpanded, setOwnExpanded] = React12.useState(
2291
2318
  () => new Set(defaultExpandedIds ?? (activeParent ? [activeParent] : []))
2292
2319
  );
2293
- const [lastValue, setLastValue] = React11.useState(value);
2320
+ const [lastValue, setLastValue] = React12.useState(value);
2294
2321
  if (value !== lastValue) {
2295
2322
  setLastValue(value);
2296
2323
  if (!isControlled && activeParent && !ownExpanded.has(activeParent)) {
@@ -2311,7 +2338,7 @@ function SideNav({
2311
2338
  const renderRow = (item, onPress, isGroup) => {
2312
2339
  const selected = !isGroup && item.id === value;
2313
2340
  const button = /* @__PURE__ */ jsxs29(
2314
- AriaButton11,
2341
+ AriaButton12,
2315
2342
  {
2316
2343
  className: "pire-sidenav-item",
2317
2344
  "data-selected": selected ? "true" : void 0,
@@ -2331,7 +2358,7 @@ function SideNav({
2331
2358
  };
2332
2359
  const renderRailFlyout = (item) => /* @__PURE__ */ jsxs29(MenuTrigger2, { children: [
2333
2360
  /* @__PURE__ */ jsx37(
2334
- AriaButton11,
2361
+ AriaButton12,
2335
2362
  {
2336
2363
  className: "pire-sidenav-item",
2337
2364
  "aria-label": item.label,
@@ -2351,7 +2378,7 @@ function SideNav({
2351
2378
  ] }, item.id);
2352
2379
  const renderSection = (item) => /* @__PURE__ */ jsxs29(Disclosure, { id: item.id, className: "pire-sidenav-section", children: [
2353
2380
  /* @__PURE__ */ jsxs29(
2354
- AriaButton11,
2381
+ AriaButton12,
2355
2382
  {
2356
2383
  slot: "trigger",
2357
2384
  className: "pire-sidenav-item",
@@ -2368,7 +2395,7 @@ function SideNav({
2368
2395
  /* @__PURE__ */ jsx37(DisclosurePanel, { className: "pire-sidenav-subnav", children: item.items?.map((child) => {
2369
2396
  const selected = child.id === value;
2370
2397
  return /* @__PURE__ */ jsxs29(
2371
- AriaButton11,
2398
+ AriaButton12,
2372
2399
  {
2373
2400
  className: "pire-sidenav-item pire-sidenav-subitem",
2374
2401
  "data-selected": selected ? "true" : void 0,
@@ -2554,7 +2581,7 @@ function InlineMessage({ kind = "info", title, action, onClose, children, classN
2554
2581
  }
2555
2582
 
2556
2583
  // src/components/feedback/Toast.tsx
2557
- import * as React12 from "react";
2584
+ import * as React13 from "react";
2558
2585
  import { jsx as jsx42, jsxs as jsxs34 } from "react/jsx-runtime";
2559
2586
  var KIND_ICON2 = {
2560
2587
  info: "info",
@@ -2580,32 +2607,32 @@ function Toast({ kind = "success", onClose, position = "bottom-center", children
2580
2607
  }
2581
2608
  );
2582
2609
  }
2583
- var ToastContext = React12.createContext(null);
2610
+ var ToastContext = React13.createContext(null);
2584
2611
  function ToastProvider({ children, timeout = 6e3 }) {
2585
2612
  const msg = usePireMessages();
2586
- const [toasts, setToasts] = React12.useState([]);
2587
- const close = React12.useCallback((id) => setToasts((t) => t.filter((x) => x.id !== id)), []);
2588
- const add = React12.useCallback((toast) => {
2613
+ const [toasts, setToasts] = React13.useState([]);
2614
+ const close = React13.useCallback((id) => setToasts((t) => t.filter((x) => x.id !== id)), []);
2615
+ const add = React13.useCallback((toast) => {
2589
2616
  const id = Math.random().toString(36).slice(2);
2590
2617
  setToasts((t) => [...t, { ...toast, id }]);
2591
2618
  const ms = toast.timeout ?? timeout;
2592
2619
  if (ms > 0) setTimeout(() => close(id), ms);
2593
2620
  return id;
2594
2621
  }, [close, timeout]);
2595
- const value = React12.useMemo(() => ({ add, close }), [add, close]);
2622
+ const value = React13.useMemo(() => ({ add, close }), [add, close]);
2596
2623
  return /* @__PURE__ */ jsxs34(ToastContext.Provider, { value, children: [
2597
2624
  children,
2598
2625
  /* @__PURE__ */ jsx42("div", { className: "pire-toast-region", role: "region", "aria-label": msg.toastRegionLabel, children: toasts.map((t) => /* @__PURE__ */ jsx42(Toast, { kind: t.kind, onClose: () => close(t.id), style: { position: "static", transform: "none" }, children: t.message }, t.id)) })
2599
2626
  ] });
2600
2627
  }
2601
2628
  function useToast() {
2602
- const ctx = React12.useContext(ToastContext);
2629
+ const ctx = React13.useContext(ToastContext);
2603
2630
  if (!ctx) throw new Error("useToast must be used inside <ToastProvider>");
2604
2631
  return ctx;
2605
2632
  }
2606
2633
 
2607
2634
  // src/components/data/KpiTile.tsx
2608
- import { Button as AriaButton12 } from "react-aria-components";
2635
+ import { Button as AriaButton13 } from "react-aria-components";
2609
2636
  import { Fragment as Fragment3, jsx as jsx43, jsxs as jsxs35 } from "react/jsx-runtime";
2610
2637
  function KpiTile({
2611
2638
  label,
@@ -2638,7 +2665,7 @@ function KpiTile({
2638
2665
  footnote ? /* @__PURE__ */ jsx43("span", { className: "pire-kpi-foot", children: footnote }) : null
2639
2666
  ] });
2640
2667
  const props = { className: cx("pire-kpi", className), "data-status": status, style };
2641
- return onPress ? /* @__PURE__ */ jsx43(AriaButton12, { ...props, "data-pressable": "true", onPress, children: body }) : /* @__PURE__ */ jsx43("div", { ...props, children: body });
2668
+ return onPress ? /* @__PURE__ */ jsx43(AriaButton13, { ...props, "data-pressable": "true", onPress, children: body }) : /* @__PURE__ */ jsx43("div", { ...props, children: body });
2642
2669
  }
2643
2670
 
2644
2671
  // src/components/data/ObjectHeader.tsx
@@ -2949,14 +2976,14 @@ function BarChart({
2949
2976
  }
2950
2977
 
2951
2978
  // src/components/data/LineChart.tsx
2952
- import * as React13 from "react";
2979
+ import * as React14 from "react";
2953
2980
  import { jsx as jsx50, jsxs as jsxs42 } from "react/jsx-runtime";
2954
2981
  var PLOT_INSET = { top: 10, right: 14, bottom: 24, left: 58 };
2955
2982
  var MARKER_LIMIT = 20;
2956
- var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React13.useEffect : React13.useLayoutEffect;
2983
+ var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React14.useEffect : React14.useLayoutEffect;
2957
2984
  function useMeasuredWidth() {
2958
- const ref = React13.useRef(null);
2959
- const [width, setWidth] = React13.useState(0);
2985
+ const ref = React14.useRef(null);
2986
+ const [width, setWidth] = React14.useState(0);
2960
2987
  useIsomorphicLayoutEffect2(() => {
2961
2988
  const element = ref.current;
2962
2989
  if (!element) return;
@@ -3119,7 +3146,7 @@ function LineChart({
3119
3146
  }
3120
3147
 
3121
3148
  // src/components/data/DonutChart.tsx
3122
- import * as React14 from "react";
3149
+ import * as React15 from "react";
3123
3150
  import { jsx as jsx51, jsxs as jsxs43 } from "react/jsx-runtime";
3124
3151
  var SEGMENT_GAP_DEGREES = 1.5;
3125
3152
  function DonutChart({
@@ -3140,7 +3167,7 @@ function DonutChart({
3140
3167
  }) {
3141
3168
  const label = rest["aria-label"];
3142
3169
  const msg = usePireMessages();
3143
- const [hoveredIndex, setHoveredIndex] = React14.useState(null);
3170
+ const [hoveredIndex, setHoveredIndex] = React15.useState(null);
3144
3171
  warnOnDonutShape(series, categories.length, label);
3145
3172
  const values = (series[0]?.values ?? []).slice(0, categories.length);
3146
3173
  const segments = categories.map((category, index) => ({ category, index, value: values[index] ?? 0 })).filter((segment) => segment.value > 0);
@@ -3218,14 +3245,14 @@ function colorForSegment(index) {
3218
3245
  }
3219
3246
 
3220
3247
  // src/components/data/LinkList.tsx
3221
- import { Button as AriaButton13 } from "react-aria-components";
3248
+ import { Button as AriaButton14 } from "react-aria-components";
3222
3249
  import { jsx as jsx52, jsxs as jsxs44 } from "react/jsx-runtime";
3223
3250
  function LinkList({ items, onSelect, emphasis = "key", className, ...rest }) {
3224
3251
  return /* @__PURE__ */ jsx52("div", { className: cx("pire-linklist", className), role: "list", "data-emphasis": emphasis, ...rest, children: items.map((item) => {
3225
3252
  const keySlot = item.key ? /* @__PURE__ */ jsx52("span", { className: "pire-linklist-key", children: item.key }) : null;
3226
3253
  const textSlot = item.text ? /* @__PURE__ */ jsx52("span", { className: "pire-linklist-text", children: item.text }) : null;
3227
3254
  const [first, second] = emphasis === "text" ? [textSlot, keySlot] : [keySlot, textSlot];
3228
- return /* @__PURE__ */ jsx52("div", { role: "listitem", className: "pire-linklist-row", children: /* @__PURE__ */ jsxs44(AriaButton13, { className: "pire-linklist-item", onPress: () => onSelect?.(item.id), children: [
3255
+ return /* @__PURE__ */ jsx52("div", { role: "listitem", className: "pire-linklist-row", children: /* @__PURE__ */ jsxs44(AriaButton14, { className: "pire-linklist-item", onPress: () => onSelect?.(item.id), children: [
3229
3256
  item.icon ? /* @__PURE__ */ jsx52(Icon, { name: item.icon, size: 16, style: { color: "var(--text-secondary)" } }) : null,
3230
3257
  first,
3231
3258
  second,
@@ -3342,7 +3369,7 @@ function ConfirmDialog({
3342
3369
  }
3343
3370
 
3344
3371
  // src/components/patterns/CommandPalette.tsx
3345
- import * as React15 from "react";
3372
+ import * as React16 from "react";
3346
3373
  import {
3347
3374
  Autocomplete,
3348
3375
  ModalOverlay as ModalOverlay2,
@@ -3376,17 +3403,17 @@ function CommandPalette({
3376
3403
  style
3377
3404
  }) {
3378
3405
  const msg = usePireMessages();
3379
- const [query, setQuery] = React15.useState("");
3406
+ const [query, setQuery] = React16.useState("");
3380
3407
  const { contains } = useFilter({ sensitivity: "base" });
3381
- React15.useEffect(() => {
3408
+ React16.useEffect(() => {
3382
3409
  if (isOpen) setQuery("");
3383
3410
  }, [isOpen]);
3384
- const searchableById = React15.useMemo(() => {
3411
+ const searchableById = React16.useMemo(() => {
3385
3412
  const byId = /* @__PURE__ */ new Map();
3386
3413
  for (const group of groups) for (const item of group.items) byId.set(item.id, searchableText(item));
3387
3414
  return byId;
3388
3415
  }, [groups]);
3389
- const filter = React15.useCallback((textValue, inputValue, node) => {
3416
+ const filter = React16.useCallback((textValue, inputValue, node) => {
3390
3417
  if (node.parentKey === RESULTS_SECTION_KEY) return true;
3391
3418
  return contains(searchableById.get(String(node.key)) ?? textValue, inputValue);
3392
3419
  }, [contains, searchableById]);
@@ -3469,9 +3496,9 @@ function CommandPalette({
3469
3496
  );
3470
3497
  }
3471
3498
  function useCommandPaletteShortcut(onTrigger, { key = "k", isDisabled } = {}) {
3472
- const handler = React15.useRef(onTrigger);
3499
+ const handler = React16.useRef(onTrigger);
3473
3500
  handler.current = onTrigger;
3474
- React15.useEffect(() => {
3501
+ React16.useEffect(() => {
3475
3502
  if (isDisabled) return;
3476
3503
  const onKeyDown = (event) => {
3477
3504
  if (!(event.metaKey || event.ctrlKey) || event.altKey) return;
@@ -3525,7 +3552,7 @@ function EmptyState({ icon = "file-text", title, action, compact, children, clas
3525
3552
  }
3526
3553
 
3527
3554
  // src/components/patterns/FileDropZone.tsx
3528
- import * as React16 from "react";
3555
+ import * as React17 from "react";
3529
3556
  import { DropZone, FileTrigger as FileTrigger2, isFileDropItem } from "react-aria-components";
3530
3557
  import { jsx as jsx62, jsxs as jsxs53 } from "react/jsx-runtime";
3531
3558
  var isImage2 = (file) => file.type.startsWith("image/");
@@ -3553,10 +3580,10 @@ function FileDropZone({
3553
3580
  style
3554
3581
  }) {
3555
3582
  const msg = usePireMessages();
3556
- const [uncontrolled, setUncontrolled] = React16.useState(defaultValue ?? []);
3583
+ const [uncontrolled, setUncontrolled] = React17.useState(defaultValue ?? []);
3557
3584
  const files = value ?? uncontrolled;
3558
- const created = React16.useRef([]);
3559
- React16.useEffect(() => () => {
3585
+ const created = React17.useRef([]);
3586
+ React17.useEffect(() => () => {
3560
3587
  for (const url of created.current) URL.revokeObjectURL(url);
3561
3588
  }, []);
3562
3589
  const commit = (next) => {