analytica-frontend-lib 1.1.72 → 1.1.74

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.
@@ -1,5 +1,5 @@
1
1
  // src/components/Search/Search.tsx
2
- import { CaretLeft, X as X2 } from "phosphor-react";
2
+ import { X as X2, MagnifyingGlass } from "phosphor-react";
3
3
  import {
4
4
  forwardRef as forwardRef3,
5
5
  useState as useState3,
@@ -688,20 +688,19 @@ var DropdownMenu = ({
688
688
  };
689
689
  useEffect4(() => {
690
690
  if (open) {
691
- document.addEventListener("mousedown", handleClickOutside);
691
+ document.addEventListener("pointerdown", handleClickOutside);
692
692
  document.addEventListener("keydown", handleDownkey);
693
693
  }
694
694
  return () => {
695
- document.removeEventListener("mousedown", handleClickOutside);
695
+ document.removeEventListener("pointerdown", handleClickOutside);
696
696
  document.removeEventListener("keydown", handleDownkey);
697
697
  };
698
698
  }, [open]);
699
699
  useEffect4(() => {
700
- setOpen(open);
701
700
  onOpenChange?.(open);
702
701
  }, [open, onOpenChange]);
703
702
  useEffect4(() => {
704
- if (propOpen) {
703
+ if (propOpen !== void 0) {
705
704
  setOpen(propOpen);
706
705
  }
707
706
  }, [propOpen]);
@@ -828,6 +827,7 @@ var DropdownMenuItem = forwardRef2(
828
827
  onClick,
829
828
  variant = "menu",
830
829
  store: externalStore,
830
+ preventClose = false,
831
831
  ...props
832
832
  }, ref) => {
833
833
  const store = useDropdownStore(externalStore);
@@ -839,8 +839,17 @@ var DropdownMenuItem = forwardRef2(
839
839
  e.stopPropagation();
840
840
  return;
841
841
  }
842
- onClick?.(e);
843
- setOpen(false);
842
+ if (e.type === "click") {
843
+ onClick?.(e);
844
+ } else if (e.type === "keydown") {
845
+ if (e.key === "Enter" || e.key === " ") {
846
+ onClick?.(e);
847
+ }
848
+ props.onKeyDown?.(e);
849
+ }
850
+ if (!preventClose) {
851
+ setOpen(false);
852
+ }
844
853
  };
845
854
  const getVariantClasses = () => {
846
855
  if (variant === "profile") {
@@ -867,7 +876,11 @@ var DropdownMenuItem = forwardRef2(
867
876
  `,
868
877
  onClick: handleClick,
869
878
  onKeyDown: (e) => {
870
- if (e.key === "Enter" || e.key === " ") handleClick(e);
879
+ if (e.key === "Enter" || e.key === " ") {
880
+ e.preventDefault();
881
+ e.stopPropagation();
882
+ handleClick(e);
883
+ }
871
884
  },
872
885
  tabIndex: disabled ? -1 : 0,
873
886
  ...props,
@@ -933,10 +946,17 @@ var ProfileMenuHeader = forwardRef2(({ className, name, email, store: _store, ..
933
946
  );
934
947
  });
935
948
  ProfileMenuHeader.displayName = "ProfileMenuHeader";
936
- var ProfileToggleTheme = ({ ...props }) => {
949
+ var ProfileToggleTheme = ({
950
+ store: externalStore,
951
+ ...props
952
+ }) => {
937
953
  const { themeMode, setTheme } = useTheme();
938
954
  const [modalThemeToggle, setModalThemeToggle] = useState2(false);
939
955
  const [selectedTheme, setSelectedTheme] = useState2(themeMode);
956
+ const internalStoreRef = useRef(null);
957
+ internalStoreRef.current ??= createDropdownStore();
958
+ const store = externalStore ?? internalStoreRef.current;
959
+ const setOpen = useStore(store, (s) => s.setOpen);
940
960
  const handleClick = (e) => {
941
961
  e.preventDefault();
942
962
  e.stopPropagation();
@@ -945,12 +965,20 @@ var ProfileToggleTheme = ({ ...props }) => {
945
965
  const handleSave = () => {
946
966
  setTheme(selectedTheme);
947
967
  setModalThemeToggle(false);
968
+ setOpen(false);
969
+ };
970
+ const handleCancel = () => {
971
+ setSelectedTheme(themeMode);
972
+ setModalThemeToggle(false);
973
+ setOpen(false);
948
974
  };
949
975
  return /* @__PURE__ */ jsxs4(Fragment, { children: [
950
976
  /* @__PURE__ */ jsx6(
951
977
  DropdownMenuItem,
952
978
  {
953
979
  variant: "profile",
980
+ preventClose: true,
981
+ store,
954
982
  iconLeft: /* @__PURE__ */ jsx6(
955
983
  "svg",
956
984
  {
@@ -985,19 +1013,12 @@ var ProfileToggleTheme = ({ ...props }) => {
985
1013
  Modal_default,
986
1014
  {
987
1015
  isOpen: modalThemeToggle,
988
- onClose: () => setModalThemeToggle(false),
1016
+ onClose: handleCancel,
989
1017
  title: "Apar\xEAncia",
990
1018
  size: "md",
991
1019
  footer: /* @__PURE__ */ jsxs4("div", { className: "flex gap-3", children: [
992
- /* @__PURE__ */ jsx6(
993
- Button_default,
994
- {
995
- variant: "outline",
996
- onClick: () => setModalThemeToggle(false),
997
- children: "Cancelar"
998
- }
999
- ),
1000
- /* @__PURE__ */ jsx6(Button_default, { variant: "solid", onClick: () => handleSave(), children: "Salvar" })
1020
+ /* @__PURE__ */ jsx6(Button_default, { variant: "outline", onClick: handleCancel, children: "Cancelar" }),
1021
+ /* @__PURE__ */ jsx6(Button_default, { variant: "solid", onClick: handleSave, children: "Salvar" })
1001
1022
  ] }),
1002
1023
  children: /* @__PURE__ */ jsxs4("div", { className: "flex flex-col", children: [
1003
1024
  /* @__PURE__ */ jsx6("p", { className: "text-sm text-text-500", children: "Escolha o tema:" }),
@@ -1086,11 +1107,15 @@ var Search = forwardRef3(
1086
1107
  value,
1087
1108
  onChange,
1088
1109
  placeholder = "Buscar...",
1110
+ onKeyDown: userOnKeyDown,
1089
1111
  ...props
1090
1112
  }, ref) => {
1091
1113
  const [dropdownOpen, setDropdownOpen] = useState3(false);
1114
+ const [forceClose, setForceClose] = useState3(false);
1115
+ const justSelectedRef = useRef2(false);
1092
1116
  const dropdownStore = useRef2(createDropdownStore()).current;
1093
1117
  const dropdownRef = useRef2(null);
1118
+ const inputElRef = useRef2(null);
1094
1119
  const filteredOptions = useMemo(() => {
1095
1120
  if (!options.length) {
1096
1121
  return [];
@@ -1098,24 +1123,35 @@ var Search = forwardRef3(
1098
1123
  const filtered = filterOptions(options, value || "");
1099
1124
  return filtered;
1100
1125
  }, [options, value]);
1101
- const showDropdown = controlledShowDropdown ?? (dropdownOpen && value && String(value).length > 0);
1126
+ const showDropdown = !forceClose && (controlledShowDropdown ?? (dropdownOpen && value && String(value).length > 0));
1127
+ const setOpenAndNotify = (open) => {
1128
+ setDropdownOpen(open);
1129
+ dropdownStore.setState({ open });
1130
+ onDropdownChange?.(open);
1131
+ };
1102
1132
  useEffect5(() => {
1133
+ if (justSelectedRef.current) {
1134
+ justSelectedRef.current = false;
1135
+ return;
1136
+ }
1137
+ if (forceClose) {
1138
+ setOpenAndNotify(false);
1139
+ return;
1140
+ }
1103
1141
  const shouldShow = Boolean(value && String(value).length > 0);
1104
- setDropdownOpen(shouldShow);
1105
- dropdownStore.setState({ open: shouldShow });
1106
- onDropdownChange?.(shouldShow);
1107
- }, [value, onDropdownChange, dropdownStore]);
1142
+ setOpenAndNotify(shouldShow);
1143
+ }, [value, forceClose, onDropdownChange, dropdownStore]);
1108
1144
  const handleSelectOption = (option) => {
1145
+ justSelectedRef.current = true;
1146
+ setForceClose(true);
1109
1147
  onSelect?.(option);
1110
- setDropdownOpen(false);
1111
- dropdownStore.setState({ open: false });
1148
+ setOpenAndNotify(false);
1112
1149
  updateInputValue(option, ref, onChange);
1113
1150
  };
1114
1151
  useEffect5(() => {
1115
1152
  const handleClickOutside = (event) => {
1116
1153
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
1117
- setDropdownOpen(false);
1118
- dropdownStore.setState({ open: false });
1154
+ setOpenAndNotify(false);
1119
1155
  }
1120
1156
  };
1121
1157
  if (showDropdown) {
@@ -1124,9 +1160,10 @@ var Search = forwardRef3(
1124
1160
  return () => {
1125
1161
  document.removeEventListener("mousedown", handleClickOutside);
1126
1162
  };
1127
- }, [showDropdown, dropdownStore]);
1163
+ }, [showDropdown, dropdownStore, onDropdownChange]);
1128
1164
  const generatedId = useId2();
1129
1165
  const inputId = id ?? `search-${generatedId}`;
1166
+ const dropdownId = `${inputId}-dropdown`;
1130
1167
  const handleClear = () => {
1131
1168
  if (onClear) {
1132
1169
  onClear();
@@ -1139,21 +1176,40 @@ var Search = forwardRef3(
1139
1176
  e.stopPropagation();
1140
1177
  handleClear();
1141
1178
  };
1142
- const handleLeftIconClick = () => {
1143
- if (ref && "current" in ref && ref.current) {
1144
- ref.current.blur();
1145
- }
1179
+ const handleSearchIconClick = (e) => {
1180
+ e.preventDefault();
1181
+ e.stopPropagation();
1182
+ setTimeout(() => {
1183
+ inputElRef.current?.focus();
1184
+ }, 0);
1146
1185
  };
1147
1186
  const handleInputChange = (e) => {
1187
+ setForceClose(false);
1148
1188
  onChange?.(e);
1149
1189
  onSearch?.(e.target.value);
1150
1190
  };
1191
+ const handleKeyDown = (e) => {
1192
+ userOnKeyDown?.(e);
1193
+ if (e.defaultPrevented) return;
1194
+ if (e.key === "Enter") {
1195
+ e.preventDefault();
1196
+ if (showDropdown && filteredOptions.length > 0) {
1197
+ handleSelectOption(filteredOptions[0]);
1198
+ } else if (value) {
1199
+ onSearch?.(String(value));
1200
+ setForceClose(true);
1201
+ setOpenAndNotify(false);
1202
+ }
1203
+ }
1204
+ };
1151
1205
  const getInputStateClasses = (disabled2, readOnly2) => {
1152
1206
  if (disabled2) return "cursor-not-allowed opacity-40";
1153
1207
  if (readOnly2) return "cursor-default focus:outline-none !text-text-900";
1154
1208
  return "hover:border-border-400";
1155
1209
  };
1156
- const showClearButton = value && !disabled && !readOnly;
1210
+ const hasValue = String(value ?? "").length > 0;
1211
+ const showClearButton = hasValue && !disabled && !readOnly;
1212
+ const showSearchIcon = !hasValue && !disabled && !readOnly;
1157
1213
  return /* @__PURE__ */ jsxs5(
1158
1214
  "div",
1159
1215
  {
@@ -1161,30 +1217,30 @@ var Search = forwardRef3(
1161
1217
  className: `w-full max-w-lg md:w-[488px] ${containerClassName}`,
1162
1218
  children: [
1163
1219
  /* @__PURE__ */ jsxs5("div", { className: "relative flex items-center", children: [
1164
- /* @__PURE__ */ jsx7("div", { className: "absolute left-3 top-1/2 transform -translate-y-1/2", children: /* @__PURE__ */ jsx7(
1165
- "button",
1166
- {
1167
- type: "button",
1168
- className: "w-6 h-6 text-text-800 flex items-center justify-center bg-transparent border-0 p-0 cursor-pointer hover:text-text-600 transition-colors",
1169
- onClick: handleLeftIconClick,
1170
- "aria-label": "Voltar",
1171
- children: /* @__PURE__ */ jsx7(CaretLeft, {})
1172
- }
1173
- ) }),
1174
1220
  /* @__PURE__ */ jsx7(
1175
1221
  "input",
1176
1222
  {
1177
- ref,
1223
+ ref: (node) => {
1224
+ if (ref) {
1225
+ if (typeof ref === "function") ref(node);
1226
+ else
1227
+ ref.current = node;
1228
+ }
1229
+ inputElRef.current = node;
1230
+ },
1178
1231
  id: inputId,
1179
1232
  type: "text",
1180
- className: `w-full py-0 px-4 pl-10 ${showClearButton ? "pr-10" : "pr-4"} font-normal text-text-900 focus:outline-primary-950 border rounded-full bg-background focus:bg-primary-50 border-border-300 focus:border-2 focus:border-primary-950 h-10 placeholder:text-text-600 ${getInputStateClasses(disabled, readOnly)} ${className}`,
1233
+ className: `w-full py-0 px-4 pr-10 font-normal text-text-900 focus:outline-primary-950 border rounded-full bg-background focus:bg-primary-50 border-border-300 focus:border-2 focus:border-primary-950 h-10 placeholder:text-text-600 ${getInputStateClasses(disabled, readOnly)} ${className}`,
1181
1234
  value,
1182
1235
  onChange: handleInputChange,
1236
+ onKeyDown: handleKeyDown,
1183
1237
  disabled,
1184
1238
  readOnly,
1185
1239
  placeholder,
1186
1240
  "aria-expanded": showDropdown ? "true" : void 0,
1187
1241
  "aria-haspopup": options.length > 0 ? "listbox" : void 0,
1242
+ "aria-controls": showDropdown ? dropdownId : void 0,
1243
+ "aria-autocomplete": "list",
1188
1244
  role: options.length > 0 ? "combobox" : void 0,
1189
1245
  ...props
1190
1246
  }
@@ -1198,11 +1254,22 @@ var Search = forwardRef3(
1198
1254
  "aria-label": "Limpar busca",
1199
1255
  children: /* @__PURE__ */ jsx7("span", { className: "w-6 h-6 text-text-800 flex items-center justify-center hover:text-text-600 transition-colors", children: /* @__PURE__ */ jsx7(X2, {}) })
1200
1256
  }
1257
+ ) }),
1258
+ showSearchIcon && /* @__PURE__ */ jsx7("div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2", children: /* @__PURE__ */ jsx7(
1259
+ "button",
1260
+ {
1261
+ type: "button",
1262
+ className: "p-0 border-0 bg-transparent cursor-pointer",
1263
+ onMouseDown: handleSearchIconClick,
1264
+ "aria-label": "Buscar",
1265
+ children: /* @__PURE__ */ jsx7("span", { className: "w-6 h-6 text-text-800 flex items-center justify-center hover:text-text-600 transition-colors", children: /* @__PURE__ */ jsx7(MagnifyingGlass, {}) })
1266
+ }
1201
1267
  ) })
1202
1268
  ] }),
1203
1269
  showDropdown && /* @__PURE__ */ jsx7(DropdownMenu_default, { open: showDropdown, onOpenChange: setDropdownOpen, children: /* @__PURE__ */ jsx7(
1204
1270
  DropdownMenuContent,
1205
1271
  {
1272
+ id: dropdownId,
1206
1273
  className: "w-full mt-1",
1207
1274
  style: { maxHeight: dropdownMaxHeight },
1208
1275
  align: "start",