@flytedan/flytebot-design-system 0.34.0 → 0.36.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
@@ -3871,7 +3871,28 @@ function MultiSelectPanel({
3871
3871
  );
3872
3872
  }) }) : null
3873
3873
  ] });
3874
- const footer = mode2 === "paste" ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Button, { size: "sm", variant: "secondary", onClick: doResolve, disabled: pasteLoading || !pasteText.trim(), children: pasteLoading ? "Resolving\u2026" : "Resolve" }) : void 0;
3874
+ const resolveDisabled = pasteLoading || !pasteText.trim();
3875
+ const footer = mode2 === "paste" ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3876
+ Button,
3877
+ {
3878
+ size: "sm",
3879
+ variant: "secondary",
3880
+ "aria-disabled": resolveDisabled,
3881
+ onClick: (e) => {
3882
+ if (resolveDisabled) {
3883
+ e.preventDefault();
3884
+ return;
3885
+ }
3886
+ doResolve();
3887
+ },
3888
+ onKeyDown: (e) => {
3889
+ if (resolveDisabled && (e.key === "Enter" || e.key === " ")) {
3890
+ e.preventDefault();
3891
+ }
3892
+ },
3893
+ children: pasteLoading ? "Resolving\u2026" : "Resolve"
3894
+ }
3895
+ ) : void 0;
3875
3896
  return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3876
3897
  Popover,
3877
3898
  {
@@ -3940,6 +3961,28 @@ function useReseedFromProps(value, applies, reseed) {
3940
3961
  if (!sameValue(value, applies())) reseed(value);
3941
3962
  }, [value, applies, reseed]);
3942
3963
  }
3964
+ function usePreserveFocusAcrossRemount(seed, fields) {
3965
+ const pendingName = React25.useRef(null);
3966
+ const fieldsRef = useLatest(fields);
3967
+ const capture = () => {
3968
+ const active = document.activeElement;
3969
+ pendingName.current = null;
3970
+ if (!(active instanceof HTMLElement)) return;
3971
+ for (const [name, ref] of Object.entries(fieldsRef.current)) {
3972
+ if (ref.current?.contains(active)) {
3973
+ pendingName.current = name;
3974
+ break;
3975
+ }
3976
+ }
3977
+ };
3978
+ React25.useLayoutEffect(() => {
3979
+ const name = pendingName.current;
3980
+ if (!name) return;
3981
+ pendingName.current = null;
3982
+ fieldsRef.current[name]?.current?.querySelector("input,textarea,select,button")?.focus();
3983
+ }, [seed]);
3984
+ return capture;
3985
+ }
3943
3986
  var rangeDraft = (value) => ({ min: value?.min, max: value?.max });
3944
3987
  function RangePanel({
3945
3988
  field,
@@ -3950,6 +3993,11 @@ function RangePanel({
3950
3993
  }) {
3951
3994
  const [draft, setDraft] = React25.useState(() => rangeDraft(value));
3952
3995
  const [seed, setSeed] = React25.useState(0);
3996
+ const minId = React25.useId();
3997
+ const maxId = React25.useId();
3998
+ const minWrapRef = React25.useRef(null);
3999
+ const maxWrapRef = React25.useRef(null);
4000
+ const preserveFocus = usePreserveFocusAcrossRemount(seed, { min: minWrapRef, max: maxWrapRef });
3953
4001
  const draftRef = React25.useRef(draft);
3954
4002
  const shown = () => {
3955
4003
  const { min, max } = draftRef.current;
@@ -3960,6 +4008,7 @@ function RangePanel({
3960
4008
  };
3961
4009
  const validity = useTextValidity(publish);
3962
4010
  useReseedFromProps(value, shown, (next) => {
4011
+ preserveFocus();
3963
4012
  draftRef.current = rangeDraft(next);
3964
4013
  setDraft(draftRef.current);
3965
4014
  validity.reset();
@@ -3989,9 +4038,10 @@ function RangePanel({
3989
4038
  label: field.label,
3990
4039
  footer: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Button, { size: "sm", variant: "secondary", onClick: onClose, disabled: doneDisabled, children: "Done" }),
3991
4040
  children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "fd-stack fd-gap-sm", children: [
3992
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4041
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { ref: minWrapRef, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3993
4042
  NumberInput,
3994
4043
  {
4044
+ id: minId,
3995
4045
  label: field.minLabel || "At least",
3996
4046
  value: draftMin ?? "",
3997
4047
  min: field.min,
@@ -4003,10 +4053,11 @@ function RangePanel({
4003
4053
  onValidityChange: validity.report("min")
4004
4054
  },
4005
4055
  "min-" + seed
4006
- ),
4007
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4056
+ ) }),
4057
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { ref: maxWrapRef, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4008
4058
  NumberInput,
4009
4059
  {
4060
+ id: maxId,
4010
4061
  label: field.maxLabel || "At most",
4011
4062
  value: draftMax ?? "",
4012
4063
  min: field.min,
@@ -4019,7 +4070,7 @@ function RangePanel({
4019
4070
  onValidityChange: validity.report("max")
4020
4071
  },
4021
4072
  "max-" + seed
4022
- )
4073
+ ) })
4023
4074
  ] })
4024
4075
  }
4025
4076
  );
@@ -4046,6 +4097,9 @@ function DatePanel({
4046
4097
  const daysConfirmed = React25.useRef(value?.kind === "withinDays");
4047
4098
  const [between, setBetween] = React25.useState(initial.between);
4048
4099
  const [seed, setSeed] = React25.useState(0);
4100
+ const daysId = React25.useId();
4101
+ const daysWrapRef = React25.useRef(null);
4102
+ const preserveFocus = usePreserveFocusAcrossRemount(seed, { days: daysWrapRef });
4049
4103
  const shownWithinDays = () => {
4050
4104
  const days = daysRef.current;
4051
4105
  return applicable(field, days == null ? void 0 : { kind: "withinDays", days }, validity.allValid());
@@ -4061,6 +4115,7 @@ function DatePanel({
4061
4115
  return daysConfirmed.current ? shownWithinDays() : void 0;
4062
4116
  };
4063
4117
  useReseedFromProps(value, applies, (next) => {
4118
+ preserveFocus();
4064
4119
  const d = dateDraft(field, next);
4065
4120
  setKind(d.kind);
4066
4121
  daysRef.current = d.days;
@@ -4127,9 +4182,10 @@ function DatePanel({
4127
4182
  onChange: (k) => switchKind(k)
4128
4183
  }
4129
4184
  ),
4130
- kind === "withinDays" ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4185
+ kind === "withinDays" ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { ref: daysWrapRef, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4131
4186
  NumberInput,
4132
4187
  {
4188
+ id: daysId,
4133
4189
  label: "Days",
4134
4190
  min: 1,
4135
4191
  max: maxDays,
@@ -4140,7 +4196,7 @@ function DatePanel({
4140
4196
  onValidityChange: validity.report("days")
4141
4197
  },
4142
4198
  "days-" + seed
4143
- ) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4199
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4144
4200
  DatePicker,
4145
4201
  {
4146
4202
  range: true,