@flytedan/flytebot-design-system 0.11.1 → 0.11.3

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.d.cts CHANGED
@@ -88,6 +88,10 @@ interface PopoverPosition {
88
88
  top: number | null;
89
89
  bottom: number | null;
90
90
  maxH: number;
91
+ /** The widest the layer may be: the viewport less its margins. A fixed `width`, a
92
+ * `minWidth` or an anchor-matched width wider than the screen is capped to this, so the
93
+ * surface — and the action in its footer — never runs past the viewport edge. */
94
+ maxW: number;
91
95
  side: "top" | "bottom";
92
96
  anchorWidth: number;
93
97
  }
@@ -1501,7 +1505,9 @@ interface TransferListProps<T> {
1501
1505
  * ghost that follows the cursor: with per-field props that second call has to
1502
1506
  * remember to pass each of them, and the version of this component that did exactly
1503
1507
  * that quietly dropped every field but title and meta off the dragged card. Handing
1504
- * the same object to both render sites makes that class of bug unrepresentable. */
1508
+ * the same object to both render sites makes that class of bug unrepresentable.
1509
+ * The row's `title` also names its +/- action, with the destination side's `label`:
1510
+ * "Move Alpha to In audience". */
1505
1511
  renderRow: (item: T) => EntityRowContent;
1506
1512
  /** Fired by both a drag-drop and the equivalent +/- click. The caller owns actually
1507
1513
  * moving the item between whatever backing lists it maintains — this component never
package/dist/index.d.ts CHANGED
@@ -88,6 +88,10 @@ interface PopoverPosition {
88
88
  top: number | null;
89
89
  bottom: number | null;
90
90
  maxH: number;
91
+ /** The widest the layer may be: the viewport less its margins. A fixed `width`, a
92
+ * `minWidth` or an anchor-matched width wider than the screen is capped to this, so the
93
+ * surface — and the action in its footer — never runs past the viewport edge. */
94
+ maxW: number;
91
95
  side: "top" | "bottom";
92
96
  anchorWidth: number;
93
97
  }
