@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.cjs CHANGED
@@ -823,148 +823,11 @@ function FormField({ label, htmlFor, isRequired, hint, error, layout = "stacked"
823
823
  }
824
824
 
825
825
  // src/components/forms/Input.tsx
826
+ var React6 = __toESM(require("react"), 1);
826
827
  var import_react_aria_components9 = require("react-aria-components");
827
- var import_jsx_runtime16 = require("react/jsx-runtime");
828
- function Input({
829
- label,
830
- icon,
831
- suffix,
832
- description,
833
- errorMessage,
834
- size = "md",
835
- numeric,
836
- fullWidth = true,
837
- className,
838
- style,
839
- inputRef,
840
- onChange,
841
- ...rest
842
- }) {
843
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
844
- import_react_aria_components9.TextField,
845
- {
846
- className: cx("pire-field", className),
847
- style,
848
- onChange,
849
- validationBehavior: "aria",
850
- ...rest,
851
- children: [
852
- label ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_aria_components9.Label, { className: "pire-field-label", children: [
853
- label,
854
- rest.isRequired ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
855
- ] }) : null,
856
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
857
- import_react_aria_components9.Group,
858
- {
859
- className: "pire-control",
860
- "data-size": size,
861
- "data-full-width": String(fullWidth),
862
- "data-invalid": rest.isInvalid ? "true" : void 0,
863
- "data-readonly": rest.isReadOnly ? "true" : void 0,
864
- children: [
865
- icon ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Icon, { name: icon, size: 16, className: "pire-leading-icon" }) : null,
866
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_aria_components9.Input, { ref: inputRef, className: "pire-input", "data-numeric": numeric ? "true" : void 0 }),
867
- suffix ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "pire-affix", children: suffix }) : null
868
- ]
869
- }
870
- ),
871
- description ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_aria_components9.Text, { slot: "description", className: "pire-field-hint", children: description }) : null,
872
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_aria_components9.FieldError, { className: "pire-field-error", children: errorMessage })
873
- ]
874
- }
875
- );
876
- }
877
-
878
- // src/components/forms/TextArea.tsx
879
- var React5 = __toESM(require("react"), 1);
880
- var import_react_aria_components10 = require("react-aria-components");
881
- var import_jsx_runtime17 = require("react/jsx-runtime");
882
- var useIsomorphicLayoutEffect = typeof document === "undefined" ? React5.useEffect : React5.useLayoutEffect;
883
- function TextArea({
884
- label,
885
- description,
886
- errorMessage,
887
- size = "md",
888
- rows = 3,
889
- autoGrow,
890
- maxRows,
891
- fullWidth = true,
892
- className,
893
- style,
894
- textAreaRef,
895
- onChange,
896
- ...rest
897
- }) {
898
- const innerRef = React5.useRef(null);
899
- const ref = React5.useCallback((node) => {
900
- innerRef.current = node;
901
- if (typeof textAreaRef === "function") textAreaRef(node);
902
- else if (textAreaRef) textAreaRef.current = node;
903
- }, [textAreaRef]);
904
- const grow = React5.useCallback(() => {
905
- const el = innerRef.current;
906
- if (!el || !autoGrow) return;
907
- const styles = getComputedStyle(el);
908
- const lineHeight = Number.parseFloat(styles.lineHeight) || Number.parseFloat(styles.fontSize) * 1.5;
909
- const chrome = el.offsetHeight - el.clientHeight;
910
- el.style.height = "auto";
911
- const wanted = maxRows ? Math.min(el.scrollHeight, Math.ceil(lineHeight * maxRows)) : el.scrollHeight;
912
- const next = `${wanted + chrome}px`;
913
- if (el.style.height !== next) el.style.height = next;
914
- }, [autoGrow, maxRows]);
915
- useIsomorphicLayoutEffect(() => {
916
- if (!autoGrow) {
917
- if (innerRef.current) innerRef.current.style.height = "";
918
- return;
919
- }
920
- grow();
921
- }, [autoGrow, grow, rest.value]);
922
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
923
- import_react_aria_components10.TextField,
924
- {
925
- className: cx("pire-field", className),
926
- style,
927
- onChange,
928
- validationBehavior: "aria",
929
- ...rest,
930
- children: [
931
- label ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_aria_components10.Label, { className: "pire-field-label", children: [
932
- label,
933
- rest.isRequired ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
934
- ] }) : null,
935
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
936
- import_react_aria_components10.Group,
937
- {
938
- className: "pire-control",
939
- "data-size": size,
940
- "data-full-width": String(fullWidth),
941
- "data-multiline": "true",
942
- "data-invalid": rest.isInvalid ? "true" : void 0,
943
- "data-readonly": rest.isReadOnly ? "true" : void 0,
944
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
945
- import_react_aria_components10.TextArea,
946
- {
947
- ref,
948
- rows,
949
- onInput: autoGrow ? grow : void 0,
950
- className: cx("pire-input", "pire-textarea"),
951
- "data-auto-grow": autoGrow ? "true" : void 0
952
- }
953
- )
954
- }
955
- ),
956
- description ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_aria_components10.Text, { slot: "description", className: "pire-field-hint", children: description }) : null,
957
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_aria_components10.FieldError, { className: "pire-field-error", children: errorMessage })
958
- ]
959
- }
960
- );
961
- }
962
-
963
- // src/components/forms/Select.tsx
964
- var import_react_aria_components11 = require("react-aria-components");
965
828
 
