@transferwise/components 0.0.0-experimental-9b30760 → 0.0.0-experimental-683a8ba

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 (76) hide show
  1. package/build/index.esm.js +110 -114
  2. package/build/index.esm.js.map +1 -1
  3. package/build/index.js +110 -114
  4. package/build/index.js.map +1 -1
  5. package/build/types/circularButton/CircularButton.d.ts +2 -2
  6. package/build/types/circularButton/CircularButton.d.ts.map +1 -1
  7. package/build/types/common/bottomSheet/BottomSheet.d.ts.map +1 -1
  8. package/build/types/common/textFormat/formatWithPattern/index.d.ts +1 -1
  9. package/build/types/common/textFormat/formatWithPattern/index.d.ts.map +1 -1
  10. package/build/types/common/textFormat/getCountOfSymbolsInSelection/getCountOfSymbolsInSelection.d.ts +1 -1
  11. package/build/types/common/textFormat/getCountOfSymbolsInSelection/getCountOfSymbolsInSelection.d.ts.map +1 -1
  12. package/build/types/common/textFormat/getCountOfSymbolsInSelection/index.d.ts +1 -1
  13. package/build/types/common/textFormat/getCountOfSymbolsInSelection/index.d.ts.map +1 -1
  14. package/build/types/common/textFormat/getCursorPositionAfterKeystroke/index.d.ts +1 -1
  15. package/build/types/common/textFormat/getCursorPositionAfterKeystroke/index.d.ts.map +1 -1
  16. package/build/types/common/textFormat/getDistanceToSymbol/getDistanceToSymbol.d.ts +2 -2
  17. package/build/types/common/textFormat/getDistanceToSymbol/getDistanceToSymbol.d.ts.map +1 -1
  18. package/build/types/common/textFormat/getDistanceToSymbol/index.d.ts +1 -1
  19. package/build/types/common/textFormat/getDistanceToSymbol/index.d.ts.map +1 -1
  20. package/build/types/common/textFormat/getSymbolsInPatternWithPosition/index.d.ts +1 -1
  21. package/build/types/common/textFormat/getSymbolsInPatternWithPosition/index.d.ts.map +1 -1
  22. package/build/types/common/textFormat/index.d.ts +7 -6
  23. package/build/types/common/textFormat/index.d.ts.map +1 -1
  24. package/build/types/common/textFormat/unformatWithPattern/index.d.ts +1 -1
  25. package/build/types/common/textFormat/unformatWithPattern/index.d.ts.map +1 -1
  26. package/build/types/index.d.ts +1 -1
  27. package/build/types/index.d.ts.map +1 -1
  28. package/build/types/info/Info.d.ts +2 -3
  29. package/build/types/info/Info.d.ts.map +1 -1
  30. package/build/types/logo/Logo.d.ts.map +1 -1
  31. package/build/types/popover/Popover.d.ts +21 -16
  32. package/build/types/popover/Popover.d.ts.map +1 -1
  33. package/build/types/popover/index.d.ts +1 -2
  34. package/build/types/popover/index.d.ts.map +1 -1
  35. package/build/types/slidingPanel/SlidingPanel.d.ts +12 -17
  36. package/build/types/slidingPanel/SlidingPanel.d.ts.map +1 -1
  37. package/build/types/slidingPanel/index.d.ts +2 -1
  38. package/build/types/slidingPanel/index.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/src/circularButton/CircularButton.tsx +2 -2
  41. package/src/common/bottomSheet/BottomSheet.tsx +47 -41
  42. package/src/common/bottomSheet/__snapshots__/BottomSheet.spec.tsx.snap +37 -33
  43. package/src/common/textFormat/getCountOfSymbolsInSelection/{getCountOfSymbolsInSelection.js → getCountOfSymbolsInSelection.ts} +5 -1
  44. package/src/common/textFormat/getCursorPositionAfterKeystroke/{getCursorPositionAfterKeystroke.spec.js → getCursorPositionAfterKeystroke.spec.ts} +15 -18
  45. package/src/common/textFormat/getDistanceToSymbol/{getDistanceToSymbol.spec.js → getDistanceToSymbol.spec.ts} +3 -3
  46. package/src/common/textFormat/getDistanceToSymbol/{getDistanceToSymbol.js → getDistanceToSymbol.ts} +8 -3
  47. package/src/index.ts +1 -1
  48. package/src/info/Info.tsx +2 -2
  49. package/src/logo/Logo.js +1 -0
  50. package/src/logo/__snapshots__/Logo.spec.js.snap +6 -0
  51. package/src/popover/Popover.js +101 -0
  52. package/src/popover/{Popover.spec.tsx → Popover.spec.js} +2 -5
  53. package/src/popover/index.js +1 -0
  54. package/src/select/Select.spec.js +1 -1
  55. package/src/slidingPanel/SlidingPanel.spec.js +9 -19
  56. package/src/slidingPanel/SlidingPanel.tsx +62 -0
  57. package/src/slidingPanel/index.ts +2 -0
  58. package/src/sticky/Sticky.spec.js +0 -1
  59. package/src/popover/Popover.tsx +0 -106
  60. package/src/popover/index.ts +0 -2
  61. package/src/slidingPanel/SlidingPanel.js +0 -73
  62. package/src/slidingPanel/index.js +0 -1
  63. /package/src/common/textFormat/formatWithPattern/{formatWithPattern.spec.js → formatWithPattern.spec.ts} +0 -0
  64. /package/src/common/textFormat/formatWithPattern/{index.js → index.ts} +0 -0
  65. /package/src/common/textFormat/getCountOfSymbolsInSelection/{getCountOfSymbolsInSelection.spec.js → getCountOfSymbolsInSelection.spec.ts} +0 -0
  66. /package/src/common/textFormat/getCountOfSymbolsInSelection/{index.js → index.ts} +0 -0
  67. /package/src/common/textFormat/getCursorPositionAfterKeystroke/{index.js → index.ts} +0 -0
  68. /package/src/common/textFormat/getDistanceToSymbol/{index.js → index.ts} +0 -0
  69. /package/src/common/textFormat/getSymbolsInPatternWithPosition/{getSymbolsInPatternWithPosition.spec.js → getSymbolsInPatternWithPosition.spec.ts} +0 -0
  70. /package/src/common/textFormat/getSymbolsInPatternWithPosition/{index.js → index.ts} +0 -0
  71. /package/src/common/textFormat/{index.js → index.ts} +0 -0
  72. /package/src/common/textFormat/unformatWithPattern/{index.js → index.ts} +0 -0
  73. /package/src/common/textFormat/unformatWithPattern/{unformatWithPattern.spec.js → unformatWithPattern.spec.ts} +0 -0
  74. /package/src/popover/{Popover.story.tsx → Popover.story.js} +0 -0
  75. /package/src/popover/__snapshots__/{Popover.spec.tsx.snap → Popover.spec.js.snap} +0 -0
  76. /package/src/slidingPanel/{SlidingPanel.story.js → SlidingPanel.story.tsx} +0 -0
