@octaviaflow/core 3.0.11 → 3.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,49 @@
1
1
  import { type ReactNode } from "react";
2
2
  export interface AuthCardProps {
3
3
  logo?: ReactNode;
4
- title: ReactNode;
4
+ title?: ReactNode;
5
5
  description?: ReactNode;
6
6
  /** Small badge rendered next to the title (e.g. "Organization"). */
7
7
  scope?: ReactNode;
8
+ /**
9
+ * Fully custom header that REPLACES the auto-built logo + title +
10
+ * description block. Use when the default head structure isn't enough
11
+ * (split-screen layouts, custom hero treatments, etc.). When provided,
12
+ * `logo`, `title`, `description`, and `scope` are ignored.
13
+ */
14
+ header?: ReactNode;
15
+ /**
16
+ * Extra content rendered immediately after the description, before the
17
+ * body. Common uses: step indicator ("Step 2 of 3"), breadcrumb,
18
+ * informational chip.
19
+ */
20
+ headerExtra?: ReactNode;
21
+ /**
22
+ * When set, an error Banner is rendered above the body — same Banner
23
+ * the consumer would otherwise hand-roll. Pass `false` / `null` /
24
+ * `undefined` to hide. Accepts the same ReactNode shape Banner expects
25
+ * for its body.
26
+ */
27
+ error?: ReactNode;
28
+ /** Same as `error` but renders a success Banner. */
29
+ success?: ReactNode;
30
+ /**
31
+ * Header alignment. Default `"center"` matches the OctaviaFlow auth
32
+ * convention (centered logo + title). Use `"left"` for split-screen or
33
+ * marketing-heavy layouts where the auth card sits next to other content.
34
+ */
35
+ align?: "center" | "left";
36
+ /**
37
+ * Card width override. Default 400px (matches the historical default).
38
+ * Pass a number (px) or any CSS length string (e.g. "440px", "32rem").
39
+ */
40
+ width?: number | string;
8
41
  children: ReactNode;
9
42
  divider?: ReactNode;
10
43
  footer?: ReactNode;
11
44
  className?: string;
12
45
  }
