@sanity/ui 0.36.17 → 0.37.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.
@@ -24,5 +24,5 @@ export interface MenuProps extends ResponsivePaddingProps {
24
24
  /**
25
25
  * @public
26
26
  */
27
- export declare const Menu: React.ForwardRefExoticComponent<Pick<MenuProps & Omit<React.HTMLProps<HTMLDivElement>, "as" | "height" | "tabIndex" | "role">, "cite" | "data" | "form" | "label" | "slot" | "span" | "style" | "summary" | "title" | "pattern" | "accept" | "acceptCharset" | "action" | "allowFullScreen" | "allowTransparency" | "alt" | "async" | "autoComplete" | "autoFocus" | "autoPlay" | "capture" | "cellPadding" | "cellSpacing" | "charSet" | "challenge" | "checked" | "classID" | "cols" | "colSpan" | "content" | "controls" | "coords" | "crossOrigin" | "dateTime" | "default" | "defer" | "disabled" | "download" | "encType" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "frameBorder" | "headers" | "high" | "href" | "hrefLang" | "htmlFor" | "httpEquiv" | "integrity" | "keyParams" | "keyType" | "kind" | "list" | "loop" | "low" | "manifest" | "marginHeight" | "marginWidth" | "max" | "maxLength" | "media" | "mediaGroup" | "method" | "min" | "minLength" | "multiple" | "muted" | "name" | "nonce" | "noValidate" | "open" | "optimum" | "placeholder" | "playsInline" | "poster" | "preload" | "readOnly" | "rel" | "required" | "reversed" | "rows" | "rowSpan" | "sandbox" | "scope" | "scoped" | "scrolling" | "seamless" | "selected" | "shape" | "size" | "sizes" | "src" | "srcDoc" | "srcLang" | "srcSet" | "start" | "step" | "target" | "type" | "useMap" | "value" | "width" | "wmode" | "wrap" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "id" | "lang" | "spellCheck" | "translate" | "radioGroup" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "children" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "key" | keyof MenuProps> & React.RefAttributes<unknown>>;
27
+ export declare const Menu: React.ForwardRefExoticComponent<Pick<MenuProps & Omit<React.HTMLProps<HTMLDivElement>, "as" | "height" | "tabIndex" | "role">, "cite" | "data" | "form" | "label" | "slot" | "span" | "style" | "summary" | "title" | "pattern" | "accept" | "acceptCharset" | "action" | "allowFullScreen" | "allowTransparency" | "alt" | "async" | "autoComplete" | "autoFocus" | "autoPlay" | "capture" | "cellPadding" | "cellSpacing" | "charSet" | "challenge" | "checked" | "classID" | "cols" | "colSpan" | "content" | "controls" | "coords" | "crossOrigin" | "dateTime" | "default" | "defer" | "disabled" | "download" | "encType" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "frameBorder" | "headers" | "high" | "href" | "hrefLang" | "htmlFor" | "httpEquiv" | "integrity" | "keyParams" | "keyType" | "kind" | "list" | "loop" | "low" | "manifest" | "marginHeight" | "marginWidth" | "max" | "maxLength" | "media" | "mediaGroup" | "method" | "min" | "minLength" | "multiple" | "muted" | "name" | "nonce" | "noValidate" | "open" | "optimum" | "placeholder" | "playsInline" | "poster" | "preload" | "readOnly" | "rel" | "required" | "reversed" | "rows" | "rowSpan" | "sandbox" | "scope" | "scoped" | "scrolling" | "seamless" | "selected" | "shape" | "size" | "sizes" | "src" | "srcDoc" | "srcLang" | "srcSet" | "start" | "step" | "target" | "type" | "useMap" | "value" | "width" | "wmode" | "wrap" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "id" | "lang" | "spellCheck" | "translate" | "radioGroup" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "children" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "key" | keyof MenuProps> & React.RefAttributes<HTMLDivElement>>;
28
28
  //# sourceMappingURL=menu.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../../src/components/menu/menu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsE,MAAM,OAAO,CAAA;AAI1F,OAAO,EAAC,sBAAsB,EAAC,MAAM,wBAAwB,CAAA;AAK7D;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,sBAAsB;IACvD;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAC5C,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,aAAa,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAClC,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,MAAM,IAAI,CAAA;IACjD,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAA;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAC1B;AAOD;;GAEG;AACH,eAAO,MAAM,IAAI,w2LAmTf,CAAA"}
1
+ {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../../src/components/menu/menu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoD,MAAM,OAAO,CAAA;AAIxE,OAAO,EAAC,sBAAsB,EAAC,MAAM,wBAAwB,CAAA;AAK7D;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,sBAAsB;IACvD;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAC5C,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,aAAa,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAClC,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,MAAM,IAAI,CAAA;IACjD,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAA;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAC1B;AAOD;;GAEG;AACH,eAAO,MAAM,IAAI,+2LA2Hf,CAAA"}
@@ -7,8 +7,8 @@ export interface MenuContextValue {
7
7
  onClickOutside?: (event: MouseEvent) => void;
8
8
  onEscape?: () => void;
9
9
  onItemClick?: () => void;
10
- onMouseEnter: (event: React.MouseEvent<HTMLElement>) => void;
11
- onMouseLeave: (event: React.MouseEvent<HTMLElement>) => void;
10
+ onItemMouseEnter: (event: React.MouseEvent<HTMLElement>) => void;
11
+ onItemMouseLeave: (event: React.MouseEvent<HTMLElement>) => void;
12
12
  registerElement?: (el: HTMLElement) => () => void;
13
13
  }
14
14
  export declare const MenuContext: React.Context<MenuContextValue | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"menuContext.d.ts","sourceRoot":"","sources":["../../../../src/components/menu/menuContext.ts"],"names":[],"mappings":";AAGA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,GAAG,CAAA;IACZ,aAAa,EAAE,WAAW,GAAG,IAAI,CAAA;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,MAAM,IAAI,CAAA;IACtE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAC5C,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;IAC5D,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;IAC5D,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,MAAM,IAAI,CAAA;CAClD;AAMD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAoB,CAAA"}
1
+ {"version":3,"file":"menuContext.d.ts","sourceRoot":"","sources":["../../../../src/components/menu/menuContext.ts"],"names":[],"mappings":";AAGA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,GAAG,CAAA;IACZ,aAAa,EAAE,WAAW,GAAG,IAAI,CAAA;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,MAAM,IAAI,CAAA;IACtE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAC5C,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;IAChE,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;IAChE,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,MAAM,IAAI,CAAA;CAClD;AAMD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAoB,CAAA"}
@@ -7,9 +7,11 @@ import { SelectableTone } from '../../types/selectable';
7
7
  export interface MenuGroupProps {
8
8
  as?: React.ElementType | keyof JSX.IntrinsicElements;
9
9
  fontSize?: number | number[];
10
+ icon?: React.ComponentType | React.ReactNode;
10
11
  padding?: number | number[];
11
12
  popover?: Omit<PopoverProps, 'content' | 'open'>;
12
13
  radius?: number | number[];
14
+ space?: number | number[];
13
15
  text: React.ReactNode;
14
16
  tone?: SelectableTone;
15
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"menuGroup.d.ts","sourceRoot":"","sources":["../../../../src/components/menu/menuGroup.tsx"],"names":[],"mappings":"AACA,OAAO,KAAiD,MAAM,OAAO,CAAA;AAErE,OAAO,EAAe,YAAY,EAAO,MAAM,kBAAkB,CAAA;AAEjE,OAAO,EAAC,cAAc,EAAC,MAAM,wBAAwB,CAAA;AAIrD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,KAAK,CAAC,WAAW,GAAG,MAAM,GAAG,CAAC,iBAAiB,CAAA;IACpD,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC3B,OAAO,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,MAAM,CAAC,CAAA;IAChD,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC1B,IAAI,EAAE,KAAK,CAAC,SAAS,CAAA;IACrB,IAAI,CAAC,EAAE,cAAc,CAAA;CACtB;AAeD;;GAEG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,cAAc,GACnB,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,IAAI,GAAG,QAAQ,GAAG,KAAK,GAAG,UAAU,CAAC,GAC5E,KAAK,CAAC,YAAY,CAoLpB"}
1
+ {"version":3,"file":"menuGroup.d.ts","sourceRoot":"","sources":["../../../../src/components/menu/menuGroup.tsx"],"names":[],"mappings":"AACA,OAAO,KAAgF,MAAM,OAAO,CAAA;AAEpG,OAAO,EAAqB,YAAY,EAAO,MAAM,kBAAkB,CAAA;AAEvE,OAAO,EAAC,cAAc,EAAC,MAAM,wBAAwB,CAAA;AAIrD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,KAAK,CAAC,WAAW,GAAG,MAAM,GAAG,CAAC,iBAAiB,CAAA;IACpD,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC5B,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,SAAS,CAAA;IAC5C,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC3B,OAAO,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,MAAM,CAAC,CAAA;IAChD,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACzB,IAAI,EAAE,KAAK,CAAC,SAAS,CAAA;IACrB,IAAI,CAAC,EAAE,cAAc,CAAA;CACtB;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,cAAc,GACnB,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,IAAI,GAAG,QAAQ,GAAG,KAAK,GAAG,UAAU,CAAC,GAC5E,KAAK,CAAC,YAAY,CAwKpB"}
@@ -0,0 +1,25 @@
1
+ /// <reference types="react" />
2
+ /**
3
+ * @internal
4
+ */
5
+ export interface MenuController {
6
+ activeElement: HTMLElement | null;
7
+ activeIndex: number;
8
+ handleItemMouseEnter: (event: React.MouseEvent<HTMLElement>) => void;
9
+ handleItemMouseLeave: () => void;
10
+ handleKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void;
11
+ mount: (element: HTMLElement | null, selected?: boolean) => () => void;
12
+ rootElement: HTMLDivElement | null;
13
+ setRootElement: (el: HTMLDivElement | null) => void;
14
+ }
15
+ /**
16
+ * This controller is responsible for controlling UI menu state.
17
+ *
18
+ * @internal
19
+ */
20
+ export declare function useMenuController(props: {
21
+ onKeyDown?: React.KeyboardEventHandler;
22
+ originElement?: HTMLElement | null;
23
+ shouldFocus: 'first' | 'last' | null;
24
+ }): MenuController;
25
+ //# sourceMappingURL=useMenuController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMenuController.d.ts","sourceRoot":"","sources":["../../../../src/components/menu/useMenuController.ts"],"names":[],"mappings":";AAGA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,WAAW,GAAG,IAAI,CAAA;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,oBAAoB,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;IACpE,oBAAoB,EAAE,MAAM,IAAI,CAAA;IAChC,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,IAAI,CAAA;IACnE,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,MAAM,IAAI,CAAA;IACtE,WAAW,EAAE,cAAc,GAAG,IAAI,CAAA;IAClC,cAAc,EAAE,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAA;CACpD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,SAAS,CAAC,EAAE,KAAK,CAAC,oBAAoB,CAAA;IACtC,aAAa,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAClC,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAA;CACrC,GAAG,cAAc,CAoNjB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/ui",
3
- "version": "0.36.17",
3
+ "version": "0.37.0",
4
4
  "sideEffects": false,
5
5
  "source": "src/index.ts",
6
6
  "exports": {
@@ -29,11 +29,11 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@juggle/resize-observer": "^3.3.1",
32
- "@popperjs/core": "^2.10.2",
32
+ "@popperjs/core": "^2.11.2",
33
33
  "@reach/auto-id": "^0.16.0",
34
34
  "@sanity/color": "^2.1.6",
35
- "@sanity/icons": "^1.2.2",
36
- "framer-motion": "5.3.3",
35
+ "@sanity/icons": "^1.2.3",
36
+ "framer-motion": "5.5.5",
37
37
  "lodash": "^4.17.21",
38
38
  "popper-max-size-modifier": "^0.2.0",
39
39
  "react-is": "^17.0.2",
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "devDependencies": {
44
44
  "@testing-library/dom": "^8.11.1",
45
- "@testing-library/jest-dom": "^5.15.1",
45
+ "@testing-library/jest-dom": "^5.16.1",
46
46
  "@testing-library/react": "^12.1.2",
47
47
  "@types/refractor": "^3.0.2",
48
48
  "react": "^17.0.2",
@@ -71,5 +71,5 @@
71
71
  "publishConfig": {
72
72
  "access": "public"
73
73
  },
74
- "gitHead": "bffa8588fc2167c42afab5d788a69303947099a0"
74
+ "gitHead": "2622dda034809ec983fdce4c4a25ab054d3c5196"
75
75
  }
@@ -22,6 +22,11 @@ export default defineScope('components/menu', 'Menu', [
22
22
  title: 'Groups',
23
23
  component: lazy(() => import('./groups')),
24
24
  },
25
+ {
26
+ name: 'menu-group-right',
27
+ title: 'Menu group (right)',
28
+ component: lazy(() => import('./menuGroupRight')),
29
+ },
25
30
  {
26
31
  name: 'tones',
27
32
  title: 'Tones',
@@ -0,0 +1,59 @@
1
+ import {
2
+ AddIcon,
3
+ BookIcon,
4
+ CopyIcon,
5
+ EllipsisVerticalIcon,
6
+ ImageIcon,
7
+ TrashIcon,
8
+ } from '@sanity/icons'
9
+ import {
10
+ Box,
11
+ Button,
12
+ Card,
13
+ Container,
14
+ Flex,
15
+ Menu,
16
+ MenuButton,
17
+ MenuDivider,
18
+ MenuGroup,
19
+ MenuItem,
20
+ } from '@sanity/ui'
21
+ import React from 'react'
22
+
23
+ export default function MenuGroupRightStory() {
24
+ return (
25
+ <Card height="fill" tone="transparent">
26
+ <Flex align="center" height="fill" padding={4} sizing="border">
27
+ <Container width={1}>
28
+ <Card padding={2} radius={2} shadow={2}>
29
+ <Flex>
30
+ <Box flex={1} />
31
+ <Box>
32
+ <MenuButton
33
+ button={<Button icon={EllipsisVerticalIcon} mode="bleed" />}
34
+ id="right-menu"
35
+ menu={
36
+ <Menu>
37
+ <MenuGroup icon={AddIcon} popover={{placement: 'left'}} text="Add above">
38
+ <MenuItem icon={ImageIcon} text="Image" />
39
+ <MenuItem icon={BookIcon} text="Book" />
40
+ </MenuGroup>
41
+ <MenuGroup icon={AddIcon} popover={{placement: 'left'}} text="Add below">
42
+ <MenuItem icon={ImageIcon} text="Image" />
43
+ <MenuItem icon={BookIcon} text="Book" />
44
+ </MenuGroup>
45
+ <MenuDivider />
46
+ <MenuItem icon={CopyIcon} text="Duplicate" />
47
+ <MenuItem icon={TrashIcon} text="Remove" tone="critical" />
48
+ </Menu>
49
+ }
50
+ popover={{placement: 'right', portal: true}}
51
+ />
52
+ </Box>
53
+ </Flex>
54
+ </Card>
55
+ </Container>
56
+ </Flex>
57
+ </Card>
58
+ )
59
+ }
@@ -25,8 +25,8 @@ describe('components/menu', () => {
25
25
  activeIndex: 0,
26
26
  mount: (element: HTMLElement | null) => () => console.log(element),
27
27
  onItemClick: () => undefined,
28
- onMouseEnter: (event: React.MouseEvent<HTMLElement>) => console.log(event),
29
- onMouseLeave: (event: React.MouseEvent<HTMLElement>) => console.log(event),
28
+ onItemMouseEnter: (event: React.MouseEvent<HTMLElement>) => console.log(event),
29
+ onItemMouseLeave: (event: React.MouseEvent<HTMLElement>) => console.log(event),
30
30
  }
31
31
 
32
32
  return (
@@ -38,12 +38,14 @@ describe('components/menu', () => {
38
38
 
39
39
  render(<Root />)
40
40
 
41
- expect(log.mock.calls[0][0].version).toBe(0.0)
42
- expect(log.mock.calls[0][0].activeIndex).toBe(0)
43
- expect(typeof log.mock.calls[0][0].mount).toBe('function')
44
- expect(typeof log.mock.calls[0][0].onItemClick).toBe('function')
45
- expect(typeof log.mock.calls[0][0].onMouseEnter).toBe('function')
46
- expect(typeof log.mock.calls[0][0].onMouseLeave).toBe('function')
41
+ const contextValue = log.mock.calls[0][0]
42
+
43
+ expect(contextValue.version).toBe(0.0)
44
+ expect(contextValue.activeIndex).toBe(0)
45
+ expect(typeof contextValue.mount).toBe('function')
46
+ expect(typeof contextValue.onItemClick).toBe('function')
47
+ expect(typeof contextValue.onItemMouseEnter).toBe('function')
48
+ expect(typeof contextValue.onItemMouseEnter).toBe('function')
47
49
  })
48
50
 
49
51
  it('should fail when no context value is provided', async () => {
@@ -60,10 +62,11 @@ describe('components/menu', () => {
60
62
  }
61
63
 
62
64
  function Root() {
63
- const value = undefined
65
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ const value: any = undefined
64
67
 
65
68
  return (
66
- <MenuContext.Provider value={value as any}>
69
+ <MenuContext.Provider value={value}>
67
70
  <Debug />
68
71
  </MenuContext.Provider>
69
72
  )
@@ -89,12 +92,13 @@ describe('components/menu', () => {
89
92
 
90
93
  function Root() {
91
94
  // NOTE: we’re testing this because the context value may be a function in the future
92
- const value = () => {
95
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
96
+ const value: any = () => {
93
97
  return {version: 1}
94
98
  }
95
99
 
96
100
  return (
97
- <MenuContext.Provider value={value as any}>
101
+ <MenuContext.Provider value={value}>
98
102
  <Debug />
99
103
  </MenuContext.Provider>
100
104
  )
@@ -1,11 +1,11 @@
1
- import React, {forwardRef, useCallback, useEffect, useMemo, useRef, useState} from 'react'
1
+ import React, {forwardRef, useCallback, useEffect, useMemo} from 'react'
2
2
  import styled from 'styled-components'
3
- import {useClickOutside, useGlobalKeyDown} from '../../hooks'
3
+ import {useClickOutside, useForwardedRef, useGlobalKeyDown} from '../../hooks'
4
4
  import {Box, Stack} from '../../primitives'
5
5
  import {ResponsivePaddingProps} from '../../primitives/types'
6
6
  import {useLayer} from '../../utils'
7
- import {_getFocusableElements, _sortElements} from './helpers'
8
7
  import {MenuContext, MenuContextValue} from './menuContext'
8
+ import {useMenuController} from './useMenuController'
9
9
 
10
10
  /**
11
11
  * @public
@@ -39,7 +39,7 @@ const Root = styled(Box)`
39
39
  */
40
40
  export const Menu = forwardRef(function Menu(
41
41
  props: MenuProps & Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'height' | 'role' | 'tabIndex'>,
42
- ref
42
+ ref: React.ForwardedRef<HTMLDivElement>
43
43
  ) {
44
44
  const {
45
45
  children,
@@ -60,221 +60,35 @@ export const Menu = forwardRef(function Menu(
60
60
  ...restProps
61
61
  } = props
62
62
 
63
+ const forwardedRef = useForwardedRef(ref)
64
+
63
65
  const {isTopLayer} = useLayer()
64
- const [rootElement, setRootElement] = useState<HTMLDivElement | null>(null)
65
- const elementsRef = useRef<HTMLElement[]>([])
66
- const [activeIndex, setActiveIndex] = useState(-1)
67
- const activeIndexRef = useRef(activeIndex)
68
- const activeElement = elementsRef.current[activeIndex] || null
69
- const activeElementRef = useRef<HTMLElement | null>(activeElement)
70
- const mounted = Boolean(rootElement)
71
66
 
72
- const setRef = useCallback(
67
+ const {
68
+ activeElement,
69
+ activeIndex,
70
+ handleItemMouseEnter,
71
+ handleItemMouseLeave,
72
+ handleKeyDown,
73
+ mount,
74
+ rootElement,
75
+ setRootElement,
76
+ } = useMenuController({onKeyDown, originElement, shouldFocus})
77
+
78
+ const handleRefChange = useCallback(
73
79
  (el: HTMLDivElement | null) => {
74
80
  setRootElement(el)
75
- if (typeof ref === 'function') ref(el)
76
- else if (ref) ref.current = el
77
- },
78
- [ref]
79
- )
80
-
81
- const mount = useCallback(
82
- (element: HTMLElement | null, selected?: boolean): (() => void) => {
83
- if (!element) return () => undefined
84
-
85
- if (elementsRef.current.indexOf(element) === -1) {
86
- elementsRef.current.push(element)
87
- _sortElements(rootElement, elementsRef.current)
88
- }
89
-
90
- if (selected) {
91
- const selectedIndex = elementsRef.current.indexOf(element)
92
-
93
- setActiveIndex(selectedIndex)
94
- activeIndexRef.current = selectedIndex
95
- }
96
-
97
- return () => {
98
- const idx = elementsRef.current.indexOf(element)
99
-
100
- if (idx > -1) {
101
- elementsRef.current.splice(idx, 1)
102
- }
103
- }
104
- },
105
- [rootElement]
106
- )
107
-
108
- const handleKeyDown = useCallback(
109
- (event: React.KeyboardEvent<HTMLDivElement>) => {
110
- // Move focus to the element that opened the menu before handling the `Tab` press
111
- if (event.key === 'Tab') {
112
- if (originElement) {
113
- originElement.focus()
114
- }
115
-
116
- return
117
- }
118
-
119
- // Move focus to the first focusable menuitem
120
- if (event.key === 'Home') {
121
- event.preventDefault()
122
- event.stopPropagation()
123
-
124
- const focusableElements = _getFocusableElements(elementsRef.current)
125
- const el = focusableElements[0]
126
-
127
- if (!el) return
128
-
129
- const currentIndex = elementsRef.current.indexOf(el)
130
-
131
- setActiveIndex(currentIndex)
132
- activeIndexRef.current = currentIndex
133
-
134
- return
135
- }
136
-
137
- // Move focus to the last focusable menuitem
138
- if (event.key === 'End') {
139
- event.preventDefault()
140
- event.stopPropagation()
141
-
142
- const focusableElements = _getFocusableElements(elementsRef.current)
143
- const el = focusableElements[focusableElements.length - 1]
144
-
145
- if (!el) return
146
-
147
- const currentIndex = elementsRef.current.indexOf(el)
148
-
149
- setActiveIndex(currentIndex)
150
- activeIndexRef.current = currentIndex
151
-
152
- return
153
- }
154
-
155
- if (event.key === 'ArrowUp') {
156
- event.preventDefault()
157
- event.stopPropagation()
158
-
159
- const focusableElements = _getFocusableElements(elementsRef.current)
160
- const focusableLen = focusableElements.length
161
-
162
- if (focusableLen === 0) return
163
-
164
- const focusedElement = elementsRef.current[activeIndex]
165
-
166
- let focusedIndex = focusableElements.indexOf(focusedElement)
167
-
168
- focusedIndex = (focusedIndex - 1 + focusableLen) % focusableLen
169
-
170
- const el = focusableElements[focusedIndex]
171
- const currentIndex = elementsRef.current.indexOf(el)
172
-
173
- setActiveIndex(currentIndex)
174
- activeIndexRef.current = currentIndex
175
-
176
- return
177
- }
178
-
179
- if (event.key === 'ArrowDown') {
180
- event.preventDefault()
181
- event.stopPropagation()
182
-
183
- const focusableElements = _getFocusableElements(elementsRef.current)
184
- const focusableLen = focusableElements.length
185
-
186
- if (focusableLen === 0) return
187
-
188
- const focusedElement = elementsRef.current[activeIndex]
189
-
190
- let focusedIndex = focusableElements.indexOf(focusedElement)
191
-
192
- focusedIndex = (focusedIndex + 1) % focusableLen
193
-
194
- const el = focusableElements[focusedIndex]
195
- const currentIndex = elementsRef.current.indexOf(el)
196
-
197
- setActiveIndex(currentIndex)
198
- activeIndexRef.current = currentIndex
199
-
200
- return
201
- }
202
-
203
- if (onKeyDown) {
204
- onKeyDown(event)
205
- }
81
+ forwardedRef.current = el
206
82
  },
207
- [activeIndex, onKeyDown, originElement]
83
+ [forwardedRef, setRootElement]
208
84
  )
209
85
 
210
- const handleItemMouseEnter = useCallback((event: React.MouseEvent<HTMLElement>) => {
211
- const element = event.currentTarget
212
- const currentIndex = elementsRef.current.indexOf(element)
213
-
214
- setActiveIndex(currentIndex)
215
- activeIndexRef.current = currentIndex
216
- }, [])
217
-
218
- const handleItemMouseLeave = useCallback(() => {
219
- rootElement?.focus()
220
- setActiveIndex(-1)
221
- activeIndexRef.current = -1
222
- }, [rootElement])
223
-
224
86
  // Trigger `onItemSelect` when active index changes
225
87
  useEffect(() => {
226
88
  if (onItemSelect) onItemSelect(activeIndex)
227
89
  }, [activeIndex, onItemSelect])
228
90
 
229
- useEffect(() => {
230
- activeElementRef.current = activeElement
231
- }, [activeElement])
232
-
233
- // Set focus on the currently active element
234
- useEffect(() => {
235
- if (!mounted) return
236
-
237
- const rafId = window.requestAnimationFrame(() => {
238
- const _activeIndex = activeIndexRef.current
239
-
240
- if (_activeIndex === -1) {
241
- if (shouldFocus === 'first') {
242
- const focusableElements = _getFocusableElements(elementsRef.current)
243
- const el = focusableElements[0]
244
-
245
- if (el) {
246
- const currentIndex = elementsRef.current.indexOf(el)
247
-
248
- setActiveIndex(currentIndex)
249
- activeIndexRef.current = currentIndex
250
- }
251
- }
252
-
253
- if (shouldFocus === 'last') {
254
- const focusableElements = _getFocusableElements(elementsRef.current)
255
- const el = focusableElements[focusableElements.length - 1]
256
-
257
- if (el) {
258
- const currentIndex = elementsRef.current.indexOf(el)
259
-
260
- setActiveIndex(currentIndex)
261
- activeIndexRef.current = currentIndex
262
- }
263
- }
264
-
265
- return
266
- }
267
-
268
- const element = elementsRef.current[_activeIndex] || null
269
-
270
- element?.focus()
271
- })
272
-
273
- return () => {
274
- window.cancelAnimationFrame(rafId)
275
- }
276
- }, [activeIndex, mounted, shouldFocus])
277
-
91
+ // Close menu when clicking outside
278
92
  useClickOutside(
279
93
  useCallback(
280
94
  (event) => isTopLayer && onClickOutside && onClickOutside(event),
@@ -283,6 +97,7 @@ export const Menu = forwardRef(function Menu(
283
97
  [rootElement]
284
98
  )
285
99
 
100
+ // Close menu when pressing Escape
286
101
  useGlobalKeyDown(
287
102
  useCallback(
288
103
  (event) => {
@@ -297,6 +112,7 @@ export const Menu = forwardRef(function Menu(
297
112
  )
298
113
  )
299
114
 
115
+ // Register root element (for nested menus)
300
116
  useEffect(() => {
301
117
  if (!rootElement || !registerElement) return
302
118
 
@@ -311,9 +127,9 @@ export const Menu = forwardRef(function Menu(
311
127
  mount,
312
128
  onClickOutside,
313
129
  onEscape,
314
- onMouseEnter: handleItemMouseEnter,
315
- onMouseLeave: handleItemMouseLeave,
316
130
  onItemClick,
131
+ onItemMouseEnter: handleItemMouseEnter,
132
+ onItemMouseLeave: handleItemMouseLeave,
317
133
  registerElement,
318
134
  }),
319
135
  [
@@ -336,7 +152,7 @@ export const Menu = forwardRef(function Menu(
336
152
  {...restProps}
337
153
  onKeyDown={handleKeyDown}
338
154
  padding={padding}
339
- ref={setRef}
155
+ ref={handleRefChange}
340
156
  role="menu"
341
157
  tabIndex={-1}
342
158
  >
@@ -9,8 +9,8 @@ export interface MenuContextValue {
9
9
  onClickOutside?: (event: MouseEvent) => void
10
10
  onEscape?: () => void
11
11
  onItemClick?: () => void
12
- onMouseEnter: (event: React.MouseEvent<HTMLElement>) => void
13
- onMouseLeave: (event: React.MouseEvent<HTMLElement>) => void
12
+ onItemMouseEnter: (event: React.MouseEvent<HTMLElement>) => void
13
+ onItemMouseLeave: (event: React.MouseEvent<HTMLElement>) => void
14
14
  registerElement?: (el: HTMLElement) => () => void
15
15
  }
16
16