Initial commit

This commit is contained in:
2025-03-07 19:22:02 +01:00
commit 4a98255d83
55743 changed files with 5280367 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
import * as React from 'react';
import { usePopover_unstable } from './usePopover';
import { renderPopover_unstable } from './renderPopover';
/**
* Wrapper component that manages state for a PopoverTrigger and a PopoverSurface components.
*/ export const Popover = (props)=>{
const state = usePopover_unstable(props);
return renderPopover_unstable(state);
};
Popover.displayName = 'Popover';
@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Popover/Popover.tsx"],"sourcesContent":["import * as React from 'react';\nimport { usePopover_unstable } from './usePopover';\nimport { renderPopover_unstable } from './renderPopover';\nimport type { PopoverProps } from './Popover.types';\n\n/**\n * Wrapper component that manages state for a PopoverTrigger and a PopoverSurface components.\n */\nexport const Popover: React.FC<PopoverProps> = props => {\n const state = usePopover_unstable(props);\n\n return renderPopover_unstable(state);\n};\n\nPopover.displayName = 'Popover';\n"],"names":["React","usePopover_unstable","renderPopover_unstable","Popover","props","state","displayName"],"rangeMappings":";;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,mBAAmB,QAAQ,eAAe;AACnD,SAASC,sBAAsB,QAAQ,kBAAkB;AAGzD;;CAEC,GACD,OAAO,MAAMC,UAAkCC,CAAAA;IAC7C,MAAMC,QAAQJ,oBAAoBG;IAElC,OAAOF,uBAAuBG;AAChC,EAAE;AAEFF,QAAQG,WAAW,GAAG"}
@@ -0,0 +1 @@
import * as React from 'react';
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
/**
* @internal
* The default value of the tooltip's border radius (borderRadiusMedium).
*
* Unfortunately, Popper requires it to be specified as a variable instead of using CSS.
* While we could use getComputedStyle, that adds a performance penalty for something that
* will likely never change.
*/ export const popoverSurfaceBorderRadius = 4;
@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Popover/constants.ts"],"sourcesContent":["/**\n * @internal\n * The default value of the tooltip's border radius (borderRadiusMedium).\n *\n * Unfortunately, Popper requires it to be specified as a variable instead of using CSS.\n * While we could use getComputedStyle, that adds a performance penalty for something that\n * will likely never change.\n */\nexport const popoverSurfaceBorderRadius = 4;\n"],"names":["popoverSurfaceBorderRadius"],"rangeMappings":";;;;;;;","mappings":"AAAA;;;;;;;CAOC,GACD,OAAO,MAAMA,6BAA6B,EAAE"}
+3
View File
@@ -0,0 +1,3 @@
export { Popover } from './Popover';
export { renderPopover_unstable } from './renderPopover';
export { usePopover_unstable } from './usePopover';
@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Popover/index.ts"],"sourcesContent":["export { Popover } from './Popover';\nexport type { OnOpenChangeData, OpenPopoverEvents, PopoverProps, PopoverSize, PopoverState } from './Popover.types';\nexport { renderPopover_unstable } from './renderPopover';\nexport { usePopover_unstable } from './usePopover';\n"],"names":["Popover","renderPopover_unstable","usePopover_unstable"],"rangeMappings":";;","mappings":"AAAA,SAASA,OAAO,QAAQ,YAAY;AAEpC,SAASC,sBAAsB,QAAQ,kBAAkB;AACzD,SAASC,mBAAmB,QAAQ,eAAe"}
@@ -0,0 +1,26 @@
import * as React from 'react';
import { PopoverContext } from '../../popoverContext';
/**
* Render the final JSX of Popover
*/ export const renderPopover_unstable = (state)=>{
const { appearance, arrowRef, contentRef, inline, mountNode, open, openOnContext, openOnHover, setOpen, size, toggleOpen, trapFocus, triggerRef, withArrow, inertTrapFocus } = state;
return /*#__PURE__*/ React.createElement(PopoverContext.Provider, {
value: {
appearance,
arrowRef,
contentRef,
inline,
mountNode,
open,
openOnContext,
openOnHover,
setOpen,
toggleOpen,
triggerRef,
size,
trapFocus,
inertTrapFocus,
withArrow
}
}, state.popoverTrigger, state.open && state.popoverSurface);
};
@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Popover/renderPopover.tsx"],"sourcesContent":["import * as React from 'react';\nimport { PopoverContext } from '../../popoverContext';\nimport type { PopoverState } from './Popover.types';\n\n/**\n * Render the final JSX of Popover\n */\nexport const renderPopover_unstable = (state: PopoverState) => {\n const {\n appearance,\n arrowRef,\n contentRef,\n inline,\n mountNode,\n open,\n openOnContext,\n openOnHover,\n setOpen,\n size,\n toggleOpen,\n trapFocus,\n triggerRef,\n withArrow,\n inertTrapFocus,\n } = state;\n\n return (\n <PopoverContext.Provider\n value={{\n appearance,\n arrowRef,\n contentRef,\n inline,\n mountNode,\n open,\n openOnContext,\n openOnHover,\n setOpen,\n toggleOpen,\n triggerRef,\n size,\n trapFocus,\n inertTrapFocus,\n withArrow,\n }}\n >\n {state.popoverTrigger}\n {state.open && state.popoverSurface}\n </PopoverContext.Provider>\n );\n};\n"],"names":["React","PopoverContext","renderPopover_unstable","state","appearance","arrowRef","contentRef","inline","mountNode","open","openOnContext","openOnHover","setOpen","size","toggleOpen","trapFocus","triggerRef","withArrow","inertTrapFocus","Provider","value","popoverTrigger","popoverSurface"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,cAAc,QAAQ,uBAAuB;AAGtD;;CAEC,GACD,OAAO,MAAMC,yBAAyB,CAACC;IACrC,MAAM,EACJC,UAAU,EACVC,QAAQ,EACRC,UAAU,EACVC,MAAM,EACNC,SAAS,EACTC,IAAI,EACJC,aAAa,EACbC,WAAW,EACXC,OAAO,EACPC,IAAI,EACJC,UAAU,EACVC,SAAS,EACTC,UAAU,EACVC,SAAS,EACTC,cAAc,EACf,GAAGf;IAEJ,qBACE,oBAACF,eAAekB,QAAQ;QACtBC,OAAO;YACLhB;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAE;YACAE;YACAH;YACAE;YACAG;YACAD;QACF;OAECd,MAAMkB,cAAc,EACpBlB,MAAMM,IAAI,IAAIN,MAAMmB,cAAc;AAGzC,EAAE"}
@@ -0,0 +1,195 @@
import * as React from 'react';
import { useControllableState, useEventCallback, useOnClickOutside, useOnScrollOutside, elementContains, useTimeout } from '@fluentui/react-utilities';
import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
import { usePositioning, resolvePositioningShorthand, mergeArrowOffset, usePositioningMouseTarget } from '@fluentui/react-positioning';
import { useFocusFinders, useActivateModal } from '@fluentui/react-tabster';
import { arrowHeights } from '../PopoverSurface/index';
import { popoverSurfaceBorderRadius } from './constants';
/**
* Create the state required to render Popover.
*
* The returned state can be modified with hooks such as usePopoverStyles,
* before being passed to renderPopover_unstable.
*
* @param props - props from this instance of Popover
*/ export const usePopover_unstable = (props)=>{
const [contextTarget, setContextTarget] = usePositioningMouseTarget();
const initialState = {
size: 'medium',
contextTarget,
setContextTarget,
...props
};
const children = React.Children.toArray(props.children);
if (process.env.NODE_ENV !== 'production') {
if (children.length === 0) {
// eslint-disable-next-line no-console
console.warn('Popover must contain at least one child');
}
if (children.length > 2) {
// eslint-disable-next-line no-console
console.warn('Popover must contain at most two children');
}
}
let popoverTrigger = undefined;
let popoverSurface = undefined;
if (children.length === 2) {
popoverTrigger = children[0];
popoverSurface = children[1];
} else if (children.length === 1) {
popoverSurface = children[0];
}
const [open, setOpenState] = useOpenState(initialState);
const [setOpenTimeout, clearOpenTimeout] = useTimeout();
const setOpen = useEventCallback((e, shouldOpen)=>{
clearOpenTimeout();
if (!(e instanceof Event) && e.persist) {
// < React 17 still uses pooled synthetic events
e.persist();
}
if (e.type === 'mouseleave') {
var _props_mouseLeaveDelay;
// FIXME leaking Node timeout type
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
setOpenTimeout(()=>{
setOpenState(e, shouldOpen);
}, (_props_mouseLeaveDelay = props.mouseLeaveDelay) !== null && _props_mouseLeaveDelay !== void 0 ? _props_mouseLeaveDelay : 500);
} else {
setOpenState(e, shouldOpen);
}
});
const toggleOpen = React.useCallback((e)=>{
setOpen(e, !open);
}, [
setOpen,
open
]);
const positioningRefs = usePopoverRefs(initialState);
const { targetDocument } = useFluent();
var _props_closeOnIframeFocus;
useOnClickOutside({
contains: elementContains,
element: targetDocument,
callback: (ev)=>setOpen(ev, false),
refs: [
positioningRefs.triggerRef,
positioningRefs.contentRef
],
disabled: !open,
disabledFocusOnIframe: !((_props_closeOnIframeFocus = props.closeOnIframeFocus) !== null && _props_closeOnIframeFocus !== void 0 ? _props_closeOnIframeFocus : true)
});
// only close on scroll for context, or when closeOnScroll is specified
const closeOnScroll = initialState.openOnContext || initialState.closeOnScroll;
useOnScrollOutside({
contains: elementContains,
element: targetDocument,
callback: (ev)=>setOpen(ev, false),
refs: [
positioningRefs.triggerRef,
positioningRefs.contentRef
],
disabled: !open || !closeOnScroll
});
const { findFirstFocusable } = useFocusFinders();
const activateModal = useActivateModal();
React.useEffect(()=>{
if (props.unstable_disableAutoFocus) {
return;
}
const contentElement = positioningRefs.contentRef.current;
if (open && contentElement) {
var _contentElement_getAttribute;
const shouldFocusContainer = !isNaN((_contentElement_getAttribute = contentElement.getAttribute('tabIndex')) !== null && _contentElement_getAttribute !== void 0 ? _contentElement_getAttribute : undefined);
const firstFocusable = shouldFocusContainer ? contentElement : findFirstFocusable(contentElement);
firstFocusable === null || firstFocusable === void 0 ? void 0 : firstFocusable.focus();
if (shouldFocusContainer) {
// Modal activation happens automatically when something inside the modal is focused programmatically.
// When the container is focused, we need to activate the modal manually.
activateModal(contentElement);
}
}
}, [
findFirstFocusable,
activateModal,
open,
positioningRefs.contentRef,
props.unstable_disableAutoFocus
]);
var _props_inertTrapFocus, _props_inline;
return {
...initialState,
...positioningRefs,
// eslint-disable-next-line @typescript-eslint/no-deprecated
inertTrapFocus: (_props_inertTrapFocus = props.inertTrapFocus) !== null && _props_inertTrapFocus !== void 0 ? _props_inertTrapFocus : props.legacyTrapFocus === undefined ? false : !props.legacyTrapFocus,
popoverTrigger,
popoverSurface,
open,
setOpen,
toggleOpen,
setContextTarget,
contextTarget,
inline: (_props_inline = props.inline) !== null && _props_inline !== void 0 ? _props_inline : false
};
};
/**
* Creates and manages the Popover open state
*/ function useOpenState(state) {
'use no memo';
const onOpenChange = useEventCallback((e, data)=>{
var _state_onOpenChange;
return (_state_onOpenChange = state.onOpenChange) === null || _state_onOpenChange === void 0 ? void 0 : _state_onOpenChange.call(state, e, data);
});
const [open, setOpenState] = useControllableState({
state: state.open,
defaultState: state.defaultOpen,
initialState: false
});
state.open = open !== undefined ? open : state.open;
const setContextTarget = state.setContextTarget;
const setOpen = React.useCallback((e, shouldOpen)=>{
if (shouldOpen && e.type === 'contextmenu') {
setContextTarget(e);
}
if (!shouldOpen) {
setContextTarget(undefined);
}
setOpenState(shouldOpen);
onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(e, {
open: shouldOpen
});
}, [
setOpenState,
onOpenChange,
setContextTarget
]);
return [
open,
setOpen
];
}
/**
* Creates and sets the necessary trigger, target and content refs used by Popover
*/ function usePopoverRefs(state) {
'use no memo';
const positioningOptions = {
position: 'above',
align: 'center',
arrowPadding: 2 * popoverSurfaceBorderRadius,
target: state.openOnContext ? state.contextTarget : undefined,
...resolvePositioningShorthand(state.positioning)
};
// no reason to render arrow when covering the target
if (positioningOptions.coverTarget) {
state.withArrow = false;
}
if (state.withArrow) {
positioningOptions.offset = mergeArrowOffset(positioningOptions.offset, arrowHeights[state.size]);
}
const { targetRef: triggerRef, containerRef: contentRef, arrowRef } = usePositioning(positioningOptions);
return {
triggerRef,
contentRef,
arrowRef
};
}
File diff suppressed because one or more lines are too long