13
- export declare function AuthCard({ logo, title, description, scope, children, divider, footer, className, }: AuthCardProps): import("react/jsx-runtime").JSX.Element;
46
+ export declare function AuthCard({ logo, title, description, scope, header, headerExtra, error, success, align, width, children, divider, footer, className, }: AuthCardProps): import("react/jsx-runtime").JSX.Element;
14
47
  export interface AuthDividerProps {
15
48
  children?: ReactNode;
16
49
  className?: string;
@@ -38,6 +71,13 @@ export interface AuthTabsProps {
38
71
  className?: string;
39
72
  }
40
73
  export declare function AuthTabs({ tabs, defaultTab, value, onChange, className }: AuthTabsProps): import("react/jsx-runtime").JSX.Element;
74
+ export interface AuthFieldRowProps {
75
+ children: ReactNode;
76
+ /** Grid template columns. Default: "1fr 1fr". */
77
+ columns?: string;
78
+ className?: string;
79
+ }
80
+ export declare function AuthFieldRow({ children, columns, className }: AuthFieldRowProps): import("react/jsx-runtime").JSX.Element;
41
81
  export type AuthBadgeTone = "neutral" | "org" | "personal" | "developer";
42
82
  export interface AuthBadgeProps {
43
83
  tone?: AuthBadgeTone;
@@ -1 +1 @@
1
- {"version":3,"file":"AuthCard.d.ts","sourceRoot":"","sources":["../../../src/components/AuthCard/AuthCard.tsx"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,SAAS,EAA2B,MAAM,OAAO,CAAC;AAGpF,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,oEAAoE;IACpE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,OAAO,EACP,MAAM,EACN,SAAS,GACV,EAAE,aAAa,2CAgBf;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,QAAe,EAAE,SAAS,EAAE,EAAE,gBAAgB,2CAQ3E;AAKD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,gBAAgB,2CAYxF;AAKD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,aAAa,2CA6EvF;AAKD,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,WAAW,CAAC;AAEzE,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,EAAE,IAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,cAAc,2CAIlF"}
1
+ {"version":3,"file":"AuthCard.d.ts","sourceRoot":"","sources":["../../../src/components/AuthCard/AuthCard.tsx"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export { AuthBadge, type AuthBadgeProps, type AuthBadgeTone, AuthCard, type AuthCardProps, AuthDivider, type AuthDividerProps, AuthSection, type AuthSectionProps, type AuthTab, AuthTabs, type AuthTabsProps, } from "./AuthCard";
1
+ export { AuthBadge, type AuthBadgeProps, type AuthBadgeTone, AuthCard, type AuthCardProps, AuthDivider, type AuthDividerProps, AuthFieldRow, type AuthFieldRowProps, AuthSection, type AuthSectionProps, type AuthTab, AuthTabs, type AuthTabsProps, } from "./AuthCard";
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/AuthCard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,QAAQ,EACR,KAAK,aAAa,EAClB,WAAW,EACX,KAAK,gBAAgB,EACrB,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,OAAO,EACZ,QAAQ,EACR,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/AuthCard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,QAAQ,EACR,KAAK,aAAa,EAClB,WAAW,EACX,KAAK,gBAAgB,EACrB,YAAY,EACZ,KAAK,iBAAiB,EACtB,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,OAAO,EACZ,QAAQ,EACR,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC"}
@@ -19,6 +19,18 @@ export interface DropdownMenuProps {
19
19
  * supplies its own button styling.
20
20
  */
21
21
  triggerClassName?: string;
22
+ /**
23
+ * Close the menu when the user clicks (mousedown) outside both the menu
24
+ * and the trigger. Default: true — the standard popover behaviour users
25
+ * expect. Disable only when you need an explicitly-controlled menu
26
+ * (e.g. anchored to a different dismissal flow).
27
+ */
28
+ closeOnOutsideClick?: boolean;
29
+ /**
30
+ * Close the menu when the user presses Escape. Default: true.
31
+ * Disable only if Escape is needed by a parent surface.
32
+ */
33
+ closeOnEscape?: boolean;
22
34
  /**
23
35
  * Accessible name for the trigger button. Required when `trigger` is not
24
36
  * a plain string (e.g. an icon-only trigger). When omitted and `trigger`
@@ -28,5 +40,5 @@ export interface DropdownMenuProps {
28
40
  /** id of an element that labels the trigger; alternative to aria-label. */
29
41
  "aria-labelledby"?: string;
30
42
  }
31
- export declare function DropdownMenu({ trigger, items, align, className, triggerClassName, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, }: DropdownMenuProps): import("react/jsx-runtime").JSX.Element;
43
+ export declare function DropdownMenu({ trigger, items, align, className, triggerClassName, closeOnOutsideClick, closeOnEscape, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, }: DropdownMenuProps): import("react/jsx-runtime").JSX.Element;
32
44
  //# sourceMappingURL=DropdownMenu.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../../src/components/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAU,MAAM,OAAO,CAAC;AAQ/C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,SAAS,CAAC;IACnB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAsID,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,KAAK,EACL,KAAe,EACf,SAAS,EACT,gBAAgB,EAChB,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,GAClC,EAAE,iBAAiB,2CA0CnB"}
1
+ {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../../src/components/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,OAAO,CAAC;AAQ1D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,SAAS,CAAC;IACnB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AA8KD,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,KAAK,EACL,KAAe,EACf,SAAS,EACT,gBAAgB,EAChB,mBAA0B,EAC1B,aAAoB,EACpB,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,GAClC,EAAE,iBAAiB,2CA4CnB"}
package/dist/index.cjs CHANGED
@@ -372,24 +372,89 @@ function AuthCard({
372
372
  title,
373
373
  description,
374
374
  scope,
375
+ header,
376
+ headerExtra,
377
+ error,
378
+ success,
379
+ align = "center",
380
+ width,
375
381
  children,
376
382
  divider,
377
383
  footer,
378
384
  className
379
385
  }) {
380
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cn("ods-auth-card", className), children: [
381
- logo && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "ods-auth-card__logo", children: logo }),
382
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "ods-auth-card__head", children: [
383
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "ods-auth-card__title-row", children: [
384
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "ods-auth-card__title", children: title }),
385
- scope && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "ods-auth-card__scope", children: scope })
386
- ] }),
387
- description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "ods-auth-card__desc", children: description })
388
- ] }),
389
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "ods-auth-card__body", children }),
390
- divider && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "ods-auth-card__divider", children: divider }),
391
- footer && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "ods-auth-card__footer", children: footer })
392
- ] });
386
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
387
+ "div",
388
+ {
389
+ className: cn(
390
+ "ods-auth-card",
391
+ align === "left" && "ods-auth-card--left",
392
+ className
393
+ ),
394
+ style: width != null ? { width: typeof width === "number" ? `${width}px` : width } : void 0,
395
+ children: [
396
+ header ?? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
397
+ logo && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "ods-auth-card__logo", children: logo }),
398
+ (title || description || scope) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "ods-auth-card__head", children: [
399
+ (title || scope) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "ods-auth-card__title-row", children: [
400
+ title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "ods-auth-card__title", children: title }),
401
+ scope && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "ods-auth-card__scope", children: scope })
402
+ ] }),
403
+ description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "ods-auth-card__desc", children: description })
404
+ ] })
405
+ ] }),
406
+ headerExtra && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "ods-auth-card__header-extra", children: headerExtra }),
407
+ (error || success) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
408
+ "div",
409
+ {
410
+ className: "ods-auth-card__messages",
411
+ style: {
412
+ display: "flex",
413
+ flexDirection: "column",
414
+ gap: "var(--ods-space-2)"
415
+ },
416
+ children: [
417
+ error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AutoBanner, { variant: "error", children: error }),
418
+ success && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AutoBanner, { variant: "success", children: success })
419
+ ]
420
+ }
421
+ ),
422
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "ods-auth-card__body", children }),
423
+ divider && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "ods-auth-card__divider", children: divider }),
424
+ footer && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "ods-auth-card__footer", children: footer })
425
+ ]
426
+ }
427
+ );
428
+ }
429
+ function AutoBanner({
430
+ variant,
431
+ children
432
+ }) {
433
+ const tone = variant === "error" ? {
434
+ bg: "var(--ods-status-error-bg)",
435
+ fg: "var(--ods-status-error-fg)",
436
+ bd: "var(--ods-status-error-bd)"
437
+ } : {
438
+ bg: "var(--ods-status-success-bg)",
439
+ fg: "var(--ods-status-success-fg)",
440
+ bd: "var(--ods-status-success-bd)"
441
+ };
442
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
443
+ "div",
444
+ {
445
+ role: variant === "error" ? "alert" : "status",
446
+ style: {
447
+ padding: "10px 12px",
448
+ background: tone.bg,
449
+ color: tone.fg,
450
+ border: `1px solid ${tone.bd}`,
451
+ borderRadius: "var(--ods-radius-1)",
452
+ fontSize: 13,
453
+ lineHeight: 1.45
454
+ },
455
+ children
456
+ }
457
+ );
393
458
  }
