UNPKG

@carbon/ibm-products

Version:

Carbon for IBM Products

223 lines (214 loc) 8.41 kB
/** * Copyright IBM Corp. 2020, 2025 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ 'use strict'; var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js'); var react = require('@carbon/react'); var icons = require('@carbon/react/icons'); var React = require('react'); var index$1 = require('../../node_modules/@carbon/colors/es/index.js'); var Carousel = require('../Carousel/Carousel.js'); require('../Carousel/CarouselItem.js'); var index = require('../../_virtual/index.js'); var cx = require('classnames'); var devtools = require('../../global/js/utils/devtools.js'); var settings = require('../../settings.js'); var uuidv4 = require('../../global/js/utils/uuidv4.js'); var _CaretLeft, _CaretRight, _Close; // The block part of our conventional BEM class names (blockClass__E--M). const blockClass = `${settings.pkg.prefix}--guidebanner`; const componentName = 'Guidebanner'; const defaults = { collapsible: false, withLeftGutter: false, // Labels closeIconDescription: 'Close', collapseButtonLabel: 'Read less', expandButtonLabel: 'Read more', nextIconDescription: 'Next', previousIconDescription: 'Back' }; /** * The guide banner sits at the top of a page, or page-level tab, * to introduce foundational concepts related to the page's content. */ exports.Guidebanner = /*#__PURE__*/React.forwardRef((_ref, ref) => { let { children, className, collapsible = defaults.collapsible, onClose, withLeftGutter = defaults.withLeftGutter, // Labels closeIconDescription = defaults.closeIconDescription, collapseButtonLabel = defaults.collapseButtonLabel, expandButtonLabel = defaults.expandButtonLabel, nextIconDescription = defaults.nextIconDescription, previousIconDescription = defaults.previousIconDescription, title, ...rest } = _ref; const scrollRef = React.useRef(null); const toggleRef = React.useRef(null); const [scrollPosition, setScrollPosition] = React.useState(0); const [showNavigation, setShowNavigation] = React.useState(false); const [isCollapsed, setIsCollapsed] = React.useState(collapsible ? true : false); const handleClickToggle = () => { setIsCollapsed(prevState => !prevState); }; const carouselContentId = `${uuidv4.default()}--carousel-content-id`; return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({}, rest, { "aria-owns": !isCollapsed ? carouselContentId : undefined, className: cx(blockClass, className, collapsible && `${blockClass}__collapsible`, isCollapsed && `${blockClass}__collapsible-collapsed`, withLeftGutter && `${blockClass}__with-left-gutter`), ref: ref }, devtools.getDevtoolsProps(componentName)), /*#__PURE__*/React.createElement(icons.Idea, { size: 20, className: `${blockClass}__icon-idea` }), /*#__PURE__*/React.createElement("div", { className: `${blockClass}__title` }, title), /*#__PURE__*/React.createElement(Carousel.Carousel, { id: carouselContentId, className: `${blockClass}__carousel` // These colors are to match the Carousel's faded edges // against the Guidebanner's gradient background. , fadedEdgeColor: { left: index$1.blue90, right: index$1.purple70 }, ref: scrollRef, onChangeIsScrollable: value => { setShowNavigation(value); }, onScroll: scrollPercent => { setScrollPosition(scrollPercent); }, isScrollMode: true }, children), /*#__PURE__*/React.createElement("div", { className: cx([collapsible || showNavigation ? `${blockClass}__navigation` : null]) }, collapsible && /*#__PURE__*/React.createElement(react.Button, { kind: "ghost", size: "md", className: `${blockClass}__toggle-button`, onClick: handleClickToggle, ref: toggleRef, "aria-controls": !isCollapsed ? carouselContentId : undefined, "aria-expanded": !isCollapsed }, isCollapsed ? expandButtonLabel : collapseButtonLabel), showNavigation && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", { className: cx(`${blockClass}__back-button`, [scrollPosition === 0 ? `${blockClass}__back-button--disabled` : null]) }, /*#__PURE__*/React.createElement(react.IconButton, { align: "top", disabled: scrollPosition === 0, kind: "ghost", label: previousIconDescription, onClick: () => { scrollRef.current.scrollPrev(); }, size: "md" }, _CaretLeft || (_CaretLeft = /*#__PURE__*/React.createElement(icons.CaretLeft, { size: 16 })))), /*#__PURE__*/React.createElement("span", { className: cx(`${blockClass}__next-button`, [scrollPosition === 1 ? `${blockClass}__next-button--disabled` : null]) }, /*#__PURE__*/React.createElement(react.IconButton, { align: "top-right", disabled: scrollPosition === 1, kind: "ghost", label: nextIconDescription, onClick: () => { scrollRef.current.scrollNext(); }, size: "md" }, _CaretRight || (_CaretRight = /*#__PURE__*/React.createElement(icons.CaretRight, { size: 16 })))))), onClose && /*#__PURE__*/React.createElement("span", { className: `${blockClass}__close-button` }, /*#__PURE__*/React.createElement(react.IconButton, { align: "bottom-end", kind: "ghost", label: closeIconDescription, onClick: onClose, size: "md" }, _Close || (_Close = /*#__PURE__*/React.createElement(icons.Close, { size: 16 }))))); }); // Return a placeholder if not released and not enabled by feature flag exports.Guidebanner = settings.pkg.checkComponentEnabled(exports.Guidebanner, componentName); // The display name of the component, used by React. Note that displayName // is used in preference to relying on function.name. exports.Guidebanner.displayName = componentName; // The types and DocGen commentary for the component props, // in alphabetical order (for consistency). // See https://www.npmjs.com/package/prop-types#usage. exports.Guidebanner.propTypes = { /** * Provide the contents of the Guidebanner. * One or more GuidebannerElement components are required. */ children: (props, propName) => { let error; const prop = props[propName]; if (!prop) { error = new Error('`Guidebanner` requires one or more children of type `GuidebannerElement`.'); } React.Children.forEach(prop, child => { if (child.type.displayName !== 'GuidebannerElement') { // If child element is not `GuidebannerElement`, then show: // Carbon Products component's `displayName` (child.type.displayName) or // React component's `name` (child.type.name) or // HTML element's tag name (child.type). error = new Error(`\`Guidebanner\` only accepts children of type \`GuidebannerElement\`, found \`${child.type?.displayName || child.type?.name || child.type}\` instead.`); } }); return error; }, /** * Provide an optional class to be applied to the containing node. */ className: index.default.string, /** * Tooltip text and aria label for the Close button icon. */ closeIconDescription: index.default.string, /** * Text label for the Collapse button. */ collapseButtonLabel: index.default.string, /** * When true, the Guidebanner will initialize in a collapsed state, * showing the title and the Expand button. * * When expanded, it will show the GuidebannerElement child components and the Collapse button. */ collapsible: index.default.bool, /** * Text label for the Expand button. */ expandButtonLabel: index.default.string, /** * Tooltip text and aria label for the Next button icon. */ nextIconDescription: index.default.string, /** * If defined, a Close button will render in the top-right corner and a * callback function will be triggered when button is clicked. */ onClose: index.default.func, /** * Tooltip text and aria label for the Back button icon. */ previousIconDescription: index.default.string, /** * Title text. */ title: index.default.string.isRequired, /** * If true, insert 1 rem of "space" on the left of the component. * This will allow the component's content to line up with other * content on the page under special circumstances. */ withLeftGutter: index.default.bool };