@sanity/visual-editing
Version:
[](https://npm-stat.com/charts.html?package=@sanity/visual-editing) [](https://
1 lines • 15.3 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../../src/overlay-components/components/UnionInsertMenuOverlay.tsx","../../src/overlay-components/defineOverlayComponent.ts","../../src/overlay-components/defineOverlayComponents.ts","../../src/overlay-components/defineOverlayPlugin.ts"],"sourcesContent":["import {AddIcon} from '@sanity/icons'\nimport type {SchemaNode, SchemaUnionNode} from '@sanity/presentation-comlink'\nimport type {SchemaType} from '@sanity/types'\nimport {Button, Flex} from '@sanity/ui/_visual-editing'\nimport {\n useCallback,\n useRef,\n useState,\n type FunctionComponent,\n type HTMLProps,\n type MouseEvent,\n} from 'react'\nimport {styled} from 'styled-components'\nimport {useDocuments} from '../../react/useDocuments'\nimport type {ElementNode, OverlayComponent} from '../../types'\nimport {useTelemetry} from '../../ui/telemetry/useTelemetry'\nimport {getArrayInsertPatches} from '../../util/mutations'\nimport {InsertMenuPopover} from './InsertMenu'\n\nconst AddButton = styled(Button)`\n position: relative;\n transform: var(--add-button-position);\n\n --add-button-position: translateY(0);\n [data-position='top'] & {\n --add-button-position: translateY(-50%);\n }\n [data-position='right'] & {\n --add-button-position: translateX(50%);\n }\n [data-position='bottom'] & {\n --add-button-position: translateY(50%);\n }\n [data-position='left'] & {\n --add-button-position: translateX(-50%);\n }\n`\nconst HoverAreaRoot = styled(Flex)`\n pointer-events: all;\n height: var(--hover-area-height);\n width: var(--hover-area-width);\n\n --hover-area-height: 100%;\n --hover-area-width: 100%;\n &[data-position='top'],\n &[data-position='bottom'] {\n --hover-area-height: 48px;\n }\n &[data-position='right'],\n &[data-position='left'] {\n --hover-area-width: 48px;\n }\n`\n\nconst HoverArea: FunctionComponent<{\n element: ElementNode\n hoverAreaExtent: HTMLProps<HTMLDivElement>['height' | 'width']\n node: SchemaUnionNode\n onAddUnion: (insertPosition: 'before' | 'after', name: string) => void\n position: 'top' | 'right' | 'bottom' | 'left'\n}> = (props) => {\n const {element, hoverAreaExtent, node, onAddUnion, position} = props\n const [showButton, setShowButton] = useState(false)\n const onEnter = useCallback(() => {\n setShowButton(true)\n }, [])\n const onLeave = useCallback(() => {\n setShowButton(false)\n }, [])\n const ref = useRef<HTMLDivElement | null>(null)\n\n const sendTelemetry = useTelemetry()\n\n // This function clones and dispatches MouseEvents so that they can be handled\n // by the underlying element. This is useful because we want to handle hover\n // events on the overlay element to display the add button, but let the\n // underlying element handle click events, drag and drop, etc.\n const relayEventToElement = useCallback(\n (event: MouseEvent<HTMLDivElement>) => {\n if (event.target === ref.current) {\n const newEvent = new MouseEvent(event.type, {\n ...event.nativeEvent,\n bubbles: true,\n cancelable: true,\n })\n element.dispatchEvent(newEvent)\n }\n },\n [element],\n )\n\n // The element that the popover containing the InsertMenu will be positioned\n // relative to (in this case, the AddButton).\n const [popoverReferenceElement, setPopoverReferenceElement] = useState<HTMLElement | null>(null)\n\n const [menuVisible, setMenuVisible] = useState(false)\n\n const dismissPortal = useCallback(() => {\n setMenuVisible(false)\n setShowButton(false)\n }, [])\n\n const onSelect = useCallback(\n (schemaType: SchemaType) => {\n setMenuVisible(false)\n const insertPosition = position === 'top' || position === 'left' ? 'before' : 'after'\n onAddUnion(insertPosition, schemaType.name)\n\n sendTelemetry('Visual Editing Insert Menu Item Inserted', null)\n },\n [onAddUnion, position, sendTelemetry],\n )\n\n const align = position === 'top' ? 'flex-start' : position === 'bottom' ? 'flex-end' : 'center'\n const justify = position === 'left' ? 'flex-start' : position === 'right' ? 'flex-end' : 'center'\n const blockDirection = position === 'top' || position === 'bottom' ? 'height' : 'width'\n\n return (\n <HoverAreaRoot\n align={align}\n data-position={position}\n data-sanity-overlay-element\n justify={justify}\n onClick={relayEventToElement}\n onContextMenu={relayEventToElement}\n onMouseDown={relayEventToElement}\n onMouseEnter={onEnter}\n onMouseLeave={onLeave}\n onMouseUp={relayEventToElement}\n ref={ref}\n style={{\n [blockDirection]: hoverAreaExtent,\n }}\n >\n {(showButton || menuVisible) && (\n <AddButton\n ref={setPopoverReferenceElement}\n icon={AddIcon}\n mode={'ghost'}\n onClick={() => setMenuVisible((visible) => !visible)}\n radius={'full'}\n selected={menuVisible}\n />\n )}\n {menuVisible && popoverReferenceElement && (\n <InsertMenuPopover\n node={node}\n onDismiss={dismissPortal}\n referenceElement={popoverReferenceElement}\n onSelect={onSelect}\n />\n )}\n </HoverAreaRoot>\n )\n}\n\nexport const UnionInsertMenuOverlay: OverlayComponent<\n {\n direction?: 'horizontal' | 'vertical'\n hoverAreaExtent?: HTMLProps<HTMLDivElement>['height' | 'width']\n },\n SchemaUnionNode<SchemaNode>\n> = (props) => {\n const {direction = 'vertical', element, hoverAreaExtent, node, parent} = props\n\n const {getDocument} = useDocuments()\n\n const onAddUnion = useCallback(\n (insertPosition: 'before' | 'after', name: string) => {\n const doc = getDocument(node.id)\n const patches = getArrayInsertPatches(node, name, insertPosition)\n doc.patch(patches)\n },\n [getDocument, node],\n )\n\n if (!parent) return null\n\n return (\n <Flex\n height=\"fill\"\n width=\"fill\"\n direction={direction === 'horizontal' ? 'row' : 'column'}\n justify=\"space-between\"\n >\n <HoverArea\n element={element}\n hoverAreaExtent={hoverAreaExtent}\n node={parent}\n onAddUnion={onAddUnion}\n position={direction === 'horizontal' ? 'left' : 'top'}\n />\n <HoverArea\n element={element}\n hoverAreaExtent={hoverAreaExtent}\n node={parent}\n onAddUnion={onAddUnion}\n position={direction === 'horizontal' ? 'right' : 'bottom'}\n />\n </Flex>\n )\n}\n\nexport default UnionInsertMenuOverlay\n","import type {ComponentProps} from 'react'\nimport type {OverlayComponent, OverlayComponentProps} from '../types'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function defineOverlayComponent<T extends OverlayComponent<Record<string, unknown>, any>>(\n component: T,\n props?: Omit<ComponentProps<T>, keyof OverlayComponentProps>,\n): {component: T; props: typeof props} {\n return {\n component: component,\n props: props,\n }\n}\n","import type {OverlayComponent, OverlayComponentResolver} from '../types'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function defineOverlayComponents<T extends OverlayComponent>(\n resolver: OverlayComponentResolver<T>,\n): typeof resolver {\n return resolver\n}\n","import type {OverlayComponentResolverContext, OverlayPluginDefinition} from '../types'\n\n/**\n * @public\n * Helper type to check if an object has required keys\n */\nexport type HasRequiredKeys<T> = Record<string, never> extends T ? false : true\n\n/**\n * @public\n */\nexport type OverlayPluginUserFnConfigOptions<O extends Record<string, unknown>> =\n HasRequiredKeys<O> extends true ? {options: O} : {options?: O}\n\n/**\n * @public\n */\nexport type OverlayPluginUserFnConfig<O extends Record<string, unknown>> = {\n guard?: OverlayPluginDefinition['guard']\n} & OverlayPluginUserFnConfigOptions<O>\n\n/**\n * @public\n */\nexport type OverlayPluginUserFn<O extends Record<string, unknown>> =\n HasRequiredKeys<O> extends true\n ? (config: OverlayPluginUserFnConfig<O>) => OverlayPluginDefinition\n : (config?: OverlayPluginUserFnConfig<O>) => OverlayPluginDefinition\n\n/**\n * @public\n */\nexport type OverlayPluginDefineFn<O extends Record<string, unknown>> = (\n options: O,\n) => OverlayPluginDefinition\n\n/**\n * @public\n * Define an overlay plugin with conditional options parameter.\n * Adds a guard that combines the user-provided guard with the plugin's guard.\n */\nexport function defineOverlayPlugin<O extends Record<string, unknown> = Record<string, never>>(\n pluginDefinitionFn: OverlayPluginDefineFn<O>,\n): OverlayPluginUserFn<O> {\n return ((config: Parameters<OverlayPluginUserFn<O>>[0] | undefined) => {\n const {guard: pluginGuard, ...pluginDefinition} = pluginDefinitionFn(\n config?.options ?? ({} as O),\n )\n return {\n ...pluginDefinition,\n guard: (context: OverlayComponentResolverContext) => {\n const pluginGuardResult = pluginGuard?.(context)\n\n if (pluginGuardResult === false) {\n return false\n }\n\n return config?.guard?.(context) ?? true\n },\n }\n }) as OverlayPluginUserFn<O>\n}\n"],"names":["AddButton","styled","Button","HoverAreaRoot","Flex","HoverArea","props","$","_c","element","hoverAreaExtent","node","onAddUnion","position","showButton","setShowButton","useState","t0","Symbol","for","onEnter","t1","onLeave","ref","useRef","sendTelemetry","useTelemetry","t2","event","target","current","newEvent","MouseEvent","type","nativeEvent","bubbles","cancelable","dispatchEvent","relayEventToElement","popoverReferenceElement","setPopoverReferenceElement","menuVisible","setMenuVisible","t3","dismissPortal","t4","schemaType","name","onSelect","align","justify","blockDirection","t5","t6","jsx","AddIcon","_temp","t7","InsertMenuPopover","t8","jsxs","UnionInsertMenuOverlay","direction","parent","undefined","getDocument","useDocuments","insertPosition","doc","id","patches","getArrayInsertPatches","patch","visible","defineOverlayComponent","component","defineOverlayComponents","resolver","defineOverlayPlugin","pluginDefinitionFn","config","guard","pluginGuard","pluginDefinition","options","context"],"mappings":"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"}