@transferwise/components 0.0.0-experimental-af01b75 → 0.0.0-experimental-0657ea4

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 (44) hide show
  1. package/build/ExpressiveMoneyInput/Chevron/Chevron.js +10 -2
  2. package/build/ExpressiveMoneyInput/Chevron/Chevron.js.map +1 -1
  3. package/build/ExpressiveMoneyInput/Chevron/Chevron.mjs +11 -3
  4. package/build/ExpressiveMoneyInput/Chevron/Chevron.mjs.map +1 -1
  5. package/build/common/Panel/Panel.js +13 -25
  6. package/build/common/Panel/Panel.js.map +1 -1
  7. package/build/common/Panel/Panel.mjs +10 -22
  8. package/build/common/Panel/Panel.mjs.map +1 -1
  9. package/build/common/Panel/Panel.positionUtils.js +68 -0
  10. package/build/common/Panel/Panel.positionUtils.js.map +1 -0
  11. package/build/common/Panel/Panel.positionUtils.mjs +63 -0
  12. package/build/common/Panel/Panel.positionUtils.mjs.map +1 -0
  13. package/build/common/PropsValues/position.js +0 -25
  14. package/build/common/PropsValues/position.js.map +1 -1
  15. package/build/common/PropsValues/position.mjs +1 -24
  16. package/build/common/PropsValues/position.mjs.map +1 -1
  17. package/build/main.css +12 -4
  18. package/build/styles/common/Panel/Panel.css +12 -4
  19. package/build/styles/main.css +12 -4
  20. package/build/types/Body/Body.d.ts +2 -2
  21. package/build/types/ExpressiveMoneyInput/Chevron/Chevron.d.ts.map +1 -1
  22. package/build/types/IconButton/IconButton.d.ts +1 -1
  23. package/build/types/MoneyInput/MoneyInput.d.ts +1 -1
  24. package/build/types/MoneyInput/MoneyInput.d.ts.map +1 -1
  25. package/build/types/Title/Title.d.ts +2 -2
  26. package/build/types/Upload/Steps/UploadImageStep/UploadImageStep.d.ts +1 -1
  27. package/build/types/UploadInput/UploadItem/UploadItemLink.d.ts +1 -1
  28. package/build/types/common/Panel/Panel.d.ts +1 -1
  29. package/build/types/common/Panel/Panel.d.ts.map +1 -1
  30. package/build/types/common/Panel/Panel.positionUtils.d.ts +7 -0
  31. package/build/types/common/Panel/Panel.positionUtils.d.ts.map +1 -0
  32. package/build/types/common/PropsValues/position.d.ts +0 -13
  33. package/build/types/common/PropsValues/position.d.ts.map +1 -1
  34. package/build/types/common/ResponsivePanel/ResponsivePanel.d.ts +1 -1
  35. package/package.json +2 -2
  36. package/src/ExpressiveMoneyInput/Chevron/Chevron.tsx +8 -3
  37. package/src/common/Panel/Panel.css +12 -4
  38. package/src/common/Panel/Panel.less +27 -9
  39. package/src/common/Panel/Panel.positionUtils.ts +79 -0
  40. package/src/common/Panel/Panel.test.tsx +40 -0
  41. package/src/common/Panel/Panel.tsx +13 -24
  42. package/src/common/Panel/_stories/Panel.rtl.test.story.tsx +110 -0
  43. package/src/common/PropsValues/position.ts +0 -50
  44. package/src/main.css +12 -4
