@mortenbrudvik/waveui 0.12.0 → 0.14.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.
- package/README.md +362 -60
- package/dist/components/data-display/Avatar.cjs +1 -1
- package/dist/components/data-display/Avatar.cjs.map +1 -1
- package/dist/components/data-display/Avatar.colors.cjs +2 -0
- package/dist/components/data-display/Avatar.colors.cjs.map +1 -0
- package/dist/components/data-display/Avatar.colors.mjs +45 -0
- package/dist/components/data-display/Avatar.colors.mjs.map +1 -0
- package/dist/components/data-display/Avatar.context.cjs +1 -1
- package/dist/components/data-display/Avatar.context.cjs.map +1 -1
- package/dist/components/data-display/Avatar.context.mjs +4 -2
- package/dist/components/data-display/Avatar.context.mjs.map +1 -1
- package/dist/components/data-display/Avatar.mjs +103 -96
- package/dist/components/data-display/Avatar.mjs.map +1 -1
- package/dist/components/data-display/Avatar.sizes.cjs +2 -0
- package/dist/components/data-display/Avatar.sizes.cjs.map +1 -0
- package/dist/components/data-display/Avatar.sizes.mjs +41 -0
- package/dist/components/data-display/Avatar.sizes.mjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.cjs +1 -1
- package/dist/components/data-display/AvatarGroup.cjs.map +1 -1
- package/dist/components/data-display/AvatarGroup.context.cjs +2 -0
- package/dist/components/data-display/AvatarGroup.context.cjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.context.mjs +9 -0
- package/dist/components/data-display/AvatarGroup.context.mjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.mjs +65 -122
- package/dist/components/data-display/AvatarGroup.mjs.map +1 -1
- package/dist/components/data-display/AvatarGroup.partition.cjs +2 -0
- package/dist/components/data-display/AvatarGroup.partition.cjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.partition.mjs +14 -0
- package/dist/components/data-display/AvatarGroup.partition.mjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.parts.cjs +2 -0
- package/dist/components/data-display/AvatarGroup.parts.cjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.parts.mjs +178 -0
- package/dist/components/data-display/AvatarGroup.parts.mjs.map +1 -0
- package/dist/components/data-display/InteractionTag.cjs +1 -1
- package/dist/components/data-display/InteractionTag.cjs.map +1 -1
- package/dist/components/data-display/InteractionTag.mjs +36 -33
- package/dist/components/data-display/InteractionTag.mjs.map +1 -1
- package/dist/components/data-display/List.cjs +1 -1
- package/dist/components/data-display/List.cjs.map +1 -1
- package/dist/components/data-display/List.mjs +245 -195
- package/dist/components/data-display/List.mjs.map +1 -1
- package/dist/components/data-display/List.registry.cjs.map +1 -1
- package/dist/components/data-display/List.registry.mjs.map +1 -1
- package/dist/components/data-display/Persona.cjs +1 -1
- package/dist/components/data-display/Persona.cjs.map +1 -1
- package/dist/components/data-display/Persona.mjs +96 -37
- package/dist/components/data-display/Persona.mjs.map +1 -1
- package/dist/components/data-display/PresenceBadge.cjs +1 -1
- package/dist/components/data-display/PresenceBadge.cjs.map +1 -1
- package/dist/components/data-display/PresenceBadge.mjs +42 -28
- package/dist/components/data-display/PresenceBadge.mjs.map +1 -1
- package/dist/components/data-display/Tag.cjs +1 -1
- package/dist/components/data-display/Tag.cjs.map +1 -1
- package/dist/components/data-display/Tag.mjs +111 -108
- package/dist/components/data-display/Tag.mjs.map +1 -1
- package/dist/components/layout/Card.cjs +1 -1
- package/dist/components/layout/Card.cjs.map +1 -1
- package/dist/components/layout/Card.context.cjs +2 -0
- package/dist/components/layout/Card.context.cjs.map +1 -0
- package/dist/components/layout/Card.context.mjs +14 -0
- package/dist/components/layout/Card.context.mjs.map +1 -0
- package/dist/components/layout/Card.mjs +138 -92
- package/dist/components/layout/Card.mjs.map +1 -1
- package/dist/components/layout/Card.preview.cjs +2 -0
- package/dist/components/layout/Card.preview.cjs.map +1 -0
- package/dist/components/layout/Card.preview.mjs +22 -0
- package/dist/components/layout/Card.preview.mjs.map +1 -0
- package/dist/components/layout/Carousel.button.cjs +2 -0
- package/dist/components/layout/Carousel.button.cjs.map +1 -0
- package/dist/components/layout/Carousel.button.mjs +34 -0
- package/dist/components/layout/Carousel.button.mjs.map +1 -0
- package/dist/components/layout/Carousel.cjs +1 -1
- package/dist/components/layout/Carousel.cjs.map +1 -1
- package/dist/components/layout/Carousel.context.cjs +2 -0
- package/dist/components/layout/Carousel.context.cjs.map +1 -0
- package/dist/components/layout/Carousel.context.mjs +24 -0
- package/dist/components/layout/Carousel.context.mjs.map +1 -0
- package/dist/components/layout/Carousel.drag.cjs +2 -0
- package/dist/components/layout/Carousel.drag.cjs.map +1 -0
- package/dist/components/layout/Carousel.drag.mjs +79 -0
- package/dist/components/layout/Carousel.drag.mjs.map +1 -0
- package/dist/components/layout/Carousel.groups.cjs +2 -0
- package/dist/components/layout/Carousel.groups.cjs.map +1 -0
- package/dist/components/layout/Carousel.groups.mjs +23 -0
- package/dist/components/layout/Carousel.groups.mjs.map +1 -0
- package/dist/components/layout/Carousel.mjs +288 -150
- package/dist/components/layout/Carousel.mjs.map +1 -1
- package/dist/components/layout/Carousel.styles.cjs +2 -0
- package/dist/components/layout/Carousel.styles.cjs.map +1 -0
- package/dist/components/layout/Carousel.styles.mjs +30 -0
- package/dist/components/layout/Carousel.styles.mjs.map +1 -0
- package/dist/components/layout/Overflow.cjs +1 -1
- package/dist/components/layout/Overflow.cjs.map +1 -1
- package/dist/components/layout/Overflow.mjs +240 -192
- package/dist/components/layout/Overflow.mjs.map +1 -1
- package/dist/components/layout/Overflow.store.cjs +2 -0
- package/dist/components/layout/Overflow.store.cjs.map +1 -0
- package/dist/components/layout/Overflow.store.mjs +209 -0
- package/dist/components/layout/Overflow.store.mjs.map +1 -0
- package/dist/components/layout/TabList.cjs +1 -1
- package/dist/components/layout/TabList.cjs.map +1 -1
- package/dist/components/layout/TabList.mjs +163 -124
- package/dist/components/layout/TabList.mjs.map +1 -1
- package/dist/components/navigation/Breadcrumb.cjs +1 -1
- package/dist/components/navigation/Breadcrumb.cjs.map +1 -1
- package/dist/components/navigation/Breadcrumb.mjs +239 -84
- package/dist/components/navigation/Breadcrumb.mjs.map +1 -1
- package/dist/components/overlays/Dialog.slots.cjs +1 -1
- package/dist/components/overlays/Dialog.slots.cjs.map +1 -1
- package/dist/components/overlays/Dialog.slots.mjs +19 -15
- package/dist/components/overlays/Dialog.slots.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.cjs +1 -1
- package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.context.cjs +2 -0
- package/dist/components/overlays/TeachingPopover.context.cjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.context.mjs +51 -0
- package/dist/components/overlays/TeachingPopover.context.mjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.mjs +15 -185
- package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.parts.cjs +2 -0
- package/dist/components/overlays/TeachingPopover.parts.cjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.parts.mjs +398 -0
- package/dist/components/overlays/TeachingPopover.parts.mjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.root.cjs +2 -0
- package/dist/components/overlays/TeachingPopover.root.cjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.root.mjs +150 -0
- package/dist/components/overlays/TeachingPopover.root.mjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.stack.cjs +2 -0
- package/dist/components/overlays/TeachingPopover.stack.cjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.stack.mjs +86 -0
- package/dist/components/overlays/TeachingPopover.stack.mjs.map +1 -0
- package/dist/components/table/DataGrid.cjs +1 -1
- package/dist/components/table/DataGrid.cjs.map +1 -1
- package/dist/components/table/DataGrid.mjs +540 -311
- package/dist/components/table/DataGrid.mjs.map +1 -1
- package/dist/components/table/Table.cjs +1 -1
- package/dist/components/table/Table.cjs.map +1 -1
- package/dist/components/table/Table.mjs +183 -60
- package/dist/components/table/Table.mjs.map +1 -1
- package/dist/components/table/Table.shared.cjs +2 -0
- package/dist/components/table/Table.shared.cjs.map +1 -0
- package/dist/components/table/Table.shared.mjs +65 -0
- package/dist/components/table/Table.shared.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2299 -213
- package/dist/index.d.ts +2299 -213
- package/dist/index.mjs +135 -127
- package/dist/lib/breadcrumb.cjs +2 -0
- package/dist/lib/breadcrumb.cjs.map +1 -0
- package/dist/lib/breadcrumb.mjs +26 -0
- package/dist/lib/breadcrumb.mjs.map +1 -0
- package/dist/lib/classNames.cjs +1 -1
- package/dist/lib/classNames.cjs.map +1 -1
- package/dist/lib/classNames.mjs +143 -95
- package/dist/lib/classNames.mjs.map +1 -1
- package/dist/lib/events.cjs +1 -1
- package/dist/lib/events.cjs.map +1 -1
- package/dist/lib/events.mjs +35 -8
- package/dist/lib/events.mjs.map +1 -1
- package/dist/lib/icons.cjs +1 -1
- package/dist/lib/icons.cjs.map +1 -1
- package/dist/lib/icons.mjs +34 -20
- package/dist/lib/icons.mjs.map +1 -1
- package/dist/lib/initials.cjs +2 -0
- package/dist/lib/initials.cjs.map +1 -0
- package/dist/lib/initials.mjs +21 -0
- package/dist/lib/initials.mjs.map +1 -0
- package/dist/lib/table.cjs +2 -0
- package/dist/lib/table.cjs.map +1 -0
- package/dist/lib/table.mjs +16 -0
- package/dist/lib/table.mjs.map +1 -0
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/styles/tokens.css +102 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InteractionTag.cjs","names":["React","cn","INTERACTION_TAG_DISABLED_CLASSES","mergedAriaDisabledClasses","INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES","forcedColors","MERGED_DISABLED_FOCUSABLE_PROPS","useTagGroupContext","useMergedRefs","useId","tagSizeClasses","tagAppearanceClasses","tagShapeClasses","useTagGroupItem","useEventCallback","interactionTagClassNames","useHeldFocus","slotRendersContent","materialiseSlotContent","TAG_AVATAR_SIZE","isOwnEvent","isDismissKey","interactionTagPrimaryClassNames","composeEventHandlers","INTERACTION_TAG_BUTTON_BASE_CLASSES","INTERACTION_TAG_PRIMARY_BASE_CLASSES","tagStartInsetClasses","interactionTagPrimaryEndInsetClasses","interactionTagLookClasses","INTERACTION_TAG_PRIMARY_JOINED_CLASSES","focusRing","AvatarSizeContext","renderSlot","tagMediaClasses","tagIconClasses","TAG_TEXT_COLUMN_CLASSES","TAG_SECONDARY_TEXT_CLASSES","unwrapButtonGlyph","hasTextLabel","observeTextLabel","hasRenderedTextLabel","joinIds","isRepeatedActivation","interactionTagSecondaryClassNames","INTERACTION_TAG_SECONDARY_BASE_CLASSES","interactionTagSecondarySizeClasses","interactionTagDividerClasses","interactionTagSecondaryShapeClasses","DismissIcon","TAG_DISMISS_GLYPH_SIZE","require_runtime","require_cn","require_dev","require_slot","require_composeEventHandlers","require_classNames","require_useEventCallback","require_useId","require_useMergedRefs","require_aria","require_styles","require_Button_slots","require_icons","require_labelInName","require_events","require_TagGroup_context","require_Avatar_context","require_tagStyles","react","react_jsx_runtime","noop","createPrimaryRegistry","count","settled","listeners","notify","listener","onChange","INERT_PRIMARY_REGISTRY","InteractionTagContext","INERT_CONTEXT","useInteractionTagContext","componentName","isKeyOf","value","table","disabledClasses","dimDisabled","disabled","SELECTED_IN_GROUP_MESSAGE","buttonStateProps","held","InteractionTagRoot","appearanceProp","sizeProp","shapeProp","disabledProp","selectedProp","rest","group","rootRef","mergedRef","ref","secondaryRef","primaryTextId","primaries","size","appearance","shape","reportedValue","selecting","pressed","selected","look","selectedIgnored","dismiss","toggle","listItemRole","hiddenByHost","context","role","hidden","className","InteractionTagPrimary","ariaPressed","tag","hold","registerPrimary","hasMedia","media","hasIcon","icon","secondary","secondaryText","hasSecondary","avatarBox","handleClick","event","handleKeyDown","secondaryButton","primaryText","onClick","onKeyDown","onFocus","onBlur","BUTTON_CHILD_MESSAGE","InteractionTagSecondary","ariaLabel","ariaLabelledBy","dismissLabelId","contentId","ownRef","unwrapped","children","content","glyph","hasContent","literalTextLabel","labelTarget","setLabelTarget","subscribeToContent","contentHasTextLabel","hasLabel","hasPrimary","namedByConsumer","labelledBy","dismissLabel","InteractionTag"],"sources":["../../../src/components/data-display/InteractionTag.tsx"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport {\n interactionTagClassNames,\n interactionTagPrimaryClassNames,\n interactionTagSecondaryClassNames,\n} from '../../lib/classNames';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { reportMissingContext, warnOnce } from '../../lib/dev';\nimport { isOwnEvent } from '../../lib/events';\nimport { DismissIcon } from '../../lib/icons';\nimport { hasRenderedTextLabel, hasTextLabel, observeTextLabel } from '../../lib/labelInName';\nimport { materialiseSlotContent, renderSlot, slotRendersContent } from '../../lib/slot';\nimport type { Slot } from '../../lib/slot';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport type { TagAppearance, TagShape, TagSize } from '../../lib/types';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport {\n MERGED_DISABLED_FOCUSABLE_PROPS,\n mergedAriaDisabledClasses,\n unwrapButtonGlyph,\n} from '../button/Button.slots';\nimport { AvatarSizeContext } from './Avatar.context';\nimport {\n isDismissKey,\n isRepeatedActivation,\n useDismissControlFocus,\n useHeldFocus,\n useTagGroupContext,\n useTagGroupItem,\n} from './TagGroup.context';\nimport {\n INTERACTION_TAG_BUTTON_BASE_CLASSES,\n INTERACTION_TAG_DISABLED_CLASSES,\n INTERACTION_TAG_EXTRA_SMALL_HIT_CLASSES,\n INTERACTION_TAG_PRIMARY_BASE_CLASSES,\n INTERACTION_TAG_PRIMARY_JOINED_CLASSES,\n INTERACTION_TAG_SECONDARY_BASE_CLASSES,\n INTERACTION_TAG_SECONDARY_LABEL_CLASSES,\n INTERACTION_TAG_SELECTED_FORCED_COLORS,\n INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES,\n TAG_AVATAR_SIZE,\n TAG_DISMISS_GLYPH_SIZE,\n TAG_PRIMARY_TEXT_TWO_LINE_CLASSES,\n TAG_SECONDARY_TEXT_CLASSES,\n TAG_TEXT_COLUMN_CLASSES,\n interactionTagDividerClasses,\n interactionTagLookClasses,\n interactionTagPrimaryEndInsetClasses,\n interactionTagSecondaryShapeClasses,\n interactionTagSecondarySizeClasses,\n tagAppearanceClasses,\n tagIconClasses,\n tagMediaClasses,\n tagShapeClasses,\n tagSizeClasses,\n tagStartInsetClasses,\n} from './tagStyles';\nimport type { TagLook } from './tagStyles';\n\n/** Props of InteractionTag: the element that holds the Primary and Secondary buttons. */\nexport interface InteractionTagProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Identifies the tag in a TagGroup: the value `onDismiss` receives and the selection holds. Give\n * every tag of a group its own value.\n * @default a generated id (a development warning in a group that reports values)\n */\n value?: string;\n /**\n * Colour scheme of both buttons: `filled` (a neutral fill), `outline` (a border on the surface\n * behind it) or `brand` (a light brand tint that follows the brand ramp).\n * @default the TagGroup's `appearance`, else 'filled'\n */\n appearance?: TagAppearance;\n /**\n * `medium` (28px tall), `small` (24px) or `extra-small` (20px); an Avatar in the Primary's\n * `media` is 24, 20 or 16px. Fluent's medium tag is 32px.\n * @default the TagGroup's `size`, else 'medium'\n */\n size?: TagSize;\n /**\n * `circular` (a pill) or `rounded` (4px corners). Fluent's default is `rounded`.\n * @default the TagGroup's `shape`, else 'circular'\n */\n shape?: TagShape;\n /**\n * Disables both buttons natively (a disabled TagGroup does too; a part's own `disabled` cannot\n * re-enable it). A button that has focus when it is disabled keeps it, unavailable, until focus\n * leaves it. Rendered as `data-disabled` on the root.\n * @default false\n */\n disabled?: boolean;\n /**\n * Outside a selecting TagGroup: draws the selected look and makes the Primary a toggle:\n * `aria-pressed=\"true\"`, or `\"false\"` for `selected={false}`. Leave it `undefined` for an\n * action that is not a toggle (no `aria-pressed`). Inside a selecting TagGroup (`value`,\n * `defaultValue` or `onValueChange`) the group's `value` decides, and a defined `selected` is\n * ignored (a development warning). Rendered as `data-selected` on the root and both buttons.\n * Disabled wins over the selected look (`aria-pressed` and `data-selected` still render).\n * Fluent's `selected` is a look only.\n */\n selected?: boolean;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Props of InteractionTag.Primary: the tag's main action (or its toggle in a selecting TagGroup). */\nexport interface InteractionTagPrimaryProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * A visual before the text (an Avatar, sized for the tag: 24, 20 or 16px, unless it sets its\n * own `size`). Decorative (`aria-hidden`): the button is named by its text.\n */\n media?: Slot<'span'>;\n /** A decorative icon before the text (`aria-hidden`), in a 20, 16 or 12px box. */\n icon?: Slot<'span'>;\n /**\n * A second, smaller line under the text. Part of the Primary's name, not of the Secondary's. A\n * small or extra-small tag grows to 28px to fit it.\n */\n secondaryText?: React.ReactNode;\n /**\n * Disables the Primary natively; or-ed with the InteractionTag's `disabled` (it cannot\n * re-enable a disabled tag).\n * @default false\n */\n disabled?: boolean;\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n/** Props of InteractionTag.Secondary: the tag's separate Dismiss button. */\nexport interface InteractionTagSecondaryProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * Visually hidden text that names the button with the Primary's text (\"Dismiss Cherry\"). A text\n * label in the children replaces it (\"Remove Cherry\"); an `aria-label` replaces the whole name.\n * Localise it here. Fluent's order is the primary text, then the label (\"Cherry remove\").\n * @default 'Dismiss'\n */\n dismissLabel?: string;\n /**\n * Disables the Secondary natively; or-ed with the InteractionTag's `disabled` (it cannot\n * re-enable a disabled tag).\n * @default false\n */\n disabled?: boolean;\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\n/** What an InteractionTag gives its two buttons (resolved values, never `undefined` but `pressed`). */\ninterface InteractionTagContextValue {\n size: TagSize;\n shape: TagShape;\n /** The look of both buttons: the appearance, or the selected look over it. */\n look: TagLook;\n /** Whether the tag is disabled (its own `disabled`, or its TagGroup's). */\n disabled: boolean;\n /** Whether the tag is selected (`data-selected`). */\n selected: boolean;\n /** The Primary's `aria-pressed`: `undefined` for an action that is not a toggle. */\n pressed: boolean | undefined;\n /** Whether a disabled button dims itself (`false` under a host that dims the tags as a whole). */\n dimDisabled: boolean;\n /** The id of the Primary's text, the second half of the Secondary's name. */\n primaryTextId: string;\n /** Which Primaries render, so the Secondary points at the primary text only while one does. */\n primaries: PrimaryRegistry;\n /** The Secondary, which Delete and Backspace on the Primary click (read at key time). */\n secondaryRef: React.RefObject<HTMLButtonElement | null> | null;\n /**\n * Reports the dismissal to the TagGroup (its `onDismiss(value)`), after the Secondary's\n * `onClick`, and then removes the tag's value from the group's selection (D39).\n */\n dismiss: () => void;\n /** Toggles the tag's value in a selecting TagGroup's selection (the Primary's click). */\n toggle: () => void;\n}\n\nconst noop = () => {};\n\n/**\n * The Primaries an InteractionTag renders, read by its Secondary, whose name points at the\n * primary text only while a Primary renders it (no id reference to a missing element). Until the\n * root's first commit (the server render, hydration and the first client render) a Primary is\n * assumed, so the server HTML holds the whole name and a tag with a Primary renders once; a\n * Secondary without one drops the id after that commit, and takes it again when one mounts. An\n * external store (C-HOOKS): a Primary registers from a layout effect.\n */\ninterface PrimaryRegistry {\n subscribe: (onChange: () => void) => () => void;\n /** Whether the Secondary's name may point at the primary text. */\n hasPrimary: () => boolean;\n /** For a Primary's layout effect: returns its cleanup. */\n register: () => () => void;\n /** For the root's layout effect: from now on the registrations decide. */\n settle: () => void;\n}\n\nfunction createPrimaryRegistry(): PrimaryRegistry {\n let count = 0;\n let settled = false;\n const listeners = new Set<() => void>();\n const notify = () => {\n for (const listener of listeners) listener();\n };\n return {\n subscribe: (onChange) => {\n listeners.add(onChange);\n return () => {\n listeners.delete(onChange);\n };\n },\n hasPrimary: () => !settled || count > 0,\n register: () => {\n count += 1;\n notify();\n return () => {\n count -= 1;\n notify();\n };\n },\n settle: () => {\n if (settled) return;\n settled = true;\n notify();\n },\n };\n}\n\n/** The registry of the inert context: a Primary is always assumed. */\nconst INERT_PRIMARY_REGISTRY: PrimaryRegistry = {\n subscribe: () => noop,\n hasPrimary: () => true,\n register: () => noop,\n settle: noop,\n};\n\n/** Internal: `null` outside an InteractionTag. */\nconst InteractionTagContext = React.createContext<InteractionTagContextValue | null>(null);\nInteractionTagContext.displayName = 'InteractionTagContext';\n\n/** What a part reads outside an InteractionTag in production (C-CONTEXT): an enabled, unnamed tag. */\nconst INERT_CONTEXT: InteractionTagContextValue = {\n size: 'medium',\n shape: 'circular',\n look: 'filled',\n disabled: false,\n selected: false,\n pressed: undefined,\n dimDisabled: true,\n primaryTextId: '',\n primaries: INERT_PRIMARY_REGISTRY,\n secondaryRef: null,\n dismiss: () => {},\n toggle: () => {},\n};\n\nfunction useInteractionTagContext(componentName: string): InteractionTagContextValue {\n const context = React.useContext(InteractionTagContext);\n if (context) return context;\n reportMissingContext(componentName, 'InteractionTag');\n return INERT_CONTEXT;\n}\n\n/** Whether `value` is a key of `table` (an untyped value outside a union falls back). */\nfunction isKeyOf<K extends string>(\n value: unknown,\n table: Readonly<Record<K, unknown>>,\n): value is K {\n return typeof value === 'string' && Object.hasOwn(table, value);\n}\n\n/** The classes of a button's disabled states: dimmed, unless the host dims the tags itself. */\nfunction disabledClasses(disabled: boolean, dimDisabled: boolean): string {\n return cn(\n dimDisabled\n ? [INTERACTION_TAG_DISABLED_CLASSES, mergedAriaDisabledClasses]\n : INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES,\n disabled && forcedColors.disabled,\n );\n}\n\nconst SELECTED_IN_GROUP_MESSAGE =\n \"InteractionTag: `selected` has no effect in a TagGroup that selects (`value`, `defaultValue` or `onValueChange`); the group's `value` decides.\";\n\n/**\n * The state props of a tag button: natively disabled, or, while it keeps the focus it had when it\n * was disabled, the focusable disabled state (its click blocked).\n */\nfunction buttonStateProps(disabled: boolean, held: boolean) {\n if (!disabled) return undefined;\n return held ? MERGED_DISABLED_FOCUSABLE_PROPS : { disabled: true };\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\n// The InteractionTag root, documented on the exported `InteractionTag` const.\nconst InteractionTagRoot = ({\n value,\n appearance: appearanceProp,\n size: sizeProp,\n shape: shapeProp,\n disabled: disabledProp = false,\n selected: selectedProp,\n role,\n hidden,\n className,\n children,\n ref,\n ...rest\n}: InteractionTagProps) => {\n const group = useTagGroupContext();\n const rootRef = React.useRef<HTMLDivElement>(null);\n const mergedRef = useMergedRefs<HTMLDivElement>(rootRef, ref);\n const secondaryRef = React.useRef<HTMLButtonElement>(null);\n const primaryTextId = useId('interaction-tag-text');\n // After the first commit, the Primaries that registered decide the Secondary's name (D43).\n const [primaries] = React.useState(createPrimaryRegistry);\n React.useLayoutEffect(() => {\n primaries.settle();\n }, [primaries]);\n\n // The tag's own look, else its TagGroup's, else the default look.\n const size: TagSize = isKeyOf(sizeProp, tagSizeClasses) ? sizeProp : (group?.size ?? 'medium');\n const appearance: TagAppearance = isKeyOf(appearanceProp, tagAppearanceClasses)\n ? appearanceProp\n : (group?.appearance ?? 'filled');\n const shape: TagShape = isKeyOf(shapeProp, tagShapeClasses)\n ? shapeProp\n : (group?.shape ?? 'circular');\n // A disabled group disables every tag: the tag's own `disabled={false}` cannot re-enable it.\n const disabled = (group?.disabled ?? false) || disabledProp;\n const dimDisabled = group?.dimDisabled ?? true;\n\n // In a group that reports dismissals or selects, the tag's value (else a generated id).\n const reportedValue = useTagGroupItem(rootRef, value);\n // In a selecting TagGroup the group's selection decides (the Primary is always a toggle there);\n // elsewhere a boolean `selected` does, and `undefined` is an action that is no toggle.\n const selecting = group?.selecting ?? false;\n const pressed = selecting\n ? (group?.isSelected(reportedValue) ?? false)\n : typeof selectedProp === 'boolean'\n ? selectedProp\n : undefined;\n const selected = pressed === true;\n // Disabled wins over the selected look; the attributes still reflect the state.\n const look: TagLook = selected && !disabled ? 'selected' : appearance;\n\n const selectedIgnored = selecting && selectedProp !== undefined;\n React.useEffect(() => {\n if (selectedIgnored) warnOnce('InteractionTag:selected-in-group', SELECTED_IN_GROUP_MESSAGE);\n }, [selectedIgnored]);\n\n // The group's `onDismiss(value)`, then the value leaves the selection (D39), in one click.\n const dismiss = useEventCallback(() => {\n group?.dismiss(reportedValue);\n group?.deselect(reportedValue);\n });\n const toggle = useEventCallback(() => {\n group?.toggle(reportedValue);\n });\n\n // In a list TagGroup the root is a list item; the consumer's role wins.\n const listItemRole = group?.mode === 'list' ? 'listitem' : undefined;\n // A host hides the tags it counts instead of showing them (TagPicker's `overflow=\"count\"`).\n const hiddenByHost = value !== undefined && (group?.hiddenValues?.has(value) ?? false);\n\n const context = React.useMemo<InteractionTagContextValue>(\n () => ({\n size,\n shape,\n look,\n disabled,\n selected,\n pressed,\n dimDisabled,\n primaryTextId,\n primaries,\n secondaryRef,\n dismiss,\n toggle,\n }),\n [\n size,\n shape,\n look,\n disabled,\n selected,\n pressed,\n dimDisabled,\n primaryTextId,\n primaries,\n dismiss,\n toggle,\n ],\n );\n\n return (\n <InteractionTagContext.Provider value={context}>\n <div\n data-appearance={appearance}\n data-size={size}\n data-shape={shape}\n data-selected={selected ? '' : undefined}\n data-disabled={disabled ? '' : undefined}\n data-wave-tag-item=\"\"\n role={role ?? listItemRole}\n hidden={hiddenByHost || hidden}\n {...rest}\n ref={mergedRef}\n className={cn(\n interactionTagClassNames.root,\n 'group/interaction-tag inline-flex items-stretch',\n className,\n )}\n >\n {children}\n </div>\n </InteractionTagContext.Provider>\n );\n};\nInteractionTagRoot.displayName = 'InteractionTag';\n\n// ---------------------------------------------------------------------------\n// Primary\n// ---------------------------------------------------------------------------\n\n/**\n * The main action of an {@link InteractionTag}: a `<button type=\"button\">` named by its text and\n * `secondaryText` (`media` and `icon` are decorative), with the InteractionTag's look. In a\n * selecting TagGroup it is a toggle (`aria-pressed`): a click, Enter or Space adds the tag's\n * `value` to the group's selection or removes it, after its `onClick` (whose `preventDefault()`\n * cancels the toggle). Elsewhere the InteractionTag's `selected` makes it a toggle. Either state\n * renders its `aria-pressed` over one passed here, which applies only when neither is set. Delete\n * and Backspace on it click the tag's Secondary when there is one. Its props, `ref` and\n * `className` go to the button. Flat name of `InteractionTag.Primary`, for React Server\n * Components.\n */\nexport const InteractionTagPrimary = ({\n media,\n icon,\n secondaryText,\n disabled: disabledProp = false,\n 'aria-pressed': ariaPressed,\n className,\n children,\n onClick,\n onKeyDown,\n onFocus,\n onBlur,\n ref,\n ...rest\n}: InteractionTagPrimaryProps) => {\n const tag = useInteractionTagContext('InteractionTag.Primary');\n const { size, look } = tag;\n const disabled = tag.disabled || disabledProp;\n const hold = useHeldFocus(disabled);\n // Its text names the Secondary while it renders (D43).\n const registerPrimary = tag.primaries.register;\n React.useLayoutEffect(() => registerPrimary(), [registerPrimary]);\n\n // Slots that render nothing render no element and take no room.\n const hasMedia = slotRendersContent(media);\n const hasIcon = slotRendersContent(icon);\n const secondary = materialiseSlotContent(secondaryText);\n const hasSecondary = slotRendersContent(secondary);\n const avatarBox = React.useMemo(() => ({ size: TAG_AVATAR_SIZE[size] }), [size]);\n\n // In a selecting TagGroup a click (also Enter and Space) toggles the tag's value, after the\n // consumer's `onClick`; never for a click from a portal opened from the Primary (C-COMPOSE).\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (!disabled && isOwnEvent(event)) tag.toggle();\n };\n\n // Delete and Backspace dismiss the tag through the Secondary's own click, so whatever cancels\n // that click (its `onClick`'s `preventDefault()`, a disabled or held Secondary) cancels them\n // too. Not from a portal opened from the Primary, and not while the Primary itself is held.\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (disabled || event.target !== event.currentTarget || !isDismissKey(event)) return;\n const secondaryButton = tag.secondaryRef?.current;\n if (!secondaryButton || secondaryButton.disabled) return;\n event.preventDefault();\n secondaryButton.click();\n };\n\n const primaryText = (\n <span\n id={tag.primaryTextId || undefined}\n className={cn(\n interactionTagPrimaryClassNames.primaryText,\n hasSecondary && TAG_PRIMARY_TEXT_TWO_LINE_CLASSES,\n )}\n >\n {children}\n </span>\n );\n\n return (\n <button\n type=\"button\"\n // The tag's state (`selected`, or a selecting TagGroup's value) decides; a consumer\n // `aria-pressed` applies only to a Primary that is no toggle of the tag's.\n aria-pressed={tag.pressed ?? ariaPressed}\n data-selected={tag.selected ? '' : undefined}\n {...rest}\n ref={ref}\n onClick={composeEventHandlers(onClick, handleClick)}\n // After `onClick`: a held Primary's click is blocked, the toggle included.\n {...buttonStateProps(disabled, hold.held)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onFocus={composeEventHandlers(onFocus, hold.onFocus, { checkDefaultPrevented: false })}\n onBlur={composeEventHandlers(onBlur, hold.onBlur, { checkDefaultPrevented: false })}\n className={cn(\n interactionTagPrimaryClassNames.root,\n INTERACTION_TAG_BUTTON_BASE_CLASSES,\n INTERACTION_TAG_PRIMARY_BASE_CLASSES,\n tagSizeClasses[size],\n tagStartInsetClasses[size][hasMedia ? 'media' : hasIcon ? 'icon' : 'text'],\n interactionTagPrimaryEndInsetClasses[size],\n interactionTagLookClasses[look],\n look === 'selected' && [\n forcedColors.selectedContainer,\n INTERACTION_TAG_SELECTED_FORCED_COLORS,\n ],\n tagShapeClasses[tag.shape],\n INTERACTION_TAG_PRIMARY_JOINED_CLASSES,\n disabledClasses(disabled, tag.dimDisabled),\n focusRing,\n size === 'extra-small' && INTERACTION_TAG_EXTRA_SMALL_HIT_CLASSES,\n className,\n )}\n >\n {hasMedia && (\n // An Avatar without its own `size` takes the tag's box.\n <AvatarSizeContext.Provider value={avatarBox}>\n {renderSlot(\n media,\n 'span',\n cn(interactionTagPrimaryClassNames.media, tagMediaClasses[size]),\n { 'aria-hidden': true },\n )}\n </AvatarSizeContext.Provider>\n )}\n {hasIcon &&\n renderSlot(icon, 'span', cn(interactionTagPrimaryClassNames.icon, tagIconClasses[size]), {\n 'aria-hidden': true,\n })}\n {hasSecondary ? (\n <span className={TAG_TEXT_COLUMN_CLASSES}>\n {primaryText}\n {/* A space between the two texts in the button's name (\"Katri Designer\"), whatever a\n name computation makes of the column; the column layout never renders it. */}{' '}\n <span\n className={cn(\n interactionTagPrimaryClassNames.secondaryText,\n TAG_SECONDARY_TEXT_CLASSES,\n )}\n >\n {secondary}\n </span>\n </span>\n ) : (\n primaryText\n )}\n </button>\n );\n};\nInteractionTagPrimary.displayName = 'InteractionTagPrimary';\n\n// ---------------------------------------------------------------------------\n// Secondary\n// ---------------------------------------------------------------------------\n\nconst BUTTON_CHILD_MESSAGE =\n \"InteractionTag.Secondary: its content received a button. A button cannot contain a button: its children became the content of the Dismiss button and its props were dropped. Pass icon content, and handle the dismissal in `onClick` or in the TagGroup's `onDismiss`.\";\n\n/**\n * The separate Dismiss button of an {@link InteractionTag}: a `<button type=\"button\">` after the\n * Primary, named `dismissLabel` plus the Primary's text (\"Dismiss Cherry\"). Its children replace\n * the default dismiss glyph; a text label among them replaces `dismissLabel` in the name (\"Remove\n * Cherry\"), an `aria-label` the whole name. A button passed as its child is unwrapped (its children\n * become the content). Enter, Space, a click, Delete and Backspace call its `onClick`, then, in a\n * TagGroup, the group's `onDismiss(value)`. Its props, `ref` and `className` go to the button.\n * Flat name of `InteractionTag.Secondary`, for React Server Components.\n */\nexport const InteractionTagSecondary = ({\n dismissLabel = 'Dismiss',\n disabled: disabledProp = false,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className,\n children,\n onClick,\n onKeyDown,\n onFocus,\n onBlur,\n ref,\n ...rest\n}: InteractionTagSecondaryProps) => {\n const tag = useInteractionTagContext('InteractionTag.Secondary');\n const { size, look } = tag;\n const disabled = tag.disabled || disabledProp;\n const hold = useHeldFocus(disabled);\n const dismissLabelId = useId('interaction-tag-dismiss');\n const contentId = useId('interaction-tag-dismiss-content');\n const ownRef = React.useRef<HTMLButtonElement>(null);\n const mergedRef = useMergedRefs<HTMLButtonElement>(ownRef, tag.secondaryRef, ref);\n // Unmounting while it has focus (rendered conditionally), the Secondary hands focus to its own\n // tag's Primary; in a TagGroup, when the whole tag goes, the tag's own move applies (D35).\n useDismissControlFocus(ownRef);\n\n // Its children are the glyph inside the Dismiss button: a button there would nest buttons, so\n // it is unwrapped (C-SLOTS glyph rule).\n const { glyph, button: unwrapped } = unwrapButtonGlyph(children as Slot<'span'>);\n React.useEffect(() => {\n if (unwrapped) warnOnce('InteractionTag.Secondary:button-child', BUTTON_CHILD_MESSAGE);\n }, [unwrapped]);\n const content = materialiseSlotContent(glyph);\n const hasContent = slotRendersContent(content);\n const literalTextLabel = hasContent && hasTextLabel(content);\n\n // C-SLOTS naming (WCAG 2.5.3 Label in Name): a text label in the children replaces\n // `dismissLabel` (\"Remove Cherry\"). The literal children decide on the server and on the first\n // render; after mount, the rendered content does (text from components, later changes).\n const [labelTarget, setLabelTarget] = React.useState<HTMLSpanElement | null>(null);\n const subscribeToContent = React.useCallback(\n (onChange: () => void) => (labelTarget ? observeTextLabel(labelTarget, onChange) : noop),\n [labelTarget],\n );\n const contentHasTextLabel = React.useSyncExternalStore(\n subscribeToContent,\n () => (labelTarget ? hasRenderedTextLabel(labelTarget) : literalTextLabel),\n () => literalTextLabel,\n );\n const hasLabel = hasContent && contentHasTextLabel;\n // The primary text joins the name while a Primary renders it.\n const hasPrimary = React.useSyncExternalStore(\n tag.primaries.subscribe,\n tag.primaries.hasPrimary,\n () => true,\n );\n // A consumer `aria-label` replaces the whole name; a consumer `aria-labelledby` replaces ours.\n const namedByConsumer = ariaLabel !== undefined || ariaLabelledBy !== undefined;\n const labelledBy = namedByConsumer\n ? ariaLabelledBy\n : joinIds(hasLabel ? contentId : dismissLabelId, hasPrimary ? tag.primaryTextId : undefined);\n\n // The consumer's `onClick` first (its `preventDefault()` keeps the group from hearing of it),\n // then the TagGroup's `onDismiss(value)`; never for a click from a portal opened inside.\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (isOwnEvent(event)) tag.dismiss();\n };\n // Delete and Backspace dismiss as Enter does: through the button's own click, so whatever\n // cancels a click (its `onClick`'s `preventDefault()`, a held or disabled button) cancels them.\n // A held key dismisses one tag: the browser clicks a button on every repeated Enter, which\n // would reach the next tag's Dismiss control once focus moved there (D35).\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (event.target !== event.currentTarget) return;\n if (isRepeatedActivation(event)) {\n event.preventDefault();\n return;\n }\n if (!isDismissKey(event)) return;\n event.preventDefault();\n event.currentTarget.click();\n };\n\n return (\n <button\n type=\"button\"\n data-wave-tag-dismiss=\"\"\n data-selected={tag.selected ? '' : undefined}\n {...rest}\n ref={mergedRef}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n onClick={composeEventHandlers(onClick, handleClick)}\n {...buttonStateProps(disabled, hold.held)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onFocus={composeEventHandlers(onFocus, hold.onFocus, { checkDefaultPrevented: false })}\n onBlur={composeEventHandlers(onBlur, hold.onBlur, { checkDefaultPrevented: false })}\n className={cn(\n interactionTagSecondaryClassNames.root,\n INTERACTION_TAG_BUTTON_BASE_CLASSES,\n INTERACTION_TAG_SECONDARY_BASE_CLASSES,\n interactionTagSecondarySizeClasses[size],\n interactionTagLookClasses[look],\n look === 'selected' && [\n forcedColors.selectedContainer,\n INTERACTION_TAG_SELECTED_FORCED_COLORS,\n ],\n interactionTagDividerClasses[look],\n interactionTagSecondaryShapeClasses[tag.shape],\n disabledClasses(disabled, tag.dimDisabled),\n focusRing,\n size === 'extra-small' && INTERACTION_TAG_EXTRA_SMALL_HIT_CLASSES,\n className,\n )}\n >\n {!namedByConsumer && (\n <span id={dismissLabelId} className=\"sr-only\">\n {dismissLabel}\n </span>\n )}\n {hasContent ? (\n <span\n id={contentId}\n ref={setLabelTarget}\n className={cn(\n interactionTagSecondaryClassNames.dismissIcon,\n 'inline-flex items-center justify-center',\n // A text label keeps clear of the divider and the tag's end; a glyph needs no room.\n hasLabel && INTERACTION_TAG_SECONDARY_LABEL_CLASSES,\n )}\n >\n {content}\n </span>\n ) : (\n <DismissIcon\n size={TAG_DISMISS_GLYPH_SIZE[size]}\n className={interactionTagSecondaryClassNames.dismissIcon}\n />\n )}\n </button>\n );\n};\nInteractionTagSecondary.displayName = 'InteractionTagSecondary';\n\n// ---------------------------------------------------------------------------\n// Compound\n// ---------------------------------------------------------------------------\n\n/**\n * A tag with a main action and a separate Dismiss button: an element that holds two sibling\n * buttons, `InteractionTag.Primary` (the action) and `InteractionTag.Secondary` (Dismiss), never\n * one inside the other. Use it for a chip the user acts on (opens, toggles) and can also remove;\n * a `Tag` is a chip that only displays, or only dismisses.\n *\n * - **Two Tab stops**, the Primary then the Secondary. In a TagGroup toolbar both join its arrow\n * order (Primary, Secondary, next tag).\n * - **The Secondary is named after the Primary's text**: its `dismissLabel` plus the primary\n * text, \"Dismiss Cherry\" (never the secondary text). A text label in its children replaces\n * `dismissLabel` (\"Remove Cherry\"); an `aria-label` replaces the whole name.\n * - **Delete and Backspace** on either button dismiss the tag through the Secondary's click (a\n * held key dismisses once); without a Secondary they do nothing. Enter, Space and a click on the\n * Secondary dismiss too: remove the tag in its `onClick`, or in a TagGroup's `onDismiss(value)`,\n * which is called after it.\n * - **In a selecting TagGroup** (`value`, `defaultValue` or `onValueChange` on the group) the\n * Primary toggles the tag's `value` in the group's selection (`aria-pressed`, the selected\n * look), and dismissing a selected tag also removes its value from the selection.\n * - **`selected`**, outside a selecting TagGroup, draws the selected look and makes the Primary a\n * toggle (`aria-pressed`); leave it `undefined` for an action that is not a toggle.\n * - **Look**: `size`, `appearance` and `shape`, Tag's sizes and colours (a TagGroup gives its\n * defaults); `disabled` disables both buttons natively. The Primary takes `media` (an Avatar,\n * sized for the tag), `icon` and `secondaryText`.\n * - Fluent's `hasSecondaryAction` is not needed: the Primary squares its end corners next to a\n * Secondary by itself, also when the Secondary is rendered conditionally or wrapped.\n * - React Server Components cannot dot into a client module: import the flat names\n * `InteractionTagPrimary` and `InteractionTagSecondary` there.\n * - Renders `data-appearance`, `data-size` and `data-shape`, and while set `data-selected` and\n * `data-disabled`, on the root; `data-selected` on both buttons.\n *\n * @example\n * <InteractionTag value=\"cherry\">\n * <InteractionTag.Primary icon={<FruitIcon />} onClick={openDetails}>\n * Cherry\n * </InteractionTag.Primary>\n * <InteractionTag.Secondary onClick={() => remove('cherry')} />\n * </InteractionTag>\n */\nexport const InteractionTag = /* @__PURE__ */ Object.assign(InteractionTagRoot, {\n Primary: InteractionTagPrimary,\n Secondary: InteractionTagSecondary,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InteractionTag.cjs","names":["React","cn","INTERACTION_TAG_DISABLED_CLASSES","mergedAriaDisabledClasses","INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES","forcedColors","MERGED_DISABLED_FOCUSABLE_PROPS","useTagGroupContext","useMergedRefs","useId","tagSizeClasses","tagAppearanceClasses","tagShapeClasses","useTagGroupItem","useEventCallback","interactionTagClassNames","useHeldFocus","slotRendersContent","materialiseSlotContent","TAG_AVATAR_SIZE","isOwnEvent","isDismissKey","interactionTagPrimaryClassNames","composeEventHandlers","INTERACTION_TAG_BUTTON_BASE_CLASSES","INTERACTION_TAG_PRIMARY_BASE_CLASSES","tagStartInsetClasses","interactionTagPrimaryEndInsetClasses","interactionTagLookClasses","INTERACTION_TAG_PRIMARY_JOINED_CLASSES","focusRing","AvatarSizeContext","renderSlot","tagMediaClasses","tagIconClasses","TAG_TEXT_COLUMN_CLASSES","TAG_SECONDARY_TEXT_CLASSES","unwrapButtonGlyph","hasTextLabel","observeTextLabel","hasRenderedTextLabel","joinIds","isRepeatedActivation","interactionTagSecondaryClassNames","INTERACTION_TAG_SECONDARY_BASE_CLASSES","interactionTagSecondarySizeClasses","interactionTagDividerClasses","interactionTagSecondaryShapeClasses","DismissIcon","TAG_DISMISS_GLYPH_SIZE","require_runtime","require_cn","require_dev","require_slot","require_composeEventHandlers","require_classNames","require_useEventCallback","require_useId","require_useMergedRefs","require_aria","require_styles","require_Button_slots","require_icons","require_labelInName","require_events","require_TagGroup_context","require_Avatar_context","require_tagStyles","react","react_jsx_runtime","noop","createPrimaryRegistry","count","settled","listeners","notify","listener","onChange","INERT_PRIMARY_REGISTRY","InteractionTagContext","INERT_CONTEXT","useInteractionTagContext","componentName","isKeyOf","value","table","disabledClasses","dimDisabled","disabled","SELECTED_IN_GROUP_MESSAGE","buttonStateProps","held","InteractionTagRoot","appearanceProp","sizeProp","shapeProp","disabledProp","selectedProp","rest","group","rootRef","mergedRef","ref","secondaryRef","primaryTextId","primaries","size","appearance","shape","reportedValue","selecting","pressed","selected","look","selectedIgnored","dismiss","toggle","listItemRole","hiddenByHost","context","role","hidden","className","InteractionTagPrimary","ariaPressed","tag","hold","registerPrimary","hasMedia","media","hasIcon","icon","secondary","secondaryText","hasSecondary","avatarBox","handleClick","event","handleKeyDown","secondaryButton","primaryText","onClick","onKeyDown","onFocus","onBlur","BUTTON_CHILD_MESSAGE","InteractionTagSecondary","ariaLabel","ariaLabelledBy","dismissLabelId","contentId","ownRef","unwrapped","children","content","glyph","hasContent","literalTextLabel","labelTarget","setLabelTarget","subscribeToContent","contentHasTextLabel","hasLabel","hasPrimary","namedByConsumer","labelledBy","dismissLabel","InteractionTag"],"sources":["../../../src/components/data-display/InteractionTag.tsx"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport {\n interactionTagClassNames,\n interactionTagPrimaryClassNames,\n interactionTagSecondaryClassNames,\n} from '../../lib/classNames';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { reportMissingContext, warnOnce } from '../../lib/dev';\nimport { isOwnEvent } from '../../lib/events';\nimport { DismissIcon } from '../../lib/icons';\nimport { hasRenderedTextLabel, hasTextLabel, observeTextLabel } from '../../lib/labelInName';\nimport { materialiseSlotContent, renderSlot, slotRendersContent } from '../../lib/slot';\nimport type { Slot } from '../../lib/slot';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport type { TagAppearance, TagShape, TagSize } from '../../lib/types';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport {\n MERGED_DISABLED_FOCUSABLE_PROPS,\n mergedAriaDisabledClasses,\n unwrapButtonGlyph,\n} from '../button/Button.slots';\nimport { AvatarSizeContext } from './Avatar.context';\nimport {\n isDismissKey,\n isRepeatedActivation,\n useDismissControlFocus,\n useHeldFocus,\n useTagGroupContext,\n useTagGroupItem,\n} from './TagGroup.context';\nimport {\n INTERACTION_TAG_BUTTON_BASE_CLASSES,\n INTERACTION_TAG_DISABLED_CLASSES,\n INTERACTION_TAG_EXTRA_SMALL_HIT_CLASSES,\n INTERACTION_TAG_PRIMARY_BASE_CLASSES,\n INTERACTION_TAG_PRIMARY_JOINED_CLASSES,\n INTERACTION_TAG_SECONDARY_BASE_CLASSES,\n INTERACTION_TAG_SECONDARY_LABEL_CLASSES,\n INTERACTION_TAG_SELECTED_FORCED_COLORS,\n INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES,\n TAG_AVATAR_SIZE,\n TAG_DISMISS_GLYPH_SIZE,\n TAG_PRIMARY_TEXT_TWO_LINE_CLASSES,\n TAG_SECONDARY_TEXT_CLASSES,\n TAG_TEXT_COLUMN_CLASSES,\n interactionTagDividerClasses,\n interactionTagLookClasses,\n interactionTagPrimaryEndInsetClasses,\n interactionTagSecondaryShapeClasses,\n interactionTagSecondarySizeClasses,\n tagAppearanceClasses,\n tagIconClasses,\n tagMediaClasses,\n tagShapeClasses,\n tagSizeClasses,\n tagStartInsetClasses,\n} from './tagStyles';\nimport type { TagLook } from './tagStyles';\n\n/** Props of InteractionTag: the element that holds the Primary and Secondary buttons. */\nexport interface InteractionTagProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Identifies the tag in a TagGroup: the value `onDismiss` receives and the selection holds. Give\n * every tag of a group its own value.\n * @default a generated id (a development warning in a group that reports values)\n */\n value?: string;\n /**\n * Colour scheme of both buttons: `filled` (a neutral fill), `outline` (a border on the surface\n * behind it) or `brand` (a light brand tint that follows the brand ramp).\n * @default the TagGroup's `appearance`, else 'filled'\n */\n appearance?: TagAppearance;\n /**\n * `medium` (28px tall), `small` (24px) or `extra-small` (20px); an Avatar in the Primary's\n * `media` is 24, 20 or 16px. Fluent's medium tag is 32px.\n * @default the TagGroup's `size`, else 'medium'\n */\n size?: TagSize;\n /**\n * `circular` (a pill) or `rounded` (4px corners). Fluent's default is `rounded`.\n * @default the TagGroup's `shape`, else 'circular'\n */\n shape?: TagShape;\n /**\n * Disables both buttons natively (a disabled TagGroup does too; a part's own `disabled` cannot\n * re-enable it). A button that has focus when it is disabled keeps it, unavailable, until focus\n * leaves it. Rendered as `data-disabled` on the root.\n * @default false\n */\n disabled?: boolean;\n /**\n * Outside a selecting TagGroup: draws the selected look and makes the Primary a toggle:\n * `aria-pressed=\"true\"`, or `\"false\"` for `selected={false}`. Leave it `undefined` for an\n * action that is not a toggle (no `aria-pressed`). Inside a selecting TagGroup (`value`,\n * `defaultValue` or `onValueChange`) the group's `value` decides, and a defined `selected` is\n * ignored (a development warning). Rendered as `data-selected` on the root and both buttons.\n * Disabled wins over the selected look (`aria-pressed` and `data-selected` still render).\n * Fluent's `selected` is a look only.\n */\n selected?: boolean;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Props of InteractionTag.Primary: the tag's main action (or its toggle in a selecting TagGroup). */\nexport interface InteractionTagPrimaryProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * A visual before the text (an Avatar, sized for the tag: 24, 20 or 16px, unless it sets its\n * own `size`). Decorative (`aria-hidden`): the button is named by its text.\n */\n media?: Slot<'span'>;\n /** A decorative icon before the text (`aria-hidden`), in a 20, 16 or 12px box. */\n icon?: Slot<'span'>;\n /**\n * A second, smaller line under the text. Part of the Primary's name, not of the Secondary's. A\n * small or extra-small tag grows to 28px to fit it.\n */\n secondaryText?: React.ReactNode;\n /**\n * Disables the Primary natively; or-ed with the InteractionTag's `disabled` (it cannot\n * re-enable a disabled tag).\n * @default false\n */\n disabled?: boolean;\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n/** Props of InteractionTag.Secondary: the tag's separate Dismiss button. */\nexport interface InteractionTagSecondaryProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * Visually hidden text that names the button with the Primary's text (\"Dismiss Cherry\"). A text\n * label in the children replaces it (\"Remove Cherry\"); an `aria-label` replaces the whole name.\n * Localise it here. Fluent's order is the primary text, then the label (\"Cherry remove\").\n * @default 'Dismiss'\n */\n dismissLabel?: string;\n /**\n * Disables the Secondary natively; or-ed with the InteractionTag's `disabled` (it cannot\n * re-enable a disabled tag).\n * @default false\n */\n disabled?: boolean;\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\n/** What an InteractionTag gives its two buttons (resolved values, never `undefined` but `pressed`). */\ninterface InteractionTagContextValue {\n size: TagSize;\n shape: TagShape;\n /** The look of both buttons: the appearance, or the selected look over it. */\n look: TagLook;\n /** Whether the tag is disabled (its own `disabled`, or its TagGroup's). */\n disabled: boolean;\n /** Whether the tag is selected (`data-selected`). */\n selected: boolean;\n /** The Primary's `aria-pressed`: `undefined` for an action that is not a toggle. */\n pressed: boolean | undefined;\n /** Whether a disabled button dims itself (`false` under a host that dims the tags as a whole). */\n dimDisabled: boolean;\n /** The id of the Primary's text, the second half of the Secondary's name. */\n primaryTextId: string;\n /** Which Primaries render, so the Secondary points at the primary text only while one does. */\n primaries: PrimaryRegistry;\n /** The Secondary, which Delete and Backspace on the Primary click (read at key time). */\n secondaryRef: React.RefObject<HTMLButtonElement | null> | null;\n /**\n * Reports the dismissal to the TagGroup (its `onDismiss(value)`), after the Secondary's\n * `onClick`, and then removes the tag's value from the group's selection (D39).\n */\n dismiss: () => void;\n /** Toggles the tag's value in a selecting TagGroup's selection (the Primary's click). */\n toggle: () => void;\n}\n\nconst noop = () => {};\n\n/**\n * The Primaries an InteractionTag renders, read by its Secondary, whose name points at the\n * primary text only while a Primary renders it (no id reference to a missing element). Until the\n * root's first commit (the server render, hydration and the first client render) a Primary is\n * assumed, so the server HTML holds the whole name and a tag with a Primary renders once; a\n * Secondary without one drops the id after that commit, and takes it again when one mounts. An\n * external store (C-HOOKS): a Primary registers from a layout effect.\n */\ninterface PrimaryRegistry {\n subscribe: (onChange: () => void) => () => void;\n /** Whether the Secondary's name may point at the primary text. */\n hasPrimary: () => boolean;\n /** For a Primary's layout effect: returns its cleanup. */\n register: () => () => void;\n /** For the root's layout effect: from now on the registrations decide. */\n settle: () => void;\n}\n\nfunction createPrimaryRegistry(): PrimaryRegistry {\n let count = 0;\n let settled = false;\n const listeners = new Set<() => void>();\n const notify = () => {\n for (const listener of listeners) listener();\n };\n return {\n subscribe: (onChange) => {\n listeners.add(onChange);\n return () => {\n listeners.delete(onChange);\n };\n },\n hasPrimary: () => !settled || count > 0,\n register: () => {\n count += 1;\n notify();\n return () => {\n count -= 1;\n notify();\n };\n },\n settle: () => {\n if (settled) return;\n settled = true;\n notify();\n },\n };\n}\n\n/** The registry of the inert context: a Primary is always assumed. */\nconst INERT_PRIMARY_REGISTRY: PrimaryRegistry = {\n subscribe: () => noop,\n hasPrimary: () => true,\n register: () => noop,\n settle: noop,\n};\n\n/** Internal: `null` outside an InteractionTag. */\nconst InteractionTagContext = React.createContext<InteractionTagContextValue | null>(null);\nInteractionTagContext.displayName = 'InteractionTagContext';\n\n/** What a part reads outside an InteractionTag in production (C-CONTEXT): an enabled, unnamed tag. */\nconst INERT_CONTEXT: InteractionTagContextValue = {\n size: 'medium',\n shape: 'circular',\n look: 'filled',\n disabled: false,\n selected: false,\n pressed: undefined,\n dimDisabled: true,\n primaryTextId: '',\n primaries: INERT_PRIMARY_REGISTRY,\n secondaryRef: null,\n dismiss: () => {},\n toggle: () => {},\n};\n\nfunction useInteractionTagContext(componentName: string): InteractionTagContextValue {\n const context = React.useContext(InteractionTagContext);\n if (context) return context;\n reportMissingContext(componentName, 'InteractionTag');\n return INERT_CONTEXT;\n}\n\n/** Whether `value` is a key of `table` (an untyped value outside a union falls back). */\nfunction isKeyOf<K extends string>(\n value: unknown,\n table: Readonly<Record<K, unknown>>,\n): value is K {\n return typeof value === 'string' && Object.hasOwn(table, value);\n}\n\n/** The classes of a button's disabled states: dimmed, unless the host dims the tags itself. */\nfunction disabledClasses(disabled: boolean, dimDisabled: boolean): string {\n return cn(\n dimDisabled\n ? [INTERACTION_TAG_DISABLED_CLASSES, mergedAriaDisabledClasses]\n : INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES,\n disabled && forcedColors.disabled,\n );\n}\n\nconst SELECTED_IN_GROUP_MESSAGE =\n \"InteractionTag: `selected` has no effect in a TagGroup that selects (`value`, `defaultValue` or `onValueChange`); the group's `value` decides.\";\n\n/**\n * The state props of a tag button: natively disabled, or, while it keeps the focus it had when it\n * was disabled, the focusable disabled state (its click blocked).\n */\nfunction buttonStateProps(disabled: boolean, held: boolean) {\n if (!disabled) return undefined;\n return held ? MERGED_DISABLED_FOCUSABLE_PROPS : { disabled: true };\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\n// The InteractionTag root, documented on the exported `InteractionTag` const.\nconst InteractionTagRoot = ({\n value,\n appearance: appearanceProp,\n size: sizeProp,\n shape: shapeProp,\n disabled: disabledProp = false,\n selected: selectedProp,\n role,\n hidden,\n className,\n children,\n ref,\n ...rest\n}: InteractionTagProps) => {\n const group = useTagGroupContext();\n const rootRef = React.useRef<HTMLDivElement>(null);\n const mergedRef = useMergedRefs<HTMLDivElement>(rootRef, ref);\n const secondaryRef = React.useRef<HTMLButtonElement>(null);\n const primaryTextId = useId('interaction-tag-text');\n // After the first commit, the Primaries that registered decide the Secondary's name (D43).\n const [primaries] = React.useState(createPrimaryRegistry);\n React.useLayoutEffect(() => {\n primaries.settle();\n }, [primaries]);\n\n // The tag's own look, else its TagGroup's, else the default look.\n const size: TagSize = isKeyOf(sizeProp, tagSizeClasses) ? sizeProp : (group?.size ?? 'medium');\n const appearance: TagAppearance = isKeyOf(appearanceProp, tagAppearanceClasses)\n ? appearanceProp\n : (group?.appearance ?? 'filled');\n const shape: TagShape = isKeyOf(shapeProp, tagShapeClasses)\n ? shapeProp\n : (group?.shape ?? 'circular');\n // A disabled group disables every tag: the tag's own `disabled={false}` cannot re-enable it.\n const disabled = (group?.disabled ?? false) || disabledProp;\n const dimDisabled = group?.dimDisabled ?? true;\n\n // In a group that reports dismissals or selects, the tag's value (else a generated id).\n const reportedValue = useTagGroupItem(rootRef, value);\n // In a selecting TagGroup the group's selection decides (the Primary is always a toggle there);\n // elsewhere a boolean `selected` does, and `undefined` is an action that is no toggle.\n const selecting = group?.selecting ?? false;\n const pressed = selecting\n ? (group?.isSelected(reportedValue) ?? false)\n : typeof selectedProp === 'boolean'\n ? selectedProp\n : undefined;\n const selected = pressed === true;\n // Disabled wins over the selected look; the attributes still reflect the state.\n const look: TagLook = selected && !disabled ? 'selected' : appearance;\n\n const selectedIgnored = selecting && selectedProp !== undefined;\n React.useEffect(() => {\n if (selectedIgnored) warnOnce('InteractionTag:selected-in-group', SELECTED_IN_GROUP_MESSAGE);\n }, [selectedIgnored]);\n\n // The group's `onDismiss(value)`, then the value leaves the selection (D39), in one click.\n const dismiss = useEventCallback(() => {\n group?.dismiss(reportedValue);\n group?.deselect(reportedValue);\n });\n const toggle = useEventCallback(() => {\n group?.toggle(reportedValue);\n });\n\n // In a list TagGroup the root is a list item; the consumer's role wins.\n const listItemRole = group?.mode === 'list' ? 'listitem' : undefined;\n // A host hides the tags it counts instead of showing them (TagPicker's `overflow=\"count\"`).\n const hiddenByHost = value !== undefined && (group?.hiddenValues?.has(value) ?? false);\n\n const context = React.useMemo<InteractionTagContextValue>(\n () => ({\n size,\n shape,\n look,\n disabled,\n selected,\n pressed,\n dimDisabled,\n primaryTextId,\n primaries,\n secondaryRef,\n dismiss,\n toggle,\n }),\n [\n size,\n shape,\n look,\n disabled,\n selected,\n pressed,\n dimDisabled,\n primaryTextId,\n primaries,\n dismiss,\n toggle,\n ],\n );\n\n return (\n <InteractionTagContext.Provider value={context}>\n <div\n data-appearance={appearance}\n data-size={size}\n data-shape={shape}\n data-selected={selected ? '' : undefined}\n data-disabled={disabled ? '' : undefined}\n data-wave-tag-item=\"\"\n role={role ?? listItemRole}\n hidden={hiddenByHost || hidden}\n {...rest}\n ref={mergedRef}\n className={cn(\n interactionTagClassNames.root,\n 'group/interaction-tag inline-flex items-stretch',\n className,\n )}\n >\n {children}\n </div>\n </InteractionTagContext.Provider>\n );\n};\nInteractionTagRoot.displayName = 'InteractionTag';\n\n// ---------------------------------------------------------------------------\n// Primary\n// ---------------------------------------------------------------------------\n\n/**\n * The main action of an {@link InteractionTag}: a `<button type=\"button\">` named by its text and\n * `secondaryText` (`media` and `icon` are decorative), with the InteractionTag's look. In a\n * selecting TagGroup it is a toggle (`aria-pressed`): a click, Enter or Space adds the tag's\n * `value` to the group's selection or removes it, after its `onClick` (whose `preventDefault()`\n * cancels the toggle). Elsewhere the InteractionTag's `selected` makes it a toggle. Either state\n * renders its `aria-pressed` over one passed here, which applies only when neither is set. Delete\n * and Backspace on it click the tag's Secondary when there is one. Its props, `ref` and\n * `className` go to the button. Flat name of `InteractionTag.Primary`, for React Server\n * Components.\n */\nexport const InteractionTagPrimary = ({\n media,\n icon,\n secondaryText,\n disabled: disabledProp = false,\n 'aria-pressed': ariaPressed,\n className,\n children,\n onClick,\n onKeyDown,\n onFocus,\n onBlur,\n ref,\n ...rest\n}: InteractionTagPrimaryProps) => {\n const tag = useInteractionTagContext('InteractionTag.Primary');\n const { size, look, shape } = tag;\n const disabled = tag.disabled || disabledProp;\n const hold = useHeldFocus(disabled);\n // Its text names the Secondary while it renders (D43).\n const registerPrimary = tag.primaries.register;\n React.useLayoutEffect(() => registerPrimary(), [registerPrimary]);\n\n // Slots that render nothing render no element and take no room.\n const hasMedia = slotRendersContent(media);\n const hasIcon = slotRendersContent(icon);\n const secondary = materialiseSlotContent(secondaryText);\n const hasSecondary = slotRendersContent(secondary);\n const avatarBox = React.useMemo(\n () => ({\n size: TAG_AVATAR_SIZE[size],\n shape: shape === 'rounded' ? ('square' as const) : ('circular' as const),\n }),\n [size, shape],\n );\n\n // In a selecting TagGroup a click (also Enter and Space) toggles the tag's value, after the\n // consumer's `onClick`; never for a click from a portal opened from the Primary (C-COMPOSE).\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (!disabled && isOwnEvent(event)) tag.toggle();\n };\n\n // Delete and Backspace dismiss the tag through the Secondary's own click, so whatever cancels\n // that click (its `onClick`'s `preventDefault()`, a disabled or held Secondary) cancels them\n // too. Not from a portal opened from the Primary, and not while the Primary itself is held.\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (disabled || event.target !== event.currentTarget || !isDismissKey(event)) return;\n const secondaryButton = tag.secondaryRef?.current;\n if (!secondaryButton || secondaryButton.disabled) return;\n event.preventDefault();\n secondaryButton.click();\n };\n\n const primaryText = (\n <span\n id={tag.primaryTextId || undefined}\n className={cn(\n interactionTagPrimaryClassNames.primaryText,\n hasSecondary && TAG_PRIMARY_TEXT_TWO_LINE_CLASSES,\n )}\n >\n {children}\n </span>\n );\n\n return (\n <button\n type=\"button\"\n // The tag's state (`selected`, or a selecting TagGroup's value) decides; a consumer\n // `aria-pressed` applies only to a Primary that is no toggle of the tag's.\n aria-pressed={tag.pressed ?? ariaPressed}\n data-selected={tag.selected ? '' : undefined}\n {...rest}\n ref={ref}\n onClick={composeEventHandlers(onClick, handleClick)}\n // After `onClick`: a held Primary's click is blocked, the toggle included.\n {...buttonStateProps(disabled, hold.held)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onFocus={composeEventHandlers(onFocus, hold.onFocus, { checkDefaultPrevented: false })}\n onBlur={composeEventHandlers(onBlur, hold.onBlur, { checkDefaultPrevented: false })}\n className={cn(\n interactionTagPrimaryClassNames.root,\n INTERACTION_TAG_BUTTON_BASE_CLASSES,\n INTERACTION_TAG_PRIMARY_BASE_CLASSES,\n tagSizeClasses[size],\n tagStartInsetClasses[size][hasMedia ? 'media' : hasIcon ? 'icon' : 'text'],\n interactionTagPrimaryEndInsetClasses[size],\n interactionTagLookClasses[look],\n look === 'selected' && [\n forcedColors.selectedContainer,\n INTERACTION_TAG_SELECTED_FORCED_COLORS,\n ],\n tagShapeClasses[tag.shape],\n INTERACTION_TAG_PRIMARY_JOINED_CLASSES,\n disabledClasses(disabled, tag.dimDisabled),\n focusRing,\n size === 'extra-small' && INTERACTION_TAG_EXTRA_SMALL_HIT_CLASSES,\n className,\n )}\n >\n {hasMedia && (\n // An Avatar without its own `size` takes the tag's box.\n <AvatarSizeContext.Provider value={avatarBox}>\n {renderSlot(\n media,\n 'span',\n cn(interactionTagPrimaryClassNames.media, tagMediaClasses[size]),\n { 'aria-hidden': true },\n )}\n </AvatarSizeContext.Provider>\n )}\n {hasIcon &&\n renderSlot(icon, 'span', cn(interactionTagPrimaryClassNames.icon, tagIconClasses[size]), {\n 'aria-hidden': true,\n })}\n {hasSecondary ? (\n <span className={TAG_TEXT_COLUMN_CLASSES}>\n {primaryText}\n {/* A space between the two texts in the button's name (\"Katri Designer\"), whatever a\n name computation makes of the column; the column layout never renders it. */}{' '}\n <span\n className={cn(\n interactionTagPrimaryClassNames.secondaryText,\n TAG_SECONDARY_TEXT_CLASSES,\n )}\n >\n {secondary}\n </span>\n </span>\n ) : (\n primaryText\n )}\n </button>\n );\n};\nInteractionTagPrimary.displayName = 'InteractionTagPrimary';\n\n// ---------------------------------------------------------------------------\n// Secondary\n// ---------------------------------------------------------------------------\n\nconst BUTTON_CHILD_MESSAGE =\n \"InteractionTag.Secondary: its content received a button. A button cannot contain a button: its children became the content of the Dismiss button and its props were dropped. Pass icon content, and handle the dismissal in `onClick` or in the TagGroup's `onDismiss`.\";\n\n/**\n * The separate Dismiss button of an {@link InteractionTag}: a `<button type=\"button\">` after the\n * Primary, named `dismissLabel` plus the Primary's text (\"Dismiss Cherry\"). Its children replace\n * the default dismiss glyph; a text label among them replaces `dismissLabel` in the name (\"Remove\n * Cherry\"), an `aria-label` the whole name. A button passed as its child is unwrapped (its children\n * become the content). Enter, Space, a click, Delete and Backspace call its `onClick`, then, in a\n * TagGroup, the group's `onDismiss(value)`. Its props, `ref` and `className` go to the button.\n * Flat name of `InteractionTag.Secondary`, for React Server Components.\n */\nexport const InteractionTagSecondary = ({\n dismissLabel = 'Dismiss',\n disabled: disabledProp = false,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className,\n children,\n onClick,\n onKeyDown,\n onFocus,\n onBlur,\n ref,\n ...rest\n}: InteractionTagSecondaryProps) => {\n const tag = useInteractionTagContext('InteractionTag.Secondary');\n const { size, look } = tag;\n const disabled = tag.disabled || disabledProp;\n const hold = useHeldFocus(disabled);\n const dismissLabelId = useId('interaction-tag-dismiss');\n const contentId = useId('interaction-tag-dismiss-content');\n const ownRef = React.useRef<HTMLButtonElement>(null);\n const mergedRef = useMergedRefs<HTMLButtonElement>(ownRef, tag.secondaryRef, ref);\n // Unmounting while it has focus (rendered conditionally), the Secondary hands focus to its own\n // tag's Primary; in a TagGroup, when the whole tag goes, the tag's own move applies (D35).\n useDismissControlFocus(ownRef);\n\n // Its children are the glyph inside the Dismiss button: a button there would nest buttons, so\n // it is unwrapped (C-SLOTS glyph rule).\n const { glyph, button: unwrapped } = unwrapButtonGlyph(children as Slot<'span'>);\n React.useEffect(() => {\n if (unwrapped) warnOnce('InteractionTag.Secondary:button-child', BUTTON_CHILD_MESSAGE);\n }, [unwrapped]);\n const content = materialiseSlotContent(glyph);\n const hasContent = slotRendersContent(content);\n const literalTextLabel = hasContent && hasTextLabel(content);\n\n // C-SLOTS naming (WCAG 2.5.3 Label in Name): a text label in the children replaces\n // `dismissLabel` (\"Remove Cherry\"). The literal children decide on the server and on the first\n // render; after mount, the rendered content does (text from components, later changes).\n const [labelTarget, setLabelTarget] = React.useState<HTMLSpanElement | null>(null);\n const subscribeToContent = React.useCallback(\n (onChange: () => void) => (labelTarget ? observeTextLabel(labelTarget, onChange) : noop),\n [labelTarget],\n );\n const contentHasTextLabel = React.useSyncExternalStore(\n subscribeToContent,\n () => (labelTarget ? hasRenderedTextLabel(labelTarget) : literalTextLabel),\n () => literalTextLabel,\n );\n const hasLabel = hasContent && contentHasTextLabel;\n // The primary text joins the name while a Primary renders it.\n const hasPrimary = React.useSyncExternalStore(\n tag.primaries.subscribe,\n tag.primaries.hasPrimary,\n () => true,\n );\n // A consumer `aria-label` replaces the whole name; a consumer `aria-labelledby` replaces ours.\n const namedByConsumer = ariaLabel !== undefined || ariaLabelledBy !== undefined;\n const labelledBy = namedByConsumer\n ? ariaLabelledBy\n : joinIds(hasLabel ? contentId : dismissLabelId, hasPrimary ? tag.primaryTextId : undefined);\n\n // The consumer's `onClick` first (its `preventDefault()` keeps the group from hearing of it),\n // then the TagGroup's `onDismiss(value)`; never for a click from a portal opened inside.\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (isOwnEvent(event)) tag.dismiss();\n };\n // Delete and Backspace dismiss as Enter does: through the button's own click, so whatever\n // cancels a click (its `onClick`'s `preventDefault()`, a held or disabled button) cancels them.\n // A held key dismisses one tag: the browser clicks a button on every repeated Enter, which\n // would reach the next tag's Dismiss control once focus moved there (D35).\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (event.target !== event.currentTarget) return;\n if (isRepeatedActivation(event)) {\n event.preventDefault();\n return;\n }\n if (!isDismissKey(event)) return;\n event.preventDefault();\n event.currentTarget.click();\n };\n\n return (\n <button\n type=\"button\"\n data-wave-tag-dismiss=\"\"\n data-selected={tag.selected ? '' : undefined}\n {...rest}\n ref={mergedRef}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n onClick={composeEventHandlers(onClick, handleClick)}\n {...buttonStateProps(disabled, hold.held)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onFocus={composeEventHandlers(onFocus, hold.onFocus, { checkDefaultPrevented: false })}\n onBlur={composeEventHandlers(onBlur, hold.onBlur, { checkDefaultPrevented: false })}\n className={cn(\n interactionTagSecondaryClassNames.root,\n INTERACTION_TAG_BUTTON_BASE_CLASSES,\n INTERACTION_TAG_SECONDARY_BASE_CLASSES,\n interactionTagSecondarySizeClasses[size],\n interactionTagLookClasses[look],\n look === 'selected' && [\n forcedColors.selectedContainer,\n INTERACTION_TAG_SELECTED_FORCED_COLORS,\n ],\n interactionTagDividerClasses[look],\n interactionTagSecondaryShapeClasses[tag.shape],\n disabledClasses(disabled, tag.dimDisabled),\n focusRing,\n size === 'extra-small' && INTERACTION_TAG_EXTRA_SMALL_HIT_CLASSES,\n className,\n )}\n >\n {!namedByConsumer && (\n <span id={dismissLabelId} className=\"sr-only\">\n {dismissLabel}\n </span>\n )}\n {hasContent ? (\n <span\n id={contentId}\n ref={setLabelTarget}\n className={cn(\n interactionTagSecondaryClassNames.dismissIcon,\n 'inline-flex items-center justify-center',\n // A text label keeps clear of the divider and the tag's end; a glyph needs no room.\n hasLabel && INTERACTION_TAG_SECONDARY_LABEL_CLASSES,\n )}\n >\n {content}\n </span>\n ) : (\n <DismissIcon\n size={TAG_DISMISS_GLYPH_SIZE[size]}\n className={interactionTagSecondaryClassNames.dismissIcon}\n />\n )}\n </button>\n );\n};\nInteractionTagSecondary.displayName = 'InteractionTagSecondary';\n\n// ---------------------------------------------------------------------------\n// Compound\n// ---------------------------------------------------------------------------\n\n/**\n * A tag with a main action and a separate Dismiss button: an element that holds two sibling\n * buttons, `InteractionTag.Primary` (the action) and `InteractionTag.Secondary` (Dismiss), never\n * one inside the other. Use it for a chip the user acts on (opens, toggles) and can also remove;\n * a `Tag` is a chip that only displays, or only dismisses.\n *\n * - **Two Tab stops**, the Primary then the Secondary. In a TagGroup toolbar both join its arrow\n * order (Primary, Secondary, next tag).\n * - **The Secondary is named after the Primary's text**: its `dismissLabel` plus the primary\n * text, \"Dismiss Cherry\" (never the secondary text). A text label in its children replaces\n * `dismissLabel` (\"Remove Cherry\"); an `aria-label` replaces the whole name.\n * - **Delete and Backspace** on either button dismiss the tag through the Secondary's click (a\n * held key dismisses once); without a Secondary they do nothing. Enter, Space and a click on the\n * Secondary dismiss too: remove the tag in its `onClick`, or in a TagGroup's `onDismiss(value)`,\n * which is called after it.\n * - **In a selecting TagGroup** (`value`, `defaultValue` or `onValueChange` on the group) the\n * Primary toggles the tag's `value` in the group's selection (`aria-pressed`, the selected\n * look), and dismissing a selected tag also removes its value from the selection.\n * - **`selected`**, outside a selecting TagGroup, draws the selected look and makes the Primary a\n * toggle (`aria-pressed`); leave it `undefined` for an action that is not a toggle.\n * - **Look**: `size`, `appearance` and `shape`, Tag's sizes and colours (a TagGroup gives its\n * defaults); `disabled` disables both buttons natively. The Primary takes `media` (an Avatar,\n * sized for the tag), `icon` and `secondaryText`.\n * - Fluent's `hasSecondaryAction` is not needed: the Primary squares its end corners next to a\n * Secondary by itself, also when the Secondary is rendered conditionally or wrapped.\n * - React Server Components cannot dot into a client module: import the flat names\n * `InteractionTagPrimary` and `InteractionTagSecondary` there.\n * - Renders `data-appearance`, `data-size` and `data-shape`, and while set `data-selected` and\n * `data-disabled`, on the root; `data-selected` on both buttons.\n *\n * @example\n * <InteractionTag value=\"cherry\">\n * <InteractionTag.Primary icon={<FruitIcon />} onClick={openDetails}>\n * Cherry\n * </InteractionTag.Primary>\n * <InteractionTag.Secondary onClick={() => remove('cherry')} />\n * </InteractionTag>\n */\nexport const InteractionTag = /* @__PURE__ */ Object.assign(InteractionTagRoot, {\n Primary: InteractionTagPrimary,\n Secondary: InteractionTagSecondary,\n});\n"],"mappings":"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"}
|
|
@@ -6,9 +6,9 @@ import { composeEventHandlers as o } from "../../lib/composeEventHandlers.mjs";
|
|
|
6
6
|
import { interactionTagClassNames as s, interactionTagPrimaryClassNames as c, interactionTagSecondaryClassNames as l } from "../../lib/classNames.mjs";
|
|
7
7
|
import { useEventCallback as u } from "../../hooks/useEventCallback.mjs";
|
|
8
8
|
import { useId as d } from "../../hooks/useId.mjs";
|
|
9
|
-
import { useMergedRefs as
|
|
10
|
-
import { joinIds as
|
|
11
|
-
import { focusRing as
|
|
9
|
+
import { useMergedRefs as ee } from "../../hooks/useMergedRefs.mjs";
|
|
10
|
+
import { joinIds as te } from "../../lib/aria.mjs";
|
|
11
|
+
import { focusRing as f, forcedColors as p } from "../../lib/styles.mjs";
|
|
12
12
|
import { MERGED_DISABLED_FOCUSABLE_PROPS as m, mergedAriaDisabledClasses as h, unwrapButtonGlyph as g } from "../button/Button.slots.mjs";
|
|
13
13
|
import { DismissIcon as _ } from "../../lib/icons.mjs";
|
|
14
14
|
import { hasRenderedTextLabel as v, hasTextLabel as y, observeTextLabel as b } from "../../lib/labelInName.mjs";
|
|
@@ -71,8 +71,8 @@ var fe = "InteractionTag: `selected` has no effect in a TagGroup that selects (`
|
|
|
71
71
|
function pe(e, t) {
|
|
72
72
|
if (e) return t ? m : { disabled: !0 };
|
|
73
73
|
}
|
|
74
|
-
var Z = ({ value: t, appearance: r, size: i, shape: a, disabled: o = !1, selected: c, role: l, hidden:
|
|
75
|
-
let g = E(), _ = W.useRef(null), v =
|
|
74
|
+
var Z = ({ value: t, appearance: r, size: i, shape: a, disabled: o = !1, selected: c, role: l, hidden: te, className: f, children: p, ref: m, ...h }) => {
|
|
75
|
+
let g = E(), _ = W.useRef(null), v = ee(_, m), y = W.useRef(null), b = d("interaction-tag-text"), [x] = W.useState(J);
|
|
76
76
|
W.useLayoutEffect(() => {
|
|
77
77
|
x.settle();
|
|
78
78
|
}, [x]);
|
|
@@ -120,28 +120,31 @@ var Z = ({ value: t, appearance: r, size: i, shape: a, disabled: o = !1, selecte
|
|
|
120
120
|
"data-disabled": T ? "" : void 0,
|
|
121
121
|
"data-wave-tag-item": "",
|
|
122
122
|
role: l ?? L,
|
|
123
|
-
hidden: R ||
|
|
123
|
+
hidden: R || te,
|
|
124
124
|
...h,
|
|
125
125
|
ref: v,
|
|
126
|
-
className: e(s.root, "group/interaction-tag inline-flex items-stretch",
|
|
126
|
+
className: e(s.root, "group/interaction-tag inline-flex items-stretch", f),
|
|
127
127
|
children: p
|
|
128
128
|
})
|
|
129
129
|
});
|
|
130
130
|
};
|
|
131
131
|
Z.displayName = "InteractionTag";
|
|
132
|
-
var Q = ({ media: t, icon: n, secondaryText: s, disabled: l = !1, "aria-pressed": u, className: d, children:
|
|
133
|
-
let y = ue("InteractionTag.Primary"), { size: b, look: C } = y,
|
|
134
|
-
W.useLayoutEffect(() =>
|
|
135
|
-
let
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
132
|
+
var Q = ({ media: t, icon: n, secondaryText: s, disabled: l = !1, "aria-pressed": u, className: d, children: ee, onClick: te, onKeyDown: m, onFocus: h, onBlur: g, ref: _, ...v }) => {
|
|
133
|
+
let y = ue("InteractionTag.Primary"), { size: b, look: C, shape: w } = y, E = y.disabled || l, D = T(E), A = y.primaries.register;
|
|
134
|
+
W.useLayoutEffect(() => A(), [A]);
|
|
135
|
+
let N = a(t), P = a(n), I = r(s), z = a(I), re = W.useMemo(() => ({
|
|
136
|
+
size: F[b],
|
|
137
|
+
shape: w === "rounded" ? "square" : "circular"
|
|
138
|
+
}), [b, w]), ie = (e) => {
|
|
139
|
+
!E && x(e) && y.toggle();
|
|
140
|
+
}, V = (e) => {
|
|
141
|
+
if (E || e.target !== e.currentTarget || !S(e)) return;
|
|
139
142
|
let t = y.secondaryRef?.current;
|
|
140
143
|
t && !t.disabled && (e.preventDefault(), t.click());
|
|
141
|
-
},
|
|
144
|
+
}, q = /* @__PURE__ */ G("span", {
|
|
142
145
|
id: y.primaryTextId || void 0,
|
|
143
|
-
className: e(c.primaryText,
|
|
144
|
-
children:
|
|
146
|
+
className: e(c.primaryText, z && "text-caption-1 leading-3.5"),
|
|
147
|
+
children: ee
|
|
145
148
|
});
|
|
146
149
|
return /* @__PURE__ */ K("button", {
|
|
147
150
|
type: "button",
|
|
@@ -149,41 +152,41 @@ var Q = ({ media: t, icon: n, secondaryText: s, disabled: l = !1, "aria-pressed"
|
|
|
149
152
|
"data-selected": y.selected ? "" : void 0,
|
|
150
153
|
...v,
|
|
151
154
|
ref: _,
|
|
152
|
-
onClick: o(
|
|
153
|
-
...pe(
|
|
154
|
-
onKeyDown: o(m,
|
|
155
|
-
onFocus: o(h,
|
|
156
|
-
onBlur: o(g,
|
|
157
|
-
className: e(c.root, k, j, H[b], U[b][
|
|
155
|
+
onClick: o(te, ie),
|
|
156
|
+
...pe(E, D.held),
|
|
157
|
+
onKeyDown: o(m, V),
|
|
158
|
+
onFocus: o(h, D.onFocus, { checkDefaultPrevented: !1 }),
|
|
159
|
+
onBlur: o(g, D.onBlur, { checkDefaultPrevented: !1 }),
|
|
160
|
+
className: e(c.root, k, j, H[b], U[b][N ? "media" : P ? "icon" : "text"], B[b], ne[C], C === "selected" && [p.selectedContainer, "forced-colors:border-[Highlight]"], se[y.shape], M, de(E, y.dimDisabled), f, b === "extra-small" && "before:absolute before:inset-x-0 before:-inset-y-0.5", d),
|
|
158
161
|
children: [
|
|
159
|
-
|
|
160
|
-
value:
|
|
162
|
+
N && /* @__PURE__ */ G(O.Provider, {
|
|
163
|
+
value: re,
|
|
161
164
|
children: i(t, "span", e(c.media, oe[b]), { "aria-hidden": !0 })
|
|
162
165
|
}),
|
|
163
|
-
|
|
164
|
-
|
|
166
|
+
P && i(n, "span", e(c.icon, ae[b]), { "aria-hidden": !0 }),
|
|
167
|
+
z ? /* @__PURE__ */ K("span", {
|
|
165
168
|
className: R,
|
|
166
169
|
children: [
|
|
167
|
-
|
|
170
|
+
q,
|
|
168
171
|
" ",
|
|
169
172
|
/* @__PURE__ */ G("span", {
|
|
170
173
|
className: e(c.secondaryText, L),
|
|
171
|
-
children:
|
|
174
|
+
children: I
|
|
172
175
|
})
|
|
173
176
|
]
|
|
174
|
-
}) :
|
|
177
|
+
}) : q
|
|
175
178
|
]
|
|
176
179
|
});
|
|
177
180
|
};
|
|
178
181
|
Q.displayName = "InteractionTagPrimary";
|
|
179
182
|
var me = "InteractionTag.Secondary: its content received a button. A button cannot contain a button: its children became the content of the Dismiss button and its props were dropped. Pass icon content, and handle the dismissal in `onClick` or in the TagGroup's `onDismiss`.", $ = ({ dismissLabel: t = "Dismiss", disabled: i = !1, "aria-label": s, "aria-labelledby": c, className: u, children: m, onClick: h, onKeyDown: E, onFocus: D, onBlur: O, ref: A, ...j }) => {
|
|
180
|
-
let M = ue("InteractionTag.Secondary"), { size: P, look: F } = M, L = M.disabled || i, R = T(L), B = d("interaction-tag-dismiss"), V = d("interaction-tag-dismiss-content"), ae = W.useRef(null), oe =
|
|
183
|
+
let M = ue("InteractionTag.Secondary"), { size: P, look: F } = M, L = M.disabled || i, R = T(L), B = d("interaction-tag-dismiss"), V = d("interaction-tag-dismiss-content"), ae = W.useRef(null), oe = ee(ae, M.secondaryRef, A);
|
|
181
184
|
w(ae);
|
|
182
185
|
let { glyph: se, button: H } = g(m);
|
|
183
186
|
W.useEffect(() => {
|
|
184
187
|
H && n("InteractionTag.Secondary:button-child", me);
|
|
185
188
|
}, [H]);
|
|
186
|
-
let U = r(se), J = a(U), ce = J && y(U), [Y, le] = W.useState(null), X = W.useCallback((e) => Y ? b(Y, e) : q, [Y]), fe = W.useSyncExternalStore(X, () => Y ? v(Y) : ce, () => ce), Z = J && fe, Q = W.useSyncExternalStore(M.primaries.subscribe, M.primaries.hasPrimary, () => !0), $ = s !== void 0 || c !== void 0, he = $ ? c :
|
|
189
|
+
let U = r(se), J = a(U), ce = J && y(U), [Y, le] = W.useState(null), X = W.useCallback((e) => Y ? b(Y, e) : q, [Y]), fe = W.useSyncExternalStore(X, () => Y ? v(Y) : ce, () => ce), Z = J && fe, Q = W.useSyncExternalStore(M.primaries.subscribe, M.primaries.hasPrimary, () => !0), $ = s !== void 0 || c !== void 0, he = $ ? c : te(Z ? V : B, Q ? M.primaryTextId : void 0), ge = (e) => {
|
|
187
190
|
x(e) && M.dismiss();
|
|
188
191
|
}, _e = (e) => {
|
|
189
192
|
if (e.target === e.currentTarget) {
|
|
@@ -207,7 +210,7 @@ var me = "InteractionTag.Secondary: its content received a button. A button cann
|
|
|
207
210
|
onKeyDown: o(E, _e),
|
|
208
211
|
onFocus: o(D, R.onFocus, { checkDefaultPrevented: !1 }),
|
|
209
212
|
onBlur: o(O, R.onBlur, { checkDefaultPrevented: !1 }),
|
|
210
|
-
className: e(l.root, k, N, ie[P], ne[F], F === "selected" && [p.selectedContainer, "forced-colors:border-[Highlight]"], z[F], re[M.shape], de(L, M.dimDisabled),
|
|
213
|
+
className: e(l.root, k, N, ie[P], ne[F], F === "selected" && [p.selectedContainer, "forced-colors:border-[Highlight]"], z[F], re[M.shape], de(L, M.dimDisabled), f, P === "extra-small" && "before:absolute before:inset-x-0 before:-inset-y-0.5", u),
|
|
211
214
|
children: [!$ && /* @__PURE__ */ G("span", {
|
|
212
215
|
id: B,
|
|
213
216
|
className: "sr-only",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InteractionTag.mjs","names":["useId","useId$1","React","noop","createPrimaryRegistry","count","settled","listeners","notify","listener","onChange","INERT_PRIMARY_REGISTRY","InteractionTagContext","INERT_CONTEXT","useInteractionTagContext","reportMissingContext","componentName","isKeyOf","value","table","disabledClasses","cn","dimDisabled","INTERACTION_TAG_DISABLED_CLASSES","mergedAriaDisabledClasses","INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES","disabled","forcedColors","SELECTED_IN_GROUP_MESSAGE","buttonStateProps","held","MERGED_DISABLED_FOCUSABLE_PROPS","InteractionTagRoot","appearanceProp","sizeProp","shapeProp","disabledProp","selectedProp","rest","group","useTagGroupContext","rootRef","mergedRef","useMergedRefs","ref","secondaryRef","primaryTextId","primaries","size","tagSizeClasses","appearance","tagAppearanceClasses","shape","tagShapeClasses","reportedValue","useTagGroupItem","selecting","pressed","selected","look","selectedIgnored","warnOnce","dismiss","useEventCallback","toggle","listItemRole","hiddenByHost","context","role","hidden","interactionTagClassNames","className","InteractionTagPrimary","ariaPressed","tag","hold","useHeldFocus","registerPrimary","hasMedia","slotRendersContent","media","hasIcon","icon","secondary","materialiseSlotContent","secondaryText","hasSecondary","avatarBox","TAG_AVATAR_SIZE","handleClick","isOwnEvent","event","handleKeyDown","isDismissKey","secondaryButton","primaryText","interactionTagPrimaryClassNames","composeEventHandlers","onClick","onKeyDown","onFocus","onBlur","INTERACTION_TAG_BUTTON_BASE_CLASSES","INTERACTION_TAG_PRIMARY_BASE_CLASSES","tagStartInsetClasses","interactionTagPrimaryEndInsetClasses","interactionTagLookClasses","INTERACTION_TAG_PRIMARY_JOINED_CLASSES","focusRing","AvatarSizeContext","renderSlot","tagMediaClasses","tagIconClasses","TAG_TEXT_COLUMN_CLASSES","TAG_SECONDARY_TEXT_CLASSES","BUTTON_CHILD_MESSAGE","InteractionTagSecondary","ariaLabel","ariaLabelledBy","dismissLabelId","contentId","ownRef","unwrapped","unwrapButtonGlyph","children","content","glyph","hasContent","literalTextLabel","hasTextLabel","labelTarget","setLabelTarget","subscribeToContent","observeTextLabel","contentHasTextLabel","hasRenderedTextLabel","hasLabel","hasPrimary","namedByConsumer","labelledBy","joinIds","isRepeatedActivation","interactionTagSecondaryClassNames","INTERACTION_TAG_SECONDARY_BASE_CLASSES","interactionTagSecondarySizeClasses","interactionTagDividerClasses","interactionTagSecondaryShapeClasses","dismissLabel","DismissIcon","TAG_DISMISS_GLYPH_SIZE","InteractionTag"],"sources":["../../../src/components/data-display/InteractionTag.tsx"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport {\n interactionTagClassNames,\n interactionTagPrimaryClassNames,\n interactionTagSecondaryClassNames,\n} from '../../lib/classNames';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { reportMissingContext, warnOnce } from '../../lib/dev';\nimport { isOwnEvent } from '../../lib/events';\nimport { DismissIcon } from '../../lib/icons';\nimport { hasRenderedTextLabel, hasTextLabel, observeTextLabel } from '../../lib/labelInName';\nimport { materialiseSlotContent, renderSlot, slotRendersContent } from '../../lib/slot';\nimport type { Slot } from '../../lib/slot';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport type { TagAppearance, TagShape, TagSize } from '../../lib/types';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport {\n MERGED_DISABLED_FOCUSABLE_PROPS,\n mergedAriaDisabledClasses,\n unwrapButtonGlyph,\n} from '../button/Button.slots';\nimport { AvatarSizeContext } from './Avatar.context';\nimport {\n isDismissKey,\n isRepeatedActivation,\n useDismissControlFocus,\n useHeldFocus,\n useTagGroupContext,\n useTagGroupItem,\n} from './TagGroup.context';\nimport {\n INTERACTION_TAG_BUTTON_BASE_CLASSES,\n INTERACTION_TAG_DISABLED_CLASSES,\n INTERACTION_TAG_EXTRA_SMALL_HIT_CLASSES,\n INTERACTION_TAG_PRIMARY_BASE_CLASSES,\n INTERACTION_TAG_PRIMARY_JOINED_CLASSES,\n INTERACTION_TAG_SECONDARY_BASE_CLASSES,\n INTERACTION_TAG_SECONDARY_LABEL_CLASSES,\n INTERACTION_TAG_SELECTED_FORCED_COLORS,\n INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES,\n TAG_AVATAR_SIZE,\n TAG_DISMISS_GLYPH_SIZE,\n TAG_PRIMARY_TEXT_TWO_LINE_CLASSES,\n TAG_SECONDARY_TEXT_CLASSES,\n TAG_TEXT_COLUMN_CLASSES,\n interactionTagDividerClasses,\n interactionTagLookClasses,\n interactionTagPrimaryEndInsetClasses,\n interactionTagSecondaryShapeClasses,\n interactionTagSecondarySizeClasses,\n tagAppearanceClasses,\n tagIconClasses,\n tagMediaClasses,\n tagShapeClasses,\n tagSizeClasses,\n tagStartInsetClasses,\n} from './tagStyles';\nimport type { TagLook } from './tagStyles';\n\n/** Props of InteractionTag: the element that holds the Primary and Secondary buttons. */\nexport interface InteractionTagProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Identifies the tag in a TagGroup: the value `onDismiss` receives and the selection holds. Give\n * every tag of a group its own value.\n * @default a generated id (a development warning in a group that reports values)\n */\n value?: string;\n /**\n * Colour scheme of both buttons: `filled` (a neutral fill), `outline` (a border on the surface\n * behind it) or `brand` (a light brand tint that follows the brand ramp).\n * @default the TagGroup's `appearance`, else 'filled'\n */\n appearance?: TagAppearance;\n /**\n * `medium` (28px tall), `small` (24px) or `extra-small` (20px); an Avatar in the Primary's\n * `media` is 24, 20 or 16px. Fluent's medium tag is 32px.\n * @default the TagGroup's `size`, else 'medium'\n */\n size?: TagSize;\n /**\n * `circular` (a pill) or `rounded` (4px corners). Fluent's default is `rounded`.\n * @default the TagGroup's `shape`, else 'circular'\n */\n shape?: TagShape;\n /**\n * Disables both buttons natively (a disabled TagGroup does too; a part's own `disabled` cannot\n * re-enable it). A button that has focus when it is disabled keeps it, unavailable, until focus\n * leaves it. Rendered as `data-disabled` on the root.\n * @default false\n */\n disabled?: boolean;\n /**\n * Outside a selecting TagGroup: draws the selected look and makes the Primary a toggle:\n * `aria-pressed=\"true\"`, or `\"false\"` for `selected={false}`. Leave it `undefined` for an\n * action that is not a toggle (no `aria-pressed`). Inside a selecting TagGroup (`value`,\n * `defaultValue` or `onValueChange`) the group's `value` decides, and a defined `selected` is\n * ignored (a development warning). Rendered as `data-selected` on the root and both buttons.\n * Disabled wins over the selected look (`aria-pressed` and `data-selected` still render).\n * Fluent's `selected` is a look only.\n */\n selected?: boolean;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Props of InteractionTag.Primary: the tag's main action (or its toggle in a selecting TagGroup). */\nexport interface InteractionTagPrimaryProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * A visual before the text (an Avatar, sized for the tag: 24, 20 or 16px, unless it sets its\n * own `size`). Decorative (`aria-hidden`): the button is named by its text.\n */\n media?: Slot<'span'>;\n /** A decorative icon before the text (`aria-hidden`), in a 20, 16 or 12px box. */\n icon?: Slot<'span'>;\n /**\n * A second, smaller line under the text. Part of the Primary's name, not of the Secondary's. A\n * small or extra-small tag grows to 28px to fit it.\n */\n secondaryText?: React.ReactNode;\n /**\n * Disables the Primary natively; or-ed with the InteractionTag's `disabled` (it cannot\n * re-enable a disabled tag).\n * @default false\n */\n disabled?: boolean;\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n/** Props of InteractionTag.Secondary: the tag's separate Dismiss button. */\nexport interface InteractionTagSecondaryProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * Visually hidden text that names the button with the Primary's text (\"Dismiss Cherry\"). A text\n * label in the children replaces it (\"Remove Cherry\"); an `aria-label` replaces the whole name.\n * Localise it here. Fluent's order is the primary text, then the label (\"Cherry remove\").\n * @default 'Dismiss'\n */\n dismissLabel?: string;\n /**\n * Disables the Secondary natively; or-ed with the InteractionTag's `disabled` (it cannot\n * re-enable a disabled tag).\n * @default false\n */\n disabled?: boolean;\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\n/** What an InteractionTag gives its two buttons (resolved values, never `undefined` but `pressed`). */\ninterface InteractionTagContextValue {\n size: TagSize;\n shape: TagShape;\n /** The look of both buttons: the appearance, or the selected look over it. */\n look: TagLook;\n /** Whether the tag is disabled (its own `disabled`, or its TagGroup's). */\n disabled: boolean;\n /** Whether the tag is selected (`data-selected`). */\n selected: boolean;\n /** The Primary's `aria-pressed`: `undefined` for an action that is not a toggle. */\n pressed: boolean | undefined;\n /** Whether a disabled button dims itself (`false` under a host that dims the tags as a whole). */\n dimDisabled: boolean;\n /** The id of the Primary's text, the second half of the Secondary's name. */\n primaryTextId: string;\n /** Which Primaries render, so the Secondary points at the primary text only while one does. */\n primaries: PrimaryRegistry;\n /** The Secondary, which Delete and Backspace on the Primary click (read at key time). */\n secondaryRef: React.RefObject<HTMLButtonElement | null> | null;\n /**\n * Reports the dismissal to the TagGroup (its `onDismiss(value)`), after the Secondary's\n * `onClick`, and then removes the tag's value from the group's selection (D39).\n */\n dismiss: () => void;\n /** Toggles the tag's value in a selecting TagGroup's selection (the Primary's click). */\n toggle: () => void;\n}\n\nconst noop = () => {};\n\n/**\n * The Primaries an InteractionTag renders, read by its Secondary, whose name points at the\n * primary text only while a Primary renders it (no id reference to a missing element). Until the\n * root's first commit (the server render, hydration and the first client render) a Primary is\n * assumed, so the server HTML holds the whole name and a tag with a Primary renders once; a\n * Secondary without one drops the id after that commit, and takes it again when one mounts. An\n * external store (C-HOOKS): a Primary registers from a layout effect.\n */\ninterface PrimaryRegistry {\n subscribe: (onChange: () => void) => () => void;\n /** Whether the Secondary's name may point at the primary text. */\n hasPrimary: () => boolean;\n /** For a Primary's layout effect: returns its cleanup. */\n register: () => () => void;\n /** For the root's layout effect: from now on the registrations decide. */\n settle: () => void;\n}\n\nfunction createPrimaryRegistry(): PrimaryRegistry {\n let count = 0;\n let settled = false;\n const listeners = new Set<() => void>();\n const notify = () => {\n for (const listener of listeners) listener();\n };\n return {\n subscribe: (onChange) => {\n listeners.add(onChange);\n return () => {\n listeners.delete(onChange);\n };\n },\n hasPrimary: () => !settled || count > 0,\n register: () => {\n count += 1;\n notify();\n return () => {\n count -= 1;\n notify();\n };\n },\n settle: () => {\n if (settled) return;\n settled = true;\n notify();\n },\n };\n}\n\n/** The registry of the inert context: a Primary is always assumed. */\nconst INERT_PRIMARY_REGISTRY: PrimaryRegistry = {\n subscribe: () => noop,\n hasPrimary: () => true,\n register: () => noop,\n settle: noop,\n};\n\n/** Internal: `null` outside an InteractionTag. */\nconst InteractionTagContext = React.createContext<InteractionTagContextValue | null>(null);\nInteractionTagContext.displayName = 'InteractionTagContext';\n\n/** What a part reads outside an InteractionTag in production (C-CONTEXT): an enabled, unnamed tag. */\nconst INERT_CONTEXT: InteractionTagContextValue = {\n size: 'medium',\n shape: 'circular',\n look: 'filled',\n disabled: false,\n selected: false,\n pressed: undefined,\n dimDisabled: true,\n primaryTextId: '',\n primaries: INERT_PRIMARY_REGISTRY,\n secondaryRef: null,\n dismiss: () => {},\n toggle: () => {},\n};\n\nfunction useInteractionTagContext(componentName: string): InteractionTagContextValue {\n const context = React.useContext(InteractionTagContext);\n if (context) return context;\n reportMissingContext(componentName, 'InteractionTag');\n return INERT_CONTEXT;\n}\n\n/** Whether `value` is a key of `table` (an untyped value outside a union falls back). */\nfunction isKeyOf<K extends string>(\n value: unknown,\n table: Readonly<Record<K, unknown>>,\n): value is K {\n return typeof value === 'string' && Object.hasOwn(table, value);\n}\n\n/** The classes of a button's disabled states: dimmed, unless the host dims the tags itself. */\nfunction disabledClasses(disabled: boolean, dimDisabled: boolean): string {\n return cn(\n dimDisabled\n ? [INTERACTION_TAG_DISABLED_CLASSES, mergedAriaDisabledClasses]\n : INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES,\n disabled && forcedColors.disabled,\n );\n}\n\nconst SELECTED_IN_GROUP_MESSAGE =\n \"InteractionTag: `selected` has no effect in a TagGroup that selects (`value`, `defaultValue` or `onValueChange`); the group's `value` decides.\";\n\n/**\n * The state props of a tag button: natively disabled, or, while it keeps the focus it had when it\n * was disabled, the focusable disabled state (its click blocked).\n */\nfunction buttonStateProps(disabled: boolean, held: boolean) {\n if (!disabled) return undefined;\n return held ? MERGED_DISABLED_FOCUSABLE_PROPS : { disabled: true };\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\n// The InteractionTag root, documented on the exported `InteractionTag` const.\nconst InteractionTagRoot = ({\n value,\n appearance: appearanceProp,\n size: sizeProp,\n shape: shapeProp,\n disabled: disabledProp = false,\n selected: selectedProp,\n role,\n hidden,\n className,\n children,\n ref,\n ...rest\n}: InteractionTagProps) => {\n const group = useTagGroupContext();\n const rootRef = React.useRef<HTMLDivElement>(null);\n const mergedRef = useMergedRefs<HTMLDivElement>(rootRef, ref);\n const secondaryRef = React.useRef<HTMLButtonElement>(null);\n const primaryTextId = useId('interaction-tag-text');\n // After the first commit, the Primaries that registered decide the Secondary's name (D43).\n const [primaries] = React.useState(createPrimaryRegistry);\n React.useLayoutEffect(() => {\n primaries.settle();\n }, [primaries]);\n\n // The tag's own look, else its TagGroup's, else the default look.\n const size: TagSize = isKeyOf(sizeProp, tagSizeClasses) ? sizeProp : (group?.size ?? 'medium');\n const appearance: TagAppearance = isKeyOf(appearanceProp, tagAppearanceClasses)\n ? appearanceProp\n : (group?.appearance ?? 'filled');\n const shape: TagShape = isKeyOf(shapeProp, tagShapeClasses)\n ? shapeProp\n : (group?.shape ?? 'circular');\n // A disabled group disables every tag: the tag's own `disabled={false}` cannot re-enable it.\n const disabled = (group?.disabled ?? false) || disabledProp;\n const dimDisabled = group?.dimDisabled ?? true;\n\n // In a group that reports dismissals or selects, the tag's value (else a generated id).\n const reportedValue = useTagGroupItem(rootRef, value);\n // In a selecting TagGroup the group's selection decides (the Primary is always a toggle there);\n // elsewhere a boolean `selected` does, and `undefined` is an action that is no toggle.\n const selecting = group?.selecting ?? false;\n const pressed = selecting\n ? (group?.isSelected(reportedValue) ?? false)\n : typeof selectedProp === 'boolean'\n ? selectedProp\n : undefined;\n const selected = pressed === true;\n // Disabled wins over the selected look; the attributes still reflect the state.\n const look: TagLook = selected && !disabled ? 'selected' : appearance;\n\n const selectedIgnored = selecting && selectedProp !== undefined;\n React.useEffect(() => {\n if (selectedIgnored) warnOnce('InteractionTag:selected-in-group', SELECTED_IN_GROUP_MESSAGE);\n }, [selectedIgnored]);\n\n // The group's `onDismiss(value)`, then the value leaves the selection (D39), in one click.\n const dismiss = useEventCallback(() => {\n group?.dismiss(reportedValue);\n group?.deselect(reportedValue);\n });\n const toggle = useEventCallback(() => {\n group?.toggle(reportedValue);\n });\n\n // In a list TagGroup the root is a list item; the consumer's role wins.\n const listItemRole = group?.mode === 'list' ? 'listitem' : undefined;\n // A host hides the tags it counts instead of showing them (TagPicker's `overflow=\"count\"`).\n const hiddenByHost = value !== undefined && (group?.hiddenValues?.has(value) ?? false);\n\n const context = React.useMemo<InteractionTagContextValue>(\n () => ({\n size,\n shape,\n look,\n disabled,\n selected,\n pressed,\n dimDisabled,\n primaryTextId,\n primaries,\n secondaryRef,\n dismiss,\n toggle,\n }),\n [\n size,\n shape,\n look,\n disabled,\n selected,\n pressed,\n dimDisabled,\n primaryTextId,\n primaries,\n dismiss,\n toggle,\n ],\n );\n\n return (\n <InteractionTagContext.Provider value={context}>\n <div\n data-appearance={appearance}\n data-size={size}\n data-shape={shape}\n data-selected={selected ? '' : undefined}\n data-disabled={disabled ? '' : undefined}\n data-wave-tag-item=\"\"\n role={role ?? listItemRole}\n hidden={hiddenByHost || hidden}\n {...rest}\n ref={mergedRef}\n className={cn(\n interactionTagClassNames.root,\n 'group/interaction-tag inline-flex items-stretch',\n className,\n )}\n >\n {children}\n </div>\n </InteractionTagContext.Provider>\n );\n};\nInteractionTagRoot.displayName = 'InteractionTag';\n\n// ---------------------------------------------------------------------------\n// Primary\n// ---------------------------------------------------------------------------\n\n/**\n * The main action of an {@link InteractionTag}: a `<button type=\"button\">` named by its text and\n * `secondaryText` (`media` and `icon` are decorative), with the InteractionTag's look. In a\n * selecting TagGroup it is a toggle (`aria-pressed`): a click, Enter or Space adds the tag's\n * `value` to the group's selection or removes it, after its `onClick` (whose `preventDefault()`\n * cancels the toggle). Elsewhere the InteractionTag's `selected` makes it a toggle. Either state\n * renders its `aria-pressed` over one passed here, which applies only when neither is set. Delete\n * and Backspace on it click the tag's Secondary when there is one. Its props, `ref` and\n * `className` go to the button. Flat name of `InteractionTag.Primary`, for React Server\n * Components.\n */\nexport const InteractionTagPrimary = ({\n media,\n icon,\n secondaryText,\n disabled: disabledProp = false,\n 'aria-pressed': ariaPressed,\n className,\n children,\n onClick,\n onKeyDown,\n onFocus,\n onBlur,\n ref,\n ...rest\n}: InteractionTagPrimaryProps) => {\n const tag = useInteractionTagContext('InteractionTag.Primary');\n const { size, look } = tag;\n const disabled = tag.disabled || disabledProp;\n const hold = useHeldFocus(disabled);\n // Its text names the Secondary while it renders (D43).\n const registerPrimary = tag.primaries.register;\n React.useLayoutEffect(() => registerPrimary(), [registerPrimary]);\n\n // Slots that render nothing render no element and take no room.\n const hasMedia = slotRendersContent(media);\n const hasIcon = slotRendersContent(icon);\n const secondary = materialiseSlotContent(secondaryText);\n const hasSecondary = slotRendersContent(secondary);\n const avatarBox = React.useMemo(() => ({ size: TAG_AVATAR_SIZE[size] }), [size]);\n\n // In a selecting TagGroup a click (also Enter and Space) toggles the tag's value, after the\n // consumer's `onClick`; never for a click from a portal opened from the Primary (C-COMPOSE).\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (!disabled && isOwnEvent(event)) tag.toggle();\n };\n\n // Delete and Backspace dismiss the tag through the Secondary's own click, so whatever cancels\n // that click (its `onClick`'s `preventDefault()`, a disabled or held Secondary) cancels them\n // too. Not from a portal opened from the Primary, and not while the Primary itself is held.\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (disabled || event.target !== event.currentTarget || !isDismissKey(event)) return;\n const secondaryButton = tag.secondaryRef?.current;\n if (!secondaryButton || secondaryButton.disabled) return;\n event.preventDefault();\n secondaryButton.click();\n };\n\n const primaryText = (\n <span\n id={tag.primaryTextId || undefined}\n className={cn(\n interactionTagPrimaryClassNames.primaryText,\n hasSecondary && TAG_PRIMARY_TEXT_TWO_LINE_CLASSES,\n )}\n >\n {children}\n </span>\n );\n\n return (\n <button\n type=\"button\"\n // The tag's state (`selected`, or a selecting TagGroup's value) decides; a consumer\n // `aria-pressed` applies only to a Primary that is no toggle of the tag's.\n aria-pressed={tag.pressed ?? ariaPressed}\n data-selected={tag.selected ? '' : undefined}\n {...rest}\n ref={ref}\n onClick={composeEventHandlers(onClick, handleClick)}\n // After `onClick`: a held Primary's click is blocked, the toggle included.\n {...buttonStateProps(disabled, hold.held)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onFocus={composeEventHandlers(onFocus, hold.onFocus, { checkDefaultPrevented: false })}\n onBlur={composeEventHandlers(onBlur, hold.onBlur, { checkDefaultPrevented: false })}\n className={cn(\n interactionTagPrimaryClassNames.root,\n INTERACTION_TAG_BUTTON_BASE_CLASSES,\n INTERACTION_TAG_PRIMARY_BASE_CLASSES,\n tagSizeClasses[size],\n tagStartInsetClasses[size][hasMedia ? 'media' : hasIcon ? 'icon' : 'text'],\n interactionTagPrimaryEndInsetClasses[size],\n interactionTagLookClasses[look],\n look === 'selected' && [\n forcedColors.selectedContainer,\n INTERACTION_TAG_SELECTED_FORCED_COLORS,\n ],\n tagShapeClasses[tag.shape],\n INTERACTION_TAG_PRIMARY_JOINED_CLASSES,\n disabledClasses(disabled, tag.dimDisabled),\n focusRing,\n size === 'extra-small' && INTERACTION_TAG_EXTRA_SMALL_HIT_CLASSES,\n className,\n )}\n >\n {hasMedia && (\n // An Avatar without its own `size` takes the tag's box.\n <AvatarSizeContext.Provider value={avatarBox}>\n {renderSlot(\n media,\n 'span',\n cn(interactionTagPrimaryClassNames.media, tagMediaClasses[size]),\n { 'aria-hidden': true },\n )}\n </AvatarSizeContext.Provider>\n )}\n {hasIcon &&\n renderSlot(icon, 'span', cn(interactionTagPrimaryClassNames.icon, tagIconClasses[size]), {\n 'aria-hidden': true,\n })}\n {hasSecondary ? (\n <span className={TAG_TEXT_COLUMN_CLASSES}>\n {primaryText}\n {/* A space between the two texts in the button's name (\"Katri Designer\"), whatever a\n name computation makes of the column; the column layout never renders it. */}{' '}\n <span\n className={cn(\n interactionTagPrimaryClassNames.secondaryText,\n TAG_SECONDARY_TEXT_CLASSES,\n )}\n >\n {secondary}\n </span>\n </span>\n ) : (\n primaryText\n )}\n </button>\n );\n};\nInteractionTagPrimary.displayName = 'InteractionTagPrimary';\n\n// ---------------------------------------------------------------------------\n// Secondary\n// ---------------------------------------------------------------------------\n\nconst BUTTON_CHILD_MESSAGE =\n \"InteractionTag.Secondary: its content received a button. A button cannot contain a button: its children became the content of the Dismiss button and its props were dropped. Pass icon content, and handle the dismissal in `onClick` or in the TagGroup's `onDismiss`.\";\n\n/**\n * The separate Dismiss button of an {@link InteractionTag}: a `<button type=\"button\">` after the\n * Primary, named `dismissLabel` plus the Primary's text (\"Dismiss Cherry\"). Its children replace\n * the default dismiss glyph; a text label among them replaces `dismissLabel` in the name (\"Remove\n * Cherry\"), an `aria-label` the whole name. A button passed as its child is unwrapped (its children\n * become the content). Enter, Space, a click, Delete and Backspace call its `onClick`, then, in a\n * TagGroup, the group's `onDismiss(value)`. Its props, `ref` and `className` go to the button.\n * Flat name of `InteractionTag.Secondary`, for React Server Components.\n */\nexport const InteractionTagSecondary = ({\n dismissLabel = 'Dismiss',\n disabled: disabledProp = false,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className,\n children,\n onClick,\n onKeyDown,\n onFocus,\n onBlur,\n ref,\n ...rest\n}: InteractionTagSecondaryProps) => {\n const tag = useInteractionTagContext('InteractionTag.Secondary');\n const { size, look } = tag;\n const disabled = tag.disabled || disabledProp;\n const hold = useHeldFocus(disabled);\n const dismissLabelId = useId('interaction-tag-dismiss');\n const contentId = useId('interaction-tag-dismiss-content');\n const ownRef = React.useRef<HTMLButtonElement>(null);\n const mergedRef = useMergedRefs<HTMLButtonElement>(ownRef, tag.secondaryRef, ref);\n // Unmounting while it has focus (rendered conditionally), the Secondary hands focus to its own\n // tag's Primary; in a TagGroup, when the whole tag goes, the tag's own move applies (D35).\n useDismissControlFocus(ownRef);\n\n // Its children are the glyph inside the Dismiss button: a button there would nest buttons, so\n // it is unwrapped (C-SLOTS glyph rule).\n const { glyph, button: unwrapped } = unwrapButtonGlyph(children as Slot<'span'>);\n React.useEffect(() => {\n if (unwrapped) warnOnce('InteractionTag.Secondary:button-child', BUTTON_CHILD_MESSAGE);\n }, [unwrapped]);\n const content = materialiseSlotContent(glyph);\n const hasContent = slotRendersContent(content);\n const literalTextLabel = hasContent && hasTextLabel(content);\n\n // C-SLOTS naming (WCAG 2.5.3 Label in Name): a text label in the children replaces\n // `dismissLabel` (\"Remove Cherry\"). The literal children decide on the server and on the first\n // render; after mount, the rendered content does (text from components, later changes).\n const [labelTarget, setLabelTarget] = React.useState<HTMLSpanElement | null>(null);\n const subscribeToContent = React.useCallback(\n (onChange: () => void) => (labelTarget ? observeTextLabel(labelTarget, onChange) : noop),\n [labelTarget],\n );\n const contentHasTextLabel = React.useSyncExternalStore(\n subscribeToContent,\n () => (labelTarget ? hasRenderedTextLabel(labelTarget) : literalTextLabel),\n () => literalTextLabel,\n );\n const hasLabel = hasContent && contentHasTextLabel;\n // The primary text joins the name while a Primary renders it.\n const hasPrimary = React.useSyncExternalStore(\n tag.primaries.subscribe,\n tag.primaries.hasPrimary,\n () => true,\n );\n // A consumer `aria-label` replaces the whole name; a consumer `aria-labelledby` replaces ours.\n const namedByConsumer = ariaLabel !== undefined || ariaLabelledBy !== undefined;\n const labelledBy = namedByConsumer\n ? ariaLabelledBy\n : joinIds(hasLabel ? contentId : dismissLabelId, hasPrimary ? tag.primaryTextId : undefined);\n\n // The consumer's `onClick` first (its `preventDefault()` keeps the group from hearing of it),\n // then the TagGroup's `onDismiss(value)`; never for a click from a portal opened inside.\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (isOwnEvent(event)) tag.dismiss();\n };\n // Delete and Backspace dismiss as Enter does: through the button's own click, so whatever\n // cancels a click (its `onClick`'s `preventDefault()`, a held or disabled button) cancels them.\n // A held key dismisses one tag: the browser clicks a button on every repeated Enter, which\n // would reach the next tag's Dismiss control once focus moved there (D35).\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (event.target !== event.currentTarget) return;\n if (isRepeatedActivation(event)) {\n event.preventDefault();\n return;\n }\n if (!isDismissKey(event)) return;\n event.preventDefault();\n event.currentTarget.click();\n };\n\n return (\n <button\n type=\"button\"\n data-wave-tag-dismiss=\"\"\n data-selected={tag.selected ? '' : undefined}\n {...rest}\n ref={mergedRef}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n onClick={composeEventHandlers(onClick, handleClick)}\n {...buttonStateProps(disabled, hold.held)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onFocus={composeEventHandlers(onFocus, hold.onFocus, { checkDefaultPrevented: false })}\n onBlur={composeEventHandlers(onBlur, hold.onBlur, { checkDefaultPrevented: false })}\n className={cn(\n interactionTagSecondaryClassNames.root,\n INTERACTION_TAG_BUTTON_BASE_CLASSES,\n INTERACTION_TAG_SECONDARY_BASE_CLASSES,\n interactionTagSecondarySizeClasses[size],\n interactionTagLookClasses[look],\n look === 'selected' && [\n forcedColors.selectedContainer,\n INTERACTION_TAG_SELECTED_FORCED_COLORS,\n ],\n interactionTagDividerClasses[look],\n interactionTagSecondaryShapeClasses[tag.shape],\n disabledClasses(disabled, tag.dimDisabled),\n focusRing,\n size === 'extra-small' && INTERACTION_TAG_EXTRA_SMALL_HIT_CLASSES,\n className,\n )}\n >\n {!namedByConsumer && (\n <span id={dismissLabelId} className=\"sr-only\">\n {dismissLabel}\n </span>\n )}\n {hasContent ? (\n <span\n id={contentId}\n ref={setLabelTarget}\n className={cn(\n interactionTagSecondaryClassNames.dismissIcon,\n 'inline-flex items-center justify-center',\n // A text label keeps clear of the divider and the tag's end; a glyph needs no room.\n hasLabel && INTERACTION_TAG_SECONDARY_LABEL_CLASSES,\n )}\n >\n {content}\n </span>\n ) : (\n <DismissIcon\n size={TAG_DISMISS_GLYPH_SIZE[size]}\n className={interactionTagSecondaryClassNames.dismissIcon}\n />\n )}\n </button>\n );\n};\nInteractionTagSecondary.displayName = 'InteractionTagSecondary';\n\n// ---------------------------------------------------------------------------\n// Compound\n// ---------------------------------------------------------------------------\n\n/**\n * A tag with a main action and a separate Dismiss button: an element that holds two sibling\n * buttons, `InteractionTag.Primary` (the action) and `InteractionTag.Secondary` (Dismiss), never\n * one inside the other. Use it for a chip the user acts on (opens, toggles) and can also remove;\n * a `Tag` is a chip that only displays, or only dismisses.\n *\n * - **Two Tab stops**, the Primary then the Secondary. In a TagGroup toolbar both join its arrow\n * order (Primary, Secondary, next tag).\n * - **The Secondary is named after the Primary's text**: its `dismissLabel` plus the primary\n * text, \"Dismiss Cherry\" (never the secondary text). A text label in its children replaces\n * `dismissLabel` (\"Remove Cherry\"); an `aria-label` replaces the whole name.\n * - **Delete and Backspace** on either button dismiss the tag through the Secondary's click (a\n * held key dismisses once); without a Secondary they do nothing. Enter, Space and a click on the\n * Secondary dismiss too: remove the tag in its `onClick`, or in a TagGroup's `onDismiss(value)`,\n * which is called after it.\n * - **In a selecting TagGroup** (`value`, `defaultValue` or `onValueChange` on the group) the\n * Primary toggles the tag's `value` in the group's selection (`aria-pressed`, the selected\n * look), and dismissing a selected tag also removes its value from the selection.\n * - **`selected`**, outside a selecting TagGroup, draws the selected look and makes the Primary a\n * toggle (`aria-pressed`); leave it `undefined` for an action that is not a toggle.\n * - **Look**: `size`, `appearance` and `shape`, Tag's sizes and colours (a TagGroup gives its\n * defaults); `disabled` disables both buttons natively. The Primary takes `media` (an Avatar,\n * sized for the tag), `icon` and `secondaryText`.\n * - Fluent's `hasSecondaryAction` is not needed: the Primary squares its end corners next to a\n * Secondary by itself, also when the Secondary is rendered conditionally or wrapped.\n * - React Server Components cannot dot into a client module: import the flat names\n * `InteractionTagPrimary` and `InteractionTagSecondary` there.\n * - Renders `data-appearance`, `data-size` and `data-shape`, and while set `data-selected` and\n * `data-disabled`, on the root; `data-selected` on both buttons.\n *\n * @example\n * <InteractionTag value=\"cherry\">\n * <InteractionTag.Primary icon={<FruitIcon />} onClick={openDetails}>\n * Cherry\n * </InteractionTag.Primary>\n * <InteractionTag.Secondary onClick={() => remove('cherry')} />\n * </InteractionTag>\n */\nexport const InteractionTag = /* @__PURE__ */ Object.assign(InteractionTagRoot, {\n Primary: InteractionTagPrimary,\n Secondary: InteractionTagSecondary,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InteractionTag.mjs","names":["useId","useId$1","React","noop","createPrimaryRegistry","count","settled","listeners","notify","listener","onChange","INERT_PRIMARY_REGISTRY","InteractionTagContext","INERT_CONTEXT","useInteractionTagContext","reportMissingContext","componentName","isKeyOf","value","table","disabledClasses","cn","dimDisabled","INTERACTION_TAG_DISABLED_CLASSES","mergedAriaDisabledClasses","INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES","disabled","forcedColors","SELECTED_IN_GROUP_MESSAGE","buttonStateProps","held","MERGED_DISABLED_FOCUSABLE_PROPS","InteractionTagRoot","appearanceProp","sizeProp","shapeProp","disabledProp","selectedProp","rest","group","useTagGroupContext","rootRef","mergedRef","useMergedRefs","ref","secondaryRef","primaryTextId","primaries","size","tagSizeClasses","appearance","tagAppearanceClasses","shape","tagShapeClasses","reportedValue","useTagGroupItem","selecting","pressed","selected","look","selectedIgnored","warnOnce","dismiss","useEventCallback","toggle","listItemRole","hiddenByHost","context","role","hidden","interactionTagClassNames","className","InteractionTagPrimary","ariaPressed","tag","hold","useHeldFocus","registerPrimary","hasMedia","slotRendersContent","media","hasIcon","icon","secondary","materialiseSlotContent","secondaryText","hasSecondary","avatarBox","TAG_AVATAR_SIZE","handleClick","isOwnEvent","event","handleKeyDown","isDismissKey","secondaryButton","primaryText","interactionTagPrimaryClassNames","composeEventHandlers","onClick","onKeyDown","onFocus","onBlur","INTERACTION_TAG_BUTTON_BASE_CLASSES","INTERACTION_TAG_PRIMARY_BASE_CLASSES","tagStartInsetClasses","interactionTagPrimaryEndInsetClasses","interactionTagLookClasses","INTERACTION_TAG_PRIMARY_JOINED_CLASSES","focusRing","AvatarSizeContext","renderSlot","tagMediaClasses","tagIconClasses","TAG_TEXT_COLUMN_CLASSES","TAG_SECONDARY_TEXT_CLASSES","BUTTON_CHILD_MESSAGE","InteractionTagSecondary","ariaLabel","ariaLabelledBy","dismissLabelId","contentId","ownRef","unwrapped","unwrapButtonGlyph","children","content","glyph","hasContent","literalTextLabel","hasTextLabel","labelTarget","setLabelTarget","subscribeToContent","observeTextLabel","contentHasTextLabel","hasRenderedTextLabel","hasLabel","hasPrimary","namedByConsumer","labelledBy","joinIds","isRepeatedActivation","interactionTagSecondaryClassNames","INTERACTION_TAG_SECONDARY_BASE_CLASSES","interactionTagSecondarySizeClasses","interactionTagDividerClasses","interactionTagSecondaryShapeClasses","dismissLabel","DismissIcon","TAG_DISMISS_GLYPH_SIZE","InteractionTag"],"sources":["../../../src/components/data-display/InteractionTag.tsx"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport {\n interactionTagClassNames,\n interactionTagPrimaryClassNames,\n interactionTagSecondaryClassNames,\n} from '../../lib/classNames';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { reportMissingContext, warnOnce } from '../../lib/dev';\nimport { isOwnEvent } from '../../lib/events';\nimport { DismissIcon } from '../../lib/icons';\nimport { hasRenderedTextLabel, hasTextLabel, observeTextLabel } from '../../lib/labelInName';\nimport { materialiseSlotContent, renderSlot, slotRendersContent } from '../../lib/slot';\nimport type { Slot } from '../../lib/slot';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport type { TagAppearance, TagShape, TagSize } from '../../lib/types';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport {\n MERGED_DISABLED_FOCUSABLE_PROPS,\n mergedAriaDisabledClasses,\n unwrapButtonGlyph,\n} from '../button/Button.slots';\nimport { AvatarSizeContext } from './Avatar.context';\nimport {\n isDismissKey,\n isRepeatedActivation,\n useDismissControlFocus,\n useHeldFocus,\n useTagGroupContext,\n useTagGroupItem,\n} from './TagGroup.context';\nimport {\n INTERACTION_TAG_BUTTON_BASE_CLASSES,\n INTERACTION_TAG_DISABLED_CLASSES,\n INTERACTION_TAG_EXTRA_SMALL_HIT_CLASSES,\n INTERACTION_TAG_PRIMARY_BASE_CLASSES,\n INTERACTION_TAG_PRIMARY_JOINED_CLASSES,\n INTERACTION_TAG_SECONDARY_BASE_CLASSES,\n INTERACTION_TAG_SECONDARY_LABEL_CLASSES,\n INTERACTION_TAG_SELECTED_FORCED_COLORS,\n INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES,\n TAG_AVATAR_SIZE,\n TAG_DISMISS_GLYPH_SIZE,\n TAG_PRIMARY_TEXT_TWO_LINE_CLASSES,\n TAG_SECONDARY_TEXT_CLASSES,\n TAG_TEXT_COLUMN_CLASSES,\n interactionTagDividerClasses,\n interactionTagLookClasses,\n interactionTagPrimaryEndInsetClasses,\n interactionTagSecondaryShapeClasses,\n interactionTagSecondarySizeClasses,\n tagAppearanceClasses,\n tagIconClasses,\n tagMediaClasses,\n tagShapeClasses,\n tagSizeClasses,\n tagStartInsetClasses,\n} from './tagStyles';\nimport type { TagLook } from './tagStyles';\n\n/** Props of InteractionTag: the element that holds the Primary and Secondary buttons. */\nexport interface InteractionTagProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Identifies the tag in a TagGroup: the value `onDismiss` receives and the selection holds. Give\n * every tag of a group its own value.\n * @default a generated id (a development warning in a group that reports values)\n */\n value?: string;\n /**\n * Colour scheme of both buttons: `filled` (a neutral fill), `outline` (a border on the surface\n * behind it) or `brand` (a light brand tint that follows the brand ramp).\n * @default the TagGroup's `appearance`, else 'filled'\n */\n appearance?: TagAppearance;\n /**\n * `medium` (28px tall), `small` (24px) or `extra-small` (20px); an Avatar in the Primary's\n * `media` is 24, 20 or 16px. Fluent's medium tag is 32px.\n * @default the TagGroup's `size`, else 'medium'\n */\n size?: TagSize;\n /**\n * `circular` (a pill) or `rounded` (4px corners). Fluent's default is `rounded`.\n * @default the TagGroup's `shape`, else 'circular'\n */\n shape?: TagShape;\n /**\n * Disables both buttons natively (a disabled TagGroup does too; a part's own `disabled` cannot\n * re-enable it). A button that has focus when it is disabled keeps it, unavailable, until focus\n * leaves it. Rendered as `data-disabled` on the root.\n * @default false\n */\n disabled?: boolean;\n /**\n * Outside a selecting TagGroup: draws the selected look and makes the Primary a toggle:\n * `aria-pressed=\"true\"`, or `\"false\"` for `selected={false}`. Leave it `undefined` for an\n * action that is not a toggle (no `aria-pressed`). Inside a selecting TagGroup (`value`,\n * `defaultValue` or `onValueChange`) the group's `value` decides, and a defined `selected` is\n * ignored (a development warning). Rendered as `data-selected` on the root and both buttons.\n * Disabled wins over the selected look (`aria-pressed` and `data-selected` still render).\n * Fluent's `selected` is a look only.\n */\n selected?: boolean;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Props of InteractionTag.Primary: the tag's main action (or its toggle in a selecting TagGroup). */\nexport interface InteractionTagPrimaryProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * A visual before the text (an Avatar, sized for the tag: 24, 20 or 16px, unless it sets its\n * own `size`). Decorative (`aria-hidden`): the button is named by its text.\n */\n media?: Slot<'span'>;\n /** A decorative icon before the text (`aria-hidden`), in a 20, 16 or 12px box. */\n icon?: Slot<'span'>;\n /**\n * A second, smaller line under the text. Part of the Primary's name, not of the Secondary's. A\n * small or extra-small tag grows to 28px to fit it.\n */\n secondaryText?: React.ReactNode;\n /**\n * Disables the Primary natively; or-ed with the InteractionTag's `disabled` (it cannot\n * re-enable a disabled tag).\n * @default false\n */\n disabled?: boolean;\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n/** Props of InteractionTag.Secondary: the tag's separate Dismiss button. */\nexport interface InteractionTagSecondaryProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * Visually hidden text that names the button with the Primary's text (\"Dismiss Cherry\"). A text\n * label in the children replaces it (\"Remove Cherry\"); an `aria-label` replaces the whole name.\n * Localise it here. Fluent's order is the primary text, then the label (\"Cherry remove\").\n * @default 'Dismiss'\n */\n dismissLabel?: string;\n /**\n * Disables the Secondary natively; or-ed with the InteractionTag's `disabled` (it cannot\n * re-enable a disabled tag).\n * @default false\n */\n disabled?: boolean;\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\n/** What an InteractionTag gives its two buttons (resolved values, never `undefined` but `pressed`). */\ninterface InteractionTagContextValue {\n size: TagSize;\n shape: TagShape;\n /** The look of both buttons: the appearance, or the selected look over it. */\n look: TagLook;\n /** Whether the tag is disabled (its own `disabled`, or its TagGroup's). */\n disabled: boolean;\n /** Whether the tag is selected (`data-selected`). */\n selected: boolean;\n /** The Primary's `aria-pressed`: `undefined` for an action that is not a toggle. */\n pressed: boolean | undefined;\n /** Whether a disabled button dims itself (`false` under a host that dims the tags as a whole). */\n dimDisabled: boolean;\n /** The id of the Primary's text, the second half of the Secondary's name. */\n primaryTextId: string;\n /** Which Primaries render, so the Secondary points at the primary text only while one does. */\n primaries: PrimaryRegistry;\n /** The Secondary, which Delete and Backspace on the Primary click (read at key time). */\n secondaryRef: React.RefObject<HTMLButtonElement | null> | null;\n /**\n * Reports the dismissal to the TagGroup (its `onDismiss(value)`), after the Secondary's\n * `onClick`, and then removes the tag's value from the group's selection (D39).\n */\n dismiss: () => void;\n /** Toggles the tag's value in a selecting TagGroup's selection (the Primary's click). */\n toggle: () => void;\n}\n\nconst noop = () => {};\n\n/**\n * The Primaries an InteractionTag renders, read by its Secondary, whose name points at the\n * primary text only while a Primary renders it (no id reference to a missing element). Until the\n * root's first commit (the server render, hydration and the first client render) a Primary is\n * assumed, so the server HTML holds the whole name and a tag with a Primary renders once; a\n * Secondary without one drops the id after that commit, and takes it again when one mounts. An\n * external store (C-HOOKS): a Primary registers from a layout effect.\n */\ninterface PrimaryRegistry {\n subscribe: (onChange: () => void) => () => void;\n /** Whether the Secondary's name may point at the primary text. */\n hasPrimary: () => boolean;\n /** For a Primary's layout effect: returns its cleanup. */\n register: () => () => void;\n /** For the root's layout effect: from now on the registrations decide. */\n settle: () => void;\n}\n\nfunction createPrimaryRegistry(): PrimaryRegistry {\n let count = 0;\n let settled = false;\n const listeners = new Set<() => void>();\n const notify = () => {\n for (const listener of listeners) listener();\n };\n return {\n subscribe: (onChange) => {\n listeners.add(onChange);\n return () => {\n listeners.delete(onChange);\n };\n },\n hasPrimary: () => !settled || count > 0,\n register: () => {\n count += 1;\n notify();\n return () => {\n count -= 1;\n notify();\n };\n },\n settle: () => {\n if (settled) return;\n settled = true;\n notify();\n },\n };\n}\n\n/** The registry of the inert context: a Primary is always assumed. */\nconst INERT_PRIMARY_REGISTRY: PrimaryRegistry = {\n subscribe: () => noop,\n hasPrimary: () => true,\n register: () => noop,\n settle: noop,\n};\n\n/** Internal: `null` outside an InteractionTag. */\nconst InteractionTagContext = React.createContext<InteractionTagContextValue | null>(null);\nInteractionTagContext.displayName = 'InteractionTagContext';\n\n/** What a part reads outside an InteractionTag in production (C-CONTEXT): an enabled, unnamed tag. */\nconst INERT_CONTEXT: InteractionTagContextValue = {\n size: 'medium',\n shape: 'circular',\n look: 'filled',\n disabled: false,\n selected: false,\n pressed: undefined,\n dimDisabled: true,\n primaryTextId: '',\n primaries: INERT_PRIMARY_REGISTRY,\n secondaryRef: null,\n dismiss: () => {},\n toggle: () => {},\n};\n\nfunction useInteractionTagContext(componentName: string): InteractionTagContextValue {\n const context = React.useContext(InteractionTagContext);\n if (context) return context;\n reportMissingContext(componentName, 'InteractionTag');\n return INERT_CONTEXT;\n}\n\n/** Whether `value` is a key of `table` (an untyped value outside a union falls back). */\nfunction isKeyOf<K extends string>(\n value: unknown,\n table: Readonly<Record<K, unknown>>,\n): value is K {\n return typeof value === 'string' && Object.hasOwn(table, value);\n}\n\n/** The classes of a button's disabled states: dimmed, unless the host dims the tags itself. */\nfunction disabledClasses(disabled: boolean, dimDisabled: boolean): string {\n return cn(\n dimDisabled\n ? [INTERACTION_TAG_DISABLED_CLASSES, mergedAriaDisabledClasses]\n : INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES,\n disabled && forcedColors.disabled,\n );\n}\n\nconst SELECTED_IN_GROUP_MESSAGE =\n \"InteractionTag: `selected` has no effect in a TagGroup that selects (`value`, `defaultValue` or `onValueChange`); the group's `value` decides.\";\n\n/**\n * The state props of a tag button: natively disabled, or, while it keeps the focus it had when it\n * was disabled, the focusable disabled state (its click blocked).\n */\nfunction buttonStateProps(disabled: boolean, held: boolean) {\n if (!disabled) return undefined;\n return held ? MERGED_DISABLED_FOCUSABLE_PROPS : { disabled: true };\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\n// The InteractionTag root, documented on the exported `InteractionTag` const.\nconst InteractionTagRoot = ({\n value,\n appearance: appearanceProp,\n size: sizeProp,\n shape: shapeProp,\n disabled: disabledProp = false,\n selected: selectedProp,\n role,\n hidden,\n className,\n children,\n ref,\n ...rest\n}: InteractionTagProps) => {\n const group = useTagGroupContext();\n const rootRef = React.useRef<HTMLDivElement>(null);\n const mergedRef = useMergedRefs<HTMLDivElement>(rootRef, ref);\n const secondaryRef = React.useRef<HTMLButtonElement>(null);\n const primaryTextId = useId('interaction-tag-text');\n // After the first commit, the Primaries that registered decide the Secondary's name (D43).\n const [primaries] = React.useState(createPrimaryRegistry);\n React.useLayoutEffect(() => {\n primaries.settle();\n }, [primaries]);\n\n // The tag's own look, else its TagGroup's, else the default look.\n const size: TagSize = isKeyOf(sizeProp, tagSizeClasses) ? sizeProp : (group?.size ?? 'medium');\n const appearance: TagAppearance = isKeyOf(appearanceProp, tagAppearanceClasses)\n ? appearanceProp\n : (group?.appearance ?? 'filled');\n const shape: TagShape = isKeyOf(shapeProp, tagShapeClasses)\n ? shapeProp\n : (group?.shape ?? 'circular');\n // A disabled group disables every tag: the tag's own `disabled={false}` cannot re-enable it.\n const disabled = (group?.disabled ?? false) || disabledProp;\n const dimDisabled = group?.dimDisabled ?? true;\n\n // In a group that reports dismissals or selects, the tag's value (else a generated id).\n const reportedValue = useTagGroupItem(rootRef, value);\n // In a selecting TagGroup the group's selection decides (the Primary is always a toggle there);\n // elsewhere a boolean `selected` does, and `undefined` is an action that is no toggle.\n const selecting = group?.selecting ?? false;\n const pressed = selecting\n ? (group?.isSelected(reportedValue) ?? false)\n : typeof selectedProp === 'boolean'\n ? selectedProp\n : undefined;\n const selected = pressed === true;\n // Disabled wins over the selected look; the attributes still reflect the state.\n const look: TagLook = selected && !disabled ? 'selected' : appearance;\n\n const selectedIgnored = selecting && selectedProp !== undefined;\n React.useEffect(() => {\n if (selectedIgnored) warnOnce('InteractionTag:selected-in-group', SELECTED_IN_GROUP_MESSAGE);\n }, [selectedIgnored]);\n\n // The group's `onDismiss(value)`, then the value leaves the selection (D39), in one click.\n const dismiss = useEventCallback(() => {\n group?.dismiss(reportedValue);\n group?.deselect(reportedValue);\n });\n const toggle = useEventCallback(() => {\n group?.toggle(reportedValue);\n });\n\n // In a list TagGroup the root is a list item; the consumer's role wins.\n const listItemRole = group?.mode === 'list' ? 'listitem' : undefined;\n // A host hides the tags it counts instead of showing them (TagPicker's `overflow=\"count\"`).\n const hiddenByHost = value !== undefined && (group?.hiddenValues?.has(value) ?? false);\n\n const context = React.useMemo<InteractionTagContextValue>(\n () => ({\n size,\n shape,\n look,\n disabled,\n selected,\n pressed,\n dimDisabled,\n primaryTextId,\n primaries,\n secondaryRef,\n dismiss,\n toggle,\n }),\n [\n size,\n shape,\n look,\n disabled,\n selected,\n pressed,\n dimDisabled,\n primaryTextId,\n primaries,\n dismiss,\n toggle,\n ],\n );\n\n return (\n <InteractionTagContext.Provider value={context}>\n <div\n data-appearance={appearance}\n data-size={size}\n data-shape={shape}\n data-selected={selected ? '' : undefined}\n data-disabled={disabled ? '' : undefined}\n data-wave-tag-item=\"\"\n role={role ?? listItemRole}\n hidden={hiddenByHost || hidden}\n {...rest}\n ref={mergedRef}\n className={cn(\n interactionTagClassNames.root,\n 'group/interaction-tag inline-flex items-stretch',\n className,\n )}\n >\n {children}\n </div>\n </InteractionTagContext.Provider>\n );\n};\nInteractionTagRoot.displayName = 'InteractionTag';\n\n// ---------------------------------------------------------------------------\n// Primary\n// ---------------------------------------------------------------------------\n\n/**\n * The main action of an {@link InteractionTag}: a `<button type=\"button\">` named by its text and\n * `secondaryText` (`media` and `icon` are decorative), with the InteractionTag's look. In a\n * selecting TagGroup it is a toggle (`aria-pressed`): a click, Enter or Space adds the tag's\n * `value` to the group's selection or removes it, after its `onClick` (whose `preventDefault()`\n * cancels the toggle). Elsewhere the InteractionTag's `selected` makes it a toggle. Either state\n * renders its `aria-pressed` over one passed here, which applies only when neither is set. Delete\n * and Backspace on it click the tag's Secondary when there is one. Its props, `ref` and\n * `className` go to the button. Flat name of `InteractionTag.Primary`, for React Server\n * Components.\n */\nexport const InteractionTagPrimary = ({\n media,\n icon,\n secondaryText,\n disabled: disabledProp = false,\n 'aria-pressed': ariaPressed,\n className,\n children,\n onClick,\n onKeyDown,\n onFocus,\n onBlur,\n ref,\n ...rest\n}: InteractionTagPrimaryProps) => {\n const tag = useInteractionTagContext('InteractionTag.Primary');\n const { size, look, shape } = tag;\n const disabled = tag.disabled || disabledProp;\n const hold = useHeldFocus(disabled);\n // Its text names the Secondary while it renders (D43).\n const registerPrimary = tag.primaries.register;\n React.useLayoutEffect(() => registerPrimary(), [registerPrimary]);\n\n // Slots that render nothing render no element and take no room.\n const hasMedia = slotRendersContent(media);\n const hasIcon = slotRendersContent(icon);\n const secondary = materialiseSlotContent(secondaryText);\n const hasSecondary = slotRendersContent(secondary);\n const avatarBox = React.useMemo(\n () => ({\n size: TAG_AVATAR_SIZE[size],\n shape: shape === 'rounded' ? ('square' as const) : ('circular' as const),\n }),\n [size, shape],\n );\n\n // In a selecting TagGroup a click (also Enter and Space) toggles the tag's value, after the\n // consumer's `onClick`; never for a click from a portal opened from the Primary (C-COMPOSE).\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (!disabled && isOwnEvent(event)) tag.toggle();\n };\n\n // Delete and Backspace dismiss the tag through the Secondary's own click, so whatever cancels\n // that click (its `onClick`'s `preventDefault()`, a disabled or held Secondary) cancels them\n // too. Not from a portal opened from the Primary, and not while the Primary itself is held.\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (disabled || event.target !== event.currentTarget || !isDismissKey(event)) return;\n const secondaryButton = tag.secondaryRef?.current;\n if (!secondaryButton || secondaryButton.disabled) return;\n event.preventDefault();\n secondaryButton.click();\n };\n\n const primaryText = (\n <span\n id={tag.primaryTextId || undefined}\n className={cn(\n interactionTagPrimaryClassNames.primaryText,\n hasSecondary && TAG_PRIMARY_TEXT_TWO_LINE_CLASSES,\n )}\n >\n {children}\n </span>\n );\n\n return (\n <button\n type=\"button\"\n // The tag's state (`selected`, or a selecting TagGroup's value) decides; a consumer\n // `aria-pressed` applies only to a Primary that is no toggle of the tag's.\n aria-pressed={tag.pressed ?? ariaPressed}\n data-selected={tag.selected ? '' : undefined}\n {...rest}\n ref={ref}\n onClick={composeEventHandlers(onClick, handleClick)}\n // After `onClick`: a held Primary's click is blocked, the toggle included.\n {...buttonStateProps(disabled, hold.held)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onFocus={composeEventHandlers(onFocus, hold.onFocus, { checkDefaultPrevented: false })}\n onBlur={composeEventHandlers(onBlur, hold.onBlur, { checkDefaultPrevented: false })}\n className={cn(\n interactionTagPrimaryClassNames.root,\n INTERACTION_TAG_BUTTON_BASE_CLASSES,\n INTERACTION_TAG_PRIMARY_BASE_CLASSES,\n tagSizeClasses[size],\n tagStartInsetClasses[size][hasMedia ? 'media' : hasIcon ? 'icon' : 'text'],\n interactionTagPrimaryEndInsetClasses[size],\n interactionTagLookClasses[look],\n look === 'selected' && [\n forcedColors.selectedContainer,\n INTERACTION_TAG_SELECTED_FORCED_COLORS,\n ],\n tagShapeClasses[tag.shape],\n INTERACTION_TAG_PRIMARY_JOINED_CLASSES,\n disabledClasses(disabled, tag.dimDisabled),\n focusRing,\n size === 'extra-small' && INTERACTION_TAG_EXTRA_SMALL_HIT_CLASSES,\n className,\n )}\n >\n {hasMedia && (\n // An Avatar without its own `size` takes the tag's box.\n <AvatarSizeContext.Provider value={avatarBox}>\n {renderSlot(\n media,\n 'span',\n cn(interactionTagPrimaryClassNames.media, tagMediaClasses[size]),\n { 'aria-hidden': true },\n )}\n </AvatarSizeContext.Provider>\n )}\n {hasIcon &&\n renderSlot(icon, 'span', cn(interactionTagPrimaryClassNames.icon, tagIconClasses[size]), {\n 'aria-hidden': true,\n })}\n {hasSecondary ? (\n <span className={TAG_TEXT_COLUMN_CLASSES}>\n {primaryText}\n {/* A space between the two texts in the button's name (\"Katri Designer\"), whatever a\n name computation makes of the column; the column layout never renders it. */}{' '}\n <span\n className={cn(\n interactionTagPrimaryClassNames.secondaryText,\n TAG_SECONDARY_TEXT_CLASSES,\n )}\n >\n {secondary}\n </span>\n </span>\n ) : (\n primaryText\n )}\n </button>\n );\n};\nInteractionTagPrimary.displayName = 'InteractionTagPrimary';\n\n// ---------------------------------------------------------------------------\n// Secondary\n// ---------------------------------------------------------------------------\n\nconst BUTTON_CHILD_MESSAGE =\n \"InteractionTag.Secondary: its content received a button. A button cannot contain a button: its children became the content of the Dismiss button and its props were dropped. Pass icon content, and handle the dismissal in `onClick` or in the TagGroup's `onDismiss`.\";\n\n/**\n * The separate Dismiss button of an {@link InteractionTag}: a `<button type=\"button\">` after the\n * Primary, named `dismissLabel` plus the Primary's text (\"Dismiss Cherry\"). Its children replace\n * the default dismiss glyph; a text label among them replaces `dismissLabel` in the name (\"Remove\n * Cherry\"), an `aria-label` the whole name. A button passed as its child is unwrapped (its children\n * become the content). Enter, Space, a click, Delete and Backspace call its `onClick`, then, in a\n * TagGroup, the group's `onDismiss(value)`. Its props, `ref` and `className` go to the button.\n * Flat name of `InteractionTag.Secondary`, for React Server Components.\n */\nexport const InteractionTagSecondary = ({\n dismissLabel = 'Dismiss',\n disabled: disabledProp = false,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className,\n children,\n onClick,\n onKeyDown,\n onFocus,\n onBlur,\n ref,\n ...rest\n}: InteractionTagSecondaryProps) => {\n const tag = useInteractionTagContext('InteractionTag.Secondary');\n const { size, look } = tag;\n const disabled = tag.disabled || disabledProp;\n const hold = useHeldFocus(disabled);\n const dismissLabelId = useId('interaction-tag-dismiss');\n const contentId = useId('interaction-tag-dismiss-content');\n const ownRef = React.useRef<HTMLButtonElement>(null);\n const mergedRef = useMergedRefs<HTMLButtonElement>(ownRef, tag.secondaryRef, ref);\n // Unmounting while it has focus (rendered conditionally), the Secondary hands focus to its own\n // tag's Primary; in a TagGroup, when the whole tag goes, the tag's own move applies (D35).\n useDismissControlFocus(ownRef);\n\n // Its children are the glyph inside the Dismiss button: a button there would nest buttons, so\n // it is unwrapped (C-SLOTS glyph rule).\n const { glyph, button: unwrapped } = unwrapButtonGlyph(children as Slot<'span'>);\n React.useEffect(() => {\n if (unwrapped) warnOnce('InteractionTag.Secondary:button-child', BUTTON_CHILD_MESSAGE);\n }, [unwrapped]);\n const content = materialiseSlotContent(glyph);\n const hasContent = slotRendersContent(content);\n const literalTextLabel = hasContent && hasTextLabel(content);\n\n // C-SLOTS naming (WCAG 2.5.3 Label in Name): a text label in the children replaces\n // `dismissLabel` (\"Remove Cherry\"). The literal children decide on the server and on the first\n // render; after mount, the rendered content does (text from components, later changes).\n const [labelTarget, setLabelTarget] = React.useState<HTMLSpanElement | null>(null);\n const subscribeToContent = React.useCallback(\n (onChange: () => void) => (labelTarget ? observeTextLabel(labelTarget, onChange) : noop),\n [labelTarget],\n );\n const contentHasTextLabel = React.useSyncExternalStore(\n subscribeToContent,\n () => (labelTarget ? hasRenderedTextLabel(labelTarget) : literalTextLabel),\n () => literalTextLabel,\n );\n const hasLabel = hasContent && contentHasTextLabel;\n // The primary text joins the name while a Primary renders it.\n const hasPrimary = React.useSyncExternalStore(\n tag.primaries.subscribe,\n tag.primaries.hasPrimary,\n () => true,\n );\n // A consumer `aria-label` replaces the whole name; a consumer `aria-labelledby` replaces ours.\n const namedByConsumer = ariaLabel !== undefined || ariaLabelledBy !== undefined;\n const labelledBy = namedByConsumer\n ? ariaLabelledBy\n : joinIds(hasLabel ? contentId : dismissLabelId, hasPrimary ? tag.primaryTextId : undefined);\n\n // The consumer's `onClick` first (its `preventDefault()` keeps the group from hearing of it),\n // then the TagGroup's `onDismiss(value)`; never for a click from a portal opened inside.\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (isOwnEvent(event)) tag.dismiss();\n };\n // Delete and Backspace dismiss as Enter does: through the button's own click, so whatever\n // cancels a click (its `onClick`'s `preventDefault()`, a held or disabled button) cancels them.\n // A held key dismisses one tag: the browser clicks a button on every repeated Enter, which\n // would reach the next tag's Dismiss control once focus moved there (D35).\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (event.target !== event.currentTarget) return;\n if (isRepeatedActivation(event)) {\n event.preventDefault();\n return;\n }\n if (!isDismissKey(event)) return;\n event.preventDefault();\n event.currentTarget.click();\n };\n\n return (\n <button\n type=\"button\"\n data-wave-tag-dismiss=\"\"\n data-selected={tag.selected ? '' : undefined}\n {...rest}\n ref={mergedRef}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n onClick={composeEventHandlers(onClick, handleClick)}\n {...buttonStateProps(disabled, hold.held)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onFocus={composeEventHandlers(onFocus, hold.onFocus, { checkDefaultPrevented: false })}\n onBlur={composeEventHandlers(onBlur, hold.onBlur, { checkDefaultPrevented: false })}\n className={cn(\n interactionTagSecondaryClassNames.root,\n INTERACTION_TAG_BUTTON_BASE_CLASSES,\n INTERACTION_TAG_SECONDARY_BASE_CLASSES,\n interactionTagSecondarySizeClasses[size],\n interactionTagLookClasses[look],\n look === 'selected' && [\n forcedColors.selectedContainer,\n INTERACTION_TAG_SELECTED_FORCED_COLORS,\n ],\n interactionTagDividerClasses[look],\n interactionTagSecondaryShapeClasses[tag.shape],\n disabledClasses(disabled, tag.dimDisabled),\n focusRing,\n size === 'extra-small' && INTERACTION_TAG_EXTRA_SMALL_HIT_CLASSES,\n className,\n )}\n >\n {!namedByConsumer && (\n <span id={dismissLabelId} className=\"sr-only\">\n {dismissLabel}\n </span>\n )}\n {hasContent ? (\n <span\n id={contentId}\n ref={setLabelTarget}\n className={cn(\n interactionTagSecondaryClassNames.dismissIcon,\n 'inline-flex items-center justify-center',\n // A text label keeps clear of the divider and the tag's end; a glyph needs no room.\n hasLabel && INTERACTION_TAG_SECONDARY_LABEL_CLASSES,\n )}\n >\n {content}\n </span>\n ) : (\n <DismissIcon\n size={TAG_DISMISS_GLYPH_SIZE[size]}\n className={interactionTagSecondaryClassNames.dismissIcon}\n />\n )}\n </button>\n );\n};\nInteractionTagSecondary.displayName = 'InteractionTagSecondary';\n\n// ---------------------------------------------------------------------------\n// Compound\n// ---------------------------------------------------------------------------\n\n/**\n * A tag with a main action and a separate Dismiss button: an element that holds two sibling\n * buttons, `InteractionTag.Primary` (the action) and `InteractionTag.Secondary` (Dismiss), never\n * one inside the other. Use it for a chip the user acts on (opens, toggles) and can also remove;\n * a `Tag` is a chip that only displays, or only dismisses.\n *\n * - **Two Tab stops**, the Primary then the Secondary. In a TagGroup toolbar both join its arrow\n * order (Primary, Secondary, next tag).\n * - **The Secondary is named after the Primary's text**: its `dismissLabel` plus the primary\n * text, \"Dismiss Cherry\" (never the secondary text). A text label in its children replaces\n * `dismissLabel` (\"Remove Cherry\"); an `aria-label` replaces the whole name.\n * - **Delete and Backspace** on either button dismiss the tag through the Secondary's click (a\n * held key dismisses once); without a Secondary they do nothing. Enter, Space and a click on the\n * Secondary dismiss too: remove the tag in its `onClick`, or in a TagGroup's `onDismiss(value)`,\n * which is called after it.\n * - **In a selecting TagGroup** (`value`, `defaultValue` or `onValueChange` on the group) the\n * Primary toggles the tag's `value` in the group's selection (`aria-pressed`, the selected\n * look), and dismissing a selected tag also removes its value from the selection.\n * - **`selected`**, outside a selecting TagGroup, draws the selected look and makes the Primary a\n * toggle (`aria-pressed`); leave it `undefined` for an action that is not a toggle.\n * - **Look**: `size`, `appearance` and `shape`, Tag's sizes and colours (a TagGroup gives its\n * defaults); `disabled` disables both buttons natively. The Primary takes `media` (an Avatar,\n * sized for the tag), `icon` and `secondaryText`.\n * - Fluent's `hasSecondaryAction` is not needed: the Primary squares its end corners next to a\n * Secondary by itself, also when the Secondary is rendered conditionally or wrapped.\n * - React Server Components cannot dot into a client module: import the flat names\n * `InteractionTagPrimary` and `InteractionTagSecondary` there.\n * - Renders `data-appearance`, `data-size` and `data-shape`, and while set `data-selected` and\n * `data-disabled`, on the root; `data-selected` on both buttons.\n *\n * @example\n * <InteractionTag value=\"cherry\">\n * <InteractionTag.Primary icon={<FruitIcon />} onClick={openDetails}>\n * Cherry\n * </InteractionTag.Primary>\n * <InteractionTag.Secondary onClick={() => remove('cherry')} />\n * </InteractionTag>\n */\nexport const InteractionTag = /* @__PURE__ */ Object.assign(InteractionTagRoot, {\n Primary: InteractionTagPrimary,\n Secondary: InteractionTagSecondary,\n});\n"],"mappings":"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"}
|