colibri-ui 0.8.76 → 0.8.78

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 (128) hide show
  1. package/Autocomplete/Autocomplete.d.ts +6 -0
  2. package/Autocomplete/Autocomplete.js +298 -0
  3. package/Autocomplete/Autocomplete.module.css +147 -0
  4. package/Autocomplete/index.d.ts +2 -0
  5. package/Autocomplete/index.js +7 -0
  6. package/Autocomplete/index.props.d.ts +39 -0
  7. package/Autocomplete/package.json +9 -0
  8. package/Button/tokens.d.ts +78 -0
  9. package/Button/tokens.js +84 -0
  10. package/Calendar/Calendar.js +3 -1
  11. package/Input/index.d.ts +1 -1
  12. package/Input/index.js +20 -14
  13. package/Input/index.props.d.ts +4 -1
  14. package/List/List.d.ts +5 -0
  15. package/List/List.js +161 -0
  16. package/List/List.module.css +185 -0
  17. package/List/index.d.ts +2 -0
  18. package/List/index.js +9 -0
  19. package/List/index.props.d.ts +43 -0
  20. package/List/package.json +9 -0
  21. package/Modal/Modal.module.css +14 -7
  22. package/Modal/components/Body/Body.module.css +12 -0
  23. package/Modal/components/Body/index.d.ts +3 -0
  24. package/Modal/components/Body/index.js +27 -0
  25. package/Modal/components/Body/index.props.d.ts +1 -0
  26. package/Modal/components/Close/index.js +5 -2
  27. package/Modal/components/Close/index.props.d.ts +1 -0
  28. package/Modal/components/Footer/Footer.module.css +10 -0
  29. package/Modal/components/Footer/index.d.ts +3 -0
  30. package/Modal/components/Footer/index.js +23 -0
  31. package/Modal/components/Footer/index.props.d.ts +1 -0
  32. package/Modal/components/Header/Header.module.css +32 -0
  33. package/Modal/components/Header/index.d.ts +3 -0
  34. package/Modal/components/Header/index.js +37 -0
  35. package/Modal/components/Header/index.props.d.ts +1 -0
  36. package/Modal/components/Title/index.js +20 -7
  37. package/Modal/components/Title/index.props.d.ts +1 -2
  38. package/Modal/context.d.ts +9 -0
  39. package/Modal/context.js +15 -0
  40. package/Modal/index.d.ts +12 -2
  41. package/Modal/index.js +103 -31
  42. package/Modal/index.props.d.ts +25 -0
  43. package/Modal/useModalStack.d.ts +2 -0
  44. package/Modal/useModalStack.js +20 -0
  45. package/README.md +59 -0
  46. package/Theme/breakpoints.d.ts +20 -16
  47. package/Theme/breakpoints.js +21 -32
  48. package/Theme/colors/index.d.ts +4 -0
  49. package/Theme/colors/theme_buenos_aires.d.ts +4 -0
  50. package/Theme/colors/theme_buenos_aires.js +2 -0
  51. package/Theme/colors/theme_jaipur.d.ts +4 -0
  52. package/Theme/colors/theme_jaipur.js +2 -0
  53. package/Theme/index.d.ts +300 -152
  54. package/Theme/index.js +6 -2
  55. package/Theme/themes/buenos_aires.d.ts +73 -76
  56. package/Theme/themes/buenos_aires.js +73 -76
  57. package/Theme/themes/jaipur.d.ts +73 -76
  58. package/Theme/themes/jaipur.js +73 -76
  59. package/esm/Autocomplete/Autocomplete.d.ts +6 -0
  60. package/esm/Autocomplete/Autocomplete.js +288 -0
  61. package/esm/Autocomplete/Autocomplete.module.css +147 -0
  62. package/esm/Autocomplete/index.d.ts +2 -0
  63. package/esm/Autocomplete/index.props.d.ts +39 -0
  64. package/esm/Button/tokens.d.ts +78 -0
  65. package/esm/Button/tokens.js +82 -0
  66. package/esm/Calendar/Calendar.js +3 -1
  67. package/esm/Input/index.d.ts +1 -1
  68. package/esm/Input/index.js +16 -10
  69. package/esm/Input/index.props.d.ts +4 -1
  70. package/esm/List/List.d.ts +5 -0
  71. package/esm/List/List.js +150 -0
  72. package/esm/List/List.module.css +185 -0
  73. package/esm/List/index.d.ts +2 -0
  74. package/esm/List/index.props.d.ts +43 -0
  75. package/esm/Modal/Modal.module.css +14 -7
  76. package/esm/Modal/components/Body/Body.module.css +12 -0
  77. package/esm/Modal/components/Body/index.d.ts +3 -0
  78. package/esm/Modal/components/Body/index.js +18 -0
  79. package/esm/Modal/components/Body/index.props.d.ts +1 -0
  80. package/esm/Modal/components/Close/index.js +4 -2
  81. package/esm/Modal/components/Close/index.props.d.ts +1 -0
  82. package/esm/Modal/components/Footer/Footer.module.css +10 -0
  83. package/esm/Modal/components/Footer/index.d.ts +3 -0
  84. package/esm/Modal/components/Footer/index.js +15 -0
  85. package/esm/Modal/components/Footer/index.props.d.ts +1 -0
  86. package/esm/Modal/components/Header/Header.module.css +32 -0
  87. package/esm/Modal/components/Header/index.d.ts +3 -0
  88. package/esm/Modal/components/Header/index.js +28 -0
  89. package/esm/Modal/components/Header/index.props.d.ts +1 -0
  90. package/esm/Modal/components/Title/index.js +20 -8
  91. package/esm/Modal/components/Title/index.props.d.ts +1 -2
  92. package/esm/Modal/context.d.ts +9 -0
  93. package/esm/Modal/context.js +12 -0
  94. package/esm/Modal/index.d.ts +12 -2
  95. package/esm/Modal/index.js +92 -25
  96. package/esm/Modal/index.props.d.ts +25 -0
  97. package/esm/Modal/useModalStack.d.ts +2 -0
  98. package/esm/Modal/useModalStack.js +18 -0
  99. package/esm/Theme/breakpoints.d.ts +20 -16
  100. package/esm/Theme/breakpoints.js +20 -26
  101. package/esm/Theme/colors/index.d.ts +4 -0
  102. package/esm/Theme/colors/theme_buenos_aires.d.ts +4 -0
  103. package/esm/Theme/colors/theme_buenos_aires.js +2 -0
  104. package/esm/Theme/colors/theme_jaipur.d.ts +4 -0
  105. package/esm/Theme/colors/theme_jaipur.js +2 -0
  106. package/esm/Theme/index.d.ts +300 -152
  107. package/esm/Theme/index.js +3 -2
  108. package/esm/Theme/themes/buenos_aires.d.ts +73 -76
  109. package/esm/Theme/themes/buenos_aires.js +73 -76
  110. package/esm/Theme/themes/jaipur.d.ts +73 -76
  111. package/esm/Theme/themes/jaipur.js +73 -76
  112. package/esm/hooks/useMediaSizes/index.d.ts +2 -2
  113. package/esm/hooks/useMediaSizes/index.js +2 -2
  114. package/esm/hooks/useTrapFocus/index.d.ts +1 -1
  115. package/esm/hooks/useTrapFocus/index.js +3 -2
  116. package/esm/index.d.ts +8 -3
  117. package/esm/index.js +7 -0
  118. package/esm/theme_ba_variables.css +149 -76
  119. package/esm/theme_jaipur_variables.css +149 -76
  120. package/hooks/useMediaSizes/index.d.ts +2 -2
  121. package/hooks/useMediaSizes/index.js +1 -1
  122. package/hooks/useTrapFocus/index.d.ts +1 -1
  123. package/hooks/useTrapFocus/index.js +3 -2
  124. package/index.d.ts +8 -3
  125. package/index.js +54 -35
  126. package/package.json +1 -1
  127. package/theme_ba_variables.css +149 -76
  128. package/theme_jaipur_variables.css +149 -76
