@datarobot/design-system 28.2.2 → 28.3.0-experimental

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 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core';
3
3
  import { TooltipPlacementsType } from '../tooltip';
4
4
  import './dropdown-item-title.less';
5
5
  export type DropdownItemTitleOption = {
6
+ key: string | number;
6
7
  iconClass?: string;
7
8
  icon?: IconProp;
8
9
  title?: ReactNode;
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _react = _interopRequireDefault(require("react"));
7
+ var _react = _interopRequireWildcard(require("react"));
8
8
  var _classnames = _interopRequireDefault(require("classnames"));
9
9
  var _faChevronRight = require("@fortawesome/free-solid-svg-icons/faChevronRight");
10
10
  var _fontAwesomeIcon = require("../font-awesome-icon");
@@ -12,6 +12,7 @@ var _truncateWithTooltip = require("../truncate-with-tooltip");
12
12
  var _tooltip = require("../tooltip");
13
13
  var _jsxRuntime = require("react/jsx-runtime");
14
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
15
16
  const DropdownItemTitle = ({
16
17
  option,
17
18
  isMultiLevelHandler = false
@@ -25,7 +26,8 @@ const DropdownItemTitle = ({
25
26
  tooltipPlacement,
26
27
  tooltipText,
27
28
  tooltipDocsLink,
28
- tooltipTestId
29
+ tooltipTestId,
30
+ key
29
31
  } = option;
30
32
  const props = {
31
33
  tooltipText,
@@ -59,14 +61,14 @@ const DropdownItemTitle = ({
59
61
  })
60
62
  });
61
63
  const withTruncatableText = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
62
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_truncateWithTooltip.TruncateWithTooltip, {
64
+ children: [/*#__PURE__*/(0, _react.createElement)(_truncateWithTooltip.TruncateWithTooltip, {
63
65
  ...props,
64
- children: itemTitle
65
- }), subtext && /*#__PURE__*/(0, _jsxRuntime.jsx)(_truncateWithTooltip.TruncateWithTooltip, {
66
+ key: key
67
+ }, itemTitle), subtext && /*#__PURE__*/(0, _react.createElement)(_truncateWithTooltip.TruncateWithTooltip, {
66
68
  ...props,
67
69
  tooltipTestId: `${tooltipTestId}-subtext`,
68
- children: itemSubText
69
- })]
70
+ key: `${key}-subtext`
71
+ }, itemSubText)]
70
72
  });
71
73
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
72
74
  className: (0, _classnames.default)('drop-item-content-wrap', {
@@ -18,11 +18,16 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
18
18
  const DefaultTriggerContent = ({
19
19
  selectedItem,
20
20
  defaultTriggerText
21
- }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_truncateWithTooltip.TruncateWithTooltip, {
22
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
23
- children: selectedItem?.title ?? defaultTriggerText
24
- })
25
- });
21
+ }) => {
22
+ const id = (0, _react.useId)();
23
+ const title = selectedItem?.title ?? defaultTriggerText;
24
+ const key = typeof title === 'string' && title.length ? title : id;
25
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_truncateWithTooltip.TruncateWithTooltip, {
26
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
27
+ children: title
28
+ })
29
+ }, key);
30
+ };
26
31
  const DropdownMenuTrigger = /*#__PURE__*/(0, _react.forwardRef)(({
27
32
  onClick,
28
33
  isOpen,
@@ -31,6 +31,7 @@ const DefaultTriggerContent = function ({
31
31
  });
32
32
  }
33
33
  const triggerContent = getGenericTriggerContent(selectedItem, options);
34
+ const key = selectedItem?.key;
34
35
  if (triggerContent) {
35
36
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
36
37
  className: "selected-item-details",
@@ -38,7 +39,7 @@ const DefaultTriggerContent = function ({
38
39
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
39
40
  children: triggerContent
40
41
  })
41
- })
42
+ }, key)
42
43
  });
43
44
  }
