@rescui/select 0.9.4 → 0.10.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/lib/select.js CHANGED
@@ -1,5 +1,9 @@
1
1
  import "core-js/modules/es.object.to-string.js";
2
2
  import "core-js/modules/web.dom-collections.for-each.js";
3
+ import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
4
+ import _Object$getOwnPropertySymbols from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols";
5
+ import _Object$getOwnPropertyDescriptor from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor";
6
+ import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors";
3
7
  import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
4
8
  import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
5
9
  import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
@@ -12,43 +16,35 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
12
16
  import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
13
17
  import _concatInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/concat";
14
18
  import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
15
- import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
16
- import _Object$getOwnPropertySymbols from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols";
17
- import _Object$getOwnPropertyDescriptor from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor";
18
- import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors";
19
+ import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
19
20
  import "core-js/modules/es.array.join.js";
20
21
  import "core-js/modules/es.regexp.constructor.js";
21
22
  import "core-js/modules/es.regexp.exec.js";
22
23
  import "core-js/modules/es.regexp.to-string.js";
23
24
  import "core-js/modules/es.function.name.js";
24
- import React, { useRef, useState, useEffect, useMemo, useCallback } from 'react';
25
+ import React, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
25
26
  import PropTypes from 'prop-types';
27
+ import cn from 'classnames';
26
28
  import scrollIntoView from 'scroll-into-view-if-needed';
27
29
  import { Dropdown } from '@rescui/dropdown';
28
30
  import { Menu, MenuItem, Divider, GroupHeader } from '@rescui/menu';
29
- import { useTheme } from '@rescui/ui-contexts';
31
+ import { useThemeWithUndefined } from '@rescui/ui-contexts';
30
32
  import SelectTrigger from './parts/trigger.js';
31
33
  import FormTriggerWrapper from './parts/form-trigger-wrapper.js';
34
+ import { useObservableForceRerender } from './parts/use-observable-force-rerender.js';
32
35
  import { optionType, optionsGroupType, noOptionsMessageConfigType } from './common-prop-types.js';
33
- import { useStrongMemo, getDefaultCursorIndex, isGroupsEmpty, getMovedCursorIndex, shouldOpenSelect, isIndexMatchCursor, reverseTheme, getPlainOptionsFromGroups, getEmptyMessage, withoutGroupsLabel, OptionGroupTypes, getOptionValue, convertToOptionGroupsIfNeeded, escapeRegex, calculateMaxHeight } from './utils.js';
36
+ import { useStrongMemo, getDefaultCursorIndex, isGroupsEmpty, getMovedCursorIndex, shouldOpenSelect, isIndexMatchCursor, withoutGroupsLabel, getPlainOptionsFromGroups, getEmptyMessage, OptionGroupTypes, getOptionValue, convertToOptionGroupsIfNeeded, escapeRegex, calculateMaxHeight } from './utils.js';
34
37
  import { ARROW_DOWN, ARROW_UP, ENTER, SPACE, TAB, ESCAPE, BACKSPACE } from './key-codes.js';
35
38
  import styles from './parts/common-select.p.module.css.js'; // eslint-disable-next-line complexity
36
39
 
37
40
  var Option = function Option(_ref) {
38
- var groups = _ref.groups,
39
- selected = _ref.selected,
41
+ var selected = _ref.selected,
40
42
  cursorIndex = _ref.cursorIndex,
41
- size = _ref.size,
42
43
  item = _ref.item,
43
44
  isLastItem = _ref.isLastItem,
44
45
  highlightedItemRef = _ref.highlightedItemRef,
45
46
  handleSelectIndex = _ref.handleSelectIndex,
46
47
  handleHighlightIndex = _ref.handleHighlightIndex;
47
- var marginInPx = withoutGroupsLabel(groups) ? 0 : {
48
- l: 12,
49
- m: 6,
50
- s: 0
51
- }[size];
52
48
 
53
49
  if (item.type === OptionGroupTypes.OPTION) {
54
50
  var _context;
@@ -68,18 +64,14 @@ var Option = function Option(_ref) {
68
64
  onClick: function onClick() {
69
65
  return handleSelectIndex(index);
70
66
  },
71
- style: {
72
- marginBottom: isLastItem ? "".concat(marginInPx, "px") : ''
73
- },
67
+ className: cn(isLastItem && styles.lastOption),
74
68
  "data-test": _filterInstanceProperty(_context = ['select-menu-item', isHighlighted && 'select-menu-item-highlighted', isSelected && 'select-menu-item-selected']).call(_context, Boolean).join(' ')
75
69
  }, label);
76
70
  }
