@kaizen/components 1.80.2 → 1.80.4

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 (74) hide show
  1. package/codemods/README.md +24 -0
  2. package/codemods/migrateV2NextToCurrent/index.ts +40 -0
  3. package/codemods/migrateV2NextToCurrent/migrateV2NextToCurrent.spec.ts +555 -0
  4. package/codemods/migrateV2NextToCurrent/migrateV2NextToCurrent.ts +104 -0
  5. package/codemods/renameV2ComponentImportsAndUsages/index.ts +30 -0
  6. package/codemods/renameV2ComponentImportsAndUsages/renameV2ComponentImportsAndUsages.spec.ts +390 -0
  7. package/codemods/renameV2ComponentImportsAndUsages/renameV2ComponentImportsAndUsages.ts +151 -0
  8. package/codemods/utils/createModulePathTransformer.spec.ts +209 -0
  9. package/codemods/utils/createModulePathTransformer.ts +59 -0
  10. package/codemods/utils/createRenameMapFromGroups.ts +31 -0
  11. package/codemods/utils/index.ts +3 -0
  12. package/codemods/utils/updateJsxElementTagName.spec.ts +129 -0
  13. package/codemods/utils/updateJsxElementTagName.ts +56 -0
  14. package/codemods/utils/updateKaioImports.spec.ts +82 -0
  15. package/codemods/utils/updateKaioImports.ts +16 -7
  16. package/dist/cjs/src/__alpha__/SingleSelect/SingleSelect.cjs +69 -16
  17. package/dist/cjs/src/__alpha__/SingleSelect/context/SingleSelectContext.cjs +13 -0
  18. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/Popover/Popover.cjs +54 -0
  19. package/dist/cjs/src/__alpha__/SingleSelect/{SingleSelect.module.css.cjs → subcomponents/Popover/Popover.module.css.cjs} +1 -1
  20. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/Popover/utils/usePopoverPositioning.cjs +94 -0
  21. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/Popover/utils/usePositioningStyles.cjs +69 -0
  22. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/Popover/utils/useSupportsAnchorPositioning.cjs +12 -0
  23. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.cjs +41 -5
  24. package/dist/esm/src/__alpha__/SingleSelect/SingleSelect.mjs +60 -10
  25. package/dist/esm/src/__alpha__/SingleSelect/context/SingleSelectContext.mjs +10 -0
  26. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Popover/Popover.mjs +49 -0
  27. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Popover/Popover.module.css.mjs +4 -0
  28. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Popover/utils/usePopoverPositioning.mjs +92 -0
  29. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Popover/utils/usePositioningStyles.mjs +67 -0
  30. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Popover/utils/useSupportsAnchorPositioning.mjs +10 -0
  31. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.mjs +43 -7
  32. package/dist/styles.css +43 -21
  33. package/dist/types/__alpha__/SingleSelect/SingleSelect.d.ts +7 -9
  34. package/dist/types/__alpha__/SingleSelect/context/SingleSelectContext.d.ts +12 -0
  35. package/dist/types/__alpha__/SingleSelect/context/index.d.ts +1 -0
  36. package/dist/types/__alpha__/SingleSelect/subcomponents/List/List.d.ts +2 -1
  37. package/dist/types/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.d.ts +2 -1
  38. package/dist/types/__alpha__/SingleSelect/subcomponents/ListSection/ListSection.d.ts +2 -1
  39. package/dist/types/__alpha__/SingleSelect/subcomponents/Popover/Popover.d.ts +6 -0
  40. package/dist/types/__alpha__/SingleSelect/subcomponents/Popover/index.d.ts +1 -0
  41. package/dist/types/__alpha__/SingleSelect/subcomponents/Popover/utils/index.d.ts +2 -0
  42. package/dist/types/__alpha__/SingleSelect/subcomponents/Popover/utils/usePopoverPositioning.d.ts +4 -0
  43. package/dist/types/__alpha__/SingleSelect/subcomponents/Popover/utils/usePositioningStyles.d.ts +4 -0
  44. package/dist/types/__alpha__/SingleSelect/subcomponents/Popover/utils/useSupportsAnchorPositioning.d.ts +1 -0
  45. package/dist/types/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.d.ts +2 -1
  46. package/dist/types/__alpha__/SingleSelect/subcomponents/index.d.ts +1 -0
  47. package/dist/types/__alpha__/SingleSelect/types.d.ts +45 -0
  48. package/package.json +4 -4
  49. package/src/__alpha__/SingleSelect/SingleSelect.tsx +79 -14
  50. package/src/__alpha__/SingleSelect/_docs/SingleSelect.mdx +5 -2
  51. package/src/__alpha__/SingleSelect/_docs/SingleSelect.spec.stories.tsx +100 -0
  52. package/src/__alpha__/SingleSelect/_docs/SingleSelect.stickersheet.stories.tsx +4 -4
  53. package/src/__alpha__/SingleSelect/_docs/SingleSelect.stories.tsx +21 -2
  54. package/src/__alpha__/SingleSelect/context/SingleSelectContext.tsx +21 -0
  55. package/src/__alpha__/SingleSelect/context/index.ts +1 -0
  56. package/src/__alpha__/SingleSelect/subcomponents/List/List.module.css +0 -1
  57. package/src/__alpha__/SingleSelect/subcomponents/List/List.tsx +2 -1
  58. package/src/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.module.css +7 -0
  59. package/src/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.tsx +2 -1
  60. package/src/__alpha__/SingleSelect/subcomponents/ListSection/ListSection.tsx +3 -1
  61. package/src/__alpha__/SingleSelect/subcomponents/Popover/Popover.module.css +24 -0
  62. package/src/__alpha__/SingleSelect/subcomponents/Popover/Popover.tsx +54 -0
  63. package/src/__alpha__/SingleSelect/subcomponents/Popover/index.ts +1 -0
  64. package/src/__alpha__/SingleSelect/subcomponents/Popover/utils/index.ts +2 -0
  65. package/src/__alpha__/SingleSelect/subcomponents/Popover/utils/usePopoverPositioning.ts +108 -0
  66. package/src/__alpha__/SingleSelect/subcomponents/Popover/utils/usePositioningStyles.ts +75 -0
  67. package/src/__alpha__/SingleSelect/subcomponents/Popover/utils/useSupportsAnchorPositioning.ts +13 -0
  68. package/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.module.css +1 -0
  69. package/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.tsx +29 -7
  70. package/src/__alpha__/SingleSelect/subcomponents/index.ts +1 -0
  71. package/src/__alpha__/SingleSelect/types.ts +58 -0
  72. package/dist/esm/src/__alpha__/SingleSelect/SingleSelect.module.css.mjs +0 -4
  73. package/src/__alpha__/SingleSelect/SingleSelect.module.css +0 -9
  74. package/src/__alpha__/SingleSelect/SingleSelect.spec.tsx +0 -26
