@acusti/dropdown 1.0.0 → 1.1.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/README.md CHANGED
@@ -294,8 +294,9 @@ type Props = {
294
294
  * Whether the body is a list of selectable items (the default) or
295
295
  * arbitrary interactive content such as a form. hasItems={false} turns
296
296
  * off item selection and item keyboard navigation, gives the popup
297
- * role="dialog" (unless isSearchable), and keeps it open on clicks
298
- * inside the body. Defaults to true and isn’t inferred from the children.
297
+ * role="dialog" (unless isSearchable), keeps it open on clicks inside
298
+ * the body, and leaves Space and Enter pressed in the body to the
299
+ * controls there. Defaults to true and isn’t inferred from the children.
299
300
  */
300
301
  hasItems?: boolean;
301
302
  /**
@@ -322,7 +323,9 @@ type Props = {
322
323
  /**
323
324
  * Whether the dropdown stays open after an item is submitted, e.g. for a
324
325
  * multi-select. Defaults to !hasItems: a menu closes on submit, while a
325
- * hasItems={false} dialog stays open.
326
+ * hasItems={false} dialog stays open. In a hasItems={false} dropdown, a
327
+ * submit is a form in the body being submitted, or Enter in a
328
+ * single-line input there that no form owns.
326
329
  */
327
330
  keepOpenOnSubmit?: boolean;
328
331
  /**
@@ -714,6 +717,49 @@ function InteractiveDropdown() {
714
717
  }
715
718
  ```
716
719
 
720
+ The body’s controls keep their own keys while the dropdown is open: Space
721
+ and Enter go to whatever has focus there. Space types a space into a text
722
+ field, toggles a checkbox, and presses a button; Enter adds a line break to
723
+ a textarea, submits the form around a text input, presses a button, and
724
+ follows a link. The same goes for whatever keeps focus outside the dropdown
725
+ while it’s open, as when it opened on hover. Escape closes the dropdown
726
+ unless focus is in a text field (a text input, a textarea, or an editable
727
+ element). On the trigger, Space and Enter open the dropdown and, unless
728
+ focus is in a text field or a checkbox there, close it again, as a click
729
+ there does.
730
+
731
+ A `hasItems={false}` dropdown stays open until it is dismissed. Pass
732
+ `keepOpenOnSubmit={false}` to close it when its content is submitted. A
733
+ submit is a form in the body being submitted, by Enter in one of its inputs
734
+ or by its submit button, or Enter in a single-line input that no form owns:
735
+
736
+ ```tsx
737
+ <Dropdown hasItems={false} keepOpenOnSubmit={false}>
738
+ Rename
739
+ <form onSubmit={handleSubmit}>
740
+ <label>
741
+ Name <input name="name" required />
742
+ </label>
743
+ <button type="submit">Save</button>
744
+ </form>
745
+ </Dropdown>
746
+ ```
747
+
748
+ Unless the form opts out of validation (`noValidate`, or a submit button
749
+ with `formNoValidate`), its `submit` event doesn’t fire until the browser’s
750
+ validation passes, so the dropdown stays open while a required field is
751
+ empty. To keep it open after a submit that your own checks reject, call
752
+ `event.stopPropagation()` in the form’s `onSubmit` before it returns. A
753
+ check that finishes later, such as a server round trip or a form library
754
+ that validates asynchronously, can’t keep it open.
755
+
756
+ Enter in an input that no form owns counts the way a form would count it:
757
+ not when a handler has prevented the key, as a combobox does to pick an
758
+ option, and not when it commits an IME composition.
759
+
760
+ When a submit closes the dropdown while focus is in its body, focus returns
761
+ to the trigger, as it does on Escape.
762
+
717
763
  ### Placement Customization with CSS Variables
718
764
 
719
765
  Placement is best customized in CSS instead of props. The component exposes
@@ -1262,7 +1308,11 @@ intent delay while the highlight stays on the parent, and only → moves the
1262
1308
  highlight into it.
1263
1309
 
1264
1310
  - **Enter/Space**: Open the dropdown; with an item highlighted, select it
1265
- (leaf items) or open its submenu (parent items)
1311
+ (leaf items) or open its submenu (parent items). In the body of a
1312
+ `hasItems={false}` dropdown, they go to
1313
+ [the control that has focus](#dropdown-with-interactive-content) instead,
1314
+ and on its open trigger, outside a text field or a checkbox, they close
1315
+ it
1266
1316
  - **Escape**: Close the dropdown entirely — including any open submenus —
1267
1317
  and return focus to the trigger (macOS-style; use ← to back out one level
1268
1318
  at a time)
@@ -70,8 +70,9 @@ export type Props = {
70
70
  * Whether the body is a list of selectable items (the default) or
71
71
  * arbitrary interactive content such as a form. hasItems={false} turns
72
72
  * off item selection and item keyboard navigation, gives the popup
73
- * role="dialog" (unless isSearchable), and keeps it open on clicks
74
- * inside the body. Defaults to true and isn’t inferred from the children.
73
+ * role="dialog" (unless isSearchable), keeps it open on clicks inside
74
+ * the body, and leaves Space and Enter pressed in the body to the
75
+ * controls there. Defaults to true and isn’t inferred from the children.
75
76
  */
76
77
  hasItems?: boolean;
77
78
  /**
@@ -98,7 +99,9 @@ export type Props = {
98
99
  /**
99
100
  * Whether the dropdown stays open after an item is submitted, e.g. for a
100
101
  * multi-select. Defaults to !hasItems: a menu closes on submit, while a
101
- * hasItems={false} dialog stays open.
102
+ * hasItems={false} dialog stays open. In a hasItems={false} dropdown, a
103
+ * submit is a form in the body being submitted, or Enter in a
104
+ * single-line input there that no form owns.
102
105
  */
103
106
  keepOpenOnSubmit?: boolean;
104
107
  /**