@react-fabric/form 1.0.0-beta.19 → 1.0.0-beta.21

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.
@@ -3,6 +3,7 @@
3
3
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
4
  var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
5
5
  var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
6
+ var react$1 = require('@floating-ui/react');
6
7
  var core = require('@react-fabric/core');
7
8
  var utilities = require('@react-fabric/utilities');
8
9
  var classNames = require('classnames');
@@ -43,41 +44,86 @@ var ColorInput = function ColorInput(_ref) {
43
44
  return onChange(e);
44
45
  });
45
46
  }, [onChange]);
47
+ var arrowRef = react.useRef(null);
48
+ var _useState3 = react.useState(false),
49
+ _useState4 = _slicedToArray(_useState3, 2),
50
+ isOpen = _useState4[0],
51
+ setIsOpen = _useState4[1];
52
+ var _useFloating = react$1.useFloating({
53
+ open: isOpen,
54
+ onOpenChange: function onOpenChange(open, _, reason) {
55
+ if (reason === "reference-press") return;
56
+ setIsOpen(open);
57
+ },
58
+ strategy: "fixed",
59
+ placement: "bottom",
60
+ whileElementsMounted: react$1.autoUpdate,
61
+ middleware: [react$1.shift({
62
+ padding: 8
63
+ }), react$1.flip(), react$1.offset(9), react$1.arrow({
64
+ element: arrowRef
65
+ })]
66
+ }),
67
+ refs = _useFloating.refs,
68
+ floatingStyles = _useFloating.floatingStyles,
69
+ context = _useFloating.context;
70
+ var click = react$1.useClick(context, {
71
+ enabled: !disabled
72
+ });
73
+ var dismiss = react$1.useDismiss(context, {
74
+ referencePress: true
75
+ });
76
+ var _useInteractions = react$1.useInteractions([dismiss, click]),
77
+ getReferenceProps = _useInteractions.getReferenceProps,
78
+ getFloatingProps = _useInteractions.getFloatingProps;
46
79
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
47
80
  className: classNames("flex-content min-h-[1.5em] min-w-[3.5em] self-stretch flex items-center outline-tint-200 rounded", !disabled && "bg-base", !noOutline && "bg-[var(--fabric-input)] outline overflow-hidden"),