@@ -2,31 +2,84 @@
2
2
 
3
3
  var tslib = require('tslib');
4
4
  var React = require('react');
5
+ var select = require('@react-stately/select');
5
6
  var reactAriaComponents = require('react-aria-components');
7
+ var SingleSelectContext = require('./context/SingleSelectContext.cjs');
6
8
  var List = require('./subcomponents/List/List.cjs');
7
9
  var ListSection = require('./subcomponents/ListSection/ListSection.cjs');
8
10
  var ListItem = require('./subcomponents/ListItem/ListItem.cjs');
9
11
  var Trigger = require('./subcomponents/Trigger/Trigger.cjs');
10
- var SingleSelect_module = require('./SingleSelect.module.css.cjs');
12
+ var Popover = require('./subcomponents/Popover/Popover.cjs');
11
13
  function _interopDefault(e) {
12
14
  return e && e.__esModule ? e : {
13
15
  default: e
14
16
  };
15
17
  }
16
18
  var React__default = /*#__PURE__*/_interopDefault(React);
17
- var SingleSelect = function (_a) {
18
- var classNameOverride = _a.classNameOverride,
19
- children = _a.children,
20
- restProps = tslib.__rest(_a, ["classNameOverride", "children"]);
21
- return React__default.default.createElement(reactAriaComponents.Select, tslib.__assign({
22
- className: classNameOverride,
23
- placeholder: ""
24
- }, restProps), React__default.default.createElement(Trigger.Trigger, null), React__default.default.createElement(reactAriaComponents.Popover, {
25
- className: SingleSelect_module.popover
26
- }, children));
27
- };
28
- SingleSelect.displayName = 'SingleSelect';
29
- SingleSelect.List = List.List;
30
- SingleSelect.ListItem = ListItem.ListItem;
31
- SingleSelect.ListSection = ListSection.ListSection;
19
+ const SingleSelect = /*#__PURE__*/function () {
20
+ const SingleSelect = function (_a) {
21
+ var items = _a.items,
22
+ onSelectionChange = _a.onSelectionChange,
23
+ children = _a.children,
24
+ restProps = tslib.__rest(_a, ["items", "onSelectionChange", "children"]);
25
+ var buttonRef = React__default.default.useRef(null);
26
+ var popoverRef = React__default.default.useRef(null);
27
+ var racPopoverRef = React__default.default.useRef(null);
28
+ var uniqueId = React.useId();
29
+ var anchorName = "--trigger-".concat(uniqueId);
30
+ var state = select.useSelectState({
31
+ items: items
32
+ });
33
+ var handleOnSelectionChange = React__default.default.useCallback(function (keys) {
34
+ var key = null;
35
+ if (keys instanceof Set && keys.size > 0) {
36
+ key = Array.from(keys)[0];
37
+ }
38
+ state.setSelectedKey(key);
39
+ if (onSelectionChange) {
40
+ onSelectionChange(key);
41
+ }
42
+ }, [state, onSelectionChange]);
43
+ // Cloning children here to allow users to pass in a custom ListItem or ListSection
44
+ // and still have the SingleSelect handle selection state
45
+ var injectedChildren = React.useMemo(function () {
46
+ if (!React.isValidElement(children)) return null;
47
+ var selectedKeys = state.selectedKey ? new Set([state.selectedKey]) : new Set();
48
+ return React.cloneElement(children, {
49
+ selectionMode: 'single',
50
+ selectedKeys: selectedKeys,
51
+ onSelectionChange: handleOnSelectionChange,
52
+ autoFocus: 'first'
53
+ });
54
+ }, [children, handleOnSelectionChange, state.selectedKey]);
55
+ return React__default.default.createElement(SingleSelectContext.SingleSelectContext.Provider, {
56
+ value: {
57
+ isOpen: state.isOpen,
58
+ setOpen: state.setOpen,
59
+ selectedKey: state.selectedKey,
60
+ items: items,
61
+ anchorName: anchorName
62
+ }
63
+ }, React__default.default.createElement(reactAriaComponents.Select
64
+ // TODO: allow user to pass in label
65
+ , tslib.__assign({
66
+ "aria-label": 'single-select',
67
+ onSelectionChange: function (key) {
68
+ return handleOnSelectionChange(key != null ? new Set([key]) : new Set());
69
+ },
70
+ placeholder: ""
71
+ }, restProps), React__default.default.createElement(Trigger.Trigger, {
72
+ buttonRef: buttonRef
73
+ }), state.isOpen && React__default.default.createElement(Popover.Popover, {
74
+ buttonRef: buttonRef,
75
+ popoverRef: popoverRef,
76
+ racPopoverRef: racPopoverRef
77
+ }, injectedChildren)));
78
+ };
79
+ SingleSelect.displayName = 'SingleSelect';
80
+ SingleSelect.List = List.List;
81
+ SingleSelect.ListItem = ListItem.ListItem;
82
+ SingleSelect.ListSection = ListSection.ListSection;
83
+ return SingleSelect;
84
+ }();
32
85
  exports.SingleSelect = SingleSelect;
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var SingleSelectContext = React.createContext(undefined);
5
+ var useSingleSelectContext = function () {
6
+ var context = React.useContext(SingleSelectContext);
7
+ if (!context) {
8
+ throw new Error('useSingleSelectContext must be used within a SingleSelectContext.Provider');
9
+ }
10
+ return context;
11
+ };
12
+ exports.SingleSelectContext = SingleSelectContext;
13
+ exports.useSingleSelectContext = useSingleSelectContext;
@@ -0,0 +1,54 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var reactAriaComponents = require('react-aria-components');
5
+ var SingleSelectContext = require('../../context/SingleSelectContext.cjs');
6
+ var usePositioningStyles = require('./utils/usePositioningStyles.cjs');
7
+ var Popover_module = require('./Popover.module.css.cjs');
8
+ function _interopDefault(e) {
9
+ return e && e.__esModule ? e : {
10
+ default: e
11
+ };
12
+ }
13
+ var React__default = /*#__PURE__*/_interopDefault(React);
14
+ var Popover = function (_a) {
15
+ var buttonRef = _a.buttonRef,
16
+ popoverRef = _a.popoverRef,
17
+ racPopoverRef = _a.racPopoverRef,
18
+ children = _a.children;
19
+ var _b = SingleSelectContext.useSingleSelectContext(),
20
+ isOpen = _b.isOpen,
21
+ setOpen = _b.setOpen,
22
+ anchorName = _b.anchorName;
23
+ var _c = usePositioningStyles.usePositioningStyles(buttonRef, popoverRef, anchorName),
24
+ popoverStyle = _c.popoverStyle,
25
+ isPositioned = _c.isPositioned;
26
+ var shouldShowPopover = React.useMemo(function () {
27
+ return isOpen && isPositioned;
28
+ }, [isOpen, isPositioned]);
29
+ React.useLayoutEffect(function () {
30
+ var popover = popoverRef.current;
31
+ if (!(popover === null || popover === void 0 ? void 0 : popover.showPopover) || !(popover === null || popover === void 0 ? void 0 : popover.hidePopover)) return;
32
+ if (shouldShowPopover) {
33
+ popover.showPopover();
34
+ } else {
35
+ popover.hidePopover();
36
+ }
37
+ // eslint-disable-next-line react-hooks/exhaustive-deps
38
+ }, [shouldShowPopover]);
39
+ return React__default.default.createElement(reactAriaComponents.Popover, {
40
+ shouldUpdatePosition: false,
41
+ trigger: "manual",
42
+ isOpen: isOpen,
43
+ onOpenChange: setOpen,
44
+ ref: racPopoverRef
45
+ }, React__default.default.createElement("div", {
46
+ // @ts-expect-error - popover attribute is not included in current ts version, ignore type error
47
+ popover: "manual",
48
+ ref: popoverRef,
49
+ className: Popover_module.popover,
50
+ style: popoverStyle
51
+ }, children));
52
+ };
53
+ Popover.displayName = 'SingleSelect.Popover';
54
+ exports.Popover = Popover;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  var styles = {
4
- "popover": "SingleSelect-module_popover__ZjL9n"
4
+ "popover": "Popover-module_popover__BjY2S"
5
5
  };