@@ -6,19 +6,17 @@
6
6
  width: 100%;
7
7
  z-index: 1000;
8
8
  }
9
-
10
- .title-wrapper {
11
- align-items: center;
12
- border-bottom: var(--border-width-hairline) solid var(--component-modal-border);
13
- display: flex;
14
- justify-content: space-between;
15
- padding: var(--space-4) var(--space-5);
9
+ .root_contained {
10
+ left: 0;
11
+ position: absolute;
12
+ z-index: 2;
16
13
  }
17
14
 
18
15
  .close-wrapper {
19
16
  align-items: center;
20
17
  box-sizing: border-box;
21
18
  display: flex;
19
+ flex: none;
22
20
  justify-content: flex-end;
23
21
  min-height: var(--component-modal-close-min-height);
24
22
  padding: 0 var(--space-5);
@@ -32,6 +30,9 @@
32
30
  top: 0;
33
31
  width: 100%;
34
32
  }
33
+ .root_contained .modal-overlay {
34
+ position: absolute;
35
+ }
35
36
 
36
37
  .modal-wrapper {
37
38
  background-color: var(--component-modal-bg);
@@ -53,4 +54,10 @@
53
54
  max-height: calc(100vh - var(--component-modal-viewport-offset));
54
55
  max-width: calc(100vw - var(--component-modal-viewport-offset));
55
56
  min-width: var(--component-modal-desktop-min-width);
57
+ }
58
+
59
+ .modal-wrapper_contained.modal-wrapper_desktop {
60
+ max-height: calc(100% - var(--space-8));
61
+ max-width: calc(100% - var(--space-8));
62
+ min-width: 0;
56
63
  }
@@ -0,0 +1,12 @@
1
+ .root {
2
+ box-sizing: border-box;
3
+ display: flex;
4
+ flex: 1 1 auto;
5
+ flex-direction: column;
6
+ min-height: 0;
7
+ overflow-y: auto;
8
+ padding: var(--space-4) var(--space-5);
9
+ }
10
+ .root_bleed {
11
+ padding: 0;
12
+ }
@@ -0,0 +1,3 @@
1
+ import type { FC } from "react";
2
+ import type { BodyProps } from "./index.props";
3
+ export declare const Body: FC<BodyProps>;
@@ -0,0 +1,18 @@
1
+ import _defineProperty from '@babel/runtime/helpers/defineProperty';
2
+ import { __rest } from 'tslib';
3
+ import React from 'react';
4
+ import clsx from 'clsx';
5
+ import styles from './Body.module.css';
6
+
7
+ var Body = function Body(_a) {
8
+ var children = _a.children,
9
+ className = _a.className,
10
+ _a$bleed = _a.bleed,
11
+ bleed = _a$bleed === void 0 ? false : _a$bleed,
12
+ props = __rest(_a, ["children", "className", "bleed"]);
13
+ return /*#__PURE__*/React.createElement("div", Object.assign({}, props, {
14
+ className: clsx(styles.root, _defineProperty({}, styles.root_bleed, bleed), className)
15
+ }), children);
16
+ };
17
+
18
+ export { Body };
@@ -0,0 +1 @@
1
+ export type { ModalBodyProps as BodyProps } from "../../index.props";
@@ -1,16 +1,18 @@
1
1
  import React from 'react';
2
+ import clsx from 'clsx';
2
3
  import 'tslib';
3
4
  import { Close as Close$1 } from '../../../Icons/Close.js';
4
5
  import styles from './Close.module.css';
5
6
 
6
7
  var Close = function Close(_ref) {
7
- var onClick = _ref.onClick,
8
+ var className = _ref.className,
9
+ onClick = _ref.onClick,
8
10
  ariaLabel = _ref["aria-label"];
9
11
  return /*#__PURE__*/React.createElement("button", {
10
12
  type: "button",
11
13
  onClick: onClick,
12
14
  "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : "Close",
13
- className: styles["close-button"]
15
+ className: clsx(styles["close-button"], className)
14
16
  }, /*#__PURE__*/React.createElement(Close$1, {
15
17
  width: 18,
16
18
  height: 18
@@ -1,4 +1,5 @@
1
1
  export type CloseButtonProps = {
2
+ className?: string;
2
3
  onClick?: () => void;
3
4
  "aria-label"?: string;
4
5
  };
@@ -0,0 +1,10 @@
1
+ .root {
2
+ align-items: center;
3
+ border-top: var(--border-width-hairline) solid var(--component-modal-border);
4
+ box-sizing: border-box;
5
+ display: flex;
6
+ flex: none;
7
+ gap: var(--space-3);
8
+ justify-content: flex-end;
9
+ padding: var(--space-4) var(--space-5);
10
+ }
@@ -0,0 +1,3 @@
1
+ import type { FC } from "react";
2
+ import type { FooterProps } from "./index.props";
3
+ export declare const Footer: FC<FooterProps>;
@@ -0,0 +1,15 @@
1
+ import { __rest } from 'tslib';
2
+ import React from 'react';
3
+ import clsx from 'clsx';
4
+ import styles from './Footer.module.css';
5
+
6
+ var Footer = function Footer(_a) {
7
+ var children = _a.children,
8
+ className = _a.className,
9
+ props = __rest(_a, ["children", "className"]);
10
+ return /*#__PURE__*/React.createElement("div", Object.assign({}, props, {
11
+ className: clsx(styles.root, className)
12
+ }), children);
13
+ };
14
+
15
+ export { Footer };
@@ -0,0 +1 @@
1
+ export type { ModalFooterProps as FooterProps } from "../../index.props";
@@ -0,0 +1,32 @@
1
+ .root {
2
+ align-items: center;
3
+ border-bottom: var(--border-width-hairline) solid var(--component-modal-border);
4
+ box-sizing: border-box;
5
+ display: flex;
6
+ flex: none;
7
+ gap: var(--space-3);
8
+ padding: var(--space-4) var(--space-5);
9
+ }
10
+ .root_overlay {
11
+ align-items: flex-start;
12
+ background: transparent;
13
+ border-bottom: none;
14
+ left: 0;
15
+ pointer-events: none;
16
+ position: absolute;
17
+ right: 0;
18
+ top: 0;
19
+ z-index: 1;
20
+ }
21
+ .root_overlay > * {
22
+ pointer-events: auto;
23
+ }
24
+
25
+ .close {
26
+ margin-left: auto;
27
+ }
28
+ .root_overlay .close {
29
+ background-color: var(--component-modal-bg);
30
+ border-radius: var(--component-modal-radius);
31
+ box-shadow: var(--shadow-raised);
32
+ }
@@ -0,0 +1,3 @@
1
+ import type { FC } from "react";
2
+ import type { HeaderProps } from "./index.props";
3
+ export declare const Header: FC<HeaderProps>;
@@ -0,0 +1,28 @@
1
+ import _defineProperty from '@babel/runtime/helpers/defineProperty';
2
+ import { __rest } from 'tslib';
3
+ import React from 'react';
4
+ import clsx from 'clsx';
5
+ import { useModalContext } from '../../context.js';
6
+ import { Close } from '../Close/index.js';
7
+ import styles from './Header.module.css';
8
+
9
+ var Header = function Header(_a) {
10
+ var children = _a.children,
11
+ className = _a.className,
12
+ _a$overlay = _a.overlay,
13
+ overlay = _a$overlay === void 0 ? false : _a$overlay,
14
+ _a$closeAriaLabel = _a.closeAriaLabel,
15
+ closeAriaLabel = _a$closeAriaLabel === void 0 ? "Close modal" : _a$closeAriaLabel,
16
+ props = __rest(_a, ["children", "className", "overlay", "closeAriaLabel"]);
17
+ var _useModalContext = useModalContext(),
18
+ onClose = _useModalContext.onClose;
19
+ return /*#__PURE__*/React.createElement("div", Object.assign({}, props, {
20
+ className: clsx(styles.root, _defineProperty({}, styles.root_overlay, overlay), className)
21
+ }), children, /*#__PURE__*/React.createElement(Close, {
22
+ className: styles.close,
23
+ onClick: onClose,
24
+ "aria-label": closeAriaLabel
25
+ }));
26
+ };
27
+
28
+ export { Header };
@@ -0,0 +1 @@
1
+ export type { ModalHeaderProps as HeaderProps } from "../../index.props";
@@ -1,16 +1,28 @@
1
- import React from 'react';
1
+ import { __rest } from 'tslib';
2
+ import React, { useEffect } from 'react';
3
+ import clsx from 'clsx';
2
4
  import { Typography } from '../../../Typography/index.js';
5
+ import { useModalContext } from '../../context.js';
3
6
  import styles from './Title.module.css';
4
7
 
5
- var Title = function Title(_ref) {
6
- var children = _ref.children;
8
+ var Title = function Title(_a) {
9
+ var children = _a.children,
10
+ className = _a.className,
11
+ props = __rest(_a, ["children", "className"]);
12
+ var _useModalContext = useModalContext(),
13
+ titleId = _useModalContext.titleId,
14
+ registerTitle = _useModalContext.registerTitle;
15
+ useEffect(function () {
16
+ return registerTitle();
17
+ }, [registerTitle]);
7
18
  return /*#__PURE__*/React.createElement(Typography, {
8
- tag: "h3",
9
- size: "h3",
19
+ tag: "h4",
20
+ size: "h4",
10
21
  className: styles.title
11
- }, /*#__PURE__*/React.createElement("div", {
12
- className: styles.wrapper
13
- }, children));
22
+ }, /*#__PURE__*/React.createElement("div", Object.assign({}, props, {
23
+ id: titleId,
24
+ className: clsx(styles.wrapper, className)
25
+ }), children));
14
26
  };
15
27
 
16
28
  export { Title };
@@ -1,2 +1 @@
1
- import type { PropsWithChildren } from "react";
2
- export type TitleProps = PropsWithChildren;
1
+ export type { ModalTitleProps as TitleProps } from "../../index.props";
@@ -0,0 +1,9 @@
1
+ type ModalContextValue = {
2
+ onClose: () => void;
3
+ titleId: string;
4
+ registerTitle: () => () => void;
5
+ container: HTMLDivElement | null;
6
+ };
7
+ export declare const ModalContext: import("react").Context<ModalContextValue | null>;
8
+ export declare const useModalContext: () => ModalContextValue;
9
+ export {};
@@ -0,0 +1,12 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ var ModalContext = /*#__PURE__*/createContext(null);
4
+ var useModalContext = function useModalContext() {
5
+ var context = useContext(ModalContext);
6
+ if (!context) {
7
+ throw new Error("Modal compound components must be used inside <Modal>");
8
+ }
9
+ return context;
10
+ };
11
+
12
+ export { ModalContext, useModalContext };
@@ -1,3 +1,13 @@
1
- import type { FC, PropsWithChildren } from "react";
1
+ import React from "react";
2
+ import { Body } from "./components/Body";
3
+ import { Footer } from "./components/Footer";
4
+ import { Header } from "./components/Header";
5
+ import { Title } from "./components/Title";
2
6
  import type { ModalProps } from "./index.props";
3
- export declare const Modal: FC<PropsWithChildren<ModalProps>>;
7
+ export declare const Modal: React.FC<React.PropsWithChildren<ModalProps>> & {
8
+ Header: React.FC<import("./index.props").ModalHeaderProps>;
9
+ Title: React.FC<import("./index.props").ModalTitleProps>;
10
+ Body: React.FC<import("./index.props").ModalBodyProps>;
11
+ Footer: React.FC<import("./index.props").ModalFooterProps>;
12
+ };
13
+ export { Header as ModalHeader, Title as ModalTitle, Body as ModalBody, Footer as ModalFooter, };
@@ -1,29 +1,81 @@
1
1
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
2
- import React, { useRef, useCallback, useEffect } from 'react';
2
+ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
3
+ import React, { useRef, useState, useContext, useId, useCallback, useMemo, useEffect, Children, isValidElement } from 'react';
3
4
  import clsx from 'clsx';
4
5
  import { useScrollLock } from '../hooks/useScrollLock/index.js';
5
6
  import { useTrapFocus } from '../hooks/useTrapFocus/index.js';
6
7
  import { Portal } from '../Portal/index.js';
7
8
  import { useMediaSizes } from '../hooks/useMediaSizes/index.js';
8
- import { Content } from './components/Content/index.js';
9
+ import { Body } from './components/Body/index.js';
9
10
  import { Close } from './components/Close/index.js';
11
+ import { Content } from './components/Content/index.js';
12
+ import { Footer } from './components/Footer/index.js';
13
+ import { Header } from './components/Header/index.js';
10
14
  import { Title } from './components/Title/index.js';
15
+ import { ModalContext } from './context.js';
16
+ import { useModalStack } from './useModalStack.js';
11
17
  import styles from './Modal.module.css';
12
18
 
13
- var Modal = function Modal(_ref) {
19
+ var compoundParts = [Header, Body, Footer];
20
+ var isCompoundPart = function isCompoundPart(child) {
21
+ return /*#__PURE__*/isValidElement(child) && compoundParts.includes(child.type);
22
+ };
23
+ var hasHeader = function hasHeader(children) {
24
+ return Children.toArray(children).some(function (child) {
25
+ return /*#__PURE__*/isValidElement(child) && child.type === Header;
26
+ });
27
+ };
28
+ var ModalRoot = function ModalRoot(_ref) {
14
29
  var children = _ref.children,
15
30
  className = _ref.className,
16
31
  onClose = _ref.onClose,
17
- title = _ref.title;
32
+ title = _ref.title,
33
+ _ref$withinParent = _ref.withinParent,
34
+ withinParent = _ref$withinParent === void 0 ? false : _ref$withinParent;
18
35
  var modalRef = useRef(null);
36
+ var _useState = useState(null),
37
+ _useState2 = _slicedToArray(_useState, 2),
38
+ container = _useState2[0],
39
+ setContainer = _useState2[1];
40
+ var parentModal = useContext(ModalContext);
41
+ var parentContainer = withinParent ? parentModal === null || parentModal === void 0 ? void 0 : parentModal.container : undefined;
42
+ var isContained = Boolean(parentContainer);
19
43
  var isDesktop = useMediaSizes(function (bp) {
20
- return bp.up("md");
44
+ return bp.up("lg");
21
45
  });
46
+ var titleId = useId();
47
+ var _useState3 = useState(0),
48
+ _useState4 = _slicedToArray(_useState3, 2),
49
+ titleCount = _useState4[0],
50
+ setTitleCount = _useState4[1];
51
+ var isTopmost = useModalStack(titleId);
22
52
  useScrollLock();
23
- useTrapFocus(modalRef);
53
+ useTrapFocus(modalRef, isTopmost);
24
54
  var handleClose = useCallback(function () {
25
55
  onClose === null || onClose === void 0 ? void 0 : onClose();
26
56
  }, [onClose]);
57
+ var registerTitle = useCallback(function () {
58
+ setTitleCount(function (count) {
59
+ return count + 1;
60
+ });
61
+ return function () {
62
+ return setTitleCount(function (count) {
63
+ return count - 1;
64
+ });
65
+ };
66
+ }, []);
67
+ var setWrapperRef = useCallback(function (node) {
68
+ modalRef.current = node;
69
+ setContainer(node);
70
+ }, []);
71
+ var contextValue = useMemo(function () {
72
+ return {
73
+ onClose: handleClose,
74
+ titleId: titleId,
75
+ registerTitle: registerTitle,
76
+ container: container
77
+ };
78
+ }, [handleClose, titleId, registerTitle, container]);
27
79
  var handleOverlayClick = useCallback(function (event) {
28
80
  if (event.target === event.currentTarget) {
29
81
  handleClose();
@@ -31,7 +83,7 @@ var Modal = function Modal(_ref) {
31
83
  }, [handleClose]);
32
84
  useEffect(function () {
33
85
  var handleEscape = function handleEscape(event) {
34
- if (event.key === "Escape") {
86
+ if (event.key === "Escape" && isTopmost()) {
35
87
  handleClose();
36
88
  }
37
89
  };
@@ -39,30 +91,45 @@ var Modal = function Modal(_ref) {
39
91
  return function () {
40
92
  return document.removeEventListener("keydown", handleEscape);
41
93
  };
42
- }, [handleClose]);
43
- return /*#__PURE__*/React.createElement(Portal, null, /*#__PURE__*/React.createElement("div", {
44
- className: styles.root,
94
+ }, [handleClose, isTopmost]);
95
+ var isCompound = Children.toArray(children).some(isCompoundPart);
96
+ var standaloneClose = /*#__PURE__*/React.createElement("div", {
97
+ className: styles["close-wrapper"]
98
+ }, /*#__PURE__*/React.createElement(Close, {
99
+ onClick: handleClose,
100
+ "aria-label": "Close modal"
101
+ }));
102
+ var content;
103
+ if (isCompound) {
104
+ content = /*#__PURE__*/React.createElement(React.Fragment, null, !hasHeader(children) && standaloneClose, children);
105
+ } else {
106
+ content = /*#__PURE__*/React.createElement(React.Fragment, null, title ? (/*#__PURE__*/React.createElement(Header, null, /*#__PURE__*/React.createElement(Title, null, title))) : standaloneClose, /*#__PURE__*/React.createElement(Content, null, children));
107
+ }
108
+ // Wait for the parent window node instead of flashing in document.body.
109
+ if (withinParent && parentModal && !parentContainer) return null;
110
+ return /*#__PURE__*/React.createElement(Portal, {
111
+ node: parentContainer
112
+ }, /*#__PURE__*/React.createElement(ModalContext.Provider, {
113
+ value: contextValue
114
+ }, /*#__PURE__*/React.createElement("div", {
115
+ className: clsx(styles.root, _defineProperty({}, styles.root_contained, isContained)),
45
116
  role: "dialog",
46
117
  "aria-modal": "true",
47
- "aria-labelledby": title ? "modal-title" : undefined
118
+ "aria-labelledby": titleCount > 0 ? titleId : undefined
48
119
  }, /*#__PURE__*/React.createElement("div", {
49
120
  className: styles["modal-overlay"],
50
121
  onClick: handleOverlayClick,
51
122
  "aria-hidden": "true"
52
123
  }), /*#__PURE__*/React.createElement("div", {
53
- className: clsx(styles["modal-wrapper"], _defineProperty(_defineProperty({}, styles["modal-wrapper_desktop"], isDesktop), styles["modal-wrapper_mobile"], !isDesktop), className),
54
- ref: modalRef
55
- }, title ? (/*#__PURE__*/React.createElement("div", {
56
- className: styles["title-wrapper"]
57
- }, /*#__PURE__*/React.createElement(Title, null, title), /*#__PURE__*/React.createElement(Close, {
58
- onClick: handleClose,
59
- "aria-label": "Close modal"
60
- }))) : (/*#__PURE__*/React.createElement("div", {
61
- className: styles["close-wrapper"]
62
- }, /*#__PURE__*/React.createElement(Close, {
63
- onClick: handleClose,
64
- "aria-label": "Close modal"
65
- }))), /*#__PURE__*/React.createElement(Content, null, children))));
124
+ className: clsx(styles["modal-wrapper"], _defineProperty(_defineProperty(_defineProperty({}, styles["modal-wrapper_desktop"], isDesktop), styles["modal-wrapper_mobile"], !isDesktop), styles["modal-wrapper_contained"], isContained), className),
125
+ ref: setWrapperRef
126
+ }, content))));
66
127
  };
128
+ var Modal = Object.assign(ModalRoot, {
129
+ Header: Header,
130
+ Title: Title,
131
+ Body: Body,
132
+ Footer: Footer
133
+ });
67
134
 
68
- export { Modal };
135
+ export { Modal, Body as ModalBody, Footer as ModalFooter, Header as ModalHeader, Title as ModalTitle };
@@ -1,5 +1,30 @@
1
+ import type { HTMLAttributes } from "react";
1
2
  export type ModalProps = {
2
3
  className?: string;
3
4
  onClose?: () => void;
5
+ /**
6
+ * Legacy shorthand. Used only when children do not contain
7
+ * `Modal.Header`, `Modal.Body` or `Modal.Footer`.
8
+ */
4
9
  title?: string;
10
+ /**
11
+ * Renders the modal inside the parent modal window: the overlay covers
12
+ * only the parent, not the whole viewport. Works when the modal is
13
+ * rendered inside another `Modal`.
14
+ */
15
+ withinParent?: boolean;
5
16
  };
17
+ export interface ModalHeaderProps extends HTMLAttributes<HTMLDivElement> {
18
+ /**
19
+ * Places the header above the body instead of before it.
20
+ * The header becomes transparent and the body takes the whole modal.
21
+ */
22
+ overlay?: boolean;
23
+ closeAriaLabel?: string;
24
+ }
25
+ export type ModalTitleProps = HTMLAttributes<HTMLDivElement>;
26
+ export interface ModalBodyProps extends HTMLAttributes<HTMLDivElement> {
27
+ /** Removes the body padding so content goes edge to edge. */
28
+ bleed?: boolean;
29
+ }
30
+ export type ModalFooterProps = HTMLAttributes<HTMLDivElement>;
@@ -0,0 +1,2 @@
1
+ /** Tracks open modals so only the topmost one reacts to Escape and Tab. */
2
+ export declare const useModalStack: (id: string) => () => boolean;
@@ -0,0 +1,18 @@
1
+ import { useEffect, useCallback } from 'react';
2
+
3
+ var stack = [];
4
+ /** Tracks open modals so only the topmost one reacts to Escape and Tab. */
5
+ var useModalStack = function useModalStack(id) {
6
+ useEffect(function () {
7
+ stack.push(id);
8
+ return function () {
9
+ var index = stack.lastIndexOf(id);
10
+ if (index !== -1) stack.splice(index, 1);
11
+ };
12
+ }, [id]);
13
+ return useCallback(function () {
14
+ return stack[stack.length - 1] === id;
15
+ }, [id]);
16
+ };
17
+
18
+ export { useModalStack };
@@ -1,18 +1,22 @@
1
- export type Breakpoints = {
2
- hd: number;
3
- xl: number;
4
- lg: number;
5
- md: number;
6
- sm: number;
7
- xs: number;
1
+ /**
2
+ * Breakpoints shared with the apps that use the kit.
3
+ * The values match the Tailwind CSS defaults on purpose; Tailwind is not a dependency.
4
+ */
5
+ export declare const BREAKPOINTS: {
6
+ readonly sm: "40rem";
7
+ readonly md: "48rem";
8
+ readonly lg: "64rem";
9
+ readonly xl: "80rem";
10
+ readonly "2xl": "96rem";
8
11
  };
9
- export type BreakpointName = keyof Breakpoints;
10
- export type BreakpointsTheme = {
11
- values: Breakpoints;
12
- up: (breakpoint: BreakpointName, isMedial?: boolean) => string;
13
- under: (breakpoint: BreakpointName, isMedial?: boolean) => string;
14
- between: ([from, to]: [BreakpointName, BreakpointName], isMedial?: boolean) => string;
12
+ export type BreakpointName = keyof typeof BREAKPOINTS;
13
+ export type Media = {
14
+ /** `(width >= <name>)` */
15
+ up: (name: BreakpointName) => string;
16
+ /** `(width < <name>)` */
17
+ down: (name: BreakpointName) => string;
18
+ /** `(<from> <= width < <to>)` */
19
+ between: (from: BreakpointName, to: BreakpointName) => string;
15
20
  };
16
- export type BreakpointMap<T = number> = Map<BreakpointName, T>;
17
- declare const Breakpoints: BreakpointsTheme;
18
- export default Breakpoints;
21
+ /** Bare media queries, usable in `window.matchMedia`. Prefix with `@media ` in CSS-in-JS. */
22
+ export declare const media: Media;
@@ -1,31 +1,25 @@
1
- import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
2
-
3
- var Breakpoints = {
4
- values: {
5
- hd: 2560,
6
- xl: 1920,
7
- lg: 1450,
8
- md: 1075,
9
- sm: 680,
10
- xs: 320
11
- },
12
- up: function up(breakpoint) {
13
- var isMedia = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
14
- return "".concat(isMedia ? "@media " : "", "(min-width: ").concat(this.values[breakpoint], "px)");
1
+ /**
2
+ * Breakpoints shared with the apps that use the kit.
3
+ * The values match the Tailwind CSS defaults on purpose; Tailwind is not a dependency.
4
+ */
5
+ var BREAKPOINTS = {
6
+ sm: "40rem",
7
+ md: "48rem",
8
+ lg: "64rem",
9
+ xl: "80rem",
10
+ "2xl": "96rem"
11
+ };
12
+ /** Bare media queries, usable in `window.matchMedia`. Prefix with `@media ` in CSS-in-JS. */
13
+ var media = {
14
+ up: function up(name) {
15
+ return "(width >= ".concat(BREAKPOINTS[name], ")");
15
16
  },
16
- under: function under(breakpoint) {
17
- var isMedia = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
18
- return "".concat(isMedia ? "@media " : "", "(max-width: ").concat(this.values[breakpoint] - 1, "px)");
17
+ down: function down(name) {
18
+ return "(width < ".concat(BREAKPOINTS[name], ")");
19
19
  },
20
- between: function between(_ref) {
21
- var _ref2 = _slicedToArray(_ref, 2),
22
- min = _ref2[0],
23
- max = _ref2[1];
24
- var isMedia = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
25
- var from = this.values[min];
26
- var to = this.values[max] - 1;
27
- return "".concat(isMedia ? "@media " : "", "(min-width: ").concat(from, "px) and (max-width: ").concat(to, "px)");
20
+ between: function between(from, to) {
21
+ return "(".concat(BREAKPOINTS[from], " <= width < ").concat(BREAKPOINTS[to], ")");
28
22
  }
29
23
  };
30
24
 
31
- export { Breakpoints as default };
25
+ export { BREAKPOINTS, media };
@@ -24,10 +24,12 @@ declare const _default: {
24
24
  PROMO_NEON: string;
25
25
  STATUS_JP_SUCCESS: string;
26
26
  STATUS_JP_SUCCESS_BG: string;
27
+ STATUS_JP_SUCCESS_BG_HOVER: string;
27
28
  STATUS_JP_WARNING: string;
28
29
  STATUS_JP_WARNING_BG: string;
29
30
  STATUS_JP_ERROR_ACCENT: string;
30
31
  STATUS_JP_ERROR: string;
32
+ STATUS_JP_ERROR_HOVER: string;
31
33
  STATUS_JP_ERROR_BG: string;
32
34
  STATUS_JP_INFO: string;
33
35
  STATUS_JP_INFO_BG: string;
@@ -127,10 +129,12 @@ declare const _default: {
127
129
  PRIMARY_BA_5: string;
128
130
  STATUS_BA_SUCCESS: string;
129
131
  STATUS_BA_SUCCESS_BG: string;
132
+ STATUS_BA_SUCCESS_BG_HOVER: string;
130
133
  STATUS_BA_WARNING: string;
131
134
  STATUS_BA_WARNING_BG: string;
132
135
  STATUS_BA_ERROR_ACCENT: string;
133
136
  STATUS_BA_ERROR: string;
137
+ STATUS_BA_ERROR_HOVER: string;
134
138
  STATUS_BA_ERROR_BG: string;
135
139
  STATUS_BA_INFO: string;
136
140
  STATUS_BA_INFO_BG: string;