48
81
  children: [decorateStart && /*#__PURE__*/jsxRuntime.jsx("div", {
49
82
  className: classNames("text-muted leading-none flex-content", utilities.isString(decorateStart) && "px-2"),
50
83
  children: decorateStart
51
- }), /*#__PURE__*/jsxRuntime.jsxs(core.Dropdown, {
52
- showArrow: true,
53
- disabled: disabled,
54
- children: [/*#__PURE__*/jsxRuntime.jsx("button", {
55
- "data-ref": "button",
56
- className: "flex-1 flex items-center",
57
- children: /*#__PURE__*/jsxRuntime.jsx("div", {
58
- role: "none",
59
- className: "h-[1.5em] min-w-[1.5em] flex-1 flex items-center justify-center self-stretch cursor-pointer m-[0.25em] rounded outline outline-tint-100",
60
- style: {
61
- backgroundColor: actualValue,
62
- opacity: disabled ? 0.65 : 1,
63
- pointerEvents: disabled ? "none" : undefined
64
- },
65
- onClick: function onClick(e) {
66
- var _e$currentTarget$next;
67
- return (_e$currentTarget$next = e.currentTarget.nextElementSibling) === null || _e$currentTarget$next === void 0 ? void 0 : _e$currentTarget$next.focus();
68
- },
69
- children: !actualValue && /*#__PURE__*/jsxRuntime.jsx(core.Icon, {
70
- size: "md",
71
- className: "text-muted",
72
- icon: core.CoreIcons.colorSwatch
73
- })
84
+ }), /*#__PURE__*/jsxRuntime.jsx("button", _objectSpread(_objectSpread({
85
+ "data-ref": "button",
86
+ className: "flex-1 flex items-center",
87
+ ref: refs.setReference
88
+ }, getReferenceProps()), {}, {
89
+ "data-inner-clickable": "true",
90
+ "data-dropdown-open": isOpen ? true : undefined,
91
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
92
+ role: "none",
93
+ className: "h-[1.5em] min-w-[1.5em] flex-1 flex items-center justify-center self-stretch cursor-pointer m-[0.25em] rounded outline outline-tint-100",
94
+ style: {
95
+ backgroundColor: actualValue,
96
+ opacity: disabled ? 0.65 : 1,
97
+ pointerEvents: disabled ? "none" : undefined
98
+ },
99
+ children: !actualValue && /*#__PURE__*/jsxRuntime.jsx(core.Icon, {
100
+ size: "md",
101
+ className: "text-muted",
102
+ icon: core.CoreIcons.colorSwatch
74
103
  })
75
- }), /*#__PURE__*/jsxRuntime.jsx(ColorPicker.ColorPicker, _objectSpread(_objectSpread({}, rest), {}, {
104
+ })
105
+ })), isOpen && /*#__PURE__*/jsxRuntime.jsxs("div", _objectSpread(_objectSpread({
106
+ ref: refs.setFloating,
107
+ style: _objectSpread({
108
+ zIndex: "var(--z-popover)"
109
+ }, floatingStyles),
110
+ "data-testid": "dropdown-body"
111
+ }, getFloatingProps({
112
+ onClick: function onClick(e) {
113
+ return e.stopPropagation();
114
+ }
115
+ })), {}, {
116
+ children: [/*#__PURE__*/jsxRuntime.jsx(ColorPicker.ColorPicker, _objectSpread(_objectSpread({}, rest), {}, {
76
117
  onChange: handleChange,
77
118
  defaultColor: defaultColor,
78
119
  value: actualValue
79
- }))]
80
- }), !disabled && showPicker && /*#__PURE__*/jsxRuntime.jsx(core.Icon, {
120
+ })), /*#__PURE__*/jsxRuntime.jsx(react$1.FloatingArrow, {
121
+ ref: arrowRef,
122
+ context: context,
123
+ strokeWidth: 0.5,
124
+ className: "fill-base stroke-muted"
125
+ })]
126
+ })), !disabled && showPicker && /*#__PURE__*/jsxRuntime.jsx(core.Icon, {
81
127
  icon: core.CoreIcons.colorPicker,
82
128
  onClick: function onClick() {
83
129
  return window.EyeDropper && new window.EyeDropper().open().then(function (resp) {
@@ -36,7 +36,9 @@ var HiddenInput = function HiddenInput(_ref) {
36
36
  value = _ref$value === void 0 ? "" : _ref$value,
37
37
  name = _ref.name;
38
38
  react.useEffect(function () {
39
- onChange === null || onChange === void 0 || onChange(hiddenValue);
39
+ setTimeout(function () {
40
+ onChange === null || onChange === void 0 || onChange(hiddenValue);
41
+ }, 50);
40
42
  }, [hiddenValue]);
41
43
  return /*#__PURE__*/jsxRuntime.jsxs(react.Fragment, {
42
44
  children: [/*#__PURE__*/jsxRuntime.jsx("input", {
@@ -9,7 +9,7 @@ var eventHandlers = require('../utils/eventHandlers.js');
9
9
  require('@react-fabric/utilities');
10
10
  var jsxRuntime = require('react/jsx-runtime');
11
11
 
12
- var _excluded = ["ref", "value", "name", "invalid", "readOnly", "disabled", "required", "placeholder", "autoFocus", "rows", "maxRows", "variableRows", "onChange", "onEnterPressed"];
12
+ var _excluded = ["ref", "value", "name", "invalid", "readOnly", "disabled", "required", "placeholder", "autoFocus", "rows", "maxRows", "variableRows", "expandable", "onChange", "onEnterPressed"];
13
13
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
14
14
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
15
15
  var Textarea = function Textarea(_ref) {
@@ -27,6 +27,7 @@ var Textarea = function Textarea(_ref) {
27
27
  _ref$maxRows = _ref.maxRows,
28
28
  maxRows = _ref$maxRows === void 0 ? 12 : _ref$maxRows,
29
29
  variableRows = _ref.variableRows,
30
+ expandable = _ref.expandable,
30
31
  onChange = _ref.onChange,
31
32
  onEnterPressed = _ref.onEnterPressed,
32
33
  rest = _objectWithoutProperties(_ref, _excluded);
@@ -65,6 +66,7 @@ var Textarea = function Textarea(_ref) {
65
66
  disabled: disabled,
66
67
  required: required,
67
68
  wrapperRef: wrapperRef,
69
+ textareaExpandable: expandable,
68
70
  textarea: true
69
71
  }, rest), {}, {
70
72
  children: /*#__PURE__*/jsxRuntime.jsx("textarea", {
@@ -83,7 +85,9 @@ var Textarea = function Textarea(_ref) {
83
85
  autoFocus: autoFocus,
84
86
  value: actualValue,
85
87
  onChange: handleChange,
86
- onKeyDown: eventHandlers.handleEnter(onEnterPressed)
88
+ onKeyDown: eventHandlers.handleEnter(onEnterPressed, {
89
+ preventDefault: !!onEnterPressed
90
+ })
87
91
  })
88
92
  }));
89
93
  };
@@ -3,7 +3,6 @@
3
3
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
4
  var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
5
5
  var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
6
- var react$1 = require('@floating-ui/react');
7
6
  var core = require('@react-fabric/core');
8
7
  var utilities = require('@react-fabric/utilities');
9
8
  var classNames = require('classnames');
@@ -13,11 +12,10 @@ var ErrorIcon = require('./ErrorIcon.js');
13
12
  var Field_module = require('./Field.module.css');
14
13
  var FieldWrapper = require('./FieldWrapper.js');
15
14
 
16
- var _excluded = ["invalid", "error", "allowClear", "showClear", "decorateStart", "decorateEnd", "children", "onClear", "noOutline", "noBorder", "textarea", "data-inner", "data-open", "floatingExpand", "wrapperRef", "width"];
15
+ var _excluded = ["invalid", "error", "allowClear", "showClear", "decorateStart", "decorateEnd", "children", "onClear", "noOutline", "noBorder", "textarea", "textareaExpandable", "data-inner", "data-open", "floatingExpand", "wrapperRef", "width"];
17
16
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
18
17
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
19
18
  var InputWrapper = function InputWrapper(_ref) {
20
- var _elRef$current;
21
19
  var invalid = _ref.invalid,
22
20
  error = _ref.error,
23
21
  allowClear = _ref.allowClear,
@@ -30,6 +28,8 @@ var InputWrapper = function InputWrapper(_ref) {
30
28
  noBorder = _ref.noBorder,
31
29
  _ref$textarea = _ref.textarea,
32
30
  textarea = _ref$textarea === void 0 ? false : _ref$textarea,
31
+ _ref$textareaExpandab = _ref.textareaExpandable,
32
+ textareaExpandable = _ref$textareaExpandab === void 0 ? false : _ref$textareaExpandab,
33
33
  isInner = _ref["data-inner"];
34
34
  _ref["data-open"];
35
35
  var floatingExpand = _ref.floatingExpand,
@@ -69,7 +69,7 @@ var InputWrapper = function InputWrapper(_ref) {
69
69
  ref: wrapperRef,
70
70
  className: classNames(Field_module.inputWrapper, invalid && Field_module.invalidWrapper, !noOutline && !noBorder && "bg-[var(--fabric-input)] outline overflow-hidden", "flex flex-nowrap items-center", textarea ? "rounded-capped group" : "rounded", isExpanded ? "fixed inset-4 z-[99]" : floatingExpand ? "absolute inset-x-0" : "relative", !noOutline && "after:absolute after:bottom-0 after:h-px after:bg-primary-500 after:mx-auto"),
71
71
  onKeyDown: function onKeyDown(e) {
72
- return e.key === "Escape" && setExpanded(false);
72
+ return e.key === "Escape" && isExpanded && (setExpanded(false), e.stopPropagation());
73
73
  },
74
74
  children: [decorateStart && /*#__PURE__*/jsxRuntime.jsx("div", {
75
75
  onClickCapture: doFocus,
@@ -86,7 +86,7 @@ var InputWrapper = function InputWrapper(_ref) {
86
86
  onClickCapture: doFocus,
87
87
  className: classNames(Field_module.decorate, "text-muted leading-none flex-content", utilities.isString(decorateEnd) && "px-1"),
88
88
  children: decorateEnd
89
- }), textarea && /*#__PURE__*/jsxRuntime.jsx(core.Icon, {
89
+ }), textareaExpandable && /*#__PURE__*/jsxRuntime.jsx(core.Icon, {
90
90
  onClick: function onClick() {
91
91
  return setExpanded(!isExpanded);
92
92
  },
@@ -95,17 +95,14 @@ var InputWrapper = function InputWrapper(_ref) {
95
95
  })]
96
96
  });
97
97
  return /*#__PURE__*/jsxRuntime.jsx(Wrapper, _objectSpread(_objectSpread({}, wrapperProps), {}, {
98
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
98
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
99
99
  ref: elRef,
100
100
  className: "flex-1 relative min-h-8",
101
101
  style: {
102
102
  width: width,
103
103
  flexBasis: width
104
104
  },
105
- children: [!isExpanded && el, isExpanded && /*#__PURE__*/jsxRuntime.jsx(react$1.FloatingPortal, {
106
- root: (_elRef$current = elRef.current) === null || _elRef$current === void 0 ? void 0 : _elRef$current.closest(".theme-base"),
107
- children: el
108
- })]
105
+ children: el
109
106
  })
110
107
  }));
111
108
  };
@@ -133,6 +133,7 @@ var useSelect = function useSelect(_ref) {
133
133
  if (autoComplete && action.query !== undefined) {
134
134
  optionList = utilities.dedupe([action.query].concat(_toConsumableArray(optionList)));
135
135
  }
136
+ optionList = optionList.sort(utilities.compareValues("asc", labelProperty));
136
137
  var grouped = utilities.groupBy(optionList, groupProperty, "");
137
138
  if (action.open) _newState.open = true;
138
139
  _newState.items = [];
@@ -201,7 +202,7 @@ var useSelect = function useSelect(_ref) {
201
202
  });
202
203
  dispatch({
203
204
  type: "setValue",
204
- value: (_ref4 = hasValue !== null && hasValue !== void 0 ? hasValue : newOption) !== null && _ref4 !== void 0 ? _ref4 : ""
205
+ value: (_ref4 = hasValue !== null && hasValue !== void 0 ? hasValue : newOption) !== null && _ref4 !== void 0 ? _ref4 : deferred
205
206
  });
206
207
  }
207
208
  if (multiple) {
@@ -216,7 +217,7 @@ var useSelect = function useSelect(_ref) {
216
217
  if (!hasValue && newOption) {
217
218
  optionsRef.current.push(newOption);
218
219
  }
219
- return (_ref5 = hasValue !== null && hasValue !== void 0 ? hasValue : newOption) !== null && _ref5 !== void 0 ? _ref5 : "";
220
+ return (_ref5 = hasValue !== null && hasValue !== void 0 ? hasValue : newOption) !== null && _ref5 !== void 0 ? _ref5 : item;
220
221
  });
221
222
  optionsRef.current = [].concat(_toConsumableArray(optionsRef.current), _toConsumableArray(options !== null && options !== void 0 ? options : []));
222
223
  dispatch({
@@ -3,10 +3,11 @@
3
3
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
4
4
  import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
5
5
  import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
6
- import { Dropdown, Icon, CoreIcons } from '@react-fabric/core';
6
+ import { useFloating, autoUpdate, shift, flip, offset, arrow, useClick, useDismiss, useInteractions, FloatingArrow } from '@floating-ui/react';
7
+ import { Icon, CoreIcons } from '@react-fabric/core';
7
8
  import { isString } from '@react-fabric/utilities';
8
9
  import classNames from 'classnames';
9
- import { useState, useDeferredValue, useEffect, useCallback, startTransition } from 'react';
10
+ import { useState, useDeferredValue, useEffect, useCallback, startTransition, useRef } from 'react';
10
11
  import { ColorPicker } from './ColorPicker.js';
11
12
  import { jsxs, jsx } from 'react/jsx-runtime';
12
13
 
@@ -43,41 +44,86 @@ var ColorInput = function ColorInput(_ref) {
43
44
  return onChange(e);
44
45
  });
45
46
  }, [onChange]);
47
+ var arrowRef = useRef(null);
48
+ var _useState3 = useState(false),
49
+ _useState4 = _slicedToArray(_useState3, 2),
50
+ isOpen = _useState4[0],
51
+ setIsOpen = _useState4[1];
52
+ var _useFloating = useFloating({
53
+ open: isOpen,
54
+ onOpenChange: function onOpenChange(open, _, reason) {
55
+ if (reason === "reference-press") return;
56
+ setIsOpen(open);
57
+ },
58
+ strategy: "fixed",
59
+ placement: "bottom",
60
+ whileElementsMounted: autoUpdate,
61
+ middleware: [shift({
62
+ padding: 8
63
+ }), flip(), offset(9), arrow({
64
+ element: arrowRef
65
+ })]
66
+ }),
67
+ refs = _useFloating.refs,
68
+ floatingStyles = _useFloating.floatingStyles,
69
+ context = _useFloating.context;
70
+ var click = useClick(context, {
71
+ enabled: !disabled
72
+ });
73
+ var dismiss = useDismiss(context, {
74
+ referencePress: true
75
+ });
76
+ var _useInteractions = useInteractions([dismiss, click]),
77
+ getReferenceProps = _useInteractions.getReferenceProps,
78
+ getFloatingProps = _useInteractions.getFloatingProps;
46
79
  return /*#__PURE__*/jsxs("div", {
47
80
  className: classNames("flex-content min-h-[1.5em] min-w-[3.5em] self-stretch flex items-center outline-tint-200 rounded", !disabled && "bg-base", !noOutline && "bg-[var(--fabric-input)] outline overflow-hidden"),
48
81
  children: [decorateStart && /*#__PURE__*/jsx("div", {
49
82
  className: classNames("text-muted leading-none flex-content", isString(decorateStart) && "px-2"),
50
83
  children: decorateStart
51
- }), /*#__PURE__*/jsxs(Dropdown, {
52
- showArrow: true,
53
- disabled: disabled,
54
- children: [/*#__PURE__*/jsx("button", {
55
- "data-ref": "button",
56
- className: "flex-1 flex items-center",
57
- children: /*#__PURE__*/jsx("div", {
58
- role: "none",
59
- className: "h-[1.5em] min-w-[1.5em] flex-1 flex items-center justify-center self-stretch cursor-pointer m-[0.25em] rounded outline outline-tint-100",
60
- style: {
61
- backgroundColor: actualValue,
62
- opacity: disabled ? 0.65 : 1,
63
- pointerEvents: disabled ? "none" : undefined
64
- },
65
- onClick: function onClick(e) {
66
- var _e$currentTarget$next;
67
- return (_e$currentTarget$next = e.currentTarget.nextElementSibling) === null || _e$currentTarget$next === void 0 ? void 0 : _e$currentTarget$next.focus();
68
- },
69
- children: !actualValue && /*#__PURE__*/jsx(Icon, {
70
- size: "md",
71
- className: "text-muted",
72
- icon: CoreIcons.colorSwatch
73
- })
84
+ }), /*#__PURE__*/jsx("button", _objectSpread(_objectSpread({
85
+ "data-ref": "button",
86
+ className: "flex-1 flex items-center",
87
+ ref: refs.setReference
88
+ }, getReferenceProps()), {}, {
89
+ "data-inner-clickable": "true",
90
+ "data-dropdown-open": isOpen ? true : undefined,
91
+ children: /*#__PURE__*/jsx("div", {
92
+ role: "none",
93
+ className: "h-[1.5em] min-w-[1.5em] flex-1 flex items-center justify-center self-stretch cursor-pointer m-[0.25em] rounded outline outline-tint-100",
94
+ style: {
95
+ backgroundColor: actualValue,
96
+ opacity: disabled ? 0.65 : 1,
97
+ pointerEvents: disabled ? "none" : undefined
98
+ },
99
+ children: !actualValue && /*#__PURE__*/jsx(Icon, {
100
+ size: "md",
101
+ className: "text-muted",
102
+ icon: CoreIcons.colorSwatch
74
103
  })
75
- }), /*#__PURE__*/jsx(ColorPicker, _objectSpread(_objectSpread({}, rest), {}, {
104
+ })
105
+ })), isOpen && /*#__PURE__*/jsxs("div", _objectSpread(_objectSpread({
106
+ ref: refs.setFloating,
107
+ style: _objectSpread({
108
+ zIndex: "var(--z-popover)"
109
+ }, floatingStyles),
110
+ "data-testid": "dropdown-body"
111
+ }, getFloatingProps({
112
+ onClick: function onClick(e) {
113
+ return e.stopPropagation();
114
+ }
115
+ })), {}, {
116
+ children: [/*#__PURE__*/jsx(ColorPicker, _objectSpread(_objectSpread({}, rest), {}, {
76
117
  onChange: handleChange,
77
118
  defaultColor: defaultColor,
78
119
  value: actualValue
79
- }))]
80
- }), !disabled && showPicker && /*#__PURE__*/jsx(Icon, {
120
+ })), /*#__PURE__*/jsx(FloatingArrow, {
121
+ ref: arrowRef,
122
+ context: context,
123
+ strokeWidth: 0.5,
124
+ className: "fill-base stroke-muted"
125
+ })]
126
+ })), !disabled && showPicker && /*#__PURE__*/jsx(Icon, {
81
127
  icon: CoreIcons.colorPicker,
82
128
  onClick: function onClick() {
83
129
  return window.EyeDropper && new window.EyeDropper().open().then(function (resp) {
@@ -36,7 +36,9 @@ var HiddenInput = function HiddenInput(_ref) {
36
36
  value = _ref$value === void 0 ? "" : _ref$value,
37
37
  name = _ref.name;
38
38
  useEffect(function () {
39
- onChange === null || onChange === void 0 || onChange(hiddenValue);
39
+ setTimeout(function () {
40
+ onChange === null || onChange === void 0 || onChange(hiddenValue);
41
+ }, 50);
40
42
  }, [hiddenValue]);
41
43
  return /*#__PURE__*/jsxs(Fragment, {
42
44
  children: [/*#__PURE__*/jsx("input", {
@@ -9,7 +9,7 @@ import { handleEnter } from '../utils/eventHandlers.js';
9
9
  import '@react-fabric/utilities';
10
10
  import { jsx } from 'react/jsx-runtime';
11
11
 
12
- var _excluded = ["ref", "value", "name", "invalid", "readOnly", "disabled", "required", "placeholder", "autoFocus", "rows", "maxRows", "variableRows", "onChange", "onEnterPressed"];
12
+ var _excluded = ["ref", "value", "name", "invalid", "readOnly", "disabled", "required", "placeholder", "autoFocus", "rows", "maxRows", "variableRows", "expandable", "onChange", "onEnterPressed"];
13
13
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
14
14
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
15
15
  var Textarea = function Textarea(_ref) {
@@ -27,6 +27,7 @@ var Textarea = function Textarea(_ref) {
27
27
  _ref$maxRows = _ref.maxRows,
28
28
  maxRows = _ref$maxRows === void 0 ? 12 : _ref$maxRows,
29
29
  variableRows = _ref.variableRows,
30
+ expandable = _ref.expandable,
30
31
  onChange = _ref.onChange,
31
32
  onEnterPressed = _ref.onEnterPressed,
32
33
  rest = _objectWithoutProperties(_ref, _excluded);
@@ -65,6 +66,7 @@ var Textarea = function Textarea(_ref) {
65
66
  disabled: disabled,
66
67
  required: required,
67
68
  wrapperRef: wrapperRef,
69
+ textareaExpandable: expandable,
68
70
  textarea: true
69
71
  }, rest), {}, {
70
72
  children: /*#__PURE__*/jsx("textarea", {
@@ -83,7 +85,9 @@ var Textarea = function Textarea(_ref) {
83
85
  autoFocus: autoFocus,
84
86
  value: actualValue,
85
87
  onChange: handleChange,
86
- onKeyDown: handleEnter(onEnterPressed)
88
+ onKeyDown: handleEnter(onEnterPressed, {
89
+ preventDefault: !!onEnterPressed
90
+ })
87
91
  })
88
92
  }));
89
93
  };
@@ -3,7 +3,6 @@
3
3
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
4
4
  import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
5
5
  import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
6
- import { FloatingPortal } from '@floating-ui/react';
7
6
  import { Icon, CoreIcons } from '@react-fabric/core';
8
7
  import { isString } from '@react-fabric/utilities';
9
8
  import classNames from 'classnames';
@@ -13,11 +12,10 @@ import { ErrorIcon } from './ErrorIcon.js';
13
12
  import classes from './Field.module.css';
14
13
  import { FieldWrapper } from './FieldWrapper.js';
15
14
 
16
- var _excluded = ["invalid", "error", "allowClear", "showClear", "decorateStart", "decorateEnd", "children", "onClear", "noOutline", "noBorder", "textarea", "data-inner", "data-open", "floatingExpand", "wrapperRef", "width"];
15
+ var _excluded = ["invalid", "error", "allowClear", "showClear", "decorateStart", "decorateEnd", "children", "onClear", "noOutline", "noBorder", "textarea", "textareaExpandable", "data-inner", "data-open", "floatingExpand", "wrapperRef", "width"];
17
16
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
18
17
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
19
18
  var InputWrapper = function InputWrapper(_ref) {
20
- var _elRef$current;
21
19
  var invalid = _ref.invalid,
22
20
  error = _ref.error,
23
21
  allowClear = _ref.allowClear,
@@ -30,6 +28,8 @@ var InputWrapper = function InputWrapper(_ref) {
30
28
  noBorder = _ref.noBorder,
31
29
  _ref$textarea = _ref.textarea,
32
30
  textarea = _ref$textarea === void 0 ? false : _ref$textarea,
31
+ _ref$textareaExpandab = _ref.textareaExpandable,
32
+ textareaExpandable = _ref$textareaExpandab === void 0 ? false : _ref$textareaExpandab,
33
33
  isInner = _ref["data-inner"];
34
34
  _ref["data-open"];
35
35
  var floatingExpand = _ref.floatingExpand,
@@ -69,7 +69,7 @@ var InputWrapper = function InputWrapper(_ref) {
69
69
  ref: wrapperRef,
70
70
  className: classNames(classes.inputWrapper, invalid && classes.invalidWrapper, !noOutline && !noBorder && "bg-[var(--fabric-input)] outline overflow-hidden", "flex flex-nowrap items-center", textarea ? "rounded-capped group" : "rounded", isExpanded ? "fixed inset-4 z-[99]" : floatingExpand ? "absolute inset-x-0" : "relative", !noOutline && "after:absolute after:bottom-0 after:h-px after:bg-primary-500 after:mx-auto"),
71
71
  onKeyDown: function onKeyDown(e) {
72
- return e.key === "Escape" && setExpanded(false);
72
+ return e.key === "Escape" && isExpanded && (setExpanded(false), e.stopPropagation());
73
73
  },
74
74
  children: [decorateStart && /*#__PURE__*/jsx("div", {
75
75
  onClickCapture: doFocus,
@@ -86,7 +86,7 @@ var InputWrapper = function InputWrapper(_ref) {
86
86
  onClickCapture: doFocus,
87
87
  className: classNames(classes.decorate, "text-muted leading-none flex-content", isString(decorateEnd) && "px-1"),
88
88
  children: decorateEnd
89
- }), textarea && /*#__PURE__*/jsx(Icon, {
89
+ }), textareaExpandable && /*#__PURE__*/jsx(Icon, {
90
90
  onClick: function onClick() {
91
91
  return setExpanded(!isExpanded);
92
92
  },
@@ -95,17 +95,14 @@ var InputWrapper = function InputWrapper(_ref) {
95
95
  })]
96
96
  });
97
97
  return /*#__PURE__*/jsx(Wrapper, _objectSpread(_objectSpread({}, wrapperProps), {}, {
98
- children: /*#__PURE__*/jsxs("div", {
98
+ children: /*#__PURE__*/jsx("div", {
99
99
  ref: elRef,
100
100
  className: "flex-1 relative min-h-8",
101
101
  style: {
102
102
  width: width,
103
103
  flexBasis: width
104
104
  },
105
- children: [!isExpanded && el, isExpanded && /*#__PURE__*/jsx(FloatingPortal, {
106
- root: (_elRef$current = elRef.current) === null || _elRef$current === void 0 ? void 0 : _elRef$current.closest(".theme-base"),
107
- children: el
108
- })]
105
+ children: el
109
106
  })
110
107
  }));
111
108
  };
@@ -4,7 +4,7 @@ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
4
4
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
5
5
  import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
6
6
  import { useDebounce } from '@react-fabric/core';
7
- import { matchString, isString, dedupe, groupBy, isArray, EMPTY_ARRAY } from '@react-fabric/utilities';
7
+ import { matchString, isString, dedupe, compareValues, groupBy, isArray, EMPTY_ARRAY } from '@react-fabric/utilities';
8
8
  import { useMemo, useDeferredValue, useRef, useCallback, useReducer, useEffect } from 'react';
9
9
  import { getSelectedValue, makeOption } from './helpers.js';
10
10
 
@@ -133,6 +133,7 @@ var useSelect = function useSelect(_ref) {
133
133
  if (autoComplete && action.query !== undefined) {
134
134
  optionList = dedupe([action.query].concat(_toConsumableArray(optionList)));
135
135
  }
136
+ optionList = optionList.sort(compareValues("asc", labelProperty));
136
137
  var grouped = groupBy(optionList, groupProperty, "");
137
138
  if (action.open) _newState.open = true;
138
139
  _newState.items = [];
@@ -201,7 +202,7 @@ var useSelect = function useSelect(_ref) {
201
202
  });
202
203
  dispatch({
203
204
  type: "setValue",
204
- value: (_ref4 = hasValue !== null && hasValue !== void 0 ? hasValue : newOption) !== null && _ref4 !== void 0 ? _ref4 : ""
205
+ value: (_ref4 = hasValue !== null && hasValue !== void 0 ? hasValue : newOption) !== null && _ref4 !== void 0 ? _ref4 : deferred
205
206
  });
206
207
  }
207
208
  if (multiple) {
@@ -216,7 +217,7 @@ var useSelect = function useSelect(_ref) {
216
217
  if (!hasValue && newOption) {
217
218
  optionsRef.current.push(newOption);
218
219
  }
219
- return (_ref5 = hasValue !== null && hasValue !== void 0 ? hasValue : newOption) !== null && _ref5 !== void 0 ? _ref5 : "";
220
+ return (_ref5 = hasValue !== null && hasValue !== void 0 ? hasValue : newOption) !== null && _ref5 !== void 0 ? _ref5 : item;
220
221
  });
221
222
  optionsRef.current = [].concat(_toConsumableArray(optionsRef.current), _toConsumableArray(options !== null && options !== void 0 ? options : []));
222
223
  dispatch({
@@ -13,5 +13,9 @@ export interface TextareaProps extends InputProps, RefProp<HTMLTextAreaElement>
13
13
  * increment rows on value change
14
14
  */
15
15
  variableRows?: boolean;
16
+ /**
17
+ * expandable textarea
18
+ */
19
+ expandable?: boolean;
16
20
  }
17
- export declare const Textarea: ({ ref, value, name, invalid, readOnly, disabled, required, placeholder, autoFocus, rows, maxRows, variableRows, onChange, onEnterPressed, ...rest }: TextareaProps) => import("react/jsx-runtime").JSX.Element;
21
+ export declare const Textarea: ({ ref, value, name, invalid, readOnly, disabled, required, placeholder, autoFocus, rows, maxRows, variableRows, expandable, onChange, onEnterPressed, ...rest }: TextareaProps) => import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- export declare const InputWrapper: ({ invalid, error, allowClear, showClear, decorateStart, decorateEnd, children, onClear, noOutline, noBorder, textarea, "data-inner": isInner, "data-open": isOpen, floatingExpand, wrapperRef, width, ...rest }: KeyValue) => import("react/jsx-runtime").JSX.Element;
1
+ export declare const InputWrapper: ({ invalid, error, allowClear, showClear, decorateStart, decorateEnd, children, onClear, noOutline, noBorder, textarea, textareaExpandable, "data-inner": isInner, "data-open": isOpen, floatingExpand, wrapperRef, width, ...rest }: KeyValue) => import("react/jsx-runtime").JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-fabric/form",
3
- "version": "1.0.0-beta.19",
3
+ "version": "1.0.0-beta.21",
4
4
  "description": "RUF: Form package",
5
5
  "author": "Adarsh Pastakia <adarshpastakia@outlook.com>",
6
6
  "license": "MIT",
@@ -39,8 +39,8 @@
39
39
  "@dnd-kit/utilities": "^3.2.2",
40
40
  "@floating-ui/react": "^0.26.24",
41
41
  "@hookform/resolvers": "^3.9.0",
42
- "@react-fabric/core": "^1.0.0-beta.19",
43
- "@react-fabric/utilities": "^1.0.0-beta.19",
42
+ "@react-fabric/core": "^1.0.0-beta.21",
43
+ "@react-fabric/utilities": "^1.0.0-beta.21",
44
44
  "classnames": "^2.5.1",
45
45
  "color": "^4.2.3",
46
46
  "react-color": "^2.19.3",
@@ -60,5 +60,5 @@
60
60
  "node": ">=18.12.0",
61
61
  "npm": ">=8.19.0"
62
62
  },
63
- "gitHead": "1757660f7f30590d1bf5c7f2bd3526f6052dccd5"
63
+ "gitHead": "31c3d5c19bce7df519a62bd43efd1c9e6341be04"
64
64
  }
@@ -21,7 +21,19 @@
21
21
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  */
23
23
 
24
- import { CoreIcons, Dropdown, Icon } from "@react-fabric/core";
24
+ import {
25
+ arrow,
26
+ autoUpdate,
27
+ flip,
28
+ FloatingArrow,
29
+ offset,
30
+ shift,
31
+ useClick,
32
+ useDismiss,
33
+ useFloating,
34
+ useInteractions,
35
+ } from "@floating-ui/react";
36
+ import { CoreIcons, Icon } from "@react-fabric/core";
25
37
  import { type RefProp } from "@react-fabric/core/dist/types/types";
26
38
  import { isString } from "@react-fabric/utilities";
27
39
  import classNames from "classnames";
@@ -30,6 +42,7 @@ import {
30
42
  useCallback,
31
43
  useDeferredValue,
32
44
  useEffect,
45
+ useRef,
33
46
  useState,
34
47
  } from "react";
35
48
  import { type InputProps } from "../types";
@@ -74,6 +87,38 @@ export const ColorInput = ({
74
87
  [onChange],
75
88
  );
76
89
 
90
+ const arrowRef = useRef(null);
91
+ const [isOpen, setIsOpen] = useState(false);
92
+ const { refs, floatingStyles, context } = useFloating({
93
+ open: isOpen,
94
+ onOpenChange: (open, _, reason) => {
95
+ if (reason === "reference-press") return;
96
+ setIsOpen(open);
97
+ },
98
+ strategy: "fixed",
99
+ placement: "bottom",
100
+ whileElementsMounted: autoUpdate,
101
+ middleware: [
102
+ shift({ padding: 8 }),
103
+ flip(),
104
+ offset(9),
105
+ arrow({
106
+ element: arrowRef,
107
+ }),
108
+ ],
109
+ });
110
+ const click = useClick(context, {
111
+ enabled: !disabled,
112
+ });
113
+ const dismiss = useDismiss(context, {
114
+ referencePress: true,
115
+ });
116
+
117
+ const { getReferenceProps, getFloatingProps } = useInteractions([
118
+ dismiss,
119
+ click,
120
+ ]);
121
+
77
122
  return (
78
123
  <div
79
124
  className={classNames(
@@ -92,36 +137,58 @@ export const ColorInput = ({
92
137
  {decorateStart}
93
138
  </div>
94
139
  )}
95
- <Dropdown showArrow disabled={disabled}>
96
- <button data-ref="button" className="flex-1 flex items-center">
97
- <div
98
- role="none"
99
- className="h-[1.5em] min-w-[1.5em] flex-1 flex items-center justify-center self-stretch cursor-pointer m-[0.25em] rounded outline outline-tint-100"
100
- style={{
101
- backgroundColor: actualValue,
102
- opacity: disabled ? 0.65 : 1,
103
- pointerEvents: disabled ? "none" : undefined,
104
- }}
105
- onClick={(e) =>
106
- (e.currentTarget.nextElementSibling as HTMLElement)?.focus()
107
- }
108
- >
109
- {!actualValue && (
110
- <Icon
111
- size="md"
112
- className="text-muted"
113
- icon={CoreIcons.colorSwatch}
114
- />
115
- )}
116
- </div>
117
- </button>
118
- <ColorPicker
119
- {...rest}
120
- onChange={handleChange}
121
- defaultColor={defaultColor}
122
- value={actualValue}
123
- />
124
- </Dropdown>
140
+ <button
141
+ data-ref="button"
142
+ className="flex-1 flex items-center"
143
+ ref={refs.setReference}
144
+ {...getReferenceProps()}
145
+ data-inner-clickable="true"
146
+ data-dropdown-open={isOpen ? true : undefined}
147
+ >
148
+ <div
149
+ role="none"
150
+ className="h-[1.5em] min-w-[1.5em] flex-1 flex items-center justify-center self-stretch cursor-pointer m-[0.25em] rounded outline outline-tint-100"
151
+ style={{
152
+ backgroundColor: actualValue,
153
+ opacity: disabled ? 0.65 : 1,
154
+ pointerEvents: disabled ? "none" : undefined,
155
+ }}
156
+ >
157
+ {!actualValue && (
158
+ <Icon
159
+ size="md"
160
+ className="text-muted"
161
+ icon={CoreIcons.colorSwatch}
162
+ />
163
+ )}
164
+ </div>
165
+ </button>
166
+ {isOpen && (
167
+ <div
168
+ ref={refs.setFloating}
169
+ style={{
170
+ zIndex: "var(--z-popover)",
171
+ ...floatingStyles,
172
+ }}
173
+ data-testid="dropdown-body"
174
+ {...getFloatingProps({
175
+ onClick: (e) => e.stopPropagation(),
176
+ })}
177
+ >
178
+ <ColorPicker
179
+ {...rest}
180
+ onChange={handleChange}
181
+ defaultColor={defaultColor}
182
+ value={actualValue}
183
+ />
184
+ <FloatingArrow
185
+ ref={arrowRef}
186
+ context={context}
187
+ strokeWidth={0.5}
188
+ className="fill-base stroke-muted"
189
+ />
190
+ </div>
191
+ )}
125
192
  {!disabled && showPicker && (
126
193
  <Icon
127
194
  icon={CoreIcons.colorPicker}
@@ -54,7 +54,9 @@ export const HiddenInput = ({
54
54
  name,
55
55
  }: Props) => {
56
56
  useEffect(() => {
57
- onChange?.(hiddenValue);
57
+ setTimeout(() => {
58
+ onChange?.(hiddenValue);
59
+ }, 50);
58
60
  }, [hiddenValue]);
59
61
  return (
60
62
  <Fragment>
@@ -104,7 +104,7 @@ export const Input = ({
104
104
  type={type}
105
105
  ref={ref}
106
106
  autoComplete="off"
107
- {...{ autoFocus }}
107
+ autoFocus={autoFocus}
108
108
  value={actualValue}
109
109
  onChange={handleChange}
110
110
  onKeyDown={handleEnterPressed}
@@ -116,7 +116,7 @@ export const Number = ({
116
116
  step={step}
117
117
  ref={ref}
118
118
  autoComplete="off"
119
- {...{ autoFocus }}
119
+ autoFocus={autoFocus}
120
120
  value={actualValue}
121
121
  onChange={handleChange}
122
122
  onKeyDown={handleEnterPressed}
@@ -129,7 +129,7 @@ export const Password = ({
129
129
  type={show ? "text" : "password"}
130
130
  ref={ref}
131
131
  autoComplete="off"
132
- {...{ autoFocus }}
132
+ autoFocus={autoFocus}
133
133
  value={actualValue}
134
134
  onChange={handleChange}
135
135
  onKeyDown={handleEnterPressed}
@@ -150,7 +150,7 @@ export const Search = ({
150
150
  type="search"
151
151
  ref={ref}
152
152
  autoComplete="off"
153
- {...{ autoFocus }}
153
+ autoFocus={autoFocus}
154
154
  value={actualValue}
155
155
  onChange={handleChange}
156
156
  onKeyDown={handleEnterPressed}
@@ -49,6 +49,10 @@ export interface TextareaProps
49
49
  * increment rows on value change
50
50
  */
51
51
  variableRows?: boolean;
52
+ /**
53
+ * expandable textarea
54
+ */
55
+ expandable?: boolean;
52
56
  }
53
57
 
54
58
  export const Textarea = ({
@@ -64,6 +68,7 @@ export const Textarea = ({
64
68
  rows = 5,
65
69
  maxRows = 12,
66
70
  variableRows,
71
+ expandable,
67
72
  onChange,
68
73
  onEnterPressed,
69
74
  ...rest
@@ -104,6 +109,7 @@ export const Textarea = ({
104
109
  disabled={disabled}
105
110
  required={required}
106
111
  wrapperRef={wrapperRef}
112
+ textareaExpandable={expandable}
107
113
  textarea
108
114
  {...rest}
109
115
  >
@@ -120,10 +126,12 @@ export const Textarea = ({
120
126
  name={name}
121
127
  ref={ref}
122
128
  autoComplete="off"
123
- {...{ autoFocus }}
129
+ autoFocus={autoFocus}
124
130
  value={actualValue}
125
131
  onChange={handleChange}
126
- onKeyDown={handleEnter(onEnterPressed)}
132
+ onKeyDown={handleEnter(onEnterPressed, {
133
+ preventDefault: !!onEnterPressed,
134
+ })}
127
135
  />
128
136
  </InputWrapper>
129
137
  );
@@ -21,7 +21,6 @@
21
21
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  */
23
23
 
24
- import { FloatingPortal } from "@floating-ui/react";
25
24
  import { CoreIcons, Icon } from "@react-fabric/core";
26
25
  import { isString } from "@react-fabric/utilities";
27
26
  import classNames from "classnames";
@@ -50,6 +49,7 @@ export const InputWrapper = ({
50
49
  noOutline,
51
50
  noBorder,
52
51
  textarea = false,
52
+ textareaExpandable = false,
53
53
  "data-inner": isInner,
54
54
  "data-open": isOpen,
55
55
  // expand autocomplete
@@ -117,7 +117,11 @@ export const InputWrapper = ({
117
117
  !noOutline &&
118
118
  "after:absolute after:bottom-0 after:h-px after:bg-primary-500 after:mx-auto",
119
119
  )}
120
- onKeyDown={(e) => e.key === "Escape" && setExpanded(false)}
120
+ onKeyDown={(e) =>
121
+ e.key === "Escape" &&
122
+ isExpanded &&
123
+ (setExpanded(false), e.stopPropagation())
124
+ }
121
125
  >
122
126
  {decorateStart && (
123
127
  <div
@@ -156,7 +160,7 @@ export const InputWrapper = ({
156
160
  {decorateEnd}
157
161
  </div>
158
162
  )}
159
- {textarea && (
163
+ {textareaExpandable && (
160
164
  <Icon
161
165
  onClick={() => setExpanded(!isExpanded)}
162
166
  icon={isExpanded ? CoreIcons.arrowCollapse : CoreIcons.arrowExpand}
@@ -173,14 +177,7 @@ export const InputWrapper = ({
173
177
  className="flex-1 relative min-h-8"
174
178
  style={{ width, flexBasis: width }}
175
179
  >
176
- {!isExpanded && el}
177
- {isExpanded && (
178
- <FloatingPortal
179
- root={elRef.current?.closest<HTMLElement>(".theme-base")}
180
- >
181
- {el}
182
- </FloatingPortal>
183
- )}
180
+ {el}
184
181
  </div>
185
182
  </Wrapper>
186
183
  );
@@ -23,6 +23,7 @@
23
23
 
24
24
  import { useDebounce } from "@react-fabric/core";
25
25
  import {
26
+ compareValues,
26
27
  dedupe,
27
28
  EMPTY_ARRAY,
28
29
  groupBy,
@@ -223,6 +224,7 @@ export const useSelect = ({
223
224
  if (autoComplete && action.query !== undefined) {
224
225
  optionList = dedupe([action.query, ...optionList]);
225
226
  }
227
+ optionList = optionList.sort(compareValues("asc", labelProperty));
226
228
  const grouped = groupBy(optionList, groupProperty, "");
227
229
  if (action.open) newState.open = true;
228
230
  newState.items = [];
@@ -283,7 +285,7 @@ export const useSelect = ({
283
285
  dispatch({ type: "options", options: optionsRef.current });
284
286
  dispatch({
285
287
  type: "setValue",
286
- value: hasValue ?? newOption ?? "",
288
+ value: hasValue ?? newOption ?? deferred,
287
289
  });
288
290
  }
289
291
  if (multiple) {
@@ -300,7 +302,7 @@ export const useSelect = ({
300
302
  if (!hasValue && newOption) {
301
303
  optionsRef.current.push(newOption);
302
304
  }
303
- return hasValue ?? newOption ?? "";
305
+ return hasValue ?? newOption ?? item;
304
306
  },
305
307
  );
306
308
  optionsRef.current = [...optionsRef.current, ...(options ?? [])];