6
6
  module.exports = styles;
@@ -0,0 +1,94 @@
1
+ 'use strict';
2
+
3
+ var tslib = require('tslib');
4
+ var React = require('react');
5
+ function usePopoverPositioning(_a) {
6
+ var triggerRef = _a.triggerRef,
7
+ popoverRef = _a.popoverRef,
8
+ _b = _a.direction,
9
+ direction = _b === void 0 ? 'ltr' : _b,
10
+ _c = _a.offset,
11
+ offset = _c === void 0 ? 4 : _c,
12
+ _d = _a.preferredPlacement,
13
+ preferredPlacement = _d === void 0 ? 'bottom' : _d;
14
+ var _e = React.useState({
15
+ top: preferredPlacement === 'bottom' ? offset : 'auto',
16
+ bottom: preferredPlacement === 'top' ? offset : 'auto',
17
+ insetInlineStart: 0,
18
+ maxHeight: 300 // TODO: update this based on designs
19
+ }),
20
+ position = _e[0],
21
+ setPosition = _e[1];
22
+ var _f = React.useState(true),
23
+ isPositioned = _f[0],
24
+ setIsPositioned = _f[1];
25
+ var mountedRef = React.useRef(false);
26
+ var isSSR = typeof window === 'undefined';
27
+ var updatePosition = React.useCallback(function () {
28
+ var _a;
29
+ if (isSSR) return;
30
+ var trigger = triggerRef.current;
31
+ var popover = popoverRef.current;
32
+ if (!mountedRef.current || !trigger || !(popover === null || popover === void 0 ? void 0 : popover.isConnected)) {
33
+ return;
34
+ }
35
+ var triggerRect = trigger.getBoundingClientRect();
36
+ if (!triggerRect) return;
37
+ var doc = trigger.ownerDocument;
38
+ var win = (_a = doc === null || doc === void 0 ? void 0 : doc.defaultView) !== null && _a !== void 0 ? _a : window;
39
+ var isRTL = direction === 'rtl';
40
+ var inlineStart = isRTL ? win.innerWidth - triggerRect.right : triggerRect.left;
41
+ var triggerTop = triggerRect.top;
42
+ var triggerBottom = triggerRect.bottom;
43
+ var viewportHeight = win.innerHeight;
44
+ var spaceAbove = triggerTop;
45
+ var spaceBelow = viewportHeight - triggerBottom;
46
+ var shouldFlip = preferredPlacement === 'bottom' && spaceBelow < 200 && spaceAbove > spaceBelow;
47
+ var top;
48
+ var bottom;
49
+ var maxHeight;
50
+ if (shouldFlip) {
51
+ top = 'auto';
52
+ bottom = viewportHeight - triggerTop + offset;
53
+ maxHeight = Math.max(0, spaceAbove - offset);
54
+ } else {
55
+ top = triggerBottom + offset;
56
+ bottom = 'auto';
57
+ maxHeight = Math.max(0, spaceBelow - offset);
58
+ }
59
+ var newPosition = {
60
+ top: top,
61
+ bottom: bottom,
62
+ insetInlineStart: inlineStart,
63
+ maxHeight: maxHeight
64
+ };
65
+ setPosition(newPosition);
66
+ setIsPositioned(true);
67
+ }, [triggerRef, popoverRef, direction, offset, preferredPlacement, isSSR]);
68
+ React.useEffect(function () {
69
+ if (typeof window === 'undefined') return;
70
+ mountedRef.current = true;
71
+ var triggerEl = triggerRef.current;
72
+ updatePosition();
73
+ var resizeObserver = new ResizeObserver(function () {
74
+ updatePosition();
75
+ });
76
+ if (triggerEl) resizeObserver.observe(triggerEl);
77
+ var onWindowResize = function () {
78
+ return updatePosition();
79
+ };
80
+ window.addEventListener('resize', onWindowResize, {
81
+ passive: true
82
+ });
83
+ return function () {
84
+ mountedRef.current = false;
85
+ resizeObserver.disconnect();
86
+ window.removeEventListener('resize', onWindowResize);
87
+ setIsPositioned(false);
88
+ };
89
+ }, [updatePosition, triggerRef]);
90
+ return tslib.__assign(tslib.__assign({}, position), {
91
+ isPositioned: isPositioned
92
+ });
93
+ }
94
+ exports.usePopoverPositioning = usePopoverPositioning;
@@ -0,0 +1,69 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var i18n = require('@react-aria/i18n');
5
+ var usePopoverPositioning = require('./usePopoverPositioning.cjs');
6
+ var useSupportsAnchorPositioning = require('./useSupportsAnchorPositioning.cjs');
7
+ var CSS_PROPS = {
8
+ POSITION_ANCHOR: '--position-anchor',
9
+ POSITION_AREA: '--position-area'
10
+ };
11
+ var DEFAULTS = {
12
+ MAX_HEIGHT: '300px'
13
+ };
14
+ /**
15
+ * Generates manual positioning styles for browsers without anchor positioning support or SSR
16
+ */
17
+ var getManualPositioningStyles = function (positionData) {
18
+ return {
19
+ top: positionData.top,
20
+ bottom: positionData.bottom,
21
+ insetInlineStart: positionData.insetInlineStart,
22
+ maxHeight: positionData.maxHeight,
23
+ left: 'auto',
24
+ right: 'auto',
25
+ position: 'fixed'
26
+ };
27
+ };
28
+ var getAnchorPositioningStyles = function (anchorName, positionData) {
29
+ var _a;
30
+ var _b;
31
+ var styles = (_a = {
32
+ maxHeight: (_b = positionData.maxHeight) !== null && _b !== void 0 ? _b : DEFAULTS.MAX_HEIGHT
33
+ }, _a[CSS_PROPS.POSITION_ANCHOR] = anchorName, _a[CSS_PROPS.POSITION_AREA] = positionData.top === 'auto' ? 'top' : 'bottom', _a);
34
+ return styles;
35
+ };
36
+ var usePositioningStyles = function (buttonRef, popoverRef, anchorName) {
37
+ var direction = i18n.useLocale().direction;
38
+ var hasAnchorSupport = useSupportsAnchorPositioning.useSupportsAnchorPositioning();
39
+ var _a = usePopoverPositioning.usePopoverPositioning({
40
+ triggerRef: buttonRef,
41
+ popoverRef: popoverRef,
42
+ direction: direction,
43
+ preferredPlacement: 'bottom'
44
+ }),
45
+ top = _a.top,
46
+ bottom = _a.bottom,
47
+ insetInlineStart = _a.insetInlineStart,
48
+ maxHeight = _a.maxHeight,
49
+ isPositioned = _a.isPositioned;
50
+ var positionData = React.useMemo(function () {
51
+ return {
52
+ top: top,
53
+ bottom: bottom,
54
+ insetInlineStart: insetInlineStart,
55
+ maxHeight: maxHeight
56
+ };
57
+ }, [top, bottom, insetInlineStart, maxHeight]);
58
+ var popoverStyle = React.useMemo(function () {
59
+ if (hasAnchorSupport === null || !hasAnchorSupport) {
60
+ return getManualPositioningStyles(positionData);
61
+ }
62
+ return getAnchorPositioningStyles(anchorName, positionData);
63
+ }, [hasAnchorSupport, anchorName, positionData]);
64
+ return {
65
+ popoverStyle: popoverStyle,
66
+ isPositioned: isPositioned
67
+ };
68
+ };
69
+ exports.usePositioningStyles = usePositioningStyles;
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var useSupportsAnchorPositioning = function () {
5
+ return React.useMemo(function () {
6
+ if (typeof window === 'undefined' || typeof CSS === 'undefined') {
7
+ return false;
8
+ }
9
+ return CSS.supports('position-anchor', 'auto') || CSS.supports('position-try-fallbacks: flip-block');
10
+ }, []);
11
+ };
12
+ exports.useSupportsAnchorPositioning = useSupportsAnchorPositioning;
@@ -3,6 +3,7 @@
3
3
  var React = require('react');
