rsuite 5.9.0 → 5.12.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.
Files changed (40) hide show
  1. package/ButtonToolbar/styles/index.less +1 -1
  2. package/CHANGELOG.md +24 -0
  3. package/README.md +4 -0
  4. package/cjs/DateRangePicker/DateRangePicker.d.ts +2 -0
  5. package/cjs/DateRangePicker/DateRangePicker.js +4 -2
  6. package/cjs/Form/Form.d.ts +1 -1
  7. package/cjs/Form/Form.js +35 -11
  8. package/cjs/Form/FormContext.d.ts +18 -11
  9. package/cjs/Form/useSchemaModel.d.ts +9 -0
  10. package/cjs/Form/useSchemaModel.js +46 -0
  11. package/cjs/FormControl/FormControl.d.ts +5 -0
  12. package/cjs/FormControl/FormControl.js +19 -2
  13. package/cjs/FormControl/useRegisterModel.d.ts +4 -0
  14. package/cjs/FormControl/useRegisterModel.js +20 -0
  15. package/cjs/Menu/Menubar.js +10 -3
  16. package/cjs/utils/dom.d.ts +1 -1
  17. package/dist/rsuite-rtl.css +1 -1
  18. package/dist/rsuite-rtl.min.css +1 -1
  19. package/dist/rsuite-rtl.min.css.map +1 -1
  20. package/dist/rsuite.css +1 -1
  21. package/dist/rsuite.js +26 -4
  22. package/dist/rsuite.js.map +1 -1
  23. package/dist/rsuite.min.css +1 -1
  24. package/dist/rsuite.min.css.map +1 -1
  25. package/dist/rsuite.min.js +1 -1
  26. package/dist/rsuite.min.js.map +1 -1
  27. package/esm/DateRangePicker/DateRangePicker.d.ts +2 -0
  28. package/esm/DateRangePicker/DateRangePicker.js +4 -2
  29. package/esm/Form/Form.d.ts +1 -1
  30. package/esm/Form/Form.js +33 -11
  31. package/esm/Form/FormContext.d.ts +18 -11
  32. package/esm/Form/useSchemaModel.d.ts +9 -0
  33. package/esm/Form/useSchemaModel.js +39 -0
  34. package/esm/FormControl/FormControl.d.ts +5 -0
  35. package/esm/FormControl/FormControl.js +20 -6
  36. package/esm/FormControl/useRegisterModel.d.ts +4 -0
  37. package/esm/FormControl/useRegisterModel.js +14 -0
  38. package/esm/Menu/Menubar.js +9 -3
  39. package/esm/utils/dom.d.ts +1 -1
  40. package/package.json +1 -1
@@ -35,6 +35,8 @@ export interface DateRangePickerProps extends PickerBaseProps, FormControlBasePr
35
35
  onClean?: (event: React.MouseEvent) => void;
36
36
  /** Custom render value */
37
37
  renderValue?: (value: DateRange, format: string) => React.ReactNode;
38
+ /** Custom render for calendar title */
39
+ renderTitle?: (date: Date) => React.ReactNode;
38
40
  }
