@stackone/malachite 2.42.1 → 2.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"SelectableCard.js","sources":["../../src/components/SelectableCard.tsx"],"sourcesContent":["import React, { useId, useRef } from 'react';\nimport Button from './Button';\nimport DismissIcon from './CustomIcons/DismissIcon';\nimport PinIcon from './CustomIcons/PinIcon';\nimport Tag, { type TagType } from './Tag';\nimport Tooltip from './Tooltip';\nimport TruncatedTooltip from './TruncatedTooltip';\nimport Text from './Typography/Text';\nimport { useCardStripSlot } from './cardStripSlot';\nimport { FOCUS_RING_WITHIN } from './focusRing';\nimport { useAdoptedStyleSheet } from './useAdoptedStyleSheet';\n\nexport interface SelectableCardStatus {\n label: string;\n /** Maps to Tag's palette — `default` (grey) for \"Disabled\", `warning` (amber) for \"Draft\". */\n type?: TagType;\n}\n\n/** The card's palette: `profile` is green, `library` neutral, `editing` amber for a\n * profile with unsaved changes. */\nexport type SelectableCardVariant = 'profile' | 'library' | 'editing';\n\nexport interface SelectableCardProps {\n /** Identifies the card inside its group; handed back to `onSelect`. */\n value: string;\n title: string;\n /** Leading glyph on the title line, e.g. a library/book icon. */\n titleIcon?: React.ReactNode;\n /** Pins the card as the account default, marked beside the title. */\n isDefault?: boolean;\n /** Palette only — gradient, borders, indicator and eyebrow; position is settled by the strip. */\n variant?: SelectableCardVariant;\n /** Small label above the title (\"Profile\", \"Explore\"). */\n eyebrow?: string;\n /** Status pill rendered next to the eyebrow — or in its place when there is no eyebrow. */\n status?: SelectableCardStatus;\n /** Supporting copy under the title, clamped to two lines. */\n description?: string;\n /** Bottom-left summary (\"16 Actions\", \"10 Selected\"). */\n countLabel?: string;\n /** Top-right cluster (markers, an ActionMenu…). The eyebrow row gives way to one\n * xsmall control; a wider cluster needs a shorter eyebrow and status to clear it. */\n actions?: React.ReactNode;\n /** Renders an x after `actions`, tinted like the eyebrow, that calls this. */\n onDismiss?: () => void;\n /** Names the x for assistive tech and its tooltip. */\n dismissLabel?: string;\n /** Disables the x and shows this as its tooltip instead. */\n dismissDisabledReason?: string;\n selected?: boolean;\n /** Replaces the card's content with a centred in-progress message. */\n loading?: boolean;\n loadingLabel?: string;\n loadingHint?: string;\n /** Blocks selection. Draws no dimming of its own — a switched-off profile is signalled by its `status` tag. */\n disabled?: boolean;\n /** Mutes the title without blocking selection. */\n dimmed?: boolean;\n onSelect?: (value: string) => void;\n /** Tab stop for the card. */\n tabIndex?: number;\n /** Replaces the generated accessible name (eyebrow + title + status). */\n 'aria-label'?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const CARD_WIDTH_PX = 240;\nconst CARD_WIDTH = `${CARD_WIDTH_PX}px`;\nconst CARD_HEIGHT = '116px';\nconst CARD_CORNER = 'var(--malachite-radius-xxl, 14px)';\nconst CARD_RADIUS = `${CARD_CORNER} ${CARD_CORNER} 0 0`;\n\nconst MUTED = 'var(--malachite-selectable-card-muted-foreground, #7b7b7b)';\nconst EYEBROW = 'var(--malachite-text-secondary, #7b7b7b)';\n\nconst PROFILE_ACCENT = 'var(--malachite-selectable-card-accent, #047b43)';\nconst PROFILE_TINT = 'var(--malachite-selectable-card-selected-tint, #e7f8f1)';\nconst PROFILE_SELECTED_BORDER = 'var(--malachite-selectable-card-selected-border, #047b43)';\nconst PROFILE_EYEBROW_OPACITY = 0.7;\n\nconst LIBRARY_TINT = 'var(--malachite-selectable-card-library-selected-tint, #f1f1f1)';\nconst LIBRARY_SELECTED_BORDER = 'var(--malachite-selectable-card-library-selected-border, #bbbbbb)';\n\nconst EDITING_ACCENT = 'var(--malachite-selectable-card-pending-foreground, #96580a)';\nconst EDITING_TINT = 'var(--malachite-selectable-card-editing-tint, #f9f2e9)';\n\nconst SELECTED_SURFACE_END = 'var(--malachite-selectable-card-selected-surface-end, #ffffff)';\n\nconst RESTING_SURFACE = 'var(--malachite-selectable-card-background, #f1f1f1)';\nconst RESTING_BORDER = '1px solid var(--malachite-selectable-card-border, #dddddd)';\n\nconst HOVER_SURFACE_FILL = 'var(--malachite-selectable-card-hover-background, #e8e8e8)';\n\n/** How far a selected card's outline sweeps past its own edge. The strip keeps this much\n * clear of its scroller's clip. */\nexport const CARD_FLARE_PX = 14;\nconst FLARE_PX = CARD_FLARE_PX;\nconst STROKE_PX = 2;\nconst CARD_HEIGHT_PX = 116;\nconst CORNER_PX = 14;\n\n/** Weight of the strip's bottom rule, which a selected card's flare reaches down through. */\nexport const STRIP_RULE_PX = 2;\n\n/** Where the strip's rule meets the flare. The stroke is centred on its path, so the tip\n * stops half a stroke inside the flare box. */\nexport const CARD_FLARE_TIP_PX = FLARE_PX - STROKE_PX / 2;\n\nconst FLARE_BOX_WIDTH = CARD_WIDTH_PX + FLARE_PX * 2;\nconst FLARE_BOX_HEIGHT = CARD_HEIGHT_PX + STRIP_RULE_PX + STROKE_PX;\n\n/** Stroke is centred on the path, so the card's own edges sit half a stroke inside the box. */\nconst pathTo = (base: number): string => {\n const inset = STROKE_PX / 2;\n const left = FLARE_PX + inset;\n const right = FLARE_PX + CARD_WIDTH_PX - inset;\n const top = inset;\n const r = CORNER_PX - inset;\n return [\n `M${left - FLARE_PX} ${base}`,\n `A${FLARE_PX} ${FLARE_PX} 0 0 0 ${left} ${base - FLARE_PX}`,\n `L${left} ${top + r}`,\n `A${r} ${r} 0 0 1 ${left + r} ${top}`,\n `L${right - r} ${top}`,\n `A${r} ${r} 0 0 1 ${right} ${top + r}`,\n `L${right} ${base - FLARE_PX}`,\n `A${FLARE_PX} ${FLARE_PX} 0 0 0 ${right + FLARE_PX} ${base}`,\n ].join(' ');\n};\n\nconst OUTLINE_PATH = pathTo(CARD_HEIGHT_PX + STRIP_RULE_PX / 2);\n\nconst FILL_PATH = `${OUTLINE_PATH} Z`;\n\nexport const FLARE_CLASS = 'malachite-selectable-card-outline';\n\nconst ROOT_CLASS = 'malachite-selectable-card';\nconst STYLE_ID = 'malachite-selectable-card-style';\n\nconst OUTLINE_PROPERTY = '--malachite-selectable-card-state-outline';\nconst TINT_PROPERTY = '--malachite-selectable-card-state-tint';\n\ntype CardState = 'resting' | 'hover' | 'selected';\ntype SettledState = Exclude<CardState, 'hover'>;\n\ntype Declarations = Record<string, string>;\n\nconst HOVER_SURFACE: Declarations = {\n 'background-color': HOVER_SURFACE_FILL,\n 'border-left-color': 'transparent',\n};\n\nconst RESTING_SURFACE_DECLARATIONS: Declarations = {\n 'background-color': RESTING_SURFACE,\n};\n\n/** Never inline styles: an inline declaration outranks the sheet, so `:hover` could never repaint the card. */\nconst SURFACES: Record<SelectableCardVariant, Record<CardState, Declarations>> = {\n profile: {\n resting: RESTING_SURFACE_DECLARATIONS,\n hover: HOVER_SURFACE,\n selected: {\n [OUTLINE_PROPERTY]: PROFILE_SELECTED_BORDER,\n [TINT_PROPERTY]: PROFILE_TINT,\n },\n },\n library: {\n resting: RESTING_SURFACE_DECLARATIONS,\n hover: HOVER_SURFACE,\n selected: {\n [OUTLINE_PROPERTY]: LIBRARY_SELECTED_BORDER,\n [TINT_PROPERTY]: LIBRARY_TINT,\n },\n },\n editing: {\n resting: RESTING_SURFACE_DECLARATIONS,\n hover: HOVER_SURFACE,\n selected: {\n [OUTLINE_PROPERTY]: EDITING_ACCENT,\n [TINT_PROPERTY]: EDITING_TINT,\n },\n },\n};\n\nconst RESTING_EYEBROW: React.CSSProperties = { color: EYEBROW };\n\nconst EYEBROWS: Record<SelectableCardVariant, Record<SettledState, React.CSSProperties>> = {\n profile: {\n resting: RESTING_EYEBROW,\n selected: { color: PROFILE_ACCENT, opacity: PROFILE_EYEBROW_OPACITY },\n },\n library: { resting: RESTING_EYEBROW, selected: RESTING_EYEBROW },\n editing: {\n resting: RESTING_EYEBROW,\n selected: { color: EDITING_ACCENT, opacity: PROFILE_EYEBROW_OPACITY },\n },\n};\n\nconst SCROLLED_SURFACE: Declarations = { 'border-left': RESTING_BORDER };\n\nconst OUTLINE_CSS = `\n.${ROOT_CLASS}[data-state='selected'] {\n z-index: 5;\n}\n.${ROOT_CLASS} > .${FLARE_CLASS} {\n position: absolute;\n left: -${FLARE_PX}px;\n top: 0;\n z-index: 0;\n overflow: visible;\n pointer-events: none;\n}\n.${ROOT_CLASS} > *:not(.${FLARE_CLASS}):not([data-selectable-card-actions]) {\n position: relative;\n z-index: 1;\n}\n.${ROOT_CLASS} > [data-selectable-card-actions] {\n z-index: 2;\n}`;\n\nconst bodyOf = (declarations: Declarations): string =>\n Object.entries(declarations)\n .map(([property, value]) => ` ${property}: ${value};`)\n .join('\\n');\n\nconst selectorFor = (variant: SelectableCardVariant, state: CardState): string =>\n state === 'hover'\n ? `.${ROOT_CLASS}[data-variant='${variant}'][data-state='resting'][data-hoverable]:hover`\n : `.${ROOT_CLASS}[data-variant='${variant}'][data-state='${state}']`;\n\nconst ruleFor = (\n variant: SelectableCardVariant,\n state: CardState,\n declarations: Declarations,\n): string => `${selectorFor(variant, state)} {\\n${bodyOf(declarations)}\\n}`;\n\nconst SURFACE_CSS = (Object.keys(SURFACES) as SelectableCardVariant[])\n .flatMap((variant) =>\n (Object.keys(SURFACES[variant]) as CardState[]).map((state) =>\n ruleFor(variant, state, SURFACES[variant][state]),\n ),\n )\n .join('\\n');\n\nconst SLOT_CSS = `.${ROOT_CLASS}[data-pinned='false'][data-state='resting'] {\\n${bodyOf(\n SCROLLED_SURFACE,\n)}\\n}`;\n\nconst CARD_CSS = `${SLOT_CSS}\\n${SURFACE_CSS}\\n${OUTLINE_CSS}`;\n\nconst DESCRIPTION_STYLE: React.CSSProperties = {\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n color: MUTED,\n lineHeight: 1.6,\n};\n\nconst COUNT_STYLE: React.CSSProperties = { color: MUTED, letterSpacing: '0.11px' };\n\nconst PENDING = 'var(--malachite-selectable-card-pending-foreground, #96580a)';\n\nconst LOADING_LABEL_STYLE: React.CSSProperties = { color: PENDING };\nconst LOADING_HINT_STYLE: React.CSSProperties = { color: PENDING, opacity: 0.7 };\n\nconst PENDING_BODY_TOP_PX = 36;\nconst PENDING_BODY_BOTTOM_PX = 38;\n\n// The 16px library icon's glyph inset, so it lines up with the text below.\nconst TITLE_ICON_INSET_PX = 2.25;\nconst TITLE_ICON_STYLE: React.CSSProperties = {\n color: 'var(--malachite-text-primary)',\n marginLeft: -TITLE_ICON_INSET_PX,\n};\n\n// Offsets the outline button's 1px drop shadow so it centres on the eyebrow.\nconst ACTIONS_STYLE: React.CSSProperties = { transform: 'translateY(-1px)' };\n\nconst DISMISS_ICON_BOX = 'inline-flex items-center justify-center [&_svg]:size-[10px]!';\nconst DISABLED_DISMISS_STYLE: React.CSSProperties = { color: MUTED };\n\nconst DEFAULT_MARKER_LABEL = 'Default profile';\nconst DEFAULT_MARKER_SIZE_PX = 16;\n// The tilted pin's glyph inset.\nconst DEFAULT_MARKER_INSET_PX = 3;\nconst DEFAULT_MARKER_STYLE: React.CSSProperties = {\n color: PROFILE_ACCENT,\n display: 'inline-flex',\n transform: 'rotate(45deg)',\n};\nconst LEADING_DEFAULT_MARKER_STYLE: React.CSSProperties = {\n ...DEFAULT_MARKER_STYLE,\n marginLeft: -DEFAULT_MARKER_INSET_PX,\n};\n\n/** Announced rather than shown alone: a bare glyph reads as an unnamed graphic, and the tooltip\n * travels by `aria-describedby`, which describes rather than names. */\nconst DefaultMarker: React.FC<{ leading: boolean }> = ({ leading }) => (\n <Tooltip text={DEFAULT_MARKER_LABEL} triggerAs=\"span\" describesTrigger={false}>\n <span\n role=\"img\"\n aria-label={DEFAULT_MARKER_LABEL}\n style={leading ? LEADING_DEFAULT_MARKER_STYLE : DEFAULT_MARKER_STYLE}\n >\n <PinIcon size={DEFAULT_MARKER_SIZE_PX} />\n </span>\n </Tooltip>\n);\n\nconst joinIds = (ids: Array<string | undefined>): string | undefined => {\n const present = ids.filter((id): id is string => id !== undefined);\n return present.length > 0 ? present.join(' ') : undefined;\n};\n\n/** A fixed-size card that behaves as one option in a radio group: a card-shaped `Surface.Row`. */\nconst SelectableCard: React.FC<SelectableCardProps> = ({\n value,\n title,\n titleIcon,\n isDefault = false,\n variant = 'profile',\n eyebrow,\n status,\n description,\n countLabel,\n actions,\n onDismiss,\n dismissLabel = 'Dismiss',\n dismissDisabledReason,\n selected = false,\n loading = false,\n loadingLabel = 'Loading…',\n loadingHint,\n disabled = false,\n dimmed = false,\n onSelect,\n tabIndex,\n 'aria-label': ariaLabel,\n className = '',\n style,\n}) => {\n const { pinned } = useCardStripSlot();\n const hoverable = !selected && !disabled;\n\n const rootRef = useRef<HTMLDivElement>(null);\n useAdoptedStyleSheet(rootRef, CARD_CSS, STYLE_ID);\n\n const instanceId = `mal-selectable-card-${useId().replace(/[^a-zA-Z0-9_-]/g, '')}`;\n const outlineGradientId = `${instanceId}-outline`;\n const eyebrowId = `${instanceId}-eyebrow`;\n const statusId = `${instanceId}-status`;\n const titleId = `${instanceId}-title`;\n const descriptionId = `${instanceId}-description`;\n const countId = `${instanceId}-count`;\n\n const labelledBy = ariaLabel\n ? undefined\n : joinIds([eyebrow ? eyebrowId : undefined, titleId, status ? statusId : undefined]);\n const describedBy = joinIds([\n description ? descriptionId : undefined,\n countLabel ? countId : undefined,\n ]);\n\n if (loading) {\n return (\n <div\n ref={rootRef}\n role=\"status\"\n aria-busy=\"true\"\n aria-live=\"polite\"\n data-variant=\"editing\"\n data-state=\"selected\"\n className={`${ROOT_CLASS} relative flex shrink-0 flex-col items-center gap-2 px-5 text-center ${className}`.trim()}\n style={\n {\n width: CARD_WIDTH,\n height: CARD_HEIGHT,\n borderRadius: CARD_RADIUS,\n boxSizing: 'border-box',\n paddingTop: `${PENDING_BODY_TOP_PX}px`,\n paddingBottom: `${PENDING_BODY_BOTTOM_PX}px`,\n justifyContent: 'center',\n [OUTLINE_PROPERTY]: PENDING,\n [TINT_PROPERTY]: EDITING_TINT,\n ...style,\n } as React.CSSProperties\n }\n >\n {/* The same outline a selected card wears: this IS the selection while a profile\n is being built, so it has to break the strip's rule rather than sit on it. */}\n <svg\n className={FLARE_CLASS}\n width={FLARE_BOX_WIDTH}\n height={FLARE_BOX_HEIGHT}\n viewBox={`0 0 ${FLARE_BOX_WIDTH} ${FLARE_BOX_HEIGHT}`}\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <defs>\n <linearGradient id={outlineGradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0\" style={{ stopColor: `var(${TINT_PROPERTY})` }} />\n <stop offset=\"1\" style={{ stopColor: SELECTED_SURFACE_END }} />\n </linearGradient>\n </defs>\n <path\n d={FILL_PATH}\n data-malachite-shape=\"\"\n style={{ fill: `url(#${outlineGradientId})` }}\n />\n <path\n d={OUTLINE_PATH}\n data-malachite-shape=\"\"\n strokeWidth={STROKE_PX}\n style={{ fill: 'none', stroke: `var(${OUTLINE_PROPERTY})` }}\n />\n </svg>\n <Text size=\"small\" fontWeight=\"semi-bold\" style={LOADING_LABEL_STYLE}>\n {loadingLabel}\n </Text>\n {loadingHint ? (\n <Text size=\"xsmall\" fontWeight=\"semi-bold\" style={LOADING_HINT_STYLE}>\n {loadingHint}\n </Text>\n ) : null}\n </div>\n );\n }\n\n const titleInTopRow = variant === 'library';\n\n const eyebrowStyle = EYEBROWS[variant][selected ? 'selected' : 'resting'];\n const hasCornerCluster = Boolean(actions) || Boolean(onDismiss);\n const isDismissDisabled = dismissDisabledReason !== undefined;\n const eyebrowRowEnd =\n actions && onDismiss ? 'pr-[48px]' : hasCornerCluster ? 'pr-[18px]' : 'pr-1';\n\n return (\n <div\n ref={rootRef}\n data-variant={variant}\n data-pinned={pinned ? 'true' : 'false'}\n data-state={selected ? 'selected' : 'resting'}\n data-hoverable={hoverable ? '' : undefined}\n className={`${ROOT_CLASS} group relative grid shrink-0 grid-rows-[1fr_auto] ${FOCUS_RING_WITHIN} ${className}`.trim()}\n style={{\n width: CARD_WIDTH,\n height: CARD_HEIGHT,\n borderRadius: CARD_RADIUS,\n boxSizing: 'border-box',\n ...style,\n }}\n >\n {selected ? (\n <svg\n className={FLARE_CLASS}\n width={FLARE_BOX_WIDTH}\n height={FLARE_BOX_HEIGHT}\n viewBox={`0 0 ${FLARE_BOX_WIDTH} ${FLARE_BOX_HEIGHT}`}\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <defs>\n <linearGradient id={outlineGradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0\" style={{ stopColor: `var(${TINT_PROPERTY})` }} />\n <stop offset=\"1\" style={{ stopColor: SELECTED_SURFACE_END }} />\n </linearGradient>\n </defs>\n <path\n d={FILL_PATH}\n data-malachite-shape=\"\"\n style={{ fill: `url(#${outlineGradientId})` }}\n />\n <path\n d={OUTLINE_PATH}\n data-malachite-shape=\"\"\n strokeWidth={STROKE_PX}\n style={{ fill: 'none', stroke: `var(${OUTLINE_PROPERTY})` }}\n />\n </svg>\n ) : null}\n <button\n type=\"button\"\n role=\"radio\"\n data-value={value}\n aria-checked={selected}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n aria-describedby={describedBy}\n aria-disabled={disabled || undefined}\n tabIndex={tabIndex ?? (selected ? 0 : -1)}\n onClick={() => {\n if (disabled || selected) {\n return;\n }\n onSelect?.(value);\n }}\n className={`flex min-w-0 appearance-none flex-col border-0 bg-transparent py-0 pt-3 pr-4 pl-4 text-left outline-none ${\n disabled ? 'cursor-not-allowed' : 'cursor-pointer'\n }`}\n style={{ borderRadius: CARD_RADIUS }}\n >\n {/* Clears the corner buttons: 18px for one, 48px for `actions` and the x. */}\n <div className={`flex h-[13px] shrink-0 items-center gap-2 ${eyebrowRowEnd}`}>\n <div className=\"flex min-w-0 items-center gap-1.5\">\n {titleInTopRow ? (\n <span id={titleId} className=\"flex min-w-0 items-center gap-1.5\">\n {titleIcon ? (\n <span\n className=\"flex shrink-0 items-center\"\n style={TITLE_ICON_STYLE}\n >\n {titleIcon}\n </span>\n ) : null}\n {isDefault ? (\n <span className=\"flex shrink-0 items-center\">\n <DefaultMarker leading={!titleIcon} />\n </span>\n ) : null}\n <TruncatedTooltip text={title}>\n <Text\n size=\"small\"\n fontWeight=\"semi-bold\"\n style={dimmed ? { color: MUTED } : undefined}\n >\n {title}\n </Text>\n </TruncatedTooltip>\n </span>\n ) : null}\n {eyebrow ? (\n <span id={eyebrowId} className=\"flex min-w-0\">\n <Text size=\"xsmall\" fontWeight=\"semi-bold\" style={eyebrowStyle}>\n {eyebrow}\n </Text>\n </span>\n ) : null}\n {status ? (\n <span id={statusId} className=\"flex min-w-0\">\n <Tag\n value={status.label}\n type={status.type ?? 'default'}\n textTransform=\"none\"\n paddingSize=\"compact\"\n />\n </span>\n ) : null}\n </div>\n </div>\n\n <div\n className={`mt-[11px] flex min-w-0 flex-1 flex-col gap-1 pt-3 ${\n titleInTopRow ? 'justify-end' : 'justify-between'\n }`}\n >\n {titleInTopRow ? null : (\n <div id={titleId} className=\"flex min-w-0 items-center gap-1.5\">\n {titleIcon ? (\n <span\n className=\"flex shrink-0 items-center\"\n style={TITLE_ICON_STYLE}\n >\n {titleIcon}\n </span>\n ) : null}\n {isDefault ? (\n <span className=\"flex shrink-0 items-center\">\n <DefaultMarker leading={!titleIcon} />\n </span>\n ) : null}\n <TruncatedTooltip text={title}>\n <Text\n size=\"small\"\n fontWeight=\"semi-bold\"\n style={dimmed ? { color: MUTED } : undefined}\n >\n {title}\n </Text>\n </TruncatedTooltip>\n </div>\n )}\n {description ? (\n <span id={descriptionId} className=\"block min-w-0\">\n <Text size=\"xsmall\" style={DESCRIPTION_STYLE}>\n {description}\n </Text>\n </span>\n ) : null}\n </div>\n </button>\n\n <span id={countId} className=\"min-w-0 self-end truncate pr-4 pb-3 pl-4\">\n {countLabel ? (\n <Text size=\"xsmall\" fontWeight=\"semi-bold\" style={COUNT_STYLE}>\n {countLabel}\n </Text>\n ) : null}\n </span>\n\n {/* Lifted out of the flow rather than given a grid cell, so it can sit on the\n eyebrow row — which belongs to the control and cannot hold a second one. */}\n {hasCornerCluster ? (\n <div\n data-selectable-card-actions=\"\"\n className=\"absolute top-3 right-2 flex h-[13px] shrink-0 items-center gap-2.5\"\n >\n {actions ? (\n <span className=\"flex items-center gap-2.5\" style={ACTIONS_STYLE}>\n {actions}\n </span>\n ) : null}\n {onDismiss ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"xsmall\"\n iconOnly\n aria-label={dismissLabel}\n tooltip={dismissDisabledReason ?? dismissLabel}\n disabled={isDismissDisabled}\n className=\"shrink-0\"\n onClick={onDismiss}\n >\n <span\n className={DISMISS_ICON_BOX}\n style={isDismissDisabled ? DISABLED_DISMISS_STYLE : eyebrowStyle}\n >\n <DismissIcon />\n </span>\n </Button>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n};\n\nexport default SelectableCard;\nexport { SelectableCard };\n"],"names":["CARD_WIDTH_PX","CARD_WIDTH","CARD_HEIGHT","CARD_CORNER","CARD_RADIUS","MUTED","EYEBROW","PROFILE_ACCENT","PROFILE_TINT","PROFILE_SELECTED_BORDER","PROFILE_EYEBROW_OPACITY","LIBRARY_TINT","LIBRARY_SELECTED_BORDER","EDITING_ACCENT","EDITING_TINT","SELECTED_SURFACE_END","RESTING_SURFACE","RESTING_BORDER","HOVER_SURFACE_FILL","CARD_FLARE_PX","FLARE_PX","STROKE_PX","CARD_HEIGHT_PX","CORNER_PX","STRIP_RULE_PX","CARD_FLARE_TIP_PX","FLARE_BOX_WIDTH","FLARE_BOX_HEIGHT","pathTo","base","inset","left","right","top","OUTLINE_PATH","FILL_PATH","FLARE_CLASS","ROOT_CLASS","STYLE_ID","OUTLINE_PROPERTY","TINT_PROPERTY","HOVER_SURFACE","RESTING_SURFACE_DECLARATIONS","SURFACES","RESTING_EYEBROW","EYEBROWS","SCROLLED_SURFACE","OUTLINE_CSS","bodyOf","declarations","property","value","selectorFor","variant","state","ruleFor","SURFACE_CSS","SLOT_CSS","CARD_CSS","DESCRIPTION_STYLE","COUNT_STYLE","PENDING","LOADING_LABEL_STYLE","LOADING_HINT_STYLE","PENDING_BODY_TOP_PX","PENDING_BODY_BOTTOM_PX","TITLE_ICON_STYLE","ACTIONS_STYLE","DISMISS_ICON_BOX","DISABLED_DISMISS_STYLE","DEFAULT_MARKER_LABEL","DEFAULT_MARKER_SIZE_PX","DEFAULT_MARKER_STYLE","LEADING_DEFAULT_MARKER_STYLE","DefaultMarker","leading","jsx","Tooltip","PinIcon","joinIds","ids","present","id","SelectableCard","title","titleIcon","isDefault","eyebrow","status","description","countLabel","actions","onDismiss","dismissLabel","dismissDisabledReason","selected","loading","loadingLabel","loadingHint","disabled","dimmed","onSelect","tabIndex","ariaLabel","className","style","pinned","useCardStripSlot","hoverable","rootRef","useRef","useAdoptedStyleSheet","instanceId","useId","outlineGradientId","eyebrowId","statusId","titleId","descriptionId","countId","labelledBy","describedBy","jsxs","Text","titleInTopRow","eyebrowStyle","hasCornerCluster","isDismissDisabled","eyebrowRowEnd","FOCUS_RING_WITHIN","TruncatedTooltip","Tag","Button","DismissIcon"],"mappings":";;;;;;;;;;;;AAmEO,MAAMA,IAAgB,KACvBC,KAAa,GAAGD,CAAa,MAC7BE,KAAc,SACdC,KAAc,qCACdC,IAAc,GAAGD,EAAW,IAAIA,EAAW,QAE3CE,IAAQ,8DACRC,KAAU,4CAEVC,KAAiB,oDACjBC,KAAe,2DACfC,KAA0B,6DAC1BC,KAA0B,KAE1BC,KAAe,mEACfC,KAA0B,qEAE1BC,KAAiB,gEACjBC,KAAe,0DAEfC,KAAuB,kEAEvBC,KAAkB,wDAClBC,KAAiB,8DAEjBC,KAAqB,8DAIdC,KAAgB,IACvBC,IAAWD,IACXE,IAAY,GACZC,KAAiB,KACjBC,KAAY,IAGLC,KAAgB,GAIhBC,KAAoBL,IAAWC,IAAY,GAElDK,IAAkB1B,IAAgBoB,IAAW,GAC7CO,IAAmBL,KAAiBE,KAAgBH,GAGpDO,KAAS,CAACC,MAAyB;AACrC,QAAMC,IAAQT,IAAY,GACpBU,IAAOX,IAAWU,GAClBE,IAAQZ,IAAWpB,IAAgB8B,GACnCG,IAAMH,GACN,IAAIP,KAAYO;AACtB,SAAO;AAAA,IACH,IAAIC,IAAOX,CAAQ,IAAIS,CAAI;AAAA,IAC3B,IAAIT,CAAQ,IAAIA,CAAQ,UAAUW,CAAI,IAAIF,IAAOT,CAAQ;AAAA,IACzD,IAAIW,CAAI,IAAIE,IAAM,CAAC;AAAA,IACnB,IAAI,CAAC,IAAI,CAAC,UAAUF,IAAO,CAAC,IAAIE,CAAG;AAAA,IACnC,IAAID,IAAQ,CAAC,IAAIC,CAAG;AAAA,IACpB,IAAI,CAAC,IAAI,CAAC,UAAUD,CAAK,IAAIC,IAAM,CAAC;AAAA,IACpC,IAAID,CAAK,IAAIH,IAAOT,CAAQ;AAAA,IAC5B,IAAIA,CAAQ,IAAIA,CAAQ,UAAUY,IAAQZ,CAAQ,IAAIS,CAAI;AAAA,EAAA,EAC5D,KAAK,GAAG;AACd,GAEMK,IAAeN,GAAON,KAAiBE,KAAgB,CAAC,GAExDW,KAAY,GAAGD,CAAY,MAEpBE,IAAc,qCAErBC,IAAa,6BACbC,KAAW,mCAEXC,IAAmB,6CACnBC,IAAgB,0CAOhBC,IAA8B;AAAA,EAChC,oBAAoBvB;AAAA,EACpB,qBAAqB;AACzB,GAEMwB,IAA6C;AAAA,EAC/C,oBAAoB1B;AACxB,GAGM2B,IAA2E;AAAA,EAC7E,SAAS;AAAA,IACL,SAASD;AAAA,IACT,OAAOD;AAAA,IACP,UAAU;AAAA,MACN,CAACF,CAAgB,GAAG9B;AAAA,MACpB,CAAC+B,CAAa,GAAGhC;AAAA,IAAA;AAAA,EACrB;AAAA,EAEJ,SAAS;AAAA,IACL,SAASkC;AAAA,IACT,OAAOD;AAAA,IACP,UAAU;AAAA,MACN,CAACF,CAAgB,GAAG3B;AAAA,MACpB,CAAC4B,CAAa,GAAG7B;AAAA,IAAA;AAAA,EACrB;AAAA,EAEJ,SAAS;AAAA,IACL,SAAS+B;AAAA,IACT,OAAOD;AAAA,IACP,UAAU;AAAA,MACN,CAACF,CAAgB,GAAG1B;AAAA,MACpB,CAAC2B,CAAa,GAAG1B;AAAA,IAAA;AAAA,EACrB;AAER,GAEM8B,IAAuC,EAAE,OAAOtC,GAAA,GAEhDuC,KAAqF;AAAA,EACvF,SAAS;AAAA,IACL,SAASD;AAAA,IACT,UAAU,EAAE,OAAOrC,IAAgB,SAASG,GAAA;AAAA,EAAwB;AAAA,EAExE,SAAS,EAAE,SAASkC,GAAiB,UAAUA,EAAA;AAAA,EAC/C,SAAS;AAAA,IACL,SAASA;AAAA,IACT,UAAU,EAAE,OAAO/B,IAAgB,SAASH,GAAA;AAAA,EAAwB;AAE5E,GAEMoC,KAAiC,EAAE,eAAe7B,GAAA,GAElD8B,KAAc;AAAA,GACjBV,CAAU;AAAA;AAAA;AAAA,GAGVA,CAAU,OAAOD,CAAW;AAAA;AAAA,aAElBhB,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAMlBiB,CAAU,aAAaD,CAAW;AAAA;AAAA;AAAA;AAAA,GAIlCC,CAAU;AAAA;AAAA,IAIPW,KAAS,CAACC,MACZ,OAAO,QAAQA,CAAY,EACtB,IAAI,CAAC,CAACC,GAAUC,CAAK,MAAM,OAAOD,CAAQ,KAAKC,CAAK,GAAG,EACvD,KAAK;AAAA,CAAI,GAEZC,KAAc,CAACC,GAAgCC,MACjDA,MAAU,UACJ,IAAIjB,CAAU,kBAAkBgB,CAAO,mDACvC,IAAIhB,CAAU,kBAAkBgB,CAAO,kBAAkBC,CAAK,MAElEC,KAAU,CACZF,GACAC,GACAL,MACS,GAAGG,GAAYC,GAASC,CAAK,CAAC;AAAA,EAAON,GAAOC,CAAY,CAAC;AAAA,IAEhEO,KAAe,OAAO,KAAKb,CAAQ,EACpC;AAAA,EAAQ,CAACU,MACL,OAAO,KAAKV,EAASU,CAAO,CAAC,EAAkB;AAAA,IAAI,CAACC,MACjDC,GAAQF,GAASC,GAAOX,EAASU,CAAO,EAAEC,CAAK,CAAC;AAAA,EAAA;AAExD,EACC,KAAK;AAAA,CAAI,GAERG,KAAW,IAAIpB,CAAU;AAAA,EAAkDW;AAAA,EAC7EF;AACJ,CAAC;AAAA,IAEKY,KAAW,GAAGD,EAAQ;AAAA,EAAKD,EAAW;AAAA,EAAKT,EAAW,IAEtDY,KAAyC;AAAA,EAC3C,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,OAAOtD;AAAA,EACP,YAAY;AAChB,GAEMuD,KAAmC,EAAE,OAAOvD,GAAO,eAAe,SAAA,GAElEwD,IAAU,gEAEVC,KAA2C,EAAE,OAAOD,EAAA,GACpDE,KAA0C,EAAE,OAAOF,GAAS,SAAS,IAAA,GAErEG,KAAsB,IACtBC,KAAyB,IAIzBC,KAAwC;AAAA,EAC1C,OAAO;AAAA,EACP,YAAY;AAChB,GAGMC,KAAqC,EAAE,WAAW,mBAAA,GAElDC,KAAmB,gEACnBC,KAA8C,EAAE,OAAOhE,EAAA,GAEvDiE,KAAuB,mBACvBC,KAAyB,IAGzBC,KAA4C;AAAA,EAC9C,OAAOjE;AAAA,EACP,SAAS;AAAA,EACT,WAAW;AACf,GACMkE,KAAoD;AAAA,EACtD,GAAGD;AAAA,EACH,YAAY;AAChB,GAIME,KAAgD,CAAC,EAAE,SAAAC,EAAA,MACrD,gBAAAC,EAACC,IAAA,EAAQ,MAAMP,IAAsB,WAAU,QAAO,kBAAkB,IACpE,UAAA,gBAAAM;AAAA,EAAC;AAAA,EAAA;AAAA,IACG,MAAK;AAAA,IACL,cAAYN;AAAA,IACZ,OAAOK,IAAUF,KAA+BD;AAAA,IAEhD,UAAA,gBAAAI,EAACE,IAAA,EAAQ,MAAMP,GAAA,CAAwB;AAAA,EAAA;AAC3C,GACJ,GAGEQ,KAAU,CAACC,MAAuD;AACpE,QAAMC,IAAUD,EAAI,OAAO,CAACE,MAAqBA,MAAO,MAAS;AACjE,SAAOD,EAAQ,SAAS,IAAIA,EAAQ,KAAK,GAAG,IAAI;AACpD,GAGME,KAAgD,CAAC;AAAA,EACnD,OAAAhC;AAAA,EACA,OAAAiC;AAAA,EACA,WAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,SAAAjC,IAAU;AAAA,EACV,SAAAkC;AAAA,EACA,QAAAC;AAAA,EACA,aAAAC;AAAA,EACA,YAAAC;AAAA,EACA,SAAAC;AAAA,EACA,WAAAC;AAAA,EACA,cAAAC,IAAe;AAAA,EACf,uBAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,SAAAC,KAAU;AAAA,EACV,cAAAC,KAAe;AAAA,EACf,aAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,QAAAC,IAAS;AAAA,EACT,UAAAC;AAAA,EACA,UAAAC;AAAA,EACA,cAAcC;AAAA,EACd,WAAAC,IAAY;AAAA,EACZ,OAAAC;AACJ,MAAM;AACF,QAAM,EAAE,QAAAC,GAAA,IAAWC,GAAA,GACbC,KAAY,CAACb,KAAY,CAACI,GAE1BU,IAAUC,GAAuB,IAAI;AAC3C,EAAAC,GAAqBF,GAASnD,IAAUpB,EAAQ;AAEhD,QAAM0E,IAAa,uBAAuBC,GAAA,EAAQ,QAAQ,mBAAmB,EAAE,CAAC,IAC1EC,IAAoB,GAAGF,CAAU,YACjCG,IAAY,GAAGH,CAAU,YACzBI,IAAW,GAAGJ,CAAU,WACxBK,IAAU,GAAGL,CAAU,UACvBM,IAAgB,GAAGN,CAAU,gBAC7BO,IAAU,GAAGP,CAAU,UAEvBQ,KAAajB,IACb,SACAxB,GAAQ,CAACQ,IAAU4B,IAAY,QAAWE,GAAS7B,IAAS4B,IAAW,MAAS,CAAC,GACjFK,KAAc1C,GAAQ;AAAA,IACxBU,IAAc6B,IAAgB;AAAA,IAC9B5B,IAAa6B,IAAU;AAAA,EAAA,CAC1B;AAED,MAAIvB;AACA,WACI,gBAAA0B;AAAA,MAAC;AAAA,MAAA;AAAA,QACG,KAAKb;AAAA,QACL,MAAK;AAAA,QACL,aAAU;AAAA,QACV,aAAU;AAAA,QACV,gBAAa;AAAA,QACb,cAAW;AAAA,QACX,WAAW,GAAGxE,CAAU,wEAAwEmE,CAAS,GAAG,KAAA;AAAA,QAC5G,OACI;AAAA,UACI,OAAOvG;AAAA,UACP,QAAQC;AAAA,UACR,cAAcE;AAAA,UACd,WAAW;AAAA,UACX,YAAY,GAAG4D,EAAmB;AAAA,UAClC,eAAe,GAAGC,EAAsB;AAAA,UACxC,gBAAgB;AAAA,UAChB,CAAC1B,CAAgB,GAAGsB;AAAA,UACpB,CAACrB,CAAa,GAAG1B;AAAA,UACjB,GAAG2F;AAAA,QAAA;AAAA,QAMX,UAAA;AAAA,UAAA,gBAAAiB;AAAA,YAAC;AAAA,YAAA;AAAA,cACG,WAAWtF;AAAA,cACX,OAAOV;AAAA,cACP,QAAQC;AAAA,cACR,SAAS,OAAOD,CAAe,IAAIC,CAAgB;AAAA,cACnD,MAAK;AAAA,cACL,eAAY;AAAA,cAEZ,UAAA;AAAA,gBAAA,gBAAAiD,EAAC,QAAA,EACG,UAAA,gBAAA8C,EAAC,kBAAA,EAAe,IAAIR,GAAmB,IAAG,KAAI,IAAG,KAAI,IAAG,KAAI,IAAG,KAC3D,UAAA;AAAA,kBAAA,gBAAAtC,EAAC,QAAA,EAAK,QAAO,KAAI,OAAO,EAAE,WAAW,OAAOpC,CAAa,IAAA,EAAI,CAAG;AAAA,kBAChE,gBAAAoC,EAAC,UAAK,QAAO,KAAI,OAAO,EAAE,WAAW7D,KAAqB,CAAG;AAAA,gBAAA,EAAA,CACjE,EAAA,CACJ;AAAA,gBACA,gBAAA6D;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACG,GAAGzC;AAAA,oBACH,wBAAqB;AAAA,oBACrB,OAAO,EAAE,MAAM,QAAQ+E,CAAiB,IAAA;AAAA,kBAAI;AAAA,gBAAA;AAAA,gBAEhD,gBAAAtC;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACG,GAAG1C;AAAA,oBACH,wBAAqB;AAAA,oBACrB,aAAab;AAAA,oBACb,OAAO,EAAE,MAAM,QAAQ,QAAQ,OAAOkB,CAAgB,IAAA;AAAA,kBAAI;AAAA,gBAAA;AAAA,cAC9D;AAAA,YAAA;AAAA,UAAA;AAAA,UAEJ,gBAAAqC,EAAC+C,KAAK,MAAK,SAAQ,YAAW,aAAY,OAAO7D,IAC5C,UAAAmC,GAAA,CACL;AAAA,UACCC,IACG,gBAAAtB,EAAC+C,GAAA,EAAK,MAAK,UAAS,YAAW,aAAY,OAAO5D,IAC7C,UAAAmC,EAAA,CACL,IACA;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAKhB,QAAM0B,IAAgBvE,MAAY,WAE5BwE,IAAehF,GAASQ,CAAO,EAAE0C,IAAW,aAAa,SAAS,GAClE+B,IAAmB,EAAQnC,KAAY,EAAQC,GAC/CmC,IAAoBjC,MAA0B,QAC9CkC,KACFrC,KAAWC,IAAY,cAAckC,IAAmB,cAAc;AAE1E,SACI,gBAAAJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,KAAKb;AAAA,MACL,gBAAcxD;AAAA,MACd,eAAaqD,KAAS,SAAS;AAAA,MAC/B,cAAYX,IAAW,aAAa;AAAA,MACpC,kBAAgBa,KAAY,KAAK;AAAA,MACjC,WAAW,GAAGvE,CAAU,sDAAsD4F,EAAiB,IAAIzB,CAAS,GAAG,KAAA;AAAA,MAC/G,OAAO;AAAA,QACH,OAAOvG;AAAA,QACP,QAAQC;AAAA,QACR,cAAcE;AAAA,QACd,WAAW;AAAA,QACX,GAAGqG;AAAA,MAAA;AAAA,MAGN,UAAA;AAAA,QAAAV,IACG,gBAAA2B;AAAA,UAAC;AAAA,UAAA;AAAA,YACG,WAAWtF;AAAA,YACX,OAAOV;AAAA,YACP,QAAQC;AAAA,YACR,SAAS,OAAOD,CAAe,IAAIC,CAAgB;AAAA,YACnD,MAAK;AAAA,YACL,eAAY;AAAA,YAEZ,UAAA;AAAA,cAAA,gBAAAiD,EAAC,QAAA,EACG,UAAA,gBAAA8C,EAAC,kBAAA,EAAe,IAAIR,GAAmB,IAAG,KAAI,IAAG,KAAI,IAAG,KAAI,IAAG,KAC3D,UAAA;AAAA,gBAAA,gBAAAtC,EAAC,QAAA,EAAK,QAAO,KAAI,OAAO,EAAE,WAAW,OAAOpC,CAAa,IAAA,EAAI,CAAG;AAAA,gBAChE,gBAAAoC,EAAC,UAAK,QAAO,KAAI,OAAO,EAAE,WAAW7D,KAAqB,CAAG;AAAA,cAAA,EAAA,CACjE,EAAA,CACJ;AAAA,cACA,gBAAA6D;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACG,GAAGzC;AAAA,kBACH,wBAAqB;AAAA,kBACrB,OAAO,EAAE,MAAM,QAAQ+E,CAAiB,IAAA;AAAA,gBAAI;AAAA,cAAA;AAAA,cAEhD,gBAAAtC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACG,GAAG1C;AAAA,kBACH,wBAAqB;AAAA,kBACrB,aAAab;AAAA,kBACb,OAAO,EAAE,MAAM,QAAQ,QAAQ,OAAOkB,CAAgB,IAAA;AAAA,gBAAI;AAAA,cAAA;AAAA,YAC9D;AAAA,UAAA;AAAA,QAAA,IAEJ;AAAA,QACJ,gBAAAmF;AAAA,UAAC;AAAA,UAAA;AAAA,YACG,MAAK;AAAA,YACL,MAAK;AAAA,YACL,cAAYvE;AAAA,YACZ,gBAAc4C;AAAA,YACd,cAAYQ;AAAA,YACZ,mBAAiBiB;AAAA,YACjB,oBAAkBC;AAAA,YAClB,iBAAetB,KAAY;AAAA,YAC3B,UAAUG,OAAaP,IAAW,IAAI;AAAA,YACtC,SAAS,MAAM;AACX,cAAII,KAAYJ,KAGhBM,KAAA,QAAAA,EAAWlD;AAAA,YACf;AAAA,YACA,WAAW,4GACPgD,IAAW,uBAAuB,gBACtC;AAAA,YACA,OAAO,EAAE,cAAc/F,EAAA;AAAA,YAGvB,UAAA;AAAA,cAAA,gBAAAwE,EAAC,OAAA,EAAI,WAAW,6CAA6CoD,EAAa,IACtE,UAAA,gBAAAN,EAAC,OAAA,EAAI,WAAU,qCACV,UAAA;AAAA,gBAAAE,IACG,gBAAAF,EAAC,QAAA,EAAK,IAAIL,GAAS,WAAU,qCACxB,UAAA;AAAA,kBAAAhC,IACG,gBAAAT;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACG,WAAU;AAAA,sBACV,OAAOV;AAAA,sBAEN,UAAAmB;AAAA,oBAAA;AAAA,kBAAA,IAEL;AAAA,kBACHC,IACG,gBAAAV,EAAC,QAAA,EAAK,WAAU,8BACZ,UAAA,gBAAAA,EAACF,IAAA,EAAc,SAAS,CAACW,EAAA,CAAW,EAAA,CACxC,IACA;AAAA,kBACJ,gBAAAT,EAACsD,GAAA,EAAiB,MAAM9C,GACpB,UAAA,gBAAAR;AAAA,oBAAC+C;AAAA,oBAAA;AAAA,sBACG,MAAK;AAAA,sBACL,YAAW;AAAA,sBACX,OAAOvB,IAAS,EAAE,OAAO/F,MAAU;AAAA,sBAElC,UAAA+E;AAAA,oBAAA;AAAA,kBAAA,EACL,CACJ;AAAA,gBAAA,EAAA,CACJ,IACA;AAAA,gBACHG,IACG,gBAAAX,EAAC,QAAA,EAAK,IAAIuC,GAAW,WAAU,gBAC3B,UAAA,gBAAAvC,EAAC+C,GAAA,EAAK,MAAK,UAAS,YAAW,aAAY,OAAOE,GAC7C,UAAAtC,EAAA,CACL,GACJ,IACA;AAAA,gBACHC,IACG,gBAAAZ,EAAC,QAAA,EAAK,IAAIwC,GAAU,WAAU,gBAC1B,UAAA,gBAAAxC;AAAA,kBAACuD;AAAA,kBAAA;AAAA,oBACG,OAAO3C,EAAO;AAAA,oBACd,MAAMA,EAAO,QAAQ;AAAA,oBACrB,eAAc;AAAA,oBACd,aAAY;AAAA,kBAAA;AAAA,gBAAA,GAEpB,IACA;AAAA,cAAA,EAAA,CACR,EAAA,CACJ;AAAA,cAEA,gBAAAkC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACG,WAAW,qDACPE,IAAgB,gBAAgB,iBACpC;AAAA,kBAEC,UAAA;AAAA,oBAAAA,IAAgB,OACb,gBAAAF,EAAC,OAAA,EAAI,IAAIL,GAAS,WAAU,qCACvB,UAAA;AAAA,sBAAAhC,IACG,gBAAAT;AAAA,wBAAC;AAAA,wBAAA;AAAA,0BACG,WAAU;AAAA,0BACV,OAAOV;AAAA,0BAEN,UAAAmB;AAAA,wBAAA;AAAA,sBAAA,IAEL;AAAA,sBACHC,IACG,gBAAAV,EAAC,QAAA,EAAK,WAAU,8BACZ,UAAA,gBAAAA,EAACF,IAAA,EAAc,SAAS,CAACW,EAAA,CAAW,EAAA,CACxC,IACA;AAAA,sBACJ,gBAAAT,EAACsD,GAAA,EAAiB,MAAM9C,GACpB,UAAA,gBAAAR;AAAA,wBAAC+C;AAAA,wBAAA;AAAA,0BACG,MAAK;AAAA,0BACL,YAAW;AAAA,0BACX,OAAOvB,IAAS,EAAE,OAAO/F,MAAU;AAAA,0BAElC,UAAA+E;AAAA,wBAAA;AAAA,sBAAA,EACL,CACJ;AAAA,oBAAA,GACJ;AAAA,oBAEHK,IACG,gBAAAb,EAAC,QAAA,EAAK,IAAI0C,GAAe,WAAU,iBAC/B,UAAA,gBAAA1C,EAAC+C,GAAA,EAAK,MAAK,UAAS,OAAOhE,IACtB,UAAA8B,GACL,GACJ,IACA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YACR;AAAA,UAAA;AAAA,QAAA;AAAA,0BAGH,QAAA,EAAK,IAAI8B,GAAS,WAAU,4CACxB,UAAA7B,IACG,gBAAAd,EAAC+C,GAAA,EAAK,MAAK,UAAS,YAAW,aAAY,OAAO/D,IAC7C,UAAA8B,EAAA,CACL,IACA,MACR;AAAA,QAICoC,IACG,gBAAAJ;AAAA,UAAC;AAAA,UAAA;AAAA,YACG,gCAA6B;AAAA,YAC7B,WAAU;AAAA,YAET,UAAA;AAAA,cAAA/B,sBACI,QAAA,EAAK,WAAU,6BAA4B,OAAOxB,IAC9C,aACL,IACA;AAAA,cACHyB,IACG,gBAAAhB;AAAA,gBAACwD;AAAA,gBAAA;AAAA,kBACG,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACL,UAAQ;AAAA,kBACR,cAAYvC;AAAA,kBACZ,SAASC,KAAyBD;AAAA,kBAClC,UAAUkC;AAAA,kBACV,WAAU;AAAA,kBACV,SAASnC;AAAA,kBAET,UAAA,gBAAAhB;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACG,WAAWR;AAAA,sBACX,OAAO2D,IAAoB1D,KAAyBwD;AAAA,sBAEpD,4BAACQ,IAAA,CAAA,CAAY;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBACjB;AAAA,cAAA,IAEJ;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA,IAER;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGhB;"}
1
+ {"version":3,"file":"SelectableCard.js","sources":["../../src/components/SelectableCard.tsx"],"sourcesContent":["import React, { useId, useRef } from 'react';\nimport Button from './Button';\nimport DismissIcon from './CustomIcons/DismissIcon';\nimport ExternalLinkIcon from './CustomIcons/ExternalLinkIcon';\nimport PinIcon from './CustomIcons/PinIcon';\nimport Tag, { type TagType } from './Tag';\nimport Tooltip from './Tooltip';\nimport TruncatedTooltip from './TruncatedTooltip';\nimport Text from './Typography/Text';\nimport { useCardStripSlot } from './cardStripSlot';\nimport { FOCUS_RING, FOCUS_RING_WITHIN_RADIO } from './focusRing';\nimport { useAdoptedStyleSheet } from './useAdoptedStyleSheet';\n\nexport interface SelectableCardStatus {\n label: string;\n /** Maps to Tag's palette — `default` (grey) for \"Disabled\", `warning` (amber) for \"Draft\". */\n type?: TagType;\n}\n\nexport interface SelectableCardLink {\n label: string;\n href: string;\n}\n\n/** The card's palette: `profile` is green, `library` neutral, `editing` amber for a\n * profile with unsaved changes. */\nexport type SelectableCardVariant = 'profile' | 'library' | 'editing';\n\nexport interface SelectableCardProps {\n /** Identifies the card inside its group; handed back to `onSelect`. */\n value: string;\n title: string;\n /** Leading glyph on the title line, e.g. a library/book icon. */\n titleIcon?: React.ReactNode;\n /** Pins the card as the account default, marked beside the title. */\n isDefault?: boolean;\n /** Palette only — gradient, borders, indicator and eyebrow; position is settled by the strip. */\n variant?: SelectableCardVariant;\n /** Small label above the title (\"Profile\", \"Explore\"). */\n eyebrow?: string;\n /** Status pill rendered next to the eyebrow — or in its place when there is no eyebrow. */\n status?: SelectableCardStatus;\n /** Supporting copy under the title, clamped to two lines. */\n description?: string;\n /** Bottom-left summary (\"16 Actions\", \"10 Selected\"). */\n countLabel?: string;\n /** A link along the bottom edge, opened in a new tab. Rendered beside the radio rather than\n * inside it, so it stays its own tab stop. */\n link?: SelectableCardLink;\n /** Top-right cluster (markers, an ActionMenu…). The eyebrow row gives way to one\n * xsmall control; a wider cluster needs a shorter eyebrow and status to clear it. */\n actions?: React.ReactNode;\n /** Renders an x after `actions`, tinted like the eyebrow, that calls this. */\n onDismiss?: () => void;\n /** Names the x for assistive tech and its tooltip. */\n dismissLabel?: string;\n /** Disables the x and shows this as its tooltip instead. */\n dismissDisabledReason?: string;\n selected?: boolean;\n /** Replaces the card's content with a centred in-progress message. */\n loading?: boolean;\n loadingLabel?: string;\n loadingHint?: string;\n /** Blocks selection. Draws no dimming of its own — a switched-off profile is signalled by its `status` tag. */\n disabled?: boolean;\n /** Mutes the title without blocking selection. */\n dimmed?: boolean;\n onSelect?: (value: string) => void;\n /** Tab stop for the card. */\n tabIndex?: number;\n /** Replaces the generated accessible name (eyebrow + title + status). */\n 'aria-label'?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const CARD_WIDTH_PX = 240;\nconst CARD_WIDTH = `${CARD_WIDTH_PX}px`;\nconst CARD_HEIGHT = '116px';\nconst CARD_CORNER = 'var(--malachite-radius-xxl, 14px)';\nconst CARD_RADIUS = `${CARD_CORNER} ${CARD_CORNER} 0 0`;\n\nconst MUTED = 'var(--malachite-selectable-card-muted-foreground, #7b7b7b)';\nconst EYEBROW = 'var(--malachite-text-secondary, #7b7b7b)';\n\nconst PROFILE_ACCENT = 'var(--malachite-selectable-card-accent, #047b43)';\nconst PROFILE_TINT = 'var(--malachite-selectable-card-selected-tint, #e7f8f1)';\nconst PROFILE_SELECTED_BORDER = 'var(--malachite-selectable-card-selected-border, #047b43)';\nconst PROFILE_EYEBROW_OPACITY = 0.7;\n\nconst LIBRARY_TINT = 'var(--malachite-selectable-card-library-selected-tint, #f1f1f1)';\nconst LIBRARY_SELECTED_BORDER = 'var(--malachite-selectable-card-library-selected-border, #bbbbbb)';\n\nconst EDITING_ACCENT = 'var(--malachite-selectable-card-pending-foreground, #96580a)';\nconst EDITING_TINT = 'var(--malachite-selectable-card-editing-tint, #f9f2e9)';\n\nconst SELECTED_SURFACE_END = 'var(--malachite-selectable-card-selected-surface-end, #ffffff)';\n\nconst RESTING_SURFACE = 'var(--malachite-selectable-card-background, #f1f1f1)';\nconst RESTING_BORDER = '1px solid var(--malachite-selectable-card-border, #dddddd)';\n\nconst HOVER_SURFACE_FILL = 'var(--malachite-selectable-card-hover-background, #e8e8e8)';\n\n/** How far a selected card's outline sweeps past its own edge. The strip keeps this much\n * clear of its scroller's clip. */\nexport const CARD_FLARE_PX = 14;\nconst FLARE_PX = CARD_FLARE_PX;\nconst STROKE_PX = 2;\nconst CARD_HEIGHT_PX = 116;\nconst CORNER_PX = 14;\n\n/** Weight of the strip's bottom rule, which a selected card's flare reaches down through. */\nexport const STRIP_RULE_PX = 2;\n\n/** Where the strip's rule meets the flare. The stroke is centred on its path, so the tip\n * stops half a stroke inside the flare box. */\nexport const CARD_FLARE_TIP_PX = FLARE_PX - STROKE_PX / 2;\n\nconst FLARE_BOX_WIDTH = CARD_WIDTH_PX + FLARE_PX * 2;\nconst FLARE_BOX_HEIGHT = CARD_HEIGHT_PX + STRIP_RULE_PX + STROKE_PX;\n\n/** Stroke is centred on the path, so the card's own edges sit half a stroke inside the box. */\nconst pathTo = (base: number): string => {\n const inset = STROKE_PX / 2;\n const left = FLARE_PX + inset;\n const right = FLARE_PX + CARD_WIDTH_PX - inset;\n const top = inset;\n const r = CORNER_PX - inset;\n return [\n `M${left - FLARE_PX} ${base}`,\n `A${FLARE_PX} ${FLARE_PX} 0 0 0 ${left} ${base - FLARE_PX}`,\n `L${left} ${top + r}`,\n `A${r} ${r} 0 0 1 ${left + r} ${top}`,\n `L${right - r} ${top}`,\n `A${r} ${r} 0 0 1 ${right} ${top + r}`,\n `L${right} ${base - FLARE_PX}`,\n `A${FLARE_PX} ${FLARE_PX} 0 0 0 ${right + FLARE_PX} ${base}`,\n ].join(' ');\n};\n\nconst OUTLINE_PATH = pathTo(CARD_HEIGHT_PX + STRIP_RULE_PX / 2);\n\nconst FILL_PATH = `${OUTLINE_PATH} Z`;\n\nexport const FLARE_CLASS = 'malachite-selectable-card-outline';\n\nconst ROOT_CLASS = 'malachite-selectable-card';\nconst STYLE_ID = 'malachite-selectable-card-style';\n\nconst OUTLINE_PROPERTY = '--malachite-selectable-card-state-outline';\nconst TINT_PROPERTY = '--malachite-selectable-card-state-tint';\n\ntype CardState = 'resting' | 'hover' | 'selected';\ntype SettledState = Exclude<CardState, 'hover'>;\n\ntype Declarations = Record<string, string>;\n\nconst HOVER_SURFACE: Declarations = {\n 'background-color': HOVER_SURFACE_FILL,\n 'border-left-color': 'transparent',\n};\n\nconst RESTING_SURFACE_DECLARATIONS: Declarations = {\n 'background-color': RESTING_SURFACE,\n};\n\n/** Never inline styles: an inline declaration outranks the sheet, so `:hover` could never repaint the card. */\nconst SURFACES: Record<SelectableCardVariant, Record<CardState, Declarations>> = {\n profile: {\n resting: RESTING_SURFACE_DECLARATIONS,\n hover: HOVER_SURFACE,\n selected: {\n [OUTLINE_PROPERTY]: PROFILE_SELECTED_BORDER,\n [TINT_PROPERTY]: PROFILE_TINT,\n },\n },\n library: {\n resting: RESTING_SURFACE_DECLARATIONS,\n hover: HOVER_SURFACE,\n selected: {\n [OUTLINE_PROPERTY]: LIBRARY_SELECTED_BORDER,\n [TINT_PROPERTY]: LIBRARY_TINT,\n },\n },\n editing: {\n resting: RESTING_SURFACE_DECLARATIONS,\n hover: HOVER_SURFACE,\n selected: {\n [OUTLINE_PROPERTY]: EDITING_ACCENT,\n [TINT_PROPERTY]: EDITING_TINT,\n },\n },\n};\n\nconst RESTING_EYEBROW: React.CSSProperties = { color: EYEBROW };\n\nconst EYEBROWS: Record<SelectableCardVariant, Record<SettledState, React.CSSProperties>> = {\n profile: {\n resting: RESTING_EYEBROW,\n selected: { color: PROFILE_ACCENT, opacity: PROFILE_EYEBROW_OPACITY },\n },\n library: { resting: RESTING_EYEBROW, selected: RESTING_EYEBROW },\n editing: {\n resting: RESTING_EYEBROW,\n selected: { color: EDITING_ACCENT, opacity: PROFILE_EYEBROW_OPACITY },\n },\n};\n\nconst SCROLLED_SURFACE: Declarations = { 'border-left': RESTING_BORDER };\n\nconst OUTLINE_CSS = `\n.${ROOT_CLASS}[data-state='selected'] {\n z-index: 5;\n}\n.${ROOT_CLASS} > .${FLARE_CLASS} {\n position: absolute;\n left: -${FLARE_PX}px;\n top: 0;\n z-index: 0;\n overflow: visible;\n pointer-events: none;\n}\n.${ROOT_CLASS} > *:not(.${FLARE_CLASS}):not([data-selectable-card-actions]) {\n position: relative;\n z-index: 1;\n}\n.${ROOT_CLASS} > [data-selectable-card-actions] {\n z-index: 2;\n}`;\n\nconst bodyOf = (declarations: Declarations): string =>\n Object.entries(declarations)\n .map(([property, value]) => ` ${property}: ${value};`)\n .join('\\n');\n\nconst selectorFor = (variant: SelectableCardVariant, state: CardState): string =>\n state === 'hover'\n ? `.${ROOT_CLASS}[data-variant='${variant}'][data-state='resting'][data-hoverable]:hover`\n : `.${ROOT_CLASS}[data-variant='${variant}'][data-state='${state}']`;\n\nconst ruleFor = (\n variant: SelectableCardVariant,\n state: CardState,\n declarations: Declarations,\n): string => `${selectorFor(variant, state)} {\\n${bodyOf(declarations)}\\n}`;\n\nconst SURFACE_CSS = (Object.keys(SURFACES) as SelectableCardVariant[])\n .flatMap((variant) =>\n (Object.keys(SURFACES[variant]) as CardState[]).map((state) =>\n ruleFor(variant, state, SURFACES[variant][state]),\n ),\n )\n .join('\\n');\n\nconst SLOT_CSS = `.${ROOT_CLASS}[data-pinned='false'][data-state='resting'] {\\n${bodyOf(\n SCROLLED_SURFACE,\n)}\\n}`;\n\nconst CARD_CSS = `${SLOT_CSS}\\n${SURFACE_CSS}\\n${OUTLINE_CSS}`;\n\nconst DESCRIPTION_STYLE: React.CSSProperties = {\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n color: MUTED,\n lineHeight: 1.6,\n};\n\nconst COUNT_STYLE: React.CSSProperties = { color: MUTED, letterSpacing: '0.11px' };\n\nconst LINK_CLASS = `rounded-xs text-[length:var(--malachite-font-size-xsmall,11px)] text-[var(--malachite-text-muted,rgb(76,75,75))] no-underline transition-colors hover:text-[var(--malachite-text-primary)] ${FOCUS_RING}`;\nconst LINK_STYLE: React.CSSProperties = { lineHeight: 1.6 };\nconst LINK_ICON_STYLE: React.CSSProperties = { marginLeft: 2, verticalAlign: '-1px' };\nconst LINK_ICON_SIZE_PX = 12;\n\nconst PENDING = 'var(--malachite-selectable-card-pending-foreground, #96580a)';\n\nconst LOADING_LABEL_STYLE: React.CSSProperties = { color: PENDING };\nconst LOADING_HINT_STYLE: React.CSSProperties = { color: PENDING, opacity: 0.7 };\n\nconst PENDING_BODY_TOP_PX = 36;\nconst PENDING_BODY_BOTTOM_PX = 38;\n\n// The 16px library icon's glyph inset, so it lines up with the text below.\nconst TITLE_ICON_INSET_PX = 2.25;\nconst TITLE_ICON_STYLE: React.CSSProperties = {\n color: 'var(--malachite-text-primary)',\n marginLeft: -TITLE_ICON_INSET_PX,\n};\n\n// Offsets the outline button's 1px drop shadow so it centres on the eyebrow.\nconst ACTIONS_STYLE: React.CSSProperties = { transform: 'translateY(-1px)' };\n\nconst DISMISS_ICON_BOX = 'inline-flex items-center justify-center [&_svg]:size-[10px]!';\nconst DISABLED_DISMISS_STYLE: React.CSSProperties = { color: MUTED };\n\nconst DEFAULT_MARKER_LABEL = 'Default profile';\nconst DEFAULT_MARKER_SIZE_PX = 16;\n// The tilted pin's glyph inset.\nconst DEFAULT_MARKER_INSET_PX = 3;\nconst DEFAULT_MARKER_STYLE: React.CSSProperties = {\n color: PROFILE_ACCENT,\n display: 'inline-flex',\n transform: 'rotate(45deg)',\n};\nconst LEADING_DEFAULT_MARKER_STYLE: React.CSSProperties = {\n ...DEFAULT_MARKER_STYLE,\n marginLeft: -DEFAULT_MARKER_INSET_PX,\n};\n\n/** Announced rather than shown alone: a bare glyph reads as an unnamed graphic, and the tooltip\n * travels by `aria-describedby`, which describes rather than names. */\nconst DefaultMarker: React.FC<{ leading: boolean }> = ({ leading }) => (\n <Tooltip text={DEFAULT_MARKER_LABEL} triggerAs=\"span\" describesTrigger={false}>\n <span\n role=\"img\"\n aria-label={DEFAULT_MARKER_LABEL}\n style={leading ? LEADING_DEFAULT_MARKER_STYLE : DEFAULT_MARKER_STYLE}\n >\n <PinIcon size={DEFAULT_MARKER_SIZE_PX} />\n </span>\n </Tooltip>\n);\n\nconst joinIds = (ids: Array<string | undefined>): string | undefined => {\n const present = ids.filter((id): id is string => id !== undefined);\n return present.length > 0 ? present.join(' ') : undefined;\n};\n\n/** A fixed-size card that behaves as one option in a radio group: a card-shaped `Surface.Row`. */\nconst SelectableCard: React.FC<SelectableCardProps> = ({\n value,\n title,\n titleIcon,\n isDefault = false,\n variant = 'profile',\n eyebrow,\n status,\n description,\n countLabel,\n link,\n actions,\n onDismiss,\n dismissLabel = 'Dismiss',\n dismissDisabledReason,\n selected = false,\n loading = false,\n loadingLabel = 'Loading…',\n loadingHint,\n disabled = false,\n dimmed = false,\n onSelect,\n tabIndex,\n 'aria-label': ariaLabel,\n className = '',\n style,\n}) => {\n const { pinned } = useCardStripSlot();\n const hoverable = !selected && !disabled;\n\n const rootRef = useRef<HTMLDivElement>(null);\n useAdoptedStyleSheet(rootRef, CARD_CSS, STYLE_ID);\n\n const instanceId = `mal-selectable-card-${useId().replace(/[^a-zA-Z0-9_-]/g, '')}`;\n const outlineGradientId = `${instanceId}-outline`;\n const eyebrowId = `${instanceId}-eyebrow`;\n const statusId = `${instanceId}-status`;\n const titleId = `${instanceId}-title`;\n const descriptionId = `${instanceId}-description`;\n const countId = `${instanceId}-count`;\n\n const labelledBy = ariaLabel\n ? undefined\n : joinIds([eyebrow ? eyebrowId : undefined, titleId, status ? statusId : undefined]);\n const describedBy = joinIds([\n description ? descriptionId : undefined,\n countLabel ? countId : undefined,\n ]);\n\n if (loading) {\n return (\n <div\n ref={rootRef}\n role=\"status\"\n aria-busy=\"true\"\n aria-live=\"polite\"\n data-variant=\"editing\"\n data-state=\"selected\"\n className={`${ROOT_CLASS} relative flex shrink-0 flex-col items-center gap-2 px-5 text-center ${className}`.trim()}\n style={\n {\n width: CARD_WIDTH,\n height: CARD_HEIGHT,\n borderRadius: CARD_RADIUS,\n boxSizing: 'border-box',\n paddingTop: `${PENDING_BODY_TOP_PX}px`,\n paddingBottom: `${PENDING_BODY_BOTTOM_PX}px`,\n justifyContent: 'center',\n [OUTLINE_PROPERTY]: PENDING,\n [TINT_PROPERTY]: EDITING_TINT,\n ...style,\n } as React.CSSProperties\n }\n >\n {/* The same outline a selected card wears: this IS the selection while a profile\n is being built, so it has to break the strip's rule rather than sit on it. */}\n <svg\n className={FLARE_CLASS}\n width={FLARE_BOX_WIDTH}\n height={FLARE_BOX_HEIGHT}\n viewBox={`0 0 ${FLARE_BOX_WIDTH} ${FLARE_BOX_HEIGHT}`}\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <defs>\n <linearGradient id={outlineGradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0\" style={{ stopColor: `var(${TINT_PROPERTY})` }} />\n <stop offset=\"1\" style={{ stopColor: SELECTED_SURFACE_END }} />\n </linearGradient>\n </defs>\n <path\n d={FILL_PATH}\n data-malachite-shape=\"\"\n style={{ fill: `url(#${outlineGradientId})` }}\n />\n <path\n d={OUTLINE_PATH}\n data-malachite-shape=\"\"\n strokeWidth={STROKE_PX}\n style={{ fill: 'none', stroke: `var(${OUTLINE_PROPERTY})` }}\n />\n </svg>\n <Text size=\"small\" fontWeight=\"semi-bold\" style={LOADING_LABEL_STYLE}>\n {loadingLabel}\n </Text>\n {loadingHint ? (\n <Text size=\"xsmall\" fontWeight=\"semi-bold\" style={LOADING_HINT_STYLE}>\n {loadingHint}\n </Text>\n ) : null}\n </div>\n );\n }\n\n const titleInTopRow = variant === 'library';\n\n const eyebrowStyle = EYEBROWS[variant][selected ? 'selected' : 'resting'];\n const hasCornerCluster = Boolean(actions) || Boolean(onDismiss);\n const isDismissDisabled = dismissDisabledReason !== undefined;\n const eyebrowRowEnd =\n actions && onDismiss ? 'pr-[48px]' : hasCornerCluster ? 'pr-[18px]' : 'pr-1';\n\n return (\n <div\n ref={rootRef}\n data-variant={variant}\n data-pinned={pinned ? 'true' : 'false'}\n data-state={selected ? 'selected' : 'resting'}\n data-hoverable={hoverable ? '' : undefined}\n className={`${ROOT_CLASS} group relative grid shrink-0 grid-rows-[1fr_auto] ${FOCUS_RING_WITHIN_RADIO} ${className}`.trim()}\n style={{\n width: CARD_WIDTH,\n height: CARD_HEIGHT,\n borderRadius: CARD_RADIUS,\n boxSizing: 'border-box',\n ...style,\n }}\n >\n {selected ? (\n <svg\n className={FLARE_CLASS}\n width={FLARE_BOX_WIDTH}\n height={FLARE_BOX_HEIGHT}\n viewBox={`0 0 ${FLARE_BOX_WIDTH} ${FLARE_BOX_HEIGHT}`}\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <defs>\n <linearGradient id={outlineGradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0\" style={{ stopColor: `var(${TINT_PROPERTY})` }} />\n <stop offset=\"1\" style={{ stopColor: SELECTED_SURFACE_END }} />\n </linearGradient>\n </defs>\n <path\n d={FILL_PATH}\n data-malachite-shape=\"\"\n style={{ fill: `url(#${outlineGradientId})` }}\n />\n <path\n d={OUTLINE_PATH}\n data-malachite-shape=\"\"\n strokeWidth={STROKE_PX}\n style={{ fill: 'none', stroke: `var(${OUTLINE_PROPERTY})` }}\n />\n </svg>\n ) : null}\n <button\n type=\"button\"\n role=\"radio\"\n data-value={value}\n aria-checked={selected}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n aria-describedby={describedBy}\n aria-disabled={disabled || undefined}\n tabIndex={tabIndex ?? (selected ? 0 : -1)}\n onClick={() => {\n if (disabled || selected) {\n return;\n }\n onSelect?.(value);\n }}\n className={`flex min-w-0 appearance-none flex-col border-0 bg-transparent py-0 pt-3 pr-4 pl-4 text-left outline-none ${\n disabled ? 'cursor-not-allowed' : 'cursor-pointer'\n }`}\n style={{ borderRadius: CARD_RADIUS }}\n >\n {/* Clears the corner buttons: 18px for one, 48px for `actions` and the x. */}\n <div className={`flex h-[13px] shrink-0 items-center gap-2 ${eyebrowRowEnd}`}>\n <div className=\"flex min-w-0 items-center gap-1.5\">\n {titleInTopRow ? (\n <span id={titleId} className=\"flex min-w-0 items-center gap-1.5\">\n {titleIcon ? (\n <span\n className=\"flex shrink-0 items-center\"\n style={TITLE_ICON_STYLE}\n >\n {titleIcon}\n </span>\n ) : null}\n {isDefault ? (\n <span className=\"flex shrink-0 items-center\">\n <DefaultMarker leading={!titleIcon} />\n </span>\n ) : null}\n <TruncatedTooltip text={title}>\n <Text\n size=\"small\"\n fontWeight=\"semi-bold\"\n style={dimmed ? { color: MUTED } : undefined}\n >\n {title}\n </Text>\n </TruncatedTooltip>\n </span>\n ) : null}\n {eyebrow ? (\n <span id={eyebrowId} className=\"flex min-w-0\">\n <Text size=\"xsmall\" fontWeight=\"semi-bold\" style={eyebrowStyle}>\n {eyebrow}\n </Text>\n </span>\n ) : null}\n {status ? (\n <span id={statusId} className=\"flex min-w-0\">\n <Tag\n value={status.label}\n type={status.type ?? 'default'}\n textTransform=\"none\"\n paddingSize=\"compact\"\n />\n </span>\n ) : null}\n </div>\n </div>\n\n <div\n className={`mt-[11px] flex min-w-0 flex-1 flex-col gap-1 pt-3 ${\n titleInTopRow ? 'justify-end' : 'justify-between'\n }`}\n >\n {titleInTopRow ? null : (\n <div id={titleId} className=\"flex min-w-0 items-center gap-1.5\">\n {titleIcon ? (\n <span\n className=\"flex shrink-0 items-center\"\n style={TITLE_ICON_STYLE}\n >\n {titleIcon}\n </span>\n ) : null}\n {isDefault ? (\n <span className=\"flex shrink-0 items-center\">\n <DefaultMarker leading={!titleIcon} />\n </span>\n ) : null}\n <TruncatedTooltip text={title}>\n <Text\n size=\"small\"\n fontWeight=\"semi-bold\"\n style={dimmed ? { color: MUTED } : undefined}\n >\n {title}\n </Text>\n </TruncatedTooltip>\n </div>\n )}\n {description ? (\n <span id={descriptionId} className=\"block min-w-0\">\n <Text size=\"xsmall\" style={DESCRIPTION_STYLE}>\n {description}\n </Text>\n </span>\n ) : null}\n </div>\n </button>\n\n <div className=\"flex min-w-0 flex-col gap-1 self-end pr-4 pb-3 pl-4\">\n {link ? (\n <span className=\"min-w-0\" style={LINK_STYLE}>\n <a\n href={link.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={LINK_CLASS}\n data-selectable-card-link=\"\"\n >\n {link.label}\n <span aria-hidden=\"true\">\n <ExternalLinkIcon\n size={LINK_ICON_SIZE_PX}\n style={LINK_ICON_STYLE}\n />\n </span>{' '}\n <span className=\"sr-only\">(opens in a new tab)</span>\n </a>\n </span>\n ) : null}\n {countLabel ? (\n <span id={countId} className=\"min-w-0 truncate\">\n <Text size=\"xsmall\" fontWeight=\"semi-bold\" style={COUNT_STYLE}>\n {countLabel}\n </Text>\n </span>\n ) : null}\n </div>\n\n {/* Lifted out of the flow rather than given a grid cell, so it can sit on the\n eyebrow row — which belongs to the control and cannot hold a second one. */}\n {hasCornerCluster ? (\n <div\n data-selectable-card-actions=\"\"\n className=\"absolute top-3 right-2 flex h-[13px] shrink-0 items-center gap-2.5\"\n >\n {actions ? (\n <span className=\"flex items-center gap-2.5\" style={ACTIONS_STYLE}>\n {actions}\n </span>\n ) : null}\n {onDismiss ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"xsmall\"\n iconOnly\n aria-label={dismissLabel}\n tooltip={dismissDisabledReason ?? dismissLabel}\n disabled={isDismissDisabled}\n className=\"shrink-0\"\n onClick={onDismiss}\n >\n <span\n className={DISMISS_ICON_BOX}\n style={isDismissDisabled ? DISABLED_DISMISS_STYLE : eyebrowStyle}\n >\n <DismissIcon />\n </span>\n </Button>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n};\n\nexport default SelectableCard;\nexport { SelectableCard };\n"],"names":["CARD_WIDTH_PX","CARD_WIDTH","CARD_HEIGHT","CARD_CORNER","CARD_RADIUS","MUTED","EYEBROW","PROFILE_ACCENT","PROFILE_TINT","PROFILE_SELECTED_BORDER","PROFILE_EYEBROW_OPACITY","LIBRARY_TINT","LIBRARY_SELECTED_BORDER","EDITING_ACCENT","EDITING_TINT","SELECTED_SURFACE_END","RESTING_SURFACE","RESTING_BORDER","HOVER_SURFACE_FILL","CARD_FLARE_PX","FLARE_PX","STROKE_PX","CARD_HEIGHT_PX","CORNER_PX","STRIP_RULE_PX","CARD_FLARE_TIP_PX","FLARE_BOX_WIDTH","FLARE_BOX_HEIGHT","pathTo","base","inset","left","right","top","r","OUTLINE_PATH","FILL_PATH","FLARE_CLASS","ROOT_CLASS","STYLE_ID","OUTLINE_PROPERTY","TINT_PROPERTY","HOVER_SURFACE","RESTING_SURFACE_DECLARATIONS","SURFACES","RESTING_EYEBROW","EYEBROWS","SCROLLED_SURFACE","OUTLINE_CSS","bodyOf","declarations","property","value","selectorFor","variant","state","ruleFor","SURFACE_CSS","SLOT_CSS","CARD_CSS","DESCRIPTION_STYLE","COUNT_STYLE","LINK_CLASS","FOCUS_RING","LINK_STYLE","LINK_ICON_STYLE","LINK_ICON_SIZE_PX","PENDING","LOADING_LABEL_STYLE","LOADING_HINT_STYLE","PENDING_BODY_TOP_PX","PENDING_BODY_BOTTOM_PX","TITLE_ICON_STYLE","ACTIONS_STYLE","DISMISS_ICON_BOX","DISABLED_DISMISS_STYLE","DEFAULT_MARKER_LABEL","DEFAULT_MARKER_SIZE_PX","DEFAULT_MARKER_STYLE","LEADING_DEFAULT_MARKER_STYLE","DefaultMarker","leading","jsx","Tooltip","PinIcon","joinIds","ids","present","id","SelectableCard","title","titleIcon","isDefault","eyebrow","status","description","countLabel","link","actions","onDismiss","dismissLabel","dismissDisabledReason","selected","loading","loadingLabel","loadingHint","disabled","dimmed","onSelect","tabIndex","ariaLabel","className","style","pinned","useCardStripSlot","hoverable","rootRef","useRef","useAdoptedStyleSheet","instanceId","useId","outlineGradientId","eyebrowId","statusId","titleId","descriptionId","countId","labelledBy","describedBy","jsxs","Text","titleInTopRow","eyebrowStyle","hasCornerCluster","isDismissDisabled","eyebrowRowEnd","FOCUS_RING_WITHIN_RADIO","TruncatedTooltip","Tag","ExternalLinkIcon","Button","DismissIcon"],"mappings":"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"}
@@ -1,77 +1,84 @@
1
- import { jsx as c, jsxs as j, Fragment as Z } from "react/jsx-runtime";
2
- import L, { useState as p, useRef as h, useCallback as ee, useId as te, useEffect as R, useInsertionEffect as ne } from "react";
3
- import { createPortal as re } from "react-dom";
4
- import { ensureOverlayStyles as oe, overlayIdentity as ie } from "./portalOverlay.js";
5
- import { useTopLayer as ae } from "./topLayer.js";
6
- const se = new RegExp("(?<=[/\\\\.\\-_?&#=:@])"), le = (n) => n.split(se).map((a, g) => /* @__PURE__ */ j(L.Fragment, { children: [
7
- a,
8
- /* @__PURE__ */ c("wbr", {})
9
- ] }, g)), ce = {
1
+ import { jsx as f, jsxs as N, Fragment as te } from "react/jsx-runtime";
2
+ import S, { useState as v, useRef as c, useCallback as ne, useId as re, useEffect as w, useInsertionEffect as oe } from "react";
3
+ import { createPortal as ie } from "react-dom";
4
+ import { ensureOverlayStyles as ae, overlayIdentity as se } from "./portalOverlay.js";
5
+ import { useTopLayer as le } from "./topLayer.js";
6
+ const ce = new RegExp("(?<=[/\\\\.\\-_?&#=:@])"), fe = (n) => n.split(ce).map((s, y) => /* @__PURE__ */ N(S.Fragment, { children: [
7
+ s,
8
+ /* @__PURE__ */ f("wbr", {})
9
+ ] }, y)), ue = {
10
10
  minWidth: 0,
11
11
  overflow: "hidden"
12
- }, V = {
12
+ }, k = {
13
13
  flex: 1,
14
14
  minWidth: 0
15
- }, H = 8, ge = ({
15
+ }, z = 8, we = ({
16
16
  text: n,
17
- children: a,
18
- delay: g = 1,
19
- wrapChildren: k = !1,
20
- triggerAs: z = "div",
21
- inline: S = !1,
22
- placement: N = "top",
23
- isShrinkable: T = !1,
24
- maxWidth: v = "320px",
25
- fill: w = !1,
26
- shouldShow: d,
17
+ children: s,
18
+ delay: y = 1,
19
+ wrapChildren: Y = !1,
20
+ triggerAs: O = "div",
21
+ inline: T = !1,
22
+ placement: U = "top",
23
+ isShrinkable: I = !1,
24
+ maxWidth: b = "320px",
25
+ fill: x = !1,
26
+ shouldShow: u,
27
27
  suppressed: o = !1,
28
- describesTrigger: F = !0
28
+ describesTrigger: A = !0,
29
+ showOnFocus: d = !0
29
30
  }) => {
30
- const O = T || w ? { ...T ? ce : {}, ...w ? V : {} } : void 0, [t, f] = p(!1), [u, Y] = p(!1), m = h(null), i = h(null), r = ee(() => {
31
- m.current && (clearTimeout(m.current), m.current = null), i.current !== null && (cancelAnimationFrame(i.current), i.current = null);
32
- }, []), I = () => {
33
- Y(!0), i.current !== null && cancelAnimationFrame(i.current), i.current = requestAnimationFrame(() => {
34
- i.current = null, f(!0);
31
+ const q = I || x ? { ...I ? ue : {}, ...x ? k : {} } : void 0, [t, m] = v(!1), [p, G] = v(!1), h = c(null), a = c(null), r = ne(() => {
32
+ h.current && (clearTimeout(h.current), h.current = null), a.current !== null && (cancelAnimationFrame(a.current), a.current = null);
33
+ }, []), B = () => {
34
+ G(!0), a.current !== null && cancelAnimationFrame(a.current), a.current = requestAnimationFrame(() => {
35
+ a.current = null, m(!0);
35
36
  });
36
- }, y = h(null), b = h(null);
37
- ae(y, t);
38
- const A = te(), s = n != null && n !== "" && n !== !1, U = (e) => {
39
- e.stopPropagation(), !(!s || o || d && !d()) && (r(), m.current = setTimeout(() => {
40
- I();
41
- }, g * 1e3));
42
- }, q = (e) => {
43
- e.stopPropagation(), r(), f(!1);
44
- }, G = () => {
45
- !s || o || d && !d() || (r(), I());
46
- }, K = () => {
47
- r(), f(!1);
48
- }, [X, D] = p(o);
49
- o !== X && (D(o), o && f(!1)), R(() => {
37
+ }, E = c(null), g = c(null);
38
+ le(E, t);
39
+ const F = re(), l = n != null && n !== "" && n !== !1, K = (e) => {
40
+ e.stopPropagation(), !(!l || o || u && !u()) && (r(), h.current = setTimeout(() => {
41
+ B();
42
+ }, y * 1e3));
43
+ }, X = (e) => {
44
+ e.stopPropagation(), r(), m(!1);
45
+ }, W = () => {
46
+ !d || !l || o || u && !u() || (r(), B());
47
+ }, D = () => {
48
+ r(), m(!1);
49
+ }, M = c(d);
50
+ w(() => {
51
+ var i;
52
+ const e = d && !M.current;
53
+ M.current = d, e && ((i = g.current) != null && i.matches(":focus-within")) && W();
54
+ });
55
+ const [J, Q] = v(o);
56
+ o !== J && (Q(o), o && m(!1)), w(() => {
50
57
  o && r();
51
58
  }, [o, r]);
52
- const [, B] = p({});
53
- R(() => {
59
+ const [, _] = v({});
60
+ w(() => {
54
61
  if (!t)
55
62
  return () => {
56
63
  r();
57
64
  };
58
65
  const e = () => {
59
- B({});
66
+ _({});
60
67
  };
61
68
  return window.addEventListener("scroll", e, !0), window.addEventListener("resize", e), () => {
62
69
  r(), window.removeEventListener("scroll", e, !0), window.removeEventListener("resize", e);
63
70
  };
64
- }, [t, r]), R(() => {
65
- t && B({});
71
+ }, [t, r]), w(() => {
72
+ t && _({});
66
73
  }, [t]);
67
- const J = () => {
68
- if (!b.current)
74
+ const Z = () => {
75
+ if (!g.current)
69
76
  return { display: "none" };
70
- const e = b.current.getBoundingClientRect(), l = {
77
+ const e = g.current.getBoundingClientRect(), i = {
71
78
  position: "fixed",
72
79
  display: "flex",
73
80
  width: "max-content",
74
- maxWidth: typeof v == "number" ? `${v}px` : v,
81
+ maxWidth: typeof b == "number" ? `${b}px` : b,
75
82
  minWidth: "32px",
76
83
  minHeight: "32px",
77
84
  padding: "8px 12px",
@@ -89,90 +96,90 @@ const se = new RegExp("(?<=[/\\\\.\\-_?&#=:@])"), le = (n) => n.split(se).map((a
89
96
  opacity: t ? 1 : 0,
90
97
  visibility: t ? "visible" : "hidden",
91
98
  transition: "opacity 150ms ease-in-out, transform 150ms ease-in-out, visibility 150ms ease-in-out"
92
- }, x = () => {
93
- var C;
94
- const E = e.left + e.width / 2, M = ((C = y.current) == null ? void 0 : C.getBoundingClientRect().width) ?? 0;
95
- if (M === 0)
96
- return E;
97
- const _ = M / 2, $ = H + _, P = window.innerWidth - H - _;
98
- return $ > P ? E : Math.min(Math.max(E, $), P);
99
+ }, R = () => {
100
+ var j;
101
+ const L = e.left + e.width / 2, P = ((j = E.current) == null ? void 0 : j.getBoundingClientRect().width) ?? 0;
102
+ if (P === 0)
103
+ return L;
104
+ const C = P / 2, V = z + C, H = window.innerWidth - z - C;
105
+ return V > H ? L : Math.min(Math.max(L, V), H);
99
106
  };
100
- switch (N) {
107
+ switch (U) {
101
108
  case "top":
102
109
  return {
103
- ...l,
110
+ ...i,
104
111
  top: e.top - 8,
105
- left: x(),
112
+ left: R(),
106
113
  transform: `translate(-50%, -100%) ${t ? "scale(1)" : "scale(0.95)"}`
107
114
  };
108
115
  case "bottom":
109
116
  return {
110
- ...l,
117
+ ...i,
111
118
  top: e.bottom + 8,
112
- left: x(),
119
+ left: R(),
113
120
  transform: `translateX(-50%) ${t ? "scale(1)" : "scale(0.95)"}`
114
121
  };
115
122
  case "left":
116
123
  return {
117
- ...l,
124
+ ...i,
118
125
  top: e.top + e.height / 2,
119
126
  left: e.left - 8,
120
127
  transform: `translate(-100%, -50%) ${t ? "scale(1)" : "scale(0.95)"}`
121
128
  };
122
129
  case "right":
123
130
  return {
124
- ...l,
131
+ ...i,
125
132
  top: e.top + e.height / 2,
126
133
  left: e.right + 8,
127
134
  transform: `translateY(-50%) ${t ? "scale(1)" : "scale(0.95)"}`
128
135
  };
129
136
  default:
130
137
  return {
131
- ...l,
138
+ ...i,
132
139
  top: e.top - 8,
133
- left: x(),
140
+ left: R(),
134
141
  transform: `translate(-50%, -100%) ${t ? "scale(1)" : "scale(0.95)"}`
135
142
  };
136
143
  }
137
- }, W = s && u && F ? A : void 0;
138
- ne(() => {
139
- s && u && oe();
140
- }, [s, u]);
141
- const Q = k || !L.isValidElement(a) ? /* @__PURE__ */ c("span", { "aria-describedby": W, style: w ? V : void 0, children: a }) : L.cloneElement(a, {
142
- "aria-describedby": [a.props["aria-describedby"], W].filter(Boolean).join(" ") || void 0
144
+ }, $ = l && p && A ? F : void 0;
145
+ oe(() => {
146
+ l && p && ae();
147
+ }, [l, p]);
148
+ const ee = Y || !S.isValidElement(s) ? /* @__PURE__ */ f("span", { "aria-describedby": $, style: x ? k : void 0, children: s }) : S.cloneElement(s, {
149
+ "aria-describedby": [s.props["aria-describedby"], $].filter(Boolean).join(" ") || void 0
143
150
  });
144
- return /* @__PURE__ */ j(Z, { children: [
145
- /* @__PURE__ */ c(
146
- S ? "span" : z,
151
+ return /* @__PURE__ */ N(te, { children: [
152
+ /* @__PURE__ */ f(
153
+ T ? "span" : O,
147
154
  {
148
- ref: b,
149
- className: `relative ${S ? "inline-flex max-w-full align-middle" : "flex"} items-center`,
150
- style: O,
151
- onMouseEnter: U,
152
- onMouseLeave: q,
153
- onFocus: G,
154
- onBlur: K,
155
- children: Q
155
+ ref: g,
156
+ className: `relative ${T ? "inline-flex max-w-full align-middle" : "flex"} items-center`,
157
+ style: q,
158
+ onMouseEnter: K,
159
+ onMouseLeave: X,
160
+ onFocus: W,
161
+ onBlur: D,
162
+ children: ee
156
163
  }
157
164
  ),
158
- s && u && re(
159
- /* @__PURE__ */ c(
165
+ l && p && ie(
166
+ /* @__PURE__ */ f(
160
167
  "div",
161
168
  {
162
- ref: y,
163
- id: A,
169
+ ref: E,
170
+ id: F,
164
171
  role: "tooltip",
165
- "aria-hidden": F ? void 0 : !0,
166
- ...ie("tooltip"),
167
- style: J(),
168
- children: /* @__PURE__ */ c(
172
+ "aria-hidden": A ? void 0 : !0,
173
+ ...se("tooltip"),
174
+ style: Z(),
175
+ children: /* @__PURE__ */ f(
169
176
  "span",
170
177
  {
171
178
  style: {
172
179
  minWidth: 0,
173
180
  overflowWrap: "anywhere"
174
181
  },
175
- children: typeof n == "string" ? le(n) : n
182
+ children: typeof n == "string" ? fe(n) : n
176
183
  }
177
184
  )
178
185
  }
@@ -182,6 +189,6 @@ const se = new RegExp("(?<=[/\\\\.\\-_?&#=:@])"), le = (n) => n.split(se).map((a
182
189
  ] });
183
190
  };
184
191
  export {
185
- ge as default
192
+ we as default
186
193
  };
187
194
  //# sourceMappingURL=Tooltip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.js","sources":["../../src/components/Tooltip.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId, useInsertionEffect, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ensureOverlayStyles, overlayIdentity } from './portalOverlay';\nimport { useTopLayer } from './topLayer';\n\n// Split after each delimiter so long values (URLs, dotted paths) wrap at \"/\" or \".\"\n// instead of mid-token. <wbr> is copy-safe (a zero-width space would corrupt a copied\n// URL); overflow-wrap still handles a single run too long to fit.\nconst WRAP_AFTER = /(?<=[/\\\\.\\-_?&#=:@])/;\nconst withBreakOpportunities = (value: string): React.ReactNode =>\n value.split(WRAP_AFTER).map((chunk, i) => (\n <React.Fragment key={i}>\n {chunk}\n <wbr />\n </React.Fragment>\n ));\n\ninterface TooltipProps {\n text: React.ReactNode | string;\n children: React.ReactNode;\n delay?: number;\n wrapChildren?: boolean;\n placement?: 'top' | 'bottom' | 'left' | 'right';\n isShrinkable?: boolean;\n fill?: boolean;\n /** Max width of tooltip. Default: 320px */\n maxWidth?: number | string;\n /** Called synchronously when the trigger is hovered/focused; return false to\n * suppress the tooltip for this interaction. Lets wrappers defer expensive\n * checks (e.g. truncation measurement) to interaction time instead of mount. */\n shouldShow?: () => boolean;\n suppressed?: boolean;\n triggerAs?: 'div' | 'span';\n inline?: boolean;\n /** Whether the tooltip acts as the trigger's accessible description. False where the\n * trigger already points at the same sentence on screen, so it is not announced twice. */\n describesTrigger?: boolean;\n}\n\nconst SHRINKABLE_STYLE: React.CSSProperties = {\n minWidth: 0,\n overflow: 'hidden',\n};\n\nconst FILL_STYLE: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n};\n\n/** Kept clear of the viewport edge so a clamped tooltip does not sit flush against it. */\nconst VIEWPORT_MARGIN = 8;\n\nconst Tooltip: React.FC<TooltipProps> = ({\n text,\n children,\n delay = 1,\n wrapChildren = false,\n triggerAs = 'div',\n inline = false,\n placement = 'top',\n isShrinkable = false,\n maxWidth = '320px',\n fill = false,\n shouldShow,\n suppressed = false,\n describesTrigger = true,\n}) => {\n const triggerStyle =\n isShrinkable || fill\n ? { ...(isShrinkable ? SHRINKABLE_STYLE : {}), ...(fill ? FILL_STYLE : {}) }\n : undefined;\n\n const [isVisible, setIsVisible] = useState(false);\n // Portal mounts on first show, not on mount: an at-rest tooltip otherwise\n // costs a hidden document.body node plus a getBoundingClientRect per render —\n // multiplied by every row in a large table.\n const [hasShown, setHasShown] = useState(false);\n const timeoutRef = useRef<NodeJS.Timeout | null>(null);\n const showFrameRef = useRef<number | null>(null);\n\n const cancelPendingShow = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n if (showFrameRef.current !== null) {\n cancelAnimationFrame(showFrameRef.current);\n showFrameRef.current = null;\n }\n }, []);\n\n const scheduleVisible = () => {\n // Two steps so the portal mounts hidden first and the fade-in transition\n // still runs on the very first show. The frame is tracked so leave/blur/\n // unmount can cancel a show that is already past its delay.\n setHasShown(true);\n if (showFrameRef.current !== null) {\n cancelAnimationFrame(showFrameRef.current);\n }\n showFrameRef.current = requestAnimationFrame(() => {\n showFrameRef.current = null;\n setIsVisible(true);\n });\n };\n const tooltipRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n\n // Tied to visibility, not mount: the node is latched into the DOM after its first show, and\n // re-entering on each show keeps a tooltip above the panel it is annotating.\n useTopLayer(tooltipRef, isVisible);\n\n const tooltipId = useId();\n\n const hasText = text !== null && text !== undefined && text !== '' && text !== false;\n\n const handleMouseEnter = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n if (!hasText || suppressed || (shouldShow && !shouldShow())) {\n return;\n }\n\n cancelPendingShow();\n\n timeoutRef.current = setTimeout(() => {\n scheduleVisible();\n }, delay * 1000);\n };\n\n const handleMouseLeave = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n cancelPendingShow();\n setIsVisible(false);\n };\n\n const handleFocus = () => {\n if (!hasText || suppressed || (shouldShow && !shouldShow())) {\n return;\n }\n\n cancelPendingShow();\n scheduleVisible();\n };\n\n const handleBlur = () => {\n cancelPendingShow();\n setIsVisible(false);\n };\n\n const [wasSuppressed, setWasSuppressed] = useState(suppressed);\n if (suppressed !== wasSuppressed) {\n setWasSuppressed(suppressed);\n if (suppressed) {\n setIsVisible(false);\n }\n }\n\n useEffect(() => {\n if (suppressed) {\n cancelPendingShow();\n }\n }, [suppressed, cancelPendingShow]);\n\n const [, forceUpdate] = useState({});\n\n useEffect(() => {\n // Only a VISIBLE tooltip needs to track scroll/resize; keeping global\n // listeners per mounted instance made every scroll event fan out across\n // every tooltip on the page.\n if (!isVisible) {\n return () => {\n cancelPendingShow();\n };\n }\n const handleUpdate = () => {\n forceUpdate({});\n };\n\n window.addEventListener('scroll', handleUpdate, true);\n window.addEventListener('resize', handleUpdate);\n\n return () => {\n cancelPendingShow();\n window.removeEventListener('scroll', handleUpdate, true);\n window.removeEventListener('resize', handleUpdate);\n };\n }, [isVisible, cancelPendingShow]);\n\n // The first render that mounts the tooltip has no measured width yet, so the clamp below\n // cannot run on it. One extra pass once it is in the DOM gives the clamp its measurement\n // — before the opacity transition finishes, so nothing is seen sliding into place.\n useEffect(() => {\n if (isVisible) {\n forceUpdate({});\n }\n }, [isVisible]);\n\n const getTooltipStyles = (): React.CSSProperties => {\n if (!triggerRef.current) {\n return { display: 'none' };\n }\n\n const rect = triggerRef.current.getBoundingClientRect();\n\n const baseStyles: React.CSSProperties = {\n position: 'fixed',\n display: 'flex',\n width: 'max-content',\n maxWidth: typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth,\n minWidth: '32px',\n minHeight: '32px',\n padding: '8px 12px',\n alignItems: 'center',\n gap: '8px',\n borderRadius: '12px',\n backgroundColor: 'var(--malachite-tooltip-background, rgb(59, 59, 59))',\n color: 'var(--malachite-tooltip-foreground, rgb(255, 255, 255))',\n boxShadow: 'var(--malachite-tooltip-shadow, 0px 0px 10px 0px rgba(0, 0, 0, 0.20))',\n fontSize: '14px',\n lineHeight: '1.4',\n whiteSpace: 'normal',\n textAlign: 'left',\n pointerEvents: 'none',\n opacity: isVisible ? 1 : 0,\n visibility: isVisible ? 'visible' : 'hidden',\n transition:\n 'opacity 150ms ease-in-out, transform 150ms ease-in-out, visibility 150ms ease-in-out',\n };\n\n // A trigger near the viewport edge would otherwise centre a wide tooltip half off\n // screen, where the panel or the window crops it. Clamping the CENTRE keeps the\n // `translateX(-50%)` placement honest: the box stays put, it just stops short.\n const centeredLeft = (): number => {\n const desired = rect.left + rect.width / 2;\n const width = tooltipRef.current?.getBoundingClientRect().width ?? 0;\n\n if (width === 0) {\n return desired;\n }\n\n const half = width / 2;\n const min = VIEWPORT_MARGIN + half;\n const max = window.innerWidth - VIEWPORT_MARGIN - half;\n\n // A tooltip wider than the viewport has no in-bounds centre; leave it centred\n // rather than pinning it to a nonsensical one.\n return min > max ? desired : Math.min(Math.max(desired, min), max);\n };\n\n switch (placement) {\n case 'top':\n return {\n ...baseStyles,\n top: rect.top - 8,\n left: centeredLeft(),\n transform: `translate(-50%, -100%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'bottom':\n return {\n ...baseStyles,\n top: rect.bottom + 8,\n left: centeredLeft(),\n transform: `translateX(-50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'left':\n return {\n ...baseStyles,\n top: rect.top + rect.height / 2,\n left: rect.left - 8,\n transform: `translate(-100%, -50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'right':\n return {\n ...baseStyles,\n top: rect.top + rect.height / 2,\n left: rect.right + 8,\n transform: `translateY(-50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n default:\n return {\n ...baseStyles,\n top: rect.top - 8,\n left: centeredLeft(),\n transform: `translate(-50%, -100%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n }\n };\n\n // Only reference the tooltip id once the portal can exist — a dangling\n // aria-describedby (text set, never shown) confuses assistive tech.\n const describedBy = hasText && hasShown && describesTrigger ? tooltipId : undefined;\n useInsertionEffect(() => {\n if (hasText && hasShown) {\n ensureOverlayStyles();\n }\n }, [hasText, hasShown]);\n const renderedChildren =\n wrapChildren || !React.isValidElement(children) ? (\n <span aria-describedby={describedBy} style={fill ? FILL_STYLE : undefined}>\n {children}\n </span>\n ) : (\n React.cloneElement(children as React.ReactElement, {\n 'aria-describedby':\n [(children as React.ReactElement).props['aria-describedby'], describedBy]\n .filter(Boolean)\n .join(' ') || undefined,\n })\n );\n\n const Trigger = inline ? 'span' : triggerAs;\n\n // Create the tooltip content without its own shadow root\n return (\n <>\n <Trigger\n ref={triggerRef}\n className={`relative ${inline ? 'inline-flex max-w-full align-middle' : 'flex'} items-center`}\n style={triggerStyle}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n {renderedChildren}\n </Trigger>\n\n {hasText &&\n hasShown &&\n createPortal(\n <div\n ref={tooltipRef}\n id={tooltipId}\n role=\"tooltip\"\n // Nothing references it, and the sentence is already on screen and\n // described: left in the tree it is a second copy to read past.\n aria-hidden={describesTrigger ? undefined : true}\n {...overlayIdentity('tooltip')}\n style={getTooltipStyles()}\n >\n {/* min-w-0 + overflow-wrap let long values wrap within maxWidth. */}\n <span\n style={{\n minWidth: 0,\n overflowWrap: 'anywhere',\n }}\n >\n {typeof text === 'string' ? withBreakOpportunities(text) : text}\n </span>\n </div>,\n document.body,\n )}\n </>\n );\n};\n\nexport default Tooltip;\n"],"names":["WRAP_AFTER","withBreakOpportunities","value","chunk","i","jsxs","React","SHRINKABLE_STYLE","FILL_STYLE","VIEWPORT_MARGIN","Tooltip","text","children","delay","wrapChildren","triggerAs","inline","placement","isShrinkable","maxWidth","fill","shouldShow","suppressed","describesTrigger","triggerStyle","isVisible","setIsVisible","useState","hasShown","setHasShown","timeoutRef","useRef","showFrameRef","cancelPendingShow","useCallback","scheduleVisible","tooltipRef","triggerRef","useTopLayer","tooltipId","useId","hasText","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","wasSuppressed","setWasSuppressed","useEffect","forceUpdate","handleUpdate","getTooltipStyles","rect","baseStyles","centeredLeft","desired","width","_a","half","min","max","describedBy","useInsertionEffect","ensureOverlayStyles","renderedChildren","jsx","Fragment","createPortal","overlayIdentity"],"mappings":"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"}
1
+ {"version":3,"file":"Tooltip.js","sources":["../../src/components/Tooltip.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId, useInsertionEffect, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ensureOverlayStyles, overlayIdentity } from './portalOverlay';\nimport { useTopLayer } from './topLayer';\n\n// Split after each delimiter so long values (URLs, dotted paths) wrap at \"/\" or \".\"\n// instead of mid-token. <wbr> is copy-safe (a zero-width space would corrupt a copied\n// URL); overflow-wrap still handles a single run too long to fit.\nconst WRAP_AFTER = /(?<=[/\\\\.\\-_?&#=:@])/;\nconst withBreakOpportunities = (value: string): React.ReactNode =>\n value.split(WRAP_AFTER).map((chunk, i) => (\n <React.Fragment key={i}>\n {chunk}\n <wbr />\n </React.Fragment>\n ));\n\ninterface TooltipProps {\n text: React.ReactNode | string;\n children: React.ReactNode;\n delay?: number;\n wrapChildren?: boolean;\n placement?: 'top' | 'bottom' | 'left' | 'right';\n isShrinkable?: boolean;\n fill?: boolean;\n /** Max width of tooltip. Default: 320px */\n maxWidth?: number | string;\n /** Called synchronously when the trigger is hovered/focused; return false to\n * suppress the tooltip for this interaction. Lets wrappers defer expensive\n * checks (e.g. truncation measurement) to interaction time instead of mount. */\n shouldShow?: () => boolean;\n suppressed?: boolean;\n triggerAs?: 'div' | 'span';\n inline?: boolean;\n /** Whether the tooltip acts as the trigger's accessible description. False where the\n * trigger already points at the same sentence on screen, so it is not announced twice. */\n describesTrigger?: boolean;\n /** False to open on hover only, e.g. where script moves focus onto the trigger. */\n showOnFocus?: boolean;\n}\n\nconst SHRINKABLE_STYLE: React.CSSProperties = {\n minWidth: 0,\n overflow: 'hidden',\n};\n\nconst FILL_STYLE: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n};\n\n/** Kept clear of the viewport edge so a clamped tooltip does not sit flush against it. */\nconst VIEWPORT_MARGIN = 8;\n\nconst Tooltip: React.FC<TooltipProps> = ({\n text,\n children,\n delay = 1,\n wrapChildren = false,\n triggerAs = 'div',\n inline = false,\n placement = 'top',\n isShrinkable = false,\n maxWidth = '320px',\n fill = false,\n shouldShow,\n suppressed = false,\n describesTrigger = true,\n showOnFocus = true,\n}) => {\n const triggerStyle =\n isShrinkable || fill\n ? { ...(isShrinkable ? SHRINKABLE_STYLE : {}), ...(fill ? FILL_STYLE : {}) }\n : undefined;\n\n const [isVisible, setIsVisible] = useState(false);\n // Portal mounts on first show, not on mount: an at-rest tooltip otherwise\n // costs a hidden document.body node plus a getBoundingClientRect per render —\n // multiplied by every row in a large table.\n const [hasShown, setHasShown] = useState(false);\n const timeoutRef = useRef<NodeJS.Timeout | null>(null);\n const showFrameRef = useRef<number | null>(null);\n\n const cancelPendingShow = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n if (showFrameRef.current !== null) {\n cancelAnimationFrame(showFrameRef.current);\n showFrameRef.current = null;\n }\n }, []);\n\n const scheduleVisible = () => {\n // Two steps so the portal mounts hidden first and the fade-in transition\n // still runs on the very first show. The frame is tracked so leave/blur/\n // unmount can cancel a show that is already past its delay.\n setHasShown(true);\n if (showFrameRef.current !== null) {\n cancelAnimationFrame(showFrameRef.current);\n }\n showFrameRef.current = requestAnimationFrame(() => {\n showFrameRef.current = null;\n setIsVisible(true);\n });\n };\n const tooltipRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n\n // Tied to visibility, not mount: the node is latched into the DOM after its first show, and\n // re-entering on each show keeps a tooltip above the panel it is annotating.\n useTopLayer(tooltipRef, isVisible);\n\n const tooltipId = useId();\n\n const hasText = text !== null && text !== undefined && text !== '' && text !== false;\n\n const handleMouseEnter = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n if (!hasText || suppressed || (shouldShow && !shouldShow())) {\n return;\n }\n\n cancelPendingShow();\n\n timeoutRef.current = setTimeout(() => {\n scheduleVisible();\n }, delay * 1000);\n };\n\n const handleMouseLeave = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n cancelPendingShow();\n setIsVisible(false);\n };\n\n const handleFocus = () => {\n if (!showOnFocus || !hasText || suppressed || (shouldShow && !shouldShow())) {\n return;\n }\n\n cancelPendingShow();\n scheduleVisible();\n };\n\n const handleBlur = () => {\n cancelPendingShow();\n setIsVisible(false);\n };\n\n // Turning on while the trigger already holds focus fires no focus event to open on.\n const showOnFocusRef = useRef(showOnFocus);\n useEffect(() => {\n const switchedOn = showOnFocus && !showOnFocusRef.current;\n showOnFocusRef.current = showOnFocus;\n if (switchedOn && triggerRef.current?.matches(':focus-within')) {\n handleFocus();\n }\n });\n\n const [wasSuppressed, setWasSuppressed] = useState(suppressed);\n if (suppressed !== wasSuppressed) {\n setWasSuppressed(suppressed);\n if (suppressed) {\n setIsVisible(false);\n }\n }\n\n useEffect(() => {\n if (suppressed) {\n cancelPendingShow();\n }\n }, [suppressed, cancelPendingShow]);\n\n const [, forceUpdate] = useState({});\n\n useEffect(() => {\n // Only a VISIBLE tooltip needs to track scroll/resize; keeping global\n // listeners per mounted instance made every scroll event fan out across\n // every tooltip on the page.\n if (!isVisible) {\n return () => {\n cancelPendingShow();\n };\n }\n const handleUpdate = () => {\n forceUpdate({});\n };\n\n window.addEventListener('scroll', handleUpdate, true);\n window.addEventListener('resize', handleUpdate);\n\n return () => {\n cancelPendingShow();\n window.removeEventListener('scroll', handleUpdate, true);\n window.removeEventListener('resize', handleUpdate);\n };\n }, [isVisible, cancelPendingShow]);\n\n // The first render that mounts the tooltip has no measured width yet, so the clamp below\n // cannot run on it. One extra pass once it is in the DOM gives the clamp its measurement\n // — before the opacity transition finishes, so nothing is seen sliding into place.\n useEffect(() => {\n if (isVisible) {\n forceUpdate({});\n }\n }, [isVisible]);\n\n const getTooltipStyles = (): React.CSSProperties => {\n if (!triggerRef.current) {\n return { display: 'none' };\n }\n\n const rect = triggerRef.current.getBoundingClientRect();\n\n const baseStyles: React.CSSProperties = {\n position: 'fixed',\n display: 'flex',\n width: 'max-content',\n maxWidth: typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth,\n minWidth: '32px',\n minHeight: '32px',\n padding: '8px 12px',\n alignItems: 'center',\n gap: '8px',\n borderRadius: '12px',\n backgroundColor: 'var(--malachite-tooltip-background, rgb(59, 59, 59))',\n color: 'var(--malachite-tooltip-foreground, rgb(255, 255, 255))',\n boxShadow: 'var(--malachite-tooltip-shadow, 0px 0px 10px 0px rgba(0, 0, 0, 0.20))',\n fontSize: '14px',\n lineHeight: '1.4',\n whiteSpace: 'normal',\n textAlign: 'left',\n pointerEvents: 'none',\n opacity: isVisible ? 1 : 0,\n visibility: isVisible ? 'visible' : 'hidden',\n transition:\n 'opacity 150ms ease-in-out, transform 150ms ease-in-out, visibility 150ms ease-in-out',\n };\n\n // A trigger near the viewport edge would otherwise centre a wide tooltip half off\n // screen, where the panel or the window crops it. Clamping the CENTRE keeps the\n // `translateX(-50%)` placement honest: the box stays put, it just stops short.\n const centeredLeft = (): number => {\n const desired = rect.left + rect.width / 2;\n const width = tooltipRef.current?.getBoundingClientRect().width ?? 0;\n\n if (width === 0) {\n return desired;\n }\n\n const half = width / 2;\n const min = VIEWPORT_MARGIN + half;\n const max = window.innerWidth - VIEWPORT_MARGIN - half;\n\n // A tooltip wider than the viewport has no in-bounds centre; leave it centred\n // rather than pinning it to a nonsensical one.\n return min > max ? desired : Math.min(Math.max(desired, min), max);\n };\n\n switch (placement) {\n case 'top':\n return {\n ...baseStyles,\n top: rect.top - 8,\n left: centeredLeft(),\n transform: `translate(-50%, -100%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'bottom':\n return {\n ...baseStyles,\n top: rect.bottom + 8,\n left: centeredLeft(),\n transform: `translateX(-50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'left':\n return {\n ...baseStyles,\n top: rect.top + rect.height / 2,\n left: rect.left - 8,\n transform: `translate(-100%, -50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'right':\n return {\n ...baseStyles,\n top: rect.top + rect.height / 2,\n left: rect.right + 8,\n transform: `translateY(-50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n default:\n return {\n ...baseStyles,\n top: rect.top - 8,\n left: centeredLeft(),\n transform: `translate(-50%, -100%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n }\n };\n\n // Only reference the tooltip id once the portal can exist — a dangling\n // aria-describedby (text set, never shown) confuses assistive tech.\n const describedBy = hasText && hasShown && describesTrigger ? tooltipId : undefined;\n useInsertionEffect(() => {\n if (hasText && hasShown) {\n ensureOverlayStyles();\n }\n }, [hasText, hasShown]);\n const renderedChildren =\n wrapChildren || !React.isValidElement(children) ? (\n <span aria-describedby={describedBy} style={fill ? FILL_STYLE : undefined}>\n {children}\n </span>\n ) : (\n React.cloneElement(children as React.ReactElement, {\n 'aria-describedby':\n [(children as React.ReactElement).props['aria-describedby'], describedBy]\n .filter(Boolean)\n .join(' ') || undefined,\n })\n );\n\n const Trigger = inline ? 'span' : triggerAs;\n\n // Create the tooltip content without its own shadow root\n return (\n <>\n <Trigger\n ref={triggerRef}\n className={`relative ${inline ? 'inline-flex max-w-full align-middle' : 'flex'} items-center`}\n style={triggerStyle}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n {renderedChildren}\n </Trigger>\n\n {hasText &&\n hasShown &&\n createPortal(\n <div\n ref={tooltipRef}\n id={tooltipId}\n role=\"tooltip\"\n // Nothing references it, and the sentence is already on screen and\n // described: left in the tree it is a second copy to read past.\n aria-hidden={describesTrigger ? undefined : true}\n {...overlayIdentity('tooltip')}\n style={getTooltipStyles()}\n >\n {/* min-w-0 + overflow-wrap let long values wrap within maxWidth. */}\n <span\n style={{\n minWidth: 0,\n overflowWrap: 'anywhere',\n }}\n >\n {typeof text === 'string' ? withBreakOpportunities(text) : text}\n </span>\n </div>,\n document.body,\n )}\n </>\n );\n};\n\nexport default Tooltip;\n"],"names":["WRAP_AFTER","withBreakOpportunities","value","chunk","i","jsxs","React","SHRINKABLE_STYLE","FILL_STYLE","VIEWPORT_MARGIN","Tooltip","text","children","delay","wrapChildren","triggerAs","inline","placement","isShrinkable","maxWidth","fill","shouldShow","suppressed","describesTrigger","showOnFocus","triggerStyle","isVisible","setIsVisible","useState","hasShown","setHasShown","timeoutRef","useRef","showFrameRef","cancelPendingShow","useCallback","scheduleVisible","tooltipRef","triggerRef","useTopLayer","tooltipId","useId","hasText","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","showOnFocusRef","useEffect","switchedOn","_a","wasSuppressed","setWasSuppressed","forceUpdate","handleUpdate","getTooltipStyles","rect","baseStyles","centeredLeft","desired","width","half","min","max","describedBy","useInsertionEffect","ensureOverlayStyles","renderedChildren","jsx","Fragment","createPortal","overlayIdentity"],"mappings":"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"}
@@ -1,10 +1,11 @@
1
- const o = "outline-none focus-visible:outline-offset-2 focus-visible:[outline:2px_solid_var(--malachite-text-primary)]", e = "outline-none focus-visible:[outline:2px_solid_var(--malachite-text-primary)] focus-visible:[outline-offset:-2px]", i = "pointer-events-none absolute inset-0 z-[2] hidden group-focus-visible:block [outline:2px_solid_var(--malachite-text-primary)] [outline-offset:-2px]", t = "outline-none has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:[outline:2px_solid_var(--malachite-text-primary)]", s = "outline-none focus-visible:outline-offset-2 focus-visible:[outline:2px_solid_var(--malachite-selection-bar-foreground)]", n = "outline-none focus-visible:[outline:2px_solid_var(--malachite-inline-confirm-foreground)] focus-visible:[outline-offset:-2px]";
1
+ const i = "outline-none focus-visible:outline-offset-2 focus-visible:[outline:2px_solid_var(--malachite-text-primary)]", o = "outline-none focus-visible:[outline:2px_solid_var(--malachite-text-primary)] focus-visible:[outline-offset:-2px]", e = "pointer-events-none absolute inset-0 z-[2] hidden group-focus-visible:block [outline:2px_solid_var(--malachite-text-primary)] [outline-offset:-2px]", t = "outline-none has-[input:focus-visible]:outline-offset-2 has-[input:focus-visible]:[outline:2px_solid_var(--malachite-text-primary)]", s = "outline-none has-[[role=radio]:focus-visible]:outline-offset-2 has-[[role=radio]:focus-visible]:[outline:2px_solid_var(--malachite-text-primary)]", l = "outline-none focus-visible:outline-offset-2 focus-visible:[outline:2px_solid_var(--malachite-selection-bar-foreground)]", n = "outline-none focus-visible:[outline:2px_solid_var(--malachite-inline-confirm-foreground)] focus-visible:[outline-offset:-2px]";
2
2
  export {
3
- o as FOCUS_RING,
3
+ i as FOCUS_RING,
4
4
  n as FOCUS_RING_INLINE_CONFIRM_INSET,
5
- e as FOCUS_RING_INSET,
6
- i as FOCUS_RING_INSET_OVERLAY,
7
- s as FOCUS_RING_SELECTION_BAR,
8
- t as FOCUS_RING_WITHIN
5
+ o as FOCUS_RING_INSET,
6
+ e as FOCUS_RING_INSET_OVERLAY,
7
+ l as FOCUS_RING_SELECTION_BAR,
8
+ t as FOCUS_RING_WITHIN_INPUT,
9
+ s as FOCUS_RING_WITHIN_RADIO
9
10
  };
10
11
  //# sourceMappingURL=focusRing.js.map