@datatechsolutions/ui 2.7.137 → 2.7.139

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.
@@ -766,7 +766,8 @@ function IconButton({
766
766
  isIosColor && finalColor === "ios-red" && "text-[#FF3B30] dark:text-[#FF453A]",
767
767
  isIosColor && finalColor === "ios-green" && "text-[#34C759] dark:text-[#30D158]",
768
768
  isIosColor && finalColor === "ios-orange" && "text-[#FF9500] dark:text-[#FF9F0A]",
769
- isIosColor && finalColor === "ios-purple" && "text-[#AF52DE] dark:text-[#BF5AF2]"
769
+ isIosColor && finalColor === "ios-purple" && "text-[#AF52DE] dark:text-[#BF5AF2]",
770
+ !isIosColor && "text-slate-700 dark:text-slate-300"
770
771
  ),
771
772
  outline: clsx__default.default(
772
773
  "bg-transparent border",
@@ -954,6 +955,7 @@ var Input = React11.forwardRef(
954
955
  const helperId = `${inputId}-helper`;
955
956
  const [isFocused, setIsFocused] = React11.useState(false);
956
957
  const [showPassword, setShowPassword] = React11.useState(false);
958
+ const prefersReducedMotion2 = framerMotion.useReducedMotion();
957
959
  const hasValue = value !== void 0 && value !== "";
958
960
  const characterCount = typeof value === "string" ? value.length : 0;
959
961
  const isOverLimit = maxCharacters ? characterCount > maxCharacters : false;
@@ -988,14 +990,14 @@ var Input = React11.forwardRef(
988
990
  liquid-surface h-12 w-full rounded-xl border-0
989
991
  px-4 py-3 text-base
990
992
  text-slate-900 dark:text-white
991
- placeholder:text-slate-400 dark:placeholder:text-slate-500
993
+ placeholder:text-slate-500 dark:placeholder:text-slate-500
992
994
  transition-all duration-200
993
995
  disabled:cursor-not-allowed disabled:opacity-50
994
996
  ` : `
995
997
  liquid-surface h-11 w-full rounded-xl
996
998
  px-3.5 py-2.5 text-base
997
999
  text-slate-900 dark:text-white
998
- placeholder:text-slate-400 dark:placeholder:text-slate-500
1000
+ placeholder:text-slate-500 dark:placeholder:text-slate-500
999
1001
  transition-all duration-200
1000
1002
  disabled:cursor-not-allowed disabled:opacity-50
1001
1003
  `;
@@ -1023,7 +1025,7 @@ var Input = React11.forwardRef(
1023
1025
  exit: { opacity: 0, scale: 0.8 },
1024
1026
  transition: { duration: 0.15 },
1025
1027
  onClick: togglePassword,
1026
- className: "p-1 rounded-full text-slate-400 hover:text-slate-600 dark:hover:text-slate-300 hover:bg-white/40 dark:hover:bg-white/[0.08] transition-colors",
1028
+ className: "p-2 min-h-[44px] min-w-[44px] flex items-center justify-center rounded-full text-slate-400 hover:text-slate-600 dark:hover:text-slate-300 hover:bg-white/40 dark:hover:bg-white/[0.08] transition-colors",
1027
1029
  "aria-label": showPassword ? t("hidePassword") : t("showPassword"),
1028
1030
  children: showPassword ? /* @__PURE__ */ jsxRuntime.jsx(solid.EyeSlashIcon, { className: "h-5 w-5" }) : /* @__PURE__ */ jsxRuntime.jsx(solid.EyeIcon, { className: "h-5 w-5" })
1029
1031
  }
@@ -1037,7 +1039,8 @@ var Input = React11.forwardRef(
1037
1039
  exit: { opacity: 0, scale: 0.8 },
1038
1040
  transition: { duration: 0.15 },
1039
1041
  onClick: handleClear,
1040
- className: "p-1 rounded-full text-slate-400 hover:text-slate-600 dark:hover:text-slate-300 hover:bg-white/40 dark:hover:bg-white/[0.08] transition-colors",
1042
+ className: "p-2 min-h-[44px] min-w-[44px] flex items-center justify-center rounded-full text-slate-400 hover:text-slate-600 dark:hover:text-slate-300 hover:bg-white/40 dark:hover:bg-white/[0.08] transition-colors",
1043
+ "aria-label": "Clear input",
1041
1044
  children: /* @__PURE__ */ jsxRuntime.jsx(solid.XMarkIcon, { className: "h-5 w-5" })
1042
1045
  }
1043
1046
  ) })
@@ -1065,7 +1068,7 @@ var Input = React11.forwardRef(
1065
1068
  children: successMessage
1066
1069
  }
1067
1070
  ),
1068
- !error && !successMessage && helperText && /* @__PURE__ */ jsxRuntime.jsx("p", { id: helperId, className: "text-sm text-slate-500 dark:text-slate-400", children: helperText })
1071
+ !error && !successMessage && helperText && /* @__PURE__ */ jsxRuntime.jsx("p", { id: helperId, className: "text-sm text-slate-600 dark:text-slate-400", children: helperText })
1069
1072
  ] }),
1070
1073
  showCharacterCount && /* @__PURE__ */ jsxRuntime.jsxs(
1071
1074
  "span",
@@ -1108,16 +1111,33 @@ var Input = React11.forwardRef(
1108
1111
  ...props
1109
1112
  }
1110
1113
  ),
1111
- /* @__PURE__ */ jsxRuntime.jsx(
1114
+ prefersReducedMotion2 ? /* @__PURE__ */ jsxRuntime.jsx(
1115
+ "label",
1116
+ {
1117
+ htmlFor: inputId,
1118
+ className: `
1119
+ absolute left-3.5 pointer-events-none
1120
+ text-slate-500 dark:text-slate-400
1121
+ transition-all duration-200
1122
+ ${icon ? "left-11" : ""}
1123
+ `,
1124
+ style: {
1125
+ top: hasValue || isFocused ? "0.5rem" : "50%",
1126
+ transform: hasValue || isFocused ? "none" : "translateY(-50%)",
1127
+ fontSize: hasValue || isFocused ? "0.75rem" : "1rem"
1128
+ },
1129
+ children: label
1130
+ }
1131
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1112
1132
  framerMotion.motion.label,
1113
1133
  {
1114
1134
  htmlFor: inputId,
1115
1135
  className: `
1116
- absolute left-3.5 pointer-events-none
1117
- text-slate-500 dark:text-slate-400
1118
- transition-all duration-200
1119
- ${icon ? "left-11" : ""}
1120
- `,
1136
+ absolute left-3.5 pointer-events-none
1137
+ text-slate-500 dark:text-slate-400
1138
+ transition-all duration-200
1139
+ ${icon ? "left-11" : ""}
1140
+ `,
1121
1141
  initial: false,
1122
1142
  animate: {
1123
1143
  top: hasValue || isFocused ? "0.5rem" : "50%",
@@ -2014,24 +2034,46 @@ function HeroSection({
2014
2034
  labelExtra,
2015
2035
  children
2016
2036
  }) {
2017
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "liquid-surface overflow-hidden rounded-2xl", children: [
2018
- gradient && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-1.5 w-full bg-gradient-to-r ${gradient}` }),
2019
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5 sm:p-8", children: [
2020
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-slate-600 dark:text-white/70", children: [
2021
- icon,
2022
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: label }),
2023
- labelExtra
2024
- ] }),
2025
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex flex-wrap items-center justify-between gap-4", children: [
2026
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold tracking-tight text-slate-900 dark:text-white sm:text-4xl", children: title }),
2027
- actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: actions })
2028
- ] }),
2029
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 max-w-xl text-sm text-slate-500 dark:text-white/60 sm:mt-3 sm:text-lg", children: subtitle }),
2030
- toolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: toolbar }),
2031
- badges && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-6 flex flex-wrap items-center gap-4", children: badges }),
2032
- children
2033
- ] })
2034
- ] });
2037
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2038
+ "div",
2039
+ {
2040
+ role: "banner",
2041
+ "data-testid": "hero-section",
2042
+ className: "liquid-surface overflow-hidden rounded-2xl",
2043
+ children: [
2044
+ gradient && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-1.5 w-full bg-gradient-to-r ${gradient}` }),
2045
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5 sm:p-8", children: [
2046
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-slate-600 dark:text-white/70", children: [
2047
+ icon,
2048
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: label }),
2049
+ labelExtra
2050
+ ] }),
2051
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex flex-wrap items-center justify-between gap-4", children: [
2052
+ /* @__PURE__ */ jsxRuntime.jsx(
2053
+ "h1",
2054
+ {
2055
+ "data-testid": "hero-title",
2056
+ className: "text-2xl font-bold tracking-tight text-slate-900 dark:text-white sm:text-4xl",
2057
+ children: title
2058
+ }
2059
+ ),
2060
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: actions })
2061
+ ] }),
2062
+ /* @__PURE__ */ jsxRuntime.jsx(
2063
+ "p",
2064
+ {
2065
+ "data-testid": "hero-subtitle",
2066
+ className: "mt-2 max-w-xl text-sm text-slate-500 dark:text-white/60 sm:mt-3 sm:text-lg",
2067
+ children: subtitle
2068
+ }
2069
+ ),
2070
+ toolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "hero-toolbar", className: "mt-4", children: toolbar }),
2071
+ badges && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-6 flex flex-wrap items-center gap-4", children: badges }),
2072
+ children
2073
+ ] })
2074
+ ]
2075
+ }
2076
+ );
2035
2077
  }