package/build/main.css CHANGED
@@ -21875,27 +21875,35 @@ button.np-option {
21875
21875
  .np-panel[data-popper-placement^="top"] > .np-panel__content {
21876
21876
  transform: translateY(10px) scale(0.95);
21877
21877
  }
21878
- .np-panel[data-popper-placement^="top"] > .np-panel__content .np-panel__arrow {
21878
+ .np-panel[data-popper-placement^="top"] .np-panel__arrow {
21879
21879
  inset-block-end: -6px;
21880
21880
  }
21881
21881
  .np-panel[data-popper-placement^="right"] > .np-panel__content {
21882
21882
  transform: translateX(-10px) scale(0.95);
21883
21883
  }
21884
- .np-panel[data-popper-placement^="right"] > .np-panel__content .np-panel__arrow {
21884
+ .np-panel[data-popper-placement^="right"] .np-panel__arrow {
21885
21885
  inset-inline-start: -6px;
21886
21886
  }
21887
+ [dir="rtl"] .np-panel[data-popper-placement^="right"] .np-panel__arrow {
21888
+ inset-inline-start: unset;
21889
+ inset-inline-end: -6px;
21890
+ }
21887
21891
  .np-panel[data-popper-placement^="bottom"] > .np-panel__content {
21888
21892
  transform: translateY(-10px) scale(0.95);
21889
21893
  }
21890
- .np-panel[data-popper-placement^="bottom"] > .np-panel__content .np-panel__arrow {
21894
+ .np-panel[data-popper-placement^="bottom"] .np-panel__arrow {
21891
21895
  inset-block-start: -6px;
21892
21896
  }
21893
21897
  .np-panel[data-popper-placement^="left"] > .np-panel__content {
21894
21898
  transform: translateX(10px) scale(0.95);
21895
21899
  }
21896
- .np-panel[data-popper-placement^="left"] > .np-panel__content .np-panel__arrow {
21900
+ .np-panel[data-popper-placement^="left"] .np-panel__arrow {
21897
21901
  inset-inline-end: -6px;
21898
21902
  }
21903
+ [dir="rtl"] .np-panel[data-popper-placement^="left"] .np-panel__arrow {
21904
+ inset-inline-end: unset;
21905
+ inset-inline-start: -6px;
21906
+ }
21899
21907
  .np-theme-personal .np-panel__content {
21900
21908
  border-radius: 16px;
21901
21909
  border-radius: var(--radius-medium);
@@ -39,27 +39,35 @@
39
39
  .np-panel[data-popper-placement^="top"] > .np-panel__content {
40
40
  transform: translateY(10px) scale(0.95);
41
41
  }
42
- .np-panel[data-popper-placement^="top"] > .np-panel__content .np-panel__arrow {
42
+ .np-panel[data-popper-placement^="top"] .np-panel__arrow {
43
43
  inset-block-end: -6px;
44
44
  }
45
45
  .np-panel[data-popper-placement^="right"] > .np-panel__content {
46
46
  transform: translateX(-10px) scale(0.95);
47
47
  }
48
- .np-panel[data-popper-placement^="right"] > .np-panel__content .np-panel__arrow {
48
+ .np-panel[data-popper-placement^="right"] .np-panel__arrow {
49
49
  inset-inline-start: -6px;
50
50
  }
51
+ [dir="rtl"] .np-panel[data-popper-placement^="right"] .np-panel__arrow {
52
+ inset-inline-start: unset;
53
+ inset-inline-end: -6px;
54
+ }
51
55
  .np-panel[data-popper-placement^="bottom"] > .np-panel__content {
52
56
  transform: translateY(-10px) scale(0.95);
53
57
  }
54
- .np-panel[data-popper-placement^="bottom"] > .np-panel__content .np-panel__arrow {
58
+ .np-panel[data-popper-placement^="bottom"] .np-panel__arrow {
55
59
  inset-block-start: -6px;
56
60
  }
57
61
  .np-panel[data-popper-placement^="left"] > .np-panel__content {
58
62
  transform: translateX(10px) scale(0.95);
59
63
  }
60
- .np-panel[data-popper-placement^="left"] > .np-panel__content .np-panel__arrow {
64
+ .np-panel[data-popper-placement^="left"] .np-panel__arrow {
61
65
  inset-inline-end: -6px;
62
66
  }
67
+ [dir="rtl"] .np-panel[data-popper-placement^="left"] .np-panel__arrow {
68
+ inset-inline-end: unset;
69
+ inset-inline-start: -6px;
70
+ }
63
71
  .np-theme-personal .np-panel__content {
64
72
  border-radius: 16px;
65
73
  border-radius: var(--radius-medium);
@@ -21875,27 +21875,35 @@ button.np-option {
21875
21875
  .np-panel[data-popper-placement^="top"] > .np-panel__content {
21876
21876
  transform: translateY(10px) scale(0.95);
21877
21877
  }
21878
- .np-panel[data-popper-placement^="top"] > .np-panel__content .np-panel__arrow {
21878
+ .np-panel[data-popper-placement^="top"] .np-panel__arrow {
21879
21879
  inset-block-end: -6px;
21880
21880
  }
21881
21881
  .np-panel[data-popper-placement^="right"] > .np-panel__content {
21882
21882
  transform: translateX(-10px) scale(0.95);
21883
21883
  }
21884
- .np-panel[data-popper-placement^="right"] > .np-panel__content .np-panel__arrow {
21884
+ .np-panel[data-popper-placement^="right"] .np-panel__arrow {
21885
21885
  inset-inline-start: -6px;
21886
21886
  }
21887
+ [dir="rtl"] .np-panel[data-popper-placement^="right"] .np-panel__arrow {
21888
+ inset-inline-start: unset;
21889
+ inset-inline-end: -6px;
21890
+ }
21887
21891
  .np-panel[data-popper-placement^="bottom"] > .np-panel__content {
21888
21892
  transform: translateY(-10px) scale(0.95);
21889
21893
  }
21890
- .np-panel[data-popper-placement^="bottom"] > .np-panel__content .np-panel__arrow {
21894
+ .np-panel[data-popper-placement^="bottom"] .np-panel__arrow {
21891
21895
  inset-block-start: -6px;
21892
21896
  }
21893
21897
  .np-panel[data-popper-placement^="left"] > .np-panel__content {
21894
21898
  transform: translateX(10px) scale(0.95);
21895
21899
  }
21896
- .np-panel[data-popper-placement^="left"] > .np-panel__content .np-panel__arrow {
21900
+ .np-panel[data-popper-placement^="left"] .np-panel__arrow {
21897
21901
  inset-inline-end: -6px;
21898
21902
  }
21903
+ [dir="rtl"] .np-panel[data-popper-placement^="left"] .np-panel__arrow {
21904
+ inset-inline-end: unset;
21905
+ inset-inline-start: -6px;
21906
+ }
21899
21907
  .np-theme-personal .np-panel__content {
21900
21908
  border-radius: 16px;
21901
21909
  border-radius: var(--radius-medium);
@@ -11,7 +11,7 @@ export type BodyProps = HTMLAttributes<HTMLSpanElement | HTMLParagraphElement> &
11
11
  */
12
12
  preserveNewlines?: boolean;
13
13
  };
14
- declare const Body: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLSpanElement | HTMLParagraphElement> & {
14
+ declare const Body: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLParagraphElement | HTMLSpanElement> & {
15
15
  /** @default 'body-default' */
16
16
  type?: BodyTypes;
17
17
  /** @default 'div' */
@@ -21,6 +21,6 @@ declare const Body: import("react").ForwardRefExoticComponent<HTMLAttributes<HTM
21
21
  * @default false
22
22
  */
23
23
  preserveNewlines?: boolean;
24
- } & import("react").RefAttributes<HTMLDivElement | HTMLSpanElement | HTMLParagraphElement | null>>;
24
+ } & import("react").RefAttributes<HTMLDivElement | HTMLParagraphElement | HTMLSpanElement | null>>;
25
25
  export default Body;
26
26
  //# sourceMappingURL=Body.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Chevron.d.ts","sourceRoot":"","sources":["../../../../src/ExpressiveMoneyInput/Chevron/Chevron.tsx"],"names":[],"mappings":"AAIA,UAAU,KAAK;IACb,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,OAAO,GAAI,gBAAuB,KAAK,gCA0BnD,CAAC"}
1
+ {"version":3,"file":"Chevron.d.ts","sourceRoot":"","sources":["../../../../src/ExpressiveMoneyInput/Chevron/Chevron.tsx"],"names":[],"mappings":"AAMA,UAAU,KAAK;IACb,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,OAAO,GAAI,gBAAuB,KAAK,gCA6BnD,CAAC"}
@@ -16,6 +16,6 @@ declare const IconButton: import("react").ForwardRefExoticComponent<{
16
16
  /** @default 'default' */
17
17
  type?: "default" | "negative";
18
18
  'data-testid'?: string;
19
- } & Pick<AnchorHTMLAttributes<HTMLAnchorElement>, "onClick" | "target" | "href"> & Pick<ButtonHTMLAttributes<HTMLButtonElement>, "disabled" | "onClick"> & Pick<HTMLAttributes<HTMLDivElement>, "children" | "className" | "id" | "tabIndex" | "role" | "aria-label"> & import("react").RefAttributes<unknown>>;
19
+ } & Pick<AnchorHTMLAttributes<HTMLAnchorElement>, "onClick" | "target" | "href"> & Pick<ButtonHTMLAttributes<HTMLButtonElement>, "disabled" | "onClick"> & Pick<HTMLAttributes<HTMLDivElement>, "id" | "className" | "tabIndex" | "role" | "aria-label" | "children"> & import("react").RefAttributes<unknown>>;
20
20
  export default IconButton;
21
21
  //# sourceMappingURL=IconButton.d.ts.map
@@ -55,6 +55,7 @@ declare const _default: import("react").FC<{
55
55
  selectProps?: Partial<SelectInputProps<CurrencyOptionItem>> | undefined;
56
56
  amount: number | null;
57
57
  searchPlaceholder?: string | undefined;
58
+ decimals?: number | undefined;
58
59
  currencies: readonly CurrencyItem[];
59
60
  selectedCurrency: CurrencyOptionItem;
60
61
  onCurrencyChange?: ((value: CurrencyOptionItem) => void) | undefined;
@@ -66,7 +67,6 @@ declare const _default: import("react").FC<{
66
67
  }) => void) | undefined;
67
68
  customActionLabel?: import("react").ReactNode;
68
69
  onCustomAction?: (() => void) | undefined;
69
- decimals?: number | undefined;
70
70
  }>;
71
71
  export default _default;
72
72
  //# sourceMappingURL=MoneyInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MoneyInput.d.ts","sourceRoot":"","sources":["../../../src/MoneyInput/MoneyInput.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE9E,OAAO,EAGL,SAAS,EACT,UAAU,EACV,SAAS,EAEV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAuB,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAEnF,OAAO,EAKL,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAO/B,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;AAoDnE,MAAM,WAAW,eAAgB,SAAQ,qBAAqB;IAC5D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,SAAS,YAAY,EAAE,CAAC;IACpC,gBAAgB,EAAE,kBAAkB,CAAC;IACrC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IAC1C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,YAAY,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3F,iBAAiB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC5D;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,kCAAkC,GAAG,eAAe,GAC9D,OAAO,CAAC,wBAAwB,CAAC,CAAC;;SA5B7B,MAAM;wBACS,MAAM;YAMnB,SAAS,GAAG,UAAU,GAAG,SAAS;kBAF3B,MAAM;iBAYP,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;kBACrB,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;YAZnD,MAAM,GAAG,IAAI;wBAID,MAAM;gBARd,SAAS,YAAY,EAAE;sBACjB,kBAAkB;wBACjB,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI;sBAIrC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;;sBAM9B,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,YAAY,EAAE,CAAA;KAAE,KAAK,IAAI;;sBAEzE,MAAM,IAAI;eAQhB,MAAM;;AAyanB,wBAA2F"}
1
+ {"version":3,"file":"MoneyInput.d.ts","sourceRoot":"","sources":["../../../src/MoneyInput/MoneyInput.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE9E,OAAO,EAGL,SAAS,EACT,UAAU,EACV,SAAS,EAEV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAuB,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAEnF,OAAO,EAKL,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAO/B,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;AAoDnE,MAAM,WAAW,eAAgB,SAAQ,qBAAqB;IAC5D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,SAAS,YAAY,EAAE,CAAC;IACpC,gBAAgB,EAAE,kBAAkB,CAAC;IACrC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IAC1C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,YAAY,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3F,iBAAiB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC5D;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,kCAAkC,GAAG,eAAe,GAC9D,OAAO,CAAC,wBAAwB,CAAC,CAAC;;SA5B7B,MAAM;wBACS,MAAM;YAMnB,SAAS,GAAG,UAAU,GAAG,SAAS;kBAF3B,MAAM;iBAYP,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;kBACrB,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;YAZnD,MAAM,GAAG,IAAI;wBAID,MAAM;eAcf,MAAM;gBAtBL,SAAS,YAAY,EAAE;sBACjB,kBAAkB;wBACjB,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI;sBAIrC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;;sBAM9B,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,YAAY,EAAE,CAAA;KAAE,KAAK,IAAI;;sBAEzE,MAAM,IAAI;;AAib7B,wBAA2F"}
@@ -10,7 +10,7 @@ export type TitleProps = LabelHTMLAttributes<HTMLHeadingElement | HTMLSpanElemen
10
10
  */
11
11
  type?: TitleTypes;
12
12
  };
13
- declare const Title: React.ForwardRefExoticComponent<React.LabelHTMLAttributes<HTMLSpanElement | HTMLHeadingElement | HTMLLabelElement> & React.LiHTMLAttributes<HTMLLIElement> & {
13
+ declare const Title: React.ForwardRefExoticComponent<React.LabelHTMLAttributes<HTMLHeadingElement | HTMLLabelElement | HTMLSpanElement> & React.LiHTMLAttributes<HTMLLIElement> & {
14
14
  /**
15
15
  * Default value will based one `type` prop
16
16
  */
@@ -19,6 +19,6 @@ declare const Title: React.ForwardRefExoticComponent<React.LabelHTMLAttributes<H
19
19
  * Default value: {@link DEFAULT_TYPE}
20
20
  */
21
21
  type?: TitleTypes;
22
- } & React.RefAttributes<HTMLSpanElement | HTMLHeadingElement | HTMLLabelElement | HTMLLegendElement | HTMLLIElement>>;
22
+ } & React.RefAttributes<HTMLHeadingElement | HTMLLabelElement | HTMLLegendElement | HTMLLIElement | HTMLSpanElement>>;
23
23
  export default Title;
24
24
  //# sourceMappingURL=Title.d.ts.map
@@ -15,7 +15,7 @@ export default class UploadImageStep extends PureComponent<UploadImageStepProps>
15
15
  uploadInputRef: import("react").RefObject<HTMLInputElement>;
16
16
  onManualUpload: () => void;
17
17
  onKeyDown: (event: React.KeyboardEvent<HTMLLabelElement>) => void;
18
- getImage: () => number | true | import("react").JSX.Element | Iterable<import("react").ReactNode>;
18
+ getImage: () => number | true | Iterable<import("react").ReactNode> | import("react").JSX.Element;
19
19
  render(): import("react").JSX.Element;
20
20
  }
21
21
  //# sourceMappingURL=UploadImageStep.d.ts.map
@@ -5,5 +5,5 @@ export declare const UploadItemLink: import("react").ForwardRefExoticComponent<{
5
5
  singleFileUpload: boolean;
6
6
  } & {
7
7
  children?: import("react").ReactNode | undefined;
8
- } & import("react").RefAttributes<HTMLDivElement | HTMLAnchorElement>>;
8
+ } & import("react").RefAttributes<HTMLAnchorElement | HTMLDivElement>>;
9
9
  //# sourceMappingURL=UploadItemLink.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { HTMLAttributes, PropsWithChildren, RefObject, SyntheticEvent } from 'react';
2
- import { type FloatingPlacement } from '..';
2
+ import { type FloatingPlacement } from './Panel.positionUtils';
3
3
  export type PanelProps = PropsWithChildren<{
4
4
  arrow?: boolean;
5
5
  flip?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../../../src/common/Panel/Panel.tsx"],"names":[],"mappings":"AAWA,OAAO,EAEL,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,cAAc,EAIf,MAAM,OAAO,CAAC;AAEf,OAAO,EAAY,KAAK,iBAAiB,EAAuB,MAAM,IAAI,CAAC;AAwB3E,MAAM,MAAM,UAAU,GAAG,iBAAiB,CAAC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,KAAK,IAAI,CAAC;IAClD,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC,GACA,cAAc,CAAC,cAAc,CAAC,CAAC;AAEjC,QAAA,MAAM,KAAK;YAZD,OAAO;WACR,OAAO;cACJ,OAAO;WACV,OAAO;cACJ,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,KAAK,IAAI;eACtC,iBAAiB;eACjB,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC;kBACtB,OAAO;qBACJ,OAAO;;;mFAkGxB,CAAC;AAEH,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../../../src/common/Panel/Panel.tsx"],"names":[],"mappings":"AAUA,OAAO,EAEL,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,cAAc,EAIf,MAAM,OAAO,CAAC;AAMf,OAAO,EACL,KAAK,iBAAiB,EAKvB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,MAAM,UAAU,GAAG,iBAAiB,CAAC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,KAAK,IAAI,CAAC;IAClD,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC,GACA,cAAc,CAAC,cAAc,CAAC,CAAC;AAEjC,QAAA,MAAM,KAAK;YAZD,OAAO;WACR,OAAO;cACJ,OAAO;WACV,OAAO;cACJ,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,KAAK,IAAI;eACtC,iBAAiB;eACjB,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC;kBACtB,OAAO;qBACJ,OAAO;;;mFAoGxB,CAAC;AAEH,eAAe,KAAK,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Placement } from '@floating-ui/react';
2
+ export type FloatingPlacement = 'top' | 'right' | 'bottom' | 'left' | 'top-left' | 'top-right' | 'right-top' | 'right-bottom' | 'bottom-left' | 'bottom-right' | 'left-top' | 'left-bottom';
3
+ export declare const POPOVER_OFFSET = 16;
4
+ export declare const fallbackPlacements: Record<Placement, Placement[]>;
5
+ export declare const positionToPlacement: (position: FloatingPlacement) => Placement;
6
+ export declare const mirrorPositionForRtl: (position: FloatingPlacement) => FloatingPlacement;
7
+ //# sourceMappingURL=Panel.positionUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Panel.positionUtils.d.ts","sourceRoot":"","sources":["../../../../src/common/Panel/Panel.positionUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GACzB,KAAK,GACL,OAAO,GACP,QAAQ,GACR,MAAM,GACN,UAAU,GACV,WAAW,GACX,WAAW,GACX,cAAc,GACd,aAAa,GACb,cAAc,GACd,UAAU,GACV,aAAa,CAAC;AAElB,eAAO,MAAM,cAAc,KAAK,CAAC;AAKjC,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,CAa7D,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,UAAU,iBAAiB,KAAG,SAqBjE,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,UAAU,iBAAiB,KAAG,iBAmBlE,CAAC"}
@@ -1,4 +1,3 @@
1
- import type { Placement } from '@floating-ui/react';
2
1
  export declare enum Position {
3
2
  BOTTOM = "bottom",
4
3
  BOTTOM_LEFT = "bottom-left",
@@ -19,16 +18,4 @@ export type PositionTop = 'top';
19
18
  export type PositionRight = 'right';
20
19
  export type PositionBottom = 'bottom';
21
20
  export type PositionLeft = 'left';
22
- export type PositionTopLeft = 'top-left';
23
- export type PositionTopRight = 'top-right';
24
- export type PositionBottomLeft = 'bottom-left';
25
- export type PositionBottomRight = 'bottom-right';
26
- export type PositionLeftTop = 'left-top';
27
- export type PositionLeftBottom = 'left-bottom';
28
- export type PositionRightTop = 'right-top';
29
- export type PositionRightBottom = 'right-bottom';
30
- /** Neptune position values that can be converted to floating-ui Placement */
31
- export type FloatingPlacement = PositionTop | PositionRight | PositionBottom | PositionLeft | PositionTopLeft | PositionTopRight | PositionRightTop | PositionRightBottom | PositionBottomLeft | PositionBottomRight | PositionLeftTop | PositionLeftBottom;
32
- /** Maps Neptune position values to floating-ui Placement */
33
- export declare const positionToPlacement: (position: FloatingPlacement) => Placement;
34
21
  //# sourceMappingURL=position.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../../../../src/common/PropsValues/position.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,oBAAY,QAAQ;IAClB,MAAM,WAAW;IACjB,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,WAAW,gBAAgB;IAC3B,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,YAAY,iBAAiB;IAC7B,SAAS,cAAc;IACvB,GAAG,QAAQ;IACX,QAAQ,aAAa;IACrB,SAAS,cAAc;CACxB;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;AACtC,MAAM,MAAM,WAAW,GAAG,KAAK,CAAC;AAChC,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC;AACpC,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;AACtC,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC;AACzC,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAC3C,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAC/C,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC;AACjD,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC;AACzC,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAC/C,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAC3C,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAEjD,6EAA6E;AAC7E,MAAM,MAAM,iBAAiB,GACzB,WAAW,GACX,aAAa,GACb,cAAc,GACd,YAAY,GACZ,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,GAClB,mBAAmB,GACnB,eAAe,GACf,kBAAkB,CAAC;AAEvB,4DAA4D;AAC5D,eAAO,MAAM,mBAAmB,GAAI,UAAU,iBAAiB,KAAG,SAqBjE,CAAC"}
1
+ {"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../../../../src/common/PropsValues/position.ts"],"names":[],"mappings":"AAAA,oBAAY,QAAQ;IAClB,MAAM,WAAW;IACjB,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,WAAW,gBAAgB;IAC3B,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,YAAY,iBAAiB;IAC7B,SAAS,cAAc;IACvB,GAAG,QAAQ;IACX,QAAQ,aAAa;IACrB,SAAS,cAAc;CACxB;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;AACtC,MAAM,MAAM,WAAW,GAAG,KAAK,CAAC;AAChC,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC;AACpC,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;AACtC,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC"}
@@ -4,7 +4,7 @@ declare const ResponsivePanel: import("react").ForwardRefExoticComponent<{
4
4
  altAxis?: boolean;
5
5
  open?: boolean;
6
6
  onClose?: (event: Event | import("react").SyntheticEvent) => void;
7
- position?: import("..").FloatingPlacement;
7
+ position?: import("../Panel/Panel.positionUtils").FloatingPlacement;
8
8
  anchorRef: import("react").RefObject<Element | null>;
9
9
  anchorWidth?: boolean;
10
10
  considerHeight?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transferwise/components",
3
- "version": "0.0.0-experimental-af01b75",
3
+ "version": "0.0.0-experimental-0657ea4",
4
4
  "description": "Neptune React components",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -91,7 +91,7 @@
91
91
  "storybook": "^10.5.4",
92
92
  "storybook-addon-tag-badges": "^3.1.0",
93
93
  "storybook-addon-test-codegen": "^3.0.4",
94
- "@transferwise/less-config": "0.0.0-experimental-af01b75",
94
+ "@transferwise/less-config": "3.2.0",
95
95
  "@wise/components-theming": "1.10.3",
96
96
  "@wise/wds-configs": "0.0.0"
97
97
  },
@@ -1,12 +1,17 @@
1
- import { ChevronLeft } from '@transferwise/icons';
1
+ import { ChevronLeft, ChevronRight } from '@transferwise/icons';
2
2
  import { clsx } from 'clsx';
3
3
  import { motion } from 'motion/react';
4
4
 
5
+ import { useDirection } from '../../common/hooks';
6
+
5
7
  interface Props {
6
8
  shouldShow: boolean;
7
9
  }
8
10
 
9
11
  export const Chevron = ({ shouldShow = true }: Props) => {
12
+ const { isRTL } = useDirection();
13
+ const Icon = isRTL ? ChevronRight : ChevronLeft;
14
+
10
15
  return (
11
16
  <div
12
17
  className={clsx(
@@ -17,7 +22,7 @@ export const Chevron = ({ shouldShow = true }: Props) => {
17
22
  >
18
23
  <motion.div
19
24
  animate={{
20
- x: [12, 0, 0, -12],
25
+ x: isRTL ? [-12, 0, 0, 12] : [12, 0, 0, -12],
21
26
  opacity: [0, 1, 1, 0],
22
27
  }}
23
28
  transition={{
@@ -28,7 +33,7 @@ export const Chevron = ({ shouldShow = true }: Props) => {
28
33
  repeatType: 'loop',
29
34
  }}
30
35
  >
31
- <ChevronLeft />
36
+ <Icon />
32
37
  </motion.div>
33
38
  </div>
34
39
  );
@@ -39,27 +39,35 @@
39
39
  .np-panel[data-popper-placement^="top"] > .np-panel__content {
40
40
  transform: translateY(10px) scale(0.95);
41
41
  }
42
- .np-panel[data-popper-placement^="top"] > .np-panel__content .np-panel__arrow {
42
+ .np-panel[data-popper-placement^="top"] .np-panel__arrow {
43
43
  inset-block-end: -6px;
44
44
  }
45
45
  .np-panel[data-popper-placement^="right"] > .np-panel__content {
46
46
  transform: translateX(-10px) scale(0.95);
47
47
  }
48
- .np-panel[data-popper-placement^="right"] > .np-panel__content .np-panel__arrow {
48
+ .np-panel[data-popper-placement^="right"] .np-panel__arrow {
49
49
  inset-inline-start: -6px;
50
50
  }
51
+ [dir="rtl"] .np-panel[data-popper-placement^="right"] .np-panel__arrow {
52
+ inset-inline-start: unset;
53
+ inset-inline-end: -6px;
54
+ }
51
55
  .np-panel[data-popper-placement^="bottom"] > .np-panel__content {
52
56
  transform: translateY(-10px) scale(0.95);
53
57
  }
54
- .np-panel[data-popper-placement^="bottom"] > .np-panel__content .np-panel__arrow {
58
+ .np-panel[data-popper-placement^="bottom"] .np-panel__arrow {
55
59
  inset-block-start: -6px;
56
60
  }
57
61
  .np-panel[data-popper-placement^="left"] > .np-panel__content {
58
62
  transform: translateX(10px) scale(0.95);
59
63
  }
60
- .np-panel[data-popper-placement^="left"] > .np-panel__content .np-panel__arrow {
64
+ .np-panel[data-popper-placement^="left"] .np-panel__arrow {
61
65
  inset-inline-end: -6px;
62
66
  }
67
+ [dir="rtl"] .np-panel[data-popper-placement^="left"] .np-panel__arrow {
68
+ inset-inline-end: unset;
69
+ inset-inline-start: -6px;
70
+ }
63
71
  .np-theme-personal .np-panel__content {
64
72
  border-radius: 16px;
65
73
  border-radius: var(--radius-medium);
@@ -11,7 +11,7 @@
11
11
  opacity 0.2s cubic-bezier(0.6, 0.2, 0.1, 1),
12
12
  transform 0.2s cubic-bezier(0.6, 0.2, 0.1, 1),
13
13
  visibility 0s linear 0.2s;
14
-
14
+
15
15
  .np-theme-personal & {
16
16
  border-radius: var(--radius-small);
17
17
  }
@@ -45,35 +45,53 @@
45
45
  background: var(--color-background-elevated);
46
46
  }
47
47
 
48
- &[data-popper-placement^="top"] > &__content {
49
- transform: translateY(10px) scale(0.95);
48
+ &[data-popper-placement^="top"] {
49
+ > .np-panel__content {
50
+ transform: translateY(10px) scale(0.95);
51
+ }
50
52
 
51
53
  .np-panel__arrow {
52
54
  bottom: -6px;
53
55
  }
54
56
  }
55
57
 
56
- &[data-popper-placement^="right"] > &__content {
57
- transform: translateX(-10px) scale(0.95);
58
+ &[data-popper-placement^="right"] {
59
+ > .np-panel__content {
60
+ transform: translateX(-10px) scale(0.95);
61
+ }
58
62
 
59
63
  .np-panel__arrow {
60
64
  left: -6px;
65
+
66
+ [dir="rtl"] & {
67
+ left: unset;
68
+ right: -6px;
69
+ }
61
70
  }
62
71
  }
63
72
 
64
- &[data-popper-placement^="bottom"] > &__content {
65
- transform: translateY(-10px) scale(0.95);
73
+ &[data-popper-placement^="bottom"] {
74
+ > .np-panel__content {
75
+ transform: translateY(-10px) scale(0.95);
76
+ }
66
77
 
67
78
  .np-panel__arrow {
68
79
  top: -6px;
69
80
  }
70
81
  }
71
82
 
72
- &[data-popper-placement^="left"] > &__content {
73
- transform: translateX(10px) scale(0.95);
83
+ &[data-popper-placement^="left"] {
84
+ > .np-panel__content {
85
+ transform: translateX(10px) scale(0.95);
86
+ }
74
87
 
75
88
  .np-panel__arrow {
76
89
  right: -6px;
90
+
91
+ [dir="rtl"] & {
92
+ right: unset;
93
+ left: -6px;
94
+ }
77
95
  }
78
96
  }
79
97
  }
@@ -0,0 +1,79 @@
1
+ import type { Placement } from '@floating-ui/react';
2
+
3
+ export type FloatingPlacement =
4
+ | 'top'
5
+ | 'right'
6
+ | 'bottom'
7
+ | 'left'
8
+ | 'top-left'
9
+ | 'top-right'
10
+ | 'right-top'
11
+ | 'right-bottom'
12
+ | 'bottom-left'
13
+ | 'bottom-right'
14
+ | 'left-top'
15
+ | 'left-bottom';
16
+
17
+ export const POPOVER_OFFSET = 16;
18
+
19
+ // By default the flip positioning explores only the opposite alternative. So if left is passed and there's no enough space
20
+ // the right one gets chosen. If there's no space on both sides popover goes back to the initially chosen one left.
21
+ // This mapping forces popover to try the four available positions before going back to the initial chosen one.
22
+ export const fallbackPlacements: Record<Placement, Placement[]> = {
23
+ top: ['bottom', 'right', 'left'],
24
+ bottom: ['top', 'right', 'left'],
25
+ left: ['right', 'top', 'bottom'],
26
+ right: ['left', 'top', 'bottom'],
27
+ 'top-start': ['bottom-start', 'top-end', 'bottom-end'],
28
+ 'top-end': ['bottom-end', 'top-start', 'bottom-start'],
29
+ 'bottom-start': ['top-start', 'bottom-end', 'top-end'],
30
+ 'bottom-end': ['top-end', 'bottom-start', 'top-start'],
31
+ 'left-start': ['right-start', 'left-end', 'right-end'],
32
+ 'left-end': ['right-end', 'left-start', 'right-start'],
33
+ 'right-start': ['left-start', 'right-end', 'left-end'],
34
+ 'right-end': ['left-end', 'right-start', 'left-start'],
35
+ };
36
+
37
+ export const positionToPlacement = (position: FloatingPlacement): Placement => {
38
+ switch (position) {
39
+ case 'top-left':
40
+ return 'top-start';
41
+ case 'top-right':
42
+ return 'top-end';
43
+ case 'bottom-left':
44
+ return 'bottom-start';
45
+ case 'bottom-right':
46
+ return 'bottom-end';
47
+ case 'left-top':
48
+ return 'left-start';
49
+ case 'left-bottom':
50
+ return 'left-end';
51
+ case 'right-top':
52
+ return 'right-start';
53
+ case 'right-bottom':
54
+ return 'right-end';
55
+ default:
56
+ return position;
57
+ }
58
+ };
59
+
60
+ export const mirrorPositionForRtl = (position: FloatingPlacement): FloatingPlacement => {
61
+ switch (position) {
62
+ case 'left':
63
+ return 'right';
64
+ case 'right':
65
+ return 'left';
66
+ case 'left-top':
67
+ return 'right-top';
68
+ case 'left-bottom':
69
+ return 'right-bottom';
70
+ case 'right-top':
71
+ return 'left-top';
72
+ case 'right-bottom':
73
+ return 'left-bottom';
74
+ default:
75
+ // top-left/top-right/bottom-left/bottom-right map to start/end via
76
+ // positionToPlacement, and floating-ui already flips start/end in RTL.
77
+ return position;
78
+ }
79
+ };
@@ -1,6 +1,7 @@
1
1
  import { createRef } from 'react';
2
2
 
3
3
  import { Position } from '..';
4
+ import { DirectionProvider } from '../../Provider/Direction/DirectionProvider';
4
5
  import { render } from '../../test-utils';
5
6
 
6
7
  import Panel from './Panel';
@@ -93,4 +94,43 @@ describe('Panel', () => {
93
94
  expect(getPanel()).toHaveAttribute('data-popper-placement', expectedPlacement);
94
95
  });
95
96
  });
97
+
98
+ describe('RTL position mirroring', () => {
99
+ it.each<[PanelProps['position'], string]>([
100
+ [Position.LEFT, 'right'],
101
+ [Position.RIGHT, 'left'],
102
+ [Position.LEFT_TOP, 'right-start'],
103
+ [Position.LEFT_BOTTOM, 'right-end'],
104
+ [Position.RIGHT_TOP, 'left-start'],
105
+ [Position.RIGHT_BOTTOM, 'left-end'],
106
+ ])('mirrors %s in RTL to floating-ui placement %s', (position, expectedPlacement) => {
107
+ render(
108
+ <DirectionProvider direction="rtl">
109
+ <Panel {...props} position={position} />
110
+ </DirectionProvider>,
111
+ );
112
+
113
+ expect(getPanel()).toHaveAttribute('data-popper-placement', expectedPlacement);
114
+ });
115
+
116
+ it.each<[PanelProps['position'], string]>([
117
+ [Position.TOP, 'top'],
118
+ [Position.BOTTOM, 'bottom'],
119
+ [Position.TOP_LEFT, 'top-start'],
120
+ [Position.TOP_RIGHT, 'top-end'],
121
+ [Position.BOTTOM_LEFT, 'bottom-start'],
122
+ [Position.BOTTOM_RIGHT, 'bottom-end'],
123
+ ])(
124
+ 'does not mirror %s in RTL (floating-ui handles start/end flip)',
125
+ (position, expectedPlacement) => {
126
+ render(
127
+ <DirectionProvider direction="rtl">
128
+ <Panel {...props} position={position} />
129
+ </DirectionProvider>,
130
+ );
131
+
132
+ expect(getPanel()).toHaveAttribute('data-popper-placement', expectedPlacement);
133
+ },
134
+ );
135
+ });
96
136
  });
@@ -3,7 +3,6 @@ import {
3
3
  autoUpdate,
4
4
  flip as flipMiddleware,
5
5
  offset,
6
- type Placement,
7
6
  shift,
8
7
  size as sizeMiddleware,
9
8
  useFloating,
@@ -20,29 +19,17 @@ import {
20
19
  useRef,
21
20
  } from 'react';
22
21
 
23
- import { Position, type FloatingPlacement, positionToPlacement } from '..';
24
- import Dimmer from '../../Dimmer';
25
22
  import { OverlayIdContext } from '../../Provider/overlay/OverlayIdProvider';
26
-
27
- const POPOVER_OFFSET = 16;
28
-
29
- // By default the flip positioning explores only the opposite alternative. So if left is passed and there's no enough space
30
- // the right one gets chosen. If there's no space on both sides popover goes back to the initially chosen one left.
31
- // This mapping forces popover to try the four available positions before going back to the initial chosen one.
32
- const fallbackPlacements: Record<Placement, Placement[]> = {
33
- [Position.TOP]: [Position.BOTTOM, Position.RIGHT, Position.LEFT],
34
- [Position.BOTTOM]: [Position.TOP, Position.RIGHT, Position.LEFT],
35
- [Position.LEFT]: [Position.RIGHT, Position.TOP, Position.BOTTOM],
36
- [Position.RIGHT]: [Position.LEFT, Position.TOP, Position.BOTTOM],
37
- 'top-start': ['bottom-start', 'top-end', 'bottom-end'],
38
- 'top-end': ['bottom-end', 'top-start', 'bottom-start'],
39
- 'bottom-start': ['top-start', 'bottom-end', 'top-end'],
40
- 'bottom-end': ['top-end', 'bottom-start', 'top-start'],
41
- 'left-start': ['right-start', 'left-end', 'right-end'],
42
- 'left-end': ['right-end', 'left-start', 'right-start'],
43
- 'right-start': ['left-start', 'right-end', 'left-end'],
44
- 'right-end': ['left-end', 'right-start', 'left-start'],
45
- };
23
+ import Dimmer from '../../Dimmer';
24
+ import useDirection from '../hooks/useDirection';
25
+ import { Position } from '..';
26
+ import {
27
+ type FloatingPlacement,
28
+ POPOVER_OFFSET,
29
+ fallbackPlacements,
30
+ mirrorPositionForRtl,
31
+ positionToPlacement,
32
+ } from './Panel.positionUtils';
46
33
 
47
34
  export type PanelProps = PropsWithChildren<{
48
35
  arrow?: boolean;
@@ -74,7 +61,9 @@ const Panel = forwardRef<HTMLDivElement, PanelProps>(function Panel(
74
61
  reference,
75
62
  ) {
76
63
  const arrowRef = useRef<HTMLDivElement | null>(null);
77
- const floatingPlacement = positionToPlacement(position);
64
+ const { isRTL } = useDirection();
65
+ const resolvedPosition = isRTL ? mirrorPositionForRtl(position) : position;
66
+ const floatingPlacement = positionToPlacement(resolvedPosition);
78
67
 
79
68
  const middleware = [];
80
69