39
41
  export interface DateRangePicker extends PickerComponent<DateRangePickerProps> {
40
42
  /** Allow the maximum number of days specified, other dates are disabled */
@@ -67,7 +67,8 @@ var DateRangePicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
67
67
  onOk = props.onOk,
68
68
  onOpen = props.onOpen,
69
69
  onSelect = props.onSelect,
70
- rest = _objectWithoutPropertiesLoose(props, ["as", "classPrefix", "className", "appearance", "cleanable", "character", "defaultCalendarValue", "defaultValue", "disabled", "disabledDate", "format", "hoverRange", "isoWeek", "limitEndYear", "locale", "menuClassName", "menuStyle", "oneTap", "placeholder", "placement", "ranges", "renderValue", "showOneCalendar", "showWeekNumbers", "showMeridian", "style", "toggleAs", "caretAs", "value", "onChange", "onClean", "onClose", "onEnter", "onEntered", "onExited", "onOk", "onOpen", "onSelect"]);
70
+ renderTitle = props.renderTitle,
71
+ rest = _objectWithoutPropertiesLoose(props, ["as", "classPrefix", "className", "appearance", "cleanable", "character", "defaultCalendarValue", "defaultValue", "disabled", "disabledDate", "format", "hoverRange", "isoWeek", "limitEndYear", "locale", "menuClassName", "menuStyle", "oneTap", "placeholder", "placement", "ranges", "renderValue", "showOneCalendar", "showWeekNumbers", "showMeridian", "style", "toggleAs", "caretAs", "value", "onChange", "onClean", "onClose", "onEnter", "onEntered", "onExited", "onOk", "onOpen", "onSelect", "renderTitle"]);
71
72
 
72
73
  var _useClassNames = useClassNames(classPrefix),
73
74
  merge = _useClassNames.merge,
@@ -535,7 +536,8 @@ var DateRangePicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
535
536
  onChangeCalendarTime: handleChangeCalendarTime,
536
537
  onMouseMove: handleMouseMove,
537
538
  onSelect: handleSelectDate,
538
- onToggleMeridian: handleToggleMeridian
539
+ onToggleMeridian: handleToggleMeridian,
540
+ renderTitle: renderTitle
539
541
  };