4
4
  var reactAriaComponents = require('react-aria-components');
5
5
  var Icon = require('../../../../__next__/Icon/Icon.cjs');
6
+ var SingleSelectContext = require('../../context/SingleSelectContext.cjs');
6
7
  var Trigger_module = require('./Trigger.module.css.cjs');
7
8
  function _interopDefault(e) {
8
9
  return e && e.__esModule ? e : {
@@ -10,12 +11,47 @@ function _interopDefault(e) {
10
11
  };
11
12
  }
12
13
  var React__default = /*#__PURE__*/_interopDefault(React);
13
- var Trigger = function () {
14
- return React__default.default.createElement(reactAriaComponents.Button, {
15
- className: Trigger_module.button
16
- }, React__default.default.createElement(reactAriaComponents.SelectValue, null), React__default.default.createElement(Icon.Icon, {
14
+ function flattenItems(items) {
15
+ return items.flatMap(function (item) {
16
+ return 'options' in item ? item.options : item;
17
+ });
18
+ }
19
+ var Trigger = function (_a) {
20
+ var buttonRef = _a.buttonRef;
21
+ var _b = SingleSelectContext.useSingleSelectContext(),
22
+ isOpen = _b.isOpen,
23
+ setOpen = _b.setOpen,
24
+ selectedKey = _b.selectedKey,
25
+ items = _b.items,
26
+ anchorName = _b.anchorName;
27
+ var flattenedItems = React.useMemo(function () {
28
+ return flattenItems(items);
29
+ }, [items]);
30
+ var selectedLabel = React.useMemo(function () {
31
+ var _a;
32
+ var key = selectedKey;
33
+ var item = flattenedItems.find(function (i) {
34
+ return i.value === key;
35
+ });
36
+ return (_a = item === null || item === void 0 ? void 0 : item.label) !== null && _a !== void 0 ? _a : React__default.default.createElement("div", null);
37
+ }, [flattenedItems, selectedKey]);
38
+ return React__default.default.createElement("div", {
39
+ style: {
40
+ position: 'relative'
41
+ }
42
+ }, React__default.default.createElement(reactAriaComponents.Button, {
43
+ className: Trigger_module.button,
44
+ ref: buttonRef,
45
+ onPress: function () {
46
+ return setOpen(!isOpen);
47
+ },
48
+ "aria-expanded": isOpen,
49
+ style: {
50
+ '--anchor-name': anchorName
51
+ }
52
+ }, selectedLabel, React__default.default.createElement(Icon.Icon, {
17
53
  name: "keyboard_arrow_down",
18
54
  isPresentational: true
19
- }));
55
+ })));
20
56
  };
21
57
  exports.Trigger = Trigger;
@@ -1,22 +1,72 @@
1
1
  import { __rest, __assign } from 'tslib';
2
- import React from 'react';
3
- import { Select, Popover } from 'react-aria-components';
2
+ import React, { useId, useMemo, isValidElement, cloneElement } from 'react';
3
+ import { useSelectState } from '@react-stately/select';
4
+ import { Select } from 'react-aria-components';
5
+ import { SingleSelectContext } from './context/SingleSelectContext.mjs';
4
6
  import { List } from './subcomponents/List/List.mjs';
5
7
  import { ListSection } from './subcomponents/ListSection/ListSection.mjs';
6
8
  import { ListItem } from './subcomponents/ListItem/ListItem.mjs';
7
9
  import { Trigger } from './subcomponents/Trigger/Trigger.mjs';
8
- import styles from './SingleSelect.module.css.mjs';
10
+ import { Popover } from './subcomponents/Popover/Popover.mjs';
9
11
  const SingleSelect = /*#__PURE__*/function () {
10
12
  const SingleSelect = function (_a) {
11
- var classNameOverride = _a.classNameOverride,
13
+ var items = _a.items,
14
+ onSelectionChange = _a.onSelectionChange,
12
15
  children = _a.children,
13
- restProps = __rest(_a, ["classNameOverride", "children"]);
14
- return /*#__PURE__*/React.createElement(Select, __assign({
15
- className: classNameOverride,
16
+ restProps = __rest(_a, ["items", "onSelectionChange", "children"]);
17
+ var buttonRef = React.useRef(null);
18
+ var popoverRef = React.useRef(null);
19
+ var racPopoverRef = React.useRef(null);
20
+ var uniqueId = useId();
21
+ var anchorName = "--trigger-".concat(uniqueId);
22
+ var state = useSelectState({
23
+ items: items
24
+ });
25
+ var handleOnSelectionChange = React.useCallback(function (keys) {
26
+ var key = null;
27
+ if (keys instanceof Set && keys.size > 0) {
28
+ key = Array.from(keys)[0];
29
+ }
30
+ state.setSelectedKey(key);
31
+ if (onSelectionChange) {
32
+ onSelectionChange(key);
33
+ }
34
+ }, [state, onSelectionChange]);
35
+ // Cloning children here to allow users to pass in a custom ListItem or ListSection
36
+ // and still have the SingleSelect handle selection state
37
+ var injectedChildren = useMemo(function () {
38
+ if (! /*#__PURE__*/isValidElement(children)) return null;
39
+ var selectedKeys = state.selectedKey ? new Set([state.selectedKey]) : new Set();
40
+ return /*#__PURE__*/cloneElement(children, {
41
+ selectionMode: 'single',
42
+ selectedKeys: selectedKeys,
43
+ onSelectionChange: handleOnSelectionChange,
44
+ autoFocus: 'first'
45
+ });
46
+ }, [children, handleOnSelectionChange, state.selectedKey]);
47
+ return /*#__PURE__*/React.createElement(SingleSelectContext.Provider, {
48
+ value: {
49
+ isOpen: state.isOpen,
50
+ setOpen: state.setOpen,
51
+ selectedKey: state.selectedKey,
52
+ items: items,
53
+ anchorName: anchorName
54
+ }
55
+ }, /*#__PURE__*/React.createElement(Select
56
+ // TODO: allow user to pass in label
57
+ , __assign({
58
+ "aria-label": 'single-select',
59
+ onSelectionChange: function (key) {
60
+ return handleOnSelectionChange(key != null ? new Set([key]) : new Set());
61
+ },
16
62
  placeholder: ""
17
- }, restProps), /*#__PURE__*/React.createElement(Trigger, null), /*#__PURE__*/React.createElement(Popover, {
18
- className: styles.popover
19
- }, children));
63
+ }, restProps), /*#__PURE__*/React.createElement(Trigger, {
64
+ buttonRef: buttonRef
65
+ }), state.isOpen && (/*#__PURE__*/React.createElement(Popover, {
66
+ buttonRef: buttonRef,
67
+ popoverRef: popoverRef,
68
+ racPopoverRef: racPopoverRef
69
+ }, injectedChildren))));
20
70
  };
21
71
  SingleSelect.displayName = 'SingleSelect';
22
72
  SingleSelect.List = List;
@@ -0,0 +1,10 @@
1
+ import { createContext, useContext } from 'react';
2
+ var SingleSelectContext = /*#__PURE__*/createContext(undefined);
3
+ var useSingleSelectContext = function () {
4
+ var context = useContext(SingleSelectContext);
5
+ if (!context) {
6
+ throw new Error('useSingleSelectContext must be used within a SingleSelectContext.Provider');
7
+ }
8
+ return context;
9
+ };
10
+ export { SingleSelectContext, useSingleSelectContext };
@@ -0,0 +1,49 @@
1
+ import React, { useMemo, useLayoutEffect } from 'react';
2
+ import { Popover as Popover$1 } from 'react-aria-components';
3
+ import { useSingleSelectContext } from '../../context/SingleSelectContext.mjs';
4
+ import { usePositioningStyles } from './utils/usePositioningStyles.mjs';
5
+ import styles from './Popover.module.css.mjs';
6
+ const Popover = /*#__PURE__*/function () {
7
+ const Popover = function (_a) {
8
+ var buttonRef = _a.buttonRef,
9
+ popoverRef = _a.popoverRef,
10
+ racPopoverRef = _a.racPopoverRef,
11
+ children = _a.children;
12
+ var _b = useSingleSelectContext(),
13
+ isOpen = _b.isOpen,
14
+ setOpen = _b.setOpen,
15
+ anchorName = _b.anchorName;
16
+ var _c = usePositioningStyles(buttonRef, popoverRef, anchorName),
17
+ popoverStyle = _c.popoverStyle,
18
+ isPositioned = _c.isPositioned;
19
+ var shouldShowPopover = useMemo(function () {
20
+ return isOpen && isPositioned;
21
+ }, [isOpen, isPositioned]);
22
+ useLayoutEffect(function () {
23
+ var popover = popoverRef.current;
24
+ if (!(popover === null || popover === void 0 ? void 0 : popover.showPopover) || !(popover === null || popover === void 0 ? void 0 : popover.hidePopover)) return;
25
+ if (shouldShowPopover) {
26
+ popover.showPopover();
27
+ } else {
28
+ popover.hidePopover();
29
+ }
30
+ // eslint-disable-next-line react-hooks/exhaustive-deps
31
+ }, [shouldShowPopover]);
32
+ return /*#__PURE__*/React.createElement(Popover$1, {
33
+ shouldUpdatePosition: false,
34
+ trigger: "manual",
35
+ isOpen: isOpen,
36
+ onOpenChange: setOpen,
37
+ ref: racPopoverRef
38
+ }, /*#__PURE__*/React.createElement("div", {
39
+ // @ts-expect-error - popover attribute is not included in current ts version, ignore type error
40
+ popover: "manual",
41
+ ref: popoverRef,
42
+ className: styles.popover,
43
+ style: popoverStyle
44
+ }, children));
45
+ };
46
+ Popover.displayName = 'SingleSelect.Popover';
47
+ return Popover;
48
+ }();
49
+ export { Popover };
@@ -0,0 +1,4 @@
1
+ var styles = {
2
+ "popover": "Popover-module_popover__BjY2S"
3
+ };
4
+ export { styles as default };
@@ -0,0 +1,92 @@
1
+ import { __assign } from 'tslib';
2
+ import { useState, useRef, useCallback, useEffect } from 'react';
3
+ function usePopoverPositioning(_a) {
4
+ var triggerRef = _a.triggerRef,
5
+ popoverRef = _a.popoverRef,
6
+ _b = _a.direction,
7
+ direction = _b === void 0 ? 'ltr' : _b,
8
+ _c = _a.offset,
9
+ offset = _c === void 0 ? 4 : _c,
10
+ _d = _a.preferredPlacement,
11
+ preferredPlacement = _d === void 0 ? 'bottom' : _d;
12
+ var _e = useState({
13
+ top: preferredPlacement === 'bottom' ? offset : 'auto',
14
+ bottom: preferredPlacement === 'top' ? offset : 'auto',
15
+ insetInlineStart: 0,
16
+ maxHeight: 300 // TODO: update this based on designs
17
+ }),
18
+ position = _e[0],
19
+ setPosition = _e[1];
20
+ var _f = useState(true),
21
+ isPositioned = _f[0],
22
+ setIsPositioned = _f[1];
23
+ var mountedRef = useRef(false);
24
+ var isSSR = typeof window === 'undefined';
25
+ var updatePosition = useCallback(function () {
26
+ var _a;
27
+ if (isSSR) return;
28
+ var trigger = triggerRef.current;
29
+ var popover = popoverRef.current;
30
+ if (!mountedRef.current || !trigger || !(popover === null || popover === void 0 ? void 0 : popover.isConnected)) {
31
+ return;
32
+ }
33
+ var triggerRect = trigger.getBoundingClientRect();
34
+ if (!triggerRect) return;
35
+ var doc = trigger.ownerDocument;
36
+ var win = (_a = doc === null || doc === void 0 ? void 0 : doc.defaultView) !== null && _a !== void 0 ? _a : window;
37
+ var isRTL = direction === 'rtl';
38
+ var inlineStart = isRTL ? win.innerWidth - triggerRect.right : triggerRect.left;
39
+ var triggerTop = triggerRect.top;
40
+ var triggerBottom = triggerRect.bottom;
41
+ var viewportHeight = win.innerHeight;
42
+ var spaceAbove = triggerTop;
43
+ var spaceBelow = viewportHeight - triggerBottom;
44
+ var shouldFlip = preferredPlacement === 'bottom' && spaceBelow < 200 && spaceAbove > spaceBelow;
45
+ var top;
46
+ var bottom;
47
+ var maxHeight;
48
+ if (shouldFlip) {
49
+ top = 'auto';
50
+ bottom = viewportHeight - triggerTop + offset;
51
+ maxHeight = Math.max(0, spaceAbove - offset);
52
+ } else {
53
+ top = triggerBottom + offset;
54
+ bottom = 'auto';
55
+ maxHeight = Math.max(0, spaceBelow - offset);
56
+ }
57
+ var newPosition = {
58
+ top: top,
59
+ bottom: bottom,
60
+ insetInlineStart: inlineStart,
61
+ maxHeight: maxHeight
62
+ };
63
+ setPosition(newPosition);
64
+ setIsPositioned(true);
65
+ }, [triggerRef, popoverRef, direction, offset, preferredPlacement, isSSR]);
66
+ useEffect(function () {
67
+ if (typeof window === 'undefined') return;
68
+ mountedRef.current = true;
69
+ var triggerEl = triggerRef.current;
70
+ updatePosition();
71
+ var resizeObserver = new ResizeObserver(function () {
72
+ updatePosition();
73
+ });
74
+ if (triggerEl) resizeObserver.observe(triggerEl);
75
+ var onWindowResize = function () {
76
+ return updatePosition();
77
+ };
78
+ window.addEventListener('resize', onWindowResize, {
79
+ passive: true
80
+ });
81
+ return function () {
82
+ mountedRef.current = false;
83
+ resizeObserver.disconnect();
84
+ window.removeEventListener('resize', onWindowResize);
85
+ setIsPositioned(false);
86
+ };
87
+ }, [updatePosition, triggerRef]);
88
+ return __assign(__assign({}, position), {
89
+ isPositioned: isPositioned
90
+ });
91
+ }
92
+ export { usePopoverPositioning };