@acusti/dropdown 1.0.0-rc.1 → 1.0.0-rc.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/README.md CHANGED
@@ -1,9 +1,10 @@
1
1
  # @acusti/dropdown
2
2
 
3
- [![latest version](https://img.shields.io/npm/v/@acusti/dropdown?style=for-the-badge)](https://www.npmjs.com/package/@acusti/dropdown)
4
- [![maintenance status](https://img.shields.io/npms-io/maintenance-score/@acusti/dropdown?style=for-the-badge)](https://npms.io/search?q=%40acusti%2Fdropdown)
5
- [![downloads per month](https://img.shields.io/npm/dm/@acusti/dropdown?style=for-the-badge)](https://www.npmjs.com/package/@acusti/dropdown)
6
- [![bundle size](https://deno.bundlejs.com/badge?q=@acusti/dropdown)](https://bundlejs.com/?q=%40acusti%2Fdropdown)
3
+ [![Open on npmx.dev](https://npmx.dev/api/registry/badge/version/@acusti/dropdown)](https://npmx.dev/package/@acusti/dropdown)
4
+ [![Open on npmx.dev](https://npmx.dev/api/registry/badge/size/@acusti/dropdown)](https://npmx.dev/package/@acusti/dropdown)
5
+ [![Open on npmx.dev](https://npmx.dev/api/registry/badge/dependencies/@acusti/dropdown)](https://npmx.dev/package/@acusti/dropdown)
6
+ [![Open on npmx.dev](https://npmx.dev/api/registry/badge/downloads-month/@acusti/dropdown)](https://npmx.dev/package/@acusti/dropdown)
7
+ [![Open on npmx.dev](https://npmx.dev/api/registry/badge/updated/@acusti/dropdown)](https://npmx.dev/package/@acusti/dropdown)
7
8
 
8
9
  `Dropdown` is a React component that renders a menu-like UI with a trigger
9
10
  that the user clicks to disclose a dropdown anchored to that trigger. The
@@ -1042,7 +1043,8 @@ Menubar behaviors:
1042
1043
  tabbing away and back returns you where you were; it starts on (and falls
1043
1044
  back to) the first enabled member. A searchable member sits outside this
1044
1045
  — it’s a `combobox`, not a menu item, so it keeps its own native tab stop
1045
- and never takes the bar’s
1046
+ and never takes the bar’s. ←/→ inside its input stay caret movement, and
1047
+ the bar’s roving passes over it rather than landing in it
1046
1048
  - at most one menu in the bar is open at a time
1047
1049
  - opening a trigger’s menu (by click or keyboard) engages the bar
1048
1050
  (menu-mode). While engaged, hovering or focusing another trigger switches
package/dist/Dropdown.js CHANGED
@@ -309,15 +309,15 @@ var compareDocumentOrder = (a, b) => {
309
309
  return 0;
310
310
  };
311
311
  var NON_MENU_CONTROL_SELECTOR = "a[href], button, input, select, textarea, [tabindex]";
312
- var findNextEnabledMember = (members, fromIndex, direction) => {
312
+ var canHoldTabStop = (member) => !member.isDisabled() && member.isMenuPopup();
313
+ var findNextTargetMember = (members, fromIndex, direction) => {
313
314
  const { length } = members;
314
315
  for (let step = 1; step < length; step++) {
315
316
  const member = members[((fromIndex + direction * step) % length + length) % length];
316
- if (!member.isDisabled()) return member;
317
+ if (canHoldTabStop(member)) return member;
317
318
  }
318
319
  return null;
319
320
  };
320
- var canHoldTabStop = (member) => !member.isDisabled() && member.isMenuPopup();
321
321
  function Menubar(t0) {
322
322
  const $ = c(22);
323
323
  const { children, className, style } = t0;
@@ -365,7 +365,7 @@ function Menubar(t0) {
365
365
  if (members_0.length < 2) return;
366
366
  const index = members_0.findIndex((member_0) => member_0.element === fromElement);
367
367
  if (index === -1) return;
368
- const next = findNextEnabledMember(members_0, index, direction);
368
+ const next = findNextTargetMember(members_0, index, direction);
369
369
  if (!next) return;
370
370
  members_0[index].close();
371
371
  next.open();
@@ -380,10 +380,18 @@ function Menubar(t0) {
380
380
  },
381
381
  registerMember(member_2) {
382
382
  membersRef.current.add(member_2);
383
- setTabbableElement((current) => current == null && canHoldTabStop(member_2) ? member_2.element : current);
383
+ setTabbableElement((current) => {
384
+ if (current == null) return canHoldTabStop(member_2) ? member_2.element : current;
385
+ if (current === member_2.element && !canHoldTabStop(member_2)) return null;
386
+ return current;
387
+ });
384
388
  return () => {
385
389
  membersRef.current.delete(member_2);
386
- reconcile();
390
+ if (member_2.element !== tabbableElement) return;
391
+ queueMicrotask(() => {
392
+ for (const registered of membersRef.current) if (registered.element === member_2.element) return;
393
+ reconcile();
394
+ });
387
395
  };
388
396
  },
389
397
  tabbableElement
@@ -397,15 +405,16 @@ function Menubar(t0) {
397
405
  t6 = (event) => {
398
406
  const { key } = event;
399
407
  if (key !== "ArrowLeft" && key !== "ArrowRight") return;
408
+ if (isEventTargetUsingKeyEvent(event.nativeEvent)) return;
400
409
  const members_1 = getOrderedMembers();
401
410
  if (members_1.length < 2) return;
402
411
  if (members_1.some(_temp2)) return;
403
412
  const eventTarget = event.target;
404
413
  const index_0 = members_1.findIndex((member_4) => member_4.element.contains(eventTarget));
405
- if (index_0 === -1) return;
414
+ if (index_0 === -1 || !members_1[index_0].isMenuPopup()) return;
406
415
  event.preventDefault();
407
416
  event.stopPropagation();
408
- const next_0 = findNextEnabledMember(members_1, index_0, key === "ArrowRight" ? 1 : -1);
417
+ const next_0 = findNextTargetMember(members_1, index_0, key === "ArrowRight" ? 1 : -1);
409
418
  if (!next_0) return;
410
419
  next_0.focusTrigger();
411
420
  };
@@ -538,7 +547,7 @@ function RootDropdown(t0) {
538
547
  const keepOpenOnSubmit = t3 === void 0 ? !hasItems : t3;
539
548
  const childrenCount = Children.count(children);
540
549
  if (childrenCount !== 1 && childrenCount !== 2) {
541
- if (childrenCount === 0) throw new Error("@acusti/dropdown requires either 1 child (the dropdown body) or 2 children: the dropdown trigger and the dropdown body. Received no children.");
550
+ if (childrenCount === 0) throw new Error(CHILDREN_ERROR + " Received no children.");
542
551
  console.error(`${CHILDREN_ERROR} Received ${childrenCount} children.`);
543
552
  }
544
553
  let trigger;
@@ -1468,76 +1477,77 @@ function RootDropdown(t0) {
1468
1477
  } else t45 = $[120];
1469
1478
  const handleBodyRef = t45;
1470
1479
  let bodyLabelledBy;
1471
- if (!isValidElement(trigger)) if (isSearchable) {
1472
- const t46 = valueLabel ?? "";
1473
- let t47;
1474
- if ($[121] === Symbol.for("react.memo_cache_sentinel")) {
1475
- t47 = () => setIsOpen(true);
1476
- $[121] = t47;
1477
- } else t47 = $[121];
1478
- let t48;
1479
- if ($[122] !== bodyId || $[123] !== disabled || $[124] !== isOpen || $[125] !== name || $[126] !== placeholder || $[127] !== popupRole || $[128] !== t46 || $[129] !== tabIndex || $[130] !== triggerId) {
1480
- t48 = /* @__PURE__ */ jsx("input", {
1481
- "aria-autocomplete": "list",
1482
- "aria-controls": bodyId,
1483
- "aria-expanded": isOpen,
1484
- "aria-haspopup": popupRole,
1485
- autoComplete: "off",
1486
- className: "uktdropdown-trigger",
1487
- defaultValue: t46,
1488
- disabled,
1489
- id: triggerId,
1490
- name,
1491
- onFocus: t47,
1492
- placeholder,
1493
- ref: inputElementRef,
1494
- role: "combobox",
1495
- tabIndex,
1496
- type: "text"
1497
- });
1498
- $[122] = bodyId;
1499
- $[123] = disabled;
1500
- $[124] = isOpen;
1501
- $[125] = name;
1502
- $[126] = placeholder;
1503
- $[127] = popupRole;
1504
- $[128] = t46;
1505
- $[129] = tabIndex;
1506
- $[130] = triggerId;
1507
- $[131] = t48;
1508
- } else t48 = $[131];
1509
- trigger = t48;
1480
+ if (!isValidElement(trigger)) {
1481
+ if (isSearchable) {
1482
+ const t46 = valueLabel ?? "";
1483
+ let t47;
1484
+ if ($[121] === Symbol.for("react.memo_cache_sentinel")) {
1485
+ t47 = () => setIsOpen(true);
1486
+ $[121] = t47;
1487
+ } else t47 = $[121];
1488
+ let t48;
1489
+ if ($[122] !== bodyId || $[123] !== disabled || $[124] !== isOpen || $[125] !== name || $[126] !== placeholder || $[127] !== popupRole || $[128] !== t46 || $[129] !== tabIndex || $[130] !== triggerId) {
1490
+ t48 = /* @__PURE__ */ jsx("input", {
1491
+ "aria-autocomplete": "list",
1492
+ "aria-controls": bodyId,
1493
+ "aria-expanded": isOpen,
1494
+ "aria-haspopup": popupRole,
1495
+ autoComplete: "off",
1496
+ className: "uktdropdown-trigger",
1497
+ defaultValue: t46,
1498
+ disabled,
1499
+ id: triggerId,
1500
+ name,
1501
+ onFocus: t47,
1502
+ placeholder,
1503
+ ref: inputElementRef,
1504
+ role: "combobox",
1505
+ tabIndex,
1506
+ type: "text"
1507
+ });
1508
+ $[122] = bodyId;
1509
+ $[123] = disabled;
1510
+ $[124] = isOpen;
1511
+ $[125] = name;
1512
+ $[126] = placeholder;
1513
+ $[127] = popupRole;
1514
+ $[128] = t46;
1515
+ $[129] = tabIndex;
1516
+ $[130] = triggerId;
1517
+ $[131] = t48;
1518
+ } else t48 = $[131];
1519
+ trigger = t48;
1520
+ } else {
1521
+ bodyLabelledBy = triggerId;
1522
+ const t46 = isMenubarItem ? "menuitem" : void 0;
1523
+ const t47 = menubarTabIndex ?? 0;
1524
+ let t48;
1525
+ if ($[132] !== bodyId || $[133] !== disabled || $[134] !== isOpen || $[135] !== popupRole || $[136] !== t46 || $[137] !== t47 || $[138] !== trigger || $[139] !== triggerId) {
1526
+ t48 = /* @__PURE__ */ jsx("button", {
1527
+ "aria-controls": bodyId,
1528
+ "aria-expanded": isOpen,
1529
+ "aria-haspopup": popupRole,
1530
+ className: "uktdropdown-trigger",
1531
+ disabled,
1532
+ id: triggerId,
1533
+ role: t46,
1534
+ tabIndex: t47,
1535
+ type: "button",
1536
+ children: trigger
1537
+ });
1538
+ $[132] = bodyId;
1539
+ $[133] = disabled;
1540
+ $[134] = isOpen;
1541
+ $[135] = popupRole;
1542
+ $[136] = t46;
1543
+ $[137] = t47;
1544
+ $[138] = trigger;
1545
+ $[139] = triggerId;
1546
+ $[140] = t48;
1547
+ } else t48 = $[140];
1548
+ trigger = t48;
1549
+ }
1510
1550
  } else {
1511
- bodyLabelledBy = triggerId;
1512
- const t46 = isMenubarItem ? "menuitem" : void 0;
1513
- const t47 = menubarTabIndex ?? 0;
1514
- let t48;
1515
- if ($[132] !== bodyId || $[133] !== disabled || $[134] !== isOpen || $[135] !== popupRole || $[136] !== t46 || $[137] !== t47 || $[138] !== trigger || $[139] !== triggerId) {
1516
- t48 = /* @__PURE__ */ jsx("button", {
1517
- "aria-controls": bodyId,
1518
- "aria-expanded": isOpen,
1519
- "aria-haspopup": popupRole,
1520
- className: "uktdropdown-trigger",
1521
- disabled,
1522
- id: triggerId,
1523
- role: t46,
1524
- tabIndex: t47,
1525
- type: "button",
1526
- children: trigger
1527
- });
1528
- $[132] = bodyId;
1529
- $[133] = disabled;
1530
- $[134] = isOpen;
1531
- $[135] = popupRole;
1532
- $[136] = t46;
1533
- $[137] = t47;
1534
- $[138] = trigger;
1535
- $[139] = triggerId;
1536
- $[140] = t48;
1537
- } else t48 = $[140];
1538
- trigger = t48;
1539
- }
1540
- else {
1541
1551
  const triggerProps = trigger.props;
1542
1552
  const resolvedTriggerId = triggerProps.id ?? triggerId;
1543
1553
  const isTextInputTrigger = isTextInputElement(trigger);