@dr.pogodin/react-utils 1.33.0 → 1.33.1

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.
@@ -15,13 +15,9 @@ export type PropsT<NameT, OnChangeT = React.ChangeEventHandler<HTMLSelectElement
15
15
  theme: Theme<typeof validThemeKeys>;
16
16
  value?: string;
17
17
  };
18
- export declare const optionValidator: PT.Requireable<NonNullable<string | NonNullable<PT.InferProps<{
19
- name: PT.Requireable<string>;
20
- value: PT.Validator<string>;
21
- }>>>>;
22
- export declare const optionsValidator: PT.Requireable<NonNullable<NonNullable<string | NonNullable<PT.InferProps<{
23
- name: PT.Requireable<string>;
24
- value: PT.Validator<string>;
25
- }>>>>[]>;
18
+ export declare const optionValidator: PT.Requireable<OptionT<React.ReactNode> | string>;
19
+ export declare const optionsValidator: PT.Requireable<NonNullable<string | OptionT<React.ReactNode>>[]>;
20
+ export declare const stringOptionValidator: PT.Requireable<OptionT<string> | string>;
21
+ export declare const stringOptionsValidator: PT.Requireable<NonNullable<string | OptionT<string>>[]>;
26
22
  /** Returns option value and name as a tuple. */
27
23
  export declare function optionValueName<NameT>(option: OptionT<NameT> | string): [string, NameT | string];
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.33.0",
2
+ "version": "1.33.1",
3
3
  "bin": {
4
4
  "react-utils-build": "bin/build.js",
5
5
  "react-utils-setup": "bin/setup.js"
@@ -109,9 +109,17 @@ const BaseModal: React.FunctionComponent<PropsT> = ({
109
109
  <div
110
110
  aria-label="Cancel"
111
111
  className={theme.overlay}
112
- onClick={() => onCancel && onCancel()}
112
+ onClick={(e) => {
113
+ if (onCancel) {
114
+ onCancel();
115
+ e.stopPropagation();
116
+ }
117
+ }}
113
118
  onKeyDown={(e) => {
114
- if (e.key === 'Escape' && onCancel) onCancel();
119
+ if (e.key === 'Escape' && onCancel) {
120
+ onCancel();
121
+ e.stopPropagation();
122
+ }
115
123
  }}
116
124
  ref={(node) => {
117
125
  if (node && node !== overlayRef.current) {
@@ -122,9 +130,23 @@ const BaseModal: React.FunctionComponent<PropsT> = ({
122
130
  role="button"
123
131
  tabIndex={0}
124
132
  />
133
+ {
134
+ // NOTE: These rules are disabled because our intention is to keep
135
+ // the element non-interactive (thus not on the keyboard focus chain),
136
+ // and it has `onClick` handler merely to stop propagation of click
137
+ // events to its parent container. This is needed because, for example
138
+ // when the modal is wrapped into an interactive element we don't want
139
+ // any clicks inside the modal to bubble-up to that parent element
140
+ // (because visually and logically the modal dialog does not belong
141
+ // to its parent container, where it technically belongs from
142
+ // the HTML mark-up perpective).
143
+ /* eslint-disable jsx-a11y/click-events-have-key-events,
144
+ jsx-a11y/no-noninteractive-element-interactions */
145
+ }
125
146
  <div
126
147
  aria-modal="true"
127
148
  className={theme.container}
149
+ onClick={(e) => e.stopPropagation()}
128
150
  onWheel={(event) => event.stopPropagation()}
129
151
  ref={containerRef}
130
152
  role="dialog"
@@ -132,6 +154,8 @@ const BaseModal: React.FunctionComponent<PropsT> = ({
132
154
  >
133
155
  {children}
134
156
  </div>
157
+ {/* eslint-enable jsx-a11y/click-events-have-key-events,
158
+ jsx-a11y/no-noninteractive-element-interactions */}
135
159
  <div
136
160
  onFocus={() => {
137
161
  overlayRef.current?.focus();
@@ -8,8 +8,8 @@ import defaultTheme from './theme.scss';
8
8
 
9
9
  import {
10
10
  type PropsT,
11
- optionsValidator,
12
11
  optionValueName,
12
+ stringOptionsValidator,
13
13
  validThemeKeys,
14
14
  } from '../common';
15
15
 
@@ -102,7 +102,7 @@ Dropdown.propTypes = {
102
102
  filter: PT.func,
103
103
  label: PT.node,
104
104
  onChange: PT.func,
105
- options: optionsValidator,
105
+ options: stringOptionsValidator,
106
106
  theme: ThemedDropdown.themeType.isRequired,
107
107
  value: PT.string,
108
108
  };
@@ -38,9 +38,10 @@ export type PropsT<
38
38
  value?: string;
39
39
  };
40
40
 
41
- export const optionValidator = PT.oneOfType([
41
+ export const optionValidator:
42
+ PT.Requireable<OptionT<React.ReactNode> | string> = PT.oneOfType([
42
43
  PT.shape({
43
- name: PT.string,
44
+ name: PT.node,
44
45
  value: PT.string.isRequired,
45
46
  }).isRequired,
46
47
  PT.string.isRequired,
@@ -48,6 +49,17 @@ export const optionValidator = PT.oneOfType([
48
49
 
49
50
  export const optionsValidator = PT.arrayOf(optionValidator.isRequired);
50
51
 
52
+ export const stringOptionValidator:
53
+ PT.Requireable<OptionT<string> | string> = PT.oneOfType([
54
+ PT.shape({
55
+ name: PT.string,
56
+ value: PT.string.isRequired,
57
+ }).isRequired,
58
+ PT.string.isRequired,
59
+ ]);
60
+
61
+ export const stringOptionsValidator = PT.arrayOf(stringOptionValidator.isRequired);
62
+
51
63
  /** Returns option value and name as a tuple. */
52
64
  export function optionValueName<NameT>(
53
65
  option: OptionT<NameT> | string,