@@ -1501,7 +1505,9 @@ interface TransferListProps<T> {
1501
1505
  * ghost that follows the cursor: with per-field props that second call has to
1502
1506
  * remember to pass each of them, and the version of this component that did exactly
1503
1507
  * that quietly dropped every field but title and meta off the dragged card. Handing
1504
- * the same object to both render sites makes that class of bug unrepresentable. */
1508
+ * the same object to both render sites makes that class of bug unrepresentable.
1509
+ * The row's `title` also names its +/- action, with the destination side's `label`:
1510
+ * "Move Alpha to In audience". */
1505
1511
  renderRow: (item: T) => EntityRowContent;
1506
1512
  /** Fired by both a drag-drop and the equivalent +/- click. The caller owns actually
1507
1513
  * moving the item between whatever backing lists it maintains — this component never
package/dist/index.js CHANGED
@@ -85,7 +85,7 @@ var parsePlacement = (p) => {
85
85
  };
86
86
  var samePosition = (a, b) => {
87
87
  if (!a || !b) return a === b;
88
- return a.left === b.left && a.top === b.top && a.bottom === b.bottom && a.width === b.width && a.minWidth === b.minWidth && a.maxH === b.maxH && a.side === b.side && a.anchorWidth === b.anchorWidth;
88
+ return a.left === b.left && a.top === b.top && a.bottom === b.bottom && a.width === b.width && a.minWidth === b.minWidth && a.maxH === b.maxH && a.maxW === b.maxW && a.side === b.side && a.anchorWidth === b.anchorWidth;
89
89
  };
90
90
  var SCROLL_REGIONS = ".fd-pop-body, .fd-pop-list";
91
91
  var PINNED_REGIONS = ":scope > .fd-pop-header, :scope > .fd-pop-footer";
@@ -142,9 +142,10 @@ function usePopoverPosition(open, anchorRef, opts) {
142
142
  const top = side === "bottom" ? beside ? r.bottom + offset : edge : null;
143
143
  const bottom = side === "top" ? beside ? vh - r.top + offset : edge : null;
144
144
  const maxH = beside ? room : vh - MARGIN - edge;
145
+ const maxW = Math.max(0, window.innerWidth - 2 * MARGIN);
145
146
  const exact = o.matchWidth === true;
146
147
  const width = exact ? r.width : Math.max(o.width || 0, o.minWidth || 0, o.matchWidth === "min" ? r.width : 0);
147
- const w = exact || o.width ? width : Math.max(layer.width, width) || o.estWidth || 260;
148
+ const w = Math.min(maxW, exact || o.width ? width : Math.max(layer.width, width) || o.estWidth || 260);
148
149
  let left = align === "end" ? r.right - w : align === "center" ? r.left + r.width / 2 - w / 2 : r.left;
149
150
  left = Math.max(MARGIN, Math.min(left, window.innerWidth - w - MARGIN));
150
151
  const next = {
@@ -154,6 +155,7 @@ function usePopoverPosition(open, anchorRef, opts) {
154
155
  top,
155
156
  bottom,
156
157
  maxH,
158
+ maxW,
157
159
  side,
158
160
  anchorWidth: r.width
159
161
  };
@@ -178,6 +180,7 @@ function usePopoverPosition(open, anchorRef, opts) {
178
180
  }, [open, o.placement, o.offset, o.matchWidth, o.width, o.minWidth, o.maxHeight, o.estHeight]);
179
181
  return pos;
180
182
  }
183
+ var capWidth = (value, max) => value == null ? void 0 : Math.min(value, max);
181
184
  var portal = (node) => {
182
185
  if (typeof document !== "undefined") return createPortal(node, document.body);
183
186
  return node;
@@ -269,7 +272,14 @@ function Popover({
269
272
  top: pos.top == null ? "auto" : pos.top,
270
273
  bottom: pos.bottom == null ? "auto" : pos.bottom,
271
274
  width: matchWidth === true ? pos.width : width,
272
- minWidth: matchWidth === "min" ? Math.max(pos.anchorWidth, minWidth || 0) : minWidth || (matchWidth ? void 0 : 200),
275
+ // CSS lets min-width win over max-width, so every minimum is capped to the viewport too.
276
+ minWidth: capWidth(
277
+ matchWidth === "min" ? Math.max(pos.anchorWidth, minWidth || 0) : minWidth || (matchWidth ? void 0 : 200),
278
+ pos.maxW
279
+ ),
280
+ // The surface never runs past the viewport edge, whatever fixed `width` a caller asked
281
+ // for: pos.maxW is the viewport less its margins, and `left` is clamped against it.
282
+ maxWidth: pos.maxW,
273
283
  // Size to content by default — cap only at real available room between the
274
284
  // anchor and the viewport edge (pos.maxH, computed by usePopoverPosition).
275
285
  // A caller-supplied `maxHeight` narrows that further (e.g. a long menu that
@@ -3167,15 +3177,20 @@ function TransferList({
3167
3177
  if (isBeingDragged) {
3168
3178
  return /* @__PURE__ */ jsx43("div", { className: "fd-erow-placeholder", "aria-hidden": "true" });
3169
3179
  }
3180
+ const content = renderRow(item);
3181
+ const destination = (side === "left" ? right : left).label || "the other list";
3170
3182
  return /* @__PURE__ */ jsx43(
3171
3183
  EntityRow,
3172
3184
  {
3173
- ...renderRow(item),
3185
+ ...content,
3174
3186
  draggable: true,
3175
3187
  onPointerDown: (e) => beginDrag(e, item, side),
3176
3188
  action: {
3177
3189
  icon: side === "left" ? "plus" : "minus",
3178
- label: (side === "left" ? "Move to " : "Move from ") + (side === "left" ? right.label || "the other list" : left.label || "the other list"),
3190
+ // Names the row AND where it goes. A list repeats this button on every
3191
+ // row, so a name without the row's title is the same word fifty times
3192
+ // over to a screen reader, with nothing to tell one button from the next.
3193
+ label: "Move " + content.title + " to " + destination,
3179
3194
  tone: side === "left" ? "add" : "remove",
3180
3195
  onClick: () => onMove(item, side, opposite)
3181
3196
  }