UNPKG

@enact/ui

Version:

A collection of simplified unstyled cross-platform UI components for Enact

121 lines (117 loc) 4.32 kB
"use strict"; 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;