@enact/ui
Version:
A collection of simplified unstyled cross-platform UI components for Enact
121 lines (117 loc) • 4.32 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
exports.useSkins = useSkins;
var _react = require("react");
var _util = require("./util");
var _jsxRuntime = require("react/jsx-runtime");
/**
* Allows a component to respond to skin changes via the Context API
*
* Example:
* ```
* <App skin="dark">
* <Section>
* <Button>Gray Button</Button>
* <Section>
* <Popup skin="light">
* <Button>White Button</Button>
* </Popup>
* </App>
* ```
*
* @class SkinContext
* @memberof ui/Skinnable
* @private
*/var SkinContext = /*#__PURE__*/(0, _react.createContext)(null);
/**
* Configuration for `useSkins`
*
* @typedef {Object} useSkinsConfig
* @memberof ui/Skinnable
* @property {String} defaultSkin Default skin name when none has been specified or inherited.
* @property {String[]} [defaultVariants] Default variants when none have been specified or inherited.
* @property {String} [skin] Specific skin to apply to this instance which will take precedence over the default or the inherited value.
* @property {String[]} skins List of allowed skins
* @property {String[]} [skinVariants] Specific variants to apply to this instance which will take precedence over the default or the inherited value.
* @property {String[]} [variants] List of allowed variants
* @private
*/
/**
* Object returned by `useSkins`
*
* @typedef {Object} useSkinsInterface
* @memberof ui/Skinnable
* @property {String} className CSS classes for the effective skin and variants.
* @property {String} skin Effective skin based on the allowed skins, the configured.
* `skin`, the default skin, and the inherited `skin` from up the
* component tree.
* @property {String[]} variants Effective skins variant based on the allowed variants, the
* configured variants, the default variants, and the inherited
* variants from up the component tree.
* @property {Function} provideSkins Wraps a component tree with a skin provider to allow that tree
* to inherit the effective skin configured at this level.
* @private
*/
/**
* Determines the effective skin and skin variants for a component and provides a method to provide
* those values to other contained components in this subtree.
*
* ```
* function ComponentDecorator (props) {
* const skins = useSkins({
* defaultSkin: 'neutral',
* defaultVariants: [],
* skins: ['neutral', 'bold'],
* variants: ['highContrast'],
* skin: props.skin,
* skinVariants: props.skinVariants
* });
*
* return skins.provideSkins(
* <Component className={classnames(props.className, skins.className)} />
* );
* }
* ```
*
* @param {useSkinsConfig} config Configuration options
* @returns {useSkinsInterface}
* @private
*/
function useSkins(config) {
var defaultSkin = config.defaultSkin,
defaultVariants = config.defaultVariants,
skin = config.skin,
skins = config.skins,
skinVariants = config.skinVariants,
variants = config.variants;
var _ref = (0, _react.use)(SkinContext) || {},
parentSkin = _ref.parentSkin,
parentVariants = _ref.parentVariants;
var effectiveSkin = (0, _util.determineSkin)(defaultSkin, skin, parentSkin);
var effectiveVariants = (0, _react.useMemo)(function () {
return (0, _util.determineVariants)(defaultVariants, variants, skinVariants, parentVariants);
}, [defaultVariants, variants, skinVariants, parentVariants]);
var className = (0, _util.getClassName)(skins, effectiveSkin, effectiveVariants);
var value = (0, _react.useMemo)(function () {
return {
parentSkin: effectiveSkin,
parentVariants: effectiveVariants
};
}, [effectiveSkin, effectiveVariants]);
var provideSkins = (0, _react.useCallback)(function (children) {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(SkinContext, {
value: value,
children: children
});
}, [value]);
return {
className: className,
skin: effectiveSkin,
variants: effectiveVariants,
provideSkins: provideSkins
};
}
var _default = exports["default"] = useSkins;