@lumx/react 2.2.20-alpha.xss.datatable → 2.2.20

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 (79) hide show
  1. package/esm/_internal/ClickAwayProvider.js +90 -12
  2. package/esm/_internal/ClickAwayProvider.js.map +1 -1
  3. package/esm/_internal/DatePickerField.js +18 -11
  4. package/esm/_internal/DatePickerField.js.map +1 -1
  5. package/esm/_internal/Dialog2.js +2 -2
  6. package/esm/_internal/Dialog2.js.map +1 -1
  7. package/esm/_internal/GenericBlock.js +90 -0
  8. package/esm/_internal/GenericBlock.js.map +1 -0
  9. package/esm/_internal/Lightbox2.js +2 -2
  10. package/esm/_internal/Lightbox2.js.map +1 -1
  11. package/esm/_internal/LinkPreview.js +22 -12
  12. package/esm/_internal/LinkPreview.js.map +1 -1
  13. package/esm/_internal/Popover2.js +21 -8
  14. package/esm/_internal/Popover2.js.map +1 -1
  15. package/esm/_internal/SelectMultiple.js +16 -4
  16. package/esm/_internal/SelectMultiple.js.map +1 -1
  17. package/esm/_internal/alert-dialog.js +2 -2
  18. package/esm/_internal/autocomplete.js +2 -1
  19. package/esm/_internal/autocomplete.js.map +1 -1
  20. package/esm/_internal/button.js +2 -1
  21. package/esm/_internal/button.js.map +1 -1
  22. package/esm/_internal/comment-block.js +2 -1
  23. package/esm/_internal/comment-block.js.map +1 -1
  24. package/esm/_internal/date-picker.js +3 -2
  25. package/esm/_internal/date-picker.js.map +1 -1
  26. package/esm/_internal/dialog.js +2 -2
  27. package/esm/_internal/dropdown.js +2 -1
  28. package/esm/_internal/dropdown.js.map +1 -1
  29. package/esm/_internal/expansion-panel.js +1 -1
  30. package/esm/_internal/generic-block.js +12 -0
  31. package/esm/_internal/generic-block.js.map +1 -0
  32. package/esm/_internal/lightbox.js +3 -2
  33. package/esm/_internal/lightbox.js.map +1 -1
  34. package/esm/_internal/popover.js +2 -1
  35. package/esm/_internal/popover.js.map +1 -1
  36. package/esm/_internal/select.js +2 -1
  37. package/esm/_internal/select.js.map +1 -1
  38. package/esm/_internal/side-navigation.js +2 -1
  39. package/esm/_internal/side-navigation.js.map +1 -1
  40. package/esm/_internal/slideshow.js +2 -1
  41. package/esm/_internal/slideshow.js.map +1 -1
  42. package/esm/_internal/text-field.js +2 -1
  43. package/esm/_internal/text-field.js.map +1 -1
  44. package/esm/_internal/tooltip.js +2 -1
  45. package/esm/_internal/tooltip.js.map +1 -1
  46. package/esm/_internal/type.js.map +1 -1
  47. package/esm/_internal/useFocusTrap.js +62 -78
  48. package/esm/_internal/useFocusTrap.js.map +1 -1
  49. package/esm/index.js +3 -2
  50. package/esm/index.js.map +1 -1
  51. package/package.json +4 -4
  52. package/src/components/date-picker/DatePickerField.tsx +15 -16
  53. package/src/components/date-picker/types.ts +2 -2
  54. package/src/components/dialog/Dialog.stories.tsx +53 -13
  55. package/src/components/dialog/Dialog.tsx +1 -1
  56. package/src/components/dialog/__snapshots__/Dialog.test.tsx.snap +75 -14
  57. package/src/components/generic-block/GenericBlock.stories.tsx +149 -0
  58. package/src/components/generic-block/GenericBlock.test.tsx +28 -0
  59. package/src/components/generic-block/GenericBlock.tsx +120 -0
  60. package/src/components/generic-block/__snapshots__/GenericBlock.test.tsx.snap +92 -0
  61. package/src/components/generic-block/index.ts +1 -0
  62. package/src/components/lightbox/Lightbox.tsx +1 -1
  63. package/src/components/link-preview/LinkPreview.test.tsx +50 -55
  64. package/src/components/link-preview/LinkPreview.tsx +43 -16
  65. package/src/components/popover/Popover.tsx +20 -4
  66. package/src/components/select/Select.stories.tsx +2 -0
  67. package/src/components/select/Select.tsx +11 -1
  68. package/src/components/select/SelectMultiple.stories.tsx +2 -0
  69. package/src/components/select/SelectMultiple.tsx +11 -1
  70. package/src/components/select/constants.ts +2 -0
  71. package/src/components/table/__snapshots__/Table.test.tsx.snap +5 -0
  72. package/src/hooks/useCallbackOnEscape.ts +21 -13
  73. package/src/hooks/useFocusTrap.ts +68 -51
  74. package/src/index.ts +1 -0
  75. package/src/stories/generated/GenericBlock/Demos.stories.tsx +6 -0
  76. package/src/utils/makeListenerTowerContext.ts +32 -0
  77. package/src/utils/type.ts +3 -0
  78. package/types.d.ts +48 -5
  79. package/src/components/link-preview/__snapshots__/LinkPreview.test.tsx.snap +0 -51