394
459
  function AuthDivider({ children = "OR", className }) {
395
460
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cn("ods-auth-divider", className), children: [
@@ -6525,9 +6590,37 @@ function MenuPopup({
6525
6590
  menuItems,
6526
6591
  triggerRef,
6527
6592
  align,
6528
- className
6593
+ className,
6594
+ closeOnOutsideClick,
6595
+ closeOnEscape
6529
6596
  }) {
6530
6597
  const menuRef = (0, import_react31.useRef)(null);
6598
+ (0, import_react31.useEffect)(() => {
6599
+ if (!state.isOpen || !closeOnOutsideClick) return;
6600
+ const handler = (e) => {
6601
+ const target = e.target;
6602
+ if (!target) return;
6603
+ const insideMenu = menuRef.current?.contains(target);
6604
+ const insideTrigger = triggerRef.current?.contains(target);
6605
+ if (!insideMenu && !insideTrigger) {
6606
+ state.close();
6607
+ }
6608
+ };
6609
+ document.addEventListener("mousedown", handler, true);
6610
+ return () => document.removeEventListener("mousedown", handler, true);
6611
+ }, [state.isOpen, closeOnOutsideClick]);
6612
+ (0, import_react31.useEffect)(() => {
6613
+ if (!state.isOpen || !closeOnEscape) return;
6614
+ const handler = (e) => {
6615
+ if (e.key === "Escape") {
6616
+ e.stopPropagation();
6617
+ state.close();
6618
+ triggerRef.current?.focus();
6619
+ }
6620
+ };
6621
+ document.addEventListener("keydown", handler);
6622
+ return () => document.removeEventListener("keydown", handler);
6623
+ }, [state.isOpen, closeOnEscape]);
6531
6624
  const nonSepItems = menuItems.filter((i) => !i.separator);
6532
6625
  const children = nonSepItems.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)($05678f3aee5e7d1a$export$6d08773d2e66f8f2, { textValue: item.label, children: item.label }, idx));
6533
6626
  const treeState = $6b915bde6cd300dd$export$728d6ba534403756({
@@ -6607,6 +6700,8 @@ function DropdownMenu({
6607
6700
  align = "start",
6608
6701
  className,
6609
6702
  triggerClassName,
6703
+ closeOnOutsideClick = true,
6704
+ closeOnEscape = true,
6610
6705
  "aria-label": ariaLabel,
6611
6706
  "aria-labelledby": ariaLabelledby
6612
6707
  }) {
@@ -6641,7 +6736,9 @@ function DropdownMenu({
6641
6736
  menuItems: items,
6642
6737
  triggerRef,
6643
6738
  align,
6644
- className
6739
+ className,
6740
+ closeOnOutsideClick,
6741
+ closeOnEscape
6645
6742
  }
6646
6743
  )
6647
6744
  ] });
@@ -11497,8 +11594,9 @@ function RailItem({
11497
11594
  tooltipDelay,
11498
11595
  suppressTooltip
11499
11596
  }) {
11500
- const [tipOpen, setTipOpen] = (0, import_react53.useState)(false);
11597
+ const [open, setOpen] = (0, import_react53.useState)(false);
11501
11598
  const timerRef = (0, import_react53.useRef)(null);
11599
+ const hasChildren = !!(item.children && item.children.length > 0);
11502
11600
  const clear = () => {
11503
11601
  if (timerRef.current) {
11504
11602
  clearTimeout(timerRef.current);
@@ -11509,11 +11607,11 @@ function RailItem({
11509
11607
  const show = () => {
11510
11608
  if (suppressTooltip) return;
11511
11609
  clear();
11512
- timerRef.current = setTimeout(() => setTipOpen(true), tooltipDelay);
11610
+ timerRef.current = setTimeout(() => setOpen(true), tooltipDelay);
11513
11611
  };
11514
11612
  const hide = () => {
11515
11613
  clear();
11516
- setTipOpen(false);
11614
+ setOpen(false);
11517
11615
  };
11518
11616
  const Comp = item.href ? "a" : "button";
11519
11617
  const labelText = typeof item.label === "string" ? item.label : void 0;
@@ -11532,13 +11630,20 @@ function RailItem({
11532
11630
  type: item.href ? void 0 : "button",
11533
11631
  href: item.href,
11534
11632
  onClick: item.onClick,
11535
- className: cn("ods-sidebar__rail-item", item.active && "ods-sidebar__rail-item--active"),
11633
+ className: cn(
11634
+ "ods-sidebar__rail-item",
11635
+ hasChildren && "ods-sidebar__rail-item--parent",
11636
+ item.active && "ods-sidebar__rail-item--active"
11637
+ ),
11536
11638
  "aria-current": item.active ? "page" : void 0,
11537
11639
  "aria-label": labelText,
11640
+ "aria-haspopup": hasChildren ? "menu" : void 0,
11641
+ "aria-expanded": hasChildren ? open : void 0,
11538
11642
  children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "ods-sidebar__rail-icon", children: item.icon })
11539
11643
  }
11540
11644
  ),
11541
- tipOpen && labelText && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "ods-sidebar__rail-tooltip", role: "tooltip", children: [
11645
+ open && labelText && hasChildren && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(RailFlyout, { title: labelText, items: item.children ?? [] }),
11646
+ open && labelText && !hasChildren && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "ods-sidebar__rail-tooltip", role: "tooltip", children: [
11542
11647
  /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "ods-sidebar__rail-tooltip-label", children: labelText }),
11543
11648
  item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("kbd", { className: "ods-sidebar__rail-kbd", children: item.shortcut })
11544
11649
  ] })
@@ -11546,6 +11651,34 @@ function RailItem({
11546
11651
  }
11547
11652
  );
11548
11653
  }
