@mortenbrudvik/waveui 0.13.0 → 0.14.1

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.
Files changed (83) hide show
  1. package/README.md +302 -49
  2. package/dist/components/data-display/Avatar.context.cjs.map +1 -1
  3. package/dist/components/data-display/Avatar.context.mjs.map +1 -1
  4. package/dist/components/data-display/List.cjs +1 -1
  5. package/dist/components/data-display/List.cjs.map +1 -1
  6. package/dist/components/data-display/List.mjs +245 -195
  7. package/dist/components/data-display/List.mjs.map +1 -1
  8. package/dist/components/data-display/List.registry.cjs.map +1 -1
  9. package/dist/components/data-display/List.registry.mjs.map +1 -1
  10. package/dist/components/layout/Overflow.cjs +1 -1
  11. package/dist/components/layout/Overflow.cjs.map +1 -1
  12. package/dist/components/layout/Overflow.mjs +240 -192
  13. package/dist/components/layout/Overflow.mjs.map +1 -1
  14. package/dist/components/layout/Overflow.store.cjs +2 -0
  15. package/dist/components/layout/Overflow.store.cjs.map +1 -0
  16. package/dist/components/layout/Overflow.store.mjs +209 -0
  17. package/dist/components/layout/Overflow.store.mjs.map +1 -0
  18. package/dist/components/navigation/Breadcrumb.cjs +1 -1
  19. package/dist/components/navigation/Breadcrumb.cjs.map +1 -1
  20. package/dist/components/navigation/Breadcrumb.mjs +239 -84
  21. package/dist/components/navigation/Breadcrumb.mjs.map +1 -1
  22. package/dist/components/overlays/Dialog.slots.cjs +1 -1
  23. package/dist/components/overlays/Dialog.slots.cjs.map +1 -1
  24. package/dist/components/overlays/Dialog.slots.mjs +19 -15
  25. package/dist/components/overlays/Dialog.slots.mjs.map +1 -1
  26. package/dist/components/overlays/TeachingPopover.cjs +1 -1
  27. package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
  28. package/dist/components/overlays/TeachingPopover.context.cjs +2 -0
  29. package/dist/components/overlays/TeachingPopover.context.cjs.map +1 -0
  30. package/dist/components/overlays/TeachingPopover.context.mjs +51 -0
  31. package/dist/components/overlays/TeachingPopover.context.mjs.map +1 -0
  32. package/dist/components/overlays/TeachingPopover.mjs +15 -185
  33. package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
  34. package/dist/components/overlays/TeachingPopover.parts.cjs +2 -0
  35. package/dist/components/overlays/TeachingPopover.parts.cjs.map +1 -0
  36. package/dist/components/overlays/TeachingPopover.parts.mjs +405 -0
  37. package/dist/components/overlays/TeachingPopover.parts.mjs.map +1 -0
  38. package/dist/components/overlays/TeachingPopover.root.cjs +2 -0
  39. package/dist/components/overlays/TeachingPopover.root.cjs.map +1 -0
  40. package/dist/components/overlays/TeachingPopover.root.mjs +158 -0
  41. package/dist/components/overlays/TeachingPopover.root.mjs.map +1 -0
  42. package/dist/components/overlays/TeachingPopover.stack.cjs +2 -0
  43. package/dist/components/overlays/TeachingPopover.stack.cjs.map +1 -0
  44. package/dist/components/overlays/TeachingPopover.stack.mjs +86 -0
  45. package/dist/components/overlays/TeachingPopover.stack.mjs.map +1 -0
  46. package/dist/components/table/DataGrid.cjs +1 -1
  47. package/dist/components/table/DataGrid.cjs.map +1 -1
  48. package/dist/components/table/DataGrid.mjs +540 -311
  49. package/dist/components/table/DataGrid.mjs.map +1 -1
  50. package/dist/components/table/Table.cjs +1 -1
  51. package/dist/components/table/Table.cjs.map +1 -1
  52. package/dist/components/table/Table.mjs +183 -60
  53. package/dist/components/table/Table.mjs.map +1 -1
  54. package/dist/components/table/Table.shared.cjs +2 -0
  55. package/dist/components/table/Table.shared.cjs.map +1 -0
  56. package/dist/components/table/Table.shared.mjs +65 -0
  57. package/dist/components/table/Table.shared.mjs.map +1 -0
  58. package/dist/index.cjs +1 -1
  59. package/dist/index.d.cts +1755 -162
  60. package/dist/index.d.ts +1755 -162
  61. package/dist/index.mjs +135 -132
  62. package/dist/lib/breadcrumb.cjs +2 -0
  63. package/dist/lib/breadcrumb.cjs.map +1 -0
  64. package/dist/lib/breadcrumb.mjs +26 -0
  65. package/dist/lib/breadcrumb.mjs.map +1 -0
  66. package/dist/lib/classNames.cjs +1 -1
  67. package/dist/lib/classNames.cjs.map +1 -1
  68. package/dist/lib/classNames.mjs +66 -38
  69. package/dist/lib/classNames.mjs.map +1 -1
  70. package/dist/lib/events.cjs +1 -1
  71. package/dist/lib/events.cjs.map +1 -1
  72. package/dist/lib/events.mjs +35 -8
  73. package/dist/lib/events.mjs.map +1 -1
  74. package/dist/lib/icons.cjs +1 -1
  75. package/dist/lib/icons.cjs.map +1 -1
  76. package/dist/lib/icons.mjs +34 -20
  77. package/dist/lib/icons.mjs.map +1 -1
  78. package/dist/lib/table.cjs +2 -0
  79. package/dist/lib/table.cjs.map +1 -0
  80. package/dist/lib/table.mjs +16 -0
  81. package/dist/lib/table.mjs.map +1 -0
  82. package/dist/styles.css +1 -1
  83. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeachingPopover.parts.mjs","names":["_Fragment","React","isRefObject","target","isElementTarget","isVirtualTarget","resolveTarget","isButtonLikeElement","isElementOfType","action","Button","renderAction","activate","event","onActivate","own","ownAppearance","isWaveButton","cn","className","composeEventHandlers","onClick","appearance","resolved","resolveSlot","props","TeachingSurface","rest","context","announce","useAnnounce","titles","useTitleRegistry","stepTitle","step","hasTarget","surface","setSurface","pointsAtOneNow","value","targetResolved","setTargetResolved","elementAvailable","surfaceRef","targetRef","targetPropRef","availabilityRef","arrowRef","placedSide","usePopupPosition","shown","resolvePositioning","positioning","targetAvailable","anchorReady","isPositioned","visible","elementRef","useMergedRefs","ref","setFloating","element","setReference","latest","available","useDismiss","dismiss","triggerFocusRef","useTriggerFocusRef","triggerRef","onSurfaceKeyDown","usePopoverTabOrder","getTabbableThrough","announcedRef","previous","index","stepPosition","hasContent","slotRendersContent","children","ownId","id","Portal","titleId","footerLayout","hasTrigger","surfaceId","onKeyDown","floatingProps","style","rootClassName","focusRing","PopoverBeak","arrowStyles","teachingPopoverClassNames","TeachingPopoverSurfaceContext","Fragment","TeachingPopoverHeader","TeachingPopoverTitle","TeachingPopoverBody","TeachingPopoverFooter","TeachingPopoverTrigger","useTeachingPopoverContext","isClient","useIsClient","expanded","triggerElementRef","triggerProps","requestOpen","useTriggerElement","TeachingPopoverSurface","registerSurface","setCustomSurfaceId","teachingPopoverSurfaceClassNames","hasIcon","icon","hasCaption","teachingPopoverHeaderClassNames","renderSlot","materialiseSlotContent","ModalCloseButton","dismissButton","idProp","registry","registerTitle","register","node","mergedRef","as","teachingPopoverTitleClassNames","teachingPopoverBodyClassNames","media","vertical","teachingPopoverFooterClassNames","TeachingFooterContent","renderStepButtons","TeachingStepDots","secondary","primary","count","i","forcedColors","secondaryAction","goBack","isFirst","initialStepText","focusableDisabledProps","preventIfDisabled","backLabel","primaryAction","goNext","isLast","finalStepText","doneLabel","nextLabel","TeachingPopoverCarousel","teachingPopoverCarouselClassNames","TeachingPopoverCarouselFooter","TeachingPopoverCarouselNav","navLabel","teachingPopoverCarouselNavClassNames","current","navButtonLabel","goToStep","defaultPageCount","total","TeachingPopoverCarouselPageCount","text","teachingPopoverCarouselPageCountClassNames","centered","layout","footer","setFooter","footerRef","stacked","useCarouselFooterStacked","indicator","teachingPopoverCarouselFooterClassNames"],"sources":["../../../src/components/overlays/TeachingPopover.parts.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport {\n teachingPopoverBodyClassNames,\n teachingPopoverCarouselClassNames,\n teachingPopoverCarouselFooterClassNames,\n teachingPopoverCarouselNavClassNames,\n teachingPopoverCarouselPageCountClassNames,\n teachingPopoverClassNames,\n teachingPopoverFooterClassNames,\n teachingPopoverHeaderClassNames,\n teachingPopoverSurfaceClassNames,\n teachingPopoverTitleClassNames,\n} from '../../lib/classNames';\nimport { focusableDisabledProps, preventIfDisabled } from '../../lib/aria';\nimport { isElementOfType } from '../../lib/children';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport {\n materialiseSlotContent,\n renderSlot,\n resolveSlot,\n slotRendersContent,\n type Slot,\n} from '../../lib/slot';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport type { VirtualElement } from '../../lib/types';\nimport { useAnnounce } from '../../hooks/useAnnounce';\nimport { useDismiss } from '../../hooks/useDismiss';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { resolvePositioning, usePopupPosition } from '../../hooks/usePopupPosition';\nimport { useRestoreFocus } from '../../hooks/useRestoreFocus';\nimport { useTriggerElement, useTriggerFocusRef } from '../../hooks/useTriggerElement';\nimport { Button } from '../button/Button';\nimport { Portal } from '../portal/Portal';\nimport { useTitleRegistry } from './Dialog.shared';\nimport { ModalCloseButton } from './Dialog.slots';\nimport { getTabbableThrough, PopoverBeak, usePopoverTabOrder } from './Popover.shared';\nimport { useCarouselFooterStacked } from './TeachingPopover.stack';\nimport {\n TeachingPopoverSurfaceContext,\n useTeachingPopoverContext,\n type TeachingPopoverAction,\n type TeachingPopoverContextValue,\n type TeachingPopoverTarget,\n} from './TeachingPopover.context';\n\n/*\n * The TeachingPopover's parts and the surface they share with the root: `TeachingSurface` holds\n * the surface's hooks (positioning, dismissal, focus, keyboard order, announcements, the title\n * registry), so the `steps` form and `TeachingPopover.Surface` render one element the same way.\n * The content parts (Header, Title, Body, Footer) show the current step without children; the\n * `steps` form renders them that way (Pattern 15), so both forms render the same markup. The\n * carousel parts (Carousel, CarouselNav, CarouselPageCount, CarouselFooter) read the same state,\n * and both footers share the step dots and the step buttons. Imports the context module only\n * (never the root or `TeachingPopover.tsx`).\n */\n\n/**\n * Props a `TeachingPopover.Trigger` puts on its element; a render-prop child receives them (spread\n * them onto the element that opens the popover).\n */\nexport type TeachingPopoverTriggerChildProps = Omit<\n React.HTMLAttributes<HTMLElement>,\n 'children'\n> & {\n 'aria-haspopup': 'dialog';\n 'aria-expanded': boolean;\n /** The surface's id, only while the popover is open. */\n 'aria-controls': string | undefined;\n onClick: React.MouseEventHandler<HTMLElement>;\n ref: React.RefCallback<HTMLElement>;\n};\n\n/** Properties for the TeachingPopoverTrigger sub-component. */\nexport interface TeachingPopoverTriggerProps extends Omit<\n React.HTMLAttributes<HTMLElement>,\n 'children'\n> {\n /**\n * The element that opens and closes the popover (its props are merged onto it), or a render\n * function that receives the trigger props.\n */\n children: React.ReactNode | ((props: TeachingPopoverTriggerChildProps) => React.ReactNode);\n /**\n * `false` renders a wrapper `<span>` carrying the trigger props around the children instead of\n * merging them onto the child. `aria-haspopup`, `aria-expanded` and `aria-controls`, which a\n * generic element cannot carry, go to the first element in the tab order inside the span. A\n * render-prop child ignores `asChild` and receives every prop.\n * @default true\n */\n asChild?: boolean;\n /** Ref to the trigger element (the child, or the wrapper span). */\n ref?: React.Ref<HTMLElement>;\n}\n\n/** Properties for the TeachingPopoverSurface sub-component. */\nexport interface TeachingPopoverSurfaceProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The popover's content. Without children (or with children that render nothing) the surface\n * shows the current step as the `steps` form does: `TeachingPopover.Header`, `Title`, `Body` and\n * `Footer` without children of their own (the Close button, the step title, its body, and the\n * footer with the step dots and the buttons). Children replace all of that: build it from those\n * parts, each showing its share of the current step unless you give it children, or from your\n * own content. A `TeachingPopover.Title` among the children (at any depth) names the surface;\n * without one, name it with `aria-label` or `aria-labelledby`.\n */\n children?: React.ReactNode;\n /** Ref to the popover surface (`role=\"dialog\"`). */\n ref?: React.Ref<HTMLDivElement>;\n}\n\nfunction isRefObject(\n target: NonNullable<TeachingPopoverTarget>,\n): target is React.RefObject<HTMLElement | null> {\n return 'current' in target;\n}\n\nfunction isElementTarget(target: TeachingPopoverTarget | undefined): target is HTMLElement {\n return (\n target != null && !isRefObject(target) && typeof (target as Partial<Node>).nodeType === 'number'\n );\n}\n\nfunction isVirtualTarget(target: TeachingPopoverTarget | undefined): target is VirtualElement {\n return target != null && !isRefObject(target) && !isElementTarget(target);\n}\n\nfunction resolveTarget(target: TeachingPopoverTarget | undefined): HTMLElement | null {\n if (!target || isVirtualTarget(target)) return null;\n return isRefObject(target) ? target.current : target;\n}\n\nconst isButtonLikeElement = (action: unknown): action is React.ReactElement<ActionElementProps> =>\n isElementOfType<ActionElementProps>(action as React.ReactNode, Button, 'button', 'a');\n\ninterface ActionElementProps {\n className?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n appearance?: string;\n}\n\n/**\n * Renders a footer action as a button: content gets a Button around it, a slot object renders as\n * a Button (or its `as`), and a Button-like element is used as given. Every form composes its own\n * `onClick` before `onActivate`.\n */\nfunction renderAction(\n action: TeachingPopoverAction,\n appearance: 'primary' | 'outline',\n className: string,\n onActivate: () => void,\n): React.ReactElement | null {\n const activate = (event: React.MouseEvent<HTMLElement>) => {\n if (!event.defaultPrevented) onActivate();\n };\n if (isButtonLikeElement(action)) {\n const { className: own, onClick, appearance: ownAppearance } = action.props;\n const isWaveButton = isElementOfType(action, Button);\n return React.cloneElement(action, {\n className: cn(className, own),\n onClick: composeEventHandlers(onClick, activate),\n ...(isWaveButton ? { appearance: ownAppearance ?? appearance } : undefined),\n });\n }\n const resolved = resolveSlot<React.ElementType>(action, Button, className);\n if (!resolved) return null;\n const { onClick, ...props } = resolved.props as ActionElementProps & Record<string, unknown>;\n // The slot's `as` changes Button's element, never the component: Button keeps the link behaviour,\n // `role=\"button\"` and the keyboard activation of a non-interactive element, the focus ring and\n // the look. `appearance` is Button's own prop, so it never reaches the DOM.\n return React.createElement(\n Button as React.ElementType,\n {\n appearance,\n ...props,\n ...(resolved.Component === Button ? undefined : { as: resolved.Component }),\n onClick: composeEventHandlers(onClick, activate),\n },\n resolved.children,\n );\n}\n\n/** Properties of {@link TeachingSurface}. */\ninterface TeachingSurfaceProps extends React.HTMLAttributes<HTMLDivElement> {\n /** The context of the TeachingPopover the surface belongs to. */\n context: TeachingPopoverContextValue;\n /** The stable classes of the component that renders the surface, first in its classes. */\n rootClassName: string;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * The popover surface (internal): the non-modal `role=\"dialog\"` element, rendered in place, or\n * portaled and positioned next to the target with a beak, with its dismissal, focus, keyboard\n * order and step announcements. The root renders it with its own props while no\n * `TeachingPopover.Surface` is among its children; `TeachingPopover.Surface` renders it with its\n * props. Its children replace the content parts of the current step; a `TeachingPopover.Title`\n * among them registers its id, which names the surface.\n */\nexport const TeachingSurface = ({\n context,\n rootClassName,\n id,\n className,\n style,\n onKeyDown,\n children,\n ref,\n ...rest\n}: TeachingSurfaceProps) => {\n const {\n target,\n side,\n align,\n positioning,\n shown,\n index,\n step,\n stepPosition,\n titleId,\n footerLayout,\n dismiss,\n hasTrigger,\n triggerRef,\n surfaceId,\n } = context;\n const announce = useAnnounce();\n // The titles among the children of a surface with content of its own (see the provider below).\n const titles = useTitleRegistry();\n const stepTitle = step?.title;\n const hasTarget = target !== undefined;\n\n const [surface, setSurface] = React.useState<HTMLDivElement | null>(null);\n // Whether `target` pointed at an element when it was last read. An element (or `null`) is known\n // during render and is mirrored here right away (C-HOOKS: adjust state during render). A ref\n // cannot be read during render, React does not re-render when it attaches or detaches, and\n // floating-ui keeps `isPositioned` after `setReference(null)`, so the layout effect below reads\n // a ref after each commit and mirrors it here through a deferred update (C-HOOKS). Until that\n // update has read a newly passed ref, the ref keeps this last known availability: moving between\n // attached refs (a multi-target tour) or passing a new ref object on every render never hides\n // the popover, and a switch to a ref that is not attached hides it once the update lands.\n const pointsAtOneNow = (value: TeachingPopoverTarget | undefined) =>\n isElementTarget(value) || isVirtualTarget(value);\n const [targetResolved, setTargetResolved] = React.useState(() => pointsAtOneNow(target));\n const elementAvailable = target === null ? false : pointsAtOneNow(target) ? true : undefined;\n if (elementAvailable !== undefined && elementAvailable !== targetResolved) {\n setTargetResolved(elementAvailable);\n }\n const surfaceRef = React.useRef<HTMLDivElement | null>(null);\n const targetRef = React.useRef<HTMLElement | null>(null);\n // The latest `target` prop and committed availability, read by the deferred update so that the\n // newest target and attachment win and an unchanged resolution sets no state.\n const targetPropRef = React.useRef(target);\n const availabilityRef = React.useRef(targetResolved);\n const arrowRef = React.useRef<HTMLDivElement | null>(null);\n\n // Destructured: react-hooks/refs treats an object whose member is passed to `ref` as a ref.\n const {\n setReference,\n setFloating,\n floatingProps,\n arrowStyles,\n side: placedSide,\n isPositioned,\n } = usePopupPosition({\n open: shown && hasTarget,\n side,\n align,\n arrowRef,\n ...resolvePositioning(positioning, { offset: 12 }),\n });\n // An anchored popover is shown only while it points at a resolved target: otherwise the surface\n // is rendered (so it can be measured) but hidden, unfocused, silent and without an Escape layer.\n const targetAvailable = target != null && (isRefObject(target) ? targetResolved : true);\n const anchorReady = !hasTarget || (targetAvailable && isPositioned);\n const visible = shown && anchorReady;\n const elementRef = useMergedRefs<HTMLDivElement>(ref, surfaceRef, setSurface, setFloating);\n\n // Point the positioning at the target after every commit. A ref is read once more when the whole\n // commit is done (the C-HOOKS deferred-update pattern): a target that comes after the popover in\n // the tree attaches its ref after this effect has run. That update re-reads the latest target,\n // and only a changed element or availability updates the reference or the state.\n React.useLayoutEffect(() => {\n targetPropRef.current = target;\n availabilityRef.current = targetResolved;\n const element = resolveTarget(target);\n targetRef.current = element;\n setReference(isVirtualTarget(target) ? target : element);\n if (target == null || !isRefObject(target)) return;\n queueMicrotask(() => {\n const latest = resolveTarget(targetPropRef.current);\n if (latest !== targetRef.current) {\n targetRef.current = latest;\n setReference(latest);\n }\n const available = latest !== null;\n if (available !== availabilityRef.current) {\n availabilityRef.current = available;\n setTargetResolved(available);\n }\n });\n });\n\n const { layerId } = useDismiss({\n open: visible,\n onDismiss: dismiss,\n refs: [surfaceRef],\n anchorRef: targetRef,\n kind: 'popover',\n outsidePress: false,\n });\n\n // Focus returns to the Trigger when there is one (as `Popover.Trigger`), else to the element that\n // had it, else to the target.\n const triggerFocusRef = useTriggerFocusRef(triggerRef);\n useRestoreFocus({\n enabled: visible,\n container: surface,\n triggerRef: triggerFocusRef,\n fallback: () => targetRef.current,\n onlyIfFocusInside: true,\n });\n\n // Portaled next to a target: the keyboard order of the popover placed right after the target.\n const onSurfaceKeyDown = usePopoverTabOrder({\n enabled: visible && hasTarget,\n surface,\n anchorRef: targetRef,\n getPreviousStop: getTabbableThrough,\n });\n\n // Move focus into the popover when it becomes visible (and when a new surface mounts).\n React.useEffect(() => {\n if (visible && surface) surface.focus({ preventScroll: hasTarget });\n }, [visible, surface, hasTarget]);\n\n // Announce the new step politely after a step change while the popover stays shown (not on\n // mount, not while hidden, and not in the commit that shows it, such as an opening that starts\n // the step over: the heading, which carries the step position, is read when the popover shows\n // and takes focus).\n const announcedRef = React.useRef({ index, visible });\n React.useEffect(() => {\n const previous = announcedRef.current;\n announcedRef.current = { index, visible };\n if (previous.index === index || !previous.visible) return;\n if (visible && stepTitle !== undefined) {\n announce(`${stepTitle}, ${stepPosition}`);\n }\n }, [index, visible, stepTitle, stepPosition, announce]);\n\n if (!shown || !step) return null;\n\n // Children replace the content parts of the step. The parts without children name the surface\n // by the title id known while rendering (the server HTML too); with children of yours, the\n // first TeachingPopover.Title that registers does, and no title means no `aria-labelledby`.\n const hasContent = slotRendersContent(children);\n const ownId = id || undefined;\n\n return (\n <Portal disabled={!hasTarget} layerId={layerId}>\n <div\n role=\"dialog\"\n aria-labelledby={hasContent ? titles.titleId : titleId}\n tabIndex={-1}\n data-layout={footerLayout}\n id={ownId ?? (hasTrigger ? surfaceId : undefined)}\n {...rest}\n ref={elementRef}\n onKeyDown={composeEventHandlers(onKeyDown, onSurfaceKeyDown)}\n {...(hasTarget\n ? {\n 'data-side': floatingProps['data-side'],\n 'data-align': floatingProps['data-align'],\n style: {\n ...style,\n ...floatingProps.style,\n ...(anchorReady ? undefined : { visibility: 'hidden' as const }),\n },\n }\n : { style })}\n className={cn(\n rootClassName,\n 'relative w-80 rounded-md border border-border bg-background p-5 text-foreground shadow-8',\n focusRing,\n className,\n )}\n >\n {hasTarget && (\n <PopoverBeak\n ref={arrowRef}\n side={placedSide}\n style={arrowStyles}\n data-wave-teaching-popover-arrow=\"\"\n className={teachingPopoverClassNames.beak}\n />\n )}\n\n {/* Titles among your children register here; the default content's does not (its id is\n known while rendering), and a popover nested inside provides its own registry. */}\n <TeachingPopoverSurfaceContext.Provider value={hasContent ? titles.context : null}>\n {hasContent ? (\n children\n ) : (\n <>\n <TeachingPopoverHeader />\n <TeachingPopoverTitle />\n <TeachingPopoverBody />\n <TeachingPopoverFooter />\n </>\n )}\n </TeachingPopoverSurfaceContext.Provider>\n </div>\n </Portal>\n );\n};\nTeachingSurface.displayName = 'TeachingSurface';\n\n/**\n * The element that opens and closes the popover (Fluent's `TeachingPopoverTrigger`, as\n * `Popover.Trigger`). Its props are merged onto the single child (no wrapper element):\n * `aria-haspopup=\"dialog\"`, `aria-expanded`, `aria-controls` (while open), a composed `onClick`\n * that opens the popover, or dismisses it while it is open (as Close does: `onOpenChange(false)`,\n * then `onDismiss`), and a ref. The child's own handlers and classes are kept; the live state ARIA\n * always wins. A render function receives the props instead; `asChild={false}` renders a wrapper\n * span, and a custom child that neither forwards `ref` nor spreads its props falls back to that\n * span automatically (with a development warning). On the span, the state ARIA goes to the first\n * element in the tab order inside it.\n *\n * When TeachingPopover has no `target` (and no `positioning.target`), the popover points at the\n * trigger: it is portaled next to it with a beak and takes its place in the keyboard order right\n * after it. Focus returns to the trigger when the popover closes, with a `target` too (as with\n * `Popover.Trigger`). Place it directly inside TeachingPopover (a Fragment is fine): the popover\n * then starts closed unless `defaultOpen` says otherwise. A trigger nested deeper still works, but\n * leaves `defaultOpen` at `true` and becomes the target once it has mounted.\n *\n * @example\n * <TeachingPopover steps={steps}>\n * <TeachingPopover.Trigger>\n * <Button>Take the tour</Button>\n * </TeachingPopover.Trigger>\n * </TeachingPopover>\n *\n * Also exported as `TeachingPopoverTrigger` for React Server Components, which cannot use the\n * dotted `TeachingPopover.Trigger` (that needs a client file).\n */\nexport const TeachingPopoverTrigger = ({\n children,\n asChild,\n onClick,\n ref,\n ...rest\n}: TeachingPopoverTriggerProps) => {\n const { shown, requestOpen, dismiss, surfaceId, triggerElementRef } =\n useTeachingPopoverContext('TeachingPopover.Trigger');\n // A popover that points at its trigger lives in a portal, which renders only in the browser:\n // until then (the server HTML, hydration) the trigger reports it closed, so its aria-expanded\n // and aria-controls never describe a surface that is not there.\n const isClient = useIsClient();\n const expanded = shown && isClient;\n const elementRef = useMergedRefs<HTMLElement>(ref, triggerElementRef);\n\n const triggerProps = {\n ...rest,\n 'aria-haspopup': 'dialog' as const,\n 'aria-expanded': expanded,\n 'aria-controls': expanded ? surfaceId : undefined,\n onClick: composeEventHandlers(onClick, () => (shown ? dismiss() : requestOpen())),\n ref: elementRef,\n } as TeachingPopoverTriggerChildProps;\n\n return useTriggerElement(children, triggerProps, {\n componentName: 'TeachingPopover.Trigger',\n asChild,\n });\n};\nTeachingPopoverTrigger.displayName = 'TeachingPopoverTrigger';\n\n/**\n * The popover surface (Fluent's `TeachingPopoverSurface`): the non-modal `role=\"dialog\"` element\n * that the `steps` form renders, with the same behaviour (in place, or portaled next to the\n * target with a beak; focus, dismissal, keyboard order and step announcements), so your\n * `className`, `style`, `ref` and other props reach the element the `steps` form gives\n * TeachingPopover's own. Without children it shows the current step as the `steps` form does;\n * children replace that content: build it from `TeachingPopover.Header`, `Title`, `Body` and\n * `Footer`, or from your own (then name the surface with `aria-label` or `aria-labelledby`).\n *\n * Render one inside TeachingPopover; TeachingPopover then renders no surface of its own, and its\n * own `className`, `style`, `ref` and other element props are ignored (a development warning says\n * so). Write it directly inside TeachingPopover (a Fragment is fine) where you can: there it is\n * found while rendering. One inside an element or a component of yours is found once it has\n * mounted, so until then TeachingPopover's own surface renders next to it: in the server HTML, and\n * in the browser's first commit (before anything is painted or focused). A second Surface renders\n * a second popover (a development warning says so).\n *\n * Also exported as `TeachingPopoverSurface` for React Server Components, which cannot use the\n * dotted `TeachingPopover.Surface` (that needs a client file).\n */\nexport const TeachingPopoverSurface = ({ id, ref, ...rest }: TeachingPopoverSurfaceProps) => {\n const context = useTeachingPopoverContext('TeachingPopover.Surface');\n const { registerSurface, setCustomSurfaceId } = context;\n // Registered wherever it is among TeachingPopover's children: the root then drops its own\n // surface (in the commit after this one when the root's scan did not find it), and warns when\n // more than one registers.\n React.useLayoutEffect(() => registerSurface(), [registerSurface]);\n // Its id is the one the Trigger's `aria-controls` names.\n const ownId = id || undefined;\n React.useEffect(() => {\n setCustomSurfaceId(ownId);\n return () => setCustomSurfaceId(undefined);\n }, [ownId, setCustomSurfaceId]);\n\n return (\n <TeachingSurface\n context={context}\n rootClassName={cn(teachingPopoverClassNames.root, teachingPopoverSurfaceClassNames.root)}\n id={id}\n {...rest}\n ref={ref}\n />\n );\n};\nTeachingPopoverSurface.displayName = 'TeachingPopoverSurface';\n\n/** Properties for the TeachingPopoverHeader sub-component. */\nexport interface TeachingPopoverHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * A short caption above the title, such as “Tip” or “New”. Without it (and without `icon`) the\n * header holds only the Close button, as the `steps` form's does; with either, they sit in a row\n * at the top of the popover, next to the Close button.\n */\n children?: React.ReactNode;\n /**\n * A decorative icon before the caption (`aria-hidden`), such as a light bulb. None by default\n * (Fluent's header shows a light bulb). A value that renders nothing renders no element.\n */\n icon?: Slot<'span'>;\n /**\n * The Close button at the popover's top end, which dismisses it (`onOpenChange(false)`, then\n * `onDismiss`) and is named by TeachingPopover's `closeLabel`. Content (an icon) replaces the\n * dismiss glyph inside the built-in button. A `<button>` or a `Button`, or a slot object whose\n * `as` is one, is merged into it, never nested: its props and handlers (called first) reach the\n * built-in button, its content goes inside, and a development warning says so; a text label of\n * two or more letters or digits in it names the button instead of `closeLabel` (WCAG 2.5.3,\n * Label in Name), as does its own `aria-label`. `null` renders no Close button; `undefined` and\n * booleans keep the default.\n */\n dismissButton?: Slot<'span'>;\n /** Ref to the header element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * The top of the popover (Fluent's `TeachingPopoverHeader`): the Close button, and an optional\n * caption with a decorative `icon` before the title. Without children it holds only the Close\n * button, as the `steps` form does. Place it first in a `TeachingPopover.Surface`.\n *\n * Also exported as `TeachingPopoverHeader` for React Server Components, which cannot use the\n * dotted `TeachingPopover.Header` (that needs a client file).\n */\nexport const TeachingPopoverHeader = ({\n icon,\n dismissButton,\n className,\n children,\n ref,\n ...rest\n}: TeachingPopoverHeaderProps) => {\n const { step, closeLabel, dismiss } = useTeachingPopoverContext('TeachingPopover.Header');\n if (!step) return null;\n\n const hasIcon = slotRendersContent(icon);\n const hasCaption = slotRendersContent(children);\n return (\n // The row lines up with the Close button, which keeps its place at the top end of the surface\n // whether or not the header has a caption.\n <div\n ref={ref}\n className={cn(\n teachingPopoverHeaderClassNames.root,\n (hasIcon || hasCaption) &&\n '-mt-2 mb-2 flex min-h-6 items-center gap-1.5 pe-8 text-caption-1 font-semibold text-primary',\n className,\n )}\n {...rest}\n >\n {hasIcon &&\n renderSlot(\n icon,\n 'span',\n cn(teachingPopoverHeaderClassNames.icon, 'inline-flex shrink-0 items-center'),\n { 'aria-hidden': true },\n )}\n {hasCaption && materialiseSlotContent(children)}\n <ModalCloseButton\n componentName=\"TeachingPopover.Header\"\n closeButton={dismissButton}\n slotName=\"dismissButton\"\n closeLabel={closeLabel}\n onClose={dismiss}\n className={cn(teachingPopoverClassNames.closeButton, 'absolute end-3 top-3')}\n />\n </div>\n );\n};\nTeachingPopoverHeader.displayName = 'TeachingPopoverHeader';\n\n/** The TeachingPopover.Title's own props (component-specific props only). */\nexport interface TeachingPopoverTitleOwnProps {\n /**\n * The title text: the current step's `title` without children (or with children that render\n * nothing). A visually hidden step position (“, step 2 of 3”, worded by `labels.step`) follows\n * either, so the heading, which names the popover, says where the tour is.\n */\n children?: React.ReactNode;\n}\n\n/** Props of {@link TeachingPopoverTitle} rendered as `C` (default `'h3'`), including `ref`. */\nexport type TeachingPopoverTitleProps<C extends React.ElementType = 'h3'> = PolymorphicProps<\n C,\n TeachingPopoverTitleOwnProps\n>;\n\n/** The props the implementation reads, for any `as` (the public typing is `PolymorphicComponent`). */\ntype TeachingPopoverTitleImplProps = TeachingPopoverTitleOwnProps &\n React.HTMLAttributes<HTMLElement> & {\n as?: React.ElementType;\n ref?: React.Ref<HTMLElement>;\n };\n\n/**\n * The step title (Fluent's `TeachingPopoverTitle`): an `<h3>` (another level, or any element,\n * with `as`) holding the current step's `title`, or your children, and a visually hidden step\n * position. It names the surface: the surface's `aria-labelledby` points at its `id` (yours, or a\n * generated one), wherever it is among the Surface's children (inside `TeachingPopover.Body`, as\n * in Fluent, works too).\n *\n * Also exported as `TeachingPopoverTitle` for React Server Components, which cannot use the\n * dotted `TeachingPopover.Title` (that needs a client file).\n */\nexport const TeachingPopoverTitle: PolymorphicComponent<'h3', TeachingPopoverTitleOwnProps> = (\n props,\n) => {\n const {\n as,\n id: idProp,\n className,\n children,\n ref,\n ...rest\n } = props as TeachingPopoverTitleImplProps;\n const { step, stepPosition, titleId } = useTeachingPopoverContext('TeachingPopover.Title');\n const registry = React.useContext(TeachingPopoverSurfaceContext);\n const id = idProp || titleId;\n // Registered while the element is mounted: the surface is named by the titles it renders.\n const registerTitle = registry?.registerTitle;\n const register = React.useCallback(\n (node: HTMLElement | null) => (node && registerTitle ? registerTitle(id) : undefined),\n [registerTitle, id],\n );\n const mergedRef = useMergedRefs<HTMLElement>(ref, register);\n if (!step) return null;\n\n const Component: React.ElementType = as ?? 'h3';\n return (\n <Component\n id={id}\n className={cn(\n teachingPopoverTitleClassNames.root,\n teachingPopoverClassNames.title,\n 'mb-2 pe-8 text-subtitle-1 font-semibold text-foreground',\n className,\n )}\n {...rest}\n ref={mergedRef}\n >\n {slotRendersContent(children) ? materialiseSlotContent(children) : step.title}\n <span className=\"sr-only\">{`, ${stepPosition}`}</span>\n </Component>\n );\n};\nTeachingPopoverTitle.displayName = 'TeachingPopoverTitle';\n\n/** Properties for the TeachingPopoverBody sub-component. */\nexport interface TeachingPopoverBodyProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The body content: the current step's `body` without children (or with children that render\n * nothing).\n */\n children?: React.ReactNode;\n /**\n * Media above the content, such as a picture or a short video of the feature, inside a `<span>`\n * (`media={<img src=\"…\" alt=\"…\" />}`; a slot object sets the span's own attributes). It is\n * content, not decoration: give a picture its `alt` (`alt=\"\"` when the text says it all). A\n * value that renders nothing renders no element.\n */\n media?: Slot<'span'>;\n /** Ref to the body element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * The step body (Fluent's `TeachingPopoverBody`): the current step's `body`, or your children,\n * after an optional `media` element.\n *\n * Also exported as `TeachingPopoverBody` for React Server Components, which cannot use the\n * dotted `TeachingPopover.Body` (that needs a client file).\n */\nexport const TeachingPopoverBody = ({\n media,\n className,\n children,\n ref,\n ...rest\n}: TeachingPopoverBodyProps) => {\n const { step } = useTeachingPopoverContext('TeachingPopover.Body');\n if (!step) return null;\n\n return (\n <div\n ref={ref}\n className={cn(\n teachingPopoverBodyClassNames.root,\n teachingPopoverClassNames.body,\n 'mb-4 text-body-1 text-muted-foreground',\n className,\n )}\n {...rest}\n >\n {slotRendersContent(media) &&\n renderSlot(\n media,\n 'span',\n cn(teachingPopoverBodyClassNames.media, 'mb-3 block overflow-hidden rounded-md'),\n )}\n {slotRendersContent(children) ? materialiseSlotContent(children) : step.body}\n </div>\n );\n};\nTeachingPopoverBody.displayName = 'TeachingPopoverBody';\n\n/** Properties for the TeachingPopoverFooter sub-component. */\nexport interface TeachingPopoverFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The footer content. Without children (or with children that render nothing) the step dots and\n * the buttons of the current step: Back and Next (Done on the last step), or the\n * `primaryAction` and `secondaryAction` that replace them.\n */\n children?: React.ReactNode;\n /** Ref to the footer element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * The bottom row (Fluent's `TeachingPopoverFooter`): the step dots and the buttons of the current\n * step, laid out by TeachingPopover's `footerLayout` (rendered as `data-layout` here too), or your\n * children. The steps, the actions and their labels stay on TeachingPopover.\n *\n * Also exported as `TeachingPopoverFooter` for React Server Components, which cannot use the\n * dotted `TeachingPopover.Footer` (that needs a client file).\n */\nexport const TeachingPopoverFooter = ({\n className,\n children,\n ref,\n ...rest\n}: TeachingPopoverFooterProps) => {\n const context = useTeachingPopoverContext('TeachingPopover.Footer');\n const { step, footerLayout } = context;\n if (!step) return null;\n\n const vertical = footerLayout === 'vertical';\n return (\n <div\n ref={ref}\n data-layout={footerLayout}\n className={cn(\n teachingPopoverFooterClassNames.root,\n teachingPopoverClassNames.footer,\n 'flex gap-2',\n vertical ? 'flex-col items-stretch gap-4' : 'items-center justify-between',\n className,\n )}\n {...rest}\n >\n {slotRendersContent(children) ? (\n materialiseSlotContent(children)\n ) : (\n <TeachingFooterContent context={context} />\n )}\n </div>\n );\n};\nTeachingPopoverFooter.displayName = 'TeachingPopoverFooter';\n\n/**\n * The default content of the footer (internal): the step dots and the buttons of the current\n * step (Back and Next or Done, or the actions that replace them).\n */\nfunction TeachingFooterContent({ context }: { context: TeachingPopoverContextValue }) {\n const vertical = context.footerLayout === 'vertical';\n const { secondary, primary } = renderStepButtons(context);\n\n return (\n <>\n <TeachingStepDots\n count={context.count}\n index={context.index}\n className={vertical && 'justify-center'}\n />\n\n <div className={cn('flex gap-2', vertical ? 'flex-col items-stretch' : 'items-center')}>\n {secondary}\n {primary}\n </div>\n </>\n );\n}\nTeachingFooterContent.displayName = 'TeachingFooterContent';\n\n/**\n * The decorative step dots (internal): one per step, the current one wider and marked\n * `aria-current`, all hidden from assistive technology (the heading carries the step position).\n * The default indicator of both footers.\n */\nfunction TeachingStepDots({\n count,\n index,\n className,\n}: {\n count: number;\n index: number;\n className?: string | false;\n}) {\n return (\n <div aria-hidden=\"true\" className={cn('flex items-center gap-1.5', className)}>\n {Array.from({ length: count }, (_, i) => (\n <span\n key={i}\n data-wave-teaching-popover-dot=\"\"\n aria-current={i === index ? 'step' : undefined}\n className={cn(\n teachingPopoverClassNames.dot,\n 'h-1.5 rounded-full transition-[width,background-color] motion-reduce:transition-none',\n i === index\n ? cn('w-4 bg-primary', forcedColors.fill)\n : 'w-1.5 bg-stroke-accessible forced-colors:bg-[CanvasText] forced-colors:forced-color-adjust-none',\n )}\n />\n ))}\n </div>\n );\n}\nTeachingStepDots.displayName = 'TeachingStepDots';\n\n/** What a TeachingPopover.CarouselFooter changes about the buttons of {@link renderStepButtons}. */\ninterface StepButtonTexts {\n /** The text of the first step's secondary button, which then dismisses the popover. */\n initialStepText?: string;\n /** The text of the primary button on the last step, in place of Done. */\n finalStepText?: string;\n}\n\n/**\n * The secondary and primary buttons of the current step (internal), shared by both footers: the\n * actions that replace them, else Back (focusable and `aria-disabled` on the first step; none for\n * a single step) and Next (Done on the last step). With `initialStepText`, the first step's\n * secondary button shows it and dismisses the popover; with `finalStepText`, the last step's\n * primary button shows it. Each stays in its place across steps, so a button that has focus\n * keeps it when the step changes.\n */\nfunction renderStepButtons(\n context: TeachingPopoverContextValue,\n { initialStepText, finalStepText }: StepButtonTexts = {},\n): { secondary: React.ReactNode; primary: React.ReactNode } {\n const {\n count,\n isFirst,\n isLast,\n goBack,\n goNext,\n dismiss,\n primaryAction,\n secondaryAction,\n backLabel,\n nextLabel,\n doneLabel,\n } = context;\n\n let secondary: React.ReactNode;\n if (secondaryAction) {\n secondary = renderAction(\n secondaryAction,\n 'outline',\n teachingPopoverClassNames.secondaryButton,\n goBack,\n );\n } else if (isFirst && initialStepText) {\n secondary = (\n <Button className={teachingPopoverClassNames.backButton} onClick={dismiss}>\n {initialStepText}\n </Button>\n );\n } else if (count > 1) {\n secondary = (\n <Button\n {...focusableDisabledProps(isFirst)}\n className={teachingPopoverClassNames.backButton}\n onClick={preventIfDisabled(isFirst, goBack)}\n >\n {backLabel}\n </Button>\n );\n }\n\n const primary = primaryAction ? (\n renderAction(primaryAction, 'primary', teachingPopoverClassNames.primaryButton, goNext)\n ) : (\n <Button appearance=\"primary\" className={teachingPopoverClassNames.nextButton} onClick={goNext}>\n {isLast ? finalStepText || doneLabel : nextLabel}\n </Button>\n );\n\n return { secondary, primary };\n}\n\n/** Properties for the TeachingPopoverCarousel sub-component. */\nexport interface TeachingPopoverCarouselProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The carousel's content. Without children (or with children that render nothing) the current\n * step as a carousel page: `TeachingPopover.Title`, `TeachingPopover.Body` and\n * `TeachingPopover.CarouselFooter` without children of their own.\n */\n children?: React.ReactNode;\n /** Ref to the carousel element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * The tour as a carousel (Fluent's `TeachingPopoverCarousel`): it holds the current step's page\n * and the carousel footer. The steps stay on TeachingPopover (its `steps` are the pages, so there\n * is no card part), and so do the step state and the callbacks: the carousel parts read them\n * wherever they are in the popover. Without children it shows the step title and body and a\n * `TeachingPopover.CarouselFooter`.\n *\n * Also exported as `TeachingPopoverCarousel` for React Server Components, which cannot use the\n * dotted `TeachingPopover.Carousel` (that needs a client file).\n */\nexport const TeachingPopoverCarousel = ({\n className,\n children,\n ref,\n ...rest\n}: TeachingPopoverCarouselProps) => {\n const { step } = useTeachingPopoverContext('TeachingPopover.Carousel');\n if (!step) return null;\n\n return (\n <div ref={ref} className={cn(teachingPopoverCarouselClassNames.root, className)} {...rest}>\n {slotRendersContent(children) ? (\n materialiseSlotContent(children)\n ) : (\n <>\n <TeachingPopoverTitle />\n <TeachingPopoverBody />\n <TeachingPopoverCarouselFooter />\n </>\n )}\n </div>\n );\n};\nTeachingPopoverCarousel.displayName = 'TeachingPopoverCarousel';\n\n/** Properties for the TeachingPopoverCarouselNav sub-component. */\nexport interface TeachingPopoverCarouselNavProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n> {\n /** Ref to the element of the step buttons. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Interactive step buttons (Fluent's `TeachingPopoverCarouselNav`): a group named by\n * `labels.nav` (“Choose step”) with one button per step, each named by `labels.navButton`\n * (“Step 2 of 3”) and a Tab stop. The current step's button has `aria-current=\"step\"`; activating\n * another one shows its step (`onStepChange`, then the step announcement), and focus stays on it.\n * Opt-in: the footers show decorative dots unless you place it, for example as the children of\n * `TeachingPopover.CarouselFooter`.\n *\n * Also exported as `TeachingPopoverCarouselNav` for React Server Components, which cannot use the\n * dotted `TeachingPopover.CarouselNav` (that needs a client file).\n */\nexport const TeachingPopoverCarouselNav = ({\n className,\n ref,\n ...rest\n}: TeachingPopoverCarouselNavProps) => {\n const { step, count, index, goToStep, navLabel, navButtonLabel } = useTeachingPopoverContext(\n 'TeachingPopover.CarouselNav',\n );\n if (!step) return null;\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-label={navLabel}\n className={cn(teachingPopoverCarouselNavClassNames.root, 'flex items-center', className)}\n {...rest}\n >\n {Array.from({ length: count }, (_, i) => {\n const current = i === index;\n return (\n <button\n key={i}\n type=\"button\"\n aria-label={navButtonLabel(i, count)}\n aria-current={current ? 'step' : undefined}\n onClick={() => goToStep(i)}\n className={cn(\n teachingPopoverCarouselNavClassNames.button,\n 'group inline-flex h-6 min-w-6 cursor-pointer items-center justify-center rounded-md border-0 bg-transparent p-0',\n focusRing,\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn(\n teachingPopoverCarouselNavClassNames.indicator,\n 'block h-1.5 rounded-full transition-[width,background-color] motion-reduce:transition-none',\n current\n ? cn('w-4 bg-primary', forcedColors.fill)\n : 'w-1.5 bg-stroke-accessible group-hover:bg-foreground forced-colors:bg-[ButtonText] forced-colors:forced-color-adjust-none',\n )}\n />\n </button>\n );\n })}\n </div>\n );\n};\nTeachingPopoverCarouselNav.displayName = 'TeachingPopoverCarouselNav';\n\nconst defaultPageCount = (current: number, total: number) => `${current} of ${total}`;\n\n/** Properties for the TeachingPopoverCarouselPageCount sub-component. */\nexport interface TeachingPopoverCarouselPageCountProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n> {\n /**\n * The text from the one-based number of the current step and the step count (Fluent's render\n * function); it also localizes the text. A result that renders nothing keeps the default. A\n * Server Component cannot pass a function: write the part with one in a client file.\n * @default (current, total) => `${current} of ${total}`\n */\n children?: (current: number, total: number) => React.ReactNode;\n /** Ref to the count element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * The visible step count (Fluent's `TeachingPopoverCarouselPageCount`), such as “2 of 3”: the\n * current step and the step count, worded by a render function child. Place it in a footer,\n * for example in `TeachingPopover.CarouselFooter` next to or instead of `TeachingPopover.CarouselNav`.\n *\n * Also exported as `TeachingPopoverCarouselPageCount` for React Server Components, which cannot\n * use the dotted `TeachingPopover.CarouselPageCount` (that needs a client file).\n */\nexport const TeachingPopoverCarouselPageCount = ({\n className,\n children,\n ref,\n ...rest\n}: TeachingPopoverCarouselPageCountProps) => {\n const { step, count, index } = useTeachingPopoverContext('TeachingPopover.CarouselPageCount');\n if (!step) return null;\n\n const text = children?.(index + 1, count);\n return (\n <div\n ref={ref}\n className={cn(\n teachingPopoverCarouselPageCountClassNames.root,\n 'shrink-0 text-caption-1 text-muted-foreground',\n className,\n )}\n {...rest}\n >\n {slotRendersContent(text) ? materialiseSlotContent(text) : defaultPageCount(index + 1, count)}\n </div>\n );\n};\nTeachingPopoverCarouselPageCount.displayName = 'TeachingPopoverCarouselPageCount';\n\n/** Properties for the TeachingPopoverCarouselFooter sub-component. */\nexport interface TeachingPopoverCarouselFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Where the indicator sits: `'offset'` puts it at the start and the buttons together at the\n * end, as `TeachingPopover.Footer` does, and the buttons wrap to a row of their own (at the end)\n * when both do not fit in one row; `'centered'` puts it between the secondary button at the\n * start and the primary button at the end, in the middle of the footer whatever the buttons'\n * widths (also without a secondary button), and when that row does not fit, the indicator takes\n * a row of its own above the buttons and the footer gets `data-stacked`. While stacked, the\n * visual order differs from the Tab order, which stays the secondary button, the indicator's\n * step buttons, then the primary button. The indicator never shrinks below its content.\n * Rendered as `data-carousel-layout`. (Fluent's default is `'centered'`; WaveUI keeps its own\n * footer's arrangement.) TeachingPopover's `footerLayout` applies to `TeachingPopover.Footer`\n * only.\n * @default 'offset'\n */\n layout?: 'offset' | 'centered';\n /**\n * The text of the first step's secondary button (“Not now”). Given, that button is enabled and\n * dismisses the popover as Close does (`onOpenChange(false)`, then `onDismiss`; not\n * `onFinish`), also on a single step. Without it the first step keeps Back, focusable and\n * `aria-disabled`, and a single step has none. A `secondaryAction` replaces the button.\n */\n initialStepText?: string;\n /**\n * The text of the primary button on the last step (“Got it”), which finishes the tour as Done\n * does. A `primaryAction` replaces the button.\n * @default TeachingPopover's `labels.done` ('Done')\n */\n finalStepText?: string;\n /**\n * The indicator: without children (or with children that render nothing) the decorative step\n * dots; give it `TeachingPopover.CarouselNav` for interactive step buttons, or\n * `TeachingPopover.CarouselPageCount` for a visible count. The buttons always render.\n */\n children?: React.ReactNode;\n /** Ref to the footer element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * The carousel's bottom row (Fluent's `TeachingPopoverCarouselFooter`): an indicator (the\n * decorative step dots, or your children) and the buttons of the current step, as in\n * `TeachingPopover.Footer`: Back and Next (Done on the last step), or the `secondaryAction` and\n * `primaryAction` that replace them. `initialStepText` turns the first step's Back into a button\n * that dismisses the popover (“Not now”), `finalStepText` relabels Done, and `layout` places the\n * indicator; the footer wraps instead of letting the indicator and the buttons overlap. The steps,\n * the actions and the callbacks stay on TeachingPopover.\n *\n * Also exported as `TeachingPopoverCarouselFooter` for React Server Components, which cannot use\n * the dotted `TeachingPopover.CarouselFooter` (that needs a client file).\n */\nexport const TeachingPopoverCarouselFooter = ({\n layout = 'offset',\n initialStepText,\n finalStepText,\n className,\n children,\n ref,\n ...rest\n}: TeachingPopoverCarouselFooterProps) => {\n const context = useTeachingPopoverContext('TeachingPopover.CarouselFooter');\n const centered = layout === 'centered';\n const [footer, setFooter] = React.useState<HTMLDivElement | null>(null);\n const footerRef = useMergedRefs<HTMLDivElement>(ref, setFooter);\n const stacked = useCarouselFooterStacked(footer, centered && context.step !== undefined);\n if (!context.step) return null;\n\n const { secondary, primary } = renderStepButtons(context, { initialStepText, finalStepText });\n // The indicator is as wide as its content: it never shrinks under the buttons. Content wider\n // than the whole footer wraps inside it.\n const indicator = slotRendersContent(children) ? (\n <div\n className={cn(\n 'flex flex-wrap items-center gap-2',\n centered && 'w-max max-w-full justify-center',\n )}\n >\n {materialiseSlotContent(children)}\n </div>\n ) : (\n <TeachingStepDots count={context.count} index={context.index} />\n );\n\n if (!centered) {\n // The indicator at the start and the buttons at the end; when both do not fit in one row, the\n // buttons wrap to a row of their own, still at the end.\n return (\n <div\n ref={footerRef}\n data-carousel-layout={layout}\n className={cn(\n teachingPopoverCarouselFooterClassNames.root,\n teachingPopoverClassNames.footer,\n 'flex flex-wrap items-center justify-between gap-2',\n className,\n )}\n {...rest}\n >\n {indicator}\n <div className=\"ms-auto flex flex-wrap items-center justify-end gap-2\">\n {secondary}\n {primary}\n </div>\n </div>\n );\n }\n\n // Centered: one row of three columns, the outer two of equal width, so the indicator sits in\n // the middle of the footer whatever the buttons' widths, with or without a secondary button.\n // When that row does not fit (useCarouselFooterStacked measures it), the indicator takes a row\n // of its own above the buttons. The DOM order stays secondary, indicator, primary in both, so\n // a button keeps focus when the layout changes.\n return (\n <div\n ref={footerRef}\n data-carousel-layout={layout}\n data-stacked={stacked ? '' : undefined}\n className={cn(\n teachingPopoverCarouselFooterClassNames.root,\n teachingPopoverClassNames.footer,\n 'items-center gap-2',\n stacked ? 'flex flex-wrap' : 'grid grid-cols-[1fr_auto_1fr]',\n className,\n )}\n {...rest}\n >\n {slotRendersContent(secondary) && (\n <div\n data-wave-carousel-footer-slot=\"secondary\"\n className={cn('flex w-max max-w-full', !stacked && 'col-start-1 justify-self-start')}\n >\n {secondary}\n </div>\n )}\n <div\n data-wave-carousel-footer-slot=\"indicator\"\n className={cn('flex justify-center', stacked ? 'order-first basis-full' : 'col-start-2')}\n >\n {indicator}\n </div>\n <div\n data-wave-carousel-footer-slot=\"primary\"\n className={cn(\n 'flex w-max max-w-full',\n stacked ? 'ms-auto' : 'col-start-3 justify-self-end',\n )}\n >\n {primary}\n </div>\n </div>\n );\n};\nTeachingPopoverCarouselFooter.displayName = 'TeachingPopoverCarouselFooter';\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/children.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/slot.cjs"),ee=require("../../lib/classNames.cjs"),i=require("../../hooks/useEventCallback.cjs"),a=require("../../hooks/useControllable.cjs"),te=require("../../hooks/useId.cjs"),ne=require("../../hooks/useMergedRefs.cjs"),re=require("../../hooks/useResolvedTarget.cjs"),ie=require("./TeachingPopover.context.cjs"),o=require("./TeachingPopover.parts.cjs");let s=require("react");s=e.__toESM(s,1);let c=require("react/jsx-runtime");var ae=`Back`,oe=`Next`,se=`Done`,ce=`Choose step`,le=(e,t)=>`step ${e+1} of ${t}`,ue=(e,t)=>`Step ${e+1} of ${t}`;function l(e,t){return r.slotRendersContent(e)?e:r.slotRendersContent(t)?t:void 0}function de(e,t){return Number.isFinite(e)?Math.min(Math.max(Math.trunc(e),0),t-1):0}function fe(e){let n={trigger:!1,surface:!1};if(e==null)return n;for(let{node:r}of t.flattenChildren(e))t.isElementOfType(r,o.TeachingPopoverTrigger)?n.trigger=!0:t.isElementOfType(r,o.TeachingPopoverSurface)&&(n.surface=!0);return n}var pe=`TeachingPopover.Surface:placement`,me=`TeachingPopover.Surface: render one TeachingPopover.Surface in a TeachingPopover; a second Surface renders a second popover.`,he=`TeachingPopover:surface-props`,ge="TeachingPopover: the props of the surface element on TeachingPopover (`className`, `style`, `ref`, `onKeyDown` and the other element props) are ignored next to a TeachingPopover.Surface: pass them to the Surface.",u=({steps:e,activeStep:t,defaultActiveStep:r,currentStep:u,defaultCurrentStep:_e,onStepChange:ve,onDismiss:d,onFinish:ye,primaryAction:be,secondaryAction:xe,footerLayout:f=`horizontal`,open:Se,defaultOpen:Ce,onOpenChange:we,closeLabel:p=`Close`,labels:m,target:h,positioning:g,side:_=`bottom`,align:v=`center`,children:y,id:b,className:x,style:S,onKeyDown:C,ref:w,...T})=>{re.useTargetConflictWarning(`TeachingPopover`,h,g?.target);let E=h===void 0?g?.target:h,Te=n.resolveDeprecatedProp(`TeachingPopover`,t,u,`currentStep`,`activeStep`),D=n.resolveDeprecatedProp(`TeachingPopover`,r,_e,`defaultCurrentStep`,`defaultActiveStep`)??0,[O,k,A]=a.useControllable(Te,D,ve),j=fe(y),[M,N]=a.useControllable(Se,Ce??!j.trigger,we),P=te.useId(`teaching-popover-title`),[Ee,De]=s.useState(M),[F,I]=s.useState(!1);M!==Ee&&(De(M),M&&!A&&!Object.is(O,D)&&I(!0)),F&&(A||Object.is(O,D))&&I(!1),s.useLayoutEffect(()=>{F&&k(D)},[F,D,k]);let L=F?D:O,R=e.length,z=M&&R>0,B=R>0?de(L,R):0,V=R>0&&B!==L,H=R>0?e[B]:void 0,U=B===0,W=B===R-1,G=R>0?(m?.step??le)(B,R):``,K=H?l(H.primaryAction,be):void 0,q=H?l(H.secondaryAction,xe):void 0,J=m?.back??ae,Oe=m?.next??oe,ke=m?.done??se,Ae=m?.nav??ce,je=m?.navButton??ue,[Me,Ne]=s.useState(null),Y=j.trigger||Me!==null,Pe=E===void 0?Y?Me:void 0:E,Fe=s.useRef(null),Ie=ne.useMergedRefs(Fe,Ne),X=s.useRef(0),[Le,Re]=s.useState(!1),ze=s.useCallback(()=>(X.current+=1,Re(!0),()=>{--X.current,X.current===0&&Re(!1)}),[]),Z=j.surface||Le;s.useEffect(()=>{X.current>1&&n.warnOnce(pe,me)});let Be=te.useId(`teaching-popover`),[Ve,He]=s.useState(void 0),Ue=(Z?Ve:b||void 0)??Be,We=i.useEventCallback(()=>N(!0)),Ge=i.useEventCallback(()=>{N(!1),d?.()}),Q=i.useEventCallback(()=>{N(!1),ye?.(),d?.()}),Ke=i.useEventCallback(()=>{U||k(B-1)}),qe=i.useEventCallback(()=>{W?Q():k(B+1)}),Je=i.useEventCallback(e=>{if(R===0)return;let t=de(e,R);t!==B&&k(t)}),Ye=Z&&(b!==void 0||x!==void 0||S!==void 0||C!==void 0||w!==void 0||Object.keys(T).length>0);s.useEffect(()=>{Ye&&n.warnOnce(he,ge)},[Ye]),s.useEffect(()=>{V&&n.warnOnce(`TeachingPopover:activeStep-range`,`TeachingPopover: activeStep ${L} is out of range for ${R} steps; showing step ${B+1}.`)},[V,L,R,B]);let $=s.useMemo(()=>({open:M,shown:z,requestOpen:We,dismiss:Ge,finish:Q,count:R,index:B,step:H,isFirst:U,isLast:W,stepPosition:G,goBack:Ke,goNext:qe,goToStep:Je,primaryAction:K,secondaryAction:q,footerLayout:f,backLabel:J,nextLabel:Oe,doneLabel:ke,closeLabel:p,navLabel:Ae,navButtonLabel:je,titleId:P,target:Pe,side:_,align:v,positioning:g,hasTrigger:Y,triggerElementRef:Ie,triggerRef:Fe,surfaceId:Ue,setCustomSurfaceId:He,registerSurface:ze}),[M,z,We,Ge,Q,R,B,H,U,W,G,Ke,qe,Je,K,q,f,J,Oe,ke,p,Ae,je,P,Pe,_,v,g,Y,Ie,Ue,ze]);return(0,c.jsxs)(ie.TeachingPopoverContext.Provider,{value:$,children:[y,Z?null:(0,c.jsx)(o.TeachingSurface,{context:$,rootClassName:ee.teachingPopoverClassNames.root,id:b,className:x,style:S,onKeyDown:C,...T,ref:w})]})};u.displayName=`TeachingPopover`,exports.TeachingPopoverRoot=u;
2
+ //# sourceMappingURL=TeachingPopover.root.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeachingPopover.root.cjs","names":["slotRendersContent","flattenChildren","isElementOfType","TeachingPopoverTrigger","TeachingPopoverSurface","resolveDeprecatedProp","useControllable","useId","React","useMergedRefs","useEventCallback","TeachingPopoverContext","TeachingSurface","teachingPopoverClassNames","require_runtime","require_children","require_dev","require_slot","require_classNames","require_useEventCallback","require_useControllable","require_useId","require_useMergedRefs","require_useResolvedTarget","require_TeachingPopover_context","require_TeachingPopover_parts","react","react_jsx_runtime","DEFAULT_BACK_LABEL","DEFAULT_NEXT_LABEL","DEFAULT_DONE_LABEL","DEFAULT_NAV_LABEL","defaultStepLabel","index","count","defaultNavButtonLabel","pickAction","own","fallback","clampStep","step","findParts","found","children","node","SURFACE_PLACEMENT_WARNING_KEY","SURFACE_PLACEMENT_WARNING","SURFACE_PROPS_WARNING_KEY","SURFACE_PROPS_WARNING","TeachingPopoverRoot","activeStepProp","primaryActionProp","secondaryActionProp","openProp","targetProp","rest","positioning","explicitTarget","controlledStep","currentStep","initialStep","defaultActiveStep","defaultCurrentStep","storedStep","setStep","stepControlled","onStepChange","parts","open","setOpen","defaultOpen","onOpenChange","titleId","openSeen","setOpenSeen","stepResetPending","setStepResetPending","rawStep","steps","shown","outOfRange","isFirst","isLast","stepPosition","labels","primaryAction","secondaryAction","backLabel","nextLabel","doneLabel","navLabel","navButtonLabel","triggerElement","setTriggerElement","hasTrigger","target","triggerRef","triggerElementRef","surfaceCountRef","hasRegisteredSurface","setHasRegisteredSurface","registerSurface","hasSurfacePart","generatedSurfaceId","customSurfaceId","setCustomSurfaceId","surfaceId","id","requestOpen","dismiss","onDismiss","finish","onFinish","goBack","goNext","goToStep","next","ignoresSurfaceProps","className","style","onKeyDown","ref","context","footerLayout","closeLabel","side","align"],"sources":["../../../src/components/overlays/TeachingPopover.root.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { teachingPopoverClassNames } from '../../lib/classNames';\nimport { resolveDeprecatedProp, warnOnce } from '../../lib/dev';\nimport { slotRendersContent } from '../../lib/slot';\nimport type { PopupAlign, PopupPositioning, PopupSide, VirtualElement } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useTargetConflictWarning } from '../../hooks/useResolvedTarget';\nimport {\n TeachingPopoverContext,\n type TeachingPopoverAction,\n type TeachingPopoverContextValue,\n type TeachingPopoverLabels,\n type TeachingPopoverStep,\n} from './TeachingPopover.context';\nimport {\n TeachingPopoverSurface,\n TeachingPopoverTrigger,\n TeachingSurface,\n} from './TeachingPopover.parts';\n\n/*\n * The TeachingPopover root: its props, the state of both forms (the open state, the step and the\n * step's resolved content), the child scan for the Trigger and the Surface, and the surface it\n * renders when no Surface is among its children. Imports the context and parts modules (never\n * `TeachingPopover.tsx`, which holds the compound).\n */\n\nconst DEFAULT_BACK_LABEL = 'Back';\nconst DEFAULT_NEXT_LABEL = 'Next';\nconst DEFAULT_DONE_LABEL = 'Done';\nconst DEFAULT_NAV_LABEL = 'Choose step';\nconst defaultStepLabel = (index: number, count: number) => `step ${index + 1} of ${count}`;\nconst defaultNavButtonLabel = (index: number, count: number) => `Step ${index + 1} of ${count}`;\n\n/** Properties for the TeachingPopover component. */\nexport interface TeachingPopoverProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Steps to display in the teaching popover (a readonly array is accepted). */\n steps: readonly TeachingPopoverStep[];\n /**\n * Controlled index of the displayed step. Out-of-range values are clamped to the first or last\n * step (with a development warning). Opening the popover leaves it as it is.\n */\n activeStep?: number;\n /**\n * Initial step index for uncontrolled usage, and the step the popover starts on again each time\n * it opens (after Done, Close, Escape or the Trigger closed it, or a controlled `open` turned it\n * off), so a tour opened again starts over; `onStepChange` is called with it when the step was\n * elsewhere.\n * @default 0\n */\n defaultActiveStep?: number;\n /** @deprecated Use `activeStep`. */\n currentStep?: number;\n /** @deprecated Use `defaultActiveStep`. */\n defaultCurrentStep?: number;\n /**\n * Called with the requested step index when Next, Back or a step button of\n * `TeachingPopover.CarouselNav` is activated (the button of the current step requests nothing),\n * and, while the step is uncontrolled, with the initial step when an opening moves the step back\n * to it (see `defaultActiveStep`).\n */\n onStepChange?: (step: number) => void;\n /**\n * Called when the popover is dismissed with Close, Done, Escape or a `TeachingPopover.Trigger`\n * that closes it.\n *\n * Done also calls it in 0.x, after `onFinish`, so that code written before `onFinish` keeps\n * working; from 1.0 only Close, Escape and the Trigger will.\n */\n onDismiss?: () => void;\n /**\n * Called when the tour is finished: Done, the button that replaces Next on the last step, or a\n * `primaryAction` on the last step whose click was not prevented. The popover closes first.\n * Close, Escape and the Trigger call only `onDismiss`. Fires on every activation, like\n * `onStepChange`.\n */\n onFinish?: () => void;\n /**\n * Replaces the Next (or Done) button on every step that sets no `primaryAction` of its own.\n */\n primaryAction?: TeachingPopoverAction;\n /**\n * Replaces the Back button on every step that sets no `secondaryAction` of its own.\n */\n secondaryAction?: TeachingPopoverAction;\n /**\n * How the footer lays out the step dots and the buttons: side by side, or the dots above\n * buttons that fill the width. Rendered as `data-layout` on the popover and on its footer.\n * `TeachingPopover.CarouselFooter` has its own `layout` instead.\n * @default 'horizontal'\n */\n footerLayout?: 'horizontal' | 'vertical';\n /** Controlled visibility of the teaching popover. */\n open?: boolean;\n /**\n * Initial visibility for uncontrolled usage: `true` (a tour that shows on page load), or\n * `false` when a `TeachingPopover.Trigger` is a direct child (a Fragment is fine), which then\n * opens it.\n * @default true (false with a direct TeachingPopover.Trigger)\n */\n defaultOpen?: boolean;\n /**\n * Called with `false` when Close, Done or Escape dismisses the popover, and with the new state\n * when a `TeachingPopover.Trigger` opens or closes it.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Accessible name of the built-in Close button (an icon-only button). Localize it with the\n * page's language.\n * @default 'Close'\n */\n closeLabel?: string;\n /**\n * Text of the Back, Next and Done buttons, the wording of the step position (“step 2 of 3”) and\n * the names of `TeachingPopover.CarouselNav`'s step buttons, for localization. Unset members keep\n * their English defaults.\n */\n labels?: TeachingPopoverLabels;\n /**\n * The element the popover points at (a ref, the element, or a `VirtualElement`: a rectangle such as a\n * point; an inline object is fine). When given, the popover is\n * rendered in a portal, positioned next to it with a beak, and flips or shifts to stay in view;\n * without it (`undefined`) the popover renders inline where it is placed (0.4 behaviour), or,\n * with a `TeachingPopover.Trigger`, points at the trigger.\n * While the target is `null` or has not been positioned against yet (an element held in state\n * that is not set yet, a ref that is not attached), the popover stays hidden: it is not\n * shown, takes no focus, announces no step change and does not handle Escape until it can\n * point at the target. It hides the same way when the target goes away later and shows again\n * when a target returns.\n *\n * An element (for example one held in state through a callback ref) is followed as soon as the\n * prop changes. A ref cannot be observed, so it is read after each render of the popover is\n * committed, wherever the target is in the tree: an element attaching to or detaching from the\n * ref is noticed the next time the popover renders (for example when the parent that mounts or\n * unmounts the target re-renders it), not in a commit that does not render the popover. A\n * memoized popover whose target mounts or unmounts in another subtree therefore stays hidden,\n * or keeps pointing at the removed element, until it renders again. A newly passed ref keeps\n * the previous visibility until it has been read, so a tour can move between attached refs\n * (`target={step === 0 ? aRef : bRef}`) without hiding, and a switch to a ref that is not\n * attached hides the popover right after that commit. Pass the element held in state when the\n * target can mount or unmount without the popover re-rendering.\n */\n target?: React.RefObject<HTMLElement | null> | HTMLElement | VirtualElement | null;\n /** Side of the `target` to open on; `start`/`end` follow the writing direction.\n * @default 'bottom'\n */\n side?: PopupSide;\n /** Alignment along the `target`'s edge.\n * @default 'center'\n */\n align?: PopupAlign;\n /**\n * Advanced positioning (Fluent's `positioning`): `offset`, `fitViewport`, `matchReferenceWidth`,\n * `fallbackPlacements` and `target` (used when the `target` prop is not set). `side` and `align`\n * stay separate props.\n * @default `{ offset: 12 }`\n */\n positioning?: PopupPositioning;\n /**\n * `TeachingPopover.Trigger` and `TeachingPopover.Surface` (Fluent's composition), rendered where\n * they are written. Without a `TeachingPopover.Surface` among them, the popover renders its\n * surface itself, after the children, with the element props given here (`className`, `style`,\n * `ref`, …); with one (best written directly inside, a Fragment is fine: see\n * `TeachingPopover.Surface`), the Surface takes them instead.\n */\n children?: React.ReactNode;\n /**\n * Ref to the popover surface (`role=\"dialog\"`). Ignored next to a `TeachingPopover.Surface`\n * (pass it to the Surface).\n */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** The action a step shows: its own when it renders anything, else the popover's. */\nfunction pickAction(\n own: TeachingPopoverAction | undefined,\n fallback: TeachingPopoverAction | undefined,\n): TeachingPopoverAction | undefined {\n if (slotRendersContent(own)) return own;\n return slotRendersContent(fallback) ? fallback : undefined;\n}\n\nfunction clampStep(step: number, count: number): number {\n if (!Number.isFinite(step)) return 0;\n return Math.min(Math.max(Math.trunc(step), 0), count - 1);\n}\n\n/**\n * Which parts are direct children (Fragments flattened, lazy types of a Server Component\n * unwrapped): a Trigger closes `defaultOpen`, a Surface replaces the root's own surface. Runs\n * during render, so the server HTML agrees (a Surface deeper down registers once mounted).\n */\nfunction findParts(children: React.ReactNode): { trigger: boolean; surface: boolean } {\n const found = { trigger: false, surface: false };\n if (children === null || children === undefined) return found;\n for (const { node } of flattenChildren(children)) {\n if (isElementOfType(node, TeachingPopoverTrigger)) found.trigger = true;\n else if (isElementOfType(node, TeachingPopoverSurface)) found.surface = true;\n }\n return found;\n}\n\nconst SURFACE_PLACEMENT_WARNING_KEY = 'TeachingPopover.Surface:placement';\nconst SURFACE_PLACEMENT_WARNING =\n 'TeachingPopover.Surface: render one TeachingPopover.Surface in a TeachingPopover; a second Surface renders a second popover.';\n\nconst SURFACE_PROPS_WARNING_KEY = 'TeachingPopover:surface-props';\nconst SURFACE_PROPS_WARNING =\n 'TeachingPopover: the props of the surface element on TeachingPopover (`className`, `style`, `ref`, `onKeyDown` and the other element props) are ignored next to a TeachingPopover.Surface: pass them to the Surface.';\n\n// The root of `TeachingPopover` (documented on the export in TeachingPopover.tsx).\nexport const TeachingPopoverRoot = ({\n steps,\n activeStep: activeStepProp,\n defaultActiveStep,\n currentStep,\n defaultCurrentStep,\n onStepChange,\n onDismiss,\n onFinish,\n primaryAction: primaryActionProp,\n secondaryAction: secondaryActionProp,\n footerLayout = 'horizontal',\n open: openProp,\n defaultOpen,\n onOpenChange,\n closeLabel = 'Close',\n labels,\n target: targetProp,\n positioning,\n side = 'bottom',\n align = 'center',\n children,\n id,\n className,\n style,\n onKeyDown,\n ref,\n ...rest\n}: TeachingPopoverProps) => {\n useTargetConflictWarning('TeachingPopover', targetProp, positioning?.target);\n const explicitTarget = (\n targetProp !== undefined ? targetProp : positioning?.target\n ) as TeachingPopoverProps['target'];\n const controlledStep = resolveDeprecatedProp(\n 'TeachingPopover',\n activeStepProp,\n currentStep,\n 'currentStep',\n 'activeStep',\n );\n const initialStep =\n resolveDeprecatedProp(\n 'TeachingPopover',\n defaultActiveStep,\n defaultCurrentStep,\n 'defaultCurrentStep',\n 'defaultActiveStep',\n ) ?? 0;\n const [storedStep, setStep, stepControlled] = useControllable(\n controlledStep,\n initialStep,\n onStepChange,\n );\n const parts = findParts(children);\n const [open, setOpen] = useControllable(openProp, defaultOpen ?? !parts.trigger, onOpenChange);\n const titleId = useId('teaching-popover-title');\n\n // An uncontrolled step starts again at the initial step each time the popover opens (not on\n // mount), whatever closed it and whatever opens it. The opening is noticed during render (C-HOOKS:\n // a previous-value state), so the opened popover shows the initial step from its first render;\n // the layout effect stores it through the setter (which calls `onStepChange` once, from the\n // commit), and the render that reads it back ends the reset.\n const [openSeen, setOpenSeen] = React.useState(open);\n const [stepResetPending, setStepResetPending] = React.useState(false);\n if (open !== openSeen) {\n setOpenSeen(open);\n if (open && !stepControlled && !Object.is(storedStep, initialStep)) {\n setStepResetPending(true);\n }\n }\n if (stepResetPending && (stepControlled || Object.is(storedStep, initialStep))) {\n setStepResetPending(false);\n }\n React.useLayoutEffect(() => {\n if (stepResetPending) setStep(initialStep);\n }, [stepResetPending, initialStep, setStep]);\n const rawStep = stepResetPending ? initialStep : storedStep;\n\n const count = steps.length;\n const shown = open && count > 0;\n const index = count > 0 ? clampStep(rawStep, count) : 0;\n const outOfRange = count > 0 && index !== rawStep;\n const step = count > 0 ? steps[index] : undefined;\n const isFirst = index === 0;\n const isLast = index === count - 1;\n const stepPosition = count > 0 ? (labels?.step ?? defaultStepLabel)(index, count) : '';\n const primaryAction = step ? pickAction(step.primaryAction, primaryActionProp) : undefined;\n const secondaryAction = step ? pickAction(step.secondaryAction, secondaryActionProp) : undefined;\n const backLabel = labels?.back ?? DEFAULT_BACK_LABEL;\n const nextLabel = labels?.next ?? DEFAULT_NEXT_LABEL;\n const doneLabel = labels?.done ?? DEFAULT_DONE_LABEL;\n const navLabel = labels?.nav ?? DEFAULT_NAV_LABEL;\n const navButtonLabel = labels?.navButton ?? defaultNavButtonLabel;\n\n // A Trigger is the target when neither `target` nor `positioning.target` is set: a direct one\n // from the first render (the surface stays hidden until its element attaches), a nested one\n // once its element has attached.\n const [triggerElement, setTriggerElement] = React.useState<HTMLElement | null>(null);\n const hasTrigger = parts.trigger || triggerElement !== null;\n const target =\n explicitTarget !== undefined ? explicitTarget : hasTrigger ? triggerElement : undefined;\n // The Trigger's element also as a ref, where the surface returns focus.\n const triggerRef = React.useRef<HTMLElement | null>(null);\n const triggerElementRef = useMergedRefs<HTMLElement>(triggerRef, setTriggerElement);\n\n // Surfaces (TeachingPopover.Surface) register while mounted, wherever they are among the\n // children: once one has, the root renders no surface of its own. A direct one is also found by\n // the scan above, so it never renders next to the root's own; one inside a component of yours\n // does in its first commit, until its registration re-renders the root. After every commit\n // (every surface's layout effect has run) more than one warns.\n const surfaceCountRef = React.useRef(0);\n const [hasRegisteredSurface, setHasRegisteredSurface] = React.useState(false);\n const registerSurface = React.useCallback(() => {\n surfaceCountRef.current += 1;\n setHasRegisteredSurface(true);\n return () => {\n surfaceCountRef.current -= 1;\n if (surfaceCountRef.current === 0) setHasRegisteredSurface(false);\n };\n }, []);\n const hasSurfacePart = parts.surface || hasRegisteredSurface;\n React.useEffect(() => {\n if (surfaceCountRef.current > 1) {\n warnOnce(SURFACE_PLACEMENT_WARNING_KEY, SURFACE_PLACEMENT_WARNING);\n }\n });\n\n // The Trigger's `aria-controls`: the surface's id (the root's own `id` on its own surface, or\n // the id a Surface reports), else a generated one.\n const generatedSurfaceId = useId('teaching-popover');\n const [customSurfaceId, setCustomSurfaceId] = React.useState<string | undefined>(undefined);\n const surfaceId = (hasSurfacePart ? customSurfaceId : id || undefined) ?? generatedSurfaceId;\n\n const requestOpen = useEventCallback(() => setOpen(true));\n const dismiss = useEventCallback(() => {\n setOpen(false);\n onDismiss?.();\n });\n // Done: close, then `onFinish`. `onDismiss` still follows in 0.x (see its JSDoc).\n const finish = useEventCallback(() => {\n setOpen(false);\n onFinish?.();\n onDismiss?.();\n });\n const goBack = useEventCallback(() => {\n if (!isFirst) setStep(index - 1);\n });\n const goNext = useEventCallback(() => {\n if (isLast) finish();\n else setStep(index + 1);\n });\n // A step button of TeachingPopover.CarouselNav: the shown (clamped) step requests nothing.\n const goToStep = useEventCallback((target: number) => {\n if (count === 0) return;\n const next = clampStep(target, count);\n if (next !== index) setStep(next);\n });\n\n // Next to a Surface the root renders no surface element, so its element props go nowhere.\n const ignoresSurfaceProps =\n hasSurfacePart &&\n (id !== undefined ||\n className !== undefined ||\n style !== undefined ||\n onKeyDown !== undefined ||\n ref !== undefined ||\n Object.keys(rest).length > 0);\n React.useEffect(() => {\n if (ignoresSurfaceProps) warnOnce(SURFACE_PROPS_WARNING_KEY, SURFACE_PROPS_WARNING);\n }, [ignoresSurfaceProps]);\n\n React.useEffect(() => {\n if (!outOfRange) return;\n warnOnce(\n 'TeachingPopover:activeStep-range',\n `TeachingPopover: activeStep ${rawStep} is out of range for ${count} steps; showing step ${index + 1}.`,\n );\n }, [outOfRange, rawStep, count, index]);\n\n const context = React.useMemo<TeachingPopoverContextValue>(\n () => ({\n open,\n shown,\n requestOpen,\n dismiss,\n finish,\n count,\n index,\n step,\n isFirst,\n isLast,\n stepPosition,\n goBack,\n goNext,\n goToStep,\n primaryAction,\n secondaryAction,\n footerLayout,\n backLabel,\n nextLabel,\n doneLabel,\n closeLabel,\n navLabel,\n navButtonLabel,\n titleId,\n target,\n side,\n align,\n positioning,\n hasTrigger,\n triggerElementRef,\n triggerRef,\n surfaceId,\n setCustomSurfaceId,\n registerSurface,\n }),\n [\n open,\n shown,\n requestOpen,\n dismiss,\n finish,\n count,\n index,\n step,\n isFirst,\n isLast,\n stepPosition,\n goBack,\n goNext,\n goToStep,\n primaryAction,\n secondaryAction,\n footerLayout,\n backLabel,\n nextLabel,\n doneLabel,\n closeLabel,\n navLabel,\n navButtonLabel,\n titleId,\n target,\n side,\n align,\n positioning,\n hasTrigger,\n triggerElementRef,\n surfaceId,\n registerSurface,\n ],\n );\n\n return (\n <TeachingPopoverContext.Provider value={context}>\n {children}\n {hasSurfacePart ? null : (\n <TeachingSurface\n context={context}\n rootClassName={teachingPopoverClassNames.root}\n id={id}\n className={className}\n style={style}\n onKeyDown={onKeyDown}\n {...rest}\n ref={ref}\n />\n )}\n </TeachingPopoverContext.Provider>\n );\n};\nTeachingPopoverRoot.displayName = 'TeachingPopover';\n"],"mappings":"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AM,cAAgB,CACfsD,GACLhE,EAAA,SACE,mCACA,+BAA+B6D,EAAQ,uBAAuB3C,EAAM,uBAAuBD,EAAQ,EAAE,EACvG,CACF,EAAG,CAAC+C,EAAYH,EAAS3C,EAAOD,CAAK,CAAC,EAEtC,IAAMyF,EAAUlH,EAAM,aACb,CACL,OACA,QACA,eACA,WACA,SACA,QACA,QACA,OACA,UACA,SACA,eACA,UACA,UACA,YACA,gBACA,kBACA,eACA,YACA,aACA,aACA,aACA,YACA,kBACA,UACA,UACA,OACA,QACA,cACA,aACA,qBACA,cACA,aACA,sBACA,kBACF,GACA,CACE4D,EACAW,EACA6B,GACAC,GACAE,EACA7E,EACAD,EACAO,EACAyC,EACAC,EACAC,EACA8B,GACAC,GACAC,GACA9B,EACAC,EACAqC,EACApC,EACAC,GACAC,GACAmC,EACAlC,GACAC,GACAnB,EACAuB,GACA8B,EACAC,EACAtE,EACAsC,EACAG,GACAS,GACAL,EACF,CACF,EAEA,OACE,EAAA1E,EAAA,KAAA,CAAChB,GAAAA,uBAAuB,SAAxB,CAAiC,MAAO+G,EAAxC,SAAA,CACG/E,EACA2D,EAAiB,MAChB,EAAA3E,EAAA,IAAA,CAACf,EAAAA,gBAAD,CACW,UACT,cAAeC,GAAAA,0BAA0B,KACrC,KACO,YACJ,QACI,YACX,GAAI0C,EACC,KACN,CAAA,CAE4B,GAErC,EACA,EAAoB,YAAc"}
@@ -0,0 +1,158 @@
1
+ "use client";
2
+ import { flattenChildren as e, isElementOfType as t } from "../../lib/children.mjs";
3
+ import { resolveDeprecatedProp as n, warnOnce as r } from "../../lib/dev.mjs";
4
+ import { slotRendersContent as i } from "../../lib/slot.mjs";
5
+ import { teachingPopoverClassNames as ee } from "../../lib/classNames.mjs";
6
+ import { useEventCallback as a } from "../../hooks/useEventCallback.mjs";
7
+ import { useControllable as o } from "../../hooks/useControllable.mjs";
8
+ import { useId as te } from "../../hooks/useId.mjs";
9
+ import { useMergedRefs as ne } from "../../hooks/useMergedRefs.mjs";
10
+ import { useTargetConflictWarning as re } from "../../hooks/useResolvedTarget.mjs";
11
+ import { TeachingPopoverContext as ie } from "./TeachingPopover.context.mjs";
12
+ import { TeachingPopoverSurface as s, TeachingPopoverTrigger as c, TeachingSurface as ae } from "./TeachingPopover.parts.mjs";
13
+ import * as l from "react";
14
+ import { jsx as oe, jsxs as se } from "react/jsx-runtime";
15
+ //#region src/components/overlays/TeachingPopover.root.tsx
16
+ var ce = "Back", le = "Next", ue = "Done", de = "Choose step", fe = (e, t) => `step ${e + 1} of ${t}`, pe = (e, t) => `Step ${e + 1} of ${t}`;
17
+ function u(e, t) {
18
+ return i(e) ? e : i(t) ? t : void 0;
19
+ }
20
+ function d(e, t) {
21
+ return Number.isFinite(e) ? Math.min(Math.max(Math.trunc(e), 0), t - 1) : 0;
22
+ }
23
+ function me(n) {
24
+ let r = {
25
+ trigger: !1,
26
+ surface: !1
27
+ };
28
+ if (n == null) return r;
29
+ for (let { node: i } of e(n)) t(i, c) ? r.trigger = !0 : t(i, s) && (r.surface = !0);
30
+ return r;
31
+ }
32
+ var he = "TeachingPopover.Surface:placement", ge = "TeachingPopover.Surface: render one TeachingPopover.Surface in a TeachingPopover; a second Surface renders a second popover.", _e = "TeachingPopover:surface-props", ve = "TeachingPopover: the props of the surface element on TeachingPopover (`className`, `style`, `ref`, `onKeyDown` and the other element props) are ignored next to a TeachingPopover.Surface: pass them to the Surface.", f = ({ steps: e, activeStep: t, defaultActiveStep: i, currentStep: s, defaultCurrentStep: c, onStepChange: f, onDismiss: p, onFinish: ye, primaryAction: be, secondaryAction: xe, footerLayout: m = "horizontal", open: Se, defaultOpen: Ce, onOpenChange: we, closeLabel: h = "Close", labels: g, target: _, positioning: v, side: Te = "bottom", align: Ee = "center", children: y, id: b, className: x, style: S, onKeyDown: C, ref: w, ...T }) => {
33
+ re("TeachingPopover", _, v?.target);
34
+ let E = _ === void 0 ? v?.target : _, De = n("TeachingPopover", t, s, "currentStep", "activeStep"), D = n("TeachingPopover", i, c, "defaultCurrentStep", "defaultActiveStep") ?? 0, [O, k, A] = o(De, D, f), j = me(y), [M, N] = o(Se, Ce ?? !j.trigger, we), P = te("teaching-popover-title"), [Oe, ke] = l.useState(M), [F, I] = l.useState(!1);
35
+ M !== Oe && (ke(M), M && !A && !Object.is(O, D) && I(!0)), F && (A || Object.is(O, D)) && I(!1), l.useLayoutEffect(() => {
36
+ F && k(D);
37
+ }, [
38
+ F,
39
+ D,
40
+ k
41
+ ]);
42
+ let L = F ? D : O, R = e.length, z = M && R > 0, B = R > 0 ? d(L, R) : 0, V = R > 0 && B !== L, H = R > 0 ? e[B] : void 0, U = B === 0, W = B === R - 1, Ae = R > 0 ? (g?.step ?? fe)(B, R) : "", G = H ? u(H.primaryAction, be) : void 0, K = H ? u(H.secondaryAction, xe) : void 0, q = g?.back ?? ce, J = g?.next ?? le, je = g?.done ?? ue, Me = g?.nav ?? de, Ne = g?.navButton ?? pe, [Pe, Fe] = l.useState(null), Y = j.trigger || Pe !== null, Ie = E === void 0 ? Y ? Pe : void 0 : E, Le = l.useRef(null), Re = ne(Le, Fe), X = l.useRef(0), [ze, Be] = l.useState(!1), Ve = l.useCallback(() => (X.current += 1, Be(!0), () => {
43
+ --X.current, X.current === 0 && Be(!1);
44
+ }), []), Z = j.surface || ze;
45
+ l.useEffect(() => {
46
+ X.current > 1 && r(he, ge);
47
+ });
48
+ let He = te("teaching-popover"), [Ue, We] = l.useState(void 0), Ge = (Z ? Ue : b || void 0) ?? He, Ke = a(() => N(!0)), qe = a(() => {
49
+ N(!1), p?.();
50
+ }), Q = a(() => {
51
+ N(!1), ye?.(), p?.();
52
+ }), Je = a(() => {
53
+ U || k(B - 1);
54
+ }), Ye = a(() => {
55
+ W ? Q() : k(B + 1);
56
+ }), Xe = a((e) => {
57
+ if (R === 0) return;
58
+ let t = d(e, R);
59
+ t !== B && k(t);
60
+ }), Ze = Z && (b !== void 0 || x !== void 0 || S !== void 0 || C !== void 0 || w !== void 0 || Object.keys(T).length > 0);
61
+ l.useEffect(() => {
62
+ Ze && r(_e, ve);
63
+ }, [Ze]), l.useEffect(() => {
64
+ V && r("TeachingPopover:activeStep-range", `TeachingPopover: activeStep ${L} is out of range for ${R} steps; showing step ${B + 1}.`);
65
+ }, [
66
+ V,
67
+ L,
68
+ R,
69
+ B
70
+ ]);
71
+ let $ = l.useMemo(() => ({
72
+ open: M,
73
+ shown: z,
74
+ requestOpen: Ke,
75
+ dismiss: qe,
76
+ finish: Q,
77
+ count: R,
78
+ index: B,
79
+ step: H,
80
+ isFirst: U,
81
+ isLast: W,
82
+ stepPosition: Ae,
83
+ goBack: Je,
84
+ goNext: Ye,
85
+ goToStep: Xe,
86
+ primaryAction: G,
87
+ secondaryAction: K,
88
+ footerLayout: m,
89
+ backLabel: q,
90
+ nextLabel: J,
91
+ doneLabel: je,
92
+ closeLabel: h,
93
+ navLabel: Me,
94
+ navButtonLabel: Ne,
95
+ titleId: P,
96
+ target: Ie,
97
+ side: Te,
98
+ align: Ee,
99
+ positioning: v,
100
+ hasTrigger: Y,
101
+ triggerElementRef: Re,
102
+ triggerRef: Le,
103
+ surfaceId: Ge,
104
+ setCustomSurfaceId: We,
105
+ registerSurface: Ve
106
+ }), [
107
+ M,
108
+ z,
109
+ Ke,
110
+ qe,
111
+ Q,
112
+ R,
113
+ B,
114
+ H,
115
+ U,
116
+ W,
117
+ Ae,
118
+ Je,
119
+ Ye,
120
+ Xe,
121
+ G,
122
+ K,
123
+ m,
124
+ q,
125
+ J,
126
+ je,
127
+ h,
128
+ Me,
129
+ Ne,
130
+ P,
131
+ Ie,
132
+ Te,
133
+ Ee,
134
+ v,
135
+ Y,
136
+ Re,
137
+ Ge,
138
+ Ve
139
+ ]);
140
+ return /* @__PURE__ */ se(ie.Provider, {
141
+ value: $,
142
+ children: [y, Z ? null : /* @__PURE__ */ oe(ae, {
143
+ context: $,
144
+ rootClassName: ee.root,
145
+ id: b,
146
+ className: x,
147
+ style: S,
148
+ onKeyDown: C,
149
+ ...T,
150
+ ref: w
151
+ })]
152
+ });
153
+ };
154
+ f.displayName = "TeachingPopover";
155
+ //#endregion
156
+ export { f as TeachingPopoverRoot };
157
+
158
+ //# sourceMappingURL=TeachingPopover.root.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeachingPopover.root.mjs","names":["useId","useId$1","React","DEFAULT_BACK_LABEL","DEFAULT_NEXT_LABEL","DEFAULT_DONE_LABEL","DEFAULT_NAV_LABEL","defaultStepLabel","index","count","defaultNavButtonLabel","pickAction","slotRendersContent","own","fallback","clampStep","step","findParts","found","children","flattenChildren","isElementOfType","node","TeachingPopoverTrigger","TeachingPopoverSurface","SURFACE_PLACEMENT_WARNING_KEY","SURFACE_PLACEMENT_WARNING","SURFACE_PROPS_WARNING_KEY","SURFACE_PROPS_WARNING","TeachingPopoverRoot","activeStepProp","primaryActionProp","secondaryActionProp","openProp","targetProp","rest","positioning","explicitTarget","controlledStep","resolveDeprecatedProp","currentStep","initialStep","defaultActiveStep","defaultCurrentStep","storedStep","setStep","stepControlled","useControllable","onStepChange","parts","open","setOpen","defaultOpen","onOpenChange","titleId","openSeen","setOpenSeen","stepResetPending","setStepResetPending","rawStep","steps","shown","outOfRange","isFirst","isLast","stepPosition","labels","primaryAction","secondaryAction","backLabel","nextLabel","doneLabel","navLabel","navButtonLabel","triggerElement","setTriggerElement","hasTrigger","target","triggerRef","triggerElementRef","useMergedRefs","surfaceCountRef","hasRegisteredSurface","setHasRegisteredSurface","registerSurface","hasSurfacePart","warnOnce","generatedSurfaceId","customSurfaceId","setCustomSurfaceId","surfaceId","id","requestOpen","useEventCallback","dismiss","onDismiss","finish","onFinish","goBack","goNext","goToStep","next","ignoresSurfaceProps","className","style","onKeyDown","ref","context","footerLayout","closeLabel","side","align","TeachingPopoverContext","TeachingSurface","teachingPopoverClassNames"],"sources":["../../../src/components/overlays/TeachingPopover.root.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { teachingPopoverClassNames } from '../../lib/classNames';\nimport { resolveDeprecatedProp, warnOnce } from '../../lib/dev';\nimport { slotRendersContent } from '../../lib/slot';\nimport type { PopupAlign, PopupPositioning, PopupSide, VirtualElement } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useTargetConflictWarning } from '../../hooks/useResolvedTarget';\nimport {\n TeachingPopoverContext,\n type TeachingPopoverAction,\n type TeachingPopoverContextValue,\n type TeachingPopoverLabels,\n type TeachingPopoverStep,\n} from './TeachingPopover.context';\nimport {\n TeachingPopoverSurface,\n TeachingPopoverTrigger,\n TeachingSurface,\n} from './TeachingPopover.parts';\n\n/*\n * The TeachingPopover root: its props, the state of both forms (the open state, the step and the\n * step's resolved content), the child scan for the Trigger and the Surface, and the surface it\n * renders when no Surface is among its children. Imports the context and parts modules (never\n * `TeachingPopover.tsx`, which holds the compound).\n */\n\nconst DEFAULT_BACK_LABEL = 'Back';\nconst DEFAULT_NEXT_LABEL = 'Next';\nconst DEFAULT_DONE_LABEL = 'Done';\nconst DEFAULT_NAV_LABEL = 'Choose step';\nconst defaultStepLabel = (index: number, count: number) => `step ${index + 1} of ${count}`;\nconst defaultNavButtonLabel = (index: number, count: number) => `Step ${index + 1} of ${count}`;\n\n/** Properties for the TeachingPopover component. */\nexport interface TeachingPopoverProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Steps to display in the teaching popover (a readonly array is accepted). */\n steps: readonly TeachingPopoverStep[];\n /**\n * Controlled index of the displayed step. Out-of-range values are clamped to the first or last\n * step (with a development warning). Opening the popover leaves it as it is.\n */\n activeStep?: number;\n /**\n * Initial step index for uncontrolled usage, and the step the popover starts on again each time\n * it opens (after Done, Close, Escape or the Trigger closed it, or a controlled `open` turned it\n * off), so a tour opened again starts over; `onStepChange` is called with it when the step was\n * elsewhere.\n * @default 0\n */\n defaultActiveStep?: number;\n /** @deprecated Use `activeStep`. */\n currentStep?: number;\n /** @deprecated Use `defaultActiveStep`. */\n defaultCurrentStep?: number;\n /**\n * Called with the requested step index when Next, Back or a step button of\n * `TeachingPopover.CarouselNav` is activated (the button of the current step requests nothing),\n * and, while the step is uncontrolled, with the initial step when an opening moves the step back\n * to it (see `defaultActiveStep`).\n */\n onStepChange?: (step: number) => void;\n /**\n * Called when the popover is dismissed with Close, Done, Escape or a `TeachingPopover.Trigger`\n * that closes it.\n *\n * Done also calls it in 0.x, after `onFinish`, so that code written before `onFinish` keeps\n * working; from 1.0 only Close, Escape and the Trigger will.\n */\n onDismiss?: () => void;\n /**\n * Called when the tour is finished: Done, the button that replaces Next on the last step, or a\n * `primaryAction` on the last step whose click was not prevented. The popover closes first.\n * Close, Escape and the Trigger call only `onDismiss`. Fires on every activation, like\n * `onStepChange`.\n */\n onFinish?: () => void;\n /**\n * Replaces the Next (or Done) button on every step that sets no `primaryAction` of its own.\n */\n primaryAction?: TeachingPopoverAction;\n /**\n * Replaces the Back button on every step that sets no `secondaryAction` of its own.\n */\n secondaryAction?: TeachingPopoverAction;\n /**\n * How the footer lays out the step dots and the buttons: side by side, or the dots above\n * buttons that fill the width. Rendered as `data-layout` on the popover and on its footer.\n * `TeachingPopover.CarouselFooter` has its own `layout` instead.\n * @default 'horizontal'\n */\n footerLayout?: 'horizontal' | 'vertical';\n /** Controlled visibility of the teaching popover. */\n open?: boolean;\n /**\n * Initial visibility for uncontrolled usage: `true` (a tour that shows on page load), or\n * `false` when a `TeachingPopover.Trigger` is a direct child (a Fragment is fine), which then\n * opens it.\n * @default true (false with a direct TeachingPopover.Trigger)\n */\n defaultOpen?: boolean;\n /**\n * Called with `false` when Close, Done or Escape dismisses the popover, and with the new state\n * when a `TeachingPopover.Trigger` opens or closes it.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Accessible name of the built-in Close button (an icon-only button). Localize it with the\n * page's language.\n * @default 'Close'\n */\n closeLabel?: string;\n /**\n * Text of the Back, Next and Done buttons, the wording of the step position (“step 2 of 3”) and\n * the names of `TeachingPopover.CarouselNav`'s step buttons, for localization. Unset members keep\n * their English defaults.\n */\n labels?: TeachingPopoverLabels;\n /**\n * The element the popover points at (a ref, the element, or a `VirtualElement`: a rectangle such as a\n * point; an inline object is fine). When given, the popover is\n * rendered in a portal, positioned next to it with a beak, and flips or shifts to stay in view;\n * without it (`undefined`) the popover renders inline where it is placed (0.4 behaviour), or,\n * with a `TeachingPopover.Trigger`, points at the trigger.\n * While the target is `null` or has not been positioned against yet (an element held in state\n * that is not set yet, a ref that is not attached), the popover stays hidden: it is not\n * shown, takes no focus, announces no step change and does not handle Escape until it can\n * point at the target. It hides the same way when the target goes away later and shows again\n * when a target returns.\n *\n * An element (for example one held in state through a callback ref) is followed as soon as the\n * prop changes. A ref cannot be observed, so it is read after each render of the popover is\n * committed, wherever the target is in the tree: an element attaching to or detaching from the\n * ref is noticed the next time the popover renders (for example when the parent that mounts or\n * unmounts the target re-renders it), not in a commit that does not render the popover. A\n * memoized popover whose target mounts or unmounts in another subtree therefore stays hidden,\n * or keeps pointing at the removed element, until it renders again. A newly passed ref keeps\n * the previous visibility until it has been read, so a tour can move between attached refs\n * (`target={step === 0 ? aRef : bRef}`) without hiding, and a switch to a ref that is not\n * attached hides the popover right after that commit. Pass the element held in state when the\n * target can mount or unmount without the popover re-rendering.\n */\n target?: React.RefObject<HTMLElement | null> | HTMLElement | VirtualElement | null;\n /** Side of the `target` to open on; `start`/`end` follow the writing direction.\n * @default 'bottom'\n */\n side?: PopupSide;\n /** Alignment along the `target`'s edge.\n * @default 'center'\n */\n align?: PopupAlign;\n /**\n * Advanced positioning (Fluent's `positioning`): `offset`, `fitViewport`, `matchReferenceWidth`,\n * `fallbackPlacements` and `target` (used when the `target` prop is not set). `side` and `align`\n * stay separate props.\n * @default `{ offset: 12 }`\n */\n positioning?: PopupPositioning;\n /**\n * `TeachingPopover.Trigger` and `TeachingPopover.Surface` (Fluent's composition), rendered where\n * they are written. Without a `TeachingPopover.Surface` among them, the popover renders its\n * surface itself, after the children, with the element props given here (`className`, `style`,\n * `ref`, …); with one (best written directly inside, a Fragment is fine: see\n * `TeachingPopover.Surface`), the Surface takes them instead.\n */\n children?: React.ReactNode;\n /**\n * Ref to the popover surface (`role=\"dialog\"`). Ignored next to a `TeachingPopover.Surface`\n * (pass it to the Surface).\n */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** The action a step shows: its own when it renders anything, else the popover's. */\nfunction pickAction(\n own: TeachingPopoverAction | undefined,\n fallback: TeachingPopoverAction | undefined,\n): TeachingPopoverAction | undefined {\n if (slotRendersContent(own)) return own;\n return slotRendersContent(fallback) ? fallback : undefined;\n}\n\nfunction clampStep(step: number, count: number): number {\n if (!Number.isFinite(step)) return 0;\n return Math.min(Math.max(Math.trunc(step), 0), count - 1);\n}\n\n/**\n * Which parts are direct children (Fragments flattened, lazy types of a Server Component\n * unwrapped): a Trigger closes `defaultOpen`, a Surface replaces the root's own surface. Runs\n * during render, so the server HTML agrees (a Surface deeper down registers once mounted).\n */\nfunction findParts(children: React.ReactNode): { trigger: boolean; surface: boolean } {\n const found = { trigger: false, surface: false };\n if (children === null || children === undefined) return found;\n for (const { node } of flattenChildren(children)) {\n if (isElementOfType(node, TeachingPopoverTrigger)) found.trigger = true;\n else if (isElementOfType(node, TeachingPopoverSurface)) found.surface = true;\n }\n return found;\n}\n\nconst SURFACE_PLACEMENT_WARNING_KEY = 'TeachingPopover.Surface:placement';\nconst SURFACE_PLACEMENT_WARNING =\n 'TeachingPopover.Surface: render one TeachingPopover.Surface in a TeachingPopover; a second Surface renders a second popover.';\n\nconst SURFACE_PROPS_WARNING_KEY = 'TeachingPopover:surface-props';\nconst SURFACE_PROPS_WARNING =\n 'TeachingPopover: the props of the surface element on TeachingPopover (`className`, `style`, `ref`, `onKeyDown` and the other element props) are ignored next to a TeachingPopover.Surface: pass them to the Surface.';\n\n// The root of `TeachingPopover` (documented on the export in TeachingPopover.tsx).\nexport const TeachingPopoverRoot = ({\n steps,\n activeStep: activeStepProp,\n defaultActiveStep,\n currentStep,\n defaultCurrentStep,\n onStepChange,\n onDismiss,\n onFinish,\n primaryAction: primaryActionProp,\n secondaryAction: secondaryActionProp,\n footerLayout = 'horizontal',\n open: openProp,\n defaultOpen,\n onOpenChange,\n closeLabel = 'Close',\n labels,\n target: targetProp,\n positioning,\n side = 'bottom',\n align = 'center',\n children,\n id,\n className,\n style,\n onKeyDown,\n ref,\n ...rest\n}: TeachingPopoverProps) => {\n useTargetConflictWarning('TeachingPopover', targetProp, positioning?.target);\n const explicitTarget = (\n targetProp !== undefined ? targetProp : positioning?.target\n ) as TeachingPopoverProps['target'];\n const controlledStep = resolveDeprecatedProp(\n 'TeachingPopover',\n activeStepProp,\n currentStep,\n 'currentStep',\n 'activeStep',\n );\n const initialStep =\n resolveDeprecatedProp(\n 'TeachingPopover',\n defaultActiveStep,\n defaultCurrentStep,\n 'defaultCurrentStep',\n 'defaultActiveStep',\n ) ?? 0;\n const [storedStep, setStep, stepControlled] = useControllable(\n controlledStep,\n initialStep,\n onStepChange,\n );\n const parts = findParts(children);\n const [open, setOpen] = useControllable(openProp, defaultOpen ?? !parts.trigger, onOpenChange);\n const titleId = useId('teaching-popover-title');\n\n // An uncontrolled step starts again at the initial step each time the popover opens (not on\n // mount), whatever closed it and whatever opens it. The opening is noticed during render (C-HOOKS:\n // a previous-value state), so the opened popover shows the initial step from its first render;\n // the layout effect stores it through the setter (which calls `onStepChange` once, from the\n // commit), and the render that reads it back ends the reset.\n const [openSeen, setOpenSeen] = React.useState(open);\n const [stepResetPending, setStepResetPending] = React.useState(false);\n if (open !== openSeen) {\n setOpenSeen(open);\n if (open && !stepControlled && !Object.is(storedStep, initialStep)) {\n setStepResetPending(true);\n }\n }\n if (stepResetPending && (stepControlled || Object.is(storedStep, initialStep))) {\n setStepResetPending(false);\n }\n React.useLayoutEffect(() => {\n if (stepResetPending) setStep(initialStep);\n }, [stepResetPending, initialStep, setStep]);\n const rawStep = stepResetPending ? initialStep : storedStep;\n\n const count = steps.length;\n const shown = open && count > 0;\n const index = count > 0 ? clampStep(rawStep, count) : 0;\n const outOfRange = count > 0 && index !== rawStep;\n const step = count > 0 ? steps[index] : undefined;\n const isFirst = index === 0;\n const isLast = index === count - 1;\n const stepPosition = count > 0 ? (labels?.step ?? defaultStepLabel)(index, count) : '';\n const primaryAction = step ? pickAction(step.primaryAction, primaryActionProp) : undefined;\n const secondaryAction = step ? pickAction(step.secondaryAction, secondaryActionProp) : undefined;\n const backLabel = labels?.back ?? DEFAULT_BACK_LABEL;\n const nextLabel = labels?.next ?? DEFAULT_NEXT_LABEL;\n const doneLabel = labels?.done ?? DEFAULT_DONE_LABEL;\n const navLabel = labels?.nav ?? DEFAULT_NAV_LABEL;\n const navButtonLabel = labels?.navButton ?? defaultNavButtonLabel;\n\n // A Trigger is the target when neither `target` nor `positioning.target` is set: a direct one\n // from the first render (the surface stays hidden until its element attaches), a nested one\n // once its element has attached.\n const [triggerElement, setTriggerElement] = React.useState<HTMLElement | null>(null);\n const hasTrigger = parts.trigger || triggerElement !== null;\n const target =\n explicitTarget !== undefined ? explicitTarget : hasTrigger ? triggerElement : undefined;\n // The Trigger's element also as a ref, where the surface returns focus.\n const triggerRef = React.useRef<HTMLElement | null>(null);\n const triggerElementRef = useMergedRefs<HTMLElement>(triggerRef, setTriggerElement);\n\n // Surfaces (TeachingPopover.Surface) register while mounted, wherever they are among the\n // children: once one has, the root renders no surface of its own. A direct one is also found by\n // the scan above, so it never renders next to the root's own; one inside a component of yours\n // does in its first commit, until its registration re-renders the root. After every commit\n // (every surface's layout effect has run) more than one warns.\n const surfaceCountRef = React.useRef(0);\n const [hasRegisteredSurface, setHasRegisteredSurface] = React.useState(false);\n const registerSurface = React.useCallback(() => {\n surfaceCountRef.current += 1;\n setHasRegisteredSurface(true);\n return () => {\n surfaceCountRef.current -= 1;\n if (surfaceCountRef.current === 0) setHasRegisteredSurface(false);\n };\n }, []);\n const hasSurfacePart = parts.surface || hasRegisteredSurface;\n React.useEffect(() => {\n if (surfaceCountRef.current > 1) {\n warnOnce(SURFACE_PLACEMENT_WARNING_KEY, SURFACE_PLACEMENT_WARNING);\n }\n });\n\n // The Trigger's `aria-controls`: the surface's id (the root's own `id` on its own surface, or\n // the id a Surface reports), else a generated one.\n const generatedSurfaceId = useId('teaching-popover');\n const [customSurfaceId, setCustomSurfaceId] = React.useState<string | undefined>(undefined);\n const surfaceId = (hasSurfacePart ? customSurfaceId : id || undefined) ?? generatedSurfaceId;\n\n const requestOpen = useEventCallback(() => setOpen(true));\n const dismiss = useEventCallback(() => {\n setOpen(false);\n onDismiss?.();\n });\n // Done: close, then `onFinish`. `onDismiss` still follows in 0.x (see its JSDoc).\n const finish = useEventCallback(() => {\n setOpen(false);\n onFinish?.();\n onDismiss?.();\n });\n const goBack = useEventCallback(() => {\n if (!isFirst) setStep(index - 1);\n });\n const goNext = useEventCallback(() => {\n if (isLast) finish();\n else setStep(index + 1);\n });\n // A step button of TeachingPopover.CarouselNav: the shown (clamped) step requests nothing.\n const goToStep = useEventCallback((target: number) => {\n if (count === 0) return;\n const next = clampStep(target, count);\n if (next !== index) setStep(next);\n });\n\n // Next to a Surface the root renders no surface element, so its element props go nowhere.\n const ignoresSurfaceProps =\n hasSurfacePart &&\n (id !== undefined ||\n className !== undefined ||\n style !== undefined ||\n onKeyDown !== undefined ||\n ref !== undefined ||\n Object.keys(rest).length > 0);\n React.useEffect(() => {\n if (ignoresSurfaceProps) warnOnce(SURFACE_PROPS_WARNING_KEY, SURFACE_PROPS_WARNING);\n }, [ignoresSurfaceProps]);\n\n React.useEffect(() => {\n if (!outOfRange) return;\n warnOnce(\n 'TeachingPopover:activeStep-range',\n `TeachingPopover: activeStep ${rawStep} is out of range for ${count} steps; showing step ${index + 1}.`,\n );\n }, [outOfRange, rawStep, count, index]);\n\n const context = React.useMemo<TeachingPopoverContextValue>(\n () => ({\n open,\n shown,\n requestOpen,\n dismiss,\n finish,\n count,\n index,\n step,\n isFirst,\n isLast,\n stepPosition,\n goBack,\n goNext,\n goToStep,\n primaryAction,\n secondaryAction,\n footerLayout,\n backLabel,\n nextLabel,\n doneLabel,\n closeLabel,\n navLabel,\n navButtonLabel,\n titleId,\n target,\n side,\n align,\n positioning,\n hasTrigger,\n triggerElementRef,\n triggerRef,\n surfaceId,\n setCustomSurfaceId,\n registerSurface,\n }),\n [\n open,\n shown,\n requestOpen,\n dismiss,\n finish,\n count,\n index,\n step,\n isFirst,\n isLast,\n stepPosition,\n goBack,\n goNext,\n goToStep,\n primaryAction,\n secondaryAction,\n footerLayout,\n backLabel,\n nextLabel,\n doneLabel,\n closeLabel,\n navLabel,\n navButtonLabel,\n titleId,\n target,\n side,\n align,\n positioning,\n hasTrigger,\n triggerElementRef,\n surfaceId,\n registerSurface,\n ],\n );\n\n return (\n <TeachingPopoverContext.Provider value={context}>\n {children}\n {hasSurfacePart ? null : (\n <TeachingSurface\n context={context}\n rootClassName={teachingPopoverClassNames.root}\n id={id}\n className={className}\n style={style}\n onKeyDown={onKeyDown}\n {...rest}\n ref={ref}\n />\n )}\n </TeachingPopoverContext.Provider>\n );\n};\nTeachingPopoverRoot.displayName = 'TeachingPopover';\n"],"mappings":"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AACsD;EAAYH;EAASlD;EAAOD;CAAK,CAAC;CAEtC,IAAMmG,IAAUzG,EAAM,eACb;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,IACA;EACEgD;EACAW;EACA+B;EACAE;EACAE;EACAvF;EACAD;EACAQ;EACA+C;EACAC;EACAC;EACAiC;EACAC;EACAC;EACAjC;EACAC;EACAwC;EACAvC;EACAC;EACAC;EACAsC;EACArC;EACAC;EACAnB;EACAuB;EACAiC;EACAC;EACA3E;EACAwC;EACAG;EACAW;EACAN;CACF,CACF;CAEA,OACE,mBAAC4B,GAAuB,UAAxB;EAAiC,OAAOL;EAAxC,UAAA,CACGxF,GACAkE,IAAiB,OAChB,mBAAC4B,IAAD;GACW;GACT,eAAeC,GAA0B;GACrC;GACO;GACJ;GACI;GACX,GAAI/E;GACC;EACN,CAAA,CAE4B;;AAErC;AACA,EAAoB,cAAc"}
@@ -0,0 +1,2 @@
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs");let t=require("react");t=e.__toESM(t,1);var n=`data-wave-carousel-footer-slot`;function r(e,t){for(let r of Array.from(e.children))if(r.getAttribute(n)===t)return r;return null}function i(e){let t=r(e,`indicator`);return{secondary:r(e,`secondary`),indicator:t?.firstElementChild??null,primary:r(e,`primary`)}}var a=class{stacked=!1;listeners=new Set;observer=null;observed=new Set;subscribe=e=>(this.listeners.add(e),()=>{this.listeners.delete(e)});getSnapshot=()=>this.stacked;getServerSnapshot=()=>!1;measure(e){if(!e.clientWidth)return;let{secondary:t,indicator:n,primary:r}=i(e),a=0,o=0,s=e.ownerDocument.defaultView;if(s){let t=s.getComputedStyle(e);a=(parseFloat(t.paddingLeft)||0)+(parseFloat(t.paddingRight)||0),o=parseFloat(t.columnGap)||0}let c=e.clientWidth-a,l=2*Math.max(t?.offsetWidth??0,r?.offsetWidth??0)+(n?.offsetWidth??0)+2*o;this.set(l-c>.5)}connect(e){let t=()=>this.measure(e);if(typeof ResizeObserver<`u`){let n=0;return this.observer=new ResizeObserver(()=>{cancelAnimationFrame(n),n=requestAnimationFrame(t)}),this.follow(e),()=>{this.observer?.disconnect(),this.observer=null,this.observed.clear(),cancelAnimationFrame(n)}}return typeof window<`u`?(window.addEventListener(`resize`,t),()=>window.removeEventListener(`resize`,t)):()=>{}}follow(e){let t=this.observer;if(!t)return;let{secondary:n,indicator:r,primary:a}=i(e),o=new Set([e,n,r,a].filter(e=>e!==null));for(let e of Array.from(this.observed))o.has(e)||(t.unobserve(e),this.observed.delete(e));for(let e of o)this.observed.has(e)||(t.observe(e),this.observed.add(e))}set(e){if(e!==this.stacked){this.stacked=e;for(let e of Array.from(this.listeners))e()}}};function o(e,n){let[r]=t.useState(()=>new a),i=t.useSyncExternalStore(r.subscribe,r.getSnapshot,r.getServerSnapshot),[,o]=t.useReducer(e=>e+1,0);return t.useLayoutEffect(()=>{if(n&&e)return r.connect(e)},[r,n,e]),t.useLayoutEffect(()=>{if(!n||!e)return;r.follow(e);let t=r.subscribe(o);r.measure(e),t()}),n&&i}exports.useCarouselFooterStacked=o;
2
+ //# sourceMappingURL=TeachingPopover.stack.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeachingPopover.stack.cjs","names":["React","require_runtime","react","CAROUSEL_FOOTER_SLOT","slotOf","child","footer","slot","measuredElements","indicatorSlot","CarouselFooterStackStore","listener","padding","gap","view","style","available","needed","secondary","primary","indicator","measure","frame","observer","current","el","stacked","useCarouselFooterStacked","store","forceRender","count","enabled","unsubscribe"],"sources":["../../../src/components/overlays/TeachingPopover.stack.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * The attribute that marks the slots of a centered `TeachingPopover.CarouselFooter` (its direct\n * children): the secondary button, the indicator (whose first element child is measured) and the\n * primary button.\n */\nconst CAROUSEL_FOOTER_SLOT = 'data-wave-carousel-footer-slot';\n\ntype CarouselFooterSlot = 'secondary' | 'indicator' | 'primary';\n\n/** The slot element of `footer` named `slot`, if it is rendered. */\nfunction slotOf(footer: HTMLElement, slot: CarouselFooterSlot): HTMLElement | null {\n for (const child of Array.from(footer.children)) {\n if (child.getAttribute(CAROUSEL_FOOTER_SLOT) === slot) return child as HTMLElement;\n }\n return null;\n}\n\n/** The elements whose width is measured: both button slots and the indicator itself. */\nfunction measuredElements(footer: HTMLElement): {\n secondary: HTMLElement | null;\n indicator: HTMLElement | null;\n primary: HTMLElement | null;\n} {\n const indicatorSlot = slotOf(footer, 'indicator');\n return {\n secondary: slotOf(footer, 'secondary'),\n indicator: (indicatorSlot?.firstElementChild as HTMLElement | null | undefined) ?? null,\n primary: slotOf(footer, 'primary'),\n };\n}\n\n/**\n * One footer's measurement: whether its one row (the indicator centred between the buttons) does\n * not fit. Read through `useSyncExternalStore`.\n */\nclass CarouselFooterStackStore {\n private stacked = false;\n private readonly listeners = new Set<() => void>();\n private observer: ResizeObserver | null = null;\n private readonly observed = new Set<Element>();\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = (): boolean => this.stacked;\n\n /** The server HTML and hydration use the one-row layout. */\n getServerSnapshot = (): boolean => false;\n\n /**\n * The rule. The slots of the buttons and the indicator are as wide as their content in both\n * layouts (the one row and the stacked rows), so the measurement does not depend on the layout\n * it is made in. The one row has three columns, the outer two of equal width: it fits when\n * twice the wider button, the indicator and the two gaps fit in the footer's content box. A row\n * that would need unequal columns stacks instead, so the indicator of a row is always centred.\n * A footer without a box (not displayed, or not laid out yet) has no room to compare and keeps\n * its layout.\n */\n measure(footer: HTMLElement): void {\n if (!footer.clientWidth) return;\n const { secondary, indicator, primary } = measuredElements(footer);\n let padding = 0;\n let gap = 0;\n const view = footer.ownerDocument.defaultView;\n if (view) {\n const style = view.getComputedStyle(footer);\n padding = (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0);\n gap = parseFloat(style.columnGap) || 0;\n }\n const available = footer.clientWidth - padding;\n const side = Math.max(secondary?.offsetWidth ?? 0, primary?.offsetWidth ?? 0);\n const needed = 2 * side + (indicator?.offsetWidth ?? 0) + 2 * gap;\n // Half a pixel of slack for fractional widths that the integer box sizes round.\n this.set(needed - available > 0.5);\n }\n\n /** Observes `footer` and the elements it measures until the returned teardown runs. */\n connect(footer: HTMLElement): () => void {\n const measure = () => this.measure(footer);\n if (typeof ResizeObserver !== 'undefined') {\n // Measured in the next animation frame: the layout change resizes the observed footer, which\n // the browser would report as a loop error if it happened while the observer delivers.\n let frame = 0;\n this.observer = new ResizeObserver(() => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(measure);\n });\n this.follow(footer);\n return () => {\n this.observer?.disconnect();\n this.observer = null;\n this.observed.clear();\n cancelAnimationFrame(frame);\n };\n }\n if (typeof window !== 'undefined') {\n window.addEventListener('resize', measure);\n return () => window.removeEventListener('resize', measure);\n }\n return () => {};\n }\n\n /** Keeps the observer on the footer and on the elements measured now (slots come and go). */\n follow(footer: HTMLElement): void {\n const observer = this.observer;\n if (!observer) return;\n const { secondary, indicator, primary } = measuredElements(footer);\n const current = new Set<Element>(\n [footer, secondary, indicator, primary].filter((el): el is HTMLElement => el !== null),\n );\n for (const el of Array.from(this.observed)) {\n if (current.has(el)) continue;\n observer.unobserve(el);\n this.observed.delete(el);\n }\n for (const el of current) {\n if (this.observed.has(el)) continue;\n observer.observe(el);\n this.observed.add(el);\n }\n }\n\n private set(stacked: boolean): void {\n if (stacked === this.stacked) return;\n this.stacked = stacked;\n for (const listener of Array.from(this.listeners)) listener();\n }\n}\n\n/**\n * Whether a centered `TeachingPopover.CarouselFooter` stacks: `false` (one row, the indicator\n * centred between the buttons) on the server, on the first client render and while that row fits;\n * `true` (the indicator on its own row above the buttons) while it does not. `footer` is the\n * footer element, held in state through a callback ref. With `enabled` false (the offset layout,\n * which wraps by itself) nothing is observed or measured and the result is `false`.\n */\nexport function useCarouselFooterStacked(footer: HTMLElement | null, enabled: boolean): boolean {\n const [store] = React.useState(() => new CarouselFooterStackStore());\n const stacked = React.useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getServerSnapshot,\n );\n const [, forceRender] = React.useReducer((count: number) => count + 1, 0);\n\n React.useLayoutEffect(() => {\n if (!enabled || !footer) return undefined;\n return store.connect(footer);\n }, [store, enabled, footer]);\n\n // After every commit, before paint: a step changes the buttons and the indicator without a\n // resize of the footer. useSyncExternalStore subscribes only in a passive effect, which can run\n // after the browser painted, so a change found here re-renders through `forceRender` (the\n // pattern of MessageBar's reflow).\n React.useLayoutEffect(() => {\n if (!enabled || !footer) return;\n store.follow(footer);\n const unsubscribe = store.subscribe(forceRender);\n store.measure(footer);\n unsubscribe();\n });\n\n return enabled && stacked;\n}\n"],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ "use client";
2
+ import * as e from "react";
3
+ //#region src/components/overlays/TeachingPopover.stack.ts
4
+ var t = "data-wave-carousel-footer-slot";
5
+ function n(e, n) {
6
+ for (let r of Array.from(e.children)) if (r.getAttribute(t) === n) return r;
7
+ return null;
8
+ }
9
+ function r(e) {
10
+ let t = n(e, "indicator");
11
+ return {
12
+ secondary: n(e, "secondary"),
13
+ indicator: t?.firstElementChild ?? null,
14
+ primary: n(e, "primary")
15
+ };
16
+ }
17
+ var i = class {
18
+ stacked = !1;
19
+ listeners = /* @__PURE__ */ new Set();
20
+ observer = null;
21
+ observed = /* @__PURE__ */ new Set();
22
+ subscribe = (e) => (this.listeners.add(e), () => {
23
+ this.listeners.delete(e);
24
+ });
25
+ getSnapshot = () => this.stacked;
26
+ getServerSnapshot = () => !1;
27
+ measure(e) {
28
+ if (!e.clientWidth) return;
29
+ let { secondary: t, indicator: n, primary: i } = r(e), a = 0, o = 0, s = e.ownerDocument.defaultView;
30
+ if (s) {
31
+ let t = s.getComputedStyle(e);
32
+ a = (parseFloat(t.paddingLeft) || 0) + (parseFloat(t.paddingRight) || 0), o = parseFloat(t.columnGap) || 0;
33
+ }
34
+ let c = e.clientWidth - a, l = 2 * Math.max(t?.offsetWidth ?? 0, i?.offsetWidth ?? 0) + (n?.offsetWidth ?? 0) + 2 * o;
35
+ this.set(l - c > .5);
36
+ }
37
+ connect(e) {
38
+ let t = () => this.measure(e);
39
+ if (typeof ResizeObserver < "u") {
40
+ let n = 0;
41
+ return this.observer = new ResizeObserver(() => {
42
+ cancelAnimationFrame(n), n = requestAnimationFrame(t);
43
+ }), this.follow(e), () => {
44
+ this.observer?.disconnect(), this.observer = null, this.observed.clear(), cancelAnimationFrame(n);
45
+ };
46
+ }
47
+ return typeof window < "u" ? (window.addEventListener("resize", t), () => window.removeEventListener("resize", t)) : () => {};
48
+ }
49
+ follow(e) {
50
+ let t = this.observer;
51
+ if (!t) return;
52
+ let { secondary: n, indicator: i, primary: a } = r(e), o = new Set([
53
+ e,
54
+ n,
55
+ i,
56
+ a
57
+ ].filter((e) => e !== null));
58
+ for (let e of Array.from(this.observed)) o.has(e) || (t.unobserve(e), this.observed.delete(e));
59
+ for (let e of o) this.observed.has(e) || (t.observe(e), this.observed.add(e));
60
+ }
61
+ set(e) {
62
+ if (e !== this.stacked) {
63
+ this.stacked = e;
64
+ for (let e of Array.from(this.listeners)) e();
65
+ }
66
+ }
67
+ };
68
+ function a(t, n) {
69
+ let [r] = e.useState(() => new i()), a = e.useSyncExternalStore(r.subscribe, r.getSnapshot, r.getServerSnapshot), [, o] = e.useReducer((e) => e + 1, 0);
70
+ return e.useLayoutEffect(() => {
71
+ if (n && t) return r.connect(t);
72
+ }, [
73
+ r,
74
+ n,
75
+ t
76
+ ]), e.useLayoutEffect(() => {
77
+ if (!n || !t) return;
78
+ r.follow(t);
79
+ let e = r.subscribe(o);
80
+ r.measure(t), e();
81
+ }), n && a;
82
+ }
83
+ //#endregion
84
+ export { a as useCarouselFooterStacked };
85
+
86
+ //# sourceMappingURL=TeachingPopover.stack.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeachingPopover.stack.mjs","names":["React","CAROUSEL_FOOTER_SLOT","slotOf","child","footer","slot","measuredElements","indicatorSlot","CarouselFooterStackStore","listener","padding","gap","view","style","available","needed","secondary","primary","indicator","measure","frame","observer","current","el","stacked","useCarouselFooterStacked","store","forceRender","count","enabled","unsubscribe"],"sources":["../../../src/components/overlays/TeachingPopover.stack.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * The attribute that marks the slots of a centered `TeachingPopover.CarouselFooter` (its direct\n * children): the secondary button, the indicator (whose first element child is measured) and the\n * primary button.\n */\nconst CAROUSEL_FOOTER_SLOT = 'data-wave-carousel-footer-slot';\n\ntype CarouselFooterSlot = 'secondary' | 'indicator' | 'primary';\n\n/** The slot element of `footer` named `slot`, if it is rendered. */\nfunction slotOf(footer: HTMLElement, slot: CarouselFooterSlot): HTMLElement | null {\n for (const child of Array.from(footer.children)) {\n if (child.getAttribute(CAROUSEL_FOOTER_SLOT) === slot) return child as HTMLElement;\n }\n return null;\n}\n\n/** The elements whose width is measured: both button slots and the indicator itself. */\nfunction measuredElements(footer: HTMLElement): {\n secondary: HTMLElement | null;\n indicator: HTMLElement | null;\n primary: HTMLElement | null;\n} {\n const indicatorSlot = slotOf(footer, 'indicator');\n return {\n secondary: slotOf(footer, 'secondary'),\n indicator: (indicatorSlot?.firstElementChild as HTMLElement | null | undefined) ?? null,\n primary: slotOf(footer, 'primary'),\n };\n}\n\n/**\n * One footer's measurement: whether its one row (the indicator centred between the buttons) does\n * not fit. Read through `useSyncExternalStore`.\n */\nclass CarouselFooterStackStore {\n private stacked = false;\n private readonly listeners = new Set<() => void>();\n private observer: ResizeObserver | null = null;\n private readonly observed = new Set<Element>();\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = (): boolean => this.stacked;\n\n /** The server HTML and hydration use the one-row layout. */\n getServerSnapshot = (): boolean => false;\n\n /**\n * The rule. The slots of the buttons and the indicator are as wide as their content in both\n * layouts (the one row and the stacked rows), so the measurement does not depend on the layout\n * it is made in. The one row has three columns, the outer two of equal width: it fits when\n * twice the wider button, the indicator and the two gaps fit in the footer's content box. A row\n * that would need unequal columns stacks instead, so the indicator of a row is always centred.\n * A footer without a box (not displayed, or not laid out yet) has no room to compare and keeps\n * its layout.\n */\n measure(footer: HTMLElement): void {\n if (!footer.clientWidth) return;\n const { secondary, indicator, primary } = measuredElements(footer);\n let padding = 0;\n let gap = 0;\n const view = footer.ownerDocument.defaultView;\n if (view) {\n const style = view.getComputedStyle(footer);\n padding = (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0);\n gap = parseFloat(style.columnGap) || 0;\n }\n const available = footer.clientWidth - padding;\n const side = Math.max(secondary?.offsetWidth ?? 0, primary?.offsetWidth ?? 0);\n const needed = 2 * side + (indicator?.offsetWidth ?? 0) + 2 * gap;\n // Half a pixel of slack for fractional widths that the integer box sizes round.\n this.set(needed - available > 0.5);\n }\n\n /** Observes `footer` and the elements it measures until the returned teardown runs. */\n connect(footer: HTMLElement): () => void {\n const measure = () => this.measure(footer);\n if (typeof ResizeObserver !== 'undefined') {\n // Measured in the next animation frame: the layout change resizes the observed footer, which\n // the browser would report as a loop error if it happened while the observer delivers.\n let frame = 0;\n this.observer = new ResizeObserver(() => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(measure);\n });\n this.follow(footer);\n return () => {\n this.observer?.disconnect();\n this.observer = null;\n this.observed.clear();\n cancelAnimationFrame(frame);\n };\n }\n if (typeof window !== 'undefined') {\n window.addEventListener('resize', measure);\n return () => window.removeEventListener('resize', measure);\n }\n return () => {};\n }\n\n /** Keeps the observer on the footer and on the elements measured now (slots come and go). */\n follow(footer: HTMLElement): void {\n const observer = this.observer;\n if (!observer) return;\n const { secondary, indicator, primary } = measuredElements(footer);\n const current = new Set<Element>(\n [footer, secondary, indicator, primary].filter((el): el is HTMLElement => el !== null),\n );\n for (const el of Array.from(this.observed)) {\n if (current.has(el)) continue;\n observer.unobserve(el);\n this.observed.delete(el);\n }\n for (const el of current) {\n if (this.observed.has(el)) continue;\n observer.observe(el);\n this.observed.add(el);\n }\n }\n\n private set(stacked: boolean): void {\n if (stacked === this.stacked) return;\n this.stacked = stacked;\n for (const listener of Array.from(this.listeners)) listener();\n }\n}\n\n/**\n * Whether a centered `TeachingPopover.CarouselFooter` stacks: `false` (one row, the indicator\n * centred between the buttons) on the server, on the first client render and while that row fits;\n * `true` (the indicator on its own row above the buttons) while it does not. `footer` is the\n * footer element, held in state through a callback ref. With `enabled` false (the offset layout,\n * which wraps by itself) nothing is observed or measured and the result is `false`.\n */\nexport function useCarouselFooterStacked(footer: HTMLElement | null, enabled: boolean): boolean {\n const [store] = React.useState(() => new CarouselFooterStackStore());\n const stacked = React.useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getServerSnapshot,\n );\n const [, forceRender] = React.useReducer((count: number) => count + 1, 0);\n\n React.useLayoutEffect(() => {\n if (!enabled || !footer) return undefined;\n return store.connect(footer);\n }, [store, enabled, footer]);\n\n // After every commit, before paint: a step changes the buttons and the indicator without a\n // resize of the footer. useSyncExternalStore subscribes only in a passive effect, which can run\n // after the browser painted, so a change found here re-renders through `forceRender` (the\n // pattern of MessageBar's reflow).\n React.useLayoutEffect(() => {\n if (!enabled || !footer) return;\n store.follow(footer);\n const unsubscribe = store.subscribe(forceRender);\n store.measure(footer);\n unsubscribe();\n });\n\n return enabled && stacked;\n}\n"],"mappings":"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"}