@@ -1,5 +1,5 @@
1
1
  import { detectOverflow } from '@popperjs/core';
2
- import React, { forwardRef, ReactNode, RefObject, useEffect, useMemo, useRef, useState } from 'react';
2
+ import React, { forwardRef, ReactNode, RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { createPortal } from 'react-dom';
4
4
  import { usePopper } from 'react-popper';
5
5
 
@@ -13,6 +13,7 @@ import { ClickAwayProvider } from '@lumx/react/utils/ClickAwayProvider';
13
13
  import { Comp, GenericProps, getRootClassName, handleBasicClasses, ValueOf } from '@lumx/react/utils';
14
14
  import { mergeRefs } from '@lumx/react/utils/mergeRefs';
15
15
  import { useFocusWithin } from '@lumx/react/hooks/useFocusWithin';
16
+ import { getFirstAndLastFocusable } from '@lumx/react/utils/focus/getFirstAndLastFocusable';
16
17
 
17
18
  /**
18
19
  * Different possible placements for the popover.
@@ -90,6 +91,8 @@ export interface PopoverProps extends GenericProps {
90
91
  isOpen: boolean;
91
92
  /** Offset placement relative to anchor. */
92
93
  offset?: Offset;
94
+ /** Reference to the parent element that triggered the popover (will get back focus on close or else fallback on the anchor element). */
95
+ parentElement?: RefObject<HTMLElement>;
93
96
  /** Placement relative to anchor. */
94
97
  placement?: Placement;
95
98
  /** Whether the popover should be rendered into a DOM node that exists outside the DOM hierarchy of the parent component. */
@@ -212,6 +215,7 @@ export const Popover: Comp<PopoverProps, HTMLDivElement> = forwardRef((props, re
212
215
  isOpen,
213
216
  offset,
214
217
  onClose,
218
+ parentElement,
215
219
  placement,
216
220
  style,
217
221
  usePortal,
@@ -245,7 +249,8 @@ export const Popover: Comp<PopoverProps, HTMLDivElement> = forwardRef((props, re
245
249
  });
246
250
 
247
251
  /** Action on close */
248
- const handleClose = () => {
252
+ // eslint-disable-next-line react-hooks/rules-of-hooks
253
+ const handleClose = useCallback(() => {
249
254
  if (!onClose) {
250
255
  return;
251
256
  }
@@ -256,11 +261,22 @@ export const Popover: Comp<PopoverProps, HTMLDivElement> = forwardRef((props, re
256
261
  * unless specifically requested not to.
257
262
  */
258
263
  if (isFocusedWithin.current && focusAnchorOnClose) {
259
- anchorRef.current?.focus();
264
+ if (parentElement?.current) {
265
+ parentElement?.current.focus();
266
+ }
267
+
268
+ const firstFocusable = anchorRef?.current && getFirstAndLastFocusable(anchorRef?.current).first;
269
+ if (firstFocusable) {
270
+ // Focus the first focusable element in anchor.
271
+ firstFocusable.focus();
272
+ } else {
273
+ // Fallback on the anchor element.
274
+ anchorRef?.current?.focus();
275
+ }
260
276
  }
261
277
 
262
278
  onClose();
263
- };
279
+ }, [anchorRef, focusAnchorOnClose, onClose, parentElement]);
264
280
 
265
281
  const modifiers: any = [];
266
282
  const actualOffset: [number, number] = [offset?.along ?? 0, (offset?.away ?? 0) + (hasArrow ? ARROW_SIZE : 0)];
@@ -1,3 +1,4 @@
1
+ import { mdiBullhornOutline } from '@lumx/icons/';
1
2
  import { List, ListItem, Select, Size, TextField } from '@lumx/react';
2
3
  import { useBooleanState } from '@lumx/react/hooks/useBooleanState';
3
4
  import { text } from '@storybook/addon-knobs';
@@ -32,6 +33,7 @@ export const SimpleSelect = ({ theme }: any) => {
32
33
  theme={theme}
33
34
  onInputClick={toggleSelect}
34
35
  onDropdownClose={closeSelect}
36
+ icon={mdiBullhornOutline}
35
37
  >
36
38
  <List isClickable>
37
39
  {CHOICES.length > 0
@@ -5,7 +5,7 @@ import lodashIsEmpty from 'lodash/isEmpty';
5
5
 
6
6
  import { mdiAlertCircle, mdiCheckCircle, mdiCloseCircle, mdiMenuDown } from '@lumx/icons';
7
7
 
8
- import { Emphasis, Size } from '@lumx/react/components';
8
+ import { Emphasis, Size, Theme } from '@lumx/react/components';
9
9
  import { IconButton } from '@lumx/react/components/button/IconButton';
10
10
  import { Chip } from '@lumx/react/components/chip/Chip';
11
11
  import { Icon } from '@lumx/react/components/icon/Icon';
@@ -46,6 +46,7 @@ const SelectField: React.FC<SelectProps> = ({
46
46
  handleKeyboardNav,
47
47
  hasError,
48
48
  hasInputClear,
49
+ icon,
49
50
  id,
50
51
  isDisabled,
51
52
  isEmpty,
@@ -89,6 +90,15 @@ const SelectField: React.FC<SelectProps> = ({
89
90
  aria-disabled={isDisabled || undefined}
90
91
  {...forwardedProps}
91
92
  >
93
+ {icon && (
94
+ <Icon
95
+ className={`${CLASSNAME}__input-icon`}
96
+ color={theme === Theme.dark ? 'light' : undefined}
97
+ icon={icon}
98
+ size={Size.xs}
99
+ />
100
+ )}
101
+
92
102
  <div
93
103
  className={classNames([
94
104
  `${CLASSNAME}__input-native`,
@@ -1,4 +1,5 @@
1
1
  /* istanbul ignore file */
2
+ import { mdiTram } from '@lumx/icons/';
2
3
  import { Chip, List, ListItem, SelectMultiple, Size } from '@lumx/react';
3
4
  import { useBooleanState } from '@lumx/react/hooks/useBooleanState';
4
5
  import noop from 'lodash/noop';
@@ -40,6 +41,7 @@ export const DefaultSelectMultiple = ({ theme }: any) => {
40
41
  theme={theme}
41
42
  onInputClick={toggleSelect}
42
43
  onDropdownClose={closeSelect}
44
+ icon={mdiTram}
43
45
  >
44
46
  <List isClickable>
45
47
  {CHOICES.length > 0
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { mdiAlertCircle, mdiCheckCircle, mdiClose, mdiCloseCircle, mdiMenuDown } from '@lumx/icons';
6
6
 
7
- import { Size } from '@lumx/react/components';
7
+ import { Size, Theme } from '@lumx/react/components';
8
8
  import { Chip } from '@lumx/react/components/chip/Chip';
9
9
  import { Icon } from '@lumx/react/components/icon/Icon';
10
10
  import { InputLabel } from '@lumx/react/components/input-label/InputLabel';
@@ -59,6 +59,7 @@ export const SelectMultipleField: React.FC<SelectMultipleProps> = ({
59
59
  anchorRef,
60
60
  handleKeyboardNav,
61
61
  hasError,
62
+ icon,
62
63
  id,
63
64
  isDisabled,
64
65
  isEmpty,
@@ -102,6 +103,15 @@ export const SelectMultipleField: React.FC<SelectMultipleProps> = ({
102
103
  aria-disabled={isDisabled || undefined}
103
104
  {...forwardedProps}
104
105
  >
106
+ {icon && (
107
+ <Icon
108
+ className={`${CLASSNAME}__input-icon`}
109
+ color={theme === Theme.dark ? 'light' : undefined}
110
+ icon={icon}
111
+ size={Size.xs}
112
+ />
113
+ )}
114
+
105
115
  <div className={`${CLASSNAME}__chips`}>
106
116
  {!isEmpty &&
107
117
  value.map((val, index) => selectedChipRender?.(val, index, onClear, isDisabled, theme))}
@@ -21,6 +21,8 @@ export interface CoreSelectProps extends GenericProps {
21
21
  helper?: string;
22
22
  /** Whether the select should close on click. */
23
23
  closeOnClick?: boolean;
24
+ /** Icon (SVG path). */
25
+ icon?: string;
24
26
  /** Whether the component is disabled or not. */
25
27
  isDisabled?: boolean;
26
28
  /** Whether the component is required or not. */
@@ -3,6 +3,11 @@
3
3
  exports[`<Table> Snapshots and structure should render story 'Default' 1`] = `
4
4
  <table
5
5
  className="lumx-table lumx-table--has-dividers lumx-table--theme-light"
6
+ style={
7
+ Object {
8
+ "minWidth": 620,
9
+ }
10
+ }
6
11
  >
7
12
  <TableHeader>
8
13
  <TableRow>
@@ -1,25 +1,33 @@
1
1
  import { DOCUMENT } from '@lumx/react/constants';
2
2
  import { Callback, onEscapePressed } from '@lumx/react/utils';
3
3
  import { useEffect } from 'react';
4
+ import { Listener, makeListenerTowerContext } from '@lumx/react/utils/makeListenerTowerContext';
5
+
6
+ const LISTENERS = makeListenerTowerContext();
4
7
 
5
8
  /**
6
- * Triggers a callback when the escape key is pressed.
9
+ * Register a global listener on 'Escape' key pressed.
10
+ *
11
+ * If multiple listener are registered, only the last one is maintained. When a listener is unregistered, the previous
12
+ * one gets activated again.
7
13
  *
8
14
  * @param callback Callback
9
15
  * @param closeOnEscape Disables the hook when false
10
- * @param rootElement Element on which to listen the escape key
11
16
  */
12
- export function useCallbackOnEscape(
13
- callback: Callback | undefined,
14
- closeOnEscape = true,
15
- rootElement = DOCUMENT?.body,
16
- ) {
17
+ export function useCallbackOnEscape(callback: Callback | undefined, closeOnEscape = true) {
17
18
  useEffect(() => {
18
- if (closeOnEscape && callback && rootElement) {
19
- const onKeyDown = onEscapePressed(callback);
20
- rootElement.addEventListener('keydown', onKeyDown);
21
- return () => rootElement.removeEventListener('keydown', onKeyDown);
19
+ const rootElement = DOCUMENT?.body;
20
+ if (!closeOnEscape || !callback || !rootElement) {
21
+ return undefined;
22
22
  }
23
- return undefined;
24
- }, [callback, closeOnEscape, rootElement]);
23
+ const onKeyDown = onEscapePressed(callback);
24
+
25
+ const listener: Listener = {
26
+ enable: () => rootElement.addEventListener('keydown', onKeyDown),
27
+ disable: () => rootElement.removeEventListener('keydown', onKeyDown),
28
+ };
29
+
30
+ LISTENERS.register(listener);
31
+ return () => LISTENERS.unregister(listener);
32
+ }, [callback, closeOnEscape]);
25
33
  }
@@ -2,67 +2,84 @@ import { useEffect } from 'react';
2
2
 
3
3
  import { DOCUMENT } from '@lumx/react/constants';
4
4
  import { getFirstAndLastFocusable } from '@lumx/react/utils/focus/getFirstAndLastFocusable';
5
+ import { Falsy } from '@lumx/react/utils';
6
+ import { Listener, makeListenerTowerContext } from '@lumx/react/utils/makeListenerTowerContext';
7
+
8
+ const FOCUS_TRAPS = makeListenerTowerContext();
5
9
 
6
10
  /**
7
- * Add a key down event handler to the given root element (document.body by default) to trap the move of focus
8
- * (TAB and SHIFT-TAB keys) inside the given focusZoneElement.
9
- * Will focus the given focus element when activating the focus trap.
11
+ * Trap 'Tab' focus switch inside the `focusZoneElement`.
12
+ *
13
+ * If multiple focus trap are activated, only the last one is maintained and when a focus trap closes, the previous one
14
+ * gets activated again.
10
15
  *
11
16
  * @param focusZoneElement The element in which to trap the focus.
12
- * @param focusElement The element to focus when the focus trap is activated.
13
- * @param rootElement The element on which the key down event will be placed.
17
+ * @param focusElement The element to focus when the focus trap is activated (otherwise the first focusable element
18
+ * will be focused).
14
19
  */
15
- export function useFocusTrap(
16
- focusZoneElement: HTMLElement | null,
17
- focusElement?: HTMLElement | null,
18
- rootElement = DOCUMENT?.body,
19
- ): void {
20
+ export function useFocusTrap(focusZoneElement: HTMLElement | Falsy, focusElement?: HTMLElement | null): void {
20
21
  useEffect(() => {
21
- if (rootElement && focusZoneElement) {
22
- (document.activeElement as HTMLElement)?.blur();
23
- if (focusElement) {
24
- focusElement.focus();
22
+ // Body element can be undefined in SSR context.
23
+ const rootElement = DOCUMENT?.body;
24
+
25
+ if (!rootElement || !focusZoneElement) {
26
+ return undefined;
27
+ }
28
+
29
+ // Trap 'Tab' key down focus switch into the focus zone.
30
+ const trapTabFocusInFocusZone = (evt: KeyboardEvent) => {
31
+ const { key } = evt;
32
+ if (key !== 'Tab') {
33
+ return;
25
34
  }
35
+ const focusable = getFirstAndLastFocusable(focusZoneElement);
26
36
 
27
- const onKeyDown = (evt: KeyboardEvent) => {
28
- const { key } = evt;
29
- if (key !== 'Tab') {
30
- return;
31
- }
32
- const focusable = getFirstAndLastFocusable(focusZoneElement);
37
+ // Prevent focus switch if no focusable available.
38
+ if (!focusable.first) {
39
+ evt.preventDefault();
40
+ return;
41
+ }
33
42
 
34
- // Prevent focus switch if no focusable available.
35
- if (!focusable.first) {
36
- evt.preventDefault();
37
- return;
38
- }
43
+ if (
44
+ // No previous focus
45
+ !document.activeElement ||
46
+ // Previous focus is at the end of the focus zone.
47
+ (!evt.shiftKey && document.activeElement === focusable.last) ||
48
+ // Previous focus is outside the focus zone
49
+ !focusZoneElement.contains(document.activeElement)
50
+ ) {
51
+ focusable.first.focus();
52
+ evt.preventDefault();
53
+ return;
54
+ }
39
55
 
40
- if (
41
- // No previous focus
42
- !document.activeElement ||
43
- // Previous focus is at the end of the focus zone.
44
- (!evt.shiftKey && document.activeElement === focusable.last) ||
45
- // Previous focus is outside the focus zone
46
- !focusZoneElement.contains(document.activeElement)
47
- ) {
48
- focusable.first.focus();
49
- evt.preventDefault();
50
- return;
51
- }
56
+ if (
57
+ // Focus order reversed
58
+ evt.shiftKey &&
59
+ // Previous focus is at the start of the focus zone.
60
+ document.activeElement === focusable.first
61
+ ) {
62
+ focusable.last.focus();
63
+ evt.preventDefault();
64
+ }
65
+ };
52
66
 
53
- if (
54
- // Focus order reversed
55
- evt.shiftKey &&
56
- // Previous focus is at the start of the focus zone.
57
- document.activeElement === focusable.first
58
- ) {
59
- focusable.last.focus();
60
- evt.preventDefault();
61
- }
62
- };
63
- rootElement.addEventListener('keydown', onKeyDown);
64
- return () => rootElement.removeEventListener('keydown', onKeyDown);
67
+ const focusTrap: Listener = {
68
+ enable: () => rootElement.addEventListener('keydown', trapTabFocusInFocusZone),
69
+ disable: () => rootElement.removeEventListener('keydown', trapTabFocusInFocusZone),
70
+ };
71
+
72
+ // SETUP:
73
+ if (focusElement && focusZoneElement.contains(focusElement)) {
74
+ // Focus the given element.
75
+ focusElement.focus();
76
+ } else {
77
+ // Focus the first focusable element in the zone.
78
+ getFirstAndLastFocusable(focusZoneElement).first?.focus();
65
79
  }
66
- return undefined;
67
- }, [focusElement, focusZoneElement, rootElement]);
80
+ FOCUS_TRAPS.register(focusTrap);
81
+
82
+ // TEARDOWN:
83
+ return () => FOCUS_TRAPS.unregister(focusTrap);
84
+ }, [focusElement, focusZoneElement]);
68
85
  }
package/src/index.ts CHANGED
@@ -15,6 +15,7 @@ export * from './components/dropdown';
15
15
  export * from './components/expansion-panel';
16
16
  export * from './components/flag';
17
17
  export * from './components/flex-box';
18
+ export * from './components/generic-block';
18
19
  export * from './components/grid';
19
20
  export * from './components/icon';
20
21
  export * from './components/image-block';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * File generated when storybook is started. Do not edit directly!
3
+ */
4
+ export default { title: 'LumX components/generic-block/GenericBlock Demos' };
5
+
6
+ export { App as Default } from './default';
@@ -0,0 +1,32 @@
1
+ import last from 'lodash/last';
2
+ import pull from 'lodash/pull';
3
+
4
+ export type Listener = { enable(): void; disable(): void };
5
+
6
+ /**
7
+ * Keep track of listeners, only the last registered listener gets activated at any point (previously registered
8
+ * listener are disabled).
9
+ * When a listener gets unregistered, the previously registered listener gets enabled again.
10
+ */
11
+ export function makeListenerTowerContext() {
12
+ const LISTENERS: Listener[] = [];
13
+
14
+ return {
15
+ register(listener: Listener) {
16
+ // Disable previous listener.
17
+ last(LISTENERS)?.disable();
18
+ // Keep track of current listener.
19
+ LISTENERS.push(listener);
20
+ // Enable current listener.
21
+ listener.enable();
22
+ },
23
+ unregister(listener: Listener) {
24
+ // Disable current listener.
25
+ listener.disable();
26
+ // Remove current listener.
27
+ pull(LISTENERS, listener);
28
+ // Enable previous listener.
29
+ last(LISTENERS)?.enable();
30
+ },
31
+ };
32
+ }
package/src/utils/type.ts CHANGED
@@ -31,6 +31,9 @@ export type Comp<P, T = HTMLElement> = {
31
31
  className?: string;
32
32
  };
33
33
 
34
+ /** Union type of all heading elements */
35
+ export type HeadingElement = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
36
+
34
37
  /**
35
38
  * Define a generic props types.
36
39
  */
package/types.d.ts CHANGED
@@ -18,6 +18,8 @@ export declare type Comp<P, T = HTMLElement> = {
18
18
  /** Component base class name. */
19
19
  className?: string;
20
20
  };
21
+ /** Union type of all heading elements */
22
+ export declare type HeadingElement = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
21
23
  /**
22
24
  * Define a generic props types.
23
25
  */
@@ -741,7 +743,7 @@ export interface DatePickerProps extends GenericProps {
741
743
  /** Props to pass to the previous month button (minus those already set by the DatePickerControlled props). */
742
744
  previousButtonProps: Pick<IconButtonProps, "label"> & Omit<IconButtonProps, "label" | "onClick" | "icon" | "emphasis">;
743
745
  /** Reference to the <button> element corresponding to the current date or the selected date. */
744
- todayOrSelectedDateRef?: RefObject<HTMLButtonElement>;
746
+ todayOrSelectedDateRef?: Ref<HTMLButtonElement>;
745
747
  /** Currently selected date. */
746
748
  value: Date | undefined;
747
749
  /** On change callback. */
@@ -949,6 +951,8 @@ export interface PopoverProps extends GenericProps {
949
951
  isOpen: boolean;
950
952
  /** Offset placement relative to anchor. */
951
953
  offset?: Offset;
954
+ /** Reference to the parent element that triggered the popover (will get back focus on close or else fallback on the anchor element). */
955
+ parentElement?: RefObject<HTMLElement>;
952
956
  /** Placement relative to anchor. */
953
957
  placement?: Placement;
954
958
  /** Whether the popover should be rendered into a DOM node that exists outside the DOM hierarchy of the parent component. */
@@ -1122,6 +1126,41 @@ export interface FlexBoxProps extends GenericProps {
1122
1126
  * @return React element.
1123
1127
  */
1124
1128
  export declare const FlexBox: Comp<FlexBoxProps, HTMLDivElement>;
1129
+ export interface GenericBlockProps extends FlexBoxProps {
1130
+ /** Component to use as visual element. */
1131
+ figure?: ReactNode;
1132
+ /** Actions to set after the main content. */
1133
+ actions?: ReactNode;
1134
+ /** Main content to display */
1135
+ children: ReactNode;
1136
+ /** Orientation of the 3 sections */
1137
+ orientation?: FlexBoxProps["orientation"];
1138
+ /** Horizontal alignment. */
1139
+ hAlign?: FlexBoxProps["hAlign"];
1140
+ /** Vertical alignment. */
1141
+ vAlign?: FlexBoxProps["vAlign"];
1142
+ /**
1143
+ * The props to forward to the content.
1144
+ * By default, the content will have the same alignment as wrapper.
1145
+ */
1146
+ contentProps?: Omit<FlexBoxProps, "children">;
1147
+ /** props to forward to the actions element. */
1148
+ actionsProps?: Omit<FlexBoxProps, "children">;
1149
+ /** props to forward to the figure element. */
1150
+ figureProps?: Omit<FlexBoxProps, "children">;
1151
+ }
1152
+ /**
1153
+ * The GenericBlock is a layout component made of 3 sections that can be
1154
+ * displayed either horizontally of vertically with the same gap between each section.
1155
+ *
1156
+ * The sections are:
1157
+ * * (Optional) `Figure` => A visual element to display before the main content.
1158
+ * * (Required) `Content` => The main content displayed
1159
+ * * (Optional) `Actions` => One or more actions to set after the element.
1160
+ *
1161
+ * @see https://www.figma.com/file/lzzrQmsfaXRaOyRfoEogPZ/DS%3A-playground?node-id=1%3A4076
1162
+ */
1163
+ export declare const GenericBlock: Comp<GenericBlockProps, HTMLDivElement>;
1125
1164
  export declare type GridGutterSize = Extract<Size, "regular" | "big" | "huge">;
1126
1165
  /**
1127
1166
  * Defines the props of the component.
@@ -1431,12 +1470,12 @@ export declare const Link: Comp<LinkProps, HTMLAnchorElement | HTMLButtonElement
1431
1470
  * Defines the props of the component.
1432
1471
  */
1433
1472
  export interface LinkPreviewProps extends GenericProps {
1434
- /** Description (either a string, or sanitized html). */
1435
- description?: string | {
1436
- __html: string;
1437
- };
1473
+ /** Description. */
1474
+ description?: string;
1438
1475
  /** Link URL. */
1439
1476
  link: string;
1477
+ /** Custom react component for the link (can be used to inject react router Link). */
1478
+ linkAs?: "a" | any;
1440
1479
  /** Props to pass to the link (minus those already set by the LinkPreview props). */
1441
1480
  linkProps?: Omit<LinkProps, "color" | "colorVariant" | "href" | "target">;
1442
1481
  /** Size variant. */
@@ -1447,6 +1486,8 @@ export interface LinkPreviewProps extends GenericProps {
1447
1486
  thumbnailProps?: ThumbnailProps;
1448
1487
  /** Title. */
1449
1488
  title?: string;
1489
+ /** Customize the title heading tag. */
1490
+ titleHeading?: HeadingElement;
1450
1491
  }
1451
1492
  /**
1452
1493
  * LinkPreview component.
@@ -1856,6 +1897,8 @@ export interface CoreSelectProps extends GenericProps {
1856
1897
  helper?: string;
1857
1898
  /** Whether the select should close on click. */
1858
1899
  closeOnClick?: boolean;
1900
+ /** Icon (SVG path). */
1901
+ icon?: string;
1859
1902
  /** Whether the component is disabled or not. */
1860
1903
  isDisabled?: boolean;
1861
1904
  /** Whether the component is required or not. */
@@ -1,51 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`<LinkPreview> Snapshots and structure should render correctly 1`] = `
4
- <div
5
- className="lumx-link-preview lumx-link-preview--size-regular lumx-link-preview--theme-light"
6
- >
7
- <div
8
- className="lumx-link-preview__wrapper"
9
- >
10
- <div
11
- className="lumx-link-preview__container"
12
- >
13
- <div
14
- className="lumx-link-preview__link"
15
- >
16
- <Link
17
- className="lumx-link-preview__link"
18
- color="primary"
19
- colorVariant="N"
20
- target="_blank"
21
- />
22
- </div>
23
- </div>
24
- </div>
25
- </div>
26
- `;
27
-
28
- exports[`<LinkPreview> Snapshots and structure should render correctly 2`] = `
29
- <div
30
- className="lumx-link-preview lumx-link-preview--size-regular lumx-link-preview--theme-light"
31
- >
32
- <div
33
- className="lumx-link-preview__wrapper"
34
- >
35
- <div
36
- className="lumx-link-preview__container"
37
- >
38
- <div
39
- className="lumx-link-preview__link"
40
- >
41
- <Link
42
- className="lumx-link-preview__link"
43
- color="primary"
44
- colorVariant="N"
45
- target="_blank"
46
- />
47
- </div>
48
- </div>
49
- </div>
50
- </div>
51
- `;