2036
2078
  var DEFAULT_STYLE_CONFIG = {
2037
2079
  default: {
@@ -2304,6 +2346,9 @@ function StatCard({
2304
2346
  return /* @__PURE__ */ jsxRuntime.jsxs(
2305
2347
  "div",
2306
2348
  {
2349
+ role: "status",
2350
+ "aria-label": label,
2351
+ "data-testid": label ? `stat-card-${label.toLowerCase().replace(/\s+/g, "-")}` : "stat-card",
2307
2352
  onClick,
2308
2353
  className: `group relative overflow-hidden rounded-xl p-5 transition-all duration-200 ${isClickable ? "cursor-pointer" : ""} ${isActive ? `bg-gradient-to-br ${colorConfig.activeGradient} ring-2 ring-offset-2 ${colorConfig.activeRing} shadow-xl` : `liquid-surface hover:shadow-md ${isFiltered ? "ring-indigo-300 dark:ring-indigo-500/50" : isUrgent ? "ring-amber-300 dark:ring-amber-500/50" : ""}`} ${className}`,
2309
2354
  children: [
@@ -2335,6 +2380,7 @@ function StatCard({
2335
2380
  /* @__PURE__ */ jsxRuntime.jsx(
2336
2381
  "p",
2337
2382
  {
2383
+ "data-testid": "stat-card-value",
2338
2384
  className: `mt-4 text-3xl font-bold ${isActive ? "text-white" : isUrgent ? colorConfig.urgentValueColor || colorConfig.valueColor : colorConfig.valueColor}`,
2339
2385
  children: value
2340
2386
  }
@@ -2342,6 +2388,7 @@ function StatCard({
2342
2388
  /* @__PURE__ */ jsxRuntime.jsx(
2343
2389
  "p",
2344
2390
  {
2391
+ "data-testid": "stat-card-label",
2345
2392
  className: `mt-1 text-sm ${isActive ? "text-white/75" : "text-slate-500 dark:text-slate-400"}`,
2346
2393
  children: label
2347
2394
  }
@@ -2645,7 +2692,7 @@ function CircleSpinner({ size, color, className, ariaLabel }) {
2645
2692
  "div",
2646
2693
  {
2647
2694
  className: clsx.clsx(
2648
- "rounded-full animate-spin",
2695
+ "rounded-full animate-spin motion-reduce:animate-none",
2649
2696
  config.size,
2650
2697
  config.border,
2651
2698
  colors3.track,
@@ -2660,9 +2707,10 @@ function CircleSpinner({ size, color, className, ariaLabel }) {
2660
2707
  function DotsSpinner({ size, color, className, ariaLabel }) {
2661
2708
  const config = sizeConfig[size];
2662
2709
  const colors3 = colorClasses2[color];
2710
+ const prefersReducedMotion2 = framerMotion.useReducedMotion();
2663
2711
  const dotVariants = {
2664
2712
  initial: { scale: 0.8, opacity: 0.4 },
2665
- animate: { scale: 1, opacity: 1 }
2713
+ animate: prefersReducedMotion2 ? { scale: 1, opacity: 1 } : { scale: 1, opacity: 1 }
2666
2714
  };
2667
2715
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("flex items-center gap-1", className), role: "status", "aria-label": ariaLabel, children: [0, 1, 2].map((index) => /* @__PURE__ */ jsxRuntime.jsx(
2668
2716
  framerMotion.motion.div,
@@ -2675,7 +2723,7 @@ function DotsSpinner({ size, color, className, ariaLabel }) {
2675
2723
  variants: dotVariants,
2676
2724
  initial: "initial",
2677
2725
  animate: "animate",
2678
- transition: {
2726
+ transition: prefersReducedMotion2 ? { duration: 0 } : {
2679
2727
  duration: 0.5,
2680
2728
  repeat: Infinity,
2681
2729
  repeatType: "reverse",
@@ -2688,16 +2736,17 @@ function DotsSpinner({ size, color, className, ariaLabel }) {
2688
2736
  function PulseSpinner({ size, color, className, ariaLabel }) {
2689
2737
  const config = sizeConfig[size];
2690
2738
  const colors3 = colorClasses2[color];
2739
+ const prefersReducedMotion2 = framerMotion.useReducedMotion();
2691
2740
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx.clsx("relative", config.size, className), role: "status", "aria-label": ariaLabel, children: [
2692
2741
  /* @__PURE__ */ jsxRuntime.jsx(
2693
2742
  framerMotion.motion.div,
2694
2743
  {
2695
2744
  className: clsx.clsx("absolute inset-0 rounded-full", colors3.dot),
2696
- animate: {
2745
+ animate: prefersReducedMotion2 ? {} : {
2697
2746
  scale: [1, 1.5, 1],
2698
2747
  opacity: [0.7, 0, 0.7]
2699
2748
  },
2700
- transition: {
2749
+ transition: prefersReducedMotion2 ? { duration: 0 } : {
2701
2750
  duration: 1.5,
2702
2751
  repeat: Infinity,
2703
2752
  ease: "easeInOut"
@@ -2732,7 +2781,8 @@ function Spinner({
2732
2781
  {
2733
2782
  size,
2734
2783
  color,
2735
- className
2784
+ className,
2785
+ ariaLabel
2736
2786
  }
2737
2787
  );
2738
2788
  }
@@ -3037,10 +3087,42 @@ function SegmentedControl({
3037
3087
  chunkUZ3CMNUJ_js.triggerHaptic("light");
3038
3088
  onChange(segmentValue);
3039
3089
  };
3090
+ const handleKeyDown = React11.useCallback(
3091
+ (event) => {
3092
+ if (disabled) return;
3093
+ const currentIndex = normalizedSegments.findIndex((seg) => seg.value === value);
3094
+ let nextIndex = -1;
3095
+ if (event.key === "ArrowRight" || event.key === "ArrowDown") {
3096
+ event.preventDefault();
3097
+ nextIndex = (currentIndex + 1) % normalizedSegments.length;
3098
+ } else if (event.key === "ArrowLeft" || event.key === "ArrowUp") {
3099
+ event.preventDefault();
3100
+ nextIndex = (currentIndex - 1 + normalizedSegments.length) % normalizedSegments.length;
3101
+ } else if (event.key === "Home") {
3102
+ event.preventDefault();
3103
+ nextIndex = 0;
3104
+ } else if (event.key === "End") {
3105
+ event.preventDefault();
3106
+ nextIndex = normalizedSegments.length - 1;
3107
+ }
3108
+ if (nextIndex >= 0) {
3109
+ const nextSegment = normalizedSegments[nextIndex];
3110
+ onChange(nextSegment.value);
3111
+ chunkUZ3CMNUJ_js.triggerHaptic("light");
3112
+ const buttons = containerRef.current?.querySelectorAll("button");
3113
+ buttons?.[nextIndex]?.focus();
3114
+ }
3115
+ },
3116
+ [disabled, normalizedSegments, value, onChange]
3117
+ );
3040
3118
  return /* @__PURE__ */ jsxRuntime.jsxs(
3041
3119
  "div",
3042
3120
  {
3043
3121
  ref: containerRef,
3122
+ role: "tablist",
3123
+ "aria-live": "polite",
3124
+ "data-testid": "segmented-control",
3125
+ onKeyDown: handleKeyDown,
3044
3126
  className: `
3045
3127
  relative inline-flex items-center rounded-xl
3046
3128
  bg-white/40 dark:bg-white/[0.08]
@@ -3067,6 +3149,11 @@ function SegmentedControl({
3067
3149
  "button",
3068
3150
  {
3069
3151
  type: "button",
3152
+ role: "tab",
3153
+ "aria-selected": isSelected,
3154
+ "aria-label": segment.label,
3155
+ tabIndex: isSelected ? 0 : -1,
3156
+ "data-testid": `tab-${segment.value}`,
3070
3157
  onClick: () => handleSelect(segment.value),
3071
3158
  className: `
3072
3159
  relative z-10 flex items-center justify-center gap-1.5
@@ -5413,11 +5500,14 @@ function GlassModal({
5413
5500
  children,
5414
5501
  panelClassName = "rounded-[2rem]",
5415
5502
  contentClassName = "fixed inset-0 flex items-center justify-center overflow-y-auto p-3 sm:p-5 lg:p-6",
5416
- zIndex = "z-50"
5417
- }) {
5418
- return /* @__PURE__ */ jsxRuntime.jsxs(Headless6.Dialog, { open, onClose, className: `relative ${zIndex}`, children: [
5419
- /* @__PURE__ */ jsxRuntime.jsx(Headless6.DialogBackdrop, { className: "fixed inset-0 bg-slate-900/40 backdrop-blur-md dark:bg-black/50" }),
5420
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: contentClassName, children: /* @__PURE__ */ jsxRuntime.jsx(Headless6.DialogPanel, { className: panelClassName, children }) })
5503
+ zIndex = "z-50",
5504
+ overlayTestId,
5505
+ panelTestId,
5506
+ ariaLabelledBy
5507
+ }) {
5508
+ return /* @__PURE__ */ jsxRuntime.jsxs(Headless6.Dialog, { open, onClose, className: `relative ${zIndex}`, "aria-labelledby": ariaLabelledBy, children: [
5509
+ /* @__PURE__ */ jsxRuntime.jsx(Headless6.DialogBackdrop, { className: "fixed inset-0 bg-slate-900/40 backdrop-blur-md dark:bg-black/50", "data-testid": overlayTestId }),
5510
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: contentClassName, children: /* @__PURE__ */ jsxRuntime.jsx(Headless6.DialogPanel, { className: panelClassName, "data-testid": panelTestId, children }) })
5421
5511
  ] });
5422
5512
  }
5423
5513
  function Text({ className, ...props }) {
@@ -5920,7 +6010,8 @@ function GlassModalShell({
5920
6010
  type: "button",
5921
6011
  onClick: onClose,
5922
6012
  "aria-label": closeLabel,
5923
- className: "absolute right-4 top-4 inline-flex h-9 w-9 items-center justify-center rounded-xl text-slate-400 transition hover:bg-white/40 hover:text-slate-700 dark:hover:bg-white/[0.08] dark:hover:text-white",
6013
+ "data-testid": "modal-close",
6014
+ className: "absolute right-4 top-4 inline-flex h-9 w-9 items-center justify-center rounded-xl text-slate-400 transition hover:bg-white/40 hover:text-slate-700 dark:hover:bg-white/[0.08] dark:hover:text-white focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2",
5924
6015
  children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.XMarkIcon, { className: "h-5 w-5" })
5925
6016
  }
5926
6017
  ),
@@ -5930,14 +6021,14 @@ function GlassModalShell({
5930
6021
  ] }),
5931
6022
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3 pr-10", children: [
5932
6023
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5933
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-slate-900 dark:text-white sm:text-2xl", children: title }),
6024
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { id: "modal-title", "data-testid": "modal-title", className: "text-xl font-bold text-slate-900 dark:text-white sm:text-2xl", children: title }),
5934
6025
  subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-slate-500 dark:text-slate-400", children: subtitle })
5935
6026
  ] }),
5936
6027
  headerActions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: headerActions })
5937
6028
  ] })
5938
6029
  ] }),
5939
6030
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-[72vh] overflow-y-auto px-5 pb-5 sm:px-8 sm:pb-8", children }),
5940
- footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-white/20 px-5 py-4 dark:border-white/10 sm:px-8", children: footer })
6031
+ footer && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "modal-footer", className: "border-t border-white/20 px-5 py-4 dark:border-white/10 sm:px-8", children: footer })
5941
6032
  ] });
5942
6033
  return /* @__PURE__ */ jsxRuntime.jsx(
5943
6034
  GlassModal,
@@ -5946,7 +6037,10 @@ function GlassModalShell({
5946
6037
  onClose,
5947
6038
  contentClassName: "fixed inset-0 overflow-y-auto p-3 sm:p-6",
5948
6039
  panelClassName: `liquid-surface-strong w-full overflow-hidden rounded-2xl mx-auto mt-[4vh] sm:mt-[8vh] ${SIZE_CLASSES2[maxWidth]} ${className}`,
6040
+ ariaLabelledBy: "modal-title",
5949
6041
  zIndex,
6042
+ overlayTestId: "modal-overlay",
6043
+ panelTestId: "modal-panel",
5950
6044
  children: onSubmit ? /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit: handleSubmit, children: inner }) : inner
5951
6045
  }
5952
6046
  );
@@ -5977,6 +6071,7 @@ function GlassFormModal({
5977
6071
  disabled: isLoading,
5978
6072
  outline: true,
5979
6073
  className: "w-full sm:w-auto",
6074
+ "data-testid": "form-modal-cancel",
5980
6075
  children: cancelLabel
5981
6076
  }
5982
6077
  ),
@@ -5989,11 +6084,12 @@ function GlassFormModal({
5989
6084
  loadingText: submitLabel,
5990
6085
  color: "ios-glass-blue",
5991
6086
  className: "w-full sm:w-auto",
6087
+ "data-testid": "form-modal-submit",
5992
6088
  children: submitLabel
5993
6089
  }
5994
6090
  )
5995
6091
  ] }) }) : void 0;
5996
- return /* @__PURE__ */ jsxRuntime.jsx(
6092
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "form-modal", role: "dialog", "aria-modal": "true", "aria-label": title, children: /* @__PURE__ */ jsxRuntime.jsx(
5997
6093
  GlassModalShell,
5998
6094
  {
5999
6095
  open,
@@ -6007,7 +6103,7 @@ function GlassFormModal({
6007
6103
  footer: defaultFooter,
6008
6104
  children
6009
6105
  }
6010
- );
6106
+ ) });
6011
6107
  }
6012
6108
  function ContextMenu({
6013
6109
  position,
@@ -6670,13 +6766,13 @@ function FormInput({
6670
6766
  onValueChange,
6671
6767
  ...props
6672
6768
  }) {
6673
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6769
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": label ? `field-${label.toLowerCase().replace(/\s+/g, "-")}` : "form-field", children: [
6674
6770
  label ? /* @__PURE__ */ jsxRuntime.jsxs("label", { className: `mb-1.5 block font-medium text-gray-500 dark:text-gray-400 ${labelClasses[inputSize]}`, children: [
6675
6771
  label,
6676
6772
  required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-0.5 text-red-500", children: "*" }) : null
6677
6773
  ] }) : null,
6678
6774
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapperClass(error), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative flex items-center ${sizeClasses3[inputSize]} ${className}`, children: [
6679
- icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-2 text-gray-400 dark:text-gray-500", children: icon }) : null,
6775
+ icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-2 text-gray-400 dark:text-gray-500", "aria-hidden": "true", children: icon }) : null,
6680
6776
  /* @__PURE__ */ jsxRuntime.jsx(
6681
6777
  "input",
6682
6778
  {
@@ -6699,7 +6795,7 @@ function FormTextarea({
6699
6795
  onValueChange,
6700
6796
  ...props
6701
6797
  }) {
6702
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6798
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": label ? `field-${label.toLowerCase().replace(/\s+/g, "-")}` : "form-field", children: [
6703
6799
  label ? /* @__PURE__ */ jsxRuntime.jsxs("label", { className: `mb-1.5 block font-medium text-gray-500 dark:text-gray-400 ${labelClasses[inputSize]}`, children: [
6704
6800
  label,
6705
6801
  required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-0.5 text-red-500", children: "*" }) : null
@@ -6745,7 +6841,7 @@ function FormPriceInput({
6745
6841
  className = ""
6746
6842
  }) {
6747
6843
  const sizes3 = priceSizeConfig[priceSize ?? defaultPriceSize(inputSize)];
6748
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6844
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": label ? `field-${label.toLowerCase().replace(/\s+/g, "-")}` : "form-field", children: [
6749
6845
  label ? /* @__PURE__ */ jsxRuntime.jsxs("label", { className: `mb-1.5 block font-medium text-gray-500 dark:text-gray-400 ${labelClasses[inputSize]}`, children: [
6750
6846
  label,
6751
6847
  required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-0.5 text-red-500", children: "*" }) : null
@@ -6788,7 +6884,7 @@ function FormSelect({
6788
6884
  options,
6789
6885
  ...props
6790
6886
  }) {
6791
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6887
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": label ? `field-${label.toLowerCase().replace(/\s+/g, "-")}` : "form-field", children: [
6792
6888
  label ? /* @__PURE__ */ jsxRuntime.jsxs("label", { className: `mb-1.5 block font-medium text-gray-500 dark:text-gray-400 ${labelClasses[inputSize]}`, children: [
6793
6889
  label,
6794
6890
  required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-0.5 text-red-500", children: "*" }) : null
@@ -7336,7 +7432,7 @@ function SearchFilterToolbar({
7336
7432
  label
7337
7433
  };
7338
7434
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7339
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
7435
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "search", "data-testid": "search-toolbar", className: "flex items-center gap-3", children: [
7340
7436
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "liquid-surface flex flex-1 items-center gap-2 flex-wrap min-h-12 rounded-xl px-3.5 py-1.5 transition-colors duration-200 focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-blue-500 dark:focus-within:ring-offset-gray-900", children: [
7341
7437
  /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.MagnifyingGlassIcon, { className: "h-5 w-5 shrink-0 text-slate-400 dark:text-slate-500" }),
7342
7438
  filterPills,
@@ -7347,6 +7443,8 @@ function SearchFilterToolbar({
7347
7443
  value: query,
7348
7444
  onChange: (event) => onQueryChange(event.target.value),
7349
7445
  placeholder,
7446
+ "aria-label": label,
7447
+ "data-testid": "search-input",
7350
7448
  className: "min-w-[100px] flex-1 bg-transparent py-1 text-base text-gray-900 outline-none placeholder:text-slate-400 dark:text-white dark:placeholder:text-slate-500"
7351
7449
  }
7352
7450
  )
@@ -7435,6 +7533,12 @@ function SearchFilterToolbar({
7435
7533
  function isPlainTextTitle(title) {
7436
7534
  return typeof title === "string" || typeof title === "number";
7437
7535
  }
7536
+ function getTestIdFromTitle(title) {
7537
+ if (isPlainTextTitle(title)) {
7538
+ return `entity-card-${String(title).toLowerCase().replace(/\s+/g, "-")}`;
7539
+ }
7540
+ return "entity-card";
7541
+ }
7438
7542
  function StatusBadgeInternal({ status }) {
7439
7543
  const tCommon = nextIntl.useTranslations("common");
7440
7544
  if (typeof status !== "boolean") {
@@ -7461,9 +7565,24 @@ function EntityCard({
7461
7565
  dragProps
7462
7566
  }) {
7463
7567
  const isInteractive = Boolean(onClick);
7568
+ const plainTextTitle = isPlainTextTitle(title) ? String(title) : void 0;
7569
+ const handleKeyDown = React11.useCallback(
7570
+ (event) => {
7571
+ if (onClick && (event.key === "Enter" || event.key === " ")) {
7572
+ event.preventDefault();
7573
+ onClick();
7574
+ }
7575
+ },
7576
+ [onClick]
7577
+ );
7464
7578
  return /* @__PURE__ */ jsxRuntime.jsxs(
7465
7579
  Card,
7466
7580
  {
7581
+ role: isInteractive ? "article" : "listitem",
7582
+ "aria-label": isInteractive ? plainTextTitle : void 0,
7583
+ "data-testid": getTestIdFromTitle(title),
7584
+ tabIndex: isInteractive ? 0 : void 0,
7585
+ onKeyDown: isInteractive ? handleKeyDown : void 0,
7467
7586
  className: `group overflow-hidden transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md ${isInteractive ? "cursor-pointer" : ""} ${className}`,
7468
7587
  onPress: onClick,
7469
7588
  pressable: isInteractive,
@@ -7472,21 +7591,21 @@ function EntityCard({
7472
7591
  accentGradient && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-1.5 w-full bg-gradient-to-r ${accentGradient}` }),
7473
7592
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
7474
7593
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
7475
- /* @__PURE__ */ jsxRuntime.jsx(
7594
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "entity-card-title", children: /* @__PURE__ */ jsxRuntime.jsx(
7476
7595
  ItemSummary,
7477
7596
  {
7478
7597
  icon,
7479
7598
  title,
7480
- subtitle,
7599
+ subtitle: subtitle ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-testid": "entity-card-subtitle", children: subtitle }) : void 0,
7481
7600
  iconContainerClassName: "shrink-0",
7482
7601
  titleClassName: isPlainTextTitle(title) ? "truncate font-semibold text-slate-900 dark:text-white" : "font-semibold text-slate-900 dark:text-white",
7483
7602
  subtitleClassName: "mt-0.5 text-xs text-slate-500 dark:text-slate-400"
7484
7603
  }
7485
- ),
7604
+ ) }),
7486
7605
  status !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(StatusBadgeInternal, { status })
7487
7606
  ] }),
7488
7607
  children && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3", children }),
7489
- footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 border-t border-white/30 pt-3 dark:border-white/10 flex gap-2 justify-end opacity-0 transition-opacity duration-200 group-hover:opacity-100", children: footer })
7608
+ footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 border-t border-white/30 pt-3 dark:border-white/10 flex gap-2 justify-end opacity-0 transition-opacity duration-200 group-hover:opacity-100 group-focus-within:opacity-100", children: footer })
7490
7609
  ] })
