@equinor/eds-core-react 0.46.0 → 0.48.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 (45) hide show
  1. package/dist/eds-core-react.cjs +130 -33
  2. package/dist/esm/components/Autocomplete/AddNewOption.js +45 -0
  3. package/dist/esm/components/Autocomplete/Autocomplete.js +58 -11
  4. package/dist/esm/components/Autocomplete/Autocomplete.tokens.js +1 -1
  5. package/dist/esm/components/Autocomplete/Option.js +1 -1
  6. package/dist/esm/components/Button/tokens/contained.js +1 -1
  7. package/dist/esm/components/Button/tokens/contained_icon.js +1 -1
  8. package/dist/esm/components/Button/tokens/ghost.js +1 -1
  9. package/dist/esm/components/Button/tokens/icon.js +1 -1
  10. package/dist/esm/components/Button/tokens/outlined.js +1 -1
  11. package/dist/esm/components/Datepicker/calendars/Calendar.js +1 -0
  12. package/dist/esm/components/Datepicker/calendars/CalendarHeader.js +8 -3
  13. package/dist/esm/components/Datepicker/calendars/RangeCalendar.js +2 -1
  14. package/dist/esm/components/Datepicker/calendars/YearGrid.js +2 -6
  15. package/dist/esm/components/Datepicker/utils/getPageYears.js +10 -0
  16. package/dist/esm/components/Input/Input.tokens.js +1 -1
  17. package/dist/esm/components/InputWrapper/InputWrapper.tokens.js +1 -1
  18. package/dist/esm/components/Menu/MenuItem.js +3 -3
  19. package/dist/esm/components/Table/DataCell/DataCell.tokens.js +1 -1
  20. package/dist/esm/components/Table/index.js +1 -1
  21. package/dist/esm/components/Tabs/TabList.js +10 -6
  22. package/dist/esm/components/Tabs/TabPanels.js +2 -2
  23. package/dist/esm/components/Tooltip/Tooltip.js +2 -1
  24. package/dist/esm/index.js +1 -1
  25. package/dist/esm/node_modules/.pnpm/{ramda@0.30.1 → ramda@0.31.3}/node_modules/ramda/es/mergeDeepRight.js +1 -1
  26. package/dist/esm/node_modules/.pnpm/{ramda@0.30.1 → ramda@0.31.3}/node_modules/ramda/es/mergeWith.js +1 -1
  27. package/dist/esm/node_modules/.pnpm/{ramda@0.30.1 → ramda@0.31.3}/node_modules/ramda/es/mergeWithKey.js +1 -1
  28. package/dist/types/components/Autocomplete/AddNewOption.d.ts +13 -0
  29. package/dist/types/components/Autocomplete/Autocomplete.d.ts +4 -0
  30. package/dist/types/components/Autocomplete/Option.d.ts +6 -0
  31. package/dist/types/components/Datepicker/calendars/CalendarHeader.d.ts +2 -1
  32. package/dist/types/components/Datepicker/utils/getPageYears.d.ts +1 -0
  33. package/dist/types/components/Table/index.d.ts +3 -3
  34. package/dist/types/components/Tabs/Tabs.context.d.ts +1 -1
  35. package/dist/types/components/Tabs/Tabs.d.ts +2 -2
  36. package/dist/types/components/Tooltip/Tooltip.d.ts +4 -0
  37. package/package.json +8 -8
  38. /package/dist/esm/node_modules/.pnpm/{ramda@0.30.1 → ramda@0.31.3}/node_modules/ramda/es/internal/_curry1.js +0 -0
  39. /package/dist/esm/node_modules/.pnpm/{ramda@0.30.1 → ramda@0.31.3}/node_modules/ramda/es/internal/_curry2.js +0 -0
  40. /package/dist/esm/node_modules/.pnpm/{ramda@0.30.1 → ramda@0.31.3}/node_modules/ramda/es/internal/_curry3.js +0 -0
  41. /package/dist/esm/node_modules/.pnpm/{ramda@0.30.1 → ramda@0.31.3}/node_modules/ramda/es/internal/_has.js +0 -0
  42. /package/dist/esm/node_modules/.pnpm/{ramda@0.30.1 → ramda@0.31.3}/node_modules/ramda/es/internal/_isObject.js +0 -0
  43. /package/dist/esm/node_modules/.pnpm/{ramda@0.30.1 → ramda@0.31.3}/node_modules/ramda/es/internal/_isPlaceholder.js +0 -0
  44. /package/dist/esm/node_modules/.pnpm/{ramda@0.30.1 → ramda@0.31.3}/node_modules/ramda/es/mergeDeepWithKey.js +0 -0
  45. /package/dist/esm/node_modules/.pnpm/{ramda@0.30.1 → ramda@0.31.3}/node_modules/ramda/es/pickBy.js +0 -0
