@mortenbrudvik/waveui 0.9.0 → 0.11.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 +758 -152
- package/dist/components/button/Toolbar.cjs +1 -1
- package/dist/components/button/Toolbar.cjs.map +1 -1
- package/dist/components/button/Toolbar.mjs +25 -30
- package/dist/components/button/Toolbar.mjs.map +1 -1
- package/dist/components/button/Toolbar.navigation.cjs +2 -0
- package/dist/components/button/Toolbar.navigation.cjs.map +1 -0
- package/dist/components/button/Toolbar.navigation.mjs +17 -0
- package/dist/components/button/Toolbar.navigation.mjs.map +1 -0
- 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.context.cjs +2 -0
- package/dist/components/data-display/Avatar.context.cjs.map +1 -0
- package/dist/components/data-display/Avatar.context.mjs +9 -0
- package/dist/components/data-display/Avatar.context.mjs.map +1 -0
- package/dist/components/data-display/Avatar.mjs +66 -61
- package/dist/components/data-display/Avatar.mjs.map +1 -1
- package/dist/components/data-display/InteractionTag.cjs +2 -0
- package/dist/components/data-display/InteractionTag.cjs.map +1 -0
- package/dist/components/data-display/InteractionTag.mjs +234 -0
- package/dist/components/data-display/InteractionTag.mjs.map +1 -0
- 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 +222 -90
- package/dist/components/data-display/Tag.mjs.map +1 -1
- package/dist/components/data-display/TagGroup.cjs +2 -0
- package/dist/components/data-display/TagGroup.cjs.map +1 -0
- package/dist/components/data-display/TagGroup.context.cjs +2 -0
- package/dist/components/data-display/TagGroup.context.cjs.map +1 -0
- package/dist/components/data-display/TagGroup.context.mjs +113 -0
- package/dist/components/data-display/TagGroup.context.mjs.map +1 -0
- package/dist/components/data-display/TagGroup.mjs +149 -0
- package/dist/components/data-display/TagGroup.mjs.map +1 -0
- package/dist/components/data-display/tagStyles.cjs +2 -0
- package/dist/components/data-display/tagStyles.cjs.map +1 -0
- package/dist/components/data-display/tagStyles.mjs +108 -0
- package/dist/components/data-display/tagStyles.mjs.map +1 -0
- package/dist/components/feedback/Toaster.cjs +1 -1
- package/dist/components/feedback/Toaster.cjs.map +1 -1
- package/dist/components/feedback/Toaster.mjs +213 -181
- package/dist/components/feedback/Toaster.mjs.map +1 -1
- package/dist/components/input/Calendar.cjs +2 -0
- package/dist/components/input/Calendar.cjs.map +1 -0
- package/dist/components/input/Calendar.mjs +352 -0
- package/dist/components/input/Calendar.mjs.map +1 -0
- package/dist/components/input/Calendar.views.cjs +2 -0
- package/dist/components/input/Calendar.views.cjs.map +1 -0
- package/dist/components/input/Calendar.views.mjs +194 -0
- package/dist/components/input/Calendar.views.mjs.map +1 -0
- package/dist/components/input/ColorArea.cjs +1 -1
- package/dist/components/input/ColorArea.cjs.map +1 -1
- package/dist/components/input/ColorArea.mjs +18 -18
- package/dist/components/input/ColorArea.mjs.map +1 -1
- package/dist/components/input/Combobox.cjs +1 -1
- package/dist/components/input/Combobox.cjs.map +1 -1
- package/dist/components/input/Combobox.expand.cjs +1 -1
- package/dist/components/input/Combobox.expand.cjs.map +1 -1
- package/dist/components/input/Combobox.expand.mjs +7 -7
- package/dist/components/input/Combobox.expand.mjs.map +1 -1
- package/dist/components/input/Combobox.mjs +232 -156
- package/dist/components/input/Combobox.mjs.map +1 -1
- package/dist/components/input/Combobox.text.cjs +2 -0
- package/dist/components/input/Combobox.text.cjs.map +1 -0
- package/dist/components/input/Combobox.text.mjs +24 -0
- package/dist/components/input/Combobox.text.mjs.map +1 -0
- package/dist/components/input/DatePicker.cjs +1 -1
- package/dist/components/input/DatePicker.cjs.map +1 -1
- package/dist/components/input/DatePicker.mjs +203 -288
- package/dist/components/input/DatePicker.mjs.map +1 -1
- package/dist/components/input/Dropdown.cjs +1 -1
- package/dist/components/input/Dropdown.cjs.map +1 -1
- package/dist/components/input/Dropdown.mjs +135 -109
- package/dist/components/input/Dropdown.mjs.map +1 -1
- package/dist/components/input/Listbox.cjs +2 -0
- package/dist/components/input/Listbox.cjs.map +1 -0
- package/dist/components/input/Listbox.mjs +134 -0
- package/dist/components/input/Listbox.mjs.map +1 -0
- package/dist/components/input/Option.cjs +1 -1
- package/dist/components/input/Option.cjs.map +1 -1
- package/dist/components/input/Option.mjs +163 -97
- package/dist/components/input/Option.mjs.map +1 -1
- package/dist/components/input/SwatchPicker.cjs +1 -1
- package/dist/components/input/SwatchPicker.cjs.map +1 -1
- package/dist/components/input/SwatchPicker.context.cjs +2 -0
- package/dist/components/input/SwatchPicker.context.cjs.map +1 -0
- package/dist/components/input/SwatchPicker.context.mjs +35 -0
- package/dist/components/input/SwatchPicker.context.mjs.map +1 -0
- package/dist/components/input/SwatchPicker.mjs +131 -103
- package/dist/components/input/SwatchPicker.mjs.map +1 -1
- package/dist/components/input/SwatchPicker.swatches.cjs +2 -0
- package/dist/components/input/SwatchPicker.swatches.cjs.map +1 -0
- package/dist/components/input/SwatchPicker.swatches.mjs +207 -0
- package/dist/components/input/SwatchPicker.swatches.mjs.map +1 -0
- package/dist/components/input/TagPicker.cjs +1 -1
- package/dist/components/input/TagPicker.cjs.map +1 -1
- package/dist/components/input/TagPicker.context.cjs +2 -0
- package/dist/components/input/TagPicker.context.cjs.map +1 -0
- package/dist/components/input/TagPicker.context.mjs +20 -0
- package/dist/components/input/TagPicker.context.mjs.map +1 -0
- package/dist/components/input/TagPicker.create.cjs +2 -0
- package/dist/components/input/TagPicker.create.cjs.map +1 -0
- package/dist/components/input/TagPicker.create.mjs +24 -0
- package/dist/components/input/TagPicker.create.mjs.map +1 -0
- package/dist/components/input/TagPicker.mjs +13 -274
- package/dist/components/input/TagPicker.mjs.map +1 -1
- package/dist/components/input/TagPicker.option.cjs +2 -0
- package/dist/components/input/TagPicker.option.cjs.map +1 -0
- package/dist/components/input/TagPicker.option.mjs +45 -0
- package/dist/components/input/TagPicker.option.mjs.map +1 -0
- package/dist/components/input/TagPicker.overflow.cjs +2 -0
- package/dist/components/input/TagPicker.overflow.cjs.map +1 -0
- package/dist/components/input/TagPicker.overflow.mjs +153 -0
- package/dist/components/input/TagPicker.overflow.mjs.map +1 -0
- package/dist/components/input/TagPicker.parts.cjs +2 -0
- package/dist/components/input/TagPicker.parts.cjs.map +1 -0
- package/dist/components/input/TagPicker.parts.mjs +425 -0
- package/dist/components/input/TagPicker.parts.mjs.map +1 -0
- package/dist/components/input/TagPicker.root.cjs +2 -0
- package/dist/components/input/TagPicker.root.cjs.map +1 -0
- package/dist/components/input/TagPicker.root.mjs +416 -0
- package/dist/components/input/TagPicker.root.mjs.map +1 -0
- package/dist/components/input/TimePicker.cjs +1 -1
- package/dist/components/input/TimePicker.cjs.map +1 -1
- package/dist/components/input/TimePicker.mjs +77 -77
- package/dist/components/input/TimePicker.mjs.map +1 -1
- package/dist/components/input/dateUtils.cjs +1 -1
- package/dist/components/input/dateUtils.cjs.map +1 -1
- package/dist/components/input/dateUtils.mjs +114 -96
- package/dist/components/input/dateUtils.mjs.map +1 -1
- package/dist/components/input/pickerLabels.cjs +2 -0
- package/dist/components/input/pickerLabels.cjs.map +1 -0
- package/dist/components/input/pickerLabels.mjs +16 -0
- package/dist/components/input/pickerLabels.mjs.map +1 -0
- package/dist/components/input/pickerValues.cjs +2 -0
- package/dist/components/input/pickerValues.cjs.map +1 -0
- package/dist/components/input/pickerValues.mjs +24 -0
- package/dist/components/input/pickerValues.mjs.map +1 -0
- package/dist/components/layout/Accordion.cjs.map +1 -1
- package/dist/components/layout/Accordion.mjs.map +1 -1
- package/dist/components/navigation/Hamburger.cjs +2 -0
- package/dist/components/navigation/Hamburger.cjs.map +1 -0
- package/dist/components/navigation/Hamburger.mjs +54 -0
- package/dist/components/navigation/Hamburger.mjs.map +1 -0
- package/dist/components/navigation/Nav.cjs +1 -1
- package/dist/components/navigation/Nav.cjs.map +1 -1
- package/dist/components/navigation/Nav.context.cjs +2 -0
- package/dist/components/navigation/Nav.context.cjs.map +1 -0
- package/dist/components/navigation/Nav.context.mjs +137 -0
- package/dist/components/navigation/Nav.context.mjs.map +1 -0
- package/dist/components/navigation/Nav.mjs +151 -258
- package/dist/components/navigation/Nav.mjs.map +1 -1
- package/dist/components/navigation/Nav.parts.cjs +2 -0
- package/dist/components/navigation/Nav.parts.cjs.map +1 -0
- package/dist/components/navigation/Nav.parts.mjs +77 -0
- package/dist/components/navigation/Nav.parts.mjs.map +1 -0
- package/dist/components/navigation/Nav.root.cjs +2 -0
- package/dist/components/navigation/Nav.root.cjs.map +1 -0
- package/dist/components/navigation/Nav.root.mjs +78 -0
- package/dist/components/navigation/Nav.root.mjs.map +1 -0
- package/dist/components/navigation/NavDrawer.cjs +2 -0
- package/dist/components/navigation/NavDrawer.cjs.map +1 -0
- package/dist/components/navigation/NavDrawer.context.cjs +2 -0
- package/dist/components/navigation/NavDrawer.context.cjs.map +1 -0
- package/dist/components/navigation/NavDrawer.context.mjs +11 -0
- package/dist/components/navigation/NavDrawer.context.mjs.map +1 -0
- package/dist/components/navigation/NavDrawer.mjs +179 -0
- package/dist/components/navigation/NavDrawer.mjs.map +1 -0
- package/dist/components/overlays/Dialog.cjs +1 -1
- package/dist/components/overlays/Dialog.cjs.map +1 -1
- package/dist/components/overlays/Dialog.mjs +190 -125
- package/dist/components/overlays/Dialog.mjs.map +1 -1
- package/dist/components/overlays/Dialog.shared.cjs +1 -1
- package/dist/components/overlays/Dialog.shared.cjs.map +1 -1
- package/dist/components/overlays/Dialog.shared.mjs +157 -81
- package/dist/components/overlays/Dialog.shared.mjs.map +1 -1
- package/dist/components/overlays/Dialog.slots.cjs +2 -0
- package/dist/components/overlays/Dialog.slots.cjs.map +1 -0
- package/dist/components/overlays/Dialog.slots.mjs +129 -0
- package/dist/components/overlays/Dialog.slots.mjs.map +1 -0
- package/dist/components/overlays/Drawer.cjs +1 -1
- package/dist/components/overlays/Drawer.cjs.map +1 -1
- package/dist/components/overlays/Drawer.context.cjs +2 -0
- package/dist/components/overlays/Drawer.context.cjs.map +1 -0
- package/dist/components/overlays/Drawer.context.mjs +29 -0
- package/dist/components/overlays/Drawer.context.mjs.map +1 -0
- package/dist/components/overlays/Drawer.mjs +12 -187
- package/dist/components/overlays/Drawer.mjs.map +1 -1
- package/dist/components/overlays/Drawer.panel.cjs +2 -0
- package/dist/components/overlays/Drawer.panel.cjs.map +1 -0
- package/dist/components/overlays/Drawer.panel.mjs +159 -0
- package/dist/components/overlays/Drawer.panel.mjs.map +1 -0
- package/dist/components/overlays/Drawer.parts.cjs +2 -0
- package/dist/components/overlays/Drawer.parts.cjs.map +1 -0
- package/dist/components/overlays/Drawer.parts.mjs +152 -0
- package/dist/components/overlays/Drawer.parts.mjs.map +1 -0
- package/dist/components/overlays/Drawer.root.cjs +2 -0
- package/dist/components/overlays/Drawer.root.cjs.map +1 -0
- package/dist/components/overlays/Drawer.root.mjs +207 -0
- package/dist/components/overlays/Drawer.root.mjs.map +1 -0
- package/dist/components/overlays/Drawer.scroll.cjs +2 -0
- package/dist/components/overlays/Drawer.scroll.cjs.map +1 -0
- package/dist/components/overlays/Drawer.scroll.mjs +42 -0
- package/dist/components/overlays/Drawer.scroll.mjs.map +1 -0
- package/dist/components/table/useGridNavigation.cjs +1 -1
- package/dist/components/table/useGridNavigation.cjs.map +1 -1
- package/dist/components/table/useGridNavigation.mjs +67 -70
- package/dist/components/table/useGridNavigation.mjs.map +1 -1
- package/dist/hooks/useActiveDescendant.cjs +2 -0
- package/dist/hooks/useActiveDescendant.cjs.map +1 -0
- package/dist/hooks/useActiveDescendant.mjs +56 -0
- package/dist/hooks/useActiveDescendant.mjs.map +1 -0
- package/dist/hooks/useDismiss.cjs.map +1 -1
- package/dist/hooks/useDismiss.mjs.map +1 -1
- package/dist/hooks/useFocusTrap.cjs +1 -1
- package/dist/hooks/useFocusTrap.cjs.map +1 -1
- package/dist/hooks/useFocusTrap.mjs +115 -98
- package/dist/hooks/useFocusTrap.mjs.map +1 -1
- package/dist/hooks/useListbox.cjs +1 -1
- package/dist/hooks/useListbox.cjs.map +1 -1
- package/dist/hooks/useListbox.mjs +250 -210
- package/dist/hooks/useListbox.mjs.map +1 -1
- package/dist/hooks/useModalLayer.cjs +1 -1
- package/dist/hooks/useModalLayer.cjs.map +1 -1
- package/dist/hooks/useModalLayer.mjs +35 -22
- package/dist/hooks/useModalLayer.mjs.map +1 -1
- package/dist/hooks/useRestoreFocus.cjs +1 -1
- package/dist/hooks/useRestoreFocus.cjs.map +1 -1
- package/dist/hooks/useRestoreFocus.mjs +91 -78
- package/dist/hooks/useRestoreFocus.mjs.map +1 -1
- package/dist/hooks/useRovingGrid.cjs +2 -0
- package/dist/hooks/useRovingGrid.cjs.map +1 -0
- package/dist/hooks/useRovingGrid.mjs +69 -0
- package/dist/hooks/useRovingGrid.mjs.map +1 -0
- package/dist/hooks/useRovingTabIndex.cjs +1 -1
- package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
- package/dist/hooks/useRovingTabIndex.mjs +102 -78
- package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +4391 -394
- package/dist/index.d.ts +4391 -394
- package/dist/index.mjs +115 -101
- package/dist/lib/classNames.cjs +1 -1
- package/dist/lib/classNames.cjs.map +1 -1
- package/dist/lib/classNames.mjs +170 -74
- package/dist/lib/classNames.mjs.map +1 -1
- package/dist/lib/date.cjs +2 -0
- package/dist/lib/date.cjs.map +1 -0
- package/dist/lib/date.mjs +44 -0
- package/dist/lib/date.mjs.map +1 -0
- package/dist/lib/focus.cjs +1 -1
- package/dist/lib/focus.cjs.map +1 -1
- package/dist/lib/focus.mjs +5 -2
- package/dist/lib/focus.mjs.map +1 -1
- package/dist/lib/icons.cjs +1 -1
- package/dist/lib/icons.cjs.map +1 -1
- package/dist/lib/icons.mjs +13 -6
- package/dist/lib/icons.mjs.map +1 -1
- package/dist/lib/layers.cjs +1 -1
- package/dist/lib/layers.cjs.map +1 -1
- package/dist/lib/layers.mjs +53 -47
- package/dist/lib/layers.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/styles/tokens.css +25 -0
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn as e } from "../../lib/cn.mjs";
|
|
3
3
|
import { getElementType as t } from "../../lib/children.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import { materialiseSlotContent as
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
-
import {
|
|
4
|
+
import { hasWarned as n, isDev as r, warnDeprecated as i, warnOnce as a } from "../../lib/dev.mjs";
|
|
5
|
+
import { materialiseSlotContent as o, renderSlot as s, slotRendersContent as c, slotWrapsDefaultContent as l } from "../../lib/slot.mjs";
|
|
6
|
+
import { composeEventHandlers as u } from "../../lib/composeEventHandlers.mjs";
|
|
7
|
+
import { tagClassNames as d } from "../../lib/classNames.mjs";
|
|
8
|
+
import { useEventCallback as f } from "../../hooks/useEventCallback.mjs";
|
|
9
|
+
import { useId as p } from "../../hooks/useId.mjs";
|
|
10
|
+
import { useMergedRefs as m } from "../../hooks/useMergedRefs.mjs";
|
|
11
|
+
import { focusRing as h, forcedColors as g } from "../../lib/styles.mjs";
|
|
12
|
+
import { Button as _ } from "../button/Button.mjs";
|
|
13
|
+
import { BUTTON_OWN_PROP_KEYS as v, MERGED_DISABLED_FOCUSABLE_PROPS as y, placeButtonIcon as b } from "../button/Button.slots.mjs";
|
|
14
|
+
import { DismissIcon as x } from "../../lib/icons.mjs";
|
|
15
|
+
import { mergeProps as S } from "../../lib/mergeProps.mjs";
|
|
16
|
+
import { hasRenderedTextLabel as C, hasTextLabel as w, observeTextLabel as T } from "../../lib/labelInName.mjs";
|
|
17
|
+
import { isEditableTarget as ee, isOwnEvent as E } from "../../lib/events.mjs";
|
|
18
|
+
import { TagHostContext as D, isDismissKey as O, isRepeatedActivation as te, useDismissControlFocus as ne, useHeldFocus as re, useTagGroupContext as ie, useTagGroupItem as ae } from "./TagGroup.context.mjs";
|
|
19
|
+
import { AvatarSizeContext as oe } from "./Avatar.context.mjs";
|
|
20
|
+
import { TAG_AVATAR_SIZE as se, TAG_DISMISS_BASE_CLASSES as ce, TAG_DISMISS_GLYPH_SIZE as le, TAG_ROOT_BASE_CLASSES as ue, TAG_SECONDARY_TEXT_CLASSES as de, TAG_SELECTED_CLASSES as fe, TAG_TEXT_COLUMN_CLASSES as pe, tagAppearanceClasses as me, tagDismissRingClasses as he, tagDismissSizeClasses as ge, tagDismissStateClasses as _e, tagEndInsetClasses as ve, tagIconClasses as ye, tagMediaClasses as be, tagShapeClasses as xe, tagSizeClasses as Se, tagStartInsetClasses as Ce } from "./tagStyles.mjs";
|
|
21
|
+
import * as k from "react";
|
|
22
|
+
import { jsx as A, jsxs as j } from "react/jsx-runtime";
|
|
16
23
|
//#region src/components/data-display/Tag.tsx
|
|
17
|
-
var
|
|
24
|
+
var M = /* @__PURE__ */ new Set([
|
|
18
25
|
"type",
|
|
19
26
|
"disabled",
|
|
20
27
|
"autoFocus",
|
|
@@ -26,75 +33,75 @@ var w = /* @__PURE__ */ new Set([
|
|
|
26
33
|
"formTarget",
|
|
27
34
|
"name",
|
|
28
35
|
"value"
|
|
29
|
-
]),
|
|
30
|
-
function
|
|
36
|
+
]), N = /^on[A-Z]/, P = /* @__PURE__ */ new Set(["aria-label", "aria-labelledby"]), we = () => {};
|
|
37
|
+
function Te(e) {
|
|
31
38
|
let t = {}, n = !1;
|
|
32
|
-
for (let [r, i] of Object.entries(e))
|
|
39
|
+
for (let [r, i] of Object.entries(e)) P.has(r) ? i !== void 0 && (n = !0) : t[r] = i;
|
|
33
40
|
return {
|
|
34
41
|
props: t,
|
|
35
42
|
ignoredName: n
|
|
36
43
|
};
|
|
37
44
|
}
|
|
38
|
-
var
|
|
39
|
-
function
|
|
40
|
-
if (typeof e != "object" || !e ||
|
|
45
|
+
var F = "inline-flex items-center justify-center";
|
|
46
|
+
function Ee(e) {
|
|
47
|
+
if (typeof e != "object" || !e || k.isValidElement(e) || Symbol.iterator in e) return !1;
|
|
41
48
|
let t = Object.getPrototypeOf(e);
|
|
42
49
|
return t === null || t === Object.prototype;
|
|
43
50
|
}
|
|
44
|
-
function
|
|
45
|
-
return /* @__PURE__ */
|
|
46
|
-
size:
|
|
47
|
-
className:
|
|
51
|
+
function I(e, t) {
|
|
52
|
+
return /* @__PURE__ */ A(x, {
|
|
53
|
+
size: e,
|
|
54
|
+
className: t
|
|
48
55
|
});
|
|
49
56
|
}
|
|
50
|
-
function
|
|
51
|
-
if (!
|
|
57
|
+
function De(n, r) {
|
|
58
|
+
if (!c(n)) return {
|
|
52
59
|
buttonProps: null,
|
|
53
|
-
content:
|
|
60
|
+
content: I(r, d.dismissIcon),
|
|
54
61
|
warning: null,
|
|
55
62
|
ignoredName: !1,
|
|
56
63
|
contentMayName: !1,
|
|
57
64
|
literalTextLabel: !1,
|
|
58
65
|
disabledFocusable: !1
|
|
59
66
|
};
|
|
60
|
-
let
|
|
61
|
-
if (
|
|
62
|
-
let { children: t, dangerouslySetInnerHTML:
|
|
67
|
+
let i = t(n);
|
|
68
|
+
if (k.isValidElement(n) && (i === "button" || i === _)) {
|
|
69
|
+
let { children: t, dangerouslySetInnerHTML: a, ...l } = n.props, u = i === _, f = l;
|
|
63
70
|
if (u) {
|
|
64
|
-
|
|
65
|
-
for (let [e, t] of Object.entries(l))
|
|
71
|
+
f = {};
|
|
72
|
+
for (let [e, t] of Object.entries(l)) v.has(e) || (f[e] = t);
|
|
66
73
|
}
|
|
67
|
-
let
|
|
68
|
-
className:
|
|
69
|
-
dangerouslySetInnerHTML:
|
|
74
|
+
let p = u ? l.icon : void 0, { props: m, ignoredName: h } = Te(f), g = c(p) ? s(p, "span", e(d.dismissIcon, F), { "aria-hidden": !0 }) : null, y = a == null ? o(t) : /* @__PURE__ */ A("span", {
|
|
75
|
+
className: F,
|
|
76
|
+
dangerouslySetInnerHTML: a
|
|
70
77
|
});
|
|
71
78
|
return {
|
|
72
|
-
buttonProps:
|
|
73
|
-
content:
|
|
79
|
+
buttonProps: m,
|
|
80
|
+
content: g || c(y) ? b(g, y, u && l.iconPosition) : I(r, d.dismissIcon),
|
|
74
81
|
warning: "button-element",
|
|
75
|
-
ignoredName:
|
|
82
|
+
ignoredName: h,
|
|
76
83
|
contentMayName: !0,
|
|
77
|
-
literalTextLabel: y
|
|
84
|
+
literalTextLabel: w(y),
|
|
78
85
|
disabledFocusable: u && !!l.disabledFocusable
|
|
79
86
|
};
|
|
80
87
|
}
|
|
81
|
-
if (
|
|
82
|
-
let t = n.as ===
|
|
83
|
-
for (let [e,
|
|
84
|
-
let
|
|
85
|
-
return
|
|
86
|
-
buttonProps:
|
|
87
|
-
content:
|
|
88
|
-
warning:
|
|
89
|
-
ignoredName:
|
|
88
|
+
if (Ee(n)) {
|
|
89
|
+
let t = n.as === _, i = n.as === "button" || t || Object.keys(n).some((e) => M.has(e) || N.test(e)), a = {}, u = {}, f = {}, p = !1;
|
|
90
|
+
for (let [e, r] of Object.entries(n)) e === "as" ? r !== "button" && !t && (u.as = r) : t && v.has(e) ? f[e] = r : P.has(e) ? r !== void 0 && (p = !0) : e === "children" || e === "dangerouslySetInnerHTML" ? u[e] = r : i || e.startsWith("aria-") && e !== "aria-hidden" ? a[e] = r : u[e] = r;
|
|
91
|
+
let m = c(f.icon);
|
|
92
|
+
return m ? u.children = b(s(f.icon, "span", e(d.dismissIcon, F)), o(u.children), f.iconPosition) : l(u.as ?? "span", u) && (u.children = I(r)), {
|
|
93
|
+
buttonProps: i || Object.keys(a).length > 0 ? a : null,
|
|
94
|
+
content: s(u, "span", e(!m && d.dismissIcon, F), { "aria-hidden": !0 }),
|
|
95
|
+
warning: i ? "button-object" : null,
|
|
96
|
+
ignoredName: p,
|
|
90
97
|
contentMayName: !1,
|
|
91
98
|
literalTextLabel: !1,
|
|
92
|
-
disabledFocusable: !!
|
|
99
|
+
disabledFocusable: !!f.disabledFocusable
|
|
93
100
|
};
|
|
94
101
|
}
|
|
95
102
|
return {
|
|
96
103
|
buttonProps: null,
|
|
97
|
-
content:
|
|
104
|
+
content: s(n, "span", e(d.dismissIcon, F), { "aria-hidden": !0 }),
|
|
98
105
|
warning: null,
|
|
99
106
|
ignoredName: !1,
|
|
100
107
|
contentMayName: !1,
|
|
@@ -102,51 +109,176 @@ function M(n) {
|
|
|
102
109
|
disabledFocusable: !1
|
|
103
110
|
};
|
|
104
111
|
}
|
|
105
|
-
var
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
112
|
+
var Oe = /* @__PURE__ */ new Set([
|
|
113
|
+
"button",
|
|
114
|
+
"fieldset",
|
|
115
|
+
"input",
|
|
116
|
+
"optgroup",
|
|
117
|
+
"option",
|
|
118
|
+
"select",
|
|
119
|
+
"textarea"
|
|
120
|
+
]), ke = /* @__PURE__ */ new Set([
|
|
121
|
+
"button",
|
|
122
|
+
"data",
|
|
123
|
+
"input",
|
|
124
|
+
"li",
|
|
125
|
+
"meter",
|
|
126
|
+
"option",
|
|
127
|
+
"progress",
|
|
128
|
+
"select",
|
|
129
|
+
"textarea"
|
|
130
|
+
]), L = {
|
|
131
|
+
disabled: !0,
|
|
132
|
+
"aria-disabled": void 0,
|
|
133
|
+
"data-disabled": void 0,
|
|
134
|
+
"data-disabled-focusable": void 0
|
|
135
|
+
};
|
|
136
|
+
function R(e, t) {
|
|
137
|
+
return typeof e == "string" && Object.hasOwn(t, e);
|
|
138
|
+
}
|
|
139
|
+
function Ae(e) {
|
|
140
|
+
e.preventDefault(), e.stopPropagation();
|
|
141
|
+
}
|
|
142
|
+
function je({ buttonProps: e, content: t, contentMayName: n, literalTextLabel: r, disabledFocusable: i, disabled: a, dismissLabel: o, contentId: s, dismissName: c, buttonRef: l }) {
|
|
143
|
+
let d = p("tag-dismiss"), f = p("tag-dismiss-text"), { ref: h, ...g } = e, _ = k.useRef(null), v = m(_, l, h);
|
|
144
|
+
ne(_);
|
|
145
|
+
let [b, x] = k.useState(null), S = k.useCallback((e) => b ? T(b, e) : we, [b]), w = k.useSyncExternalStore(S, () => b ? C(b) : r, () => r), ee = n && w, E = re(a), D = a ? E.held ? y : L : i ? y : void 0, O = c !== void 0;
|
|
146
|
+
return /* @__PURE__ */ j("button", {
|
|
147
|
+
...g,
|
|
148
|
+
ref: v,
|
|
149
|
+
type: g.type ?? "button",
|
|
150
|
+
...D,
|
|
151
|
+
"aria-label": O ? c : void 0,
|
|
152
|
+
"aria-labelledby": O ? void 0 : `${ee ? f : d} ${s}`,
|
|
153
|
+
onFocus: u(g.onFocus, E.onFocus, { checkDefaultPrevented: !1 }),
|
|
154
|
+
onBlur: u(g.onBlur, E.onBlur, { checkDefaultPrevented: !1 }),
|
|
155
|
+
children: [!O && /* @__PURE__ */ A("span", {
|
|
156
|
+
id: d,
|
|
157
|
+
className: "sr-only",
|
|
158
|
+
children: o
|
|
159
|
+
}), n ? /* @__PURE__ */ A("span", {
|
|
160
|
+
id: f,
|
|
161
|
+
ref: x,
|
|
162
|
+
className: "inline-flex items-center justify-center gap-[inherit]",
|
|
163
|
+
children: t
|
|
164
|
+
}) : t]
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
je.displayName = "TagDismissButton";
|
|
168
|
+
var Me = /* @__PURE__ */ new Set([
|
|
169
|
+
"a",
|
|
170
|
+
"button",
|
|
171
|
+
"input",
|
|
172
|
+
"select",
|
|
173
|
+
"textarea",
|
|
174
|
+
"li"
|
|
175
|
+
]), Ne = "Tag: `as=\"button\"` with `dismissible` puts the Dismiss button inside a button. Use InteractionTag instead: `InteractionTag.Primary` for the action, `InteractionTag.Secondary` for Dismiss.", Pe = "Tag: a dismissible tag rendered as a link (`as=\"a\"` or a link component) puts the Dismiss button inside the link. Put the link in the tag's content: `<Tag dismissible><a href>…</a></Tag>`.", Fe = "TagGroup: a tag in a `role=\"list\"` group is not a list item (its element is a link, a button or a component). Put a link in the tag's content (`<Tag><a href>…</a></Tag>`), or wrap the tag in an element with `role=\"listitem\"`.";
|
|
176
|
+
function Ie(e) {
|
|
177
|
+
for (let t = e; t && !t.matches("[data-wave-tag-group]"); t = t.parentElement) if (t.getAttribute("role") === "listitem" || t.localName === "li") return !0;
|
|
178
|
+
return !1;
|
|
179
|
+
}
|
|
180
|
+
var z = (t) => {
|
|
181
|
+
let { as: l, appearance: _, size: v, shape: y, disabled: b, selected: x = !1, value: C, media: w, icon: T, secondaryText: ne, dismissible: M, onDismiss: N, dismissIcon: P, dismissLabel: we = "Dismiss", className: Te, children: F, role: Ee, hidden: I, onClick: L, onFocus: z, onBlur: Le, onKeyDown: Re, ref: ze, ...Be } = t, B = l ?? "span", Ve = p("tag-content"), V = ie(), He = k.useContext(D), H = k.useRef(null), Ue = m(H, ze), We = k.useRef(null), Ge = k.useRef(null), U = R(v, Se) ? v : V?.size ?? "medium", W = R(_, me) ? _ : V?.appearance ?? "filled", Ke = R(y, xe) ? y : V?.shape ?? "circular", G = (V?.disabled ?? !1) || b === !0, K = M ?? V?.dismissible ?? !1, q = x && !G ? "selected" : W, qe = V?.dimDisabled ?? !0, Je = ae(H, C, { reported: K && (V?.reportsDismissals ?? !1) }), Ye = B === "a", Xe = Ye && G, Ze = B === "button", J = re((Ye || Ze) && G), Y = Ze && J.held, { buttonProps: Qe, content: $e, warning: X, ignoredName: et, contentMayName: tt, literalTextLabel: nt, disabledFocusable: rt } = De(K ? P : void 0, le[U]);
|
|
182
|
+
k.useEffect(() => {
|
|
183
|
+
X === "button-element" ? a("Tag:dismissIcon-button", "Tag: `dismissIcon` received a button. Its props were merged into the built-in dismiss button (a button cannot contain another button), which is named by its text label (or `dismissLabel`) and the tag content. Pass icon content instead, e.g. `dismissIcon={<CloseIcon />}`, and handle the dismissal in `onDismiss`.") : X === "button-object" && i("Tag", "dismissIcon={{ onClick, type, disabled, … }} (button props on the slot object)", "onDismiss and icon content in dismissIcon", "Its props are merged onto the built-in dismiss button, which is named by `dismissLabel` and the tag content.");
|
|
184
|
+
}, [X]);
|
|
185
|
+
let Z = M === void 0 && !(V?.dismissible ?? !1) && (N !== void 0 || P !== void 0);
|
|
186
|
+
k.useEffect(() => {
|
|
187
|
+
Z && a("Tag:dismiss-without-dismissible", "Tag: `onDismiss` and `dismissIcon` take effect only with `dismissible`; no dismiss button was rendered. Add `dismissible` to render it.");
|
|
188
|
+
}, [Z]), k.useEffect(() => {
|
|
189
|
+
et && a("Tag:dismissIcon-name", "Tag: `aria-label`/`aria-labelledby` on `dismissIcon` are ignored. The dismiss button is named by `dismissLabel` (default \"Dismiss\") and the tag content, e.g. \"Dismiss Cherry\"; set `dismissLabel` to change or localise it.");
|
|
190
|
+
}, [et]), k.useEffect(() => {
|
|
191
|
+
if (!K || !r || n("Tag:nested-button")) return;
|
|
192
|
+
let e = H.current?.localName;
|
|
193
|
+
e === "button" ? a("Tag:nested-button", Ne) : e === "a" && a("Tag:nested-button", Pe);
|
|
194
|
+
});
|
|
195
|
+
let it = V?.mode === "list";
|
|
196
|
+
k.useEffect(() => {
|
|
197
|
+
if (!it || !r || n("TagGroup:list-item")) return;
|
|
198
|
+
let e = H.current;
|
|
199
|
+
e && !Ie(e) && a("TagGroup:list-item", Fe);
|
|
200
|
+
});
|
|
201
|
+
let at = c(w), ot = c(T), st = o(ne), ct = c(st), lt = k.useMemo(() => ({ size: se[U] }), [U]), ut = (e) => typeof B != "string" || e.has(B), Q = {};
|
|
202
|
+
ut(Oe) && (G || b !== void 0) && (Q.disabled = G && !Y), Y && (Q["aria-disabled"] = !0, Q["data-disabled-focusable"] = ""), C !== void 0 && ut(ke) && (Q.value = C), Xe && (Q["aria-disabled"] = !0, J.held ? Q["data-disabled-focusable"] = "" : (Q.href = void 0, Q.role = "link"));
|
|
203
|
+
let dt = it && typeof B == "string" && !Me.has(B) ? "listitem" : void 0, ft = C !== void 0 && (V?.hiddenValues?.has(C) ?? !1), pt = Xe || Y ? (e) => {
|
|
204
|
+
E(e) ? Ae(e) : L?.(e);
|
|
205
|
+
} : L, mt = f((e) => {
|
|
206
|
+
let t = We.current, n = Ge.current;
|
|
207
|
+
t && n && O(e) && t.contains(e.target) && !ee(e.target) && (e.preventDefault(), n.click());
|
|
208
|
+
}), $ = {
|
|
117
209
|
type: "button",
|
|
118
|
-
|
|
119
|
-
|
|
210
|
+
"data-wave-tag-dismiss": "",
|
|
211
|
+
className: e(d.dismissButton, ce, ge[U], !G && [
|
|
212
|
+
"disabled:opacity-50",
|
|
213
|
+
"aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:focus-visible:opacity-100",
|
|
214
|
+
_e[q]
|
|
215
|
+
], h, he[U], q === "selected" && "focus-visible:outline-primary-foreground", He?.dismissButtonClassName),
|
|
216
|
+
onKeyDown: (e) => {
|
|
217
|
+
if (e.target === e.currentTarget) {
|
|
218
|
+
if (te(e)) {
|
|
219
|
+
e.preventDefault();
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
O(e) && (e.preventDefault(), e.currentTarget.click());
|
|
223
|
+
}
|
|
224
|
+
}
|
|
120
225
|
};
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
})
|
|
226
|
+
(N || V) && ($.onClick = (e) => {
|
|
227
|
+
E(e) && (N?.(), V?.dismiss(Je));
|
|
228
|
+
});
|
|
229
|
+
let ht = Qe ? S($, Qe) : $, gt = /* @__PURE__ */ A("span", {
|
|
230
|
+
id: Ve,
|
|
231
|
+
ref: We,
|
|
232
|
+
className: e(d.primaryText, "inline-flex items-center gap-1", ct && "text-caption-1 leading-3.5"),
|
|
233
|
+
children: F
|
|
234
|
+
});
|
|
235
|
+
return /* @__PURE__ */ j(B, {
|
|
236
|
+
"data-size": U,
|
|
237
|
+
"data-appearance": W,
|
|
238
|
+
"data-shape": Ke,
|
|
239
|
+
"data-selected": x ? "" : void 0,
|
|
240
|
+
"data-disabled": G ? "" : void 0,
|
|
241
|
+
"data-wave-tag-item": "",
|
|
242
|
+
role: Ee ?? dt,
|
|
243
|
+
hidden: ft || I,
|
|
244
|
+
...Be,
|
|
245
|
+
...Q,
|
|
246
|
+
ref: Ue,
|
|
247
|
+
className: e(d.root, ue, Se[U], Ce[U][at ? "media" : ot ? "icon" : "text"], ve[U][K ? "dismiss" : "text"], q === "selected" ? [fe, g.selectedContainer] : me[W], G && [qe && "opacity-50 focus-visible:opacity-100 has-focus-visible:opacity-100", g.disabled], xe[Ke], Te),
|
|
248
|
+
onClick: pt,
|
|
249
|
+
onKeyDown: u(Re, mt),
|
|
250
|
+
onFocus: u(z, J.onFocus, { checkDefaultPrevented: !1 }),
|
|
251
|
+
onBlur: u(Le, J.onBlur, { checkDefaultPrevented: !1 }),
|
|
252
|
+
children: [
|
|
253
|
+
at && /* @__PURE__ */ A(oe.Provider, {
|
|
254
|
+
value: lt,
|
|
255
|
+
children: s(w, "span", e(d.media, be[U]))
|
|
256
|
+
}),
|
|
257
|
+
ot && s(T, "span", e(d.icon, ye[U]), { "aria-hidden": !0 }),
|
|
258
|
+
ct ? /* @__PURE__ */ j("span", {
|
|
259
|
+
className: pe,
|
|
260
|
+
children: [gt, /* @__PURE__ */ A("span", {
|
|
261
|
+
className: e(d.secondaryText, de),
|
|
262
|
+
children: st
|
|
263
|
+
})]
|
|
264
|
+
}) : gt,
|
|
265
|
+
K && /* @__PURE__ */ A(je, {
|
|
266
|
+
buttonProps: ht,
|
|
267
|
+
content: $e,
|
|
268
|
+
contentMayName: tt,
|
|
269
|
+
literalTextLabel: nt,
|
|
270
|
+
disabledFocusable: rt,
|
|
271
|
+
disabled: G,
|
|
272
|
+
dismissLabel: we,
|
|
273
|
+
contentId: Ve,
|
|
274
|
+
dismissName: He?.dismissName,
|
|
275
|
+
buttonRef: Ge
|
|
276
|
+
})
|
|
277
|
+
]
|
|
146
278
|
});
|
|
147
279
|
};
|
|
148
|
-
|
|
280
|
+
z.displayName = "Tag";
|
|
149
281
|
//#endregion
|
|
150
|
-
export {
|
|
282
|
+
export { z as Tag };
|
|
151
283
|
|
|
152
284
|
//# sourceMappingURL=Tag.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tag.mjs","names":["useId","useId$1","React","BUTTON_ONLY_KEYS","HANDLER_KEY","NAME_KEYS","noop","withoutName","result","ignoredName","key","value","props","iconClassName","isPlainObject","proto","defaultDismissContent","DismissIcon","resolveDismissSlot","slotRendersContent","slot","tagClassNames","elementType","getElementType","Button","markup","elementProps","isWaveButton","slotProps","BUTTON_OWN_PROP_KEYS","icon","buttonProps","iconNode","renderSlot","cn","ownContent","materialiseSlotContent","children","placeButtonIcon","hasTextLabel","asWaveButton","isButtonObject","contentProps","ownProps","hasButtonIcon","slotWrapsDefaultContent","Tag","rest","Component","as","contentId","dismissLabelId","dismissTextId","slotButtonProps","dismissible","dismissIcon","labelTarget","setLabelTarget","subscribeToContent","observeTextLabel","onChange","contentHasTextLabel","hasRenderedTextLabel","literalTextLabel","namedByContent","contentMayName","warning","warnOnce","warnDeprecated","dismissPropsIgnored","onDismiss","ownButtonProps","mergedAriaDisabledClasses","focusRing","dismissButtonProps","mergeProps","className","disabledFocusable","MERGED_DISABLED_FOCUSABLE_PROPS","dismissLabel","content"],"sources":["../../../src/components/data-display/Tag.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { tagClassNames } from '../../lib/classNames';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { mergeProps } from '../../lib/mergeProps';\nimport { getElementType } from '../../lib/children';\nimport {\n materialiseSlotContent,\n renderSlot,\n slotRendersContent,\n slotWrapsDefaultContent,\n} from '../../lib/slot';\nimport { focusRing } from '../../lib/styles';\nimport { DismissIcon } from '../../lib/icons';\nimport { hasRenderedTextLabel, hasTextLabel, observeTextLabel } from '../../lib/labelInName';\nimport type { Slot, SlotObject } from '../../lib/slot';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport { useId } from '../../hooks/useId';\nimport { Button } from '../button/Button';\nimport {\n BUTTON_OWN_PROP_KEYS,\n MERGED_DISABLED_FOCUSABLE_PROPS,\n mergedAriaDisabledClasses,\n placeButtonIcon,\n} from '../button/Button.slots';\n\n/**\n * The Tag's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props only).\n * Every other prop comes from the rendered element (`as`, default `span`).\n */\nexport interface TagOwnProps {\n /**\n * Whether the tag renders a dismiss button. `onDismiss` and `dismissIcon` take effect only with\n * it (a development warning says so when they are passed without it).\n */\n dismissible?: boolean;\n /**\n * Called when the dismiss button is activated (click, Enter or Space). Passing it does not render\n * the dismiss button: set `dismissible` too. When it removes the tag, move focus yourself (see\n * \"Focus after dismissal\" on {@link Tag}).\n */\n onDismiss?: () => void;\n /**\n * Content of the dismiss button (an icon). The Tag always renders its own dismiss\n * `<button type=\"button\">`, wired to `onDismiss` and named by `dismissLabel` plus the tag\n * content; this slot only replaces the icon inside it.\n *\n * A `<button>` element or a Wave `Button` passed here is not nested (a button cannot contain a\n * button): its props are merged into the dismiss button (its `onClick` runs first and can call\n * `preventDefault()` to skip `onDismiss`) and a development warning recommends icon content.\n * A Wave `Button`'s own props are not attributes: its `icon` becomes decorative content before\n * its children (after them with `iconPosition=\"after\"`), `disabledFocusable` makes the dismiss\n * button unavailable but focusable as on the Button (`onDismiss` is not called), and\n * `appearance` and `size` are ignored.\n * A slot object with button props (`type`, `disabled`, event handlers, `as: 'button'` or\n * `as: Button`) is the deprecated 0.4 button-object form: its props (`className`, `id`,\n * `aria-*`, handlers, …) are merged onto the dismiss button, except its content (`children`,\n * `dangerouslySetInnerHTML`, rendered inside the button) and the naming attributes (see below);\n * for `as: Button`, the Button's own props apply as for a `Button` element — pass icon content\n * and use `onDismiss` instead.\n * The `aria-*` attributes of an icon slot object also go to the dismiss button, because the icon\n * is `aria-hidden`.\n *\n * The dismiss button's name is `dismissLabel` plus the tag content (\"Dismiss Cherry\"):\n * `aria-label` and `aria-labelledby` on the slot are ignored (development warning). Icon\n * content is decorative (`aria-hidden`). The children of a merged `<button>`/`Button` (or its\n * `dangerouslySetInnerHTML` markup) are rendered as is inside the dismiss button, next to the\n * decorative `icon` of a Wave `Button`: when they render a text label (at least two letters or\n * digits outside `aria-hidden`/`hidden` content, text from components such as translations\n * included), that text replaces `dismissLabel` in the name, so the name contains the visible\n * label (WCAG 2.5.3): `<button>Remove</button>` or\n * `<Button icon={<CloseIcon />}>Remove</Button>` on \"Cherry\" is named \"Remove Cherry\". An icon or\n * a lone character (`x`, `×`) keeps \"Dismiss Cherry\". Text hidden only with CSS still counts as\n * the label.\n *\n * When the slot renders no content (`[]`, `<></>`, a childless merged button, a slot object\n * without `children`), the default dismiss icon is shown; a slot object then styles it, e.g.\n * `{ className: 'text-error' }`. A slot object that renders a component or a void element\n * (`{ as: CloseIcon }`, `{ as: 'img', src, alt: '' }`) or sets `dangerouslySetInnerHTML` is the\n * icon itself: no default icon is added. Only takes effect with `dismissible`.\n */\n dismissIcon?: Slot<'span'> | SlotObject<'button'>;\n /**\n * Visually hidden text that names the dismiss button together with the tag content\n * (`aria-labelledby`), e.g. \"Dismiss Cherry\". Localise it here. A text label rendered by a\n * merged `<button>` slot replaces it (see `dismissIcon`).\n * @default 'Dismiss'\n */\n dismissLabel?: string;\n}\n\n/**\n * Props of {@link Tag} rendered as `C` (default `'span'`). `TagProps` without a type argument is\n * the 0.4 name.\n */\nexport type TagProps<C extends React.ElementType = 'span'> = PolymorphicProps<C, TagOwnProps>;\n\n/** The props the implementation reads, for any `as` (the public typing is `PolymorphicComponent`). */\ntype TagImplProps = TagOwnProps &\n React.HTMLAttributes<HTMLElement> & {\n as?: React.ElementType;\n ref?: React.Ref<HTMLElement>;\n };\n\ntype UnknownProps = Record<string, unknown>;\n\n/** Attributes that only make sense on the dismiss `<button>` itself. */\nconst BUTTON_ONLY_KEYS: ReadonlySet<string> = new Set([\n 'type',\n 'disabled',\n 'autoFocus',\n 'form',\n 'formAction',\n 'formEncType',\n 'formMethod',\n 'formNoValidate',\n 'formTarget',\n 'name',\n 'value',\n]);\n\nconst HANDLER_KEY = /^on[A-Z]/;\n\n/**\n * Naming attributes a slot cannot set: the Tag names its dismiss button itself\n * (`aria-labelledby` = `dismissLabel` + tag content, data-display#10), so these are dropped.\n */\nconst NAME_KEYS: ReadonlySet<string> = new Set(['aria-label', 'aria-labelledby']);\n\n/** The props of a merged `<button>` or Wave `Button` that the Tag reads itself. */\ninterface WaveButtonSlotProps extends UnknownProps {\n icon?: Slot<'span'>;\n iconPosition?: unknown;\n disabledFocusable?: unknown;\n children?: React.ReactNode;\n dangerouslySetInnerHTML?: React.HTMLAttributes<HTMLElement>['dangerouslySetInnerHTML'];\n}\n\ninterface ResolvedDismissSlot {\n /** Props merged onto the wired dismiss button (`null`: none). */\n buttonProps: UnknownProps | null;\n /** What renders inside the dismiss button. */\n content: React.ReactNode;\n /** Which development warning the slot needs. */\n warning: 'button-element' | 'button-object' | null;\n /** Whether the slot passed `aria-label`/`aria-labelledby`, which the Tag ignores. */\n ignoredName: boolean;\n /**\n * `true` when the content is rendered as is (a merged `<button>`/`Button`), so a text label in it\n * replaces `dismissLabel` in the name (C-SLOTS naming, WCAG 2.5.3); `false` when the content is\n * decorative (`aria-hidden`).\n */\n contentMayName: boolean;\n /**\n * Whether the literal content contains a text label: the name for the server render and the\n * first client render. After mount the rendered content decides.\n */\n literalTextLabel: boolean;\n /**\n * Whether a merged Wave `Button` set `disabledFocusable`: the dismiss button is then unavailable\n * but focusable, as the Button would be.\n */\n disabledFocusable: boolean;\n}\n\nconst noop = () => {};\n\n/** `props` without the naming attributes, and whether any was set. */\nfunction withoutName(props: UnknownProps): { props: UnknownProps; ignoredName: boolean } {\n const result: UnknownProps = {};\n let ignoredName = false;\n for (const [key, value] of Object.entries(props)) {\n if (NAME_KEYS.has(key)) {\n if (value !== undefined) ignoredName = true;\n } else {\n result[key] = value;\n }\n }\n return { props: result, ignoredName };\n}\n\nconst iconClassName = 'inline-flex items-center justify-center';\n\nfunction isPlainObject(value: unknown): value is UnknownProps {\n if (typeof value !== 'object' || value === null) return false;\n if (React.isValidElement(value) || Symbol.iterator in value) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === null || proto === Object.prototype;\n}\n\n/**\n * The decorative default dismiss glyph. It carries the dismiss icon part class when it is the\n * dismiss button's own content, not when the element of a slot object wraps it.\n */\nfunction defaultDismissContent(className?: string): React.ReactNode {\n return <DismissIcon size={12} className={className} />;\n}\n\n/**\n * Splits the dismissIcon slot into dismiss-button props and icon content (C-SLOTS). The icon\n * content is `aria-hidden`, so no attribute that means something to assistive technology stays on\n * it: button-form props go to the dismiss button, and so do the `aria-*` attributes of an icon slot\n * object; the naming attributes are dropped (see {@link NAME_KEYS}).\n *\n * Content that renders nothing (`[]`, `<></>`, a childless merged button, a slot object without\n * `children`) shows the default icon, so the dismiss button is never an empty, invisible Tab stop.\n */\nfunction resolveDismissSlot(slot: TagOwnProps['dismissIcon']): ResolvedDismissSlot {\n if (!slotRendersContent(slot)) {\n return {\n buttonProps: null,\n content: defaultDismissContent(tagClassNames.dismissIcon),\n warning: null,\n ignoredName: false,\n contentMayName: false,\n literalTextLabel: false,\n disabledFocusable: false,\n };\n }\n\n // A `<button>` or a Wave `Button` (also one written in a Server Component, whose type arrives as\n // a lazy reference) is merged into the dismiss button. Its content is rendered as is, after the\n // Button's icon, which is decorative (as in MessageBar and SearchBox); its text label names it.\n const elementType = getElementType(slot as React.ReactNode);\n if (\n React.isValidElement<WaveButtonSlotProps>(slot) &&\n (elementType === 'button' || elementType === Button)\n ) {\n const { children, dangerouslySetInnerHTML: markup, ...elementProps } = slot.props;\n const isWaveButton = elementType === Button;\n let slotProps: UnknownProps = elementProps;\n if (isWaveButton) {\n // Wave Button's own props are not attributes: `icon`, `iconPosition` and\n // `disabledFocusable` are applied here, the others (`appearance`, `size`) are dropped.\n slotProps = {};\n for (const [key, value] of Object.entries(elementProps)) {\n if (!BUTTON_OWN_PROP_KEYS.has(key)) slotProps[key] = value;\n }\n }\n const icon = isWaveButton ? elementProps.icon : undefined;\n const { props: buttonProps, ignoredName } = withoutName(slotProps);\n const iconNode = slotRendersContent(icon)\n ? renderSlot(icon, 'span', cn(tagClassNames.dismissIcon, iconClassName), {\n 'aria-hidden': true,\n })\n : null;\n // A generator is read once by the check; its items are what renders (and names the button).\n // Markup of the merged button (`dangerouslySetInnerHTML`) is its content as well: the dismiss\n // button holds its own name text, so the markup renders in a span inside it.\n const ownContent =\n markup != null ? (\n <span className={iconClassName} dangerouslySetInnerHTML={markup} />\n ) : (\n materialiseSlotContent(children)\n );\n return {\n buttonProps,\n content:\n iconNode || slotRendersContent(ownContent)\n ? placeButtonIcon(iconNode, ownContent, isWaveButton && elementProps.iconPosition)\n : defaultDismissContent(tagClassNames.dismissIcon),\n warning: 'button-element',\n ignoredName,\n contentMayName: true,\n literalTextLabel: hasTextLabel(ownContent),\n disabledFocusable: isWaveButton && Boolean(elementProps.disabledFocusable),\n };\n }\n\n if (isPlainObject(slot)) {\n // 0.4 rendered the whole object as the dismiss element, so an object with button props\n // describes the button: everything but its content goes to the dismiss button. `as: Button`\n // is that form too (a button cannot contain a button); its icon becomes decorative content.\n const asWaveButton = slot.as === Button;\n const isButtonObject =\n slot.as === 'button' ||\n asWaveButton ||\n Object.keys(slot).some((key) => BUTTON_ONLY_KEYS.has(key) || HANDLER_KEY.test(key));\n const buttonProps: UnknownProps = {};\n const contentProps: UnknownProps = {};\n // Wave Button's own props are not attributes: `icon`, `iconPosition` and `disabledFocusable`\n // are applied below, the others (`appearance`, `size`) are dropped.\n const ownProps: UnknownProps = {};\n let ignoredName = false;\n for (const [key, value] of Object.entries(slot)) {\n if (key === 'as') {\n if (value !== 'button' && !asWaveButton) contentProps.as = value;\n } else if (asWaveButton && BUTTON_OWN_PROP_KEYS.has(key)) {\n ownProps[key] = value;\n } else if (NAME_KEYS.has(key)) {\n if (value !== undefined) ignoredName = true;\n } else if (key === 'children' || key === 'dangerouslySetInnerHTML') {\n // Content, also in the button-object form: the dismiss button holds its own name text.\n contentProps[key] = value;\n } else if (isButtonObject || (key.startsWith('aria-') && key !== 'aria-hidden')) {\n buttonProps[key] = value;\n } else {\n contentProps[key] = value;\n }\n }\n // An object without content styles the default icon, e.g. `{ className: 'text-error' }` (as in\n // MessageBar and SearchBox); a Wave Button's icon comes before the content (after it with\n // `iconPosition=\"after\"`).\n // The dismiss icon part is the merged Button's icon element when there is one, else the\n // element this slot object renders (a default glyph inside it stays without the part class).\n const hasButtonIcon = slotRendersContent(ownProps.icon);\n if (hasButtonIcon) {\n contentProps.children = placeButtonIcon(\n renderSlot(\n ownProps.icon as Slot<'span'>,\n 'span',\n cn(tagClassNames.dismissIcon, iconClassName),\n ),\n materialiseSlotContent(contentProps.children),\n ownProps.iconPosition,\n );\n } else if (slotWrapsDefaultContent(contentProps.as ?? 'span', contentProps)) {\n contentProps.children = defaultDismissContent();\n }\n return {\n buttonProps: isButtonObject || Object.keys(buttonProps).length > 0 ? buttonProps : null,\n content: renderSlot(\n contentProps as SlotObject<'span'>,\n 'span',\n cn(!hasButtonIcon && tagClassNames.dismissIcon, iconClassName),\n { 'aria-hidden': true },\n ),\n warning: isButtonObject ? 'button-object' : null,\n ignoredName,\n contentMayName: false,\n literalTextLabel: false,\n disabledFocusable: Boolean(ownProps.disabledFocusable),\n };\n }\n\n return {\n buttonProps: null,\n content: renderSlot(\n slot as Slot<'span'>,\n 'span',\n cn(tagClassNames.dismissIcon, iconClassName),\n {\n 'aria-hidden': true,\n },\n ),\n warning: null,\n ignoredName: false,\n contentMayName: false,\n literalTextLabel: false,\n disabledFocusable: false,\n };\n}\n\n/**\n * A compact label (a \"chip\") for a keyword, category or filter, optionally dismissible.\n *\n * - The dismiss button is a real `<button type=\"button\">` wired to `onDismiss`. Its accessible\n * name is `dismissLabel` plus the tag content (\"Dismiss Cherry\"), so a row of tags has\n * distinguishable dismiss buttons.\n * - `dismissIcon` replaces only the icon inside that button (see {@link TagOwnProps.dismissIcon}).\n * - Polymorphic: `as=\"a\"` renders a link chip with anchor props type-checked.\n *\n * **Focus after dismissal.** A tag cannot keep focus once you remove it. When `onDismiss` removes\n * the tag, move focus to the next tag's dismiss button (else the previous one, else a sensible\n * element nearby); TagGroup (planned) will do this for you. The neighbour stays mounted, so you\n * can focus it in `onDismiss` before removing the tag.\n *\n * @example\n * <Tag>React</Tag>\n * <Tag dismissible onDismiss={() => remove('cherry')}>Cherry</Tag>\n * <Tag dismissible dismissLabel=\"Remove\" dismissIcon={<CloseIcon />}>Cherry</Tag>\n */\nexport const Tag: PolymorphicComponent<'span', TagOwnProps> = (props) => {\n const {\n as,\n dismissible,\n onDismiss,\n dismissIcon,\n dismissLabel = 'Dismiss',\n className,\n children,\n ref,\n ...rest\n } = props as TagImplProps;\n const Component: React.ElementType = as ?? 'span';\n const contentId = useId('tag-content');\n const dismissLabelId = useId('tag-dismiss');\n const dismissTextId = useId('tag-dismiss-text');\n\n const {\n buttonProps: slotButtonProps,\n content,\n warning,\n ignoredName,\n contentMayName,\n literalTextLabel,\n disabledFocusable,\n } = resolveDismissSlot(dismissible ? dismissIcon : undefined);\n\n // C-SLOTS naming (WCAG 2.5.3 Label in Name): the rendered text label of a merged button replaces\n // `dismissLabel` in the name (\"Remove Cherry\"). The literal content decides on the server and on\n // the first 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 namedByContent = contentMayName && contentHasTextLabel;\n\n React.useEffect(() => {\n if (warning === 'button-element') {\n warnOnce(\n 'Tag:dismissIcon-button',\n 'Tag: `dismissIcon` received a button. Its props were merged into the built-in dismiss button (a button cannot contain another button), which is named by its text label (or `dismissLabel`) and the tag content. Pass icon content instead, e.g. `dismissIcon={<CloseIcon />}`, and handle the dismissal in `onDismiss`.',\n );\n } else if (warning === 'button-object') {\n warnDeprecated(\n 'Tag',\n 'dismissIcon={{ onClick, type, disabled, … }} (button props on the slot object)',\n 'onDismiss and icon content in dismissIcon',\n 'Its props are merged onto the built-in dismiss button, which is named by `dismissLabel` and the tag content.',\n );\n }\n }, [warning]);\n\n // `onDismiss`/`dismissIcon` alone render no dismiss button (unlike MessageBar's `onDismiss`).\n // An explicit `dismissible={false}` is a deliberate state, so only a missing flag warns.\n const dismissPropsIgnored =\n dismissible === undefined && (onDismiss !== undefined || dismissIcon !== undefined);\n React.useEffect(() => {\n if (dismissPropsIgnored) {\n warnOnce(\n 'Tag:dismiss-without-dismissible',\n 'Tag: `onDismiss` and `dismissIcon` take effect only with `dismissible`; no dismiss button was rendered. Add `dismissible` to render it.',\n );\n }\n }, [dismissPropsIgnored]);\n\n React.useEffect(() => {\n if (ignoredName) {\n warnOnce(\n 'Tag:dismissIcon-name',\n 'Tag: `aria-label`/`aria-labelledby` on `dismissIcon` are ignored. The dismiss button is named by `dismissLabel` (default \"Dismiss\") and the tag content, e.g. \"Dismiss Cherry\"; set `dismissLabel` to change or localise it.',\n );\n }\n }, [ignoredName]);\n\n const ownButtonProps: UnknownProps = {\n type: 'button',\n className: cn(\n tagClassNames.dismissButton,\n 'inline-flex size-5 shrink-0 items-center justify-center rounded-full border-0 bg-transparent p-0 text-foreground',\n 'not-disabled:not-aria-disabled:hover:bg-subtle-pressed',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n mergedAriaDisabledClasses,\n focusRing,\n ),\n 'aria-labelledby': `${namedByContent ? dismissTextId : dismissLabelId} ${contentId}`,\n };\n if (onDismiss) ownButtonProps.onClick = onDismiss;\n const dismissButtonProps = slotButtonProps\n ? mergeProps(ownButtonProps, slotButtonProps)\n : ownButtonProps;\n\n return (\n <Component\n ref={ref}\n className={cn(\n tagClassNames.root,\n 'inline-flex items-center gap-1 rounded-full bg-muted py-1 ps-3 text-body-1 text-foreground',\n dismissible ? 'pe-1.5' : 'pe-3',\n className,\n )}\n {...rest}\n >\n <span\n id={contentId}\n className={cn(tagClassNames.primaryText, 'inline-flex items-center gap-1')}\n >\n {children}\n </span>\n {dismissible && (\n <button\n {...dismissButtonProps}\n type={(dismissButtonProps.type as 'button' | 'submit' | 'reset' | undefined) ?? 'button'}\n // A merged `disabledFocusable` Button makes the dismiss button unavailable but focusable\n // (spread last: it wins over `disabled` and `onDismiss`).\n {...(disabledFocusable ? MERGED_DISABLED_FOCUSABLE_PROPS : undefined)}\n >\n <span id={dismissLabelId} className=\"sr-only\">\n {dismissLabel}\n </span>\n {contentMayName ? (\n // The merged button's own content, rendered as is: its text label can name the button.\n // `gap-[inherit]` keeps a gap set on the button between the content items.\n <span\n id={dismissTextId}\n ref={setLabelTarget}\n className=\"inline-flex items-center justify-center gap-[inherit]\"\n >\n {content}\n </span>\n ) : (\n content\n )}\n </button>\n )}\n </Component>\n );\n};\n\nTag.displayName = 'Tag';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Tag.mjs","names":["useId","useId$1","React","BUTTON_ONLY_KEYS","HANDLER_KEY","NAME_KEYS","noop","withoutName","result","ignoredName","key","value","props","iconClassName","isPlainObject","proto","defaultDismissContent","DismissIcon","glyphSize","resolveDismissSlot","slotRendersContent","slot","tagClassNames","elementType","getElementType","Button","markup","elementProps","isWaveButton","slotProps","BUTTON_OWN_PROP_KEYS","icon","buttonProps","iconNode","renderSlot","cn","ownContent","materialiseSlotContent","children","placeButtonIcon","hasTextLabel","asWaveButton","isButtonObject","contentProps","ownProps","hasButtonIcon","slotWrapsDefaultContent","NATIVE_DISABLED_ELEMENTS","NATIVE_VALUE_ELEMENTS","NATIVELY_DISABLED_PROPS","isKeyOf","table","blockRootClick","event","TagDismissButton","dismissLabelId","dismissTextId","slotRef","ownRef","mergedRef","useMergedRefs","buttonRef","labelTarget","setLabelTarget","subscribeToContent","observeTextLabel","onChange","contentHasTextLabel","hasRenderedTextLabel","literalTextLabel","namedByContent","contentMayName","hold","useHeldFocus","disabled","stateProps","MERGED_DISABLED_FOCUSABLE_PROPS","disabledFocusable","named","dismissName","contentId","composeEventHandlers","dismissLabel","content","NO_LIST_ITEM_ROLE_ELEMENTS","NESTED_IN_BUTTON_MESSAGE","NESTED_IN_LINK_MESSAGE","LIST_ITEM_MESSAGE","isInListItem","element","root","Tag","appearanceProp","sizeProp","shapeProp","disabledProp","dismissibleProp","rest","Component","as","group","useTagGroupContext","host","TagHostContext","rootRef","ref","primaryTextRef","dismissButtonRef","size","tagSizeClasses","appearance","tagAppearanceClasses","shape","tagShapeClasses","dismissible","look","selected","dimDisabled","reportedValue","useTagGroupItem","isLinkRoot","linkDisabled","isButtonRoot","rootHold","buttonRootHeld","slotButtonProps","dismissIcon","TAG_DISMISS_GLYPH_SIZE","warning","warnOnce","warnDeprecated","dismissPropsIgnored","onDismiss","isDev","hasWarned","inList","hasMedia","media","hasIcon","secondary","secondaryText","hasSecondary","avatarBox","TAG_AVATAR_SIZE","takesNative","elements","listItemRole","hiddenByHost","handleClick","isOwnEvent","onClick","handleRootKeyDown","useEventCallback","text","button","isDismissKey","ownButtonProps","TAG_DISMISS_BASE_CLASSES","tagDismissSizeClasses","tagDismissStateClasses","focusRing","tagDismissRingClasses","isRepeatedActivation","dismissButtonProps","mergeProps","primaryText","role","hidden","TAG_ROOT_BASE_CLASSES","tagStartInsetClasses","tagEndInsetClasses","TAG_SELECTED_CLASSES","forcedColors","className","onKeyDown","onFocus","onBlur","AvatarSizeContext","tagMediaClasses","tagIconClasses","TAG_TEXT_COLUMN_CLASSES","TAG_SECONDARY_TEXT_CLASSES"],"sources":["../../../src/components/data-display/Tag.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { tagClassNames } from '../../lib/classNames';\nimport { hasWarned, isDev, warnDeprecated, warnOnce } from '../../lib/dev';\nimport { mergeProps } from '../../lib/mergeProps';\nimport { getElementType } from '../../lib/children';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { isEditableTarget, isOwnEvent } from '../../lib/events';\nimport {\n materialiseSlotContent,\n renderSlot,\n slotRendersContent,\n slotWrapsDefaultContent,\n} from '../../lib/slot';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport { DismissIcon } from '../../lib/icons';\nimport { hasRenderedTextLabel, hasTextLabel, observeTextLabel } from '../../lib/labelInName';\nimport type { Slot, SlotObject } from '../../lib/slot';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport type { TagAppearance, TagShape, TagSize } from '../../lib/types';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { Button } from '../button/Button';\nimport {\n BUTTON_OWN_PROP_KEYS,\n MERGED_DISABLED_FOCUSABLE_PROPS,\n mergedAriaDisabledClasses,\n placeButtonIcon,\n} from '../button/Button.slots';\nimport { AvatarSizeContext } from './Avatar.context';\nimport {\n TAG_GROUP_SELECTOR,\n TagHostContext,\n isDismissKey,\n isRepeatedActivation,\n useDismissControlFocus,\n useHeldFocus,\n useTagGroupContext,\n useTagGroupItem,\n} from './TagGroup.context';\nimport {\n TAG_AVATAR_SIZE,\n TAG_DISABLED_DIM_CLASSES,\n TAG_DISMISS_BASE_CLASSES,\n TAG_DISMISS_GLYPH_SIZE,\n TAG_DISMISS_SELECTED_RING_CLASSES,\n TAG_PRIMARY_TEXT_TWO_LINE_CLASSES,\n TAG_ROOT_BASE_CLASSES,\n TAG_SECONDARY_TEXT_CLASSES,\n TAG_SELECTED_CLASSES,\n TAG_TEXT_COLUMN_CLASSES,\n tagAppearanceClasses,\n tagDismissRingClasses,\n tagDismissSizeClasses,\n tagDismissStateClasses,\n tagEndInsetClasses,\n tagIconClasses,\n tagMediaClasses,\n tagShapeClasses,\n tagSizeClasses,\n tagStartInsetClasses,\n} from './tagStyles';\nimport type { TagLook } from './tagStyles';\n\n/**\n * The Tag's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props only).\n * Every other prop comes from the rendered element (`as`, default `span`). The own props shadow\n * the element's attributes of the same names: `TagProps<'button'>['value']` is a `string`.\n */\nexport interface TagOwnProps {\n /**\n * Colour scheme: `filled` (a neutral fill), `outline` (a border on the surface behind it) or\n * `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, the 0.10 look), `small` (24px) or `extra-small` (20px); an Avatar in\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, the 0.10 look) or `rounded` (4px corners). Fluent's default is `rounded`.\n * @default the TagGroup's `shape`, else 'circular'\n */\n shape?: TagShape;\n /**\n * Dims the tag and disables its Dismiss button natively (no `onDismiss`, out of the Tab\n * order), whatever `dismissIcon` passes. A disabled TagGroup disables every tag. A Dismiss\n * button that has focus when the tag is disabled keeps it, unavailable, until focus leaves it.\n * Rendered as `data-disabled`. With `as=\"a\"` the link is disabled too: `aria-disabled=\"true\"`,\n * `role=\"link\"`, no `href` (out of the Tab order) and no click; a link that has focus keeps it,\n * and its `href`, until focus leaves it. With another `as`, an element that takes a native\n * `disabled` (a `<button>`) or a component receives `disabled`; a `<button>` that has focus\n * when it is disabled keeps it, unavailable (`aria-disabled`, no click), until focus leaves it.\n * @default false\n */\n disabled?: boolean;\n /**\n * Draws the selected look (the brand fill) and sets `data-selected`. A Tag is not interactive,\n * so the state is not announced: for a tag the user selects, use `InteractionTag` (its\n * `InteractionTag.Primary` is a toggle button). Disabled wins over the selected look.\n * @default false\n */\n selected?: boolean;\n /**\n * Identifies the tag in a TagGroup: the value its `onDismiss` receives (without one, a generated\n * id). Give every tag of a group its own value. Renders nothing on the default `<span>`; with\n * `as`, an element that takes a native `value` (a `<button>`, an `<li>`) still receives it.\n */\n value?: string;\n /**\n * A visual before the text, usually an `Avatar`, which takes the tag's size (24, 20 or 16px)\n * unless it sets its own `size`. Not interactive. It is not hidden from assistive technology:\n * pass `decorative` to an Avatar whose name repeats the tag's text. Use `media` or `icon`, not\n * both.\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 (`secondaryText=\"Designer\"`). It is not part of the\n * Dismiss button's name. A small or extra-small tag grows to 28px to fit it.\n */\n secondaryText?: React.ReactNode;\n /**\n * Whether the tag renders a Dismiss button. `onDismiss` and `dismissIcon` take effect only with\n * it (a development warning says so when they are passed without it). `dismissible={false}`\n * opts a tag out of a dismissible TagGroup. A Dismiss button cannot sit inside a link or a\n * button: a dismissible tag rendered as one holds it inside (a development warning). For a\n * dismissible link chip, put the link in the content,\n * `<Tag dismissible><a href=\"/topics/react\">React</a></Tag>`; for an action with a separate\n * Dismiss button, use `InteractionTag`. Fluent's dismissible Tag is a single button that\n * dismisses when it is activated.\n * @default the TagGroup's `dismissible`, else `false`\n */\n dismissible?: boolean;\n /**\n * Called when the Dismiss button is activated: a click, Enter, Space, Delete or Backspace (a\n * held key dismisses once). Passing it does not render the button: set `dismissible` too. In a\n * TagGroup the group's `onDismiss(value)` is called after it, and focus moves to the next tag\n * when the tag is removed. A standalone Tag cannot keep focus once you remove it: move focus\n * yourself (see \"Focus after dismissal\" on {@link Tag}). Fluent's Tag dismisses on Delete and\n * Backspace only inside a TagGroup.\n */\n onDismiss?: () => void;\n /**\n * Content of the dismiss button (an icon). The Tag always renders its own dismiss\n * `<button type=\"button\">`, wired to `onDismiss` and named by `dismissLabel` plus the tag's text\n * (its children; not `media`, `icon` or `secondaryText`); this slot only replaces the icon\n * inside it.\n *\n * A `<button>` element or a Wave `Button` passed here is not nested (a button cannot contain a\n * button): its props are merged into the dismiss button (its `onClick` runs first and can call\n * `preventDefault()` to skip `onDismiss`) and a development warning recommends icon content.\n * A Wave `Button`'s own props are not attributes: its `icon` becomes decorative content before\n * its children (after them with `iconPosition=\"after\"`), `disabledFocusable` makes the dismiss\n * button unavailable but focusable as on the Button (`onDismiss` is not called), and\n * `appearance` and `size` are ignored.\n * A slot object with button props (`type`, `disabled`, event handlers, `as: 'button'` or\n * `as: Button`) is the deprecated 0.4 button-object form: its props (`className`, `id`,\n * `aria-*`, handlers, …) are merged onto the dismiss button, except its content (`children`,\n * `dangerouslySetInnerHTML`, rendered inside the button) and the naming attributes (see below);\n * for `as: Button`, the Button's own props apply as for a `Button` element — pass icon content\n * and use `onDismiss` instead.\n * The `aria-*` attributes of an icon slot object also go to the dismiss button, because the icon\n * is `aria-hidden`.\n *\n * The dismiss button's name is `dismissLabel` plus the tag's text (\"Dismiss Cherry\"):\n * `aria-label` and `aria-labelledby` on the slot are ignored (development warning). Icon\n * content is decorative (`aria-hidden`). The children of a merged `<button>`/`Button` (or its\n * `dangerouslySetInnerHTML` markup) are rendered as is inside the dismiss button, next to the\n * decorative `icon` of a Wave `Button`: when they render a text label (at least two letters or\n * digits outside `aria-hidden`/`hidden` content, text from components such as translations\n * included), that text replaces `dismissLabel` in the name, so the name contains the visible\n * label (WCAG 2.5.3): `<button>Remove</button>` or\n * `<Button icon={<CloseIcon />}>Remove</Button>` on \"Cherry\" is named \"Remove Cherry\". An icon or\n * a lone character (`x`, `×`) keeps \"Dismiss Cherry\". Text hidden only with CSS still counts as\n * the label.\n *\n * When the slot renders no content (`[]`, `<></>`, a childless merged button, a slot object\n * without `children`), the default dismiss icon is shown; a slot object then styles it, e.g.\n * `{ className: 'text-error' }`. A slot object that renders a component or a void element\n * (`{ as: CloseIcon }`, `{ as: 'img', src, alt: '' }`) or sets `dangerouslySetInnerHTML` is the\n * icon itself: no default icon is added. Only takes effect with `dismissible`.\n */\n dismissIcon?: Slot<'span'> | SlotObject<'button'>;\n /**\n * Visually hidden text that names the dismiss button together with the tag's text (its\n * children; not `media`, `icon` or `secondaryText`; `aria-labelledby`), e.g. \"Dismiss Cherry\".\n * Localise it here. A text label rendered by a merged `<button>` slot replaces it (see\n * `dismissIcon`). TagPicker names the Dismiss buttons of the tags it renders itself with its\n * `labels.remove`.\n * @default 'Dismiss'\n */\n dismissLabel?: string;\n}\n\n/**\n * Props of {@link Tag} rendered as `C` (default `'span'`). `TagProps` without a type argument is\n * the 0.4 name.\n */\nexport type TagProps<C extends React.ElementType = 'span'> = PolymorphicProps<C, TagOwnProps>;\n\n/** The props the implementation reads, for any `as` (the public typing is `PolymorphicComponent`). */\ntype TagImplProps = TagOwnProps &\n React.HTMLAttributes<HTMLElement> & {\n as?: React.ElementType;\n ref?: React.Ref<HTMLElement>;\n };\n\ntype UnknownProps = Record<string, unknown>;\n\n/** Attributes that only make sense on the dismiss `<button>` itself. */\nconst BUTTON_ONLY_KEYS: ReadonlySet<string> = new Set([\n 'type',\n 'disabled',\n 'autoFocus',\n 'form',\n 'formAction',\n 'formEncType',\n 'formMethod',\n 'formNoValidate',\n 'formTarget',\n 'name',\n 'value',\n]);\n\nconst HANDLER_KEY = /^on[A-Z]/;\n\n/**\n * Naming attributes a slot cannot set: the Tag names its dismiss button itself\n * (`aria-labelledby` = `dismissLabel` + tag content, data-display#10), so these are dropped.\n */\nconst NAME_KEYS: ReadonlySet<string> = new Set(['aria-label', 'aria-labelledby']);\n\n/** The props of a merged `<button>` or Wave `Button` that the Tag reads itself. */\ninterface WaveButtonSlotProps extends UnknownProps {\n icon?: Slot<'span'>;\n iconPosition?: unknown;\n disabledFocusable?: unknown;\n children?: React.ReactNode;\n dangerouslySetInnerHTML?: React.HTMLAttributes<HTMLElement>['dangerouslySetInnerHTML'];\n}\n\ninterface ResolvedDismissSlot {\n /** Props merged onto the wired dismiss button (`null`: none). */\n buttonProps: UnknownProps | null;\n /** What renders inside the dismiss button. */\n content: React.ReactNode;\n /** Which development warning the slot needs. */\n warning: 'button-element' | 'button-object' | null;\n /** Whether the slot passed `aria-label`/`aria-labelledby`, which the Tag ignores. */\n ignoredName: boolean;\n /**\n * `true` when the content is rendered as is (a merged `<button>`/`Button`), so a text label in it\n * replaces `dismissLabel` in the name (C-SLOTS naming, WCAG 2.5.3); `false` when the content is\n * decorative (`aria-hidden`).\n */\n contentMayName: boolean;\n /**\n * Whether the literal content contains a text label: the name for the server render and the\n * first client render. After mount the rendered content decides.\n */\n literalTextLabel: boolean;\n /**\n * Whether a merged Wave `Button` set `disabledFocusable`: the dismiss button is then unavailable\n * but focusable, as the Button would be.\n */\n disabledFocusable: boolean;\n}\n\nconst noop = () => {};\n\n/** `props` without the naming attributes, and whether any was set. */\nfunction withoutName(props: UnknownProps): { props: UnknownProps; ignoredName: boolean } {\n const result: UnknownProps = {};\n let ignoredName = false;\n for (const [key, value] of Object.entries(props)) {\n if (NAME_KEYS.has(key)) {\n if (value !== undefined) ignoredName = true;\n } else {\n result[key] = value;\n }\n }\n return { props: result, ignoredName };\n}\n\nconst iconClassName = 'inline-flex items-center justify-center';\n\nfunction isPlainObject(value: unknown): value is UnknownProps {\n if (typeof value !== 'object' || value === null) return false;\n if (React.isValidElement(value) || Symbol.iterator in value) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === null || proto === Object.prototype;\n}\n\n/**\n * The decorative default dismiss glyph (12px, 10px at `extra-small`). It carries the dismiss icon\n * part class when it is the dismiss button's own content, not when the element of a slot object\n * wraps it.\n */\nfunction defaultDismissContent(glyphSize: number, className?: string): React.ReactNode {\n return <DismissIcon size={glyphSize} className={className} />;\n}\n\n/**\n * Splits the dismissIcon slot into dismiss-button props and icon content (C-SLOTS). The icon\n * content is `aria-hidden`, so no attribute that means something to assistive technology stays on\n * it: button-form props go to the dismiss button, and so do the `aria-*` attributes of an icon slot\n * object; the naming attributes are dropped (see {@link NAME_KEYS}).\n *\n * Content that renders nothing (`[]`, `<></>`, a childless merged button, a slot object without\n * `children`) shows the default icon, so the dismiss button is never an empty, invisible Tab stop.\n *\n * @param glyphSize The size (px) of the default glyph, by the tag's size.\n */\nfunction resolveDismissSlot(\n slot: TagOwnProps['dismissIcon'],\n glyphSize: number,\n): ResolvedDismissSlot {\n if (!slotRendersContent(slot)) {\n return {\n buttonProps: null,\n content: defaultDismissContent(glyphSize, tagClassNames.dismissIcon),\n warning: null,\n ignoredName: false,\n contentMayName: false,\n literalTextLabel: false,\n disabledFocusable: false,\n };\n }\n\n // A `<button>` or a Wave `Button` (also one written in a Server Component, whose type arrives as\n // a lazy reference) is merged into the dismiss button. Its content is rendered as is, after the\n // Button's icon, which is decorative (as in MessageBar and SearchBox); its text label names it.\n const elementType = getElementType(slot as React.ReactNode);\n if (\n React.isValidElement<WaveButtonSlotProps>(slot) &&\n (elementType === 'button' || elementType === Button)\n ) {\n const { children, dangerouslySetInnerHTML: markup, ...elementProps } = slot.props;\n const isWaveButton = elementType === Button;\n let slotProps: UnknownProps = elementProps;\n if (isWaveButton) {\n // Wave Button's own props are not attributes: `icon`, `iconPosition` and\n // `disabledFocusable` are applied here, the others (`appearance`, `size`) are dropped.\n slotProps = {};\n for (const [key, value] of Object.entries(elementProps)) {\n if (!BUTTON_OWN_PROP_KEYS.has(key)) slotProps[key] = value;\n }\n }\n const icon = isWaveButton ? elementProps.icon : undefined;\n const { props: buttonProps, ignoredName } = withoutName(slotProps);\n const iconNode = slotRendersContent(icon)\n ? renderSlot(icon, 'span', cn(tagClassNames.dismissIcon, iconClassName), {\n 'aria-hidden': true,\n })\n : null;\n // A generator is read once by the check; its items are what renders (and names the button).\n // Markup of the merged button (`dangerouslySetInnerHTML`) is its content as well: the dismiss\n // button holds its own name text, so the markup renders in a span inside it.\n const ownContent =\n markup != null ? (\n <span className={iconClassName} dangerouslySetInnerHTML={markup} />\n ) : (\n materialiseSlotContent(children)\n );\n return {\n buttonProps,\n content:\n iconNode || slotRendersContent(ownContent)\n ? placeButtonIcon(iconNode, ownContent, isWaveButton && elementProps.iconPosition)\n : defaultDismissContent(glyphSize, tagClassNames.dismissIcon),\n warning: 'button-element',\n ignoredName,\n contentMayName: true,\n literalTextLabel: hasTextLabel(ownContent),\n disabledFocusable: isWaveButton && Boolean(elementProps.disabledFocusable),\n };\n }\n\n if (isPlainObject(slot)) {\n // 0.4 rendered the whole object as the dismiss element, so an object with button props\n // describes the button: everything but its content goes to the dismiss button. `as: Button`\n // is that form too (a button cannot contain a button); its icon becomes decorative content.\n const asWaveButton = slot.as === Button;\n const isButtonObject =\n slot.as === 'button' ||\n asWaveButton ||\n Object.keys(slot).some((key) => BUTTON_ONLY_KEYS.has(key) || HANDLER_KEY.test(key));\n const buttonProps: UnknownProps = {};\n const contentProps: UnknownProps = {};\n // Wave Button's own props are not attributes: `icon`, `iconPosition` and `disabledFocusable`\n // are applied below, the others (`appearance`, `size`) are dropped.\n const ownProps: UnknownProps = {};\n let ignoredName = false;\n for (const [key, value] of Object.entries(slot)) {\n if (key === 'as') {\n if (value !== 'button' && !asWaveButton) contentProps.as = value;\n } else if (asWaveButton && BUTTON_OWN_PROP_KEYS.has(key)) {\n ownProps[key] = value;\n } else if (NAME_KEYS.has(key)) {\n if (value !== undefined) ignoredName = true;\n } else if (key === 'children' || key === 'dangerouslySetInnerHTML') {\n // Content, also in the button-object form: the dismiss button holds its own name text.\n contentProps[key] = value;\n } else if (isButtonObject || (key.startsWith('aria-') && key !== 'aria-hidden')) {\n buttonProps[key] = value;\n } else {\n contentProps[key] = value;\n }\n }\n // An object without content styles the default icon, e.g. `{ className: 'text-error' }` (as in\n // MessageBar and SearchBox); a Wave Button's icon comes before the content (after it with\n // `iconPosition=\"after\"`).\n // The dismiss icon part is the merged Button's icon element when there is one, else the\n // element this slot object renders (a default glyph inside it stays without the part class).\n const hasButtonIcon = slotRendersContent(ownProps.icon);\n if (hasButtonIcon) {\n contentProps.children = placeButtonIcon(\n renderSlot(\n ownProps.icon as Slot<'span'>,\n 'span',\n cn(tagClassNames.dismissIcon, iconClassName),\n ),\n materialiseSlotContent(contentProps.children),\n ownProps.iconPosition,\n );\n } else if (slotWrapsDefaultContent(contentProps.as ?? 'span', contentProps)) {\n contentProps.children = defaultDismissContent(glyphSize);\n }\n return {\n buttonProps: isButtonObject || Object.keys(buttonProps).length > 0 ? buttonProps : null,\n content: renderSlot(\n contentProps as SlotObject<'span'>,\n 'span',\n cn(!hasButtonIcon && tagClassNames.dismissIcon, iconClassName),\n { 'aria-hidden': true },\n ),\n warning: isButtonObject ? 'button-object' : null,\n ignoredName,\n contentMayName: false,\n literalTextLabel: false,\n disabledFocusable: Boolean(ownProps.disabledFocusable),\n };\n }\n\n return {\n buttonProps: null,\n content: renderSlot(\n slot as Slot<'span'>,\n 'span',\n cn(tagClassNames.dismissIcon, iconClassName),\n {\n 'aria-hidden': true,\n },\n ),\n warning: null,\n ignoredName: false,\n contentMayName: false,\n literalTextLabel: false,\n disabledFocusable: false,\n };\n}\n\n/** Elements that take a native `disabled`: a Tag rendered as one of them receives `disabled`. */\nconst NATIVE_DISABLED_ELEMENTS: ReadonlySet<string> = new Set([\n 'button',\n 'fieldset',\n 'input',\n 'optgroup',\n 'option',\n 'select',\n 'textarea',\n]);\n\n/** Elements that take a native `value`: a Tag rendered as one of them receives `value`. */\nconst NATIVE_VALUE_ELEMENTS: ReadonlySet<string> = new Set([\n 'button',\n 'data',\n 'input',\n 'li',\n 'meter',\n 'option',\n 'progress',\n 'select',\n 'textarea',\n]);\n\n/**\n * Spread last on the Dismiss button of a disabled tag: the native `disabled`, whatever a merged\n * slot passed (a merged `disabledFocusable`, `disabled={false}`), without the attributes of the\n * focusable disabled state.\n */\nconst NATIVELY_DISABLED_PROPS = {\n disabled: true,\n 'aria-disabled': undefined,\n 'data-disabled': undefined,\n 'data-disabled-focusable': undefined,\n};\n\ntype FocusHandler = (event: React.FocusEvent<HTMLElement>) => void;\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/**\n * Prevents and stops the click of a disabled link root, or of a held button root, as a natively\n * disabled control's.\n */\nfunction blockRootClick(event: React.MouseEvent<HTMLElement>) {\n event.preventDefault();\n event.stopPropagation();\n}\n\n/** Props of {@link TagDismissButton}. */\ninterface TagDismissButtonProps {\n /** The button's own props merged with the props of a merged slot. */\n buttonProps: UnknownProps;\n /** What renders inside the button: the default glyph, the slot's icon or a merged button's content. */\n content: React.ReactNode;\n /** Whether a text label in `content` names the button (the content of a merged button). */\n contentMayName: boolean;\n /** Whether the literal `content` holds a text label: the server render and the first render. */\n literalTextLabel: boolean;\n /** Whether a merged Wave `Button` set `disabledFocusable`. */\n disabledFocusable: boolean;\n /** The tag's effective `disabled`. */\n disabled: boolean;\n /** The visually hidden first half of the name. */\n dismissLabel: string;\n /** The id of the tag's primary text, the second half of the name. */\n contentId: string;\n /** A host's whole name for the button (`TagHostContext`): `aria-label` alone. */\n dismissName: string | undefined;\n /** Receives the button, so the tag's root can click it (Delete on a link in the tag's text). */\n buttonRef: React.Ref<HTMLButtonElement>;\n}\n\n/**\n * The tag's Dismiss button (internal): named by `dismissLabel`, or a merged button's text label,\n * plus the tag's text; natively disabled with its tag, and kept focusable while it has focus.\n */\nfunction TagDismissButton({\n buttonProps,\n content,\n contentMayName,\n literalTextLabel,\n disabledFocusable,\n disabled,\n dismissLabel,\n contentId,\n dismissName,\n buttonRef,\n}: TagDismissButtonProps) {\n const dismissLabelId = useId('tag-dismiss');\n const dismissTextId = useId('tag-dismiss-text');\n const { ref: slotRef, ...ownProps } = buttonProps;\n const ownRef = React.useRef<HTMLButtonElement>(null);\n const mergedRef = useMergedRefs(ownRef, buttonRef, slotRef as React.Ref<HTMLButtonElement>);\n // Unmounting while it has focus (`dismissible` turning `false`), the button hands focus to its\n // tag's own control (a link in the text), else, in a TagGroup, to the next tag (D35).\n useDismissControlFocus(ownRef);\n\n // C-SLOTS naming (WCAG 2.5.3 Label in Name): the rendered text label of a merged button replaces\n // `dismissLabel` in the name (\"Remove Cherry\"). The literal content decides on the server and on\n // the first 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 namedByContent = contentMayName && contentHasTextLabel;\n\n // A disabled tag disables its button natively (spread last, so no merged slot re-enables it);\n // a button that has focus when its tag is disabled keeps it, unavailable, until focus leaves\n // it (the browser would drop focus to the page). Otherwise a merged `disabledFocusable` Button\n // makes it unavailable but focusable (it wins over `disabled` and `onDismiss`).\n const hold = useHeldFocus(disabled);\n const stateProps = disabled\n ? hold.held\n ? MERGED_DISABLED_FOCUSABLE_PROPS\n : NATIVELY_DISABLED_PROPS\n : disabledFocusable\n ? MERGED_DISABLED_FOCUSABLE_PROPS\n : undefined;\n\n // A host's name (TagPicker's `labels.remove`) is the whole name: no hidden label text joins the\n // tag's own text content.\n const named = dismissName !== undefined;\n return (\n <button\n {...ownProps}\n ref={mergedRef}\n type={(ownProps.type as 'button' | 'submit' | 'reset' | undefined) ?? 'button'}\n {...stateProps}\n aria-label={named ? dismissName : undefined}\n aria-labelledby={\n named ? undefined : `${namedByContent ? dismissTextId : dismissLabelId} ${contentId}`\n }\n onFocus={composeEventHandlers(ownProps.onFocus as FocusHandler | undefined, hold.onFocus, {\n checkDefaultPrevented: false,\n })}\n onBlur={composeEventHandlers(ownProps.onBlur as FocusHandler | undefined, hold.onBlur, {\n checkDefaultPrevented: false,\n })}\n >\n {!named && (\n <span id={dismissLabelId} className=\"sr-only\">\n {dismissLabel}\n </span>\n )}\n {contentMayName ? (\n // The merged button's own content, rendered as is: its text label can name the button.\n // `gap-[inherit]` keeps a gap set on the button between the content items.\n <span\n id={dismissTextId}\n ref={setLabelTarget}\n className=\"inline-flex items-center justify-center gap-[inherit]\"\n >\n {content}\n </span>\n ) : (\n content\n )}\n </button>\n );\n}\nTagDismissButton.displayName = 'TagDismissButton';\n\n/** Elements that never take the `listitem` role in a list TagGroup: interactive, or a list item already. */\nconst NO_LIST_ITEM_ROLE_ELEMENTS: ReadonlySet<string> = new Set([\n 'a',\n 'button',\n 'input',\n 'select',\n 'textarea',\n 'li',\n]);\n\n/** `Tag:nested-button` for a dismissible tag whose element is a button. */\nconst NESTED_IN_BUTTON_MESSAGE =\n 'Tag: `as=\"button\"` with `dismissible` puts the Dismiss button inside a button. Use InteractionTag instead: `InteractionTag.Primary` for the action, `InteractionTag.Secondary` for Dismiss.';\n\n/** `Tag:nested-button` for a dismissible tag whose element is a link. */\nconst NESTED_IN_LINK_MESSAGE =\n 'Tag: a dismissible tag rendered as a link (`as=\"a\"` or a link component) puts the Dismiss button inside the link. Put the link in the tag\\'s content: `<Tag dismissible><a href>…</a></Tag>`.';\n\nconst LIST_ITEM_MESSAGE =\n 'TagGroup: a tag in a `role=\"list\"` group is not a list item (its element is a link, a button or a component). Put a link in the tag\\'s content (`<Tag><a href>…</a></Tag>`), or wrap the tag in an element with `role=\"listitem\"`.';\n\n/**\n * Whether a tag root in a list TagGroup is a list item: it has the role, or an element between it\n * and the group root has it (a wrapping `<li>` or `role=\"listitem\"` element), as the list requires\n * of its children.\n */\nfunction isInListItem(root: HTMLElement): boolean {\n for (\n let element: HTMLElement | null = root;\n element && !element.matches(TAG_GROUP_SELECTOR);\n element = element.parentElement\n ) {\n if (element.getAttribute('role') === 'listitem' || element.localName === 'li') return true;\n }\n return false;\n}\n\n/**\n * A compact label (a \"chip\") for a keyword, category or filter, optionally dismissible.\n *\n * - The dismiss button is a real `<button type=\"button\">` wired to `onDismiss`. Its accessible\n * name is `dismissLabel` plus the tag's text (its children; not `media`, `icon` or\n * `secondaryText`): \"Dismiss Cherry\", so a row of tags has distinguishable dismiss buttons.\n * Enter, Space, Delete and Backspace on it dismiss the tag (a held key dismisses once), and so do\n * Delete and Backspace on a link in the tag's text.\n * - `dismissIcon` replaces only the icon inside that button (see {@link TagOwnProps.dismissIcon}).\n * - The look: `appearance` (`filled`, `outline` or `brand`), `size` (28, 24 or 20px tall),\n * `shape` (`circular` or `rounded`) and the look-only `selected`, rendered as `data-appearance`,\n * `data-size`, `data-shape` and `data-selected`. `disabled` dims the tag and disables its\n * dismiss button natively (`data-disabled`).\n * - Slots before and under the text: `media` (an Avatar, sized for the tag), a decorative `icon`\n * and a second line, `secondaryText`.\n * - In a TagGroup, a tag takes the group's `size`, `appearance`, `shape` and `dismissible` unless\n * it sets its own, is disabled with the group, reports its dismissal to the group's\n * `onDismiss(value)`, and is a list item in a `role=\"list\"` group.\n * - Polymorphic: `as=\"a\"` renders a link chip with anchor props type-checked. A dismissible link\n * chip puts the link in the content, `<Tag dismissible><a href>…</a></Tag>`: a dismiss button\n * cannot sit inside a link.\n *\n * **Focus after dismissal.** A tag cannot keep focus once you remove it. In a TagGroup, focus\n * moves to the next tag for you (else the previous one, else the group's `fallbackFocusRef`). For\n * a standalone tag, move focus to the next tag's dismiss button, else the previous one, else a\n * nearby control, then remove the tag: the neighbour stays mounted, so you can focus it in\n * `onDismiss` before removing the tag.\n *\n * @example\n * <Tag>React</Tag>\n * <Tag appearance=\"brand\" size=\"small\">Beta</Tag>\n * <Tag dismissible onDismiss={() => remove('cherry')}>Cherry</Tag>\n * <Tag media={<Avatar name=\"Katri Athokas\" />} secondaryText=\"Designer\">Katri</Tag>\n * <Tag dismissible dismissLabel=\"Remove\" dismissIcon={<CloseIcon />}>Cherry</Tag>\n */\nexport const Tag: PolymorphicComponent<'span', TagOwnProps> = (props) => {\n const {\n as,\n appearance: appearanceProp,\n size: sizeProp,\n shape: shapeProp,\n disabled: disabledProp,\n selected = false,\n value,\n media,\n icon,\n secondaryText,\n dismissible: dismissibleProp,\n onDismiss,\n dismissIcon,\n dismissLabel = 'Dismiss',\n className,\n children,\n role,\n hidden,\n onClick,\n onFocus,\n onBlur,\n onKeyDown,\n ref,\n ...rest\n } = props as TagImplProps;\n const Component: React.ElementType = as ?? 'span';\n const contentId = useId('tag-content');\n const group = useTagGroupContext();\n const host = React.useContext(TagHostContext);\n const rootRef = React.useRef<HTMLElement>(null);\n const mergedRef = useMergedRefs<HTMLElement>(rootRef, ref);\n const primaryTextRef = React.useRef<HTMLSpanElement>(null);\n const dismissButtonRef = React.useRef<HTMLButtonElement>(null);\n\n // The tag's own look, else its TagGroup's, else the 0.10 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: a tag's own `disabled={false}` cannot re-enable it.\n const disabled = (group?.disabled ?? false) || disabledProp === true;\n const dismissible = dismissibleProp ?? group?.dismissible ?? false;\n // Disabled wins over the selected look; both attributes still reflect the props.\n const look: TagLook = selected && !disabled ? 'selected' : appearance;\n // A host that dims the area holding its tags (TagPicker's disabled control) dims them once.\n const dimDisabled = group?.dimDisabled ?? true;\n\n const reportedValue = useTagGroupItem(rootRef, value, {\n reported: dismissible && (group?.reportsDismissals ?? false),\n });\n\n // A link root is disabled as Nav.Item's link is: `aria-disabled`, `role=\"link\"` and no `href`,\n // so it leaves the Tab order. One that has focus when it is disabled keeps its `href`, and\n // focus, until focus leaves it; so does a button root, which is natively disabled otherwise\n // (the browser would drop its focus to the page).\n const isLinkRoot = Component === 'a';\n const linkDisabled = isLinkRoot && disabled;\n const isButtonRoot = Component === 'button';\n const rootHold = useHeldFocus((isLinkRoot || isButtonRoot) && disabled);\n const buttonRootHeld = isButtonRoot && rootHold.held;\n\n const {\n buttonProps: slotButtonProps,\n content,\n warning,\n ignoredName,\n contentMayName,\n literalTextLabel,\n disabledFocusable,\n } = resolveDismissSlot(dismissible ? dismissIcon : undefined, TAG_DISMISS_GLYPH_SIZE[size]);\n\n React.useEffect(() => {\n if (warning === 'button-element') {\n warnOnce(\n 'Tag:dismissIcon-button',\n 'Tag: `dismissIcon` received a button. Its props were merged into the built-in dismiss button (a button cannot contain another button), which is named by its text label (or `dismissLabel`) and the tag content. Pass icon content instead, e.g. `dismissIcon={<CloseIcon />}`, and handle the dismissal in `onDismiss`.',\n );\n } else if (warning === 'button-object') {\n warnDeprecated(\n 'Tag',\n 'dismissIcon={{ onClick, type, disabled, … }} (button props on the slot object)',\n 'onDismiss and icon content in dismissIcon',\n 'Its props are merged onto the built-in dismiss button, which is named by `dismissLabel` and the tag content.',\n );\n }\n }, [warning]);\n\n // `onDismiss`/`dismissIcon` alone render no dismiss button (unlike MessageBar's `onDismiss`).\n // An explicit `dismissible={false}` is a deliberate state, and a dismissible TagGroup makes the\n // tag dismissible, so only a missing flag warns.\n const dismissPropsIgnored =\n dismissibleProp === undefined &&\n !(group?.dismissible ?? false) &&\n (onDismiss !== undefined || dismissIcon !== undefined);\n React.useEffect(() => {\n if (dismissPropsIgnored) {\n warnOnce(\n 'Tag:dismiss-without-dismissible',\n 'Tag: `onDismiss` and `dismissIcon` take effect only with `dismissible`; no dismiss button was rendered. Add `dismissible` to render it.',\n );\n }\n }, [dismissPropsIgnored]);\n\n React.useEffect(() => {\n if (ignoredName) {\n warnOnce(\n 'Tag:dismissIcon-name',\n 'Tag: `aria-label`/`aria-labelledby` on `dismissIcon` are ignored. The dismiss button is named by `dismissLabel` (default \"Dismiss\") and the tag content, e.g. \"Dismiss Cherry\"; set `dismissLabel` to change or localise it.',\n );\n }\n }, [ignoredName]);\n\n // A Dismiss button inside a link or a button is interactive content inside interactive content\n // (and joins the link's name): the rendered element decides, so a link or button component\n // counts too. The 0.10 DOM still renders.\n React.useEffect(() => {\n if (!dismissible || !isDev || hasWarned('Tag:nested-button')) return;\n const element = rootRef.current?.localName;\n if (element === 'button') warnOnce('Tag:nested-button', NESTED_IN_BUTTON_MESSAGE);\n else if (element === 'a') warnOnce('Tag:nested-button', NESTED_IN_LINK_MESSAGE);\n });\n\n // A list's children must be list items (axe `aria-required-children`): a tag whose element\n // takes no `listitem` role (a link, a button, a component) needs a wrapping list item.\n const inList = group?.mode === 'list';\n React.useEffect(() => {\n if (!inList || !isDev || hasWarned('TagGroup:list-item')) return;\n const root = rootRef.current;\n if (root && !isInListItem(root)) warnOnce('TagGroup:list-item', LIST_ITEM_MESSAGE);\n });\n\n // Slots that render nothing (`''`, `[]`, `<></>`, an empty generator) render no element and\n // 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 // `disabled` and `value` are Tag props: they reach only an element that takes them natively,\n // or a component, never the default span or an anchor.\n const takesNative = (elements: ReadonlySet<string>) =>\n typeof Component !== 'string' || elements.has(Component);\n const elementProps: UnknownProps = {};\n if (takesNative(NATIVE_DISABLED_ELEMENTS) && (disabled || disabledProp !== undefined)) {\n elementProps.disabled = disabled && !buttonRootHeld;\n }\n if (buttonRootHeld) {\n // The focusable disabled state, its click blocked below (D25).\n elementProps['aria-disabled'] = true;\n elementProps['data-disabled-focusable'] = '';\n }\n if (value !== undefined && takesNative(NATIVE_VALUE_ELEMENTS)) elementProps.value = value;\n if (linkDisabled) {\n elementProps['aria-disabled'] = true;\n if (rootHold.held) {\n elementProps['data-disabled-focusable'] = '';\n } else {\n elementProps.href = undefined;\n elementProps.role = 'link';\n }\n }\n\n // In a list TagGroup the root is a list item, unless its element is interactive or a list item\n // already, or a component; the consumer's role wins.\n const listItemRole =\n inList && typeof Component === 'string' && !NO_LIST_ITEM_ROLE_ELEMENTS.has(Component)\n ? 'listitem'\n : 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 handleClick =\n linkDisabled || buttonRootHeld\n ? (event: React.MouseEvent<HTMLElement>) => {\n // A click from a portal opened inside the tag is not the root's (C-COMPOSE).\n if (isOwnEvent(event)) blockRootClick(event);\n else onClick?.(event);\n }\n : onClick;\n\n // Delete and Backspace on a focused element in the tag's text (a link chip's link) dismiss the\n // tag through its Dismiss button's click, which a disabled or held button blocks; never from an\n // editable field (its Backspace edits), the Dismiss button's own keys or a portal opened inside.\n const handleRootKeyDown = useEventCallback((event: React.KeyboardEvent<HTMLElement>) => {\n const text = primaryTextRef.current;\n const button = dismissButtonRef.current;\n if (!text || !button || !isDismissKey(event)) return;\n if (!text.contains(event.target as Node) || isEditableTarget(event.target)) return;\n event.preventDefault();\n button.click();\n });\n\n const ownButtonProps: UnknownProps = {\n type: 'button',\n 'data-wave-tag-dismiss': '',\n className: cn(\n tagClassNames.dismissButton,\n TAG_DISMISS_BASE_CLASSES,\n tagDismissSizeClasses[size],\n // A disabled tag dims itself, so its button dims nothing more and has no hover.\n !disabled && ['disabled:opacity-50', mergedAriaDisabledClasses, tagDismissStateClasses[look]],\n focusRing,\n tagDismissRingClasses[size],\n look === 'selected' && TAG_DISMISS_SELECTED_RING_CLASSES,\n host?.dismissButtonClassName,\n ),\n // Delete and Backspace dismiss as Enter does: through the button's own click, so whatever\n // cancels a click (a merged slot's `preventDefault()`, a held or disabled button) cancels\n // them too. A held key dismisses one tag: the browser clicks a button on every repeated\n // Enter, which would reach the next tag's Dismiss button once focus moved there (D35).\n onKeyDown: (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 if (onDismiss || group) {\n // The tag's own `onDismiss` first, then the group's `onDismiss(value)`, in the same click.\n ownButtonProps.onClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (!isOwnEvent(event)) return;\n onDismiss?.();\n group?.dismiss(reportedValue);\n };\n }\n const dismissButtonProps = slotButtonProps\n ? mergeProps(ownButtonProps, slotButtonProps)\n : ownButtonProps;\n\n const primaryText = (\n <span\n id={contentId}\n ref={primaryTextRef}\n className={cn(\n tagClassNames.primaryText,\n 'inline-flex items-center gap-1',\n hasSecondary && TAG_PRIMARY_TEXT_TWO_LINE_CLASSES,\n )}\n >\n {children}\n </span>\n );\n\n return (\n <Component\n data-size={size}\n data-appearance={appearance}\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 {...elementProps}\n ref={mergedRef}\n className={cn(\n tagClassNames.root,\n TAG_ROOT_BASE_CLASSES,\n tagSizeClasses[size],\n tagStartInsetClasses[size][hasMedia ? 'media' : hasIcon ? 'icon' : 'text'],\n tagEndInsetClasses[size][dismissible ? 'dismiss' : 'text'],\n look === 'selected'\n ? [TAG_SELECTED_CLASSES, forcedColors.selectedContainer]\n : tagAppearanceClasses[appearance],\n disabled && [dimDisabled && TAG_DISABLED_DIM_CLASSES, forcedColors.disabled],\n tagShapeClasses[shape],\n className,\n )}\n onClick={handleClick}\n onKeyDown={composeEventHandlers(onKeyDown, handleRootKeyDown)}\n onFocus={composeEventHandlers(onFocus, rootHold.onFocus, { checkDefaultPrevented: false })}\n onBlur={composeEventHandlers(onBlur, rootHold.onBlur, { checkDefaultPrevented: false })}\n >\n {hasMedia && (\n // An Avatar without its own `size` takes the tag's box; one in `children` keeps its size.\n <AvatarSizeContext.Provider value={avatarBox}>\n {renderSlot(media, 'span', cn(tagClassNames.media, tagMediaClasses[size]))}\n </AvatarSizeContext.Provider>\n )}\n {hasIcon &&\n renderSlot(icon, 'span', cn(tagClassNames.icon, tagIconClasses[size]), {\n 'aria-hidden': true,\n })}\n {hasSecondary ? (\n <span className={TAG_TEXT_COLUMN_CLASSES}>\n {primaryText}\n <span className={cn(tagClassNames.secondaryText, TAG_SECONDARY_TEXT_CLASSES)}>\n {secondary}\n </span>\n </span>\n ) : (\n primaryText\n )}\n {dismissible && (\n <TagDismissButton\n buttonProps={dismissButtonProps}\n content={content}\n contentMayName={contentMayName}\n literalTextLabel={literalTextLabel}\n disabledFocusable={disabledFocusable}\n disabled={disabled}\n dismissLabel={dismissLabel}\n contentId={contentId}\n dismissName={host?.dismissName}\n buttonRef={dismissButtonRef}\n />\n )}\n </Component>\n );\n};\n\nTag.displayName = 'Tag';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/composeEventHandlers.cjs"),i=require("../../lib/classNames.cjs"),a=require("../../hooks/useEventCallback.cjs"),ee=require("../../hooks/useControllable.cjs"),o=require("../../lib/focus.cjs"),te=require("../../hooks/useMergedRefs.cjs"),s=require("../button/Toolbar.navigation.cjs"),ne=require("../../hooks/useFormReset.cjs"),re=require("../internal/HiddenInput.cjs"),c=require("../input/pickerValues.cjs"),l=require("./TagGroup.context.cjs");let u=require("react");u=e.__toESM(u,1);let d=require("react/jsx-runtime");var f={medium:`gap-2`,small:`gap-1.5`,"extra-small":`gap-1`},p=`medium`,m=`filled`,h=`circular`,ie=new Set([`filled`,`outline`,`brand`]),ae=new Set([`circular`,`rounded`]);function g(e){return`TagGroup: several tags share the value "${e}". Give every tag of a group its own \`value\`: \`onDismiss\` and the selection cannot tell them apart.`}var oe='TagGroup: `role="listbox"` is not supported (an option cannot hold a Dismiss button); the group keeps the toolbar keyboard. Use InteractionTags in the default toolbar for selectable tags, or Listbox for a list of values.',se='TagGroup: this toolbar has tags but no control (no Dismiss button, InteractionTag or link). Pass `role="list"` for tags that only display.';function ce(e){let[t]=u.useState(()=>new Map),r=u.useRef(e);return u.useLayoutEffect(()=>{if(r.current=e,e)for(let[e,r]of t)r>1&&n.warnOnce(`TagGroup:duplicate-value:${e}`,g(e))},[t,e]),u.useCallback(e=>{let i=(t.get(e)??0)+1;return t.set(e,i),i>1&&r.current&&n.warnOnce(`TagGroup:duplicate-value:${e}`,g(e)),()=>{let n=(t.get(e)??1)-1;n>0?t.set(e,n):t.delete(e)}},[t])}function le(e){for(let t of e.querySelectorAll(l.TAG_ITEM_SELECTOR))if(t.parentElement?.closest(`[data-wave-tag-group]`)===e)return!0;return!1}function ue(e){for(let t of e.querySelectorAll(s.TOOLBAR_ITEM_SELECTOR))if(!o.isHiddenInput(t)&&!t.hasAttribute(`data-wave-hidden-input`))return!0;return!1}var _=({role:e,orientation:g=`horizontal`,size:_=p,appearance:v=m,shape:y=h,disabled:b=!1,dismissible:x=!1,onDismiss:S,fallbackFocusRef:C,value:de,defaultValue:w,onValueChange:T,name:fe,form:E,required:pe=!1,className:me,onKeyDown:D,onFocus:O,"aria-orientation":k,"aria-disabled":he,ref:ge,children:_e,...ve})=>{let A=e??`toolbar`,j=A===`list`?`list`:`toolbar`,M=j===`toolbar`,N=Object.hasOwn(f,_)?_:p,P=ie.has(v)?v:m,F=ae.has(y)?y:h,I=u.useContext(l.TagGroupHostContext),L=I?.removalFocus??`next-then-previous`,R=I?.hiddenValues,z=I?.dimDisabled??!0,B=u.useRef(null),{containerProps:V}=s.useToolbarNavigation({orientation:g}),ye=te.useMergedRefs(B,M?V.ref:null,ge),[H,U,be]=ee.useControllable(de,w??c.EMPTY_VALUES,e=>T?.([...e])),W=be||w!==void 0||T!==void 0,G=u.useMemo(()=>new Set(H),[H]),K=u.useCallback(e=>W&&G.has(e),[W,G]),q=a.useEventCallback(e=>{W&&!b&&U(t=>c.toggleValue(t,e).values)}),J=a.useEventCallback(e=>{W&&U(t=>t.includes(e)?t.filter(t=>t!==e):t)});ne.useFormReset(B,()=>{W&&U(e=>{let t=w??c.EMPTY_VALUES;return c.sameValues(e,t)?e:[...t]})},E);let Y=()=>{let e=B.current;e&&o.getFirstTabbable(e)?.focus()},X=S!==void 0,Z=ce(X||W),Q=a.useEventCallback(e=>{S?.(e)}),xe=u.useMemo(()=>({mode:j,size:N,appearance:P,shape:F,disabled:b,dismissible:x,dismiss:Q,reportsDismissals:X,selecting:W,isSelected:K,toggle:q,deselect:J,register:Z,rootRef:B,fallbackFocusRef:C,removalFocus:L,hiddenValues:R,dimDisabled:z}),[j,N,P,F,b,x,Q,X,W,K,q,J,Z,C,L,R,z]),$=A===`listbox`;return u.useEffect(()=>{$&&n.warnOnce(`TagGroup:listbox-role`,oe)},[$]),u.useEffect(()=>{if(!n.isDev||!M||b||n.hasWarned(`TagGroup:static-toolbar`))return;let e=B.current;e&&le(e)&&!ue(e)&&n.warnOnce(`TagGroup:static-toolbar`,se)}),(0,d.jsx)(l.TagGroupContext.Provider,{value:xe,children:(0,d.jsx)(l.TagGroupHostContext.Provider,{value:null,children:(0,d.jsxs)(`div`,{"data-orientation":g,"data-size":N,"data-appearance":P,"data-shape":F,"data-disabled":b?``:void 0,"data-wave-tag-group":``,...ve,ref:ye,role:A,"aria-orientation":A===`toolbar`?k??g:k,"aria-disabled":M&&b?!0:he,"data-roving-container":M?``:void 0,onKeyDown:M?r.composeEventHandlers(D,V.onKeyDown):D,onFocus:M?r.composeEventHandlers(O,V.onFocus,{checkDefaultPrevented:!1}):O,className:t.cn(i.tagGroupClassNames.root,`relative inline-flex flex-wrap items-center`,f[N],g===`vertical`&&`flex-col items-start`,me),children:[_e,W&&(0,d.jsx)(re.HiddenInput,{type:`text`,name:fe,form:E,disabled:b,value:H,required:pe,onInvalid:Y})]})})})};_.displayName=`TagGroup`,exports.TagGroup=_;
|
|
2
|
+
//# sourceMappingURL=TagGroup.cjs.map
|