7491
7610
  ]
7492
7611
  }
@@ -7635,6 +7754,10 @@ function FilterTileButton({
7635
7754
  {
7636
7755
  type: "button",
7637
7756
  onClick,
7757
+ role: "checkbox",
7758
+ "aria-checked": isActive,
7759
+ "aria-label": label,
7760
+ "data-testid": `filter-tile-${label.toLowerCase().replace(/\s+/g, "-")}`,
7638
7761
  className: `relative overflow-hidden rounded-2xl p-4 text-left transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 ${tokens.focusRing} dark:ring-offset-gray-900 ${isActive ? tokens.activeGradient : INACTIVE_CLASSES}`,
7639
7762
  children: [
7640
7763
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -8669,6 +8792,7 @@ function Badge({ color = "zinc", className, ...props }) {
8669
8792
  return /* @__PURE__ */ jsxRuntime.jsx(
8670
8793
  "span",
8671
8794
  {
8795
+ "data-testid": "badge",
8672
8796
  ...props,
8673
8797
  className: clsx__default.default(
8674
8798
  className,
@@ -8883,14 +9007,14 @@ function DynamicIslandConfirm({
8883
9007
  chunkUZ3CMNUJ_js.triggerHaptic("warning");
8884
9008
  }
8885
9009
  }, [open]);
8886
- return /* @__PURE__ */ jsxRuntime.jsxs(Headless6.Dialog, { open, onClose, className: "relative z-[120]", children: [
9010
+ return /* @__PURE__ */ jsxRuntime.jsxs(Headless6.Dialog, { open, onClose, className: "relative z-[120]", "aria-labelledby": "dynamic-island-title", children: [
8887
9011
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 bg-black/10 backdrop-blur-[2px]" }),
8888
9012
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 flex items-start justify-center pt-3 px-4", children: /* @__PURE__ */ jsxRuntime.jsxs(Headless6.DialogPanel, { className: "w-full max-w-sm rounded-[28px] bg-black/95 p-3 text-white shadow-2xl", children: [
8889
9013
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 px-2 py-1", children: [
8890
9014
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-9 w-9 shrink-0 rounded-xl ${iconBackground} flex items-center justify-center`, children: icon ?? /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.TrashIcon, { className: "h-5 w-5 text-white" }) }),
8891
9015
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
8892
9016
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] uppercase tracking-wide text-gray-400", children: appName }),
8893
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold", children: title })
9017
+ /* @__PURE__ */ jsxRuntime.jsx("p", { id: "dynamic-island-title", className: "text-sm font-semibold", children: title })
8894
9018
  ] })
8895
9019
  ] }),
8896
9020
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 grid grid-cols-2 gap-2", children: [
@@ -8899,7 +9023,7 @@ function DynamicIslandConfirm({
8899
9023
  {
8900
9024
  type: "button",
8901
9025
  onClick: onClose,
8902
- className: "rounded-xl bg-white/10 px-3 py-2 text-sm font-medium hover:bg-white/15",
9026
+ className: "rounded-xl bg-white/10 px-3 py-3 text-sm font-medium hover:bg-white/15 focus-visible:ring-2 focus-visible:ring-white/70",
8903
9027
  children: resolvedCancelLabel
8904
9028
  }
8905
9029
  ),
@@ -8908,7 +9032,7 @@ function DynamicIslandConfirm({
8908
9032
  {
8909
9033
  type: "button",
8910
9034
  onClick: onConfirm,
8911
- className: "rounded-xl bg-ios-red px-3 py-2 text-sm font-semibold text-white hover:bg-ios-red-hover",
9035
+ className: "rounded-xl bg-ios-red px-3 py-3 text-sm font-semibold text-white hover:bg-ios-red-hover focus-visible:ring-2 focus-visible:ring-white/70",
8912
9036
  children: resolvedConfirmLabel
8913
9037
  }
8914
9038
  )
@@ -9460,66 +9584,80 @@ var ACCENT_MAP = {
9460
9584
  function PageEmptyState({ title, message, iconName }) {
9461
9585
  const Icon = ICON_MAP[iconName] || FallbackIcon;
9462
9586
  const accent = ACCENT_MAP[iconName] || ACCENT_MAP["folder-open"];
9463
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsxRuntime.jsxs(
9464
- framerMotion.motion.div,
9587
+ const prefersReducedMotion2 = framerMotion.useReducedMotion();
9588
+ const noMotion = { opacity: 1, scale: 1, y: 0 };
9589
+ const noTransition = { duration: 0 };
9590
+ return /* @__PURE__ */ jsxRuntime.jsx(
9591
+ "div",
9465
9592
  {
9466
- initial: { opacity: 0, scale: 0.95 },
9467
- animate: { opacity: 1, scale: 1 },
9468
- transition: springPresets.gentle,
9469
- className: "liquid-surface w-full max-w-lg rounded-2xl px-8 py-14 text-center",
9470
- children: [
9471
- /* @__PURE__ */ jsxRuntime.jsx(
9472
- framerMotion.motion.div,
9473
- {
9474
- initial: { scale: 0.6, opacity: 0 },
9475
- animate: { scale: 1, opacity: 1 },
9476
- transition: springPresets.bouncy,
9477
- className: "mx-auto mb-6",
9478
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `inline-flex h-20 w-20 items-center justify-center rounded-full backdrop-blur-md border ${accent.container}`, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: `h-10 w-10 ${accent.icon}` }) })
9479
- }
9480
- ),
9481
- /* @__PURE__ */ jsxRuntime.jsx(
9482
- framerMotion.motion.h3,
9483
- {
9484
- initial: { y: 12, opacity: 0 },
9485
- animate: { y: 0, opacity: 1 },
9486
- transition: { ...springPresets.default, delay: 0.1 },
9487
- className: "text-xl font-semibold text-gray-900 dark:text-white",
9488
- children: title
9489
- }
9490
- ),
9491
- /* @__PURE__ */ jsxRuntime.jsx(
9492
- framerMotion.motion.p,
9493
- {
9494
- initial: { y: 12, opacity: 0 },
9495
- animate: { y: 0, opacity: 1 },
9496
- transition: { ...springPresets.default, delay: 0.15 },
9497
- className: "mt-3 text-sm text-gray-500 dark:text-gray-400 max-w-sm mx-auto leading-relaxed",
9498
- children: message
9499
- }
9500
- ),
9501
- /* @__PURE__ */ jsxRuntime.jsx(
9502
- framerMotion.motion.div,
9503
- {
9504
- initial: { opacity: 0 },
9505
- animate: { opacity: 1 },
9506
- transition: { delay: 0.3 },
9507
- className: "mt-8 flex items-center justify-center gap-1.5",
9508
- children: [0, 1, 2].map((i) => /* @__PURE__ */ jsxRuntime.jsx(
9593
+ role: "region",
9594
+ "aria-label": title,
9595
+ "data-testid": "empty-state",
9596
+ className: "flex items-center justify-center py-20",
9597
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
9598
+ framerMotion.motion.div,
9599
+ {
9600
+ initial: prefersReducedMotion2 ? false : { opacity: 0, scale: 0.95 },
9601
+ animate: prefersReducedMotion2 ? noMotion : { opacity: 1, scale: 1 },
9602
+ transition: prefersReducedMotion2 ? noTransition : springPresets.gentle,
9603
+ className: "liquid-surface w-full max-w-lg rounded-2xl px-8 py-14 text-center",
9604
+ children: [
9605
+ /* @__PURE__ */ jsxRuntime.jsx(
9509
9606
  framerMotion.motion.div,
9510
9607
  {
9511
- initial: { scale: 0 },
9512
- animate: { scale: 1 },
9513
- transition: { ...springPresets.bouncy, delay: 0.35 + i * 0.08 },
9514
- className: "h-1.5 w-1.5 rounded-full bg-gray-300 dark:bg-gray-600"
9515
- },
9516
- i
9517
- ))
9518
- }
9519
- )
9520
- ]
9608
+ initial: prefersReducedMotion2 ? false : { scale: 0.6, opacity: 0 },
9609
+ animate: prefersReducedMotion2 ? noMotion : { scale: 1, opacity: 1 },
9610
+ transition: prefersReducedMotion2 ? noTransition : springPresets.bouncy,
9611
+ className: "mx-auto mb-6",
9612
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `inline-flex h-20 w-20 items-center justify-center rounded-full backdrop-blur-md border ${accent.container}`, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: `h-10 w-10 ${accent.icon}` }) })
9613
+ }
9614
+ ),
9615
+ /* @__PURE__ */ jsxRuntime.jsx(
9616
+ framerMotion.motion.h3,
9617
+ {
9618
+ "data-testid": "empty-state-title",
9619
+ initial: prefersReducedMotion2 ? false : { y: 12, opacity: 0 },
9620
+ animate: prefersReducedMotion2 ? noMotion : { y: 0, opacity: 1 },
9621
+ transition: prefersReducedMotion2 ? noTransition : { ...springPresets.default, delay: 0.1 },
9622
+ className: "text-xl font-semibold text-gray-900 dark:text-white",
9623
+ children: title
9624
+ }
9625
+ ),
9626
+ /* @__PURE__ */ jsxRuntime.jsx(
9627
+ framerMotion.motion.p,
9628
+ {
9629
+ "data-testid": "empty-state-message",
9630
+ initial: prefersReducedMotion2 ? false : { y: 12, opacity: 0 },
9631
+ animate: prefersReducedMotion2 ? noMotion : { y: 0, opacity: 1 },
9632
+ transition: prefersReducedMotion2 ? noTransition : { ...springPresets.default, delay: 0.15 },
9633
+ className: "mt-3 text-sm text-gray-500 dark:text-gray-400 max-w-sm mx-auto leading-relaxed",
9634
+ children: message
9635
+ }
9636
+ ),
9637
+ /* @__PURE__ */ jsxRuntime.jsx(
9638
+ framerMotion.motion.div,
9639
+ {
9640
+ initial: prefersReducedMotion2 ? false : { opacity: 0 },
9641
+ animate: prefersReducedMotion2 ? noMotion : { opacity: 1 },
9642
+ transition: prefersReducedMotion2 ? noTransition : { delay: 0.3 },
9643
+ className: "mt-8 flex items-center justify-center gap-1.5",
9644
+ children: [0, 1, 2].map((i) => /* @__PURE__ */ jsxRuntime.jsx(
9645
+ framerMotion.motion.div,
9646
+ {
9647
+ initial: prefersReducedMotion2 ? false : { scale: 0 },
9648
+ animate: prefersReducedMotion2 ? noMotion : { scale: 1 },
9649
+ transition: prefersReducedMotion2 ? noTransition : { ...springPresets.bouncy, delay: 0.35 + i * 0.08 },
9650
+ className: "h-1.5 w-1.5 rounded-full bg-gray-300 dark:bg-gray-600"
9651
+ },
9652
+ i
9653
+ ))
9654
+ }
9655
+ )
9656
+ ]
9657
+ }
9658
+ )
9521
9659
  }
9522
- ) });
9660
+ );
9523
9661
  }
9524
9662
  var WINDSOCK_LOADER = { gradient: "from-emerald-500 to-teal-600", accentRing: "ring-emerald-500/30" };
9525
9663
  var FUEL_PRICE_LOADER = { gradient: "from-blue-500 to-indigo-600", accentRing: "ring-blue-500/30" };
@@ -11159,7 +11297,7 @@ function NotificationBadge({ count, className = "" }) {
11159
11297
  return /* @__PURE__ */ jsxRuntime.jsx(
11160
11298
  "span",
11161
11299
  {
11162
- className: `absolute -top-1 -right-1 flex items-center justify-center min-w-[18px] h-[18px] px-1 text-[10px] font-bold text-white bg-red-500 rounded-full ring-2 ring-white dark:ring-gray-800 ${count > 0 ? "animate-pulse" : ""} ${className}`,
11300
+ className: `absolute -top-1 -right-1 flex items-center justify-center min-w-[18px] h-[18px] px-1 text-[10px] font-bold text-white bg-red-500 rounded-full ring-2 ring-white dark:ring-gray-800 ${count > 0 ? "animate-pulse motion-reduce:animate-none" : ""} ${className}`,
11163
11301
  children: displayCount
11164
11302
  }
11165
11303
  );
@@ -12389,11 +12527,15 @@ function FilterPill({ icon, label, variant, onRemove }) {
12389
12527
  {
12390
12528
  type: "button",
12391
12529
  onClick: onRemove,
12530
+ role: "option",
12531
+ "aria-selected": true,
12532
+ "aria-label": typeof label === "string" ? label : void 0,
12533
+ "data-testid": "filter-pill",
12392
12534
  className: `liquid-pill liquid-pill-${variant}`,
12393
12535
  children: [
12394
12536
  icon,
12395
12537
  label,
12396
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.XMarkIcon, { className: "liquid-pill-dismiss" })
12538
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.XMarkIcon, { className: "liquid-pill-dismiss", "data-testid": "filter-pill-remove" })
12397
12539
  ]
12398
12540
  }
12399
12541
  );
@@ -14216,5 +14358,5 @@ exports.useGeoMapState = useGeoMapState;
14216
14358
  exports.useNotifications = useNotifications;
14217
14359
  exports.usePlatformShellStore = usePlatformShellStore;
14218
14360
  exports.usePullToRefresh = usePullToRefresh;
14219
- //# sourceMappingURL=chunk-5IE2FIWT.js.map
14220
- //# sourceMappingURL=chunk-5IE2FIWT.js.map
14361
+ //# sourceMappingURL=chunk-JYX3ILSA.js.map
14362
+ //# sourceMappingURL=chunk-JYX3ILSA.js.map