Private
Public Access
1
0

feat: Fluent UI Outlook Lite + connections mockup

This commit is contained in:
2026-04-14 18:52:25 +00:00
parent 1199eff6c3
commit dfa4010406
34820 changed files with 1003813 additions and 205 deletions

View File

@@ -0,0 +1,20 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "Popover", {
enumerable: true,
get: function() {
return Popover;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _usePopover = require("./usePopover");
const _renderPopover = require("./renderPopover");
const Popover = (props)=>{
const state = (0, _usePopover.usePopover_unstable)(props);
return (0, _renderPopover.renderPopover_unstable)(state);
};
Popover.displayName = 'Popover';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Popover/Popover.tsx"],"sourcesContent":["'use client';\n\nimport * 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"],"mappings":"AAAA;;;;;;;;;;;;iEAEuB,QAAQ;4BACK,eAAe;+BACZ,kBAAkB;AAMlD,MAAMG,UAAkCC,CAAAA;IAC7C,MAAMC,YAAQJ,+BAAAA,EAAoBG;IAElC,WAAOF,qCAAAA,EAAuBG;AAChC,EAAE;AAEFF,QAAQG,WAAW,GAAG"}

View File

@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "PopoverSurfaceMotion", {
enumerable: true,
get: function() {
return PopoverSurfaceMotion;
}
});
const _reactmotion = require("@fluentui/react-motion");
const _reactmotioncomponentspreview = require("@fluentui/react-motion-components-preview");
const _reactpositioning = require("@fluentui/react-positioning");
// Shared timing constants for the enter animation.
const duration = _reactmotion.motionTokens.durationSlower;
const easing = _reactmotion.motionTokens.curveDecelerateMid;
const PopoverSurfaceMotion = (0, _reactmotion.createPresenceComponent)(({ distance = 10 })=>({
enter: [
(0, _reactmotioncomponentspreview.fadeAtom)({
duration,
easing,
direction: 'enter'
}),
{
// slideAtom produces translate keyframes from `outX`/`outY` → `0px`.
// The `outX`/`outY` values read the positioning-provided CSS variables and scale
// them by `distance` so the surface slides in from the correct direction.
...(0, _reactmotioncomponentspreview.slideAtom)({
duration,
easing,
direction: 'enter',
outX: `calc(var(${_reactpositioning.POSITIONING_SLIDE_DIRECTION_VAR_X}, 0px) * ${distance})`,
outY: `calc(var(${_reactpositioning.POSITIONING_SLIDE_DIRECTION_VAR_Y}, 0px) * ${distance})`
}),
// 'accumulate' compositing adds this effect's transform on top of the element's
// existing transform, preserving any transform applied by the positioning engine.
composite: 'accumulate'
}
],
// No exit animation — the surface unmounts immediately on close.
exit: []
}));

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Popover/PopoverSurfaceMotion.ts"],"sourcesContent":["import { createPresenceComponent, motionTokens } from '@fluentui/react-motion';\nimport { fadeAtom, slideAtom } from '@fluentui/react-motion-components-preview';\nimport {\n POSITIONING_SLIDE_DIRECTION_VAR_X as slideDirectionVarX,\n POSITIONING_SLIDE_DIRECTION_VAR_Y as slideDirectionVarY,\n} from '@fluentui/react-positioning';\n\n// Shared timing constants for the enter animation.\nconst duration = motionTokens.durationSlower;\nconst easing = motionTokens.curveDecelerateMid;\n\n/**\n * Default `surfaceMotion` slot for `<Popover>`.\n *\n * Enter-only animation combining a fade and a direction-aware slide.\n * The slide reads CSS variables set by `usePositioningSlideDirection` and scales\n * them by `distance` pixels. There is no exit animation; the surface unmounts immediately.\n *\n * @param distance - Travel distance (px) for the enter slide. Defaults to `10`.\n */\nexport const PopoverSurfaceMotion = createPresenceComponent(({ distance = 10 }: { distance?: number }) => ({\n enter: [\n fadeAtom({ duration, easing, direction: 'enter' }),\n {\n // slideAtom produces translate keyframes from `outX`/`outY` → `0px`.\n // The `outX`/`outY` values read the positioning-provided CSS variables and scale\n // them by `distance` so the surface slides in from the correct direction.\n ...slideAtom({\n duration,\n easing,\n direction: 'enter',\n outX: `calc(var(${slideDirectionVarX}, 0px) * ${distance})`,\n outY: `calc(var(${slideDirectionVarY}, 0px) * ${distance})`,\n }),\n // 'accumulate' compositing adds this effect's transform on top of the element's\n // existing transform, preserving any transform applied by the positioning engine.\n composite: 'accumulate',\n },\n ],\n // No exit animation — the surface unmounts immediately on close.\n exit: [],\n}));\n"],"names":["createPresenceComponent","motionTokens","fadeAtom","slideAtom","POSITIONING_SLIDE_DIRECTION_VAR_X","slideDirectionVarX","POSITIONING_SLIDE_DIRECTION_VAR_Y","slideDirectionVarY","duration","durationSlower","easing","curveDecelerateMid","PopoverSurfaceMotion","distance","enter","direction","outX","outY","composite","exit"],"mappings":";;;;+BAoBaY;;;;;;6BApByC,yBAAyB;8CAC3C,4CAA4C;kCAIzE,8BAA8B;AAErC,mDAAmD;AACnD,MAAMJ,WAAWP,yBAAAA,CAAaQ,cAAc;AAC5C,MAAMC,SAAST,yBAAAA,CAAaU,kBAAkB;AAWvC,iCAA6BX,oCAAAA,EAAwB,CAAC,EAAEa,WAAW,EAAE,EAAyB,GAAM,CAAA;QACzGC,OAAO;gBACLZ,sCAAAA,EAAS;gBAAEM;gBAAUE;gBAAQK,WAAW;YAAQ;YAChD;gBACE,qEAAqE;gBACrE,iFAAiF;gBACjF,0EAA0E;gBAC1E,GAAGZ,2CAAAA,EAAU;oBACXK;oBACAE;oBACAK,WAAW;oBACXC,MAAM,CAAC,SAAS,EAAEX,mDAAAA,CAAmB,SAAS,EAAEQ,SAAS,CAAC,CAAC;oBAC3DI,MAAM,CAAC,SAAS,EAAEV,mDAAAA,CAAmB,SAAS,EAAEM,SAAS,CAAC,CAAC;gBAC7D,EAAE;gBACF,gFAAgF;gBAChF,kFAAkF;gBAClFK,WAAW;YACb;SACD;QACD,iEAAiE;QACjEC,MAAM,EAAE;KACV,CAAA,GAAI"}

View File

@@ -0,0 +1,19 @@
/**
* 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.
*
* @internal
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "popoverSurfaceBorderRadius", {
enumerable: true,
get: function() {
return popoverSurfaceBorderRadius;
}
});
const popoverSurfaceBorderRadius = 4;

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Popover/constants.ts"],"sourcesContent":["/**\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 *\n * @internal\n */\nexport const popoverSurfaceBorderRadius = 4;\n"],"names":["popoverSurfaceBorderRadius"],"mappings":"AAAA;;;;;;;;CAQC,GACD;;;;;;;;;;AAAO,MAAMA,6BAA6B,EAAE"}

View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
Popover: function() {
return _Popover.Popover;
},
renderPopover_unstable: function() {
return _renderPopover.renderPopover_unstable;
},
usePopoverBase_unstable: function() {
return _usePopover.usePopoverBase_unstable;
},
usePopover_unstable: function() {
return _usePopover.usePopover_unstable;
}
});
const _Popover = require("./Popover");
const _renderPopover = require("./renderPopover");
const _usePopover = require("./usePopover");

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Popover/index.ts"],"sourcesContent":["export { Popover } from './Popover';\nexport type {\n OnOpenChangeData,\n OpenPopoverEvents,\n PopoverBaseProps,\n PopoverProps,\n PopoverSize,\n PopoverBaseState,\n PopoverState,\n} from './Popover.types';\nexport { renderPopover_unstable } from './renderPopover';\nexport { usePopover_unstable, usePopoverBase_unstable } from './usePopover';\n"],"names":["Popover","renderPopover_unstable","usePopover_unstable","usePopoverBase_unstable"],"mappings":";;;;;;;;;;;;eAASA,gBAAO;;;eAUPC,qCAAsB;;;eACDE,mCAAuB;;;eAA5CD,+BAAmB;;;yBAXJ,YAAY;+BAUG,kBAAkB;4BACI,eAAe"}

