@guardian/stand 0.0.44 → 0.0.45

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.
@@ -1,5 +1,6 @@
1
1
  require("../../_virtual/_rolldown/runtime.cjs");
2
2
  const require_styles = require("./styles.cjs");
3
+ let react = require("react");
3
4
  let _emotion_react = require("@emotion/react");
4
5
  let _emotion_react_jsx_runtime = require("@emotion/react/jsx-runtime");
5
6
  let react_aria_components = require("react-aria-components");
@@ -87,7 +88,10 @@ let react_aria_components = require("react-aria-components");
87
88
  *
88
89
  * This is currently still in testing phase, so a production implementation is not yet available.
89
90
  */
90
- function Autocomplete({ addSelection, loading, onTextInputChange, options, label, placeholder, disabled, value, "data-testid": dataTestId, loadingIcon, theme, cssOverrides }) {
91
+ function Autocomplete({ addSelection, loading, onTextInputChange, options, label, placeholder, disabled, value, "data-testid": dataTestId, loadingIcon, theme, cssOverrides, addFirstOnEnter }) {
92
+ const [hoveredItemId, setHoveredItemId] = (0, react.useState)();
93
+ const [upOrDownKeyPressed, setUpOrDownKeyPressed] = (0, react.useState)(false);
94
+ const listBoxIsInUse = upOrDownKeyPressed || !!hoveredItemId;
91
95
  return /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)("div", {
92
96
  css: [_emotion_react.css`
93
97
  position: relative;
@@ -95,7 +99,10 @@ function Autocomplete({ addSelection, loading, onTextInputChange, options, label
95
99
  children: /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsxs)(react_aria_components.ComboBox, {
96
100
  "aria-label": label,
97
101
  inputValue: value,
98
- onInputChange: onTextInputChange,
102
+ onInputChange: (value) => {
103
+ setUpOrDownKeyPressed(false);
104
+ onTextInputChange(value);
105
+ },
99
106
  onChange: (key) => {
100
107
  const tag = options.find((t) => t.id === key);
101
108
  if (tag) {
@@ -112,7 +119,14 @@ function Autocomplete({ addSelection, loading, onTextInputChange, options, label
112
119
  css: require_styles.autocompleteInputStyles(theme),
113
120
  placeholder,
114
121
  disabled,
115
- "data-testid": dataTestId
122
+ "data-testid": dataTestId,
123
+ onKeyDown: addFirstOnEnter ? (event) => {
124
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") setUpOrDownKeyPressed(true);
125
+ if (event.key === "Enter") {
126
+ const [firstOption] = options;
127
+ if (firstOption && !listBoxIsInUse) addSelection(firstOption);
128
+ }
129
+ } : void 0
116
130
  }), /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(react_aria_components.Popover, {
117
131
  placement: "bottom",
118
132
  css: _emotion_react.css`
@@ -132,6 +146,12 @@ function Autocomplete({ addSelection, loading, onTextInputChange, options, label
132
146
  children: (item) => /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(react_aria_components.ListBoxItem, {
133
147
  css: require_styles.listboxItemStyles(theme),
134
148
  value: item,
149
+ onHoverChange: (isHovering) => {
150
+ setHoveredItemId((current) => {
151
+ if (isHovering) return item.id;
152
+ return current === item.id ? void 0 : current;
153
+ });
154
+ },
135
155
  children: item.name
136
156
  }, item.id)
137
157
  }), /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(react_aria_components.ListBoxLoadMoreItem, {
@@ -28,6 +28,7 @@ interface AutocompleteProps<T extends AutocompleteOption = AutocompleteOption> {
28
28
  'data-testid'?: string;
29
29
  /** `loadingIcon` - Icon used to show loading happening in the dropdown */
30
30
  loadingIcon?: ReactElement;
31
+ addFirstOnEnter?: boolean;
31
32
  /** `theme` - Used to customise the look and feel of the Autocomplete component */
32
33
  theme?: DeepPartial<ComponentAutocomplete>;
33
34
  /** `cssOverrides` - Escape hatch for styling that doesn't fall into the theme */
@@ -128,7 +129,8 @@ declare function Autocomplete<T extends AutocompleteOption = AutocompleteOption>
128
129
  'data-testid': dataTestId,
129
130
  loadingIcon,
130
131
  theme,
131
- cssOverrides
132
+ cssOverrides,
133
+ addFirstOnEnter
132
134
  }: AutocompleteProps<T>): import("@emotion/react/jsx-runtime").JSX.Element;
133
135
  //#endregion
134
136
  export { Autocomplete };
@@ -28,6 +28,7 @@ interface AutocompleteProps<T extends AutocompleteOption = AutocompleteOption> {
28
28
  'data-testid'?: string;
29
29
  /** `loadingIcon` - Icon used to show loading happening in the dropdown */
30
30
  loadingIcon?: ReactElement;
31
+ addFirstOnEnter?: boolean;
31
32
  /** `theme` - Used to customise the look and feel of the Autocomplete component */
32
33
  theme?: DeepPartial<ComponentAutocomplete>;
33
34
  /** `cssOverrides` - Escape hatch for styling that doesn't fall into the theme */
@@ -128,7 +129,8 @@ declare function Autocomplete<T extends AutocompleteOption = AutocompleteOption>
128
129
  'data-testid': dataTestId,
129
130
  loadingIcon,
130
131
  theme,
131
- cssOverrides
132
+ cssOverrides,
133
+ addFirstOnEnter
132
134
  }: AutocompleteProps<T>): import("@emotion/react/jsx-runtime").JSX.Element;
133
135
  //#endregion
134
136
  export { Autocomplete };
@@ -1,4 +1,5 @@
1
1
  import { autocompleteInputStyles, listboxInfoStyles, listboxItemStyles, listboxStyles } from "./styles.js";
2
+ import { useState } from "react";
2
3
  import { css } from "@emotion/react";
3
4
  import { jsx as jsx$1, jsxs } from "@emotion/react/jsx-runtime";
4
5
  import { Collection, ComboBox, Input, ListBox, ListBoxItem, ListBoxLoadMoreItem, Popover } from "react-aria-components";
@@ -86,7 +87,10 @@ import { Collection, ComboBox, Input, ListBox, ListBoxItem, ListBoxLoadMoreItem,
86
87
  *
87
88
  * This is currently still in testing phase, so a production implementation is not yet available.
88
89
  */
89
- function Autocomplete({ addSelection, loading, onTextInputChange, options, label, placeholder, disabled, value, "data-testid": dataTestId, loadingIcon, theme, cssOverrides }) {
90
+ function Autocomplete({ addSelection, loading, onTextInputChange, options, label, placeholder, disabled, value, "data-testid": dataTestId, loadingIcon, theme, cssOverrides, addFirstOnEnter }) {
91
+ const [hoveredItemId, setHoveredItemId] = useState();
92
+ const [upOrDownKeyPressed, setUpOrDownKeyPressed] = useState(false);
93
+ const listBoxIsInUse = upOrDownKeyPressed || !!hoveredItemId;
90
94
  return /* @__PURE__ */ jsx$1("div", {
91
95
  css: [css`
92
96
  position: relative;
@@ -94,7 +98,10 @@ function Autocomplete({ addSelection, loading, onTextInputChange, options, label
94
98
  children: /* @__PURE__ */ jsxs(ComboBox, {
95
99
  "aria-label": label,
96
100
  inputValue: value,
97
- onInputChange: onTextInputChange,
101
+ onInputChange: (value) => {
102
+ setUpOrDownKeyPressed(false);
103
+ onTextInputChange(value);
104
+ },
98
105
  onChange: (key) => {
99
106
  const tag = options.find((t) => t.id === key);
100
107
  if (tag) {
@@ -111,7 +118,14 @@ function Autocomplete({ addSelection, loading, onTextInputChange, options, label
111
118
  css: autocompleteInputStyles(theme),
112
119
  placeholder,
113
120
  disabled,
114
- "data-testid": dataTestId
121
+ "data-testid": dataTestId,
122
+ onKeyDown: addFirstOnEnter ? (event) => {
123
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") setUpOrDownKeyPressed(true);
124
+ if (event.key === "Enter") {
125
+ const [firstOption] = options;
126
+ if (firstOption && !listBoxIsInUse) addSelection(firstOption);
127
+ }
128
+ } : void 0
115
129
  }), /* @__PURE__ */ jsx$1(Popover, {
116
130
  placement: "bottom",
117
131
  css: css`
@@ -131,6 +145,12 @@ function Autocomplete({ addSelection, loading, onTextInputChange, options, label
131
145
  children: (item) => /* @__PURE__ */ jsx$1(ListBoxItem, {
132
146
  css: listboxItemStyles(theme),
133
147
  value: item,
148
+ onHoverChange: (isHovering) => {
149
+ setHoveredItemId((current) => {
150
+ if (isHovering) return item.id;
151
+ return current === item.id ? void 0 : current;
152
+ });
153
+ },
134
154
  children: item.name
135
155
  }, item.id)
136
156
  }), /* @__PURE__ */ jsx$1(ListBoxLoadMoreItem, {
@@ -110,6 +110,7 @@ function TagAutocomplete({ addTag, loading, onTextInputChange, options, label, p
110
110
  value,
111
111
  "data-testid": dataTestId,
112
112
  loadingIcon,
113
+ addFirstOnEnter: true,
113
114
  theme,
114
115
  cssOverrides
115
116
  });
@@ -109,6 +109,7 @@ function TagAutocomplete({ addTag, loading, onTextInputChange, options, label, p
109
109
  value,
110
110
  "data-testid": dataTestId,
111
111
  loadingIcon,
112
+ addFirstOnEnter: true,
112
113
  theme,
113
114
  cssOverrides
114
115
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guardian/stand",
3
- "version": "0.0.44",
3
+ "version": "0.0.45",
4
4
  "repository": {
5
5
  "url": "https://github.com/guardian/stand"
6
6
  },