UNPKG

@carbon/ibm-products

Version:
232 lines (230 loc) 9.27 kB
/** * 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_devtools = require("../../global/js/utils/devtools.js"); const require_uuidv4 = require("../../global/js/utils/uuidv4.js"); const require_ChecklistChart = require("./ChecklistChart.js"); const require_ChecklistIcon = require("./ChecklistIcon.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/Checklist/Checklist.tsx /** * Copyright IBM Corp. 2023, 2024 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ /** * TODO: Breakdown titles, icons, clickable items into sub-components * See * ModifiedTabs (ModifiedTabLabelNew, ModifiedTabLabelWithClose) * PageHeader (PageHeaderTitle, PageHeaderUtils) */ var import_classnames = /* @__PURE__ */ require_runtime.__toESM(require_index.default); const blockClass = `${require_settings.pkg.prefix}--checklist`; const componentName = "Checklist"; const defaults = { checklistAriaLabel: "Checklist", checklistToggleAriaLabel: "Checklist toggle", onClickViewAll: () => {}, onToggle: () => {}, open: true, enableToggle: true, taskLists: [], theme: "light", toggleLabel: "Toggle" }; /** * The Checklist tracks a user's progress much like Your Learning or * WalkMe. Each item in the list can be clickable, and each item has * an icon that defines the item's state as "not started", "in progress", * and "complete". */ const Checklist = react.default.forwardRef(({ chartValue, chartLabel, checklistAriaLabel = defaults.checklistAriaLabel, checklistToggleAriaLabel = defaults.checklistToggleAriaLabel, className, onClickViewAll = defaults.onClickViewAll, onToggle = defaults.onToggle, open = defaults.open, enableToggle = defaults.enableToggle, taskLists = defaults.taskLists, theme = defaults.theme, title, toggleLabel = defaults.toggleLabel, toggleLabelAlign = "top", viewAllLabel, ...rest }, ref) => { const [isOpen, setIsOpen] = (0, react.useState)(open); const listContainerId = (0, react.useRef)(require_uuidv4.default()).current; const chartLabelId = (0, react.useRef)(require_uuidv4.default()).current; const chartLabelAndValue = typeof chartValue === "number" && chartLabel; const handleClickToggle = () => { setIsOpen((prevOpen) => !prevOpen); }; const handleClickViewAll = () => { onClickViewAll(); }; (0, react.useEffect)(() => { onToggle(isOpen); }, [isOpen, onToggle]); (0, react.useEffect)(() => { setIsOpen(open); }, [open]); return /* @__PURE__ */ react.default.createElement(_carbon_react.Section, { ...rest, "aria-label": checklistAriaLabel, as: "aside", className: (0, import_classnames.default)(blockClass, className, { [`${blockClass}__closed`]: !isOpen }), ref, ...require_devtools.getDevtoolsProps(componentName) }, (title || chartLabelAndValue) && /* @__PURE__ */ react.default.createElement("header", { className: `${blockClass}__header` }, chartLabelAndValue && /* @__PURE__ */ react.default.createElement(require_ChecklistChart.ChecklistChart, { "aria-labelledby": chartLabelId, theme, value: chartValue }), /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__titles` }, title && /* @__PURE__ */ react.default.createElement(_carbon_react.Heading, { className: `${blockClass}__title` }, title), chartLabelAndValue && /* @__PURE__ */ react.default.createElement("p", { id: chartLabelId, className: `${blockClass}__chart-label` }, chartLabel)), enableToggle && /* @__PURE__ */ react.default.createElement(_carbon_react.IconButton, { align: toggleLabelAlign, "aria-controls": listContainerId, "aria-expanded": isOpen, "aria-label": checklistToggleAriaLabel, className: `${blockClass}__toggle`, kind: "ghost", label: toggleLabel, onClick: handleClickToggle, size: "sm" }, /* @__PURE__ */ react.default.createElement(_carbon_react_icons.ChevronUp, { size: 16, className: (0, import_classnames.default)(`${blockClass}__chevron`) }))), /* @__PURE__ */ react.default.createElement("div", { id: listContainerId, className: `${blockClass}__content-outer` }, /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__content-inner` }, /* @__PURE__ */ react.default.createElement("div", { className: (0, import_classnames.default)(`${blockClass}__body`) }, taskLists.map((list, index) => { return /* @__PURE__ */ react.default.createElement(_carbon_react.Section, { className: `${blockClass}__list-group`, key: `${list.title}-${index}` }, list.title && /* @__PURE__ */ react.default.createElement(_carbon_react.Heading, { title: list.title, className: `${blockClass}__list-title` }, list.title), /* @__PURE__ */ react.default.createElement("ol", { className: `${blockClass}__list` }, list.tasks.map((item, index) => { return /* @__PURE__ */ react.default.createElement("li", { className: `${blockClass}__list-item`, key: `${item.label}-${index}` }, /* @__PURE__ */ react.default.createElement(require_ChecklistIcon.ChecklistIcon, { kind: item.kind, theme }), typeof item.onClick === "function" ? /* @__PURE__ */ react.default.createElement(_carbon_react.Button, { className: (0, import_classnames.default)(`${blockClass}__button`, { [`${blockClass}__button--error`]: item.kind === "error" }), onClick: () => { item.onClick?.(item); }, size: "sm", title: item.label }, /* @__PURE__ */ react.default.createElement("div", null, item.label)) : /* @__PURE__ */ react.default.createElement("div", { className: (0, import_classnames.default)(`${blockClass}__label`, `${blockClass}__label--${item.kind}`), title: item.label }, item.label)); }))); })), viewAllLabel && /* @__PURE__ */ react.default.createElement("footer", { className: `${blockClass}__footer` }, /* @__PURE__ */ react.default.createElement(_carbon_react.Button, { className: (0, import_classnames.default)(`${blockClass}__button`, `${blockClass}__view-all`), onClick: handleClickViewAll, size: "sm" }, /* @__PURE__ */ react.default.createElement("div", null, viewAllLabel)))))); }); Checklist.displayName = componentName; Checklist.propTypes = { /** * Define both `chartLabel` and `chartValue` to show the chart and its label together. */ chartLabel: prop_types.default.node, /** * A number between 0 and 1. * * Define both `chartLabel` and `chartValue` to show the chart and its label together. */ chartValue: prop_types.default.number, /** * Aria-label for the Checklist component. */ checklistAriaLabel: prop_types.default.string, /** * Aria-label for the Checklist's toggle component. */ checklistToggleAriaLabel: prop_types.default.string, /** * Provide an optional class to be applied to the containing node. */ className: prop_types.default.string, /** * Whether or not to show the open/close toggle. */ enableToggle: prop_types.default.bool, /** * Callback for the "View all" button. See also `viewAllLabel`. */ onClickViewAll: prop_types.default.func, /** * Optional callback for when the list is opened/closed. */ onToggle: prop_types.default.func, /** * Specifies whether the component is opened or closed. * This can be set during initialization, or changed after being rendered. */ open: prop_types.default.bool, /** * The task list can be broken down into sub-lists. * * Each sub-list can include an optional `title`. * * Each task must specify the appropriate icon (`kind`) and `label`. * * If any task has an `onClick` callback function defined, * then the `label` will be rendered as a button, * else the `label` will be rendered as plain text. */ /**@ts-ignore */ taskLists: prop_types.default.arrayOf(prop_types.default.shape({ title: prop_types.default.string, tasks: prop_types.default.arrayOf(prop_types.default.shape({ kind: prop_types.default.oneOf([ "unchecked", "indeterminate", "checked", "disabled", "error" ]).isRequired, label: prop_types.default.string.isRequired, onClick: prop_types.default.func })).isRequired })).isRequired, /** * Determines the theme of the component. */ theme: prop_types.default.oneOf(["light", "dark"]), /** * The title of the component. */ title: prop_types.default.node, /** * The label for the toggle's tooltip. */ toggleLabel: prop_types.default.string, /** * The alignment of the toggle's tooltip. */ toggleLabelAlign: prop_types.default.oneOf([ "top", "top-left", "top-right", "bottom", "bottom-left", "bottom-right", "left", "right" ]), /** * If defined, will show and enable the "View all (#)" button at the bottom of the list. */ viewAllLabel: prop_types.default.string }; //#endregion exports.Checklist = Checklist;