View File

@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "renderPopover_unstable", {
enumerable: true,
get: function() {
return renderPopover_unstable;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _jsxruntime = require("@fluentui/react-jsx-runtime/jsx-runtime");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _reactutilities = require("@fluentui/react-utilities");
const _reactmotion = require("@fluentui/react-motion");
const _popoverContext = require("../../popoverContext");
const renderPopover_unstable = (state)=>{
(0, _reactutilities.assertSlots)(state);
const { appearance, arrowRef, contentRef, inline, mountNode, open, openOnContext, openOnHover, setOpen, size, toggleOpen, trapFocus, triggerRef, withArrow, inertTrapFocus } = state;
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_popoverContext.PopoverContext.Provider, {
value: {
appearance,
arrowRef,
contentRef,
inline,
mountNode,
open,
openOnContext,
openOnHover,
setOpen,
toggleOpen,
triggerRef,
size,
trapFocus,
inertTrapFocus,
withArrow
},
children: [
state.popoverTrigger,
state.popoverSurface && /*#__PURE__*/ (0, _jsxruntime.jsx)(state.surfaceMotion, {
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reactmotion.MotionRefForwarder, {
children: state.popoverSurface
})
})
]
});
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Popover/renderPopover.tsx"],"sourcesContent":["/** @jsxRuntime automatic */\n/** @jsxImportSource @fluentui/react-jsx-runtime */\n\nimport * as React from 'react';\nimport { assertSlots, type JSXElement } from '@fluentui/react-utilities';\nimport { MotionRefForwarder } from '@fluentui/react-motion';\nimport { PopoverContext } from '../../popoverContext';\nimport type { InternalPopoverSlots, PopoverState } from './Popover.types';\n\n/**\n * Render the final JSX of Popover\n */\nexport const renderPopover_unstable = (state: PopoverState): JSXElement => {\n assertSlots<InternalPopoverSlots>(state);\n\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.popoverSurface && (\n <state.surfaceMotion>\n <MotionRefForwarder>\n {/* Casting here as content should be equivalent to <PopoverSurface /> */}\n {/* FIXME: content should not be ReactNode it should be ReactElement instead. */}\n {state.popoverSurface as React.ReactElement}\n </MotionRefForwarder>\n </state.surfaceMotion>\n )}\n </PopoverContext.Provider>\n );\n};\n"],"names":["React","assertSlots","MotionRefForwarder","PopoverContext","renderPopover_unstable","state","appearance","arrowRef","contentRef","inline","mountNode","open","openOnContext","openOnHover","setOpen","size","toggleOpen","trapFocus","triggerRef","withArrow","inertTrapFocus","Provider","value","popoverTrigger","popoverSurface","surfaceMotion"],"mappings":";;;;+BAYaI;;;;;;;4BAXb,iCAAiD;iEAE1B,QAAQ;gCACc,4BAA4B;6BACtC,yBAAyB;gCAC7B,uBAAuB;AAM/C,+BAA+B,CAACC;QACrCJ,2BAAAA,EAAkCI;IAElC,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,OAAA,WAAA,OACE,gBAAA,EAACF,8BAAAA,CAAekB,QAAQ,EAAA;QACtBC,OAAO;YACLhB;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAE;YACAE;YACAH;YACAE;YACAG;YACAD;QACF;;YAECd,MAAMkB,cAAc;YACpBlB,MAAMmB,cAAc,IAAA,WAAA,OACnB,eAAA,EAACnB,MAAMoB,aAAa,EAAA;0BAClB,WAAA,OAAA,eAAA,EAACvB,+BAAAA,EAAAA;8BAGEG,MAAMmB,cAAc;;;;;AAMjC,EAAE"}