77
71
 
78
72
  if (item.type === OptionGroupTypes.DIVIDER) {
79
73
  return /*#__PURE__*/React.createElement(Divider, {
80
- style: {
81
- marginTop: "".concat(marginInPx, "px")
82
- }
74
+ className: styles.divider
83
75
  });
84
76
  }
85
77
 
@@ -106,11 +98,21 @@ var getOptionKey = function getOptionKey(item, i) {
106
98
  }
107
99
 
108
100
  return null;
109
- }; // eslint-disable-next-line complexity
101
+ };
110
102
 
103
+ var SIZE_STYLES = {
104
+ s: styles.sizeS,
105
+ m: styles.sizeM,
106
+ l: styles.sizeL
107
+ };
108
+ var MENU_SIZE_STYLES = {
109
+ s: styles.menuSizeS,
110
+ m: styles.menuSizeM,
111
+ l: styles.menuSizeL
112
+ }; // eslint-disable-next-line complexity
111
113
 
112
114
  var Select = function Select(_ref2) {
113
- var _context4;
115
+ var _context5;
114
116
 
115
117
  var options = _ref2.options,
116
118
  _ref2$size = _ref2.size,
@@ -138,21 +140,26 @@ var Select = function Select(_ref2) {
138
140
  boldLabel = _ref2.boldLabel,
139
141
  restProps = _objectWithoutProperties(_ref2, _excluded);
140
142
 
141
- var theme = useTheme(themeFromProps);
143
+ var _useState = useState(null),
144
+ _useState2 = _slicedToArray(_useState, 2),
145
+ triggerFormWrapperRef = _useState2[0],
146
+ setTriggerFormWrapperRef = _useState2[1];
147
+
148
+ var theme = useThemeWithUndefined(themeFromProps);
142
149
  var dropdownRef = useRef(null);
143
150
  var highlightedItemRef = /*#__PURE__*/React.createRef();
144
151
 
145
- var _useState = useState(false),
146
- _useState2 = _slicedToArray(_useState, 2),
147
- isKeyboardNavigating = _useState2[0],
148
- setIsKeyboardNavigating = _useState2[1];
152
+ var _useState3 = useState(false),
153
+ _useState4 = _slicedToArray(_useState3, 2),
154
+ isKeyboardNavigating = _useState4[0],
155
+ setIsKeyboardNavigating = _useState4[1];
149
156
 
150
157
  var skipScrollingRef = useRef(false);
151
158
 
152
- var _useState3 = useState(''),
153
- _useState4 = _slicedToArray(_useState3, 2),
154
- searchString = _useState4[0],
155
- setSearchString = _useState4[1];
159
+ var _useState5 = useState(''),
160
+ _useState6 = _slicedToArray(_useState5, 2),
161
+ searchString = _useState6[0],
162
+ setSearchString = _useState6[1];
156
163
 
157
164
  var groups = useStrongMemo(function () {
158
165
  return convertToOptionGroupsIfNeeded(options);
@@ -175,17 +182,17 @@ var Select = function Select(_ref2) {
175
182
  });
176
183
  }, [searchString, groups]);
177
184
 
178
- var _useState5 = useState(false),
179
- _useState6 = _slicedToArray(_useState5, 2),
180
- menuIsOpen = _useState6[0],
181
- setMenuIsOpen = _useState6[1];
185
+ var _useState7 = useState(false),
186
+ _useState8 = _slicedToArray(_useState7, 2),
187
+ menuIsOpen = _useState8[0],
188
+ setMenuIsOpen = _useState8[1];
182
189
 
183
- var _useState7 = useState(function () {
190
+ var _useState9 = useState(function () {
184
191
  return getDefaultCursorIndex(filteredGroups);
185
192
  }),
186
- _useState8 = _slicedToArray(_useState7, 2),
187
- cursorIndex = _useState8[0],
188
- setCursorIndex = _useState8[1];
193
+ _useState10 = _slicedToArray(_useState9, 2),
194
+ cursorIndex = _useState10[0],
195
+ setCursorIndex = _useState10[1];
189
196
 
190
197
  useEffect(function () {
191
198
  setCursorIndex(getDefaultCursorIndex(filteredGroups));
@@ -338,8 +345,29 @@ var Select = function Select(_ref2) {
338
345
  if (!isIndexMatchCursor(cursorIndex, index)) {
339
346
  setCursorIndex(index);
340
347
  }
341
- }, [cursorIndex]);
342
- var maxHeight = calculateMaxHeight(size);
348
+ }, [cursorIndex]); // We use invisible and "untouchable" dummy element to observe `size` changes from css to trigger force rerenders
349
+
350
+ var observableRef = useObservableForceRerender();
351
+ var sizeFromCss = null;
352
+
353
+ if (triggerFormWrapperRef && menuIsOpen) {
354
+ var _context4;
355
+
356
+ // In theory this part of the code might cause issues with SSR.
357
+ // But in this specific context, because of checking ref "triggerFormWrapperRef",
358
+ // we are sure that the value will still be "null" on the first render.
359
+ // Therefore, the first render on the client will be the same as on the server.
360
+ // Also, there will be no layout shifts on the following renders because
361
+ // it's a dropdown-content and in most cases it opens only on-demand.
362
+ // In additional, we use "observable" el to watch size changes between rerenders (@media query case).
363
+ var triggerFormWrapperStyles = getComputedStyle(triggerFormWrapperRef);
364
+ var rawSizeFromCss = triggerFormWrapperStyles.getPropertyValue('--_rs-select-size');
365
+ sizeFromCss = _includesInstanceProperty(_context4 = ['s', 'm', 'l']).call(_context4, rawSizeFromCss) ? rawSizeFromCss : null;
366
+ }
367
+
368
+ var actualSize = sizeFromCss || size;
369
+ var maxHeight = calculateMaxHeight(actualSize);
370
+ var withGroupsLabel = !withoutGroupsLabel(filteredGroups);
343
371
  return /*#__PURE__*/React.createElement(Dropdown, {
344
372
  theme: theme,
345
373
  onRequestClose: handleClose,
@@ -355,7 +383,8 @@ var Select = function Select(_ref2) {
355
383
  trigger: function trigger(_ref4) {
356
384
  var ref = _ref4.ref;
357
385
  return /*#__PURE__*/React.createElement(FormTriggerWrapper, {
358
- className: className,
386
+ ref: setTriggerFormWrapperRef,
387
+ className: cn(className, SIZE_STYLES[size]),
359
388
  theme: theme,
360
389
  size: size,
361
390
  error: restProps.error,
@@ -363,7 +392,10 @@ var Select = function Select(_ref2) {
363
392
  note: restProps.note,
364
393
  onKeyDown: handleTriggerKeyDown,
365
394
  boldLabel: boldLabel
366
- }, restProps.name && /*#__PURE__*/React.createElement("input", {
395
+ }, /*#__PURE__*/React.createElement("div", {
396
+ ref: observableRef,
397
+ className: styles.observable
398
+ }), restProps.name && /*#__PURE__*/React.createElement("input", {
367
399
  type: "hidden",
368
400
  name: restProps.name,
369
401
  value: value && value.value || ''
@@ -390,20 +422,17 @@ var Select = function Select(_ref2) {
390
422
  },
391
423
  isOpen: menuIsOpen
392
424
  }, /*#__PURE__*/React.createElement(Menu, {
393
- size: size,
394
- theme: mode === 'rock' ? reverseTheme(theme) : theme,
425
+ size: actualSize,
395
426
  disableCursor: isKeyboardNavigating,
396
- className: styles.menu,
427
+ className: cn(styles.menu, withGroupsLabel && styles.withGroupsLabel, MENU_SIZE_STYLES[actualSize]),
397
428
  enableKeyboardNavigation: false
398
- }, !isEmptyMenu ? _mapInstanceProperty(_context4 = getPlainOptionsFromGroups(filteredGroups)).call(_context4, function (item, i, collection) {
429
+ }, !isEmptyMenu ? _mapInstanceProperty(_context5 = getPlainOptionsFromGroups(filteredGroups)).call(_context5, function (item, i, collection) {
399
430
  return /*#__PURE__*/React.createElement(Option, {
400
431
  item: item,
401
432
  isLastItem: i === collection.length - 1,
402
433
  key: getOptionKey(item, i),
403
- groups: filteredGroups,
404
434
  selected: value,
405
435
  cursorIndex: cursorIndex,
406
- size: size,
407
436
  highlightedItemRef: highlightedItemRef,
408
437
  handleSelectIndex: handleSelectIndex,
409
438
  handleHighlightIndex: handleHighlightIndex
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rescui/select",
3
- "version": "0.9.4",
3
+ "version": "0.10.0",
4
4
  "description": "",
5
5
  "license": "Apache-2.0",
6
6
  "author": "JetBrains",
@@ -15,30 +15,30 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@babel/runtime-corejs3": "^7.14.0",
18
- "@rescui/dropdown": "^0.6.4",
19
- "@rescui/icons": "^0.15.3",
20
- "@rescui/menu": "^0.9.8",
21
- "@rescui/tag": "^0.9.5",
18
+ "@rescui/dropdown": "^0.7.0",
19
+ "@rescui/icons": "^0.16.0",
20
+ "@rescui/menu": "^0.10.0",
21
+ "@rescui/tag": "^0.10.0",
22
+ "@rescui/use-resize-observer": "^0.2.0",
22
23
  "classnames": "^2.2.6",
23
24
  "core-js": "^3.9.1",
24
25
  "scroll-into-view-if-needed": "2.2.20"
25
26
  },
26
27
  "peerDependencies": {
27
- "@rescui/ui-contexts": "<1.0.0",
28
+ "@rescui/ui-contexts": "^0.4.0",
28
29
  "prop-types": "^15.7.2",
29
30
  "react": ">=16.8.0 <19"
30
31
  },
31
32
  "devDependencies": {
32
- "@rescui/colors": "^0.1.11",
33
- "@rescui/postcss-preset-library": "^0.1.1",
34
- "@rescui/scripts": "^0.2.3",
35
- "@rescui/typography": "^0.15.0",
33
+ "@rescui/colors": "^0.2.0",
34
+ "@rescui/scripts": "^0.3.0",
35
+ "@rescui/typography": "^0.16.0",
36
36
  "@rescui/visual-regression": "^0.1.1",
37
- "postcss": "^8.3.0",
38
37
  "sniffr": "^1.2.0"
39
38
  },
40
39
  "scripts": {
41
- "build": "rescui-scripts build --css-modules"
40
+ "build": "rescui-scripts build && yarn run build-pcss-api",
41
+ "build-pcss-api": "rescui-scripts build-pcss-api --file public-api.p.css"
42
42
  },
43
- "gitHead": "e21b6f80037993b094ceaff022db6d4cd176a88d"
43
+ "gitHead": "51da8a7188f4c558c563065a4ff4ef5c8e74994c"
44
44
  }