@@ -1,12 +1,13 @@
1
1
  import getSymbolsInPatternWithPosition from '../getSymbolsInPatternWithPosition';
2
+ import { SymbolWithPosition } from '../getSymbolsInPatternWithPosition/getSymbolsInPatternWithPosition';
2
3
 
3
- export const getDistanceToNextSymbol = (selectionStart, pattern) => {
4
+ export const getDistanceToNextSymbol = (selectionStart: number, pattern: string) => {
4
5
  const patternArray = getSymbolsInPatternWithPosition(pattern);
5
6
  const applicablePattern = patternArray.filter((symbol) => symbol.index >= selectionStart);
6
7
  return countConsecutiveSymbols(selectionStart, applicablePattern, 'left');
7
8
  };
8
9
 
9
- export const getDistanceToPreviousSymbol = (selectionStart, pattern) => {
10
+ export const getDistanceToPreviousSymbol = (selectionStart: number, pattern: string) => {
10
11
  const patternArray = getSymbolsInPatternWithPosition(pattern);
11
12
  const applicablePattern = patternArray
12
13
  .filter((symbol) => symbol.index < selectionStart)
@@ -14,7 +15,11 @@ export const getDistanceToPreviousSymbol = (selectionStart, pattern) => {
14
15
  return countConsecutiveSymbols(selectionStart, applicablePattern, 'right');
15
16
  };
16
17
 
17
- const countConsecutiveSymbols = (selectionStart, applicablePattern, direction) => {
18
+ const countConsecutiveSymbols = (
19
+ selectionStart: number,
20
+ applicablePattern: SymbolWithPosition[],
21
+ direction: 'left' | 'right',
22
+ ) => {
18
23
  let cursor = selectionStart;
19
24
  let groupSize;
20
25
 
package/src/index.ts CHANGED
@@ -22,7 +22,6 @@ export type {
22
22
  } from './inputs/SelectInput';
23
23
  export type { TextAreaProps } from './inputs/TextArea';
24
24
  export type { PhoneNumberInputProps } from './phoneNumberInput/PhoneNumberInput';
25
- export type { PopoverProps, PopoverPreferredPlacement } from './popover';
26
25
  export type { RadioProps } from './radio';
27
26
  export type { RadioGroupProps, RadioGroupRadio } from './radioGroup';
28
27
  export type { RadioOptionProps } from './radioOption';
@@ -38,6 +37,7 @@ export type {
38
37
  CurrencyOptionItem,
39
38
  MoneyInputProps,
40
39
  } from './moneyInput';
40
+ export type { SlidingPanelProps } from './slidingPanel';
41
41
  export type {
42
42
  LayoutDirection,
43
43
  TypographyTypes,
package/src/info/Info.tsx CHANGED
@@ -5,7 +5,7 @@ import { useIntl } from 'react-intl';
5
5
 
6
6
  import { Size, Position, SizeSmall, SizeLarge } from '../common';
7
7
  import Modal from '../modal';
8
- import Popover, { PopoverPreferredPlacement } from '../popover';
8
+ import Popover from '../popover';
9
9
 
10
10
  import messages from './Info.messages';
11
11
  import { InfoPresentation } from './infoPresentations';
@@ -36,7 +36,7 @@ export interface Props {
36
36
  /**
37
37
  * Prferred placement of the Popover, does not apply to Modal
38
38
  */
39
- preferredPlacement?: PopoverPreferredPlacement;
39
+ preferredPlacement?: Position;
40
40
  }
41
41
 
42
42
  const Info = ({
package/src/logo/Logo.js CHANGED
@@ -23,6 +23,7 @@ const Logo = ({ className, inverse, type }) => {
23
23
  return (
24
24
  <span
25
25
  aria-label={type === LogoType.WISE ? 'Wise' : 'Wise business'}
26
+ role="img"
26
27
  className={classNames(className, 'np-logo')}
27
28
  >
28
29
  <LogoSm className="np-logo-svg np-logo-svg--size-sm" />
@@ -5,6 +5,7 @@ exports[`Logo on mobile renders only fast flag 1`] = `
5
5
  <span
6
6
  aria-label="Wise"
7
7
  class="class np-logo"
8
+ role="img"
8
9
  >
9
10
  <svg
10
11
  class="np-logo-svg np-logo-svg--size-sm"
@@ -39,6 +40,7 @@ exports[`Logo renders wise business logo 1`] = `
39
40
  <span
40
41
  aria-label="Wise business"
41
42
  class="class np-logo"
43
+ role="img"
42
44
  >
43
45
  <svg
44
46
  class="np-logo-svg np-logo-svg--size-sm"
@@ -73,6 +75,7 @@ exports[`Logo renders wise business logo inversed 1`] = `
73
75
  <span
74
76
  aria-label="Wise business"
75
77
  class="class np-logo"
78
+ role="img"
76
79
  >
77
80
  <svg
78
81
  class="np-logo-svg np-logo-svg--size-sm"
@@ -107,6 +110,7 @@ exports[`Logo renders wise logo 1`] = `
107
110
  <span
108
111
  aria-label="Wise"
109
112
  class="class np-logo"
113
+ role="img"
110
114
  >
111
115
  <svg
112
116
  class="np-logo-svg np-logo-svg--size-sm"
@@ -141,6 +145,7 @@ exports[`Logo renders wise logo by default 1`] = `
141
145
  <span
142
146
  aria-label="Wise"
143
147
  class="class np-logo"
148
+ role="img"
144
149
  >
145
150
  <svg
146
151
  class="np-logo-svg np-logo-svg--size-sm"
@@ -175,6 +180,7 @@ exports[`Logo renders wise logo inversed 1`] = `
175
180
  <span
176
181
  aria-label="Wise"
177
182
  class="class np-logo"
183
+ role="img"
178
184
  >
179
185
  <svg
180
186
  class="np-logo-svg np-logo-svg--size-sm"
@@ -0,0 +1,101 @@
1
+ import { useTheme } from '@wise/components-theming';
2
+ import classnames from 'classnames';
3
+ import PropTypes from 'prop-types';
4
+ import { useRef, useState, cloneElement } from 'react';
5
+
6
+ import { Position, Typography } from '../common';
7
+ import ResponsivePanel from '../common/responsivePanel';
8
+ import Title from '../title';
9
+ import { logActionRequiredIf } from '../utilities';
10
+
11
+ const Popover = ({ children, className, content, preferredPlacement, title, onClose }) => {
12
+ logActionRequired({ preferredPlacement });
13
+ const anchorReference = useRef(null);
14
+ const [open, setOpen] = useState(false);
15
+ const { isModern } = useTheme();
16
+
17
+ const handleOnClose = () => {
18
+ setOpen(false);
19
+ onClose?.();
20
+ };
21
+
22
+ return (
23
+ <span className={classnames('np-popover', className)}>
24
+ <span ref={anchorReference} className="d-inline-block">
25
+ {cloneElement(children, {
26
+ onClick: () => {
27
+ if (children?.props?.onClick) {
28
+ children.props.onClick();
29
+ }
30
+ setOpen(!open);
31
+ },
32
+ })}
33
+ </span>
34
+ <ResponsivePanel
35
+ open={open}
36
+ anchorRef={anchorReference}
37
+ position={deprecatedPlacements[preferredPlacement] || preferredPlacement}
38
+ arrow
39
+ className="np-popover__container"
40
+ onClose={handleOnClose}
41
+ >
42
+ <div
43
+ className={isModern ? 'np-popover__content np-text-default-body' : 'np-popover__content'}
44
+ aria-hidden={!open}
45
+ role="dialog"
46
+ >
47
+ {title && (
48
+ <Title type={Typography.TITLE_BODY} className="m-b-1">
49
+ {title}
50
+ </Title>
51
+ )}
52
+ {content}
53
+ </div>
54
+ </ResponsivePanel>
55
+ </span>
56
+ );
57
+ };
58
+
59
+ const logActionRequired = ({ preferredPlacement }) => {
60
+ logActionRequiredIf(
61
+ `Popover has deprecated ${preferredPlacement} value for the 'preferredPlacement' prop. Please use ${deprecatedPlacements[preferredPlacement]} instead.`,
62
+ deprecatedPlacements[preferredPlacement],
63
+ );
64
+ };
65
+
66
+ Popover.defaultProps = {
67
+ className: undefined,
68
+ preferredPlacement: Position.RIGHT,
69
+ title: undefined,
70
+ };
71
+
72
+ Popover.propTypes = {
73
+ children: PropTypes.node.isRequired,
74
+ className: PropTypes.string,
75
+ content: PropTypes.node.isRequired,
76
+ /**
77
+ * `'left-top'` / `'right-top'` are deprecated use `Position.TOP` / `'top'` instead,
78
+ * `'bottom-right'` / `'bottom-left'` are deprecated use `Position.BOTTOM` / `'bottom'` instead
79
+ */
80
+ preferredPlacement: PropTypes.oneOf([
81
+ 'top',
82
+ 'right',
83
+ 'bottom',
84
+ 'left',
85
+ 'left-top',
86
+ 'right-top',
87
+ 'bottom-right',
88
+ 'bottom-left',
89
+ ]),
90
+ onClose: PropTypes.func,
91
+ title: PropTypes.node,
92
+ };
93
+
94
+ const deprecatedPlacements = {
95
+ [Position.BOTTOM_LEFT]: Position.BOTTOM,
96
+ [Position.BOTTOM_RIGHT]: Position.BOTTOM,
97
+ [Position.LEFT_TOP]: Position.TOP,
98
+ [Position.RIGHT_TOP]: Position.TOP,
99
+ };
100
+
101
+ export default Popover;
@@ -7,7 +7,7 @@ mockMatchMedia();
7
7
 
8
8
  jest.mock('react-transition-group', () => ({
9
9
  __esModule: true,
10
- CSSTransition: (props: Record<string, unknown>) => (props.in ? props.children : null),
10
+ CSSTransition: (props) => (props.in ? props.children : null),
11
11
  }));
12
12
 
13
13
  describe('Popover', () => {
@@ -117,10 +117,7 @@ describe('Popover', () => {
117
117
  expect(handleOnClose).not.toHaveBeenCalled();
118
118
  userEvent.click(screen.getByText('Open'));
119
119
  await waitForPanel();
120
- const dimmer = getDimmer();
121
- if (dimmer != null) {
122
- userEvent.click(dimmer);
123
- }
120
+ userEvent.click(getDimmer());
124
121
  expect(handleOnClose).toHaveBeenCalledTimes(1);
125
122
  });
126
123
 
@@ -0,0 +1 @@
1
+ export { default } from './Popover';
@@ -278,7 +278,7 @@ describe('Select', () => {
278
278
 
279
279
  const bottomSheet = await screen.findByRole('dialog');
280
280
 
281
- expect(bottomSheet).toHaveClass('np-bottom-sheet');
281
+ expect(bottomSheet).toBeInTheDocument();
282
282
  });
283
283
 
284
284
  it('show list of options in Drawer when on mobile and search in enabled', async () => {
@@ -24,17 +24,7 @@ describe('SlidingPanel', () => {
24
24
 
25
25
  expect(cssTransition()).toHaveLength(1);
26
26
 
27
- expect(cssTransition().props()).toMatchObject({
28
- in: true,
29
- appear: true,
30
- timeout: {
31
- enter: 0,
32
- exit: EXIT_ANIMATION,
33
- },
34
- classNames: 'sliding-panel--open-left sliding-panel',
35
- unmountOnExit: true,
36
- });
37
- expect(cssTransition().props().children.props).toStrictEqual({
27
+ expect(cssTransition().props()).toStrictEqual({
38
28
  className: 'sliding-panel sliding-panel--open-left',
39
29
  children: null,
40
30
  });
@@ -42,24 +32,24 @@ describe('SlidingPanel', () => {
42
32
 
43
33
  it('adds fixed class', () => {
44
34
  component = shallow(<SlidingPanel {...props} slidingPanelPositionFixed />);
45
- expect(cssTransition().prop('classNames')).toBe(
46
- 'sliding-panel--open-left sliding-panel--fixed sliding-panel',
35
+ expect(cssTransition().prop('className')).toBe(
36
+ 'sliding-panel sliding-panel--open-left sliding-panel--fixed',
47
37
  );
48
38
  });
49
39
 
50
40
  it('adds border classes if showSlidingPanelBorder is set to true', () => {
51
41
  component = shallow(<SlidingPanel {...props} showSlidingPanelBorder />);
52
- expect(cssTransition().prop('classNames')).toBe(
53
- 'sliding-panel--open-left sliding-panel--border-left sliding-panel',
42
+ expect(cssTransition().prop('className')).toBe(
43
+ 'sliding-panel sliding-panel--open-left sliding-panel--border-left',
54
44
  );
55
45
  component = shallow(<SlidingPanel {...props} showSlidingPanelBorder={false} position="left" />);
56
- expect(cssTransition().prop('classNames')).toBe('sliding-panel--open-left sliding-panel');
46
+ expect(cssTransition().prop('className')).toBe('sliding-panel sliding-panel--open-left');
57
47
 
58
48
  component = shallow(<SlidingPanel {...props} showSlidingPanelBorder position="top" />);
59
- expect(cssTransition().prop('classNames')).toBe(
60
- 'sliding-panel--open-top sliding-panel--border-top sliding-panel',
49
+ expect(cssTransition().prop('className')).toBe(
50
+ 'sliding-panel sliding-panel--open-top sliding-panel--border-top',
61
51
  );
62
52
  });
63
53
 
64
- const cssTransition = () => component.find('CSSTransition');
54
+ const cssTransition = () => component.find('div');
65
55
  });
@@ -0,0 +1,62 @@
1
+ import classNames from 'classnames';
2
+ import { forwardRef, useRef } from 'react';
3
+ import mergeRefs from 'react-merge-refs';
4
+ import { CSSTransition } from 'react-transition-group';
5
+
6
+ import { Position } from '../common';
7
+
8
+ export const EXIT_ANIMATION = 350;
9
+
10
+ export interface SlidingPanelProps
11
+ extends Pick<React.ComponentPropsWithRef<'div'>, 'ref' | 'className' | 'children'> {
12
+ position?: `${Position.TOP | Position.RIGHT | Position.BOTTOM | Position.LEFT}`;
13
+ open: boolean;
14
+ showSlidingPanelBorder?: boolean;
15
+ slidingPanelPositionFixed?: boolean;
16
+ }
17
+
18
+ const SlidingPanel = forwardRef(
19
+ (
20
+ {
21
+ position = 'left',
22
+ open,
23
+ showSlidingPanelBorder,
24
+ slidingPanelPositionFixed,
25
+ className,
26
+ children,
27
+ ...rest
28
+ }: Omit<SlidingPanelProps, 'ref'>,
29
+ reference: React.ForwardedRef<HTMLDivElement>,
30
+ ) => {
31
+ const localReference = useRef<HTMLDivElement>(null);
32
+
33
+ return (
34
+ <CSSTransition
35
+ {...rest}
36
+ key={`sliding-panel--open-${position}`}
37
+ nodeRef={localReference}
38
+ in={open}
39
+ // Wait for animation to finish before unmount.
40
+ timeout={{ enter: 0, exit: EXIT_ANIMATION }}
41
+ classNames="sliding-panel"
42
+ appear
43
+ unmountOnExit
44
+ >
45
+ <div
46
+ ref={mergeRefs([reference, localReference])}
47
+ className={classNames(
48
+ 'sliding-panel',
49
+ `sliding-panel--open-${position}`,
50
+ showSlidingPanelBorder && `sliding-panel--border-${position}`,
51
+ slidingPanelPositionFixed && 'sliding-panel--fixed',
52
+ className,
53
+ )}
54
+ >
55
+ {children}
56
+ </div>
57
+ </CSSTransition>
58
+ );
59
+ },
60
+ );
61
+
62
+ export default SlidingPanel;
@@ -0,0 +1,2 @@
1
+ export { default } from './SlidingPanel';
2
+ export type { SlidingPanelProps } from './SlidingPanel';
@@ -25,7 +25,6 @@ describe('Sticky', () => {
25
25
 
26
26
  expect(slidingPanel.props()).toStrictEqual({
27
27
  children: null,
28
- className: undefined,
29
28
  open: true,
30
29
  position: 'bottom',
31
30
  showSlidingPanelBorder: true,
@@ -1,106 +0,0 @@
1
- import { useTheme } from '@wise/components-theming';
2
- import classnames from 'classnames';
3
- import { useRef, useState, cloneElement, useEffect, isValidElement } from 'react';
4
-
5
- import { Position, Typography } from '../common';
6
- import ResponsivePanel from '../common/responsivePanel';
7
- import Title from '../title';
8
- import { logActionRequired } from '../utilities';
9
-
10
- /** @deprecated Use `"top" | "bottom"` instead. */
11
- type PopoverPreferredPlacementDeprecated =
12
- | `${Position.LEFT_TOP}`
13
- | `${Position.RIGHT_TOP}`
14
- | `${Position.BOTTOM_RIGHT}`
15
- | `${Position.BOTTOM_LEFT}`;
16
-
17
- export type PopoverPreferredPlacement =
18
- | `${Position.TOP}`
19
- | `${Position.RIGHT}`
20
- | `${Position.BOTTOM}`
21
- | `${Position.LEFT}`
22
- | PopoverPreferredPlacementDeprecated;
23
-
24
- export interface PopoverProps {
25
- children?: React.ReactNode;
26
- className?: string;
27
- content: React.ReactNode;
28
- preferredPlacement?: PopoverPreferredPlacement;
29
- onClose?: () => void;
30
- title?: React.ReactNode;
31
- }
32
-
33
- function resolvePlacement(preferredPlacement: PopoverPreferredPlacement) {
34
- switch (preferredPlacement) {
35
- case 'left-top':
36
- case 'right-top':
37
- return 'top';
38
- case 'bottom-left':
39
- case 'bottom-right':
40
- return 'bottom';
41
- }
42
- return preferredPlacement;
43
- }
44
-
45
- export default function Popover({
46
- children,
47
- className,
48
- content,
49
- preferredPlacement = Position.RIGHT,
50
- title,
51
- onClose,
52
- }: PopoverProps) {
53
- const resolvedPlacement = resolvePlacement(preferredPlacement);
54
- useEffect(() => {
55
- if (resolvedPlacement !== preferredPlacement) {
56
- logActionRequired(
57
- `Popover has deprecated ${preferredPlacement} value for the 'preferredPlacement' prop. Please use ${resolvedPlacement} instead.`,
58
- );
59
- }
60
- }, [preferredPlacement, resolvedPlacement]);
61
-
62
- const anchorReference = useRef(null);
63
- const [open, setOpen] = useState(false);
64
- const { isModern } = useTheme();
65
-
66
- const handleOnClose = () => {
67
- setOpen(false);
68
- onClose?.();
69
- };
70
-
71
- return (
72
- <span className={classnames('np-popover', className)}>
73
- <span ref={anchorReference} className="d-inline-block">
74
- {isValidElement<{ onClick?: () => void }>(children)
75
- ? cloneElement(children, {
76
- onClick: () => {
77
- children.props.onClick?.();
78
- setOpen((prevOpen) => !prevOpen);
79
- },
80
- })
81
- : children}
82
- </span>
83
- <ResponsivePanel
84
- open={open}
85
- anchorRef={anchorReference}
86
- position={resolvedPlacement}
87
- arrow
88
- className="np-popover__container"
89
- onClose={handleOnClose}
90
- >
91
- <div
92
- className={isModern ? 'np-popover__content np-text-default-body' : 'np-popover__content'}
93
- aria-hidden={!open}
94
- role="dialog"
95
- >
96
- {title && (
97
- <Title type={Typography.TITLE_BODY} className="m-b-1">
98
- {title}
99
- </Title>
100
- )}
101
- {content}
102
- </div>
103
- </ResponsivePanel>
104
- </span>
105
- );
106
- }
@@ -1,2 +0,0 @@
1
- export { default } from './Popover';
2
- export type { PopoverProps, PopoverPreferredPlacement } from './Popover';
@@ -1,73 +0,0 @@
1
- import classNames from 'classnames';
2
- import PropTypes from 'prop-types';
3
- import { forwardRef, RefObject, useRef } from 'react';
4
- import mergeRefs from 'react-merge-refs';
5
- import { CSSTransition } from 'react-transition-group';
6
-
7
- export const EXIT_ANIMATION = 350;
8
-
9
- const SlidingPanel = forwardRef(
10
- (
11
- {
12
- children,
13
- className,
14
- open,
15
- position,
16
- showSlidingPanelBorder,
17
- slidingPanelPositionFixed,
18
- ...rest
19
- },
20
- reference,
21
- ) => {
22
- /** @type {RefObject<HTMLDivElement>} */
23
- const localReference = useRef(null);
24
-
25
- return (
26
- <CSSTransition
27
- {...rest}
28
- key={`sliding-panel--open-${position}`}
29
- nodeRef={localReference}
30
- in={open}
31
- // Wait for animation to finish before unmount.
32
- timeout={{ enter: 0, exit: EXIT_ANIMATION }}
33
- classNames={classNames(
34
- `sliding-panel--open-${position}`,
35
- showSlidingPanelBorder && `sliding-panel--border-${position}`,
36
- {
37
- 'sliding-panel--fixed': slidingPanelPositionFixed,
38
- },
39
- 'sliding-panel',
40
- )}
41
- appear
42
- unmountOnExit
43
- >
44
- <div
45
- ref={mergeRefs([reference, localReference])}
46
- className={classNames('sliding-panel', `sliding-panel--open-${position}`, className)}
47
- >
48
- {children}
49
- </div>
50
- </CSSTransition>
51
- );
52
- },
53
- );
54
-
55
- SlidingPanel.propTypes = {
56
- children: PropTypes.node,
57
- className: PropTypes.string,
58
- open: PropTypes.bool,
59
- position: PropTypes.oneOf(['top', 'bottom', 'left', 'right']),
60
- showSlidingPanelBorder: PropTypes.bool,
61
- slidingPanelPositionFixed: PropTypes.bool,
62
- };
63
-
64
- SlidingPanel.defaultProps = {
65
- children: null,
66
- className: undefined,
67
- open: false,
68
- position: 'left',
69
- showSlidingPanelBorder: false,
70
- slidingPanelPositionFixed: false,
71
- };
72
-
73
- export default SlidingPanel;
@@ -1 +0,0 @@
1
- export { default } from './SlidingPanel';
File without changes