View File

@@ -0,0 +1,243 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
usePopoverBase_unstable: function() {
return usePopoverBase_unstable;
},
usePopover_unstable: function() {
return usePopover_unstable;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _reactutilities = require("@fluentui/react-utilities");
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
const _reactpositioning = require("@fluentui/react-positioning");
const _reacttabster = require("@fluentui/react-tabster");
const _index = require("../PopoverSurface/index");
const _constants = require("./constants");
const _reactmotion = require("@fluentui/react-motion");
const _PopoverSurfaceMotion = require("./PopoverSurfaceMotion");
const usePopover_unstable = (props)=>{
const { appearance, size = 'medium' } = props;
const positioning = (0, _reactpositioning.resolvePositioningShorthand)(props.positioning);
const withArrow = props.withArrow && !positioning.coverTarget;
const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)();
const handlePositionEnd = (0, _reactpositioning.usePositioningSlideDirection)({
targetDocument,
onPositioningEnd: positioning.onPositioningEnd
});
const state = usePopoverBase_unstable({
...props,
positioning: {
...positioning,
onPositioningEnd: handlePositionEnd,
// Update the offset with the arrow size only when it's available
...withArrow ? {
offset: (0, _reactpositioning.mergeArrowOffset)(positioning.offset, _index.arrowHeights[size])
} : {}
}
});
return {
components: {
surfaceMotion: _PopoverSurfaceMotion.PopoverSurfaceMotion
},
appearance,
size,
...state,
surfaceMotion: (0, _reactmotion.presenceMotionSlot)(props.surfaceMotion, {
elementType: _PopoverSurfaceMotion.PopoverSurfaceMotion,
defaultProps: {
visible: state.open,
appear: true,
unmountOnExit: true
}
})
};
};
const usePopoverBase_unstable = (props)=>{
const [contextTarget, setContextTarget] = (0, _reactpositioning.usePositioningMouseTarget)();
const initialState = {
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] = (0, _reactutilities.useTimeout)();
const setOpen = (0, _reactutilities.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 } = (0, _reactsharedcontexts.useFluent_unstable)();
var _props_closeOnIframeFocus;
(0, _reactutilities.useOnClickOutside)({
contains: _reactutilities.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;
(0, _reactutilities.useOnScrollOutside)({
contains: _reactutilities.elementContains,
element: targetDocument,
callback: (ev)=>setOpen(ev, false),
refs: [
positioningRefs.triggerRef,
positioningRefs.contentRef
],
disabled: !open || !closeOnScroll
});
const { findFirstFocusable } = (0, _reacttabster.useFocusFinders)();
const activateModal = (0, _reacttabster.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 = (0, _reactutilities.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] = (0, _reactutilities.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 * _constants.popoverSurfaceBorderRadius,
target: state.openOnContext ? state.contextTarget : undefined,
...(0, _reactpositioning.resolvePositioningShorthand)(state.positioning)
};
// no reason to render arrow when covering the target
if (positioningOptions.coverTarget) {
state.withArrow = false;
}
const { targetRef: triggerRef, containerRef: contentRef, arrowRef } = (0, _reactpositioning.usePositioning)(positioningOptions);
return {
triggerRef,
contentRef,
arrowRef
};
}

File diff suppressed because one or more lines are too long