@sanity/ui 5.0.0-alpha.3 → 5.0.0-alpha.5

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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ComponentProps } from "react";
1
+ import { ComponentProps } from "react";
2
2
  import { ComponentPropsWithRef } from "react";
3
3
  import { ElementType } from "react";
4
4
  import { JSX } from "react";
@@ -641,6 +641,45 @@ export declare type MarginProps = {
641
641
  marginLeft?: Responsive<SpaceAutoNegative>;
642
642
  };
643
643
 
644
+ /**
645
+ * @beta
646
+ *
647
+ * Renders a modal dialog element — should not be used for nonmodal dialogs.
648
+ * Modal dialogs make their containing documents inert, and render on the topmost
649
+ * layer within that containing document; they must be dimissed before the containing
650
+ * document and its contents become unblocked. They also trap focus within the bounds
651
+ * of the modal element and its descendants.
652
+ *
653
+ * For more on dialogs and modality, refer to the HTML specification for the dialog element:
654
+ * https://html.spec.whatwg.org/dev/interactive-elements.html#the-dialog-element
655
+ */
656
+ export declare const Modal: typeof ModalRoot;
657
+
658
+ declare function ModalContent(props: ComponentProps<"div">): JSX.Element;
659
+
660
+ declare function ModalFooter(props: ComponentProps<"div">): JSX.Element;
661
+
662
+ /** @beta */
663
+ export declare interface ModalProps extends Omit<
664
+ React.ComponentProps<"dialog">,
665
+ "open"
666
+ > {
667
+ /** Text to be displayed as the modal's heading; optional but recommended for optimal accessibility and presentation */
668
+ header?: string;
669
+ /** Used to set the value of open to false. Fires whenever the modal is closed, either programmatically or by the user (via Esc key, clicking background, clicking the modal's close button, or any other means.) */
670
+ onClose: React.ReactEventHandler<HTMLDialogElement>;
671
+ /** Whether the modal is open; defaults to false. */
672
+ open?: boolean;
673
+ }
674
+
675
+ declare function ModalRoot(props: ModalProps): JSX.Element;
676
+
677
+ declare namespace ModalRoot {
678
+ var displayName: string;
679
+ var Content: typeof ModalContent;
680
+ var Footer: typeof ModalFooter;
681
+ }
682
+
644
683
  declare const OVERFLOW: readonly [
645
684
  "visible",
646
685
  "hidden",
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
3
3
  import { c } from "react/compiler-runtime";
4
4
  import clsx from "clsx";
5
5
  import { isValidElement, useRef, useEffect, lazy, Suspense, Children, useId, useState, cloneElement } from "react";
6
- import { SpinnerIcon, RemoveIcon, CheckmarkIcon } from "@sanity/icons";
6
+ import { SpinnerIcon, RemoveIcon, CheckmarkIcon, CloseIcon } from "@sanity/icons";
7
7
  const PREFIX = "sui", BREAKPOINTS_LENGTH = 6;
8
8
  function getProps(componentProps, propDefs) {
9
9
  const {
@@ -95,7 +95,7 @@ function getCompositeValue(propValue, propDef, key) {
95
95
  compositeValue = mapping?.[propValue];
96
96
  return compositeValue;
97
97
  }
98
- const HASH = "cfa475";
98
+ const HASH = "024922";
99
99
  function suffixClassName(className) {
100
100
  return `${className}-${HASH}`;
101
101
  }
@@ -1647,6 +1647,83 @@ ListRoot.Item = ListItem;
1647
1647
  ListRoot.ButtonItem = ListButtonItem;
1648
1648
  ListRoot.ItemText = ListItemText;
1649
1649
  ListRoot.ItemImage = ListItemImage;
1650
+ const modalProps = {
1651
+ header: {
1652
+ type: "string"
1653
+ },
1654
+ open: {
1655
+ type: "boolean"
1656
+ }
1657
+ }, modalClassName = suffixClassName("sui-Modal"), modalContentClassName = suffixClassName("sui-ModalContent"), modalFooterClassName = suffixClassName("sui-ModalFooter");
1658
+ function ModalRoot(props) {
1659
+ const $ = c(14), {
1660
+ children,
1661
+ className,
1662
+ style,
1663
+ header,
1664
+ open: t0,
1665
+ onClose,
1666
+ ...rest
1667
+ } = getProps(props, modalProps), open = t0 === void 0 ? !1 : t0, modalRef = useRef(null), headerId = useId(), modalClasses = clsx(modalClassName, "sui-inset0 sui-m-auto sui-radius5 sui-shadow3 sui-p4 sui-flex-direction-column sui-gap4 sui-overflow-y-auto");
1668
+ useEffect(() => {
1669
+ const dialogElement = modalRef.current;
1670
+ if (dialogElement)
1671
+ return open ? dialogElement.open || dialogElement.showModal() : dialogElement.open && dialogElement.close(), () => {
1672
+ dialogElement.close();
1673
+ };
1674
+ }, [open]);
1675
+ const t1 = "any", t2 = header ? headerId : void 0, t3 = clsx(modalClasses, className);
1676
+ let t4;
1677
+ $[0] !== header || $[1] !== headerId ? (t4 = header ? /* @__PURE__ */ jsx(Heading, { trim: !0, size: 1, id: headerId, children: header }) : /* @__PURE__ */ jsx("div", {}), $[0] = header, $[1] = headerId, $[2] = t4) : t4 = $[2];
1678
+ let t5;
1679
+ $[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t5 = /* @__PURE__ */ jsx(IconButton, { "aria-label": "Close", level: "tertiary", icon: CloseIcon, onClick: () => modalRef.current?.close() }), $[3] = t5) : t5 = $[3];
1680
+ let t6;
1681
+ $[4] !== t4 ? (t6 = /* @__PURE__ */ jsxs(Flex, { flexShrink: 0, justifyContent: "space-between", alignItems: "center", children: [
1682
+ t4,
1683
+ t5
1684
+ ] }), $[4] = t4, $[5] = t6) : t6 = $[5];
1685
+ let t7;
1686
+ return $[6] !== children || $[7] !== onClose || $[8] !== rest || $[9] !== style || $[10] !== t2 || $[11] !== t3 || $[12] !== t6 ? (t7 = /* @__PURE__ */ jsxs("dialog", { ...rest, ref: modalRef, closedby: t1, "aria-labelledby": t2, onClose, className: t3, style, "data-ui": "Modal", children: [
1687
+ t6,
1688
+ children
1689
+ ] }), $[6] = children, $[7] = onClose, $[8] = rest, $[9] = style, $[10] = t2, $[11] = t3, $[12] = t6, $[13] = t7) : t7 = $[13], t7;
1690
+ }
1691
+ function ModalContent(props) {
1692
+ const $ = c(12);
1693
+ let T0, children, style, t0, t1;
1694
+ if ($[0] !== props) {
1695
+ const {
1696
+ children: t22,
1697
+ className,
1698
+ style: t3,
1699
+ ...rest
1700
+ } = getProps(props, {});
1701
+ children = t22, style = t3, T0 = Box, t0 = rest, t1 = clsx(modalContentClassName, className), $[0] = props, $[1] = T0, $[2] = children, $[3] = style, $[4] = t0, $[5] = t1;
1702
+ } else
1703
+ T0 = $[1], children = $[2], style = $[3], t0 = $[4], t1 = $[5];
1704
+ let t2;
1705
+ return $[6] !== T0 || $[7] !== children || $[8] !== style || $[9] !== t0 || $[10] !== t1 ? (t2 = /* @__PURE__ */ jsx(T0, { ...t0, className: t1, style, "data-ui": "ModalContent", flexGrow: 1, overflowY: "auto", children }), $[6] = T0, $[7] = children, $[8] = style, $[9] = t0, $[10] = t1, $[11] = t2) : t2 = $[11], t2;
1706
+ }
1707
+ function ModalFooter(props) {
1708
+ const $ = c(12);
1709
+ let T0, children, style, t0, t1;
1710
+ if ($[0] !== props) {
1711
+ const {
1712
+ children: t22,
1713
+ className,
1714
+ style: t3,
1715
+ ...rest
1716
+ } = getProps(props, {});
1717
+ children = t22, style = t3, T0 = Box, t0 = rest, t1 = clsx(modalFooterClassName, className), $[0] = props, $[1] = T0, $[2] = children, $[3] = style, $[4] = t0, $[5] = t1;
1718
+ } else
1719
+ T0 = $[1], children = $[2], style = $[3], t0 = $[4], t1 = $[5];
1720
+ let t2;
1721
+ return $[6] !== T0 || $[7] !== children || $[8] !== style || $[9] !== t0 || $[10] !== t1 ? (t2 = /* @__PURE__ */ jsx(T0, { ...t0, className: t1, style, "data-ui": "ModalFooter", flexShrink: 0, children }), $[6] = T0, $[7] = children, $[8] = style, $[9] = t0, $[10] = t1, $[11] = t2) : t2 = $[11], t2;
1722
+ }
1723
+ ModalRoot.displayName = "Modal";
1724
+ const Modal = ModalRoot;
1725
+ ModalRoot.Content = ModalContent;
1726
+ ModalRoot.Footer = ModalFooter;
1650
1727
  const radioProps = {
1651
1728
  error: {
1652
1729
  type: "boolean"
@@ -1870,6 +1947,7 @@ export {
1870
1947
  Label,
1871
1948
  Link,
1872
1949
  List,
1950
+ Modal,
1873
1951
  PressArea,
1874
1952
  Radio,
1875
1953
  SkipToContent,