966
829
  // src/i18n/PireIntlProvider.tsx
967
- var React6 = __toESM(require("react"), 1);
830
+ var React5 = __toESM(require("react"), 1);
968
831
 
969
832
  // src/i18n/messages.ts
970
833
  var enMessages = {
@@ -988,6 +851,7 @@ var enMessages = {
988
851
  dateRangePresetsLabel: "Date range shortcuts",
989
852
  numberFieldIncrease: "Increase",
990
853
  numberFieldDecrease: "Decrease",
854
+ inputClear: "Clear",
991
855
  valueHelpFieldPlaceholder: "Not selected",
992
856
  valueHelpFieldClear: "Clear selection",
993
857
  valueHelpFieldOpenNamed: "Select {label}",
@@ -1042,6 +906,7 @@ var esMessages = {
1042
906
  dateRangePresetsLabel: "Atajos de rango de fechas",
1043
907
  numberFieldIncrease: "Aumentar",
1044
908
  numberFieldDecrease: "Disminuir",
909
+ inputClear: "Limpiar",
1045
910
  valueHelpFieldPlaceholder: "Sin seleccionar",
1046
911
  valueHelpFieldClear: "Limpiar selecci\xF3n",
1047
912
  valueHelpFieldOpenNamed: "Seleccionar {label}",
@@ -1077,24 +942,177 @@ var esMessages = {
1077
942
  };
1078
943
 
1079
944
  // src/i18n/PireIntlProvider.tsx
1080
- var import_jsx_runtime18 = require("react/jsx-runtime");
1081
- var MessagesContext = React6.createContext(enMessages);
945
+ var import_jsx_runtime16 = require("react/jsx-runtime");
946
+ var MessagesContext = React5.createContext(enMessages);
1082
947
  function PireIntlProvider({ messages, children }) {
1083
- const value = React6.useMemo(
948
+ const value = React5.useMemo(
1084
949
  () => messages ? { ...enMessages, ...messages } : enMessages,
1085
950
  [messages]
1086
951
  );
1087
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(MessagesContext.Provider, { value, children });
952
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MessagesContext.Provider, { value, children });
1088
953
  }
1089
954
  function usePireMessages() {
1090
- return React6.useContext(MessagesContext);
955
+ return React5.useContext(MessagesContext);
1091
956
  }
1092
957
  function useMessage(key, override) {
1093
- const messages = React6.useContext(MessagesContext);
958
+ const messages = React5.useContext(MessagesContext);
1094
959
  return override ?? messages[key];
1095
960
  }
1096
961
 
962
+ // src/components/forms/Input.tsx
963
+ var import_jsx_runtime17 = require("react/jsx-runtime");
964
+ function Input({
965
+ label,
966
+ icon,
967
+ suffix,
968
+ description,
969
+ errorMessage,
970
+ size = "md",
971
+ numeric,
972
+ isClearable,
973
+ clearLabel,
974
+ fullWidth = true,
975
+ className,
976
+ style,
977
+ inputRef,
978
+ onChange,
979
+ ...rest
980
+ }) {
981
+ const msg = usePireMessages();
982
+ const isControlled = rest.value !== void 0;
983
+ const [ownValue, setOwnValue] = React6.useState(rest.defaultValue ?? "");
984
+ const currentValue = isControlled ? rest.value : ownValue;
985
+ const handleChange = (next) => {
986
+ setOwnValue(next);
987
+ onChange?.(next);
988
+ };
989
+ const takesOverValue = isClearable && !isControlled;
990
+ const valueProps = takesOverValue ? { value: ownValue, defaultValue: void 0 } : {};
991
+ const showsClear = isClearable && currentValue !== "" && !rest.isDisabled && !rest.isReadOnly;
992
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
993
+ import_react_aria_components9.TextField,
994
+ {
995
+ className: cx("pire-field", className),
996
+ style,
997
+ onChange: handleChange,
998
+ validationBehavior: "aria",
999
+ ...rest,
1000
+ ...valueProps,
1001
+ children: [
1002
+ label ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_aria_components9.Label, { className: "pire-field-label", children: [
1003
+ label,
1004
+ rest.isRequired ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
1005
+ ] }) : null,
1006
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1007
+ import_react_aria_components9.Group,
1008
+ {
1009
+ className: "pire-control",
1010
+ "data-size": size,
1011
+ "data-full-width": String(fullWidth),
1012
+ "data-invalid": rest.isInvalid ? "true" : void 0,
1013
+ "data-readonly": rest.isReadOnly ? "true" : void 0,
1014
+ children: [
1015
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: icon, size: 16, className: "pire-leading-icon" }) : null,
1016
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_aria_components9.Input, { ref: inputRef, className: "pire-input", "data-numeric": numeric ? "true" : void 0 }),
1017
+ showsClear ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_aria_components9.Button, { className: "pire-input-clear", onPress: () => handleChange(""), children: clearLabel ?? msg.inputClear }) : null,
1018
+ suffix ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "pire-affix", children: suffix }) : null
1019
+ ]
1020
+ }
1021
+ ),
1022
+ description ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_aria_components9.Text, { slot: "description", className: "pire-field-hint", children: description }) : null,
1023
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_aria_components9.FieldError, { className: "pire-field-error", children: errorMessage })
1024
+ ]
1025
+ }
1026
+ );
1027
+ }
1028
+
1029
+ // src/components/forms/TextArea.tsx
1030
+ var React7 = __toESM(require("react"), 1);
1031
+ var import_react_aria_components10 = require("react-aria-components");
1032
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1033
+ var useIsomorphicLayoutEffect = typeof document === "undefined" ? React7.useEffect : React7.useLayoutEffect;
1034
+ function TextArea({
1035
+ label,
1036
+ description,
1037
+ errorMessage,
1038
+ size = "md",
1039
+ rows = 3,
1040
+ autoGrow,
1041
+ maxRows,
1042
+ fullWidth = true,
1043
+ className,
1044
+ style,
1045
+ textAreaRef,
1046
+ onChange,
1047
+ ...rest
1048
+ }) {
1049
+ const innerRef = React7.useRef(null);
1050
+ const ref = React7.useCallback((node) => {
1051
+ innerRef.current = node;
1052
+ if (typeof textAreaRef === "function") textAreaRef(node);
1053
+ else if (textAreaRef) textAreaRef.current = node;
1054
+ }, [textAreaRef]);
1055
+ const grow = React7.useCallback(() => {
1056
+ const el = innerRef.current;
1057
+ if (!el || !autoGrow) return;
1058
+ const styles = getComputedStyle(el);
1059
+ const lineHeight = Number.parseFloat(styles.lineHeight) || Number.parseFloat(styles.fontSize) * 1.5;
1060
+ const chrome = el.offsetHeight - el.clientHeight;
1061
+ el.style.height = "auto";
1062
+ const wanted = maxRows ? Math.min(el.scrollHeight, Math.ceil(lineHeight * maxRows)) : el.scrollHeight;
1063
+ const next = `${wanted + chrome}px`;
1064
+ if (el.style.height !== next) el.style.height = next;
1065
+ }, [autoGrow, maxRows]);
1066
+ useIsomorphicLayoutEffect(() => {
1067
+ if (!autoGrow) {
1068
+ if (innerRef.current) innerRef.current.style.height = "";
1069
+ return;
1070
+ }
1071
+ grow();
1072
+ }, [autoGrow, grow, rest.value]);
1073
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1074
+ import_react_aria_components10.TextField,
1075
+ {
1076
+ className: cx("pire-field", className),
1077
+ style,
1078
+ onChange,
1079
+ validationBehavior: "aria",
1080
+ ...rest,
1081
+ children: [
1082
+ label ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_aria_components10.Label, { className: "pire-field-label", children: [
1083
+ label,
1084
+ rest.isRequired ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
1085
+ ] }) : null,
1086
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1087
+ import_react_aria_components10.Group,
1088
+ {
1089
+ className: "pire-control",
1090
+ "data-size": size,
1091
+ "data-full-width": String(fullWidth),
1092
+ "data-multiline": "true",
1093
+ "data-invalid": rest.isInvalid ? "true" : void 0,
1094
+ "data-readonly": rest.isReadOnly ? "true" : void 0,
1095
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1096
+ import_react_aria_components10.TextArea,
1097
+ {
1098
+ ref,
1099
+ rows,
1100
+ onInput: autoGrow ? grow : void 0,
1101
+ className: cx("pire-input", "pire-textarea"),
1102
+ "data-auto-grow": autoGrow ? "true" : void 0
1103
+ }
1104
+ )
1105
+ }
1106
+ ),
1107
+ description ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_aria_components10.Text, { slot: "description", className: "pire-field-hint", children: description }) : null,
1108
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_aria_components10.FieldError, { className: "pire-field-error", children: errorMessage })
1109
+ ]
1110
+ }
1111
+ );
1112
+ }
1113
+
1097
1114
  // src/components/forms/Select.tsx