11654
+ function RailFlyout({ title, items }) {
11655
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "ods-sidebar__rail-flyout", role: "menu", children: [
11656
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "ods-sidebar__rail-flyout-header", children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "ods-sidebar__rail-flyout-title", children: title }) }),
11657
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("ul", { className: "ods-sidebar__rail-flyout-list", children: items.map((child) => {
11658
+ const ChildComp = child.href ? "a" : "button";
11659
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
11660
+ ChildComp,
11661
+ {
11662
+ type: child.href ? void 0 : "button",
11663
+ href: child.href,
11664
+ onClick: child.onClick,
11665
+ role: "menuitem",
11666
+ className: cn(
11667
+ "ods-sidebar__rail-flyout-item",
11668
+ child.active && "ods-sidebar__rail-flyout-item--active"
11669
+ ),
11670
+ "aria-current": child.active ? "page" : void 0,
11671
+ children: [
11672
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "ods-sidebar__rail-flyout-icon", children: child.icon }),
11673
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "ods-sidebar__rail-flyout-label", children: child.label }),
11674
+ child.tag && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "ods-sidebar__rail-flyout-tag", children: child.tag }),
11675
+ child.badge && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "ods-sidebar__rail-flyout-badge", children: child.badge })
11676
+ ]
11677
+ }
11678
+ ) }, child.id);
11679
+ }) })
11680
+ ] });
11681
+ }
11549
11682
  function ExpandedLayout({
11550
11683
  logo,
11551
11684
  brand,