@@ -269,7 +269,7 @@ function _isObject(x) {
269
269
  * @param {Object} l
270
270
  * @param {Object} r
271
271
  * @return {Object}
272
- * @see R.mergeDeepWithKey, R.merge, R.mergeWith
272
+ * @see R.mergeDeepWithKey, R.mergeWith
273
273
  * @example
274
274
  *
275
275
  * let concatValues = (k, l, r) => k == 'values' ? R.concat(l, r) : r
@@ -349,7 +349,7 @@ var mergeDeepWithKey = /*#__PURE__*/_curry3(function mergeDeepWithKey(fn, lObj,
349
349
  * @param {Object} lObj
350
350
  * @param {Object} rObj
351
351
  * @return {Object}
352
- * @see R.merge, R.mergeDeepLeft, R.mergeDeepWith, R.mergeDeepWithKey
352
+ * @see R.mergeDeepLeft, R.mergeDeepWith, R.mergeDeepWithKey
353
353
  * @example
354
354
  *
355
355
  * R.mergeDeepRight({ name: 'fred', age: 10, contact: { email: 'moo@example.com' }},
@@ -377,7 +377,7 @@ var mergeDeepRight = /*#__PURE__*/_curry2(function mergeDeepRight(lObj, rObj) {
377
377
  * @param {Object} l
378
378
  * @param {Object} r
379
379
  * @return {Object}
380
- * @see R.mergeDeepWith, R.merge, R.mergeWithKey
380
+ * @see R.mergeDeepWith, R.mergeWithKey
381
381
  * @example
382
382
  *
383
383
  * R.mergeWith(R.concat,
@@ -1149,6 +1149,7 @@ const Tooltip$2 = /*#__PURE__*/react.forwardRef(function Tooltip({
1149
1149
  children,
1150
1150
  style,
1151
1151
  enterDelay = 100,
1152
+ disabled = false,
1152
1153
  portalContainer,
1153
1154
  ...rest
1154
1155
  }, ref) {
@@ -1264,7 +1265,7 @@ const Tooltip$2 = /*#__PURE__*/react.forwardRef(function Tooltip({
1264
1265
  })]
1265
1266
  });
1266
1267
  return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
1267
- children: [shouldOpen && open && /*#__PURE__*/reactDom.createPortal(TooltipEl, portalContainer ?? rootElement ?? document.body), updatedChildren]
1268
+ children: [shouldOpen && open && !disabled && /*#__PURE__*/reactDom.createPortal(TooltipEl, portalContainer ?? rootElement ?? document.body), updatedChildren]
1268
1269
  });
1269
1270
  });
1270
1271
 
@@ -3998,20 +3999,24 @@ const TabList = /*#__PURE__*/react.forwardRef(function TabsList({
3998
3999
  }
3999
4000
  }, [arrowNavigating, tabsFocused]);
4000
4001
  const Tabs = react.Children.map(children, (child, $index) => {
4001
- const childProps = child.props;
4002
+ if (! /*#__PURE__*/react.isValidElement(child)) {
4003
+ return null;
4004
+ }
4005
+ const tabChild = child;
4006
+ const childProps = tabChild.props;
4002
4007
  const controlledActive = childProps.value;
4003
4008
  const isActive = controlledActive ? controlledActive === activeTab : $index === activeTab;
4004
- const tabRef = isActive ? edsUtils.mergeRefs(child.ref, selectedTabRef) : child.ref;
4009
+ const tabRef = isActive ? edsUtils.mergeRefs(tabChild.ref, selectedTabRef) : tabChild.ref;
4005
4010
  if (isActive) currentTab.current = $index;
4006
- return /*#__PURE__*/react.cloneElement(child, {
4011
+ return /*#__PURE__*/react.cloneElement(tabChild, {
4007
4012
  id: `${tabsId}-tab-${$index + 1}`,
4008
4013
  'aria-controls': `${tabsId}-panel-${$index + 1}`,
4009
4014
  active: isActive,
4010
4015
  $index,
4011
- onClick: () => handleChange($index),
4016
+ onClick: () => handleChange(controlledActive !== undefined ? controlledActive : $index),
4012
4017
  ref: tabRef
4013
4018
  });
4014
- });
4019
+ }) ?? [];
4015
4020
  const focusableChildren = Tabs.filter(child => {
4016
4021
  const childProps = child.props;
4017
4022
  return !childProps.disabled;
@@ -4098,7 +4103,7 @@ const TabPanels = /*#__PURE__*/react.forwardRef(function TabPanels({
4098
4103
  tabsId
4099
4104
  } = react.useContext(TabsContext);
4100
4105
  const Panels = react.Children.map(children, (child, $index) => {
4101
- if (conditionalRender && activeTab !== $index) return null;
4106
+ if (! /*#__PURE__*/react.isValidElement(child) || conditionalRender && activeTab !== $index) return null;
4102
4107
  return /*#__PURE__*/react.cloneElement(child, {
4103
4108
  id: `${tabsId}-panel-${$index + 1}`,
4104
4109
  'aria-labelledby': `${tabsId}-tab-${$index + 1}`,
@@ -7760,9 +7765,9 @@ const MenuItem$1 = /*#__PURE__*/react.forwardRef(function MenuItem({
7760
7765
  onClick: e => {
7761
7766
  if (onClick) {
7762
7767
  onClick(e);
7763
- if (onClose !== null && closeMenuOnClick) {
7764
- onClose(e);
7765
- }
7768
+ }
7769
+ if (onClose !== null && closeMenuOnClick) {
7770
+ onClose(e);
7766
7771
  }
7767
7772
  },
7768
7773
  children: /*#__PURE__*/jsxRuntime.jsx(Content, {
@@ -9500,11 +9505,49 @@ function AutocompleteOptionInner(props, ref) {
9500
9505
  }
9501
9506
  const AutocompleteOption = /*#__PURE__*/react.forwardRef(AutocompleteOptionInner);
9502
9507
 
9508
+ const StyledAddItemIcon = styled__default.default(Icon$1).withConfig({
9509
+ displayName: "AddNewOption__StyledAddItemIcon",
9510
+ componentId: "sc-8xtrxx-0"
9511
+ })(({
9512
+ multiple
9513
+ }) => {
9514
+ return styled.css(["padding:", ";color:", ";"], multiple ? '0.75rem' : '0 0.75rem 0 0', edsTokens.tokens.colors.interactive.primary__resting.hex);
9515
+ });
9516
+ function AddNewOptionInner(props, ref) {
9517
+ const {
9518
+ value,
9519
+ multiline,
9520
+ multiple,
9521
+ highlighted,
9522
+ onClick,
9523
+ ...other
9524
+ } = props;
9525
+ return /*#__PURE__*/jsxRuntime.jsxs(StyledListItem, {
9526
+ ref: ref,
9527
+ $highlighted: highlighted,
9528
+ "aria-label": `Add new option: ${value}`,
9529
+ onClick: e => {
9530
+ onClick(e);
9531
+ },
9532
+ ...other,
9533
+ children: [/*#__PURE__*/jsxRuntime.jsx(StyledAddItemIcon, {
9534
+ multiple: multiple,
9535
+ data: edsIcons.add_box
9536
+ }), /*#__PURE__*/jsxRuntime.jsx(AutocompleteOptionLabel, {
9537
+ $multiline: multiline,
9538
+ children: value
9539
+ })]
9540
+ });
9541
+ }
9542
+ const AddNewOption = /*#__PURE__*/react.forwardRef(AddNewOptionInner);
9543
+
9503
9544
  const Container$2 = styled__default.default.div.withConfig({
9504
9545
  displayName: "Autocomplete__Container",
9505
9546
  componentId: "sc-yvif0e-0"
9506
9547
  })(["position:relative;"]);
9507
9548
  const AllSymbol = Symbol('Select all');
9549
+ const AddSymbol = Symbol('Add new');
9550
+
9508
9551
  // MARK: styled components
9509
9552
  const StyledList = styled__default.default(List$1).withConfig({
9510
9553
  displayName: "Autocomplete__StyledList",
@@ -9638,6 +9681,7 @@ const defaultOptionDisabled = () => false;
9638
9681
  function AutocompleteInner(props, ref) {
9639
9682
  const {
9640
9683
  options = [],
9684
+ totalOptions,
9641
9685
  label,
9642
9686
  meta,
9643
9687
  className,
@@ -9647,6 +9691,7 @@ function AutocompleteInner(props, ref) {
9647
9691
  loading = false,
9648
9692
  hideClearButton = false,
9649
9693
  onOptionsChange,
9694
+ onAddNewOption,
9650
9695
  onInputChange,
9651
9696
  selectedOptions: _selectedOptions,
9652
9697
  multiple,
@@ -9701,8 +9746,9 @@ function AutocompleteInner(props, ref) {
9701
9746
  }, [allowSelectAll, multiple, typedInputValue]);
9702
9747
  const availableItems = react.useMemo(() => {
9703
9748
  if (showSelectAll) return [AllSymbol, ..._availableItems];
9749
+ if (_availableItems.length === 0 && onAddNewOption) return [AddSymbol];
9704
9750
  return _availableItems;
9705
- }, [_availableItems, showSelectAll]);
9751
+ }, [_availableItems, showSelectAll, onAddNewOption]);
9706
9752
 
9707
9753
  //issue 2304, update dataset when options are added dynamically
9708
9754
  react.useEffect(() => {
@@ -9732,7 +9778,7 @@ function AutocompleteInner(props, ref) {
9732
9778
  ...multipleSelectionProps,
9733
9779
  onSelectedItemsChange: changes => {
9734
9780
  if (onOptionsChange) {
9735
- let selectedItems = changes.selectedItems.filter(item => item !== AllSymbol);
9781
+ let selectedItems = changes.selectedItems.filter(item => item !== AllSymbol || item !== AddSymbol);
9736
9782
  if (itemCompare) {
9737
9783
  selectedItems = inputOptions.filter(item => selectedItems.some(compare => itemCompare(item, compare)));
9738
9784
  }
@@ -9785,12 +9831,10 @@ function AutocompleteInner(props, ref) {
9785
9831
  if (item == null) {
9786
9832
  return '';
9787
9833
  }
9788
- if (typeof item === 'object') {
9789
- if (optionLabel) {
9790
- return optionLabel(item);
9791
- } else {
9792
- throw new Error('Missing label. When using objects for options make sure to define the `optionLabel` property');
9793
- }
9834
+ if (optionLabel) {
9835
+ return optionLabel(item);
9836
+ } else if (typeof item === 'object') {
9837
+ throw new Error('Missing label. When using objects for options make sure to define the `optionLabel` property');
9794
9838
  }
9795
9839
  if (typeof item === 'string') {
9796
9840
  return item;
@@ -9878,6 +9922,8 @@ function AutocompleteInner(props, ref) {
9878
9922
  if (selectedItem != null && !optionDisabled(selectedItem)) {
9879
9923
  if (selectedItem === AllSymbol) {
9880
9924
  toggleAllSelected();
9925
+ } else if (selectedItem === AddSymbol) {
9926
+ onAddNewOption?.(typedInputValue);
9881
9927
  } else if (multiple) {
9882
9928
  const shouldRemove = itemCompare ? selectedItems.some(i => itemCompare(selectedItem, i)) : selectedItems.includes(selectedItem);
9883
9929
  if (shouldRemove) {
@@ -9921,11 +9967,27 @@ function AutocompleteInner(props, ref) {
9921
9967
  ...changes,
9922
9968
  isOpen: !(disabled || readOnly)
9923
9969
  };
9970
+ case downshift.useCombobox.stateChangeTypes.InputKeyDownEnter:
9971
+ case downshift.useCombobox.stateChangeTypes.ItemClick:
9972
+ if (changes.selectedItem === AddSymbol) {
9973
+ return {
9974
+ ...changes,
9975
+ inputValue: ''
9976
+ };
9977
+ }
9978
+ return {
9979
+ ...changes
9980
+ };
9924
9981
  case downshift.useCombobox.stateChangeTypes.InputBlur:
9925
9982
  return {
9926
9983
  ...changes,
9927
9984
  inputValue: changes.selectedItem ? getLabel(changes.selectedItem) : ''
9928
9985
  };
9986
+ case downshift.useCombobox.stateChangeTypes.InputChange:
9987
+ setTypedInputValue(changes.inputValue);
9988
+ return {
9989
+ ...changes
9990
+ };
9929
9991
  case downshift.useCombobox.stateChangeTypes.InputKeyDownArrowDown:
9930
9992
  case downshift.useCombobox.stateChangeTypes.InputKeyDownHome:
9931
9993
  if (readOnly) {
@@ -9979,7 +10041,9 @@ function AutocompleteInner(props, ref) {
9979
10041
  }
9980
10042
  // MARK: multiselect specific
9981
10043
  if (multiple) {
9982
- placeholderText = typeof placeholderText !== 'undefined' ? placeholderText : `${selectedItems.length}/${inputOptions.length} selected`;
10044
+ const showPlaceholder = placeholderText && selectedItems.length === 0;
10045
+ const optionCount = totalOptions || inputOptions.length;
10046
+ placeholderText = showPlaceholder ? placeholderText : `${selectedItems.length}/${optionCount} selected`;
9983
10047
  comboBoxProps = {
9984
10048
  ...comboBoxProps,
9985
10049
  selectedItem: null,
@@ -10196,6 +10260,29 @@ function AutocompleteInner(props, ref) {
10196
10260
  })
10197
10261
  }, 'select-all');
10198
10262
  }
10263
+ if (item === AddSymbol && onAddNewOption) {
10264
+ return /*#__PURE__*/jsxRuntime.jsx(AddNewOption, {
10265
+ "data-index": 0,
10266
+ "data-testid": 'add-item',
10267
+ "aria-setsize": availableItems.length,
10268
+ multiple: multiple,
10269
+ highlighted: highlightedIndex === index && !isDisabled ? 'true' : 'false',
10270
+ multiline: multiline,
10271
+ style: {
10272
+ position: 'sticky',
10273
+ top: 0,
10274
+ zIndex: 99
10275
+ },
10276
+ ...getItemProps({
10277
+ ...(multiline && {
10278
+ ref: rowVirtualizer.measureElement
10279
+ }),
10280
+ item,
10281
+ index: index
10282
+ }),
10283
+ value: `${typedInputValue}`
10284
+ }, 'add-item');
10285
+ }
10199
10286
  return /*#__PURE__*/jsxRuntime.jsx(AutocompleteOption, {
10200
10287
  "data-index": index,
10201
10288
  "aria-setsize": availableItems.length,
@@ -11299,6 +11386,15 @@ function CalendarCell({
11299
11386
  });
11300
11387
  }
11301
11388
 
11389
+ const TOTAL_VISIBLE_YEARS = 36;
11390
+ const RANGE_OFFSET = 30 / 2;
11391
+ const getPageYears = (selectedYear, yearPickerPage = 0) => {
11392
+ const page = yearPickerPage * TOTAL_VISIBLE_YEARS;
11393
+ return Array.from({
11394
+ length: TOTAL_VISIBLE_YEARS
11395
+ }, (_, i) => i + (selectedYear + page - RANGE_OFFSET));
11396
+ };
11397
+
11302
11398
  // Disable no-autofocus - it's not the native autofocus attribute, but react-aria's autoFocus prop
11303
11399
  /* eslint-disable jsx-a11y/no-autofocus */
11304
11400
  const Grid = styled__default.default.div.withConfig({
@@ -11311,8 +11407,6 @@ const GridColumn = styled__default.default.button.withConfig({
11311
11407
  })(["background-color:transparent;outline:none;border:none;display:flex;justify-content:center;cursor:pointer;padding:8px;font-size:", ";font-family:", ";font-weight:", ";line-height:", ";color:", ";border-radius:999px;", ";&:hover{background-color:#f0f0f0;}&:focus{outline:2px dashed ", ";}"], edsTokens.tokens.typography.navigation.button.fontSize, edsTokens.tokens.typography.navigation.button.fontFamily, edsTokens.tokens.typography.navigation.button.fontWeight, edsTokens.tokens.typography.navigation.button.lineHeight, edsTokens.tokens.colors.text.static_icons__default.rgba, ({
11312
11408
  $active
11313
11409
  }) => $active ? `background-color: ${edsTokens.tokens.colors.interactive.primary__selected_highlight.rgba}` : '', edsTokens.tokens.colors.interactive.primary__resting.rgba);
11314
- const TOTAL_VISIBLE_YEARS = 36;
11315
- const RANGE_OFFSET = 30 / 2;
11316
11410
  const GridFocusManager = ({
11317
11411
  year: selectedYear,
11318
11412
  setFocusedYear,
@@ -11322,10 +11416,7 @@ const GridFocusManager = ({
11322
11416
  const focusManager = reactAria.useFocusManager();
11323
11417
  const prevYear = react.useRef();
11324
11418
  const navByKeyboard = react.useRef(false);
11325
- const page = yearPickerPage * TOTAL_VISIBLE_YEARS;
11326
- const years = Array.from({
11327
- length: TOTAL_VISIBLE_YEARS
11328
- }, (_, i) => i + (selectedYear + page - RANGE_OFFSET));
11419
+ const years = getPageYears(selectedYear, yearPickerPage);
11329
11420
  react.useEffect(() => {
11330
11421
  if (prevYear.current === undefined) {
11331
11422
  prevYear.current = yearPickerPage;
@@ -11528,14 +11619,18 @@ function CalendarHeader({
11528
11619
  nextMonthDisabled,
11529
11620
  showYearPicker,
11530
11621
  setShowYearPicker,
11531
- setYearPickerPage
11622
+ setYearPickerPage,
11623
+ yearPickerPage
11532
11624
  }) {
11625
+ const years = getPageYears(state.focusedDate.year, yearPickerPage);
11626
+ const backButtonDisabled = showYearPicker && state.minValue ? years[0] < state.minValue.year : previousMonthDisabled;
11627
+ const nextButtonDisabled = showYearPicker && state.maxValue ? years[years.length - 1] > state.maxValue.year : nextMonthDisabled;
11533
11628
  return /*#__PURE__*/jsxRuntime.jsx(HeaderWrapper, {
11534
11629
  children: /*#__PURE__*/jsxRuntime.jsxs(HeaderActions, {
11535
11630
  children: [/*#__PURE__*/jsxRuntime.jsx(Button$1, {
11536
11631
  variant: 'ghost_icon',
11537
11632
  "aria-label": 'Previous month',
11538
- disabled: previousMonthDisabled,
11633
+ disabled: backButtonDisabled,
11539
11634
  onClick: () => showYearPicker ? setYearPickerPage(page => page - 1) : state.focusPreviousPage(),
11540
11635
  children: /*#__PURE__*/jsxRuntime.jsx(Icon$1, {
11541
11636
  data: edsIcons.chevron_left
@@ -11566,7 +11661,7 @@ function CalendarHeader({
11566
11661
  }), /*#__PURE__*/jsxRuntime.jsx(Button$1, {
11567
11662
  variant: 'ghost_icon',
11568
11663
  onClick: () => showYearPicker ? setYearPickerPage(page => page + 1) : state.focusNextPage(),
11569
- disabled: nextMonthDisabled,
11664
+ disabled: nextButtonDisabled,
11570
11665
  "aria-label": 'Next month',
11571
11666
  children: /*#__PURE__*/jsxRuntime.jsx(Icon$1, {
11572
11667
  data: edsIcons.chevron_right
@@ -11626,6 +11721,7 @@ const Calendar = /*#__PURE__*/react.forwardRef(({
11626
11721
  nextMonthDisabled: nextButtonProps.isDisabled,
11627
11722
  setShowYearPicker: setShowYearPicker,
11628
11723
  showYearPicker: showYearPicker,
11724
+ yearPickerPage: yearPickerPage,
11629
11725
  setYearPickerPage: setYearPickerPage
11630
11726
  })
11631
11727
  }), /*#__PURE__*/jsxRuntime.jsx(Popover.Content, {
@@ -12221,7 +12317,8 @@ const RangeCalendar = /*#__PURE__*/react.forwardRef(({
12221
12317
  title: title,
12222
12318
  setShowYearPicker: setShowYearPicker,
12223
12319
  showYearPicker: showYearPicker,
12224
- setYearPickerPage: setYearPickerPage
12320
+ setYearPickerPage: setYearPickerPage,
12321
+ yearPickerPage: yearPickerPage
12225
12322
  })
12226
12323
  }), /*#__PURE__*/jsxRuntime.jsx(Popover.Content, {
12227
12324
  children: /*#__PURE__*/jsxRuntime.jsx(CalendarGrid, {
@@ -12524,6 +12621,7 @@ exports.TableFoot = Foot;
12524
12621
  exports.TableHead = Head;
12525
12622
  exports.TableOfContents = TableOfContents;
12526
12623
  exports.TableOfContentsLinkItem = LinkItem;
12624
+ exports.TableRow = Row;
12527
12625
  exports.Tabs = Tabs;
12528
12626
  exports.TextField = TextField;
12529
12627
  exports.ToggleButton = ToggleButton;
@@ -12533,6 +12631,5 @@ exports.TopbarActions = Actions;
12533
12631
  exports.TopbarCustomContent = CustomContent;
12534
12632
  exports.TopbarHeader = Header$2;
12535
12633
  exports.Typography = Typography;
12536
- exports.tableRow = Row;
12537
12634
  exports.useEds = useEds;
12538
12635
  exports.useSideBar = useSideBar;
@@ -0,0 +1,45 @@
1
+ import { add_box } from '@equinor/eds-icons';
2
+ import { tokens } from '@equinor/eds-tokens';
3
+ import { forwardRef } from 'react';
4
+ import styled, { css } from 'styled-components';
5
+ import { Icon } from '../Icon/index.js';
6
+ import { StyledListItem, AutocompleteOptionLabel } from './Option.js';
7
+ import { jsxs, jsx } from 'react/jsx-runtime';
8
+
9
+ const StyledAddItemIcon = styled(Icon).withConfig({
10
+ displayName: "AddNewOption__StyledAddItemIcon",
11
+ componentId: "sc-8xtrxx-0"
12
+ })(({
13
+ multiple
14
+ }) => {
15
+ return css(["padding:", ";color:", ";"], multiple ? '0.75rem' : '0 0.75rem 0 0', tokens.colors.interactive.primary__resting.hex);
16
+ });
17
+ function AddNewOptionInner(props, ref) {
18
+ const {
19
+ value,
20
+ multiline,
21
+ multiple,
22
+ highlighted,
23
+ onClick,
24
+ ...other
25
+ } = props;
26
+ return /*#__PURE__*/jsxs(StyledListItem, {
27
+ ref: ref,
28
+ $highlighted: highlighted,
29
+ "aria-label": `Add new option: ${value}`,
30
+ onClick: e => {
31
+ onClick(e);
32
+ },
33
+ ...other,
34
+ children: [/*#__PURE__*/jsx(StyledAddItemIcon, {
35
+ multiple: multiple,
36
+ data: add_box
37
+ }), /*#__PURE__*/jsx(AutocompleteOptionLabel, {
38
+ $multiline: multiline,
39
+ children: value
40
+ })]
41
+ });
42
+ }
43
+ const AddNewOption = /*#__PURE__*/forwardRef(AddNewOptionInner);
44
+
45
+ export { AddNewOption };
@@ -11,9 +11,10 @@ import { multiSelect, selectTokens } from './Autocomplete.tokens.js';
11
11
  import { useToken, useIsomorphicLayoutEffect, bordersTemplate } from '@equinor/eds-utils';
12
12
  import { AutocompleteOption } from './Option.js';
13
13
  import { useFloating, offset, flip, size, useInteractions, autoUpdate } from '@floating-ui/react';
14
+ import { AddNewOption } from './AddNewOption.js';
14
15
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
15
- import pickBy from '../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/pickBy.js';
16
- import mergeWith from '../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/mergeWith.js';
16
+ import pickBy from '../../node_modules/.pnpm/ramda@0.31.3/node_modules/ramda/es/pickBy.js';
17
+ import mergeWith from '../../node_modules/.pnpm/ramda@0.31.3/node_modules/ramda/es/mergeWith.js';
17
18
  import { useEds } from '../EdsProvider/eds.context.js';
18
19
  import { Label } from '../Label/Label.js';
19
20
  import { Input } from '../Input/Input.js';
@@ -24,6 +25,8 @@ const Container = styled.div.withConfig({
24
25
  componentId: "sc-yvif0e-0"
25
26
  })(["position:relative;"]);
26
27
  const AllSymbol = Symbol('Select all');
28
+ const AddSymbol = Symbol('Add new');
29
+
27
30
  // MARK: styled components
28
31
  const StyledList = styled(List).withConfig({
29
32
  displayName: "Autocomplete__StyledList",
@@ -157,6 +160,7 @@ const defaultOptionDisabled = () => false;
157
160
  function AutocompleteInner(props, ref) {
158
161
  const {
159
162
  options = [],
163
+ totalOptions,
160
164
  label,
161
165
  meta,
162
166
  className,
@@ -166,6 +170,7 @@ function AutocompleteInner(props, ref) {
166
170
  loading = false,
167
171
  hideClearButton = false,
168
172
  onOptionsChange,
173
+ onAddNewOption,
169
174
  onInputChange,
170
175
  selectedOptions: _selectedOptions,
171
176
  multiple,
@@ -220,8 +225,9 @@ function AutocompleteInner(props, ref) {
220
225
  }, [allowSelectAll, multiple, typedInputValue]);
221
226
  const availableItems = useMemo(() => {
222
227
  if (showSelectAll) return [AllSymbol, ..._availableItems];
228
+ if (_availableItems.length === 0 && onAddNewOption) return [AddSymbol];
223
229
  return _availableItems;
224
- }, [_availableItems, showSelectAll]);
230
+ }, [_availableItems, showSelectAll, onAddNewOption]);
225
231
 
226
232
  //issue 2304, update dataset when options are added dynamically
227
233
  useEffect(() => {
@@ -251,7 +257,7 @@ function AutocompleteInner(props, ref) {
251
257
  ...multipleSelectionProps,
252
258
  onSelectedItemsChange: changes => {
253
259
  if (onOptionsChange) {
254
- let selectedItems = changes.selectedItems.filter(item => item !== AllSymbol);
260
+ let selectedItems = changes.selectedItems.filter(item => item !== AllSymbol || item !== AddSymbol);
255
261
  if (itemCompare) {
256
262
  selectedItems = inputOptions.filter(item => selectedItems.some(compare => itemCompare(item, compare)));
257
263
  }
@@ -304,12 +310,10 @@ function AutocompleteInner(props, ref) {
304
310
  if (item == null) {
305
311
  return '';
306
312
  }
307
- if (typeof item === 'object') {
308
- if (optionLabel) {
309
- return optionLabel(item);
310
- } else {
311
- throw new Error('Missing label. When using objects for options make sure to define the `optionLabel` property');
312
- }
313
+ if (optionLabel) {
314
+ return optionLabel(item);
315
+ } else if (typeof item === 'object') {
316
+ throw new Error('Missing label. When using objects for options make sure to define the `optionLabel` property');
313
317
  }
314
318
  if (typeof item === 'string') {
315
319
  return item;
@@ -397,6 +401,8 @@ function AutocompleteInner(props, ref) {
397
401
  if (selectedItem != null && !optionDisabled(selectedItem)) {
398
402
  if (selectedItem === AllSymbol) {
399
403
  toggleAllSelected();
404
+ } else if (selectedItem === AddSymbol) {
405
+ onAddNewOption?.(typedInputValue);
400
406
  } else if (multiple) {
401
407
  const shouldRemove = itemCompare ? selectedItems.some(i => itemCompare(selectedItem, i)) : selectedItems.includes(selectedItem);
402
408
  if (shouldRemove) {
@@ -440,11 +446,27 @@ function AutocompleteInner(props, ref) {
440
446
  ...changes,
441
447
  isOpen: !(disabled || readOnly)
442
448
  };
449
+ case useCombobox.stateChangeTypes.InputKeyDownEnter:
450
+ case useCombobox.stateChangeTypes.ItemClick:
451
+ if (changes.selectedItem === AddSymbol) {
452
+ return {
453
+ ...changes,
454
+ inputValue: ''
455
+ };
456
+ }
457
+ return {
458
+ ...changes
459
+ };
443
460
  case useCombobox.stateChangeTypes.InputBlur:
444
461
  return {
445
462
  ...changes,
446
463
  inputValue: changes.selectedItem ? getLabel(changes.selectedItem) : ''
447
464
  };
465
+ case useCombobox.stateChangeTypes.InputChange:
466
+ setTypedInputValue(changes.inputValue);
467
+ return {
468
+ ...changes
469
+ };
448
470
  case useCombobox.stateChangeTypes.InputKeyDownArrowDown:
449
471
  case useCombobox.stateChangeTypes.InputKeyDownHome:
450
472
  if (readOnly) {
@@ -498,7 +520,9 @@ function AutocompleteInner(props, ref) {
498
520
  }
499
521
  // MARK: multiselect specific
500
522
  if (multiple) {
501
- placeholderText = typeof placeholderText !== 'undefined' ? placeholderText : `${selectedItems.length}/${inputOptions.length} selected`;
523
+ const showPlaceholder = placeholderText && selectedItems.length === 0;
524
+ const optionCount = totalOptions || inputOptions.length;
525
+ placeholderText = showPlaceholder ? placeholderText : `${selectedItems.length}/${optionCount} selected`;
502
526
  comboBoxProps = {
503
527
  ...comboBoxProps,
504
528
  selectedItem: null,
@@ -715,6 +739,29 @@ function AutocompleteInner(props, ref) {
715
739
  })
716
740
  }, 'select-all');
717
741
  }
742
+ if (item === AddSymbol && onAddNewOption) {
743
+ return /*#__PURE__*/jsx(AddNewOption, {
744
+ "data-index": 0,
745
+ "data-testid": 'add-item',
746
+ "aria-setsize": availableItems.length,
747
+ multiple: multiple,
748
+ highlighted: highlightedIndex === index && !isDisabled ? 'true' : 'false',
749
+ multiline: multiline,
750
+ style: {
751
+ position: 'sticky',
752
+ top: 0,
753
+ zIndex: 99
754
+ },
755
+ ...getItemProps({
756
+ ...(multiline && {
757
+ ref: rowVirtualizer.measureElement
758
+ }),
759
+ item,
760
+ index: index
761
+ }),
762
+ value: `${typedInputValue}`
763
+ }, 'add-item');
764
+ }
718
765
  return /*#__PURE__*/jsx(AutocompleteOption, {
719
766
  "data-index": index,
720
767
  "aria-setsize": availableItems.length,
@@ -1,5 +1,5 @@
1
1
  import { tokens } from '@equinor/eds-tokens';
2
- import mergeDeepRight from '../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/mergeDeepRight.js';
2
+ import mergeDeepRight from '../../node_modules/.pnpm/ramda@0.31.3/node_modules/ramda/es/mergeDeepRight.js';
3
3
 
4
4
  const {
5
5
  typography,
@@ -68,4 +68,4 @@ function AutocompleteOptionInner(props, ref) {
68
68
  }
69
69
  const AutocompleteOption = /*#__PURE__*/forwardRef(AutocompleteOptionInner);
70
70
 
71
- export { AutocompleteOption, AutocompleteOptionLabel };
71
+ export { AutocompleteOption, AutocompleteOptionLabel, StyledListItem };
@@ -1,6 +1,6 @@
1
1
  import { tokens } from '@equinor/eds-tokens';
2
2
  import { button } from './button.js';
3
- import mergeDeepRight from '../../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/mergeDeepRight.js';
3
+ import mergeDeepRight from '../../../node_modules/.pnpm/ramda@0.31.3/node_modules/ramda/es/mergeDeepRight.js';
4
4
 
5
5
  const {
6
6
  colors: {
@@ -1,6 +1,6 @@
1
1
  import { tokens } from '@equinor/eds-tokens';
2
2
  import { primary as primary$1, secondary as secondary$1, danger as danger$1 } from './contained.js';
3
- import mergeDeepRight from '../../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/mergeDeepRight.js';
3
+ import mergeDeepRight from '../../../node_modules/.pnpm/ramda@0.31.3/node_modules/ramda/es/mergeDeepRight.js';
4
4
 
5
5
  const {
6
6
  clickbounds: {
@@ -1,6 +1,6 @@
1
1
  import { tokens } from '@equinor/eds-tokens';
2
2
  import { button } from './button.js';
3
- import mergeDeepRight from '../../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/mergeDeepRight.js';
3
+ import mergeDeepRight from '../../../node_modules/.pnpm/ramda@0.31.3/node_modules/ramda/es/mergeDeepRight.js';
4
4
 
5
5
  const {
6
6
  colors: {
@@ -1,6 +1,6 @@
1
1
  import { tokens } from '@equinor/eds-tokens';
2
2
  import { button } from './button.js';
3
- import mergeDeepRight from '../../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/mergeDeepRight.js';
3
+ import mergeDeepRight from '../../../node_modules/.pnpm/ramda@0.31.3/node_modules/ramda/es/mergeDeepRight.js';
4
4
 
5
5
  const {
6
6
  colors: {
@@ -1,6 +1,6 @@
1
1
  import { tokens } from '@equinor/eds-tokens';
2
2
  import { button } from './button.js';
3
- import mergeDeepRight from '../../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/mergeDeepRight.js';
3
+ import mergeDeepRight from '../../../node_modules/.pnpm/ramda@0.31.3/node_modules/ramda/es/mergeDeepRight.js';
4
4
 
5
5
  const {
6
6
  colors: {
@@ -53,6 +53,7 @@ const Calendar = /*#__PURE__*/forwardRef(({
53
53
  nextMonthDisabled: nextButtonProps.isDisabled,
54
54
  setShowYearPicker: setShowYearPicker,
55
55
  showYearPicker: showYearPicker,
56
+ yearPickerPage: yearPickerPage,
56
57
  setYearPickerPage: setYearPickerPage
57
58
  })
58
59
  }), /*#__PURE__*/jsx(Popover.Content, {
@@ -4,6 +4,7 @@ import { Icon } from '../../Icon/index.js';
4
4
  import { chevron_left, chevron_up, chevron_down, chevron_right } from '@equinor/eds-icons';
5
5
  import { CalendarDate } from '@internationalized/date';
6
6
  import { tokens } from '@equinor/eds-tokens';
7
+ import { getPageYears } from '../utils/getPageYears.js';
7
8
  import { jsx, jsxs } from 'react/jsx-runtime';
8
9
 
9
10
  const HeaderWrapper = styled.div.withConfig({
@@ -40,14 +41,18 @@ function CalendarHeader({
40
41
  nextMonthDisabled,
41
42
  showYearPicker,
42
43
  setShowYearPicker,
43
- setYearPickerPage
44
+ setYearPickerPage,
45
+ yearPickerPage
44
46
  }) {
47
+ const years = getPageYears(state.focusedDate.year, yearPickerPage);
48
+ const backButtonDisabled = showYearPicker && state.minValue ? years[0] < state.minValue.year : previousMonthDisabled;
49
+ const nextButtonDisabled = showYearPicker && state.maxValue ? years[years.length - 1] > state.maxValue.year : nextMonthDisabled;
45
50
  return /*#__PURE__*/jsx(HeaderWrapper, {
46
51
  children: /*#__PURE__*/jsxs(HeaderActions, {
47
52
  children: [/*#__PURE__*/jsx(Button, {
48
53
  variant: 'ghost_icon',
49
54
  "aria-label": 'Previous month',
50
- disabled: previousMonthDisabled,
55
+ disabled: backButtonDisabled,
51
56
  onClick: () => showYearPicker ? setYearPickerPage(page => page - 1) : state.focusPreviousPage(),
52
57
  children: /*#__PURE__*/jsx(Icon, {
53
58
  data: chevron_left
@@ -78,7 +83,7 @@ function CalendarHeader({
78
83
  }), /*#__PURE__*/jsx(Button, {
79
84
  variant: 'ghost_icon',
80
85
  onClick: () => showYearPicker ? setYearPickerPage(page => page + 1) : state.focusNextPage(),
81
- disabled: nextMonthDisabled,
86
+ disabled: nextButtonDisabled,
82
87
  "aria-label": 'Next month',
83
88
  children: /*#__PURE__*/jsx(Icon, {
84
89
  data: chevron_right
@@ -46,7 +46,8 @@ const RangeCalendar = /*#__PURE__*/forwardRef(({
46
46
  title: title,
47
47
  setShowYearPicker: setShowYearPicker,
48
48
  showYearPicker: showYearPicker,
49
- setYearPickerPage: setYearPickerPage
49
+ setYearPickerPage: setYearPickerPage,
50
+ yearPickerPage: yearPickerPage
50
51
  })
51
52
  }), /*#__PURE__*/jsx(Popover.Content, {
52
53
  children: /*#__PURE__*/jsx(CalendarGrid, {
@@ -2,6 +2,7 @@ import styled from 'styled-components';
2
2
  import { tokens } from '@equinor/eds-tokens';
3
3
  import { FocusScope, useFocusManager } from 'react-aria';
4
4
  import { useRef, useEffect } from 'react';
5
+ import { getPageYears } from '../utils/getPageYears.js';
5
6
  import { jsx } from 'react/jsx-runtime';
6
7
 
7
8
  // Disable no-autofocus - it's not the native autofocus attribute, but react-aria's autoFocus prop
@@ -16,8 +17,6 @@ const GridColumn = styled.button.withConfig({
16
17
  })(["background-color:transparent;outline:none;border:none;display:flex;justify-content:center;cursor:pointer;padding:8px;font-size:", ";font-family:", ";font-weight:", ";line-height:", ";color:", ";border-radius:999px;", ";&:hover{background-color:#f0f0f0;}&:focus{outline:2px dashed ", ";}"], tokens.typography.navigation.button.fontSize, tokens.typography.navigation.button.fontFamily, tokens.typography.navigation.button.fontWeight, tokens.typography.navigation.button.lineHeight, tokens.colors.text.static_icons__default.rgba, ({
17
18
  $active
18
19
  }) => $active ? `background-color: ${tokens.colors.interactive.primary__selected_highlight.rgba}` : '', tokens.colors.interactive.primary__resting.rgba);
19
- const TOTAL_VISIBLE_YEARS = 36;
20
- const RANGE_OFFSET = 30 / 2;
21
20
  const GridFocusManager = ({
22
21
  year: selectedYear,
23
22
  setFocusedYear,
@@ -27,10 +26,7 @@ const GridFocusManager = ({
27
26
  const focusManager = useFocusManager();
28
27
  const prevYear = useRef();
29
28
  const navByKeyboard = useRef(false);
30
- const page = yearPickerPage * TOTAL_VISIBLE_YEARS;
31
- const years = Array.from({
32
- length: TOTAL_VISIBLE_YEARS
33
- }, (_, i) => i + (selectedYear + page - RANGE_OFFSET));
29
+ const years = getPageYears(selectedYear, yearPickerPage);
34
30
  useEffect(() => {
35
31
  if (prevYear.current === undefined) {
36
32
  prevYear.current = yearPickerPage;
@@ -0,0 +1,10 @@
1
+ const TOTAL_VISIBLE_YEARS = 36;
2
+ const RANGE_OFFSET = 30 / 2;
3
+ const getPageYears = (selectedYear, yearPickerPage = 0) => {
4
+ const page = yearPickerPage * TOTAL_VISIBLE_YEARS;
5
+ return Array.from({
6
+ length: TOTAL_VISIBLE_YEARS
7
+ }, (_, i) => i + (selectedYear + page - RANGE_OFFSET));
8
+ };
9
+
10
+ export { getPageYears };
@@ -1,5 +1,5 @@
1
1
  import { tokens } from '@equinor/eds-tokens';
2
- import mergeDeepRight from '../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/mergeDeepRight.js';
2
+ import mergeDeepRight from '../../node_modules/.pnpm/ramda@0.31.3/node_modules/ramda/es/mergeDeepRight.js';
3
3
 
4
4
  const {
5
5
  colors: {
@@ -1,5 +1,5 @@
1
1
  import { tokens } from '@equinor/eds-tokens';
2
- import mergeDeepRight from '../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/mergeDeepRight.js';
2
+ import mergeDeepRight from '../../node_modules/.pnpm/ramda@0.31.3/node_modules/ramda/es/mergeDeepRight.js';
3
3
 
4
4
  const {
5
5
  colors: {
@@ -80,9 +80,9 @@ const MenuItem = /*#__PURE__*/forwardRef(function MenuItem({
80
80
  onClick: e => {
81
81
  if (onClick) {
82
82
  onClick(e);
83
- if (onClose !== null && closeMenuOnClick) {
84
- onClose(e);
85
- }
83
+ }
84
+ if (onClose !== null && closeMenuOnClick) {
85
+ onClose(e);
86
86
  }
87
87
  },
88
88
  children: /*#__PURE__*/jsx(Content, {
@@ -1,5 +1,5 @@
1
1
  import { tokens } from '@equinor/eds-tokens';
2
- import mergeDeepRight from '../../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/mergeDeepRight.js';
2
+ import mergeDeepRight from '../../../node_modules/.pnpm/ramda@0.31.3/node_modules/ramda/es/mergeDeepRight.js';
3
3
 
4
4
  const {
5
5
  typography: {
@@ -20,4 +20,4 @@ Table.Foot.displayName = 'Table.Foot';
20
20
  Table.Row.displayName = 'Table.Row';
21
21
  Table.Caption.displayName = 'Table.Caption';
22
22
 
23
- export { Table, Body as TableBody, Caption as TableCaption, Cell as TableCell, Foot as TableFoot, Head as TableHead, Row as tableRow };
23
+ export { Table, Body as TableBody, Caption as TableCaption, Cell as TableCell, Foot as TableFoot, Head as TableHead, Row as TableRow };
@@ -1,4 +1,4 @@
1
- import { forwardRef, useContext, useRef, useState, useCallback, Children, cloneElement } from 'react';
1
+ import { forwardRef, useContext, useRef, useState, useCallback, Children, isValidElement, cloneElement } from 'react';
2
2
  import styled from 'styled-components';
3
3
  import { mergeRefs } from '@equinor/eds-utils';
4
4
  import { TabsContext } from './Tabs.context.js';
@@ -39,20 +39,24 @@ const TabList = /*#__PURE__*/forwardRef(function TabsList({
39
39
  }
40
40
  }, [arrowNavigating, tabsFocused]);
41
41
  const Tabs = Children.map(children, (child, $index) => {
42
- const childProps = child.props;
42
+ if (! /*#__PURE__*/isValidElement(child)) {
43
+ return null;
44
+ }
45
+ const tabChild = child;
46
+ const childProps = tabChild.props;
43
47
  const controlledActive = childProps.value;
44
48
  const isActive = controlledActive ? controlledActive === activeTab : $index === activeTab;
45
- const tabRef = isActive ? mergeRefs(child.ref, selectedTabRef) : child.ref;
49
+ const tabRef = isActive ? mergeRefs(tabChild.ref, selectedTabRef) : tabChild.ref;
46
50
  if (isActive) currentTab.current = $index;
47
- return /*#__PURE__*/cloneElement(child, {
51
+ return /*#__PURE__*/cloneElement(tabChild, {
48
52
  id: `${tabsId}-tab-${$index + 1}`,
49
53
  'aria-controls': `${tabsId}-panel-${$index + 1}`,
50
54
  active: isActive,
51
55
  $index,
52
- onClick: () => handleChange($index),
56
+ onClick: () => handleChange(controlledActive !== undefined ? controlledActive : $index),
53
57
  ref: tabRef
54
58
  });
55
- });
59
+ }) ?? [];
56
60
  const focusableChildren = Tabs.filter(child => {
57
61
  const childProps = child.props;
58
62
  return !childProps.disabled;
@@ -1,4 +1,4 @@
1
- import { forwardRef, useContext, Children, cloneElement } from 'react';
1
+ import { forwardRef, useContext, Children, isValidElement, cloneElement } from 'react';
2
2
  import { TabsContext } from './Tabs.context.js';
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
 
@@ -12,7 +12,7 @@ const TabPanels = /*#__PURE__*/forwardRef(function TabPanels({
12
12
  tabsId
13
13
  } = useContext(TabsContext);
14
14
  const Panels = Children.map(children, (child, $index) => {
15
- if (conditionalRender && activeTab !== $index) return null;
15
+ if (! /*#__PURE__*/isValidElement(child) || conditionalRender && activeTab !== $index) return null;
16
16
  return /*#__PURE__*/cloneElement(child, {
17
17
  id: `${tabsId}-panel-${$index + 1}`,
18
18
  'aria-labelledby': `${tabsId}-tab-${$index + 1}`,
@@ -27,6 +27,7 @@ const Tooltip = /*#__PURE__*/forwardRef(function Tooltip({
27
27
  children,
28
28
  style,
29
29
  enterDelay = 100,
30
+ disabled = false,
30
31
  portalContainer,
31
32
  ...rest
32
33
  }, ref) {
@@ -142,7 +143,7 @@ const Tooltip = /*#__PURE__*/forwardRef(function Tooltip({
142
143
  })]
143
144
  });
144
145
  return /*#__PURE__*/jsxs(Fragment, {
145
- children: [shouldOpen && open && /*#__PURE__*/createPortal(TooltipEl, portalContainer ?? rootElement ?? document.body), updatedChildren]
146
+ children: [shouldOpen && open && !disabled && /*#__PURE__*/createPortal(TooltipEl, portalContainer ?? rootElement ?? document.body), updatedChildren]
146
147
  });
147
148
  });
148
149
 
package/dist/esm/index.js CHANGED
@@ -23,7 +23,7 @@ export { Body as TableBody } from './components/Table/Body.js';
23
23
  export { Cell as TableCell } from './components/Table/Cell.js';
24
24
  export { Head as TableHead } from './components/Table/Head/Head.js';
25
25
  export { Foot as TableFoot } from './components/Table/Foot/Foot.js';
26
- export { Row as tableRow } from './components/Table/Row/Row.js';
26
+ export { Row as TableRow } from './components/Table/Row/Row.js';
27
27
  export { Caption as TableCaption } from './components/Table/Caption.js';
28
28
  export { Divider } from './components/Divider/Divider.js';
29
29
  export { TextField } from './components/TextField/TextField.js';
@@ -15,7 +15,7 @@ import mergeDeepWithKey from './mergeDeepWithKey.js';
15
15
  * @param {Object} lObj
16
16
  * @param {Object} rObj
17
17
  * @return {Object}
18
- * @see R.merge, R.mergeDeepLeft, R.mergeDeepWith, R.mergeDeepWithKey
18
+ * @see R.mergeDeepLeft, R.mergeDeepWith, R.mergeDeepWithKey
19
19
  * @example
20
20
  *
21
21
  * R.mergeDeepRight({ name: 'fred', age: 10, contact: { email: 'moo@example.com' }},
@@ -16,7 +16,7 @@ import mergeWithKey from './mergeWithKey.js';
16
16
  * @param {Object} l
17
17
  * @param {Object} r
18
18
  * @return {Object}
19
- * @see R.mergeDeepWith, R.merge, R.mergeWithKey
19
+ * @see R.mergeDeepWith, R.mergeWithKey
20
20
  * @example
21
21
  *
22
22
  * R.mergeWith(R.concat,
@@ -16,7 +16,7 @@ import _has from './internal/_has.js';
16
16
  * @param {Object} l
17
17
  * @param {Object} r
18
18
  * @return {Object}
19
- * @see R.mergeDeepWithKey, R.merge, R.mergeWith
19
+ * @see R.mergeDeepWithKey, R.mergeWith
20
20
  * @example
21
21
  *
22
22
  * let concatValues = (k, l, r) => k == 'values' ? R.concat(l, r) : r
@@ -0,0 +1,13 @@
1
+ import { LiHTMLAttributes } from 'react';
2
+ export type AutocompleteOptionProps = {
3
+ value: string;
4
+ multiple: boolean;
5
+ highlighted: string;
6
+ multiline: boolean;
7
+ } & LiHTMLAttributes<HTMLLIElement>;
8
+ declare function AddNewOptionInner(props: AutocompleteOptionProps, ref: React.ForwardedRef<HTMLLIElement>): import("react/jsx-runtime").JSX.Element;
9
+ export declare const AddNewOption: (props: AutocompleteOptionProps & {
10
+ ref?: React.ForwardedRef<HTMLLIElement>;
11
+ displayName?: string | undefined;
12
+ }) => ReturnType<typeof AddNewOptionInner>;
13
+ export {};
@@ -6,6 +6,8 @@ export type AutocompleteChanges<T> = {
6
6
  export type AutocompleteProps<T> = {
7
7
  /** List of options in dropdown */
8
8
  options: readonly T[];
9
+ /** Total number of options */
10
+ totalOptions?: number;
9
11
  /** Label for the select element */
10
12
  label: ReactNode;
11
13
  /** Array of initial selected items
@@ -53,6 +55,8 @@ export type AutocompleteProps<T> = {
53
55
  * Returns input value
54
56
  */
55
57
  onInputChange?: (text: string) => void;
58
+ /** Callback for clicking the add new option button */
59
+ onAddNewOption?: (text: string) => void;
56
60
  /** Enable multiselect */
57
61
  multiple?: boolean;
58
62
  /** Add select-all option. Throws an error if true while multiple = false */
@@ -1,4 +1,10 @@
1
1
  import { LiHTMLAttributes, ReactNode } from 'react';
2
+ type StyledListItemType = {
3
+ $highlighted?: string;
4
+ $active?: string;
5
+ $isdisabled?: string;
6
+ };
7
+ export declare const StyledListItem: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, StyledListItemType>> & string;
2
8
  export declare const AutocompleteOptionLabel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, {
3
9
  $multiline: boolean;
4
10
  }>> & string;
@@ -3,7 +3,7 @@ import { Dispatch, SetStateAction } from 'react';
3
3
  /**
4
4
  * The default header for the calendar components if no custom header is provided
5
5
  */
6
- export declare function CalendarHeader({ state, title, previousMonthDisabled, nextMonthDisabled, showYearPicker, setShowYearPicker, setYearPickerPage, }: {
6
+ export declare function CalendarHeader({ state, title, previousMonthDisabled, nextMonthDisabled, showYearPicker, setShowYearPicker, setYearPickerPage, yearPickerPage, }: {
7
7
  state: CalendarState | RangeCalendarState;
8
8
  title: string;
9
9
  previousMonthDisabled?: boolean;
@@ -11,4 +11,5 @@ export declare function CalendarHeader({ state, title, previousMonthDisabled, ne
11
11
  showYearPicker: boolean;
12
12
  setShowYearPicker: (showYearPicker: boolean) => void;
13
13
  setYearPickerPage?: Dispatch<SetStateAction<number>>;
14
+ yearPickerPage: number;
14
15
  }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare const getPageYears: (selectedYear: number, yearPickerPage?: number) => number[];
@@ -3,16 +3,16 @@ import { Body as TableBody, BodyProps } from './Body';
3
3
  import { Cell as TableCell, CellProps } from './Cell';
4
4
  import { Head as TableHead, HeadProps } from './Head';
5
5
  import { Foot as TableFoot, FootProps } from './Foot';
6
- import { Row as tableRow, RowProps } from './Row';
6
+ import { Row as TableRow, RowProps } from './Row';
7
7
  import { Caption as TableCaption, CaptionProps } from './Caption';
8
8
  type TableCompoundProps = typeof BaseTable & {
9
9
  Body: typeof TableBody;
10
10
  Cell: typeof TableCell;
11
11
  Head: typeof TableHead;
12
12
  Foot: typeof TableFoot;
13
- Row: typeof tableRow;
13
+ Row: typeof TableRow;
14
14
  Caption: typeof TableCaption;
15
15
  };
16
16
  declare const Table: TableCompoundProps;
17
- export { Table, TableBody, TableCell, TableHead, TableFoot, tableRow, TableCaption, };
17
+ export { Table, TableBody, TableCell, TableHead, TableFoot, TableRow, TableCaption, };
18
18
  export type { TableProps, CellProps, BodyProps, RowProps, CaptionProps, HeadProps, FootProps, };
@@ -2,7 +2,7 @@ import { Variants } from './Tabs.types';
2
2
  type State = {
3
3
  variant: Variants;
4
4
  scrollable: boolean;
5
- handleChange: (index: number) => void;
5
+ handleChange: (value: number | string) => void;
6
6
  activeTab: number | string;
7
7
  tabsId: string;
8
8
  tabsFocused: boolean;
@@ -4,7 +4,7 @@ export type TabsProps = {
4
4
  /** The index of the active tab OR a string matching the value prop on the active tab */
5
5
  activeTab?: number | string;
6
6
  /** The callback function for selecting a tab */
7
- onChange?: (index: number) => void;
7
+ onChange?: (value: number | string) => void;
8
8
  /** Sets the width of the tabs. Tabs can have a maximum width of 360px */
9
9
  variant?: Variants;
10
10
  /** adds scrollbar if tabs overflow on non-touch devices */
@@ -14,7 +14,7 @@ declare const Tabs: import("react").ForwardRefExoticComponent<{
14
14
  /** The index of the active tab OR a string matching the value prop on the active tab */
15
15
  activeTab?: number | string;
16
16
  /** The callback function for selecting a tab */
17
- onChange?: (index: number) => void;
17
+ onChange?: (value: number | string) => void;
18
18
  /** Sets the width of the tabs. Tabs can have a maximum width of 360px */
19
19
  variant?: Variants;
20
20
  /** adds scrollbar if tabs overflow on non-touch devices */
@@ -5,6 +5,8 @@ export type TooltipProps = {
5
5
  placement?: Placement;
6
6
  /** Tooltip title */
7
7
  title?: ReactNode;
8
+ /** Disable the tooltip */
9
+ disabled?: boolean;
8
10
  /** Tooltip anchor element */
9
11
  children: React.ReactElement & React.RefAttributes<HTMLElement>;
10
12
  /** Delay in ms, default 100 */
@@ -19,6 +21,8 @@ export declare const Tooltip: import("react").ForwardRefExoticComponent<{
19
21
  placement?: Placement;
20
22
  /** Tooltip title */
21
23
  title?: ReactNode;
24
+ /** Disable the tooltip */
25
+ disabled?: boolean;
22
26
  /** Tooltip anchor element */
23
27
  children: React.ReactElement & React.RefAttributes<HTMLElement>;
24
28
  /** Delay in ms, default 100 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@equinor/eds-core-react",
3
- "version": "0.46.0",
3
+ "version": "0.48.0",
4
4
  "description": "The React implementation of the Equinor Design System",
5
5
  "sideEffects": [
6
6
  "**/*.css"
@@ -58,7 +58,7 @@
58
58
  "jest-styled-components": "^7.2.0",
59
59
  "js-file-download": "^0.4.12",
60
60
  "postcss": "^8.5.3",
61
- "ramda": "^0.30.1",
61
+ "ramda": "^0.31.3",
62
62
  "react": "^18.3.1",
63
63
  "react-dom": "^18.3.1",
64
64
  "react-hook-form": "^7.56.1",
@@ -67,8 +67,8 @@
67
67
  "rollup-plugin-delete": "^2.2.0",
68
68
  "rollup-plugin-postcss": "^4.0.2",
69
69
  "rollup-preserve-directives": "^1.1.3",
70
- "storybook": "^8.6.12",
71
- "styled-components": "6.1.17",
70
+ "storybook": "^8.6.14",
71
+ "styled-components": "6.1.19",
72
72
  "tsc-watch": "^6.2.1",
73
73
  "typescript": "^5.8.3"
74
74
  },
@@ -78,19 +78,19 @@
78
78
  "styled-components": ">=5.1"
79
79
  },
80
80
  "dependencies": {
81
- "@babel/runtime": "^7.27.1",
81
+ "@babel/runtime": "^7.27.6",
82
82
  "@floating-ui/react": "^0.27.8",
83
83
  "@internationalized/date": "^3.8.0",
84
84
  "@react-aria/utils": "^3.28.2",
85
85
  "@react-stately/calendar": "^3.8.0",
86
86
  "@react-stately/datepicker": "^3.14.0",
87
87
  "@react-types/shared": "^3.29.0",
88
- "@tanstack/react-virtual": "3.13.6",
88
+ "@tanstack/react-virtual": "3.13.12",
89
89
  "downshift": "9.0.8",
90
90
  "react-aria": "^3.39.0",
91
91
  "@equinor/eds-icons": "^0.22.0",
92
- "@equinor/eds-tokens": "0.9.2",
93
- "@equinor/eds-utils": "0.8.7"
92
+ "@equinor/eds-utils": "0.8.8",
93
+ "@equinor/eds-tokens": "0.9.2"
94
94
  },
95
95
  "scripts": {
96
96
  "build": "rollup -c --bundleConfigAsCjs && tsc -p tsconfig.build.json",