@carbon/ibm-products
Version:
Carbon for IBM Products
179 lines (177 loc) • 7.89 kB
JavaScript
/**
* Copyright IBM Corp. 2020, 2026
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
const require_runtime = require("../../_virtual/_rolldown/runtime.js");
const require_index = require("../../node_modules/classnames/index.js");
const require_settings = require("../../settings.js");
const require_useControllableState = require("../../global/js/hooks/useControllableState.js");
const require_devtools = require("../../global/js/utils/devtools.js");
const require_uuidv4 = require("../../global/js/utils/uuidv4.js");
const require_index$1 = require("../../node_modules/@carbon/colors/lib/index.js");
const require_Carousel = require("../Carousel/Carousel.js");
let react = require("react");
react = require_runtime.__toESM(react);
let prop_types = require("prop-types");
prop_types = require_runtime.__toESM(prop_types);
let _carbon_react = require("@carbon/react");
let _carbon_react_icons = require("@carbon/react/icons");
//#region src/components/Guidebanner/Guidebanner.tsx
/**
* Copyright IBM Corp. 2023, 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.
*/
var import_lib = require_index$1.default;
var import_classnames = /* @__PURE__ */ require_runtime.__toESM(require_index.default);
const blockClass = `${require_settings.pkg.prefix}--guidebanner`;
const componentName = "Guidebanner";
const defaults = {
collapsible: false,
withLeftGutter: false,
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.
*/
const Guidebanner = react.default.forwardRef((props, ref) => {
const { children, className, collapsible = defaults.collapsible, onClose, withLeftGutter = defaults.withLeftGutter, closeIconDescription = defaults.closeIconDescription, collapseButtonLabel = defaults.collapseButtonLabel, expandButtonLabel = defaults.expandButtonLabel, nextIconDescription = defaults.nextIconDescription, previousIconDescription = defaults.previousIconDescription, title, onChange, open: userOpen, ...rest } = props;
const scrollRef = (0, react.useRef)(null);
const toggleRef = (0, react.useRef)(null);
const [scrollPosition, setScrollPosition] = (0, react.useState)(0);
const [showNavigation, setShowNavigation] = (0, react.useState)(false);
const [open, setOpen] = require_useControllableState.useControllableState(userOpen ?? false, onChange);
const handleClickToggle = () => {
setOpen(!open);
};
const carouselContentId = `${require_uuidv4.default()}--carousel-content-id`;
return /* @__PURE__ */ react.default.createElement("div", {
...rest,
"aria-owns": open ? carouselContentId : void 0,
className: (0, import_classnames.default)(blockClass, className, collapsible && `${blockClass}__collapsible`, !open && `${blockClass}__collapsible-collapsed`, withLeftGutter && `${blockClass}__with-left-gutter`),
ref,
...require_devtools.getDevtoolsProps(componentName)
}, /* @__PURE__ */ react.default.createElement(_carbon_react_icons.Idea, {
size: 20,
className: `${blockClass}__icon-idea`
}), /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__title` }, title), /* @__PURE__ */ react.default.createElement(require_Carousel.Carousel, {
id: carouselContentId,
className: `${blockClass}__carousel`,
fadedEdgeColor: {
left: import_lib.blue90,
right: import_lib.purple70
},
ref: scrollRef,
onChangeIsScrollable: (value) => {
setShowNavigation(value);
},
onScroll: (scrollPercent) => {
setScrollPosition(scrollPercent);
},
isScrollMode: true
}, children), /* @__PURE__ */ react.default.createElement("div", { className: (0, import_classnames.default)([collapsible || showNavigation ? `${blockClass}__navigation` : null]) }, collapsible && /* @__PURE__ */ react.default.createElement(_carbon_react.Button, {
kind: "ghost",
size: "md",
className: `${blockClass}__toggle-button`,
onClick: handleClickToggle,
ref: toggleRef,
"aria-controls": !open ? carouselContentId : void 0,
"aria-expanded": open
}, open ? collapseButtonLabel : expandButtonLabel), showNavigation && /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement("span", { className: (0, import_classnames.default)(`${blockClass}__back-button`, [scrollPosition === 0 ? `${blockClass}__back-button--disabled` : null]) }, /* @__PURE__ */ react.default.createElement(_carbon_react.IconButton, {
align: "top",
disabled: scrollPosition === 0,
kind: "ghost",
label: previousIconDescription,
onClick: () => {
scrollRef.current.scrollPrev();
},
size: "md"
}, /* @__PURE__ */ react.default.createElement(_carbon_react_icons.CaretLeft, { size: 16 }))), /* @__PURE__ */ react.default.createElement("span", { className: (0, import_classnames.default)(`${blockClass}__next-button`, [scrollPosition === 1 ? `${blockClass}__next-button--disabled` : null]) }, /* @__PURE__ */ react.default.createElement(_carbon_react.IconButton, {
align: "top-right",
disabled: scrollPosition === 1,
kind: "ghost",
label: nextIconDescription,
onClick: () => {
scrollRef.current.scrollNext();
},
size: "md"
}, /* @__PURE__ */ react.default.createElement(_carbon_react_icons.CaretRight, { size: 16 }))))), onClose && /* @__PURE__ */ react.default.createElement("span", { className: `${blockClass}__close-button` }, /* @__PURE__ */ react.default.createElement(_carbon_react.IconButton, {
align: "bottom-end",
kind: "ghost",
label: closeIconDescription,
onClick: onClose,
size: "md"
}, /* @__PURE__ */ react.default.createElement(_carbon_react_icons.Close, { size: 16 }))));
});
Guidebanner.displayName = componentName;
Guidebanner.propTypes = {
/**
* Provide the contents of the Guidebanner.
* One or more GuidebannerElement components are required.
*/
children: prop_types.default.node,
/**
* Provide an optional class to be applied to the containing node.
*/
className: prop_types.default.string,
/**
* Tooltip text and aria label for the Close button icon.
*/
closeIconDescription: prop_types.default.string,
/**
* Text label for the Collapse button.
*/
collapseButtonLabel: prop_types.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: prop_types.default.bool,
/**
* Text label for the Expand button.
*/
expandButtonLabel: prop_types.default.string,
/**
* Tooltip text and aria label for the Next button icon.
*/
nextIconDescription: prop_types.default.string,
/**
* A handler for managing the controlled state of open prop. If not passed the open prop will not be honored and an uncontrolled state will be used.
*/
onChange: prop_types.default.func,
/**
* If defined, a Close button will render in the top-right corner and a
* callback function will be triggered when button is clicked.
*/
onClose: prop_types.default.func,
/**
* Specify whether the Guidebanner is currently open.
*/
open: prop_types.default.bool,
/**
* Tooltip text and aria label for the Back button icon.
*/
previousIconDescription: prop_types.default.string,
/**
* Title text.
*/
title: prop_types.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: prop_types.default.bool
};
//#endregion
exports.Guidebanner = Guidebanner;