@blockle/blocks-react 3.0.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +138 -0
  2. package/dist/components/feedback/Alert/Alert.d.ts +6 -0
  3. package/dist/components/feedback/Alert/Alert.d.ts.map +1 -1
  4. package/dist/components/feedback/Alert/Alert.js +2 -0
  5. package/dist/components/feedback/Toast/Toast.css.d.ts +10 -1
  6. package/dist/components/feedback/Toast/Toast.css.d.ts.map +1 -1
  7. package/dist/components/feedback/Toast/Toast.css.js +37 -10
  8. package/dist/components/feedback/Toast/ToastProvider.d.ts +9 -1
  9. package/dist/components/feedback/Toast/ToastProvider.d.ts.map +1 -1
  10. package/dist/components/feedback/Toast/ToastProvider.js +47 -24
  11. package/dist/components/form/Checkbox/Checkbox.d.ts +0 -1
  12. package/dist/components/form/Checkbox/Checkbox.d.ts.map +1 -1
  13. package/dist/components/form/Checkbox/Checkbox.js +0 -2
  14. package/dist/components/form/Checkbox/checkbox.css.d.ts.map +1 -1
  15. package/dist/components/form/Checkbox/checkbox.css.js +1 -0
  16. package/dist/components/form/Radio/Radio.d.ts +0 -1
  17. package/dist/components/form/Radio/Radio.d.ts.map +1 -1
  18. package/dist/components/form/Radio/Radio.js +1 -11
  19. package/dist/components/form/Radio/radio.css.d.ts.map +1 -1
  20. package/dist/components/form/Radio/radio.css.js +1 -0
  21. package/dist/components/form/Select/Select.d.ts +2 -1
  22. package/dist/components/form/Select/Select.d.ts.map +1 -1
  23. package/dist/components/form/Select/Select.js +2 -1
  24. package/dist/components/form/Switch/Switch.d.ts +5 -1
  25. package/dist/components/form/Switch/Switch.d.ts.map +1 -1
  26. package/dist/components/form/Switch/Switch.js +19 -29
  27. package/dist/components/form/Switch/switch.css.d.ts.map +1 -1
  28. package/dist/components/form/Switch/switch.css.js +1 -0
  29. package/dist/components/form/TextInput/TextInput.d.ts +0 -1
  30. package/dist/components/form/TextInput/TextInput.d.ts.map +1 -1
  31. package/dist/components/form/TextInput/TextInput.js +0 -2
  32. package/dist/components/overlay/Dialog/Dialog.d.ts +4 -1
  33. package/dist/components/overlay/Dialog/Dialog.d.ts.map +1 -1
  34. package/dist/components/overlay/Dialog/Dialog.js +19 -46
  35. package/dist/components/overlay/Drawer/Drawer.d.ts +9 -2
  36. package/dist/components/overlay/Drawer/Drawer.d.ts.map +1 -1
  37. package/dist/components/overlay/Drawer/Drawer.js +25 -44
  38. package/dist/components/overlay/Drawer/drawer.css.d.ts.map +1 -1
  39. package/dist/components/overlay/Drawer/drawer.css.js +4 -8
  40. package/dist/components/overlay/Popover/Popover.d.ts +15 -3
  41. package/dist/components/overlay/Popover/Popover.d.ts.map +1 -1
  42. package/dist/components/overlay/Popover/Popover.js +35 -11
  43. package/dist/components/overlay/Popover/popover-utils.d.ts +38 -1
  44. package/dist/components/overlay/Popover/popover-utils.d.ts.map +1 -1
  45. package/dist/components/overlay/Popover/popover-utils.js +92 -41
  46. package/dist/components/overlay/Tooltip/Tooltip.d.ts +8 -0
  47. package/dist/components/overlay/Tooltip/Tooltip.d.ts.map +1 -1
  48. package/dist/components/overlay/Tooltip/Tooltip.js +3 -2
  49. package/dist/components/overlay/requestCloseReason.d.ts +6 -0
  50. package/dist/components/overlay/requestCloseReason.d.ts.map +1 -0
  51. package/dist/components/overlay/useModalOverlay.d.ts +35 -0
  52. package/dist/components/overlay/useModalOverlay.d.ts.map +1 -0
  53. package/dist/components/overlay/useModalOverlay.js +85 -0
  54. package/dist/hooks/useClickOutside/useClickOutside.d.ts.map +1 -1
  55. package/dist/hooks/useClickOutside/useClickOutside.js +27 -7
  56. package/dist/hooks/useModalDialog/useModalDialog.d.ts +13 -0
  57. package/dist/hooks/useModalDialog/useModalDialog.d.ts.map +1 -0
  58. package/dist/hooks/useModalDialog/useModalDialog.js +39 -0
  59. package/dist/index.d.ts +3 -2
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/testUtils/browser/pointer.d.ts +18 -0
  62. package/dist/testUtils/browser/pointer.d.ts.map +1 -0
  63. package/package.json +2 -2
  64. package/dist/components/overlay/Dialog/dialogHelper.d.ts +0 -7
  65. package/dist/components/overlay/Dialog/dialogHelper.d.ts.map +0 -1
  66. package/dist/components/overlay/Dialog/dialogHelper.js +0 -22