1115
+ var import_react_aria_components11 = require("react-aria-components");
1098
1116
  var import_jsx_runtime19 = require("react/jsx-runtime");
1099
1117
  var norm = (o) => typeof o === "string" ? { value: o, label: o, isDisabled: false } : o;
1100
1118
  function Select({
@@ -1294,7 +1312,7 @@ function ComboBox({
1294
1312
  }
1295
1313
 
1296
1314
  // src/components/forms/MultiComboBox.tsx
1297
- var React7 = __toESM(require("react"), 1);
1315
+ var React8 = __toESM(require("react"), 1);
1298
1316
  var import_react_aria_components16 = require("react-aria-components");
1299
1317
  var import_jsx_runtime24 = require("react/jsx-runtime");
1300
1318
  var norm3 = (o) => typeof o === "string" ? { value: o, label: o } : o;
@@ -1320,15 +1338,15 @@ function MultiComboBox({
1320
1338
  ...rest
1321
1339
  }) {
1322
1340
  const msg = usePireMessages();
1323
- const items = React7.useMemo(() => options.map(norm3), [options]);
1341
+ const items = React8.useMemo(() => options.map(norm3), [options]);
1324
1342
  const collection = isFilteredExternally ? { items } : { defaultItems: items };
1325
1343
  const showsStatus = isLoading || isFilteredExternally && items.length === 0 && emptyLabel != null;
1326
- const [uncontrolled, setUncontrolled] = React7.useState(defaultValue ?? []);
1327
- const [announcement, setAnnouncement] = React7.useState("");
1328
- const inputRef = React7.useRef(null);
1344
+ const [uncontrolled, setUncontrolled] = React8.useState(defaultValue ?? []);
1345
+ const [announcement, setAnnouncement] = React8.useState("");
1346
+ const inputRef = React8.useRef(null);
1329
1347
  const raw = value ?? uncontrolled;
1330
1348
  const contentKey = raw.join("\0");
1331
- const values = React7.useMemo(() => raw, [contentKey]);
1349
+ const values = React8.useMemo(() => raw, [contentKey]);
1332
1350
  const labelOf = (v) => items.find((o) => o.value === v)?.label ?? v;
1333
1351
  const isEditable = !rest.isDisabled && !rest.isReadOnly;
1334
1352
  const commit = (next) => {
@@ -1644,10 +1662,10 @@ function DateRangePicker({
1644
1662
  }
1645
1663
 
1646
1664
  // src/components/forms/ValueHelpField.tsx
1647
- var React9 = __toESM(require("react"), 1);
1665
+ var React10 = __toESM(require("react"), 1);
1648
1666
 
1649
1667
  // src/components/patterns/ValueHelpDialog.tsx
1650
- var React8 = __toESM(require("react"), 1);
1668
+ var React9 = __toESM(require("react"), 1);
1651
1669
 
1652
1670
  // src/components/feedback/Dialog.tsx
1653
1671
  var import_react_aria_components20 = require("react-aria-components");
@@ -1870,11 +1888,11 @@ function ValueHelpDialog({
1870
1888
  onClose
1871
1889
  }) {
1872
1890
  const msg = usePireMessages();
1873
- const [query, setQuery] = React8.useState("");
1874
- React8.useEffect(() => {
1891
+ const [query, setQuery] = React9.useState("");
1892
+ React9.useEffect(() => {
1875
1893
  if (isOpen) setQuery("");
1876
1894
  }, [isOpen]);
1877
- const filtered = React8.useMemo(() => {
1895
+ const filtered = React9.useMemo(() => {
1878
1896
  if (isFilteredExternally) return rows;
1879
1897
  const q = query.trim().toLowerCase();
1880
1898
  if (!q) return rows;
@@ -1901,6 +1919,7 @@ function ValueHelpDialog({
1901
1919
  type: "search",
1902
1920
  value: query,
1903
1921
  onChange: handleSearch,
1922
+ isClearable: true,
1904
1923
  placeholder: searchPlaceholder ?? msg.valueHelpDialogSearchPlaceholder,
1905
1924
  autoFocus: true
1906
1925
  }
@@ -1955,7 +1974,7 @@ function ValueHelpField({
1955
1974
  style
1956
1975
  }) {
1957
1976
  const msg = usePireMessages();
1958
- const [open, setOpen] = React9.useState(false);
1977
+ const [open, setOpen] = React10.useState(false);
1959
1978
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cx(className), style, children: [
1960
1979
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1961
1980
  Input,
@@ -2011,7 +2030,7 @@ function ValueHelpField({
2011
2030
  }
2012
2031
 
2013
2032
  // src/components/forms/FileUpload.tsx
2014
- var React10 = __toESM(require("react"), 1);
2033
+ var React11 = __toESM(require("react"), 1);
2015
2034
  var import_react_aria_components23 = require("react-aria-components");
2016
2035
 
2017
2036
  // src/components/feedback/ProgressBar.tsx
@@ -2101,10 +2120,10 @@ function FileUpload({
2101
2120
  style
2102
2121
  }) {
2103
2122
  const msg = usePireMessages();
2104
- const [uncontrolled, setUncontrolled] = React10.useState(defaultValue ?? []);
2123
+ const [uncontrolled, setUncontrolled] = React11.useState(defaultValue ?? []);
2105
2124
  const files = value ?? uncontrolled;
2106
- const created = React10.useRef([]);
2107
- React10.useEffect(() => () => {
2125
+ const created = React11.useRef([]);
2126
+ React11.useEffect(() => () => {
2108
2127
  for (const url of created.current) URL.revokeObjectURL(url);
2109
2128
  }, []);
2110
2129
  const commit = (next) => {
@@ -2215,7 +2234,7 @@ function ShellBar({
2215
2234
  }
2216
2235
 
2217
2236
  // src/components/navigation/SideNav.tsx
2218
- var React11 = __toESM(require("react"), 1);
2237
+ var React12 = __toESM(require("react"), 1);
2219
2238
  var import_react_aria_components26 = require("react-aria-components");
2220
2239
 
2221
2240
  // src/components/navigation/Menu.tsx
@@ -2302,10 +2321,10 @@ function SideNav({
2302
2321
  const msg = usePireMessages();
2303
2322
  const activeParent = findActiveParent(groups, value);
2304
2323
  const isControlled = expandedIds != null;
2305
- const [ownExpanded, setOwnExpanded] = React11.useState(
2324
+ const [ownExpanded, setOwnExpanded] = React12.useState(
2306
2325
  () => new Set(defaultExpandedIds ?? (activeParent ? [activeParent] : []))
2307
2326
  );
2308
- const [lastValue, setLastValue] = React11.useState(value);
2327
+ const [lastValue, setLastValue] = React12.useState(value);
2309
2328
  if (value !== lastValue) {
2310
2329
  setLastValue(value);
2311
2330
  if (!isControlled && activeParent && !ownExpanded.has(activeParent)) {
@@ -2569,7 +2588,7 @@ function InlineMessage({ kind = "info", title, action, onClose, children, classN
2569
2588
  }
2570
2589
 
2571
2590
  // src/components/feedback/Toast.tsx
2572
- var React12 = __toESM(require("react"), 1);
2591
+ var React13 = __toESM(require("react"), 1);
2573
2592
  var import_jsx_runtime42 = require("react/jsx-runtime");
2574
2593
  var KIND_ICON2 = {
2575
2594
  info: "info",
@@ -2595,26 +2614,26 @@ function Toast({ kind = "success", onClose, position = "bottom-center", children
2595
2614
  }
2596
2615
  );
2597
2616
  }
2598
- var ToastContext = React12.createContext(null);
2617
+ var ToastContext = React13.createContext(null);
2599
2618
  function ToastProvider({ children, timeout = 6e3 }) {
2600
2619
  const msg = usePireMessages();
2601
- const [toasts, setToasts] = React12.useState([]);
2602
- const close = React12.useCallback((id) => setToasts((t) => t.filter((x) => x.id !== id)), []);
2603
- const add = React12.useCallback((toast) => {
2620
+ const [toasts, setToasts] = React13.useState([]);
2621
+ const close = React13.useCallback((id) => setToasts((t) => t.filter((x) => x.id !== id)), []);
2622
+ const add = React13.useCallback((toast) => {
2604
2623
  const id = Math.random().toString(36).slice(2);
2605
2624
  setToasts((t) => [...t, { ...toast, id }]);
2606
2625
  const ms = toast.timeout ?? timeout;
2607
2626
  if (ms > 0) setTimeout(() => close(id), ms);
2608
2627
  return id;
2609
2628
  }, [close, timeout]);
2610
- const value = React12.useMemo(() => ({ add, close }), [add, close]);
2629
+ const value = React13.useMemo(() => ({ add, close }), [add, close]);
2611
2630
  return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(ToastContext.Provider, { value, children: [
2612
2631
  children,
2613
2632
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "pire-toast-region", role: "region", "aria-label": msg.toastRegionLabel, children: toasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Toast, { kind: t.kind, onClose: () => close(t.id), style: { position: "static", transform: "none" }, children: t.message }, t.id)) })
2614
2633
  ] });
2615
2634
  }
2616
2635
  function useToast() {
2617
- const ctx = React12.useContext(ToastContext);
2636
+ const ctx = React13.useContext(ToastContext);
2618
2637
  if (!ctx) throw new Error("useToast must be used inside <ToastProvider>");
2619
2638
  return ctx;
2620
2639
  }
@@ -2964,14 +2983,14 @@ function BarChart({
2964
2983
  }
2965
2984
 
2966
2985
  // src/components/data/LineChart.tsx
2967
- var React13 = __toESM(require("react"), 1);
2986
+ var React14 = __toESM(require("react"), 1);
2968
2987
  var import_jsx_runtime50 = require("react/jsx-runtime");
2969
2988
  var PLOT_INSET = { top: 10, right: 14, bottom: 24, left: 58 };
2970
2989
  var MARKER_LIMIT = 20;
2971
- var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React13.useEffect : React13.useLayoutEffect;
2990
+ var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React14.useEffect : React14.useLayoutEffect;
2972
2991
  function useMeasuredWidth() {
2973
- const ref = React13.useRef(null);
2974
- const [width, setWidth] = React13.useState(0);
2992
+ const ref = React14.useRef(null);
2993
+ const [width, setWidth] = React14.useState(0);
2975
2994
  useIsomorphicLayoutEffect2(() => {
2976
2995
  const element = ref.current;
2977
2996
  if (!element) return;
@@ -3134,7 +3153,7 @@ function LineChart({
3134
3153
  }
3135
3154
 
3136
3155
  // src/components/data/DonutChart.tsx
3137
- var React14 = __toESM(require("react"), 1);
3156
+ var React15 = __toESM(require("react"), 1);
3138
3157
  var import_jsx_runtime51 = require("react/jsx-runtime");
3139
3158
  var SEGMENT_GAP_DEGREES = 1.5;
3140
3159
  function DonutChart({
@@ -3155,7 +3174,7 @@ function DonutChart({
3155
3174
  }) {
3156
3175
  const label = rest["aria-label"];
3157
3176
  const msg = usePireMessages();
3158
- const [hoveredIndex, setHoveredIndex] = React14.useState(null);
3177
+ const [hoveredIndex, setHoveredIndex] = React15.useState(null);
3159
3178
  warnOnDonutShape(series, categories.length, label);
3160
3179
  const values = (series[0]?.values ?? []).slice(0, categories.length);
3161
3180
  const segments = categories.map((category, index) => ({ category, index, value: values[index] ?? 0 })).filter((segment) => segment.value > 0);
@@ -3357,7 +3376,7 @@ function ConfirmDialog({
3357
3376
  }
3358
3377
 
3359
3378
  // src/components/patterns/CommandPalette.tsx
3360
- var React15 = __toESM(require("react"), 1);
3379
+ var React16 = __toESM(require("react"), 1);
3361
3380
  var import_react_aria_components31 = require("react-aria-components");
3362
3381
  var import_jsx_runtime59 = require("react/jsx-runtime");
3363
3382
  var RESULTS_SECTION_KEY = "__pire_results__";
@@ -3380,17 +3399,17 @@ function CommandPalette({
3380
3399
  style
3381
3400
  }) {
3382
3401
  const msg = usePireMessages();
3383
- const [query, setQuery] = React15.useState("");
3402
+ const [query, setQuery] = React16.useState("");
3384
3403
  const { contains } = (0, import_react_aria_components31.useFilter)({ sensitivity: "base" });
3385
- React15.useEffect(() => {
3404
+ React16.useEffect(() => {
3386
3405
  if (isOpen) setQuery("");
3387
3406
  }, [isOpen]);
3388
- const searchableById = React15.useMemo(() => {
3407
+ const searchableById = React16.useMemo(() => {
3389
3408
  const byId = /* @__PURE__ */ new Map();
3390
3409
  for (const group of groups) for (const item of group.items) byId.set(item.id, searchableText(item));
3391
3410
  return byId;
3392
3411
  }, [groups]);
3393
- const filter = React15.useCallback((textValue, inputValue, node) => {
3412
+ const filter = React16.useCallback((textValue, inputValue, node) => {
3394
3413
  if (node.parentKey === RESULTS_SECTION_KEY) return true;
3395
3414
  return contains(searchableById.get(String(node.key)) ?? textValue, inputValue);
3396
3415
  }, [contains, searchableById]);
@@ -3473,9 +3492,9 @@ function CommandPalette({
3473
3492
  );
3474
3493
  }
3475
3494
  function useCommandPaletteShortcut(onTrigger, { key = "k", isDisabled } = {}) {
3476
- const handler = React15.useRef(onTrigger);
3495
+ const handler = React16.useRef(onTrigger);
3477
3496
  handler.current = onTrigger;
3478
- React15.useEffect(() => {
3497
+ React16.useEffect(() => {
3479
3498
  if (isDisabled) return;
3480
3499
  const onKeyDown = (event) => {
3481
3500
  if (!(event.metaKey || event.ctrlKey) || event.altKey) return;
@@ -3529,7 +3548,7 @@ function EmptyState({ icon = "file-text", title, action, compact, children, clas
3529
3548
  }
3530
3549
 
3531
3550
  // src/components/patterns/FileDropZone.tsx
3532
- var React16 = __toESM(require("react"), 1);
3551
+ var React17 = __toESM(require("react"), 1);
3533
3552
  var import_react_aria_components33 = require("react-aria-components");
3534
3553
  var import_jsx_runtime62 = require("react/jsx-runtime");
3535
3554
  var isImage2 = (file) => file.type.startsWith("image/");
@@ -3557,10 +3576,10 @@ function FileDropZone({
3557
3576
  style
3558
3577
  }) {
3559
3578
  const msg = usePireMessages();
3560
- const [uncontrolled, setUncontrolled] = React16.useState(defaultValue ?? []);
3579
+ const [uncontrolled, setUncontrolled] = React17.useState(defaultValue ?? []);
3561
3580
  const files = value ?? uncontrolled;
3562
- const created = React16.useRef([]);
3563
- React16.useEffect(() => () => {
3581
+ const created = React17.useRef([]);
3582
+ React17.useEffect(() => () => {
3564
3583
  for (const url of created.current) URL.revokeObjectURL(url);
3565
3584
  }, []);
3566
3585
  const commit = (next) => {