Outlook_Addin_LLM/node_modules/@fluentui/foundation-legacy/lib-commonjs/slots.js

191 lines
9.4 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSlots = exports.createFactory = exports.withSlots = void 0;
var tslib_1 = require("tslib");
var React = require("react");
var merge_styles_1 = require("@fluentui/merge-styles");
var utilities_1 = require("@fluentui/utilities");
var utilities_2 = require("./utilities");
/**
* This function is required for any module that uses slots.
*
* This function is a slot resolver that automatically evaluates slot functions to generate React elements.
* A byproduct of this resolver is that it removes slots from the React hierarchy by bypassing React.createElement.
*
* To use this function on a per-file basis, use the jsx directive targeting withSlots.
* This directive must be the FIRST LINE in the file to work correctly.
* Usage of this pragma also requires withSlots import statement.
*
* See React.createElement
*/
// Can't use typeof on React.createElement since it's overloaded. Approximate createElement's signature for now
// and widen as needed.
function withSlots(type, props) {
var children = [];
for (var _i = 2; _i < arguments.length; _i++) {
children[_i - 2] = arguments[_i];
}
var slotType = type;
if (slotType.isSlot) {
// Since we are bypassing createElement, use React.Children.toArray to make sure children are
// properly assigned keys.
// TODO: should this be mutating? does React mutate children subprop with createElement?
// TODO: will toArray clobber existing keys?
// TODO: React generates warnings because it doesn't detect hidden member _store that is set in createElement.
// Even children passed to createElement without keys don't generate this warning.
// Is there a better way to prevent slots from appearing in hierarchy? toArray doesn't address root issue.
children = React.Children.toArray(children);
// TODO: There is something weird going on here with children embedded in props vs. rest args.
// Comment out these lines to see. Make sure this function is doing the right things.
if (children.length === 0) {
return slotType(props);
}
return slotType(tslib_1.__assign(tslib_1.__assign({}, props), { children: children }));
}
else {
// TODO: Are there some cases where children should NOT be spread? Also, spreading reraises perf question.
// Children had to be spread to avoid breaking KeytipData in Toggle.view:
// react-dom.development.js:18931 Uncaught TypeError: children is not a function
// Without spread, function child is a child array of one element
// TODO: is there a reason this can't be:
// return React.createElement.apply(this, arguments);
return React.createElement.apply(React, tslib_1.__spreadArray([type, props], children, false));
}
}
exports.withSlots = withSlots;
/**
* This function creates factories that render ouput depending on the user ISlotProp props passed in.
* @param DefaultComponent - Base component to render when not overridden by user props.
* @param options - Factory options, including defaultProp value for shorthand prop mapping.
* @returns ISlotFactory function used for rendering slots.
*/
function createFactory(DefaultComponent, options) {
if (options === void 0) { options = {}; }
var _a = options.defaultProp, defaultProp = _a === void 0 ? 'children' : _a;
var result = function (componentProps, userProps, userSlotOptions, defaultStyles, theme) {
// If they passed in raw JSX, just return that.
if (React.isValidElement(userProps)) {
return userProps;
}
var flattenedUserProps = _translateShorthand(defaultProp, userProps);
var finalProps = _constructFinalProps(defaultStyles, theme, componentProps, flattenedUserProps);
if (userSlotOptions) {
if (userSlotOptions.component) {
// TODO: Remove cast if possible. This cast is needed because TS errors on the intrinsic portion of ReactType.
// return <userSlotOptions.component {...finalProps} />;
var UserComponent = userSlotOptions.component;
return React.createElement(UserComponent, tslib_1.__assign({}, finalProps));
}
if (userSlotOptions.render) {
return userSlotOptions.render(finalProps, DefaultComponent);
}
}
return React.createElement(DefaultComponent, tslib_1.__assign({}, finalProps));
};
return result;
}
exports.createFactory = createFactory;
/**
* Default factory for components without explicit factories.
*/
var defaultFactory = (0, utilities_1.memoizeFunction)(function (type) { return createFactory(type); });
/**
* This function generates slots that can be used in JSX given a definition of slots and their corresponding types.
* @param userProps - Props as pass to component.
* @param slots - Slot definition object defining the default slot component for each slot.
* @returns A set of created slots that components can render in JSX.
*/
function getSlots(userProps, slots) {
var result = {};
// userProps already has default props mixed in by createComponent. Recast here to gain typing for this function.
var mixedProps = userProps;
var _loop_1 = function (name_1) {
if (slots.hasOwnProperty(name_1)) {
// This closure method requires the use of withSlots to prevent unnecessary rerenders. This is because React
// detects each closure as a different component (since it is a new instance) from the previous one and then
// forces a rerender of the entire slot subtree. For now, the only way to avoid this is to use withSlots, which
// bypasses the call to React.createElement.
var slot = function (componentProps) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
if (args.length > 0) {
// If React.createElement is being incorrectly used with slots, there will be additional arguments.
// We can detect these additional arguments and error on their presence.
throw new Error('Any module using getSlots must use withSlots. Please see withSlots javadoc for more info.');
}
// TODO: having TS infer types here seems to cause infinite loop.
// use explicit types or casting to preserve typing if possible.
// TODO: this should be a lookup on TProps property instead of being TProps directly, which is probably
// causing the infinite loop
return _renderSlot(slots[name_1],
// TODO: this cast to any is hiding a relationship issue between the first two args
componentProps, mixedProps[name_1], mixedProps.slots && mixedProps.slots[name_1],
// _defaultStyles should always be present, but a check for existence is added to make view tests
// easier to use.
mixedProps._defaultStyles && mixedProps._defaultStyles[name_1], mixedProps.theme);
};
slot.isSlot = true;
result[name_1] = slot;
}
};
for (var name_1 in slots) {
_loop_1(name_1);
}
return result;
}
exports.getSlots = getSlots;
/**
* Helper function that translates shorthand as needed.
* @param defaultProp
* @param slotProps
*/
function _translateShorthand(defaultProp, slotProps) {
var _a;
var transformedProps;
if (typeof slotProps === 'string' || typeof slotProps === 'number' || typeof slotProps === 'boolean') {
transformedProps = (_a = {},
_a[defaultProp] = slotProps,
_a);
}
else {
transformedProps = slotProps;
}
return transformedProps;
}
/**
* Helper function that constructs final styles and props given a series of props ordered by increasing priority.
*/
function _constructFinalProps(defaultStyles, theme) {
var allProps = [];
for (var _i = 2; _i < arguments.length; _i++) {
allProps[_i - 2] = arguments[_i];
}
var finalProps = {};
var classNames = [];
for (var _a = 0, allProps_1 = allProps; _a < allProps_1.length; _a++) {
var props = allProps_1[_a];
classNames.push(props && props.className);
(0, utilities_2.assign)(finalProps, props);
}
finalProps.className = (0, merge_styles_1.mergeCss)([defaultStyles, classNames], { rtl: (0, utilities_1.getRTL)(theme) });
return finalProps;
}
/**
* Render a slot given component and user props. Uses component factory if available, otherwise falls back
* to default factory.
* @param ComponentType Factory component type.
* @param componentProps The properties passed into slot from within the component.
* @param userProps The user properties passed in from outside of the component.
*/
function _renderSlot(ComponentType, componentProps, userProps, slotOptions, defaultStyles, theme) {
if (ComponentType.create !== undefined) {
return ComponentType.create(componentProps, userProps, slotOptions, defaultStyles);
}
else {
// TODO: need to resolve typing / generic issues passing through memoizeFunction. for now, cast to 'unknown'
return defaultFactory(ComponentType)(componentProps, userProps, slotOptions, defaultStyles, theme);
}
}
//# sourceMappingURL=slots.js.map