UNPKG

@navikt/ds-react

Version:

React components from the Norwegian Labour and Welfare Administration.

184 lines 9.49 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ProcessEvent = exports.Process = void 0; const react_1 = __importStar(require("react")); const Theme_1 = require("../theme/Theme"); const typography_1 = require("../typography"); const util_1 = require("../util"); const create_context_1 = require("../util/create-context"); const hooks_1 = require("../util/hooks"); const i18n_hooks_1 = require("../util/i18n/i18n.hooks"); const [ProcessContextProvider, useProcessContext] = (0, create_context_1.createContext)({ providerName: "ProcessContextProvider", hookName: "useProcessContext", name: "ProcessContext", errorMessage: "`<Process.Event />` must be used within a `<Process />` component.", }); /** * A component that presents a Process as a vertical line of events. * Each event can contain information, actions, links or status indicators. * * @see [📝 Documentation](https://aksel.nav.no/komponenter/core/process) * @see 🏷️ {@link ProcessProps} * * @example * ```jsx * <> * <Heading size="medium" spacing level="2" id="Process-heading"> * Søknadssteg * </Heading> * <Process * aria-labelledby="Process-heading" * activeStep={activeStep} * > * <Process.Event title="Start søknad" timestamp="21. august 2025" /> * <Process.Event * title="Saksopplysninger" * timestamp="22. august 2025" * icon={<PaperclipIcon />} * > * Saksopplysninger er sendt inn * </Process.Event> * <Process.Event * title="Vedlegg" * timestamp="25. august 2025" * > * <h3> Vedlegg er lastet opp </h3> * <p> * Dokumentasjon av saksopplysninger er lastet opp og tilgjengelig for * saksbehandler. * </p> * </Process.Event> * <Process.Event title="Vedtak" timestamp="8. september 2025"> * Det er gjort endelig vedtak i saken * </Process.Event> * </Process> * </> * ``` */ exports.Process = (0, react_1.forwardRef)((_a, forwardedRef) => { var { children, className, hideStatusText = false, id, isTruncated } = _a, restProps = __rest(_a, ["children", "className", "hideStatusText", "id", "isTruncated"]); const { cn } = (0, Theme_1.useRenameCSS)(); const rootId = (0, util_1.useId)(id); const rootRef = (0, react_1.useRef)(null); const mergedRef = (0, hooks_1.useMergeRefs)(forwardedRef, rootRef); const [activeChildId, setActiveChildId] = (0, react_1.useState)(undefined); const syncAriaControls = (0, react_1.useCallback)(() => { var _a; const activeChildren = (_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll('[data-process-event][aria-current="true"]'); if (!activeChildren) { setActiveChildId(undefined); return; } if (activeChildren.length > 1) { if (process.env.NODE_ENV !== "production") { console.warn("Aksel: Found multiple `<Process.Event />` elements with `status='active'`. Only one event should be active at a time.", rootRef.current); } setActiveChildId(undefined); return; } if (activeChildren.length === 1) { const lastActiveChild = activeChildren[activeChildren.length - 1]; setActiveChildId(lastActiveChild.id); } else { setActiveChildId(undefined); } }, []); return ( // `<ol />` elements with `list-style: none;` tends to be ignored by voiceover on Safari. // To resolve this, we add `role="list"` to the `<ol />` element. // eslint-disable-next-line jsx-a11y/no-redundant-roles react_1.default.createElement("ol", Object.assign({ ref: mergedRef, "data-color": "info", // biome-ignore lint/a11y/noRedundantRoles: See comment above role: "list" }, restProps, { className: cn("navds-process", className), id: rootId, "aria-controls": activeChildId, "data-truncated": isTruncated }), react_1.default.createElement(ProcessContextProvider, { hideStatusText: hideStatusText, rootId: rootId, syncAriaControls: syncAriaControls }, children))); }); exports.ProcessEvent = (0, react_1.forwardRef)((_a, forwardedRef) => { var { title, timestamp, children, bullet, hideContent, className, id, status = "uncompleted" } = _a, restProps = __rest(_a, ["title", "timestamp", "children", "bullet", "hideContent", "className", "id", "status"]); const translate = (0, i18n_hooks_1.useI18n)("Process"); const { cn } = (0, Theme_1.useRenameCSS)(); const eventId = (0, util_1.useId)(); const { syncAriaControls, hideStatusText, rootId } = useProcessContext(); // syncAriaControls is already memoized with useCallback // biome-ignore lint/correctness/useExhaustiveDependencies: We want to run this only when status changes (0, react_1.useEffect)(syncAriaControls, [status]); // eslint-disable-line react-hooks/exhaustive-deps const isActive = status === "active"; return (react_1.default.createElement("li", Object.assign({ ref: forwardedRef, "aria-current": isActive, id: id !== null && id !== void 0 ? id : eventId }, restProps, { "aria-controls": isActive ? rootId : undefined, className: cn("navds-process__event", className), "data-dot": bullet === undefined, "data-process-event": "", "data-status": status }), react_1.default.createElement(ProcessLine, { position: "start" }), react_1.default.createElement("div", { className: cn("navds-process__item") }, react_1.default.createElement(ProcessBullet, null, bullet), react_1.default.createElement("div", { className: cn("navds-process__body") }, title && react_1.default.createElement(ProcessTitle, null, title), isActive && !hideStatusText && (react_1.default.createElement(typography_1.BodyShort, { size: "small", className: cn("navds-process__active-label") }, translate("active"))), timestamp && react_1.default.createElement(ProcessTimestamp, null, timestamp), !hideContent && !!children && (react_1.default.createElement(ProcessContent, null, children)))), react_1.default.createElement(ProcessLine, { position: "end" }))); }); const ProcessTitle = ({ children }) => { const { cn } = (0, Theme_1.useRenameCSS)(); return (react_1.default.createElement(typography_1.Heading, { size: "small", as: "div", className: cn("navds-process__title") }, children)); }; const ProcessTimestamp = ({ children }) => { const { cn } = (0, Theme_1.useRenameCSS)(); return (react_1.default.createElement(typography_1.BodyShort, { spacing: true, as: "div", size: "small", textColor: "subtle", className: cn("navds-process__timestamp") }, children)); }; const ProcessContent = ({ children }) => { const { cn } = (0, Theme_1.useRenameCSS)(); return (react_1.default.createElement(typography_1.BodyLong, { as: "div", className: cn("navds-process__content") }, children)); }; const ProcessBullet = ({ children }) => { const { cn } = (0, Theme_1.useRenameCSS)(); return (react_1.default.createElement(typography_1.BodyShort, { as: "span", weight: "semibold", className: cn("navds-process__bullet"), "aria-hidden": true }, children)); }; const ProcessLine = ({ position }) => { const { cn } = (0, Theme_1.useRenameCSS)(); return (react_1.default.createElement("span", { className: cn("navds-process__line"), "data-position": position })); }; /* -------------------------- Process exports ------------------------- */ exports.Process.Event = exports.ProcessEvent; //# sourceMappingURL=Process.js.map