UNPKG

sanity

Version:

Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches

1,166 lines (1,152 loc) • 1.65 MB
import { jsx, jsxs, Fragment } from "react/jsx-runtime"; import { createContext, useContext, useRef, useLayoutEffect, useState, useMemo, memo, useCallback, forwardRef, useEffect, createElement, useId, useImperativeHandle, cloneElement, Fragment as Fragment$1, useSyncExternalStore, Suspense, Component, createRef, startTransition, PureComponent, isValidElement, Children, useReducer } from "react"; import flatten$1 from "lodash/flatten.js"; import { useMemoObservable, useObservableCallback } from "react-rx"; import { of, concat, map as map$1, from, catchError as catchError$1, Subject, merge, fromEvent, defer, throwError, timer, NEVER, empty, Observable, EMPTY as EMPTY$3, combineLatest, bufferTime, mergeMap as mergeMap$1, switchMap as switchMap$1, finalize, share, firstValueFrom, filter as filter$1, lastValueFrom, isObservable, BehaviorSubject, asyncScheduler, partition as partition$1, iif } from "rxjs"; import { switchMap, map, scan, distinctUntilChanged, catchError, shareReplay, filter, take, startWith, tap, mergeMapTo, takeUntil, mergeMap, first, concatMap, mergeAll, toArray as toArray$1, delay, reduce, share as share$1, publishReplay, refCount, withLatestFrom, groupBy as groupBy$1, throttleTime, last, distinct, skip, debounceTime, auditTime, switchMapTo, flatMap, debounce as debounce$1 } from "rxjs/operators"; import isEqual$1 from "lodash/isEqual.js"; import { ResizeObserver as ResizeObserver$1 } from "@juggle/resize-observer"; import createPubSub from "nano-pubsub"; import "lodash/throttle.js"; import isString$1 from "lodash/isString.js"; import { fromUrl } from "@sanity/bifur-client"; import { createClient } from "@sanity/client"; import { useLayer, useForwardedRef, Grid, rem, Box, Stack, Card, Spinner, Text as Text$1, Layer, Heading, Inline, Flex, Breadcrumbs, useClickOutside, Code, useTheme, MenuDivider, Menu, AvatarStack, Avatar, AvatarCounter, Badge, useToast, useGlobalKeyDown, useElementRect, TextSkeleton, Autocomplete, Checkbox as Checkbox$1, Switch as Switch$1, LayerProvider, TextInput as TextInput$1, ElementQuery, TabList, Select, TextArea, useElementSize, Skeleton, rgba, studioTheme, Container as Container$2, MenuItem as MenuItem$1, useBoundaryElement, BoundaryElementProvider, usePortal, PortalProvider, Portal, Button as Button$1, isHTMLElement, Radio, useMediaIndex, usePrefersDark, ThemeProvider, ErrorBoundary, ToastProvider, _responsive, useArrayProp } from "@sanity/ui"; import startCase from "lodash/startCase.js"; import { isValidElementType } from "react-is"; import { EllipsisHorizontalIcon, ChevronRightIcon, DocumentIcon, ImageIcon, ChevronDownIcon, ErrorOutlineIcon, ArrowDownIcon, ArrowRightIcon, RevertIcon, WarningOutlineIcon, InfoOutlineIcon, CheckmarkIcon, ToggleArrowRightIcon, BulbOutlineIcon, UnknownIcon, EditIcon, TrashIcon, CloseIcon, DotIcon, HelpCircleIcon, AccessDeniedIcon, SyncIcon, LaunchIcon, AddIcon, DragHandleIcon, UploadIcon, InsertAboveIcon, InsertBelowIcon, CopyIcon, CalendarIcon, ResetIcon, DownloadIcon, ReadOnlyIcon, BinaryDocumentIcon, SearchIcon, CropIcon, LinkIcon, BoldIcon, ItalicIcon, StrikethroughIcon, UnderlineIcon, CodeIcon, OlistIcon, UlistIcon, BlockElementIcon, InlineElementIcon, CollapseIcon, ExpandIcon, EyeOpenIcon, ChevronUpIcon, DocumentsIcon, CheckmarkCircleIcon, StringIcon, NumberIcon, BlockContentIcon, UndoIcon, ChevronLeftIcon, DesktopIcon, MoonIcon, SunIcon, ControlsIcon, ClockIcon, SpinnerIcon, ArrowLeftIcon, SortIcon, DoubleChevronRightIcon, Icon, BoltIcon, CogIcon, UsersIcon, LeaveIcon, MenuIcon } from "@sanity/icons"; import uniqueId from "lodash/uniqueId.js"; import styled, { css, keyframes, createGlobalStyle } from "styled-components"; import { T as Tooltip, B as Button, L as LocaleContext, P as Popover, M as MenuGroup, c as MenuItem, d as MenuButton, b as TooltipDelayGroupProvider, D as Dialog, i as LazyTextInput, f as DatePicker$1, g as getCalendarLabels, j as isValidDate$1, e as Tab, h as getJsonStream, u as useCurrentLocale, C as ConditionalWrapper, a as useLocale } from "./getJsonStream.js"; import { createMemoryHistory, createBrowserHistory } from "history"; import { createInstance } from "i18next"; import { useTranslation as useTranslation$1, I18nextProvider, initReactI18next } from "react-i18next"; import isPlainObject from "lodash/isPlainObject.js"; import { Schema } from "@sanity/schema"; import { DEFAULT_MAX_FIELD_DEPTH, validateSchema, groupProblems } from "@sanity/schema/_internal"; import cloneDeep from "lodash/cloneDeep.js"; import get from "lodash/get.js"; import { isIndexSegment, isKeySegment, isIndexTuple, isKeyedObject, isTypedObject, isPortableTextSpan, isPortableTextTextBlock, isObjectSchemaType, isArraySchemaType, isNumberSchemaType, isBooleanSchemaType, isStringSchemaType, isPrimitiveSchemaType, isCrossDatasetReferenceSchemaType, isReferenceSchemaType, isArrayOfObjectsSchemaType, isArrayOfBlocksSchemaType, isArrayOfPrimitivesSchemaType, isReference as isReference$1, isSlug, isTitledListValue, isImage, isCrossDatasetReference, isDeprecatedSchemaType } from "@sanity/types"; import * as legacyDateFormat from "@sanity/util/legacyDateFormat"; import { format, parse, DEFAULT_DATE_FORMAT, DEFAULT_TIME_FORMAT } from "@sanity/util/legacyDateFormat"; import memoize$1 from "lodash/memoize.js"; import { createClientConcurrencyLimiter } from "@sanity/util/client"; import { ConcurrencyLimiter } from "@sanity/util/concurrency-limiter"; import uniqBy from "lodash/uniqBy.js"; import DataLoader from "dataloader"; import * as PathUtils from "@sanity/util/paths"; import { toString, FOCUS_TERMINATOR, startsWith, isEqual as isEqual$2, trimLeft, pathFor, get as get$1 } from "@sanity/util/paths"; import deepCompare from "react-fast-compare"; import debounce from "lodash/debounce.js"; import { getTheme_v2, rgba as rgba$1, buildTheme } from "@sanity/ui/theme"; import sortBy from "lodash/sortBy.js"; import { useVirtualizer, defaultRangeExtractor, elementScroll } from "@tanstack/react-virtual"; import throttle from "lodash/throttle"; import { observableCallback } from "observable-callback"; import { usePortableTextEditor, PortableTextEditor, usePortableTextEditorSelection, PortableTextEditable } from "@sanity/portable-text-editor"; import { COLOR_HUES, hues, yellow, purple } from "@sanity/color"; import { parseISO, getMinutes, setMinutes, isValid, isSameDay, isSameMonth, isAfter, isBefore, getWeek, startOfMonth, eachWeekOfInterval, lastDayOfMonth, addDays, set as set$1, addMonths, startOfDay, endOfDay, format as format$1, parse as parse$2, startOfToday, sub, startOfMinute, endOfMinute, differenceInMonths, differenceInYears, differenceInWeeks, differenceInDays, differenceInHours, differenceInMinutes, differenceInSeconds } from "date-fns"; import omit from "lodash/omit.js"; import { cleanupEfficiency, makeDiff, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL, applyPatches, parsePatch } from "@sanity/diff-match-patch"; import orderBy from "lodash/orderBy.js"; import { getImageDimensions, isDefaultCrop, isDefaultHotspot, isImageSource, isFileSource } from "@sanity/asset-utils"; import imageUrlBuilder from "@sanity/image-url"; import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector"; import escapeRegExp$1 from "lodash/escapeRegExp.js"; import { motion, AnimatePresence } from "framer-motion"; import FocusLock from "react-focus-lock"; import uniq from "lodash/uniq.js"; import xor from "lodash/xor.js"; import { diffItem } from "sanity-diff-patch"; import shallowEquals from "shallow-equals"; import { IntentLink, useIntentLink, useRouter, useRouterState, RouteScope, useStateLink, StateLink, route, RouterProvider } from "sanity/router"; import { getDevicePixelRatio as getDevicePixelRatio$2 } from "use-device-pixel-ratio"; import classNames from "classnames"; import groupBy from "lodash/groupBy.js"; import scrollIntoView from "scroll-into-view-if-needed"; import compact from "lodash/compact.js"; import intersection from "lodash/intersection.js"; import keyBy from "lodash/keyBy.js"; import partition from "lodash/partition.js"; import toLower from "lodash/toLower.js"; import union from "lodash/union.js"; import words from "lodash/words.js"; import flow from "lodash/flow.js"; import trim from "lodash/trim.js"; import isFinite from "lodash/isFinite.js"; import { uuid } from "@sanity/uuid"; import { Mutation, BufferedDocument } from "@sanity/mutator"; import { reduce as reduce$1 } from "json-reduce"; import { exhaustMapWithTrailing } from "rxjs-exhaustmap-with-trailing"; import { resolveTypeName as resolveTypeName$1, randomKey as randomKey$1, isShallowEmptyObject, isDeepEmpty } from "@sanity/util/content"; import isEqual$3 from "lodash/isEqual"; import startCase$1 from "lodash/startCase"; import { renderToString } from "react-dom/server"; import intersection$1 from "lodash/intersection"; import isEmpty$1 from "lodash/isEmpty"; import debug$3 from "debug"; import getRandomValues from "get-random-values-esm"; import capitalize from "lodash/capitalize.js"; import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from "@dnd-kit/core"; import { restrictToHorizontalAxis, restrictToVerticalAxis } from "@dnd-kit/modifiers"; import { useSortable, SortableContext, sortableKeyboardCoordinates, horizontalListSortingStrategy, verticalListSortingStrategy } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; import speakingurl from "speakingurl"; import difference from "lodash/difference.js"; import { useTelemetry, TelemetryProvider } from "@sanity/telemetry/react"; import { defineEvent, createSessionId, createBatchedStore } from "@sanity/telemetry"; import { normalizeBlock } from "@sanity/block-tools"; import find from "lodash/find.js"; import "lodash/castArray.js"; import pick from "lodash/pick.js"; import identity from "lodash/identity.js"; import values from "lodash/values.js"; import assignWith from "lodash/assignWith.js"; import "polished"; import exif from "exif-component"; import { parse as parse$1, evaluate } from "groq-js"; import { refCountDelay } from "rxjs-etc/operators"; import { applyPatch as applyPatch$1, incremental } from "mendoza"; import { diffInput, wrap as wrap$1 } from "@sanity/diff"; import { nanoid } from "nanoid"; import sample from "lodash/sample.js"; import raf from "raf"; import { darken, lighten, hasBadContrast, readableColor } from "color2k"; import "react-dom/client"; import Refractor from "react-refractor"; import bash from "refractor/lang/bash"; import javascript from "refractor/lang/javascript"; import json from "refractor/lang/json"; import jsx2 from "refractor/lang/jsx"; import typescript from "refractor/lang/typescript"; import { PortableText as PortableText$1 } from "@portabletext/react"; import { SanityLogo as SanityLogo$1, SanityMonogram } from "@sanity/logos"; import { generateHelpUrl } from "@sanity/generate-help-url"; import { useHotModuleReload } from "use-hot-module-reload"; import arrify from "arrify"; import isHotkey from "is-hotkey"; import upperFirst from "lodash/upperFirst.js"; import isValidDate from "date-fns/isValid"; import range from "lodash/range.js"; import isObject from "lodash/isObject.js"; import findIndex$1 from "lodash/findIndex.js"; import clone from "lodash/clone.js"; const ConnectorContext = createContext({ isReviewChangesOpen: !1, onOpenReviewChanges: () => { }, onSetFocus: () => { } }); function createStore() { const reportedValues = /* @__PURE__ */ new Map(), { publish: publish2, subscribe } = createPubSub(), debouncedPublish = debounce(publish2, 10, { trailing: !0 }), read2 = () => Array.from(reportedValues.entries()); function add(id2, value) { reportedValues.has(id2), reportedValues.set(id2, value), debouncedPublish(read2()); } function update(id2, value) { reportedValues.has(id2), reportedValues.set(id2, value), debouncedPublish(read2()); } function remove2(id2) { reportedValues.has(id2), reportedValues.delete(id2), debouncedPublish(read2()); } return { add, remove: remove2, update, read: read2, subscribe }; } function isFunc(value) { return typeof value == "function"; } function read(value) { return isFunc(value) ? value() : value; } const noop$4 = () => { }; function createUseReporter(Context2) { return function(id2, value, isEqual2 = Object.is) { const { add, update, remove: remove2 } = useContext(Context2), previous = useRef(); useLayoutEffect(() => { if (id2 === null) return noop$4; const current = read(value); return add(id2, current), previous.current = current, () => { remove2(id2); }; }, [add, id2, remove2, value]), useLayoutEffect(() => { const current = read(value); typeof previous.current < "u" && !isEqual2(previous.current, current) && id2 !== null && update(id2, current), previous.current = current; }); }; } let didWarn = !1; const useReporterGuard = (id2) => { didWarn || console.warn( new Error( `No context provided for reporter. Make sure that the component calling "useReporter(${id2}, ...)", is wrapped in a <Tracker> element` ) ), didWarn = !0; }; function useReportedValueGuard() { return didWarn || console.warn( new Error( 'No context provided for reporter. Make sure that the component calling "useReportedValues()", is wrapped inside a <Tracker> element' ) ), didWarn = !0, []; } const useSubscribeGuard = () => (didWarn || console.warn( new Error( 'No context provided for reporter. Make sure that the component calling "useReportedValues()", is wrapped inside a <Tracker> element' ) ), didWarn = !0, () => { }), DEFAULT_CONTEXT = { add: useReporterGuard, update: useReporterGuard, remove: useReporterGuard, subscribe: useSubscribeGuard, read: useReportedValueGuard }; let id$1 = 0; const getNextId = () => ++id$1; function createTrackerScope() { const Context2 = createContext(DEFAULT_CONTEXT); function useReportedValues2() { const context = useContext(Context2), [values2, setValues] = useState(context.read()); return useLayoutEffect(() => (setValues(context.read()), context.subscribe(setValues)), [context]), values2; } function Tracker2(props2) { const store = useMemo(() => createStore(), []); return /* @__PURE__ */ jsx(Context2.Provider, { value: store, children: props2.children }); } const useReporter2 = createUseReporter(Context2); return { Tracker: Tracker2, useReportedValues: useReportedValues2, useReporter: useReporter2, useAutoIdReporter: (value, isEqual2 = Object.is) => useReporter2(`element-${useRef(getNextId()).current}`, value, isEqual2) }; } const CORNER_RADIUS = 4, INTERACTIVE_STROKE_WIDTH = 16, CONNECTOR_MARGIN = 8, ARROW_MARGIN_X = 8, ARROW_MARGIN_Y = 2, ARROW_SIZE = 4, ARROW_THRESHOLD = 12, STROKE_WIDTH$2 = 1, DEBUG$1 = !1, DEBUG_LAYER_BOUNDS = !1, trackerScope = createTrackerScope(), Tracker$1 = trackerScope.Tracker, useReportedValues$1 = trackerScope.useReportedValues, useReporter$1 = trackerScope.useReporter; function useUnique(value) { const valueRef = useRef(value); return isEqual$1(valueRef.current, value) || (valueRef.current = value), valueRef.current; } function createHookFromObservableFactory(observableFactory, initialValue) { const initialLoadingTuple = [initialValue, !0], initialResult = { type: "tuple", tuple: initialLoadingTuple }; return function(_arg) { const memoArg = useUnique(_arg), result = useMemoObservable( () => of(memoArg).pipe( switchMap( (arg) => concat( of({ type: "loading" }), observableFactory(arg).pipe(map((value) => ({ type: "value", value }))) ) ), scan(([prevValue], next) => next.type === "loading" ? [prevValue, !0] : [next.value, !1], initialLoadingTuple), distinctUntilChanged(([prevValue, prevIsLoading], [nextValue, nextIsLoading]) => !(prevValue !== nextValue || prevIsLoading !== nextIsLoading)), map((tuple) => ({ type: "tuple", tuple })), catchError((error) => of({ type: "error", error })) ), [memoArg], initialResult ); if (result.type === "error") throw result.error; return result.tuple; }; } function isNonNullable$2(value) { return value != null; } const DRAFTS_FOLDER = "drafts", DRAFTS_PREFIX = `${DRAFTS_FOLDER}.`; function documentIdEquals(documentId, equalsDocumentId) { return getPublishedId(documentId) === getPublishedId(equalsDocumentId); } function isDraft(document2) { return isDraftId(document2._id); } function isDraftId(id2) { return id2.startsWith(DRAFTS_PREFIX); } function getIdPair(id2) { return { draftId: getDraftId(id2), publishedId: getPublishedId(id2) }; } function isPublishedId(id2) { return !isDraftId(id2); } function getDraftId(id2) { return isDraftId(id2) ? id2 : DRAFTS_PREFIX + id2; } function getPublishedId(id2) { return isDraftId(id2) ? id2.slice(DRAFTS_PREFIX.length) : id2; } function createDraftFrom(document2) { return { ...document2, _id: getDraftId(document2._id) }; } function newDraftFrom(document2) { return { ...document2, _id: DRAFTS_PREFIX }; } function createPublishedFrom(document2) { return { ...document2, _id: getPublishedId(document2._id) }; } function collate(documents) { const byId = documents.reduce((res, doc) => { const publishedId = getPublishedId(doc._id); let entry = res.get(publishedId); return entry || (entry = { id: publishedId, type: doc._type, published: void 0, draft: void 0 }, res.set(publishedId, entry)), entry[publishedId === doc._id ? "published" : "draft"] = doc, res; }, /* @__PURE__ */ new Map()); return Array.from(byId.values()); } function removeDupes(documents) { return collate(documents).map((entry) => entry.draft || entry.published).filter(isNonNullable$2); } const EMPTY_OBJECT = Object.freeze({}), EMPTY_ARRAY$b = Object.freeze([]); function getGlobalScope() { if (typeof globalThis < "u") return globalThis; if (typeof window < "u") return window; if (typeof self < "u") return self; if (typeof global < "u") return global; throw new Error("@sanity/ui: could not locate global scope"); } const globalScope = getGlobalScope(); function isRecord$4(value) { return !!value && typeof value == "object" && !Array.isArray(value); } function isString(value) { return typeof value == "string"; } const ResizeObserver = typeof document == "object" && typeof window == "object" && window.ResizeObserver ? window.ResizeObserver : ResizeObserver$1, createSharedResizeObserver = () => { const event = createPubSub(), resizeObserver2 = new ResizeObserver( (entries) => event.publish(entries) ); return { observe: (element, observer, options) => { const unsubscribe = event.subscribe((entries) => { const entry = entries.find((e) => e.target === element); entry && observer(entry); }); return resizeObserver2.observe(element, options), () => { unsubscribe(), resizeObserver2.unobserve(element); }; }, unobserve: (element) => resizeObserver2.unobserve(element) }; }, resizeObserver = createSharedResizeObserver(), GROQ_KEYWORDS = ["match", "in", "asc", "desc", "true", "false", "null"], VALID_FIELD = /^[a-zA-Z_][a-zA-Z0-9_]*$/, fieldNeedsEscape = (fieldName) => !VALID_FIELD.test(fieldName) || GROQ_KEYWORDS.includes(fieldName), escapeField = (fieldName) => `["${fieldName}"]`, escapeFirst = (fieldName) => `@${escapeField(fieldName)}`, isEmptyArray = (value) => Array.isArray(value) && value.length === 0, joinPath = (pathArray) => { let path = ""; for (let i = 0; i < pathArray.length; i++) { const pathSegment = pathArray[i]; if (isEmptyArray(pathSegment)) { path += "[]"; continue; } if (typeof pathSegment == "number") { path += `[${pathSegment}]`; continue; } const isFirst = i === 0; fieldNeedsEscape(pathSegment) ? path = isFirst ? escapeFirst(pathSegment) : `${path}${escapeField(pathSegment)}` : path = isFirst ? pathSegment : `${path}.${pathSegment}`; } return path; }, supportsTouch = isTouchDevice$1(); function isTouchDevice$1() { return typeof window > "u" ? !1 : "ontouchstart" in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; } const segmenter = typeof Intl == "object" && "Segmenter" in Intl ? new Intl.Segmenter() : void 0; function sliceString(str, start, end) { if (end < start) throw new Error( "End must be greater than start, use `String.prototype.slice()` for negative values" ); if (!segmenter) return str.slice(start, end); let i = 0, sliced = ""; for (const value of segmenter.segment(str)) { if (i === end) return sliced; sliced += value.segment, i++; } return sliced; } function truncateString(str, maxLength) { const truncated = sliceString(str, 0, maxLength); return truncated === str ? truncated : `${truncated}\u2026`; } const LOADING_STATE = { isLoading: !0, value: void 0, error: null }; function useLoadable(value$, initialValue) { return useMemoObservable(() => value$.pipe(asLoadable()), [value$], typeof initialValue > "u" ? LOADING_STATE : { isLoading: !1, value: initialValue, error: null }); } function asLoadable() { return (value$) => value$.pipe( map((value) => ({ isLoading: !1, value, error: null })), catchError( (error) => of({ isLoading: !1, value: void 0, error }) ) ); } function userHasRole(user, roleId) { return user !== null && user.roles.some((role) => role.name === roleId); } var _a$1; const DEBUG_MODE$2 = typeof process > "u" ? !1 : (_a$1 = process == null ? void 0 : process.env) == null ? void 0 : _a$1.SANITY_STUDIO_DEBUG_I18N, DEBUG_I18N = !!DEBUG_MODE$2, debugWrappers = { reverse: (str) => `\u202E${str}`, triangles: (str) => `\u25E4 ${str} \u25E2` }; function maybeWrapT(t2) { const wrapper = DEBUG_MODE$2 === "reverse" || DEBUG_MODE$2 === "triangles" ? debugWrappers[DEBUG_MODE$2] : null; return wrapper ? (...args) => wrapper(t2(...args)) : t2; } const translationOptionOverrides = { // We're manually forcing a re-render with the locale key in the LocaleProvider, // so we don't need to bind to the i18n instance for language change events. bindI18n: !1 }; function useTranslation(ns, options) { const { t: t2 } = useTranslation$1( ns, options ? { keyPrefix: options.keyPrefix, lng: options.lng, ...translationOptionOverrides } : translationOptionOverrides ); return { t: maybeWrapT(t2) }; } const animationSpeed = 250, ChangeBarWrapper$1 = styled.div( ({ $changed, $disabled, $hasFocus, $isReviewChangeOpen }) => $disabled ? css` ${ChangeBarMarker}:after { display: none; } ` : css` --change-bar-offset: 4px; display: flex; position: relative; ${ChangeBarMarker}:after { opacity: 0.5; } @media (hover: hover) { &:hover { z-index: 10; ${ChangeBarMarker}:after { opacity: 1; } } } /* hide when field is not changed */ ${$hasFocus && css` ${ChangeBarMarker}:after { opacity: 1; } `} /* hide when field is not changed */ ${!$changed && css` ${ChangeBarMarker}:after { opacity: 0; pointer-events: none; } `} /* hide hover effect when review changes is open */ ${$isReviewChangeOpen && css` ${ChangeBarButton} { opacity: 0; } `} ` ), FieldWrapper = styled.div` flex-grow: 1; min-width: 0; `, ChangeBar = styled.div` position: relative; opacity: 1; transition: opacity 100ms; z-index: ${({ $zIndex }) => $zIndex}; `, ChangeBarMarker = styled.div((props2) => { const { media } = getTheme_v2(props2.theme); return css` position: absolute; top: -1px; left: var(--change-bar-offset); width: 1px; bottom: -1px; background-color: var(--card-bg-color); @media (min-width: ${media[0]}px) { display: unset; } &:after { content: ''; display: block; position: absolute; top: 1px; left: 0; width: 1px; bottom: 1px; background-color: var(--card-badge-caution-dot-color); border-radius: 0.5px; } `; }), ChangeBarButton = styled.button((props2) => { const { $withHoverEffect } = props2; return css` appearance: none; border: 0; outline: 0; display: block; padding: 0; background: transparent; opacity: 0; position: absolute; height: 100%; cursor: pointer; pointer-events: all; left: calc(-0.25rem + var(--change-bar-offset)); width: calc(1rem - 1px); transition: opacity ${animationSpeed}ms; &:focus { border: 0; outline: 0; } &:focus { border: 0; outline: 0; } ${$withHoverEffect && css` @media (hover: hover) { &:hover { opacity: 0.2; } } `} `; }); function ElementWithChangeBar(props2) { const { children, disabled, hasFocus, isChanged, withHoverEffect = !0 } = props2, { onOpenReviewChanges, isReviewChangesOpen } = useContext(ConnectorContext), { zIndex } = useLayer(), { t: t2 } = useTranslation(), changeBar = useMemo( () => disabled || !isChanged ? null : /* @__PURE__ */ jsxs(ChangeBar, { "data-testid": "change-bar", $zIndex: zIndex, children: [ /* @__PURE__ */ jsx(ChangeBarMarker, { "data-testid": "change-bar__marker" }), /* @__PURE__ */ jsx(Tooltip, { content: t2("changes.change-bar.aria-label"), portal: !0, children: /* @__PURE__ */ jsx( ChangeBarButton, { "aria-label": t2("changes.change-bar.aria-label"), "data-testid": "change-bar__button", onClick: isReviewChangesOpen ? void 0 : onOpenReviewChanges, tabIndex: -1, type: "button", $withHoverEffect: withHoverEffect } ) }) ] }), [disabled, isChanged, isReviewChangesOpen, onOpenReviewChanges, t2, withHoverEffect, zIndex] ); return /* @__PURE__ */ jsxs( ChangeBarWrapper$1, { "data-testid": "change-bar-wrapper", $changed: isChanged, $disabled: disabled, $hasFocus: hasFocus, $isReviewChangeOpen: isReviewChangesOpen, children: [ /* @__PURE__ */ jsx(FieldWrapper, { "data-testid": "change-bar__field-wrapper", children }), changeBar ] } ); } const ChangeBarWrapper = memo(function(props2) { const { children, disabled, hasFocus, isChanged, onMouseEnter: onMouseEnterProp, onMouseLeave: onMouseLeaveProp, path = EMPTY_ARRAY$b, withHoverEffect, ...restProps } = props2, layer = useLayer(), [hasHover, setHover] = useState(!1), onMouseEnter = useCallback( (event) => { onMouseEnterProp == null || onMouseEnterProp(event), setHover(!0); }, [onMouseEnterProp] ), onMouseLeave = useCallback( (event) => { onMouseLeaveProp == null || onMouseLeaveProp(event), setHover(!1); }, [onMouseLeaveProp] ), ref = useRef(null); return useReporter$1( disabled ? null : `field-${PathUtils.toString(path)}`, () => ({ element: ref.current, path, isChanged, hasFocus, hasHover, zIndex: layer.zIndex }), deepCompare // note: deepCompare should be ok here since we're not comparing deep values ), /* @__PURE__ */ jsx("div", { ...restProps, ref, onMouseEnter, onMouseLeave, children: /* @__PURE__ */ jsx( ElementWithChangeBar, { hasFocus, isChanged, disabled, withHoverEffect, children } ) }); }); function ChangeIndicator(props2) { const { children, hasFocus, isChanged, path, withHoverEffect, ...restProps } = props2; return /* @__PURE__ */ jsx( ChangeBarWrapper, { ...restProps, path, hasFocus, isChanged, withHoverEffect, children } ); } const ChangeIndicatorContext = createContext({ path: [], fullPath: [], focusPath: [], isChanged: !1 }), ScrollContext = createContext(null), noop$3 = () => { }, ScrollContainer = forwardRef(function(props2, ref) { const { as = "div", onScroll, ...rest } = props2, forwardedRef = useForwardedRef(ref), parentContext = useContext(ScrollContext), childContext = useMemo(() => createPubSub(), []); return useEffect(() => onScroll ? childContext.subscribe(onScroll) : noop$3, [childContext, onScroll]), useEffect(() => parentContext ? childContext.subscribe(parentContext.publish) : noop$3, [parentContext, childContext]), useEffect(() => { const handleScroll = (event) => { childContext.publish(event); }, el = forwardedRef.current; if (el) return el.addEventListener("scroll", handleScroll, { passive: !0, capture: !0 }), () => { el.removeEventListener("scroll", handleScroll); }; }, [childContext, forwardedRef]), /* @__PURE__ */ jsx(ScrollContext.Provider, { value: childContext, children: createElement(as, { ref: forwardedRef, "data-testid": "scroll-container", ...rest }) }); }); function ClampedRect(props2) { const { bounds, ...rest } = props2, x = Math.max(bounds.left, props2.left), y = Math.max(props2.top, bounds.top), height = Math.max(0, props2.height - (y - props2.top)), width = Math.max(0, props2.width - (x - props2.left)); return /* @__PURE__ */ jsx("rect", { ...rest, x, y, height, width }); } styled.rect` stroke: #ccc; fill: none; pointer-events: none; stroke-linecap: round; `; const ConnectorPath = styled.path` fill: none; pointer-events: none; stroke-linejoin: round; stroke: var(--card-badge-caution-dot-color); `, InteractivePath = styled.path` fill: none; pointer-events: stroke; stroke: transparent; cursor: pointer; stroke-linecap: round; stroke-linejoin: round; opacity: 0; &:hover { opacity: 0.2; } `, RightBarWrapper = styled(ClampedRect)` stroke: none; pointer-events: none; fill: var(--card-badge-caution-dot-color); `; function arrowPath(x, y, dir) { return [ `M ${x - ARROW_SIZE} ${y - ARROW_SIZE * dir} `, `L ${x} ${y}`, `L ${x + ARROW_SIZE} ${y - ARROW_SIZE * dir}` ].join(""); } function moveTo(x, y) { return `M${x} ${y}`; } function lineTo(x, y) { return `L${x} ${y}`; } function join(strings, delim = "") { return strings.join(delim); } function quadCurve(x1, y1, x, y) { return `Q${x1} ${y1} ${x} ${y}`; } function generateConnectorPath(line) { const { from: from2, to } = line, { left: fromX, top: fromY } = from2, { left: toX, top: toY } = to, cmds = [], r1 = Math.min(CORNER_RADIUS, Math.abs(fromY - toY) / 2); return from2.isAbove ? cmds.push( moveTo(fromX + ARROW_MARGIN_X, fromY - ARROW_THRESHOLD + ARROW_MARGIN_Y), lineTo(fromX + ARROW_MARGIN_X, fromY - CORNER_RADIUS), quadCurve(fromX + ARROW_MARGIN_X, fromY, fromX + ARROW_MARGIN_X + CORNER_RADIUS, fromY) ) : from2.isBelow ? cmds.push( moveTo(fromX + ARROW_MARGIN_X, fromY + ARROW_THRESHOLD - ARROW_MARGIN_Y), lineTo(fromX + ARROW_MARGIN_X, fromY + CORNER_RADIUS), quadCurve(fromX + ARROW_MARGIN_X, fromY, fromX + ARROW_MARGIN_X + CORNER_RADIUS, fromY) ) : cmds.push(moveTo(fromX, fromY)), to.isAbove ? fromY < to.bounds.top ? cmds.push( lineTo(to.bounds.left - 8 - r1, fromY), quadCurve(to.bounds.left - 8, fromY, to.bounds.left - 8, fromY + r1), lineTo(to.bounds.left - 8, toY - r1), quadCurve(to.bounds.left - 8, toY, to.bounds.left - 8 + r1, toY), lineTo(to.bounds.left + ARROW_MARGIN_X - CORNER_RADIUS, toY), quadCurve( to.bounds.left + ARROW_MARGIN_X, toY, to.bounds.left + ARROW_MARGIN_X, toY - CORNER_RADIUS ), lineTo(to.bounds.left + ARROW_MARGIN_X, toY - ARROW_THRESHOLD + ARROW_MARGIN_Y) ) : cmds.push( lineTo(to.bounds.left + ARROW_MARGIN_X - CORNER_RADIUS, fromY), quadCurve( to.bounds.left + ARROW_MARGIN_X, fromY, to.bounds.left + ARROW_MARGIN_X, fromY - CORNER_RADIUS ), lineTo(to.bounds.left + ARROW_MARGIN_X, toY - ARROW_THRESHOLD + ARROW_MARGIN_Y) ) : to.isBelow ? fromY > to.bounds.top + to.bounds.height ? cmds.push( lineTo(to.bounds.left - ARROW_MARGIN_X - r1, fromY), quadCurve( to.bounds.left - ARROW_MARGIN_X, fromY, to.bounds.left - ARROW_MARGIN_X, fromY - r1 ), lineTo(to.bounds.left - ARROW_MARGIN_X, toY + r1), quadCurve(to.bounds.left - ARROW_MARGIN_X, toY, to.bounds.left - ARROW_MARGIN_X + r1, toY), lineTo(to.bounds.left + ARROW_MARGIN_X - CORNER_RADIUS, toY), quadCurve( to.bounds.left + ARROW_MARGIN_X, toY, to.bounds.left + ARROW_MARGIN_X, toY + CORNER_RADIUS ), lineTo(to.bounds.left + ARROW_MARGIN_X, toY + ARROW_THRESHOLD - ARROW_MARGIN_Y) ) : cmds.push( lineTo(to.bounds.left + ARROW_MARGIN_X - CORNER_RADIUS, fromY), quadCurve( to.bounds.left + ARROW_MARGIN_X, fromY, to.bounds.left + ARROW_MARGIN_X, fromY + CORNER_RADIUS ), lineTo(to.bounds.left + ARROW_MARGIN_X, toY + ARROW_THRESHOLD - ARROW_MARGIN_Y) ) : fromY < toY ? cmds.push( lineTo(to.bounds.left + ARROW_MARGIN_X - r1, fromY), quadCurve( to.bounds.left + ARROW_MARGIN_X, fromY, to.bounds.left + ARROW_MARGIN_X, fromY + r1 ), lineTo(to.bounds.left + ARROW_MARGIN_X, toY - r1), quadCurve(to.bounds.left + ARROW_MARGIN_X, toY, to.bounds.left + ARROW_MARGIN_X + r1, toY), lineTo(toX, toY) ) : cmds.push( lineTo(to.bounds.left + ARROW_MARGIN_X - r1, fromY), quadCurve( to.bounds.left + ARROW_MARGIN_X, fromY, to.bounds.left + ARROW_MARGIN_X, fromY - r1 ), lineTo(to.bounds.left + ARROW_MARGIN_X, toY + r1), quadCurve(to.bounds.left + ARROW_MARGIN_X, toY, to.bounds.left + ARROW_MARGIN_X + r1, toY), lineTo(toX, toY) ), join(cmds); } function getConnectorLinePoint(rect, bounds) { const centerY = rect.top + rect.height / 2, isAbove = rect.top + rect.height < bounds.top + ARROW_MARGIN_Y, isBelow = rect.top > bounds.top + bounds.height - ARROW_MARGIN_Y; return { bounds, left: rect.left, top: centerY, centerY, startY: rect.top + CONNECTOR_MARGIN, endY: rect.top + rect.height - CONNECTOR_MARGIN, isAbove, isBelow, outOfBounds: isAbove || isBelow }; } function mapConnectorToLine(connector) { const fromBounds = { top: connector.from.bounds.top + ARROW_THRESHOLD, bottom: connector.from.bounds.top + connector.from.bounds.height - ARROW_THRESHOLD, left: connector.from.bounds.left, right: connector.from.bounds.left + connector.from.bounds.width, width: connector.from.bounds.width, height: connector.from.bounds.height - ARROW_THRESHOLD * 2 }, from2 = getConnectorLinePoint(connector.from.rect, fromBounds); from2.left = connector.from.rect.left + connector.from.rect.width + 1; const toBounds = { top: connector.to.bounds.top + ARROW_THRESHOLD, bottom: connector.to.bounds.top + connector.to.bounds.height - ARROW_THRESHOLD, left: connector.to.bounds.left, right: connector.to.bounds.left + connector.to.bounds.width, width: connector.to.bounds.width, height: connector.to.bounds.height - ARROW_THRESHOLD * 2 }, to = getConnectorLinePoint(connector.to.rect, toBounds), maxStartY = Math.max(to.startY, from2.startY); return from2.top = Math.min(maxStartY, from2.endY), from2.top < toBounds.top ? from2.top = Math.min(toBounds.top, from2.endY) : from2.top > toBounds.bottom && (from2.top = Math.max(toBounds.bottom, from2.startY)), to.top = Math.min(maxStartY, to.endY), to.top < fromBounds.top ? to.top = Math.min(fromBounds.top, to.endY) : to.top > fromBounds.bottom && (to.top = Math.max(fromBounds.bottom, to.startY)), from2.top = Math.min(Math.max(from2.top, fromBounds.top), fromBounds.bottom), to.top = Math.min(Math.max(to.top, toBounds.top), toBounds.bottom), { from: from2, to }; } const Connector = memo(function({ from: from2, to }) { const line = mapConnectorToLine({ from: from2, to }); if (line.from.outOfBounds && line.to.outOfBounds) return null; const linePathDescription = generateConnectorPath(line); return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(InteractivePath, { d: linePathDescription, strokeWidth: INTERACTIVE_STROKE_WIDTH }), /* @__PURE__ */ jsx(ConnectorPath, { d: linePathDescription, strokeWidth: STROKE_WIDTH$2 }), /* @__PURE__ */ jsx( RightBarWrapper, { top: to.rect.top, left: to.rect.left - 0.5, height: to.rect.height, width: STROKE_WIDTH$2, bounds: to.bounds } ), line.from.isAbove && /* @__PURE__ */ jsx( ConnectorPath, { d: arrowPath( line.from.left + ARROW_MARGIN_X, line.from.bounds.top - ARROW_THRESHOLD + ARROW_MARGIN_Y, -1 ), strokeWidth: STROKE_WIDTH$2 } ), line.from.isBelow && /* @__PURE__ */ jsx( ConnectorPath, { d: arrowPath( line.from.left + ARROW_MARGIN_X, line.from.bounds.top + line.from.bounds.height + ARROW_THRESHOLD - ARROW_MARGIN_Y, 1 ), strokeWidth: STROKE_WIDTH$2 } ), line.to.isAbove && /* @__PURE__ */ jsx( ConnectorPath, { d: arrowPath( line.to.bounds.left + ARROW_MARGIN_X, line.to.bounds.top - ARROW_THRESHOLD + ARROW_MARGIN_Y, -1 ), strokeWidth: STROKE_WIDTH$2 } ), line.to.isBelow && /* @__PURE__ */ jsx( ConnectorPath, { d: arrowPath( line.to.bounds.left + ARROW_MARGIN_X, line.to.bounds.top + line.to.bounds.height + ARROW_THRESHOLD - ARROW_MARGIN_Y, 1 ), strokeWidth: STROKE_WIDTH$2 } ), DEBUG$1 ] }); }), SvgWrapper = styled.svg` pointer-events: none; position: absolute; left: 0; top: 0; right: 0; bottom: 0; width: 100%; height: 100%; `; function focusRingBorderStyle$2(border) { return `inset 0 0 0 ${border.width}px ${border.color}`; } const AlignedBottomGrid$1 = styled(Grid)` align-items: flex-end; `; function focusRingStyle$2(opts) { const { base, border, focusRing } = opts, focusRingOutsetWidth = focusRing.offset + focusRing.width, focusRingInsetWidth = 0 - focusRing.offset, bgColor = base ? base.bg : "var(--card-bg-color)"; return [ focusRingInsetWidth > 0 && `inset 0 0 0 ${focusRingInsetWidth}px var(--card-focus-ring-color)`, border && focusRingBorderStyle$2(border), focusRingInsetWidth < 0 && `0 0 0 ${0 - focusRingInsetWidth}px ${bgColor}`, focusRingOutsetWidth > 0 && `0 0 0 ${focusRingOutsetWidth}px var(--card-focus-ring-color)` ].filter(Boolean).join(","); } const LIST_ITEM_DATA_ATTR_ACTIVE = "data-active", LIST_ITEM_INTERACTIVE_SELECTOR = "a,button", FocusOverlayDiv = styled.div(({ theme, offset }) => css` bottom: ${-offset}px; border-radius: ${rem(theme.sanity.radius[1])}; left: ${-offset}px; pointer-events: none; position: absolute; right: ${-offset}px; top: ${-offset}px; z-index: 2; ${VirtualListBox}:focus-visible & { box-shadow: ${focusRingStyle$2({ base: theme.sanity.color.base, focusRing: theme.sanity.focusRing })}; } `), PointerOverlayDiv = styled.div` bottom: 0; display: none; left: 0; position: absolute; right: 0; top: 0; z-index: 1; @media (hover: hover) { &[data-enabled='true'] { display: block; } } `, VirtualListBox = styled(Box)` height: 100%; outline: none; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; width: 100%; `, VirtualListChildBox = styled(Box).attrs(({ $height }) => ({ style: { height: `${$height}px` } }))` position: relative; width: 100%; `, CommandList = forwardRef(function({ activeItemDataAttr = LIST_ITEM_DATA_ATTR_ACTIVE, ariaLabel, ariaMultiselectable = !1, autoFocus, canReceiveFocus, fixedHeight, focusRingOffset = 0, getItemDisabled, getItemKey: getItemKey2, getItemSelected, initialIndex, initialScrollAlign = "start", inputElement, itemHeight, items, onEndReached, onEndReachedIndexOffset = 0, onlyShowSelectionWhenActive, overscan, renderItem, wrapAround = !0, ...responsivePaddingProps }, ref) { const isMountedRef = useRef(!1), commandListId = useRef(useId()), activeIndexRef = useRef(initialIndex != null ? initialIndex : 0), [childContainerElement, setChildContainerElement] = useState(null), [hovered, setHovered] = useState(!1), [pointerOverlayElement, setPointerOverlayElement] = useState(null), [virtualListElement, setVirtualListElement] = useState(null), handleChange = useCallback( (v) => { if (!onEndReached) return; const [lastItem] = [...v.getVirtualItems()].reverse(); lastItem && lastItem.index >= items.length - onEndReachedIndexOffset - 1 && isMountedRef.current && onEndReached(); }, [onEndReached, items.length, onEndReachedIndexOffset] ), virtualizer = useVirtualizer({ count: items.length, getItemKey: getItemKey2, getScrollElement: () => virtualListElement, estimateSize: () => itemHeight, onChange: handleChange, overscan }), itemIndices = useMemo(() => { let i = -1; return items.reduce((acc, _, index) => { var _a2, _b; const disabled = (_a2 = getItemDisabled == null ? void 0 : getItemDisabled(index)) != null ? _a2 : !1, selected = (_b = getItemSelected == null ? void 0 : getItemSelected(index)) != null ? _b : !1; return disabled || (i += 1), acc[index] = { activeIndex: disabled ? null : i, disabled, selected }, acc; }, []); }, [getItemDisabled, getItemSelected, items]), activeItemCount = useMemo( () => itemIndices.filter((v) => !v.disabled).length, [itemIndices] ), enableChildContainerPointerEvents = useCallback( (enabled) => pointerOverlayElement == null ? void 0 : pointerOverlayElement.setAttribute("data-enabled", (!enabled).toString()), [pointerOverlayElement] ), getChildDescendantId = useCallback( (index) => `${commandListId.current}-item-${index}`, [] ), getCommandListChildrenId = useCallback(() => `${commandListId.current}-children`, []), showChildrenActiveState = useCallback(() => { const hasFocus = [inputElement, virtualListElement].some((el) => document.activeElement === el); if (onlyShowSelectionWhenActive && !hasFocus && !hovered) return; const childElements = Array.from((childContainerElement == null ? void 0 : childContainerElement.children) || []); childElements == null || childElements.forEach((child) => { var _a2, _b, _c; const virtualIndex = Number((_a2 = child.dataset) == null ? void 0 : _a2.index), targetIndex = (_b = itemIndices[virtualIndex]) == null ? void 0 : _b.activeIndex; (_c = child.querySelector(LIST_ITEM_INTERACTIVE_SELECTOR)) == null || _c.toggleAttribute(activeItemDataAttr, targetIndex === activeIndexRef.current); }); }, [ activeItemDataAttr, childContainerElement == null ? void 0 : childContainerElement.children, hovered, inputElement, itemIndices, onlyShowSelectionWhenActive, virtualListElement ]), hideChildrenActiveState = useCallback(() => { const childElements = Array.from((childContainerElement == null ? void 0 : childContainerElement.children) || []); childElements == null || childElements.forEach((child) => { var _a2; (_a2 = child.querySelector(LIST_ITEM_INTERACTIVE_SELECTOR)) == null || _a2.toggleAttribute(activeItemDataAttr, !1); }); }, [activeItemDataAttr, childContainerElement == null ? void 0 : childContainerElement.children]), refreshChildrenActiveStateThrottled = useMemo(() => throttle(showChildrenActiveState, 200), [showChildrenActiveState]), handleUpdateActiveDescendant = useCallback(() => { const activeIndex = activeIndexRef == null ? void 0 : activeIndexRef.current; items.length > 0 ? (inputElement == null || inputElement.setAttribute("aria-activedescendant", getChildDescendantId(activeIndex)), virtualListElement == null || virtualListElement.setAttribute("aria-activedescendant", getChildDescendantId(activeIndex))) : (inputElement == null || inputElement.removeAttribute("aria-activedescendant"), virtualListElement == null || virtualListElement.removeAttribute("aria-activedescendant")); }, [getChildDescendantId, inputElement, items.length, virtualListElement]), handleGetTopIndex = useCallback(() => { var _a2, _b; const childContainerParentElement = childContainerElement == null ? void 0 : childContainerElement.parentElement; if (childContainerElement && childContainerParentElement) { const offset = childContainerParentElement.getBoundingClientRect().top - childContainerElement.getBoundingClientRect().top; return (_b = (_a2 = virtualizer.getVirtualItemForOffset(offset)) == null ? void 0 : _a2.index) != null ? _b : -1; } return -1; }, [childContainerElement, virtualizer]), setActiveIndex = useCallback( ({ index, scrollAlign, scrollIntoView: scrollIntoView2 = !0 }) => { if (activeIndexRef.current = index, handleUpdateActiveDescendant(), showChildrenActiveState(), scrollIntoView2) { const virtualListIndex = itemIndices.findIndex((i) => i.activeIndex === index); virtualListIndex > -1 && virtualizer.scrollToIndex(virtualListIndex, scrollAlign ? { align: scrollAlign } : {}); } }, [handleUpdateActiveDescendant, itemIndices, showChildrenActiveState, virtualizer] ), selectAdjacentItemIndex = useCallback( (direction) => { let nextIndex = -1; const lastIndex = activeItemCount - 1; if (direction === "next") { const wrapAroundIndex = wrapAround ? 0 : lastIndex; nextIndex = activeIndexRef.current < activeItemCount - 1 ? activeIndexRef.current + 1 : wrapAroundIndex; } if (direction === "previous") { const wrapAroundIndex = wrapAround ? lastIndex : 0; nextIndex = activeIndexRef.current > 0 ? activeIndexRef.current - 1 : wrapAroundIndex; } setActiveIndex({ index: nextIndex, scrollIntoView: !0 }), enableChildContainerPointerEvents(!1); }, [activeItemCount, enableChildContainerPointerEvents, setActiveIndex, wrapAround] ), focusElement = useCallback( (type) => { switch (type) { case "input": inputElement == null || inputElement.focus(); break; case "list": virtualListElement == null || virtualListElement.focus(); break; } }, [inputElement, virtualListElement] ), focusInputElement = useCallback(() => { inputElement == null || inputElement.focus(); }, [inputElement]), focusListElement = useCallback(() => { virtualListElement == null || virtualListElement.focus(); }, [virtualListElement]), handleChildMouseEnter = useCallback( (index) => () => { setActiveIndex({ index, scrollIntoView: !1 }); }, [setActiveIndex] ), handleFocus = useCallback(() => { showChildrenActiveState(); }, [showChildrenActiveState]), handleKeyDown = useCallback( (type) => (event) => { const childElements = Array.from((childContainerElement == null ? void 0 : childContainerElement.children) || []); if (childElements.length && (event.key === "ArrowDown" && (event.preventDefault(), focusElement(type), selectAdjacentItemIndex("next")), event.key === "ArrowUp" && (event.preventDefault(), focusElement(type), selectAdjacentItemIndex("previous")), event.key === "Enter")) { event.preventDefault(), focusElement(type); const currentElement = childElements.find( (el) => Number(el.dataset.index) === itemIndices.findIndex((i) => i.activeIndex === activeIndexRef.current) ); if (currentElement) { const clickableElement = currentElement == null ? void 0 : currentElement.querySelector( LIST_ITEM_INTERACTIVE_SELECTOR ); clickableElement == null || clickableElement.click(); } } }, [childContainerElement == null ? void 0 : childContainerElement.children, focusElement, itemIndices, selectAdjacentItemIndex] ), handleKeyDownInput = useCallback( (event) => handleKeyDown("input")(event), [handleKeyDown] ), handleKeyDownList = useCallback( (event) => handleKeyDown("list")(event), [handleKeyDown] ), handleVirtualListMouseEnter = useCallback(() => { onlyShowSelectionWhenActive && (showChildrenActiveState(), setHovered(!0)); }, [onlyShowSelectionWhenActive, showChildrenActiveState]), handleVirtualListMouseLeave = useCallback(() => { onlyShowSelectionWhenActive && (hideChildrenActiveState(), setHovered(!1)); }, [hideChildrenActiveState, onlyShowSelectionWhenActive]); useImperativeHandle( ref, () => ({ focusInputElement() { focusInputElement(); }, focusListElement() { focusListElement(); }, getTopIndex() { return handleGetTopIndex(); }, scrollToIndex(index) { setActiveIndex({ index }), enableChildContainerPointerEvents(!0); } }), [ enableChildContainerPointerEvents, focusInputElement, focusListElement, handleGetTopIndex, setActiveIndex ] ), useEffect(() => { typeof initialIndex < "u" && !isMountedRef.current && setActiveIndex({ index: initialIndex, scrollAlign: initialScrollAlign, scrollIntoView: !0 }), isMountedRef.current = !0; }, [initialIndex, initialScrollAlign, onlyShowSelectionWhenActive, setActiveIndex]), useEffect(() => { function handleMouseEvent() { enableChildContainerPointerEvents(!0); } return virtualListElement == null || virtualListElement.addEventListener("mousemove", handleMouseEvent), virtualListElement == n