44
45
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_truncateWithTooltip.TruncateWithTooltip, {
@@ -46,7 +47,7 @@ const DefaultTriggerContent = function ({
46
47
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
47
48
  children: defaultTriggerText
48
49
  })
49
- });
50
+ }, key);
50
51
  };
51
52
  function getGenericTriggerContent(selectedItem, options) {
52
53
  const selectedOptions = options.filter(option => option.isChecked).map(option => option.title);
@@ -79,18 +79,7 @@ function InlineEdit({
79
79
  const [touched, setTouched] = (0, _react.useState)(false);
80
80
  const [inputValue, setInputValue] = (0, _react.useState)(value);
81
81
  const [componentId] = (0, _react.useState)(() => (0, _uniqueId.default)());
82
-
83
- // check if 2 elements have autofocus and render in same time
84
- const [isEditMode, setIsEditMode] = (0, _react.useState)(() => {
85
- if (isSomeOneOpen() || readOnly || isLoading) {
86
- return false;
87
- }
88
- if (autoFocus) {
89
- openState.set(componentId, true);
90
- return true;
91
- }
92
- return false;
93
- });
82
+ const [isEditMode, setIsEditMode] = (0, _react.useState)(false);
94
83
  const container = (0, _react.useRef)(null);
95
84
  const handleCancel = () => {
96
85
  setInputValue(value);
@@ -119,6 +108,18 @@ function InlineEdit({
119
108
  (0, _react.useEffect)(() => () => {
120
109
  openState.delete(componentId);
121
110
  }, []);
111
+ (0, _react.useLayoutEffect)(() => {
112
+ // If the component is mounted, autoFocus is true, and there are no other inline edits in edit mode -
113
+ // set the open state and edit mode to true
114
+ // previously it was set in state initialization function but since react 18 that initialization function
115
+ // can be called twice without unmount if 2+ components rendering inline edit are wrapped in Suspense and lazy loaded
116
+ // it results in inline edits being locked up because first id is set to true, however latest render would use different id
117
+ // it turns out to be common react thing: https://stackoverflow.com/questions/73325723/suspense-as-a-root-element-causes-two-instances-of-component-in-production-and
118
+ if (autoFocus && !(isSomeOneOpen() || readOnly || isLoading)) {
119
+ openState.set(componentId, true);
120
+ setIsEditMode(true);
121
+ }
122
+ }, []);
122
123
  const onTextClick = e => {
123
124
  e.preventDefault();
124
125
  if (!isSomeOneOpen() && !readOnly && !isLoading) {
@@ -3,6 +3,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core';
3
3
  import { TooltipPlacementsType } from '../tooltip';
4
4
  import './dropdown-item-title.less';
5
5
  export type DropdownItemTitleOption = {
6
+ key: string | number;
6
7
  iconClass?: string;
7
8
  icon?: IconProp;
8
9
  title?: ReactNode;
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { createElement as _createElement } from 'react';
2
2
  import classnames from 'classnames';
3
3
  import { faChevronRight } from '@fortawesome/free-solid-svg-icons/faChevronRight';
4
4
  import { FontAwesomeIcon } from '../font-awesome-icon';
@@ -18,7 +18,8 @@ const DropdownItemTitle = ({
18
18
  tooltipPlacement,
19
19
  tooltipText,
20
20
  tooltipDocsLink,
21
- tooltipTestId
21
+ tooltipTestId,
22
+ key
22
23
  } = option;
23
24
  const props = {
24
25
  tooltipText,
@@ -52,14 +53,14 @@ const DropdownItemTitle = ({
52
53
  })
53
54
  });
54
55
  const withTruncatableText = /*#__PURE__*/_jsxs(_Fragment, {
55
- children: [/*#__PURE__*/_jsx(TruncateWithTooltip, {
56
+ children: [/*#__PURE__*/_createElement(TruncateWithTooltip, {
56
57
  ...props,
57
- children: itemTitle
58
- }), subtext && /*#__PURE__*/_jsx(TruncateWithTooltip, {
58
+ key: key
59
+ }, itemTitle), subtext && /*#__PURE__*/_createElement(TruncateWithTooltip, {
59
60
  ...props,
60
61
  tooltipTestId: `${tooltipTestId}-subtext`,
61
- children: itemSubText
62
- })]
62
+ key: `${key}-subtext`
63
+ }, itemSubText)]
63
64
  });
64
65
  return /*#__PURE__*/_jsx("div", {
65
66
  className: classnames('drop-item-content-wrap', {
@@ -1,4 +1,4 @@
1
- import React, { forwardRef } from 'react';
1
+ import React, { forwardRef, useId } from 'react';
2
2
  import classNames from 'classnames';
3
3
  import { faChevronDown } from '@fortawesome/free-solid-svg-icons/faChevronDown';
4
4
  import { FontAwesomeIcon } from '../font-awesome-icon';
@@ -10,11 +10,16 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
10
  const DefaultTriggerContent = ({
11
11
  selectedItem,
12
12
  defaultTriggerText
13
- }) => /*#__PURE__*/_jsx(TruncateWithTooltip, {
14
- children: /*#__PURE__*/_jsx("span", {
15
- children: selectedItem?.title ?? defaultTriggerText
16
- })
17
- });
13
+ }) => {
14
+ const id = useId();
15
+ const title = selectedItem?.title ?? defaultTriggerText;
16
+ const key = typeof title === 'string' && title.length ? title : id;
17
+ return /*#__PURE__*/_jsx(TruncateWithTooltip, {
18
+ children: /*#__PURE__*/_jsx("span", {
19
+ children: title
20
+ })
21
+ }, key);
22
+ };
18
23
  const DropdownMenuTrigger = /*#__PURE__*/forwardRef(({
19
24
  onClick,
20
25
  isOpen,
@@ -23,6 +23,7 @@ const DefaultTriggerContent = function ({
23
23
  });
24
24
  }
25
25
  const triggerContent = getGenericTriggerContent(selectedItem, options);
26
+ const key = selectedItem?.key;
26
27
  if (triggerContent) {
27
28
  return /*#__PURE__*/_jsx("span", {
28
29
  className: "selected-item-details",
@@ -30,7 +31,7 @@ const DefaultTriggerContent = function ({
30
31
  children: /*#__PURE__*/_jsx("span", {
31
32
  children: triggerContent
32
33
  })
33
- })
34
+ }, key)
34
35
  });
35
36
  }
36
37
  return /*#__PURE__*/_jsx(TruncateWithTooltip, {
@@ -38,7 +39,7 @@ const DefaultTriggerContent = function ({
38
39
  children: /*#__PURE__*/_jsx("span", {
39
40
  children: defaultTriggerText
40
41
  })
41
- });
42
+ }, key);
42
43
  };
43
44
  function getGenericTriggerContent(selectedItem, options) {
44
45
  const selectedOptions = options.filter(option => option.isChecked).map(option => option.title);
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useMemo, useRef } from 'react';
1
+ import React, { useState, useEffect, useMemo, useRef, useLayoutEffect } from 'react';
2
2
  import cls from 'classnames';
3
3
  import uniqueId from 'lodash-es/uniqueId';
4
4
  import { faPen } from '@fortawesome/free-solid-svg-icons/faPen';
@@ -71,18 +71,7 @@ export default function InlineEdit({
71
71
  const [touched, setTouched] = useState(false);
72
72
  const [inputValue, setInputValue] = useState(value);
73
73
  const [componentId] = useState(() => uniqueId());
74
-
75
- // check if 2 elements have autofocus and render in same time
76
- const [isEditMode, setIsEditMode] = useState(() => {
77
- if (isSomeOneOpen() || readOnly || isLoading) {
78
- return false;
79
- }
80
- if (autoFocus) {
81
- openState.set(componentId, true);
82
- return true;
83
- }
84
- return false;
85
- });
74
+ const [isEditMode, setIsEditMode] = useState(false);
86
75
  const container = useRef(null);
87
76
  const handleCancel = () => {
88
77
  setInputValue(value);
@@ -111,6 +100,18 @@ export default function InlineEdit({
111
100
  useEffect(() => () => {
112
101
  openState.delete(componentId);
113
102
  }, []);
103
+ useLayoutEffect(() => {
104
+ // If the component is mounted, autoFocus is true, and there are no other inline edits in edit mode -
105
+ // set the open state and edit mode to true
106
+ // previously it was set in state initialization function but since react 18 that initialization function
107
+ // can be called twice without unmount if 2+ components rendering inline edit are wrapped in Suspense and lazy loaded
108
+ // it results in inline edits being locked up because first id is set to true, however latest render would use different id
109
+ // it turns out to be common react thing: https://stackoverflow.com/questions/73325723/suspense-as-a-root-element-causes-two-instances-of-component-in-production-and
110
+ if (autoFocus && !(isSomeOneOpen() || readOnly || isLoading)) {
111
+ openState.set(componentId, true);
112
+ setIsEditMode(true);
113
+ }
114
+ }, []);
114
115
  const onTextClick = e => {
115
116
  e.preventDefault();
116
117
  if (!isSomeOneOpen() && !readOnly && !isLoading) {
@@ -50781,7 +50781,8 @@ var DropdownItemTitle = function DropdownItemTitle(_ref) {
50781
50781
  tooltipPlacement = option.tooltipPlacement,
50782
50782
  tooltipText = option.tooltipText,
50783
50783
  tooltipDocsLink = option.tooltipDocsLink,
50784
- tooltipTestId = option.tooltipTestId;
50784
+ tooltipTestId = option.tooltipTestId,
50785
+ key = option.key;
50785
50786
  var props = {
50786
50787
  tooltipText: tooltipText,
50787
50788
  tooltipPlacement: tooltipPlacement || _tooltip__WEBPACK_IMPORTED_MODULE_5__.TOOLTIP_PLACEMENT_TYPES.RIGHT,
@@ -50809,8 +50810,11 @@ var DropdownItemTitle = function DropdownItemTitle(_ref) {
50809
50810
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", {
50810
50811
  className: "menu-item-subtext"
50811
50812
  }, subtext));
50812
- var withTruncatableText = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_truncate_with_tooltip__WEBPACK_IMPORTED_MODULE_4__.TruncateWithTooltip, props, itemTitle), subtext && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_truncate_with_tooltip__WEBPACK_IMPORTED_MODULE_4__.TruncateWithTooltip, _extends({}, props, {
50813
- tooltipTestId: "".concat(tooltipTestId, "-subtext")
50813
+ var withTruncatableText = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_truncate_with_tooltip__WEBPACK_IMPORTED_MODULE_4__.TruncateWithTooltip, _extends({}, props, {
50814
+ key: key
50815
+ }), itemTitle), subtext && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_truncate_with_tooltip__WEBPACK_IMPORTED_MODULE_4__.TruncateWithTooltip, _extends({}, props, {
50816
+ tooltipTestId: "".concat(tooltipTestId, "-subtext"),
50817
+ key: "".concat(key, "-subtext")
50814
50818
  }), itemSubText));
50815
50819
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
50816
50820
  className: classnames__WEBPACK_IMPORTED_MODULE_1___default()('drop-item-content-wrap', {
@@ -51501,7 +51505,12 @@ var DefaultTriggerContent = function DefaultTriggerContent(_ref) {
51501
51505
  var _selectedItem$title;
51502
51506
  var selectedItem = _ref.selectedItem,
51503
51507
  defaultTriggerText = _ref.defaultTriggerText;
51504
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_truncate_with_tooltip__WEBPACK_IMPORTED_MODULE_4__.TruncateWithTooltip, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, (_selectedItem$title = selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.title) !== null && _selectedItem$title !== void 0 ? _selectedItem$title : defaultTriggerText));
51508
+ var id = (0,react__WEBPACK_IMPORTED_MODULE_0__.useId)();
51509
+ var title = (_selectedItem$title = selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.title) !== null && _selectedItem$title !== void 0 ? _selectedItem$title : defaultTriggerText;
51510
+ var key = typeof title === 'string' && title.length ? title : id;
51511
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_truncate_with_tooltip__WEBPACK_IMPORTED_MODULE_4__.TruncateWithTooltip, {
51512
+ key: key
51513
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, title));
51505
51514
  };
51506
51515
  var DropdownMenuTrigger = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(function (_ref2, ref) {
51507
51516
  var onClick = _ref2.onClick,
@@ -52143,13 +52152,17 @@ var DefaultTriggerContent = function DefaultTriggerContent(_ref) {
52143
52152
  });
52144
52153
  }
52145
52154
  var triggerContent = getGenericTriggerContent(selectedItem, options);
52155
+ var key = selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.key;
52146
52156
  if (triggerContent) {
52147
52157
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", {
52148
52158
  className: "selected-item-details"
52149
- }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_truncate_with_tooltip__WEBPACK_IMPORTED_MODULE_5__.TruncateWithTooltip, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, triggerContent)));
52159
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_truncate_with_tooltip__WEBPACK_IMPORTED_MODULE_5__.TruncateWithTooltip, {
52160
+ key: key
52161
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, triggerContent)));
52150
52162
  }
52151
52163
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_truncate_with_tooltip__WEBPACK_IMPORTED_MODULE_5__.TruncateWithTooltip, {
52152
- className: "placeholder"
52164
+ className: "placeholder",
52165
+ key: key
52153
52166
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, defaultTriggerText));
52154
52167
  };
52155
52168
  function getGenericTriggerContent(selectedItem, options) {
@@ -64526,18 +64539,7 @@ function InlineEdit(_ref) {
64526
64539
  }),
64527
64540
  _useState6 = _slicedToArray(_useState5, 1),
64528
64541
  componentId = _useState6[0];
64529
-
64530
- // check if 2 elements have autofocus and render in same time
64531
- var _useState7 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(function () {
64532
- if (isSomeOneOpen() || readOnly || isLoading) {
64533
- return false;
64534
- }
64535
- if (autoFocus) {
64536
- openState.set(componentId, true);
64537
- return true;
64538
- }
64539
- return false;
64540
- }),
64542
+ var _useState7 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false),
64541
64543
  _useState8 = _slicedToArray(_useState7, 2),
64542
64544
  isEditMode = _useState8[0],
64543
64545
  setIsEditMode = _useState8[1];
@@ -64574,6 +64576,18 @@ function InlineEdit(_ref) {
64574
64576
  openState["delete"](componentId);
64575
64577
  };
64576
64578
  }, []);
64579
+ (0,react__WEBPACK_IMPORTED_MODULE_0__.useLayoutEffect)(function () {
64580
+ // If the component is mounted, autoFocus is true, and there are no other inline edits in edit mode -
64581
+ // set the open state and edit mode to true
64582
+ // previously it was set in state initialization function but since react 18 that initialization function
64583
+ // can be called twice without unmount if 2+ components rendering inline edit are wrapped in Suspense and lazy loaded
64584
+ // it results in inline edits being locked up because first id is set to true, however latest render would use different id
64585
+ // it turns out to be common react thing: https://stackoverflow.com/questions/73325723/suspense-as-a-root-element-causes-two-instances-of-component-in-production-and
64586
+ if (autoFocus && !(isSomeOneOpen() || readOnly || isLoading)) {
64587
+ openState.set(componentId, true);
64588
+ setIsEditMode(true);
64589
+ }
64590
+ }, []);
64577
64591
  var onTextClick = function onTextClick(e) {
64578
64592
  e.preventDefault();
64579
64593
  if (!isSomeOneOpen() && !readOnly && !isLoading) {