Yugen UI

TeachingPopover

TeachingPopover introduces a new feature or walks people through steps, right next to the related element.

Built on Popover (shadow-16, with an arrow). It has a Header (icon, small title and close button), a Body (optional illustration, title and content), a Footer (primary and secondary buttons) and a Carousel for several steps ("1/3", navigation dots, “Back” / “Next” / “Finish”). appearance="brand" fills this small surface with the brand color.

Import

Install from npm, copy the source into your project with @yugen-ui/cli or the shadcn CLI, or import directly when working in this repo.

TSX
// npm install yugen-uiimport {  TeachingPopover, TeachingPopoverTrigger, TeachingPopoverSurface, TeachingPopoverHeader,  TeachingPopoverBody, TeachingPopoverTitle, TeachingPopoverFooter, TeachingPopoverCarousel,} from "yugen-ui";

Variants

Each tile is a standalone example: hover to copy, or press Code to see the source.

Brand & illustration

appearance="brand" on TeachingPopover; media appears above the content.

Vertical footer

orientation="vertical" stacks the two buttons at full width, which suits long labels.

Multiple steps (Carousel)

Each child of TeachingPopoverCarousel is one step. The first step has “Not now”, the last one “Finish”.

Usage

Do
  • Show only one TeachingPopover at a time, attached to the element it introduces.
  • Keep the title short and the content to 1–2 sentences. Always offer a way to close it (the X button or the secondary button).
  • Limit multi-step tours to 3–5 steps.
Don't
  • Don't use it for error messages or confirmations. Use MessageBar / Dialog.
  • Don't open it again after people have dismissed it.
  • Don't put forms or long content in the surface.

Props

Prop · TypeDefaultDescription
TeachingPopover.appearance"normal" | "brand"Default: "normal"Applies to the surface, header and buttons.
TeachingPopover.open / onOpenChangeboolean / (open) => voidDefault: —Controls visibility (Radix Popover).
TeachingPopoverSurface.side / align / withArrowPopover propsDefault: withArrow = trueSurface position (320px wide).
TeachingPopoverHeader.icon / dismissibleReactNode / booleanDefault: lightbulb / trueIcon before the title; close button.
TeachingPopoverBody.mediaReactNodeDefault: —Illustration above the content.
TeachingPopoverFooter.primary / secondaryReactNodeDefault: —Labels of the two buttons; the secondary button closes the popover.
TeachingPopoverFooter.closeOnPrimary / orientationboolean / "horizontal" | "vertical"Default: —Closes the popover when the primary button is clicked; direction of the buttons. The old name layout is deprecated (removed in 1.0).
TeachingPopoverCarousel.step / defaultStep / onStepChangenumberDefault: —Current step (starting at 0).
TeachingPopoverCarousel.onFinish / *Label() => void / stringDefault: —onFinish runs when “Finish” is clicked. nextLabel / previousLabel / finishLabel / dismissLabel replace “Next” / “Back” / “Finish” / “Not now”.

Messages

Text built into the component: labels, aria-labels, screen reader announcements.

English by default. Change it with the messages prop of YugenProvider, by the namespace below; messagesVi has the Vietnamese set. See Interface language.

messages.teachingPopover

Key · TypeDefault (English)messagesVi
closestring

aria-label nút X của TeachingPopoverHeader.

Default (English)"Close"messagesVi"Đóng"
nextstring

Nút của TeachingPopoverCarousel.

Default (English)"Next"messagesVi"Tiếp"
previousstringDefault (English)"Back"messagesVi"Quay lại"
finishstringDefault (English)"Finish"messagesVi"Hoàn tất"
laterstring

Nút phụ ở bước đầu (đóng popover).

Default (English)"Not now"messagesVi"Để sau"
stepRoleDescriptionstring

aria-roledescription của từng bước.

Default (English)"step"messagesVi"bước"
step(current: number, count: number) => string

Tên bước hiện tại; current đếm từ 1.

Default (English)(current, count) => `Step ${current} of ${count}`messagesVi(current, count) => `Bước ${current}/${count}`
goToStep(index: number) => string

aria-label chấm điều hướng; index đếm từ 1.

Default (English)(index) => `Go to step ${index}`messagesVi(index) => `Đến bước ${index}`