540
542
  return /*#__PURE__*/React.createElement(PickerOverlay, {
541
543
  className: classes,
@@ -33,7 +33,7 @@ export interface FormProps<T = Record<string, any>, errorMsgType = any, E = {
33
33
  /** The error message comes from context */
34
34
  errorFromContext?: boolean;
35
35
  /** Callback fired when data changing */
36
- onChange?: (formValue: T, event: React.SyntheticEvent) => void;
36
+ onChange?: (formValue: T, event?: React.SyntheticEvent) => void;
37
37
  /** Callback fired when error checking */
38
38
  onError?: (formError: E) => void;
39
39
  /** Callback fired when data cheking */
package/esm/Form/Form.js CHANGED
@@ -12,6 +12,7 @@ import FormErrorMessage from '../FormErrorMessage';
12
12
  import FormGroup from '../FormGroup';
13
13
  import FormHelpText from '../FormHelpText';
14
14
  import { useFormClassNames } from './useFormClassNames';
15
+ import useSchemaModel from './useSchemaModel';
15
16
  var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
16
17
  var _props$checkTrigger = props.checkTrigger,
17
18
  checkTrigger = _props$checkTrigger === void 0 ? 'change' : _props$checkTrigger,
@@ -27,7 +28,7 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
27
28
  _props$layout = props.layout,
28
29
  layout = _props$layout === void 0 ? 'vertical' : _props$layout,
29
30
  _props$model = props.model,
30
- model = _props$model === void 0 ? SchemaModel({}) : _props$model,
31
+ formModel = _props$model === void 0 ? SchemaModel({}) : _props$model,
31
32
  readOnly = props.readOnly,
32
33
  plaintext = props.plaintext,
33
34
  className = props.className,
@@ -39,6 +40,11 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
39
40
  onChange = props.onChange,
40
41
  rest = _objectWithoutPropertiesLoose(props, ["checkTrigger", "classPrefix", "errorFromContext", "formDefaultValue", "formValue", "formError", "fluid", "layout", "model", "readOnly", "plaintext", "className", "children", "disabled", "onSubmit", "onCheck", "onError", "onChange"]);
41
42
 
43
+ var _useSchemaModel = useSchemaModel(formModel),
44
+ getCombinedModel = _useSchemaModel.getCombinedModel,
45
+ pushFieldRule = _useSchemaModel.pushFieldRule,
46
+ removeFieldRule = _useSchemaModel.removeFieldRule;
47
+
42
48
  var classes = useFormClassNames({
43
49
  classPrefix: classPrefix,
44
50
  className: className,
@@ -73,6 +79,7 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
73
79
  var formValue = getFormValue() || {};
74
80
  var formError = {};
75
81
  var errorCount = 0;
82
+ var model = getCombinedModel();
76
83
  Object.keys(model.spec).forEach(function (key) {
77
84
  var checkResult = model.checkForField(key, formValue);
78
85
 
@@ -91,7 +98,7 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
91
98
  }
92
99
 
93
100
  return true;
94
- }, [onCheck, onError, model, getFormValue]);
101
+ }, [getFormValue, getCombinedModel, onCheck, onError]);
95
102
  /**
96
103
  * Check the data field
97
104
  * @param fieldName
@@ -102,6 +109,7 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
102
109
  var _extends2;
103
110
 
104
111
  var formValue = getFormValue() || {};
112
+ var model = getCombinedModel();
105
113
  var checkResult = model.checkForField(fieldName, formValue);
106
114
 
107
115
  var formError = _extends({}, getFormError(), (_extends2 = {}, _extends2[fieldName] = (checkResult === null || checkResult === void 0 ? void 0 : checkResult.errorMessage) || checkResult, _extends2));
@@ -115,7 +123,7 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
115
123
  }
116
124
 
117
125
  return !checkResult.hasError;
118
- }, [model, getFormValue, getFormError, onCheck, onError]);
126
+ }, [getFormValue, getCombinedModel, getFormError, onCheck, onError]);
119
127
  /**
120
128
  * Check form data asynchronously and return a Promise
121
129
  */
@@ -124,6 +132,7 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
124
132
  var formValue = getFormValue() || {};
125
133
  var promises = [];
126
134
  var keys = [];
135
+ var model = getCombinedModel();
127
136
  Object.keys(model.spec).forEach(function (key) {
128
137
  keys.push(key);
129
138
  promises.push(model.checkForFieldAsync(key, formValue));
@@ -151,7 +160,7 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
151
160
  formError: formError
152
161
  };
153
162
  });
154
- }, [model, getFormValue, onCheck, onError]);
163
+ }, [getFormValue, getCombinedModel, onCheck, onError]);
155
164
  /**
156
165
  * Asynchronously check form fields and return Promise
157
166
  * @param fieldName
@@ -159,6 +168,7 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
159
168
 
160
169
  var checkForFieldAsync = useCallback(function (fieldName) {
161
170
  var formValue = getFormValue() || {};
171
+ var model = getCombinedModel();
162
172
  return model.checkForFieldAsync(fieldName, formValue).then(function (checkResult) {
163
173
  var _extends3;
164
174
 
@@ -173,7 +183,7 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
173
183
 
174
184
  return checkResult;
175
185
  });
176
- }, [model, getFormValue, getFormError, onCheck, onError]);
186
+ }, [getFormValue, getCombinedModel, getFormError, onCheck, onError]);
177
187
  var cleanErrors = useCallback(function () {
178
188
  setFormError({});
179
189
  }, []);
@@ -199,6 +209,16 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
199
209
  resetErrors: resetErrors
200
210
  };
201
211
  });
212
+ var removeFieldError = useCallback(function (name) {
213
+ var formError = omit(getFormError(), [name]);
214
+ setFormError(formError);
215
+ onCheck === null || onCheck === void 0 ? void 0 : onCheck(formError);
216
+ }, [getFormError, onCheck]);
217
+ var removeFieldValue = useCallback(function (name) {
218
+ var formValue = omit(getFormValue(), [name]);
219
+ setFormValue(formValue);
220
+ onChange === null || onChange === void 0 ? void 0 : onChange(formValue);
221
+ }, [getFormValue, onChange]);
202
222
  var handleSubmit = useCallback(function (event) {
203
223
  if (disabled || readOnly || plaintext) {
204
224
  return;
@@ -219,10 +239,8 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
219
239
  onCheck === null || onCheck === void 0 ? void 0 : onCheck(formError);
220
240
  }, [onError, onCheck, getFormError]);
221
241
  var handleFieldSuccess = useCallback(function (name) {
222
- var formError = omit(getFormError(), [name]);
223
- setFormError(formError);
224
- onCheck === null || onCheck === void 0 ? void 0 : onCheck(formError);
225
- }, [onCheck, getFormError]);
242
+ removeFieldError(name);
243
+ }, [removeFieldError]);
226
244
  var handleFieldChange = useCallback(function (name, value, event) {
227
245
  var _extends5;
228
246
 
@@ -236,7 +254,7 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
236
254
  var rootRef = useRef(null);
237
255
  var formContextValue = useMemo(function () {
238
256
  return {
239
- model: model,
257
+ getCombinedModel: getCombinedModel,
240
258
  checkTrigger: checkTrigger,
241
259
  formDefaultValue: formDefaultValue,
242
260
  errorFromContext: errorFromContext,
@@ -244,11 +262,15 @@ var Form = /*#__PURE__*/React.forwardRef(function (props, ref) {
244
262
  plaintext: plaintext,
245
263
  disabled: disabled,
246
264
  formError: getFormError(),
265
+ removeFieldValue: removeFieldValue,
266
+ removeFieldError: removeFieldError,
267
+ pushFieldRule: pushFieldRule,
268
+ removeFieldRule: removeFieldRule,
247
269
  onFieldChange: handleFieldChange,
248
270
  onFieldError: handleFieldError,
249
271
  onFieldSuccess: handleFieldSuccess
250
272
  };
251
- }, [model, checkTrigger, formDefaultValue, errorFromContext, readOnly, plaintext, disabled, getFormError, handleFieldChange, handleFieldError, handleFieldSuccess]);
273
+ }, [getCombinedModel, checkTrigger, formDefaultValue, errorFromContext, readOnly, plaintext, disabled, getFormError, removeFieldValue, removeFieldError, pushFieldRule, removeFieldRule, handleFieldChange, handleFieldError, handleFieldSuccess]);
252
274
  return /*#__PURE__*/React.createElement("form", _extends({}, rest, {
253
275
  ref: rootRef,
254
276
  onSubmit: handleSubmit,
@@ -1,24 +1,31 @@
1
1
  import React from 'react';
2
- import { Schema } from 'schema-typed';
3
2
  import { TypeAttributes } from '../@types/common';
4
- export interface FormContextValue<T = Record<string, any>, errorMsgType = any, E = {
3
+ import type { Schema } from 'schema-typed';
4
+ import type { FieldRuleType } from './useSchemaModel';
5
+ interface TrulyFormContextValue<T = Record<string, any>, errorMsgType = any, E = {
5
6
  [P in keyof T]?: errorMsgType;
6
7
  }> {
7
- model?: Schema;
8
+ getCombinedModel: () => Schema;
9
+ formError: E;
10
+ removeFieldValue: (name: string) => void;
11
+ removeFieldError: (name: string) => void;
12
+ pushFieldRule: (name: string, fieldRule: FieldRuleType) => void;
13
+ removeFieldRule: (name: string) => void;
14
+ onFieldChange: (name: string, value: any, event: React.SyntheticEvent) => void;
15
+ onFieldError: (name: string, errorMessage: string) => void;
16
+ onFieldSuccess: (name: string) => void;
17
+ }
18
+ declare type ExternalPropsContextValue<T> = {
8
19
  checkTrigger?: TypeAttributes.CheckTrigger;
9
20
  formDefaultValue?: T;
10
21
  errorFromContext?: boolean;
11
22
  readOnly?: boolean;
12
23
  plaintext?: boolean;
13
24
  disabled?: boolean;
14
- formError?: E;
15
- onFieldChange?: (name: string, value: any, event: React.SyntheticEvent) => void;
16
- onFieldError?: (name: string, errorMessage: string) => void;
17
- onFieldSuccess?: (name: string) => void;
18
- }
19
- export declare const FormContext: React.Context<FormContextValue<Record<string, any>, any, {
20
- [x: string]: any;
21
- }>>;
25
+ };
26
+ declare type InitialContextType = Partial<Record<keyof TrulyFormContextValue, undefined>>;
27
+ export declare type FormContextValue<T = Record<string, any>, errorMsgType = any> = (TrulyFormContextValue<T, errorMsgType> | InitialContextType) & ExternalPropsContextValue<T>;
28
+ export declare const FormContext: React.Context<FormContextValue<Record<string, any>, any>>;
22
29
  export declare const FormValueContext: React.Context<Record<string, any> | undefined>;
23
30
  export declare const FormPlaintextContext: React.Context<boolean>;
24
31
  export default FormContext;
@@ -0,0 +1,9 @@
1
+ import type { MutableRefObject } from 'react';
2
+ import type { CheckType, Schema } from 'schema-typed';
3
+ export declare type FieldRuleType = MutableRefObject<CheckType<unknown, any> | undefined>;
4
+ declare function useSchemaModel(formModel: Schema): {
5
+ getCombinedModel: () => Schema<any, string>;
6
+ pushFieldRule: (name: string, fieldRule: FieldRuleType) => void;
7
+ removeFieldRule: (name: string) => void;
8
+ };
9
+ export default useSchemaModel;
@@ -0,0 +1,39 @@
1
+ import { SchemaModel } from 'schema-typed';
2
+ import { useRef, useCallback } from 'react';
3
+
4
+ function useSchemaModel(formModel) {
5
+ var subRulesRef = useRef([]);
6
+ var pushFieldRule = useCallback(function (name, fieldRule) {
7
+ subRulesRef.current.push({
8
+ name: name,
9
+ fieldRule: fieldRule
10
+ });
11
+ }, []);
12
+ var removeFieldRule = useCallback(function (name) {
13
+ var index = subRulesRef.current.findIndex(function (v) {
14
+ return v.name === name;
15
+ });
16
+ subRulesRef.current.splice(index, 1);
17
+ }, []);
18
+ var getCombinedModel = useCallback(function () {
19
+ var realSubRules = subRulesRef.current.filter(function (v) {
20
+ return Boolean(v.fieldRule.current);
21
+ });
22
+ return SchemaModel.combine(formModel, SchemaModel(realSubRules.map(function (_ref) {
23
+ var _ref2;
24
+
25
+ var name = _ref.name,
26
+ fieldRule = _ref.fieldRule;
27
+ return _ref2 = {}, _ref2[name] = fieldRule.current, _ref2;
28
+ }).reduce(function (a, b) {
29
+ return Object.assign(a, b);
30
+ }, {})));
31
+ }, [formModel]);
32
+ return {
33
+ getCombinedModel: getCombinedModel,
34
+ pushFieldRule: pushFieldRule,
35
+ removeFieldRule: removeFieldRule
36
+ };
37
+ }
38
+
39
+ export default useSchemaModel;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import Input from '../Input';
3
3
  import { TypeAttributes, FormControlBaseProps, WithAsProps } from '../@types/common';
4
+ import type { CheckType } from 'schema-typed';
4
5
  /**
5
6
  * Props that FormControl passes to its accepter
6
7
  */
@@ -28,6 +29,10 @@ export interface FormControlProps<P = any, ValueType = any> extends WithAsProps,
28
29
  disabled?: boolean;
29
30
  /** Asynchronous check value */
30
31
  checkAsync?: boolean;
32
+ /** Remove field value and error message when component is unmounted */
33
+ shouldResetWithUnmount?: boolean;
34
+ /** Validation rule */
35
+ rule?: CheckType<unknown, any>;
31
36
  }
32
37
  interface FormControlComponent extends React.FC<FormControlProps> {
33
38
  <Accepter extends React.ElementType = typeof Input>(props: FormControlProps & {
@@ -12,10 +12,8 @@ import FormErrorMessage from '../FormErrorMessage';
12
12
  import { useClassNames } from '../utils';
13
13
  import FormContext, { FormValueContext } from '../Form/FormContext';
14
14
  import { FormGroupContext } from '../FormGroup/FormGroup';
15
- /**
16
- * Props that FormControl passes to its accepter
17
- */
18
-
15
+ import { useWillUnmount } from '../utils';
16
+ import useRegisterModel from './useRegisterModel';
19
17
  var FormControl = /*#__PURE__*/React.forwardRef(function (props, ref) {
20
18
  var _useContext = useContext(FormContext),
21
19
  readOnlyContext = _useContext.readOnly,
@@ -25,10 +23,14 @@ var FormControl = /*#__PURE__*/React.forwardRef(function (props, ref) {
25
23
  _useContext$formDefau = _useContext.formDefaultValue,
26
24
  formDefaultValue = _useContext$formDefau === void 0 ? {} : _useContext$formDefau,
27
25
  formError = _useContext.formError,
26
+ removeFieldValue = _useContext.removeFieldValue,
27
+ removeFieldError = _useContext.removeFieldError,
28
+ pushFieldRule = _useContext.pushFieldRule,
29
+ removeFieldRule = _useContext.removeFieldRule,
28
30
  onFieldChange = _useContext.onFieldChange,
29
31
  onFieldError = _useContext.onFieldError,
30
32
  onFieldSuccess = _useContext.onFieldSuccess,
31
- model = _useContext.model,
33
+ getCombinedModel = _useContext.getCombinedModel,
32
34
  contextCheckTrigger = _useContext.checkTrigger;
33
35
 
34
36
  var _props$as = props.as,
@@ -54,7 +56,10 @@ var FormControl = /*#__PURE__*/React.forwardRef(function (props, ref) {
54
56
  onChange = props.onChange,
55
57
  onBlur = props.onBlur,
56
58
  defaultValue = props.defaultValue,
57
- rest = _objectWithoutPropertiesLoose(props, ["as", "accepter", "classPrefix", "className", "checkAsync", "checkTrigger", "errorPlacement", "errorMessage", "name", "value", "readOnly", "plaintext", "disabled", "onChange", "onBlur", "defaultValue"]);
59
+ _props$shouldResetWit = props.shouldResetWithUnmount,
60
+ shouldResetWithUnmount = _props$shouldResetWit === void 0 ? false : _props$shouldResetWit,
61
+ rule = props.rule,
62
+ rest = _objectWithoutPropertiesLoose(props, ["as", "accepter", "classPrefix", "className", "checkAsync", "checkTrigger", "errorPlacement", "errorMessage", "name", "value", "readOnly", "plaintext", "disabled", "onChange", "onBlur", "defaultValue", "shouldResetWithUnmount", "rule"]);
58
63
 
59
64
  var _useContext2 = useContext(FormGroupContext),
60
65
  controlId = _useContext2.controlId;
@@ -63,6 +68,13 @@ var FormControl = /*#__PURE__*/React.forwardRef(function (props, ref) {
63
68
  throw new Error("\n <FormControl> must be inside a component decorated with <Form>.\n And need to update React to 16.6.0 +.\n ");
64
69
  }
65
70
 
71
+ useRegisterModel(name, pushFieldRule, removeFieldRule, rule);
72
+ useWillUnmount(function () {
73
+ if (shouldResetWithUnmount) {
74
+ removeFieldValue === null || removeFieldValue === void 0 ? void 0 : removeFieldValue(name);
75
+ removeFieldError === null || removeFieldError === void 0 ? void 0 : removeFieldError(name);
76
+ }
77
+ });
66
78
  var trigger = checkTrigger || contextCheckTrigger;
67
79
  var formValue = useContext(FormValueContext);
68
80
  var val = isUndefined(value) ? formValue === null || formValue === void 0 ? void 0 : formValue[name] : value;
@@ -103,6 +115,8 @@ var FormControl = /*#__PURE__*/React.forwardRef(function (props, ref) {
103
115
 
104
116
  var nextFormValue = _extends({}, formValue, (_extends2 = {}, _extends2[name] = value, _extends2));
105
117
 
118
+ var model = getCombinedModel();
119
+
106
120
  if (checkAsync) {
107
121
  return model === null || model === void 0 ? void 0 : model.checkForFieldAsync(name, nextFormValue).then(function (checkResult) {
108
122
  return callbackEvents(checkResult);
@@ -0,0 +1,4 @@
1
+ import type { FieldRuleType } from '../Form/useSchemaModel';
2
+ import type { CheckType } from 'schema-typed';
3
+ declare function useRegisterModel(name: string, pushFieldRule: (n: string, r: FieldRuleType) => void, removeFieldRule: (n: string) => void, rule?: CheckType<unknown, any>): void;
4
+ export default useRegisterModel;
@@ -0,0 +1,14 @@
1
+ import { useRef, useEffect } from 'react';
2
+
3
+ function useRegisterModel(name, pushFieldRule, removeFieldRule, rule) {
4
+ var refRule = useRef(rule);
5
+ refRule.current = rule;
6
+ useEffect(function () {
7
+ pushFieldRule(name, refRule);
8
+ return function () {
9
+ removeFieldRule(name);
10
+ };
11
+ }, [name, pushFieldRule, removeFieldRule]);
12
+ }
13
+
14
+ export default useRegisterModel;
@@ -5,7 +5,10 @@ import MenuContext, { MenuActionTypes, MoveFocusTo } from './MenuContext';
5
5
  import { KEY_VALUES, useCustom } from '../utils';
6
6
  import { isFocusEntering, isFocusLeaving } from '../utils/events';
7
7
  import useMenu from './useMenu';
8
+ import { isFocusableElement } from '../utils/dom';
8
9
  export default function Menubar(_ref) {
10
+ var _items$activeItemInde3;
11
+
9
12
  var _ref$vertical = _ref.vertical,
10
13
  vertical = _ref$vertical === void 0 ? false : _ref$vertical,
11
14
  children = _ref.children,
@@ -20,7 +23,8 @@ export default function Menubar(_ref) {
20
23
  var menubarElementRef = useRef(null);
21
24
  var onFocus = useCallback(function (event) {
22
25
  // Focus moves inside Menubar
23
- if (isFocusEntering(event)) {
26
+ if (isFocusEntering(event) && // Skip if focus is moving to a focusable element within this menu
27
+ !(event.target !== event.currentTarget && isFocusableElement(event.target))) {
24
28
  if (activeItemIndex === null) {
25
29
  dispatch({
26
30
  type: MenuActionTypes.MoveFocus,
@@ -43,7 +47,9 @@ export default function Menubar(_ref) {
43
47
  rtl = _useCustom.rtl;
44
48
 
45
49
  var onKeyDown = useCallback(function (event) {
46
- var activeItemElement = isNil(activeItemIndex) ? null : items[activeItemIndex].element;
50
+ var _items$activeItemInde, _items$activeItemInde2;
51
+
52
+ var activeItemElement = isNil(activeItemIndex) ? null : (_items$activeItemInde = (_items$activeItemInde2 = items[activeItemIndex]) === null || _items$activeItemInde2 === void 0 ? void 0 : _items$activeItemInde2.element) !== null && _items$activeItemInde !== void 0 ? _items$activeItemInde : null;
47
53
 
48
54
  switch (true) {
49
55
  case !vertical && !rtl && event.key === KEY_VALUES.RIGHT:
@@ -123,7 +129,7 @@ export default function Menubar(_ref) {
123
129
  onBlur: onBlur,
124
130
  onKeyDown: onKeyDown,
125
131
  onClick: onClick,
126
- 'aria-activedescendant': isNil(activeItemIndex) ? undefined : items[activeItemIndex].element.id,
132
+ 'aria-activedescendant': isNil(activeItemIndex) ? undefined : (_items$activeItemInde3 = items[activeItemIndex]) === null || _items$activeItemInde3 === void 0 ? void 0 : _items$activeItemInde3.element.id,
127
133
  'aria-orientation': vertical ? 'vertical' : undefined // implicitly set 'horizontal'
128
134
 
129
135
  }, menubarElementRef));
@@ -1 +1 @@
1
- export declare function isFocusableElement(element: HTMLElement): boolean;
1
+ export declare function isFocusableElement(element: Element): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rsuite",
3
- "version": "5.9.0",
3
+ "version": "5.12.0",
4
4
  "description": "A suite of react components",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",