@@ -5,6 +5,7 @@ setFileScope("src/components/form/Switch/switch.css.ts", "@blockle/blocks-react"
5
5
  const container = style({
6
6
  "@layer": {
7
7
  [layers.molecule]: {
8
+ flexShrink: 0,
8
9
  cursor: "pointer",
9
10
  userSelect: "none",
10
11
  position: "relative"
@@ -2,7 +2,6 @@ import { HTMLElementProps, OptionalLiteral } from '@blockle/blocks-core';
2
2
  export type TextInputProps = {
3
3
  inputClassName?: string;
4
4
  endSlot?: React.ReactNode;
5
- name: string;
6
5
  startSlot?: React.ReactNode;
7
6
  type?: OptionalLiteral<'email' | 'number' | 'password' | 'tel' | 'text' | 'url'>;
8
7
  } & Omit<HTMLElementProps<HTMLInputElement>, 'type'>;
@@ -1 +1 @@
1
- {"version":3,"file":"TextInput.d.ts","sourceRoot":"","sources":["../../../../src/components/form/TextInput/TextInput.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAM9B,MAAM,MAAM,cAAc,GAAG;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,eAAe,CACpB,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CACzD,CAAC;CAEH,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,CAAC;AAErD,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAwC9C,CAAC"}
1
+ {"version":3,"file":"TextInput.d.ts","sourceRoot":"","sources":["../../../../src/components/form/TextInput/TextInput.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAM9B,MAAM,MAAM,cAAc,GAAG;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,eAAe,CACpB,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CACzD,CAAC;CAEH,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,CAAC;AAErD,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAsC9C,CAAC"}
@@ -8,7 +8,6 @@ const TextInput = ({
8
8
  className,
9
9
  inputClassName,
10
10
  endSlot,
11
- name,
12
11
  placeholder,
13
12
  startSlot,
14
13
  type = "text",
@@ -31,7 +30,6 @@ const TextInput = ({
31
30
  /* @__PURE__ */ jsx(
32
31
  "input",
33
32
  {
34
- name,
35
33
  type,
36
34
  placeholder,
37
35
  className: classnames(input, inputStyles, inputClassName),
@@ -1,8 +1,11 @@
1
1
  import { ComponentThemes, HTMLElementProps } from '@blockle/blocks-core';
2
+ import { RequestCloseReason } from '../requestCloseReason.js';
2
3
  type DialogTheme = ComponentThemes['dialog'];
3
4
  export type DialogProps = {
4
5
  open: boolean;
5
- onRequestClose: () => void;
6
+ onRequestClose: (reason: RequestCloseReason) => void;
7
+ /** Runs on a close request, before the component prevents it and asks to close */
8
+ onCancel?: React.ReactEventHandler<HTMLDialogElement>;
6
9
  className?: string;
7
10
  size?: DialogTheme['variants']['size'];
8
11
  'aria-label'?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../../../src/components/overlay/Dialog/Dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,gBAAgB,EAEtB,MAAM,sBAAsB,CAAC;AAY9B,KAAK,WAAW,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;AAE7C,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;AAExC,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA6FxC,CAAC"}
1
+ {"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../../../src/components/overlay/Dialog/Dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,eAAe,EAGpB,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInE,KAAK,WAAW,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;AAE7C,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,cAAc,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACrD,kFAAkF;IAClF,QAAQ,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;AAExC,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAkDxC,CAAC"}
@@ -1,21 +1,21 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
- import { hasAnimationDuration, classnames } from "@blockle/blocks-core";
4
- import { useRef, useState, useCallback } from "react";
5
- import { useClickOutside } from "../../../hooks/useClickOutside/useClickOutside.js";
3
+ import { classnames, composeRefs } from "@blockle/blocks-core";
4
+ import { useRef } from "react";
6
5
  import { useComponentStyles } from "../../../hooks/useComponentStyles/useComponentStyles.js";
7
- import { useIsomorphicLayoutEffect } from "../../../hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.js";
8
- import { useKeyboard } from "../../../hooks/useKeyboard/useKeyboard.js";
9
- import { usePreventBodyScroll } from "../../../hooks/usePreventBodyScroll/usePreventBodyScroll.js";
10
- import { useRestoreFocus } from "../../../hooks/useRestoreFocus/useRestoreFocus.js";
6
+ import { useModalDialog } from "../../../hooks/useModalDialog/useModalDialog.js";
7
+ import { useModalOverlay, DialogContext } from "../useModalOverlay.js";
11
8
  import { dialog } from "./dialog.css.js";
12
- import { useNestedDialog, DialogContext } from "./dialogHelper.js";
13
9
  const Dialog = ({
14
10
  children,
15
11
  open,
16
12
  className,
17
13
  onRequestClose,
18
14
  size,
15
+ ref,
16
+ onKeyDown,
17
+ onKeyDownCapture,
18
+ onCancel,
19
19
  ...restProps
20
20
  }) => {
21
21
  const dialogRef = useRef(null);
@@ -23,55 +23,28 @@ const Dialog = ({
23
23
  dialog: true,
24
24
  variants: { size }
25
25
  });
26
- const [enabled, setEnabled] = useState(true);
27
- const [visible, setVisible] = useState(open);
28
- useRestoreFocus(open);
29
- const isNested = useNestedDialog(open);
30
- usePreventBodyScroll(open && !isNested);
31
- const onEscape = useCallback(
32
- (event) => {
33
- event.preventDefault();
34
- onRequestClose();
35
- },
36
- [onRequestClose]
37
- );
38
- useKeyboard("Escape", onEscape, { enabled: open && enabled });
39
- useClickOutside(dialogRef, onRequestClose, { enabled: open && enabled });
40
- useIsomorphicLayoutEffect(() => {
41
- if (open && visible) {
42
- if (!dialogRef.current || !dialogRef.current.showModal) {
43
- return;
44
- }
45
- dialogRef.current.showModal();
46
- } else if (open) {
47
- setVisible(true);
48
- } else {
49
- if (!hasAnimationDuration(dialogRef.current)) {
50
- setVisible(false);
51
- }
52
- if (dialogRef.current?.close) {
53
- dialogRef.current.close();
54
- }
55
- }
56
- }, [open, visible]);
57
- const onAnimationEnd = useCallback(() => {
58
- if (!open) {
59
- setVisible(false);
60
- }
61
- }, [open]);
26
+ const { contextValue, closeRequestProps } = useModalOverlay(dialogRef, {
27
+ open,
28
+ onRequestClose,
29
+ onKeyDown,
30
+ onKeyDownCapture,
31
+ onCancel
32
+ });
33
+ const { visible, onAnimationEnd } = useModalDialog(dialogRef, open);
62
34
  if (!visible) {
63
35
  return null;
64
36
  }
65
37
  const dataOpen = typeof window === "undefined" && open ? true : void 0;
66
- return /* @__PURE__ */ jsx(DialogContext.Provider, { value: { setEnabled }, children: /* @__PURE__ */ jsx(
38
+ return /* @__PURE__ */ jsx(DialogContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
67
39
  "dialog",
68
40
  {
69
- ref: dialogRef,
41
+ ref: composeRefs(ref, dialogRef),
70
42
  open: dataOpen,
71
43
  className: classnames(dialog, dialogClassName, className),
72
44
  onAnimationEnd,
73
45
  onTransitionEnd: onAnimationEnd,
74
46
  ...restProps,
47
+ ...closeRequestProps,
75
48
  children
76
49
  }
77
50
  ) });
@@ -1,9 +1,16 @@
1
- import { HTMLElementProps } from '@blockle/blocks-core';
1
+ import { ComponentThemes, HTMLElementProps } from '@blockle/blocks-core';
2
+ import { RequestCloseReason } from '../requestCloseReason.js';
2
3
  import * as styles from './drawer.css.js';
4
+ type DrawerTheme = ComponentThemes['drawer'];
3
5
  export type DrawerProps = {
4
6
  open: boolean;
5
- onRequestClose: () => void;
7
+ onRequestClose: (reason: RequestCloseReason) => void;
8
+ /** Runs on a close request, before the component prevents it and asks to close */
9
+ onCancel?: React.ReactEventHandler<HTMLDialogElement>;
10
+ className?: string;
6
11
  placement?: keyof typeof styles.placement;
12
+ size?: DrawerTheme['variants']['size'];
7
13
  } & HTMLElementProps<HTMLDialogElement>;
8
14
  export declare const Drawer: React.FC<DrawerProps>;
15
+ export {};
9
16
  //# sourceMappingURL=Drawer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../../../src/components/overlay/Drawer/Drawer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,sBAAsB,CAAC;AAQ9B,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAC;AAE1C,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,OAAO,MAAM,CAAC,SAAS,CAAC;CAC3C,GAAG,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;AAExC,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAuFxC,CAAC"}
1
+ {"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../../../src/components/overlay/Drawer/Drawer.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,eAAe,EAGpB,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAC;AAE1C,KAAK,WAAW,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;AAE7C,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,cAAc,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACrD,kFAAkF;IAClF,QAAQ,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,OAAO,MAAM,CAAC,SAAS,CAAC;IAC1C,IAAI,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;CACxC,GAAG,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;AAExC,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAyDxC,CAAC"}
@@ -1,78 +1,59 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
- import { hasAnimationDuration, classnames } from "@blockle/blocks-core";
4
- import { useRef, useState, useCallback } from "react";
5
- import { useClickOutside } from "../../../hooks/useClickOutside/useClickOutside.js";
3
+ import { classnames, composeRefs } from "@blockle/blocks-core";
4
+ import { useRef } from "react";
6
5
  import { useComponentStyles } from "../../../hooks/useComponentStyles/useComponentStyles.js";
7
- import { useIsomorphicLayoutEffect } from "../../../hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.js";
8
- import { useKeyboard } from "../../../hooks/useKeyboard/useKeyboard.js";
9
- import { usePreventBodyScroll } from "../../../hooks/usePreventBodyScroll/usePreventBodyScroll.js";
6
+ import { useModalDialog } from "../../../hooks/useModalDialog/useModalDialog.js";
7
+ import { useModalOverlay, DialogContext } from "../useModalOverlay.js";
10
8
  import { drawer, placement } from "./drawer.css.js";
11
9
  const Drawer = ({
12
10
  open,
13
11
  onRequestClose,
12
+ className,
14
13
  placement: placement$1 = "left",
14
+ size,
15
15
  children,
16
+ ref,
17
+ onKeyDown,
18
+ onKeyDownCapture,
19
+ onCancel,
16
20
  ...restProps
17
21
  }) => {
18
22
  const dialogRef = useRef(null);
19
- const [visible, setVisible] = useState(open);
20
23
  const rootClassName = useComponentStyles("drawer", {
21
24
  root: true,
22
- variants: { placement: placement$1 }
25
+ variants: { placement: placement$1, size }
23
26
  });
24
27
  const dataOpen = typeof window === "undefined" && open ? true : void 0;
25
- usePreventBodyScroll(open);
26
- useClickOutside(dialogRef, onRequestClose, { enabled: open });
27
- const onEscape = useCallback(
28
- (event) => {
29
- event.preventDefault();
30
- onRequestClose();
31
- },
32
- [onRequestClose]
33
- );
34
- useKeyboard("Escape", onEscape, { enabled: open });
35
- useIsomorphicLayoutEffect(() => {
36
- if (open && visible) {
37
- if (!dialogRef.current || !dialogRef.current.showModal) {
38
- return;
39
- }
40
- dialogRef.current.showModal();
41
- } else if (open) {
42
- setVisible(true);
43
- } else {
44
- if (!hasAnimationDuration(dialogRef.current)) {
45
- setVisible(false);
46
- }
47
- if (dialogRef.current?.close) {
48
- dialogRef.current.close();
49
- }
50
- }
51
- }, [open, visible]);
52
- const onAnimationEnd = useCallback(() => {
53
- if (!open) {
54
- setVisible(false);
55
- }
56
- }, [open]);
28
+ const { contextValue, closeRequestProps } = useModalOverlay(dialogRef, {
29
+ open,
30
+ onRequestClose,
31
+ onKeyDown,
32
+ onKeyDownCapture,
33
+ onCancel
34
+ });
35
+ const { visible, onAnimationEnd } = useModalDialog(dialogRef, open);
57
36
  if (!visible) {
58
37
  return null;
59
38
  }
60
- return /* @__PURE__ */ jsx(
39
+ return /* @__PURE__ */ jsx(DialogContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
61
40
  "dialog",
62
41
  {
63
- ref: dialogRef,
42
+ ref: composeRefs(ref, dialogRef),
64
43
  open: dataOpen,
65
44
  className: classnames(
66
45
  drawer,
67
46
  placement[placement$1],
68
- rootClassName
47
+ rootClassName,
48
+ className
69
49
  ),
70
50
  onAnimationEnd,
71
51
  onTransitionEnd: onAnimationEnd,
72
52
  ...restProps,
53
+ ...closeRequestProps,
73
54
  children
74
55
  }
75
- );
56
+ ) });
76
57
  };
77
58
  export {
78
59
  Drawer
@@ -1 +1 @@
1
- {"version":3,"file":"drawer.css.d.ts","sourceRoot":"","sources":["../../../../src/components/overlay/Drawer/drawer.css.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,QAmBjB,CAAC;AAEH,eAAO,MAAM,SAAS;;;;;CA2CrB,CAAC"}
1
+ {"version":3,"file":"drawer.css.d.ts","sourceRoot":"","sources":["../../../../src/components/overlay/Drawer/drawer.css.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,QAmBjB,CAAC;AAEH,eAAO,MAAM,SAAS;;;;;CAuCrB,CAAC"}
@@ -29,8 +29,7 @@ const placement = {
29
29
  top: 0,
30
30
  bottom: 0,
31
31
  left: 0,
32
- height: "100%",
33
- width: "300px"
32
+ height: "100%"
34
33
  }
35
34
  }
36
35
  }),
@@ -40,8 +39,7 @@ const placement = {
40
39
  top: 0,
41
40
  right: 0,
42
41
  bottom: 0,
43
- height: "100%",
44
- width: "300px"
42
+ height: "100%"
45
43
  }
46
44
  }
47
45
  }),
@@ -50,8 +48,7 @@ const placement = {
50
48
  [layers.molecule]: {
51
49
  top: 0,
52
50
  left: 0,
53
- width: "100%",
54
- height: "300px"
51
+ width: "100%"
55
52
  }
56
53
  }
57
54
  }),
@@ -60,8 +57,7 @@ const placement = {
60
57
  [layers.molecule]: {
61
58
  bottom: 0,
62
59
  left: 0,
63
- width: "100%",
64
- height: "300px"
60
+ width: "100%"
65
61
  }
66
62
  }
67
63
  })
@@ -1,10 +1,22 @@
1
1
  import { HTMLElementProps } from '@blockle/blocks-core';
2
- export type PopoverAlign = 'top' | 'bottom' | 'left' | 'right';
2
+ import { RequestCloseReason } from '../requestCloseReason.js';
3
+ import { PopoverPlacement } from './popover-utils.js';
4
+ export type { PopoverPlacement };
3
5
  export type PopoverProps = {
4
6
  anchorElement: React.RefObject<HTMLElement | null>;
5
- onRequestClose: () => void;
7
+ onRequestClose: (reason: RequestCloseReason) => void;
6
8
  open: boolean;
7
- position?: PopoverAlign;
9
+ /**
10
+ * Side of the anchor to open on, and which of its edges to line up with.
11
+ * Flips to the opposite side when there is no room, and shifts to stay
12
+ * inside the viewport.
13
+ * @default 'top'
14
+ */
15
+ placement?: PopoverPlacement;
16
+ /**
17
+ * @deprecated Use `placement`, which wins when both are passed
18
+ */
19
+ position?: 'top' | 'bottom' | 'left' | 'right';
8
20
  sticky?: boolean;
9
21
  } & HTMLElementProps<HTMLDivElement>;
10
22
  export declare const Popover: React.FC<PopoverProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../../../../src/components/overlay/Popover/Popover.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,sBAAsB,CAAC;AAU9B,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAI/D,MAAM,MAAM,YAAY,GAAG;IACzB,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACnD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;CAElB,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;AAErC,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAqH1C,CAAC"}
1
+ {"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../../../../src/components/overlay/Popover/Popover.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,sBAAsB,CAAC;AAQ9B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE/E,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAIjC,MAAM,MAAM,YAAY,GAAG;IACzB,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACnD,cAAc,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACrD,IAAI,EAAE,OAAO,CAAC;IACd;;;;;OAKG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;CAElB,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;AAErC,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAkJ1C,CAAC"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { hasAnimationDuration, classnames, composeRefs } from "@blockle/blocks-core";
4
- import { useRef, useState, useEffect, useCallback } from "react";
4
+ import { useRef, useState, useCallback, useEffect } from "react";
5
5
  import { useClickOutside } from "../../../hooks/useClickOutside/useClickOutside.js";
6
6
  import { useComponentStyles } from "../../../hooks/useComponentStyles/useComponentStyles.js";
7
7
  import { useIsomorphicLayoutEffect } from "../../../hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.js";
@@ -14,17 +14,32 @@ const Popover = ({
14
14
  className,
15
15
  onRequestClose,
16
16
  open,
17
- position = "top",
17
+ placement: placementProp,
18
+ position,
19
+ ref,
18
20
  sticky,
19
21
  style,
20
22
  ...restProps
21
23
  }) => {
24
+ const placement = placementProp ?? position ?? "top";
22
25
  const popoverRef = useRef(null);
23
26
  const [popoverPosition, setPopoverPosition] = useState({ x: 0, y: 0 });
24
27
  const [visible, setVisible] = useState(open);
25
28
  const popoverClassName = useComponentStyles("popover", { root: true }, false);
26
- useKeyboard("Escape", onRequestClose, { enabled: open });
27
- useClickOutside(popoverRef, onRequestClose, { enabled: open });
29
+ const onEscape = useCallback(
30
+ (event) => {
31
+ if (event.defaultPrevented) {
32
+ return;
33
+ }
34
+ event.preventDefault();
35
+ onRequestClose("escape");
36
+ },
37
+ [onRequestClose]
38
+ );
39
+ useKeyboard("Escape", onEscape, { enabled: open });
40
+ useClickOutside(popoverRef, () => onRequestClose("outside-click"), {
41
+ enabled: open
42
+ });
28
43
  useIsomorphicLayoutEffect(() => {
29
44
  const element = popoverRef.current;
30
45
  if (open && visible) {
@@ -35,7 +50,7 @@ const Popover = ({
35
50
  return;
36
51
  }
37
52
  element.showPopover();
38
- const [x, y] = getPopoverPosition(position, anchorElement, popoverRef);
53
+ const [x, y] = getPopoverPosition(placement, anchorElement, popoverRef);
39
54
  setPopoverPosition({ x, y });
40
55
  } else if (open) {
41
56
  setVisible(true);
@@ -43,21 +58,30 @@ const Popover = ({
43
58
  if (!hasAnimationDuration(popoverRef.current)) {
44
59
  setVisible(false);
45
60
  }
46
- popoverRef.current?.hidePopover();
61
+ if (!element) {
62
+ return;
63
+ }
64
+ if (typeof element.hidePopover !== "function") {
65
+ console.warn(
66
+ "Popover: hidePopover method is not available on the element."
67
+ );
68
+ return;
69
+ }
70
+ element.hidePopover();
47
71
  }
48
72
  }, [open, visible]);
49
73
  useEffect(() => {
50
74
  if (open) {
51
- const [x, y] = getPopoverPosition(position, anchorElement, popoverRef);
75
+ const [x, y] = getPopoverPosition(placement, anchorElement, popoverRef);
52
76
  setPopoverPosition({ x, y });
53
77
  }
54
- }, [open, anchorElement, position]);
78
+ }, [open, anchorElement, placement]);
55
79
  useEffect(() => {
56
80
  if (!open || !sticky) {
57
81
  return;
58
82
  }
59
83
  function updatePopoverPosition() {
60
- const [x, y] = getPopoverPosition(position, anchorElement, popoverRef);
84
+ const [x, y] = getPopoverPosition(placement, anchorElement, popoverRef);
61
85
  setPopoverPosition((prev) => {
62
86
  if (prev.x === x && prev.y === y) {
63
87
  return prev;
@@ -71,7 +95,7 @@ const Popover = ({
71
95
  window.removeEventListener("resize", updatePopoverPosition);
72
96
  window.removeEventListener("scroll", updatePopoverPosition);
73
97
  };
74
- }, [position, anchorElement, open, sticky]);
98
+ }, [placement, anchorElement, open, sticky]);
75
99
  const onAnimationEnd = useCallback(() => {
76
100
  if (!open) {
77
101
  setVisible(false);
@@ -83,7 +107,7 @@ const Popover = ({
83
107
  return /* @__PURE__ */ jsx(
84
108
  Box,
85
109
  {
86
- ref: composeRefs(restProps.ref, popoverRef),
110
+ ref: composeRefs(ref, popoverRef),
87
111
  "data-open": open ? "" : void 0,
88
112
  popover: "manual",
89
113
  className: classnames(popoverClassName, className),
@@ -1,3 +1,40 @@
1
1
  export type PopoverPositions = [x: number, y: number];
2
- export declare function getPopoverPosition(position: 'top' | 'bottom' | 'left' | 'right', anchorRef: React.RefObject<HTMLElement | null>, popoverRef: React.RefObject<HTMLElement | null>): PopoverPositions;
2
+ type PopoverSide = 'top' | 'bottom' | 'left' | 'right';
3
+ type PopoverEdge = 'start' | 'end';
4
+ export type PopoverPlacement = PopoverSide | `${PopoverSide}-${PopoverEdge}`;
5
+ type Rect = {
6
+ top: number;
7
+ left: number;
8
+ width: number;
9
+ height: number;
10
+ };
11
+ type Margin = {
12
+ top: number;
13
+ right: number;
14
+ bottom: number;
15
+ left: number;
16
+ };
17
+ export type ComputePopoverPositionOptions = {
18
+ placement: PopoverPlacement;
19
+ /** The anchor's border box, relative to the viewport */
20
+ anchor: Rect;
21
+ /** The popover's untransformed border-box size and its margins */
22
+ popover: {
23
+ width: number;
24
+ height: number;
25
+ margin: Margin;
26
+ };
27
+ viewport: {
28
+ width: number;
29
+ height: number;
30
+ scrollX: number;
31
+ scrollY: number;
32
+ };
33
+ };
34
+ /**
35
+ * Returns the popover's `left` and `top`, relative to the document
36
+ */
37
+ export declare function computePopoverPosition({ placement, anchor, popover, viewport, }: ComputePopoverPositionOptions): PopoverPositions;
38
+ export declare function getPopoverPosition(placement: PopoverPlacement, anchorRef: React.RefObject<HTMLElement | null>, popoverRef: React.RefObject<HTMLElement | null>): PopoverPositions;
39
+ export {};
3
40
  //# sourceMappingURL=popover-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover-utils.d.ts","sourceRoot":"","sources":["../../../../src/components/overlay/Popover/popover-utils.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AAEtD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,EAC7C,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EAC9C,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAC9C,gBAAgB,CAqElB"}
1
+ {"version":3,"file":"popover-utils.d.ts","sourceRoot":"","sources":["../../../../src/components/overlay/Popover/popover-utils.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AAEtD,KAAK,WAAW,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAEvD,KAAK,WAAW,GAAG,OAAO,GAAG,KAAK,CAAC;AAEnC,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,GAAG,WAAW,IAAI,WAAW,EAAE,CAAC;AAE7E,KAAK,IAAI,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE,KAAK,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,gBAAgB,CAAC;IAC5B,wDAAwD;IACxD,MAAM,EAAE,IAAI,CAAC;IACb,kEAAkE;IAClE,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/E,CAAC;AAEF;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,MAAM,EACN,OAAO,EACP,QAAQ,GACT,EAAE,6BAA6B,GAAG,gBAAgB,CAyClD;AAoED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,gBAAgB,EAC3B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EAC9C,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAC9C,gBAAgB,CAyClB"}