@mattermost/compass-ui 0.1.0-alpha.14 → 0.1.0-alpha.15
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/dist/components/action-button/ActionButton.cjs +1 -1
- package/dist/components/action-button/ActionButton.cjs.map +1 -1
- package/dist/components/action-button/ActionButton.css +1 -1
- package/dist/components/action-button/ActionButton.d.ts +41 -5
- package/dist/components/action-button/ActionButton.d.ts.map +1 -1
- package/dist/components/action-button/ActionButton.js +68 -35
- package/dist/components/action-button/ActionButton.js.map +1 -1
- package/dist/components/action-button/ActionButton.module.scss.cjs +1 -1
- package/dist/components/action-button/ActionButton.module.scss.js +6 -5
- package/dist/components/action-button/ActionButton.module.scss.js.map +1 -1
- package/dist/components/action-button/index.d.ts +1 -1
- package/dist/components/action-button/index.d.ts.map +1 -1
- package/dist/components/button/Button.cjs +1 -1
- package/dist/components/button/Button.cjs.map +1 -1
- package/dist/components/button/Button.css +1 -1
- package/dist/components/button/Button.d.ts +37 -6
- package/dist/components/button/Button.d.ts.map +1 -1
- package/dist/components/button/Button.js +106 -44
- package/dist/components/button/Button.js.map +1 -1
- package/dist/components/button/Button.module.scss.cjs +1 -1
- package/dist/components/button/Button.module.scss.js +16 -15
- package/dist/components/button/Button.module.scss.js.map +1 -1
- package/dist/components/button/index.d.ts +1 -1
- package/dist/components/button/index.d.ts.map +1 -1
- package/dist/components/icon-button/IconButton.cjs +1 -1
- package/dist/components/icon-button/IconButton.cjs.map +1 -1
- package/dist/components/icon-button/IconButton.css +1 -1
- package/dist/components/icon-button/IconButton.d.ts +48 -7
- package/dist/components/icon-button/IconButton.d.ts.map +1 -1
- package/dist/components/icon-button/IconButton.js +136 -62
- package/dist/components/icon-button/IconButton.js.map +1 -1
- package/dist/components/icon-button/IconButton.module.scss.cjs +1 -1
- package/dist/components/icon-button/IconButton.module.scss.js +16 -15
- package/dist/components/icon-button/IconButton.module.scss.js.map +1 -1
- package/dist/components/icon-button/index.d.ts +1 -1
- package/dist/components/icon-button/index.d.ts.map +1 -1
- package/dist/components/right-sidebar-header/RightSidebarHeader.cjs +1 -1
- package/dist/components/right-sidebar-header/RightSidebarHeader.cjs.map +1 -1
- package/dist/components/right-sidebar-header/RightSidebarHeader.d.ts +5 -1
- package/dist/components/right-sidebar-header/RightSidebarHeader.d.ts.map +1 -1
- package/dist/components/right-sidebar-header/RightSidebarHeader.js +60 -48
- package/dist/components/right-sidebar-header/RightSidebarHeader.js.map +1 -1
- package/dist/utils/slot.cjs +2 -0
- package/dist/utils/slot.cjs.map +1 -0
- package/dist/utils/slot.d.ts +46 -0
- package/dist/utils/slot.d.ts.map +1 -0
- package/dist/utils/slot.js +88 -0
- package/dist/utils/slot.js.map +1 -0
- package/package.json +2 -1
|
@@ -1,60 +1,122 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { forwardRef as
|
|
3
|
-
import { IconSlotContext as
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
|
|
1
|
+
import { jsx as e, jsxs as z, Fragment as G } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as H, isValidElement as o } from "react";
|
|
3
|
+
import { IconSlotContext as r } from "../icon/Icon.js";
|
|
4
|
+
import C from "../spinner/Spinner.js";
|
|
5
|
+
import { renderAsChild as J } from "../../utils/slot.js";
|
|
6
|
+
import { toKebab as I } from "../../utils/string.js";
|
|
7
|
+
import a from "./Button.module.scss.js";
|
|
8
|
+
const y = {
|
|
8
9
|
"x-small": "12",
|
|
9
10
|
small: "12",
|
|
10
11
|
medium: "16",
|
|
11
12
|
large: "20"
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
13
|
+
};
|
|
14
|
+
function S({
|
|
15
|
+
appearance: m = "default",
|
|
16
|
+
className: i = "",
|
|
17
|
+
destructive: n = !1,
|
|
18
|
+
emphasis: t = "primary",
|
|
19
|
+
size: d = "medium"
|
|
20
|
+
}) {
|
|
21
|
+
return [
|
|
22
|
+
a.button,
|
|
23
|
+
a[`button--emphasis-${I(t)}`],
|
|
24
|
+
a[`button--size-${I(d)}`],
|
|
25
|
+
m === "inverted" ? a["button--appearance-inverted"] : "",
|
|
26
|
+
n ? a["button--destructive"] : "",
|
|
27
|
+
i
|
|
28
|
+
].filter(Boolean).join(" ");
|
|
29
|
+
}
|
|
30
|
+
const Q = H(function(i, n) {
|
|
31
|
+
if (i.asChild) {
|
|
32
|
+
const {
|
|
33
|
+
appearance: f = "default",
|
|
34
|
+
className: L = "",
|
|
35
|
+
destructive: R = !1,
|
|
36
|
+
emphasis: $ = "primary",
|
|
37
|
+
children: F,
|
|
38
|
+
leadingIcon: v,
|
|
39
|
+
loading: s = !1,
|
|
40
|
+
size: g = "medium",
|
|
41
|
+
trailingIcon: N,
|
|
42
|
+
disabled: K,
|
|
43
|
+
asChild: W,
|
|
44
|
+
...M
|
|
45
|
+
} = i, O = S({
|
|
46
|
+
appearance: f,
|
|
47
|
+
className: L,
|
|
48
|
+
destructive: R,
|
|
49
|
+
emphasis: $,
|
|
50
|
+
size: g
|
|
51
|
+
}), u = y[g], V = s || o(v), Z = !!(K || s), _ = F, k = V ? /* @__PURE__ */ e("span", { className: a["button__icon-slot"], "aria-hidden": !0, children: s ? /* @__PURE__ */ e(
|
|
52
|
+
C,
|
|
53
|
+
{
|
|
54
|
+
size: u,
|
|
55
|
+
inverted: f === "inverted"
|
|
56
|
+
}
|
|
57
|
+
) : /* @__PURE__ */ e(r.Provider, { value: { size: u }, children: v }) }) : null, q = !s && o(N) ? /* @__PURE__ */ e("span", { className: a["button__icon-slot"], "aria-hidden": !0, children: /* @__PURE__ */ e(r.Provider, { value: { size: u }, children: N }) }) : null;
|
|
58
|
+
return J({
|
|
59
|
+
child: _,
|
|
60
|
+
props: {
|
|
61
|
+
...M,
|
|
62
|
+
className: O,
|
|
63
|
+
...s ? { "aria-busy": !0 } : null
|
|
64
|
+
},
|
|
65
|
+
ref: n,
|
|
66
|
+
content: /* @__PURE__ */ z(G, { children: [
|
|
67
|
+
k,
|
|
68
|
+
/* @__PURE__ */ e("span", { className: a.button__label, children: _.props.children }),
|
|
69
|
+
q
|
|
70
|
+
] }),
|
|
71
|
+
disabled: Z,
|
|
72
|
+
disabledClassName: a["button--disabled"]
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
const {
|
|
76
|
+
appearance: t = "default",
|
|
77
|
+
className: d = "",
|
|
78
|
+
destructive: B = !1,
|
|
79
|
+
emphasis: x = "primary",
|
|
80
|
+
children: P,
|
|
81
|
+
leadingIcon: p,
|
|
82
|
+
loading: l = !1,
|
|
83
|
+
size: h = "medium",
|
|
84
|
+
trailingIcon: b,
|
|
85
|
+
disabled: j,
|
|
86
|
+
type: w = "button",
|
|
87
|
+
asChild: T,
|
|
88
|
+
...D
|
|
89
|
+
} = i, A = S({
|
|
90
|
+
appearance: t,
|
|
91
|
+
className: d,
|
|
92
|
+
destructive: B,
|
|
93
|
+
emphasis: x,
|
|
94
|
+
size: h
|
|
95
|
+
}), c = y[h], E = l || o(p);
|
|
96
|
+
return /* @__PURE__ */ z(
|
|
35
97
|
"button",
|
|
36
98
|
{
|
|
37
|
-
ref:
|
|
38
|
-
className:
|
|
39
|
-
type:
|
|
40
|
-
disabled:
|
|
41
|
-
...
|
|
99
|
+
ref: n,
|
|
100
|
+
className: A,
|
|
101
|
+
type: w,
|
|
102
|
+
disabled: !!(j || l),
|
|
103
|
+
...D,
|
|
42
104
|
children: [
|
|
43
|
-
|
|
44
|
-
|
|
105
|
+
E ? /* @__PURE__ */ e("span", { className: a["button__icon-slot"], "aria-hidden": !0, children: l ? /* @__PURE__ */ e(
|
|
106
|
+
C,
|
|
45
107
|
{
|
|
46
|
-
size:
|
|
47
|
-
inverted:
|
|
108
|
+
size: c,
|
|
109
|
+
inverted: t === "inverted"
|
|
48
110
|
}
|
|
49
|
-
) : /* @__PURE__ */ e(
|
|
50
|
-
/* @__PURE__ */ e("span", { className:
|
|
51
|
-
|
|
111
|
+
) : /* @__PURE__ */ e(r.Provider, { value: { size: c }, children: p }) }) : null,
|
|
112
|
+
/* @__PURE__ */ e("span", { className: a.button__label, children: P }),
|
|
113
|
+
!l && o(b) ? /* @__PURE__ */ e("span", { className: a["button__icon-slot"], "aria-hidden": !0, children: /* @__PURE__ */ e(r.Provider, { value: { size: c }, children: b }) }) : null
|
|
52
114
|
]
|
|
53
115
|
}
|
|
54
116
|
);
|
|
55
117
|
});
|
|
56
|
-
|
|
118
|
+
Q.displayName = "Button";
|
|
57
119
|
export {
|
|
58
|
-
|
|
120
|
+
Q as default
|
|
59
121
|
};
|
|
60
122
|
//# sourceMappingURL=Button.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.js","sources":["../../../src/components/button/Button.tsx"],"sourcesContent":["import {\n forwardRef,\n isValidElement,\n type ButtonHTMLAttributes,\n type ReactNode,\n} from 'react';\nimport type { IconSize } from '@/components/icon/Icon';\nimport { IconSlotContext } from '@/components/icon/Icon';\nimport Spinner from '@/components/spinner/Spinner';\nimport type { SpinnerSize } from '@/components/spinner/Spinner';\nimport { toKebab } from '@/utils/string';\nimport styles from './Button.module.scss';\n\nexport type ButtonEmphasis =\n | 'primary'\n | 'secondary'\n | 'tertiary'\n | 'quaternary'\n | 'link';\n\nexport type ButtonSize = 'x-small' | 'small' | 'medium' | 'large';\n\nexport type ButtonAppearance = 'default' | 'inverted';\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** default | inverted (for use on dark backgrounds). Maps to Figma \"Style\". */\n appearance?: ButtonAppearance;\n /** Optional CSS class name. */\n className?: string;\n /** Button label. */\n children: ReactNode;\n /** When true, uses destructive (danger) styling. */\n destructive?: boolean;\n /** Visual emphasis. Default: primary. */\n emphasis?: ButtonEmphasis;\n /** Leading icon — pass `<Icon glyph={<YourIcon />} />`. Button provides the correct size via context; no `size` prop needed on the Icon. */\n leadingIcon?: ReactNode;\n /** When true, shows a Spinner in the leading slot and disables the button. */\n loading?: boolean;\n /** Size variant. Default: medium. */\n size?: ButtonSize;\n /** Trailing icon — pass `<Icon glyph={<YourIcon />} />`. Button provides the correct size via context; no `size` prop needed on the Icon. */\n trailingIcon?: ReactNode;\n}\n\nconst SIZE_ICON_MAP: Record<ButtonSize, IconSize> = {\n 'x-small': '12',\n small: '12',\n medium: '16',\n large: '20',\n};\n\n/**\n * Buttons let people take actions or make decisions with a single tap or click — saving a\n * form, sending a message, confirming a dialog. Compass ships several button variants, each\n * with the same anatomy and rhythm so they feel like members of the same family.\n */\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n appearance = 'default',\n className = '',\n destructive = false,\n emphasis = 'primary',\n children,\n leadingIcon,\n loading = false,\n size = 'medium',\n trailingIcon,\n disabled,\n type = 'button',\n ...rest\n },\n ref,\n) {\n const iconSize = SIZE_ICON_MAP[size];\n const emphasisClass = styles[`button--emphasis-${toKebab(emphasis)}`];\n const sizeClass = styles[`button--size-${toKebab(size)}`];\n const appearanceClass =\n appearance === 'inverted' ? styles['button--appearance-inverted'] : '';\n const destructiveClass = destructive ? styles['button--destructive'] : '';\n\n const rootClass = [\n styles.button,\n emphasisClass,\n sizeClass,\n appearanceClass,\n destructiveClass,\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const supportsIcons = emphasis !== 'link';\n const showLeadingSlot =\n loading || (supportsIcons && isValidElement(leadingIcon));\n\n return (\n <button\n ref={ref}\n className={rootClass}\n type={type}\n disabled={disabled || loading}\n {...rest}\n >\n {showLeadingSlot ? (\n <span className={styles['button__icon-slot']} aria-hidden>\n {loading ? (\n <Spinner\n size={iconSize as SpinnerSize}\n inverted={appearance === 'inverted'}\n />\n ) : (\n <IconSlotContext.Provider value={{ size: iconSize }}>\n {leadingIcon}\n </IconSlotContext.Provider>\n )}\n </span>\n ) : null}\n <span className={styles['button__label']}>{children}</span>\n {supportsIcons && !loading && isValidElement(trailingIcon) ? (\n <span className={styles['button__icon-slot']} aria-hidden>\n <IconSlotContext.Provider value={{ size: iconSize }}>\n {trailingIcon}\n </IconSlotContext.Provider>\n </span>\n ) : null}\n </button>\n );\n});\n\nButton.displayName = 'Button';\n\nexport default Button;\n"],"names":["SIZE_ICON_MAP","Button","forwardRef","appearance","className","destructive","emphasis","children","leadingIcon","loading","size","trailingIcon","disabled","type","rest","ref","iconSize","emphasisClass","styles","toKebab","sizeClass","appearanceClass","destructiveClass","rootClass","supportsIcons","showLeadingSlot","isValidElement","jsxs","jsx","Spinner","IconSlotContext"],"mappings":";;;;;;AA6CA,MAAMA,IAA8C;AAAA,EAClD,WAAW;AAAA,EACX,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACT,GAOMC,IAASC,EAA2C,SACxD;AAAA,EACE,YAAAC,IAAa;AAAA,EACb,WAAAC,IAAY;AAAA,EACZ,aAAAC,IAAc;AAAA,EACd,UAAAC,IAAW;AAAA,EACX,UAAAC;AAAA,EACA,aAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,MAAAC,IAAO;AAAA,EACP,cAAAC;AAAA,EACA,UAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,GAAGC;AACL,GACAC,GACA;AACA,QAAMC,IAAWhB,EAAcU,CAAI,GAC7BO,IAAgBC,EAAO,oBAAoBC,EAAQb,CAAQ,CAAC,EAAE,GAC9Dc,IAAYF,EAAO,gBAAgBC,EAAQT,CAAI,CAAC,EAAE,GAClDW,IACJlB,MAAe,aAAae,EAAO,6BAA6B,IAAI,IAChEI,IAAmBjB,IAAca,EAAO,qBAAqB,IAAI,IAEjEK,IAAY;AAAA,IAChBL,EAAO;AAAA,IACPD;AAAA,IACAG;AAAA,IACAC;AAAA,IACAC;AAAA,IACAlB;AAAA,EAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG,GAELoB,IAAgBlB,MAAa,QAC7BmB,IACJhB,KAAYe,KAAiBE,EAAelB,CAAW;AAEzD,SACE,gBAAAmB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAZ;AAAA,MACA,WAAWQ;AAAA,MACX,MAAAV;AAAA,MACA,UAAUD,KAAYH;AAAA,MACrB,GAAGK;AAAA,MAEH,UAAA;AAAA,QAAAW,IACC,gBAAAG,EAAC,UAAK,WAAWV,EAAO,mBAAmB,GAAG,eAAW,IACtD,UAAAT,IACC,gBAAAmB;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,MAAMb;AAAA,YACN,UAAUb,MAAe;AAAA,UAAA;AAAA,QAAA,IAG3B,gBAAAyB,EAACE,EAAgB,UAAhB,EAAyB,OAAO,EAAE,MAAMd,EAAA,GACtC,UAAAR,GACH,EAAA,CAEJ,IACE;AAAA,0BACH,QAAA,EAAK,WAAWU,EAAO,eAAmB,UAAAX,GAAS;AAAA,QACnDiB,KAAiB,CAACf,KAAWiB,EAAef,CAAY,IACvD,gBAAAiB,EAAC,QAAA,EAAK,WAAWV,EAAO,mBAAmB,GAAG,eAAW,IACvD,UAAA,gBAAAU,EAACE,EAAgB,UAAhB,EAAyB,OAAO,EAAE,MAAMd,EAAA,GACtC,UAAAL,EAAA,CACH,EAAA,CACF,IACE;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AAEDV,EAAO,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Button.js","sources":["../../../src/components/button/Button.tsx"],"sourcesContent":["import {\n forwardRef,\n isValidElement,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefAttributes,\n} from 'react';\nimport type { IconSize } from '@/components/icon/Icon';\nimport { IconSlotContext } from '@/components/icon/Icon';\nimport Spinner from '@/components/spinner/Spinner';\nimport type { SpinnerSize } from '@/components/spinner/Spinner';\nimport { renderAsChild } from '@/utils/slot';\nimport { toKebab } from '@/utils/string';\nimport styles from './Button.module.scss';\n\nexport type ButtonEmphasis =\n | 'primary'\n | 'secondary'\n | 'tertiary'\n | 'quaternary'\n | 'link';\n\nexport type ButtonSize = 'x-small' | 'small' | 'medium' | 'large';\n\nexport type ButtonAppearance = 'default' | 'inverted';\n\ninterface ButtonOwnProps {\n /** default | inverted (for use on dark backgrounds). Maps to Figma \"Style\". */\n appearance?: ButtonAppearance;\n /** Optional CSS class name. */\n className?: string;\n /** When true, uses destructive (danger) styling. */\n destructive?: boolean;\n /** Visual emphasis. Default: primary. */\n emphasis?: ButtonEmphasis;\n /** Leading icon — pass `<Icon glyph={<YourIcon />} />`. Button provides the correct size via context; no `size` prop needed on the Icon. */\n leadingIcon?: ReactNode;\n /** When true, shows a Spinner in the leading slot and disables the button (or blocks navigation when `asChild`). */\n loading?: boolean;\n /** Size variant. Default: medium. */\n size?: ButtonSize;\n /** Trailing icon — pass `<Icon glyph={<YourIcon />} />`. Button provides the correct size via context; no `size` prop needed on the Icon. */\n trailingIcon?: ReactNode;\n /**\n * When true, disables the control. On a native `<button>`, sets the `disabled`\n * attribute. With `asChild`, sets `aria-disabled`, applies disabled styles, and\n * blocks click / middle-click navigation (the link stays focusable).\n */\n disabled?: boolean;\n}\n\nexport interface ButtonProps\n extends ButtonOwnProps, ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * When true, merges Button props onto the single child element instead of\n * rendering a `<button>`. Use with `<a>` or a router `Link`. Default: false.\n */\n asChild?: false;\n /** Button label. */\n children: ReactNode;\n}\n\nexport interface ButtonAsChildProps\n extends\n ButtonOwnProps,\n Omit<HTMLAttributes<HTMLElement>, 'children' | 'color'> {\n /**\n * Merges Button props onto the single child element instead of rendering a\n * `<button>`. The child's own props (`href`, `to`, `target`, …) stay on the\n * child. Do not pass `type` — it is not forwarded.\n */\n asChild: true;\n /** Single element to render as the Button (e.g. `<a>` or `<Link>`). Its children become the label. */\n children: ReactElement;\n}\n\nconst SIZE_ICON_MAP: Record<ButtonSize, IconSize> = {\n 'x-small': '12',\n small: '12',\n medium: '16',\n large: '20',\n};\n\ntype ButtonComponent = {\n (props: ButtonAsChildProps & RefAttributes<HTMLElement>): ReactElement | null;\n (props: ButtonProps & RefAttributes<HTMLButtonElement>): ReactElement | null;\n displayName?: string;\n};\n\nfunction buildRootClass({\n appearance = 'default',\n className = '',\n destructive = false,\n emphasis = 'primary',\n size = 'medium',\n}: {\n appearance?: ButtonAppearance;\n className?: string;\n destructive?: boolean;\n emphasis?: ButtonEmphasis;\n size?: ButtonSize;\n}): string {\n return [\n styles.button,\n styles[`button--emphasis-${toKebab(emphasis)}`],\n styles[`button--size-${toKebab(size)}`],\n appearance === 'inverted' ? styles['button--appearance-inverted'] : '',\n destructive ? styles['button--destructive'] : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n}\n\n/**\n * Buttons let people take actions or make decisions with a single tap or click — saving a\n * form, sending a message, confirming a dialog. Compass ships several button variants, each\n * with the same anatomy and rhythm so they feel like members of the same family.\n *\n * Pass `asChild` with a single `<a>` or router `Link` child to render a navigational CTA\n * with Button styling and anatomy (no nested `<button>`).\n */\nconst Button = forwardRef(function Button(\n props: ButtonProps | ButtonAsChildProps,\n ref: Ref<HTMLButtonElement | HTMLElement>,\n) {\n if (props.asChild) {\n const {\n appearance = 'default',\n className = '',\n destructive = false,\n emphasis = 'primary',\n children,\n leadingIcon,\n loading = false,\n size = 'medium',\n trailingIcon,\n disabled,\n asChild,\n ...rest\n } = props;\n void asChild;\n\n const rootClass = buildRootClass({\n appearance,\n className,\n destructive,\n emphasis,\n size,\n });\n const iconSize = SIZE_ICON_MAP[size];\n const showLeadingSlot = loading || isValidElement(leadingIcon);\n const isDisabled = Boolean(disabled || loading);\n const child = children as ReactElement<{ children?: ReactNode }>;\n\n const leading = showLeadingSlot ? (\n <span className={styles['button__icon-slot']} aria-hidden>\n {loading ? (\n <Spinner\n size={iconSize as SpinnerSize}\n inverted={appearance === 'inverted'}\n />\n ) : (\n <IconSlotContext.Provider value={{ size: iconSize }}>\n {leadingIcon}\n </IconSlotContext.Provider>\n )}\n </span>\n ) : null;\n\n const trailing =\n !loading && isValidElement(trailingIcon) ? (\n <span className={styles['button__icon-slot']} aria-hidden>\n <IconSlotContext.Provider value={{ size: iconSize }}>\n {trailingIcon}\n </IconSlotContext.Provider>\n </span>\n ) : null;\n\n return renderAsChild({\n child,\n props: {\n ...rest,\n className: rootClass,\n ...(loading ? { 'aria-busy': true } : null),\n },\n ref,\n content: (\n <>\n {leading}\n <span className={styles['button__label']}>\n {child.props.children}\n </span>\n {trailing}\n </>\n ),\n disabled: isDisabled,\n disabledClassName: styles['button--disabled'],\n });\n }\n\n const {\n appearance = 'default',\n className = '',\n destructive = false,\n emphasis = 'primary',\n children,\n leadingIcon,\n loading = false,\n size = 'medium',\n trailingIcon,\n disabled,\n type = 'button',\n asChild,\n ...rest\n } = props;\n void asChild;\n\n const rootClass = buildRootClass({\n appearance,\n className,\n destructive,\n emphasis,\n size,\n });\n const iconSize = SIZE_ICON_MAP[size];\n const showLeadingSlot = loading || isValidElement(leadingIcon);\n const isDisabled = Boolean(disabled || loading);\n\n return (\n <button\n ref={ref as Ref<HTMLButtonElement>}\n className={rootClass}\n type={type}\n disabled={isDisabled}\n {...rest}\n >\n {showLeadingSlot ? (\n <span className={styles['button__icon-slot']} aria-hidden>\n {loading ? (\n <Spinner\n size={iconSize as SpinnerSize}\n inverted={appearance === 'inverted'}\n />\n ) : (\n <IconSlotContext.Provider value={{ size: iconSize }}>\n {leadingIcon}\n </IconSlotContext.Provider>\n )}\n </span>\n ) : null}\n <span className={styles['button__label']}>{children}</span>\n {!loading && isValidElement(trailingIcon) ? (\n <span className={styles['button__icon-slot']} aria-hidden>\n <IconSlotContext.Provider value={{ size: iconSize }}>\n {trailingIcon}\n </IconSlotContext.Provider>\n </span>\n ) : null}\n </button>\n );\n}) as ButtonComponent;\n\nButton.displayName = 'Button';\n\nexport default Button;\n"],"names":["SIZE_ICON_MAP","buildRootClass","appearance","className","destructive","emphasis","size","styles","toKebab","Button","forwardRef","props","ref","children","leadingIcon","loading","trailingIcon","disabled","asChild","rest","rootClass","iconSize","showLeadingSlot","isValidElement","isDisabled","child","leading","jsx","Spinner","IconSlotContext","trailing","renderAsChild","jsxs","Fragment","type"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require('./Button.css');const t="
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require('./Button.css');const t="_button_aa8j5_2",a="_button__label_aa8j5_31",e={button:t,"button--disabled":"_button--disabled_aa8j5_28",button__label:a,"button__icon-slot":"_button__icon-slot_aa8j5_35","button--size-x-small":"_button--size-x-small_aa8j5_42","button--size-small":"_button--size-small_aa8j5_49","button--size-medium":"_button--size-medium_aa8j5_56","button--size-large":"_button--size-large_aa8j5_63","button--emphasis-primary":"_button--emphasis-primary_aa8j5_70","button--emphasis-secondary":"_button--emphasis-secondary_aa8j5_84","button--emphasis-tertiary":"_button--emphasis-tertiary_aa8j5_100","button--emphasis-quaternary":"_button--emphasis-quaternary_aa8j5_114","button--emphasis-link":"_button--emphasis-link_aa8j5_127","button--destructive":"_button--destructive_aa8j5_141","button--appearance-inverted":"_button--appearance-inverted_aa8j5_204"};exports.button=t;exports.button__label=a;exports.default=e;
|
|
2
2
|
//# sourceMappingURL=Button.module.scss.cjs.map
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import './Button.css';const t = "
|
|
1
|
+
import './Button.css';const t = "_button_aa8j5_2", a = "_button__label_aa8j5_31", _ = {
|
|
2
2
|
button: t,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
"
|
|
6
|
-
"button--size-small": "_button--size-
|
|
7
|
-
"button--size-
|
|
8
|
-
"button--size-
|
|
9
|
-
"button--
|
|
10
|
-
"button--emphasis-
|
|
11
|
-
"button--emphasis-
|
|
12
|
-
"button--emphasis-
|
|
13
|
-
"button--emphasis-
|
|
14
|
-
"button--
|
|
15
|
-
"button--
|
|
3
|
+
"button--disabled": "_button--disabled_aa8j5_28",
|
|
4
|
+
button__label: a,
|
|
5
|
+
"button__icon-slot": "_button__icon-slot_aa8j5_35",
|
|
6
|
+
"button--size-x-small": "_button--size-x-small_aa8j5_42",
|
|
7
|
+
"button--size-small": "_button--size-small_aa8j5_49",
|
|
8
|
+
"button--size-medium": "_button--size-medium_aa8j5_56",
|
|
9
|
+
"button--size-large": "_button--size-large_aa8j5_63",
|
|
10
|
+
"button--emphasis-primary": "_button--emphasis-primary_aa8j5_70",
|
|
11
|
+
"button--emphasis-secondary": "_button--emphasis-secondary_aa8j5_84",
|
|
12
|
+
"button--emphasis-tertiary": "_button--emphasis-tertiary_aa8j5_100",
|
|
13
|
+
"button--emphasis-quaternary": "_button--emphasis-quaternary_aa8j5_114",
|
|
14
|
+
"button--emphasis-link": "_button--emphasis-link_aa8j5_127",
|
|
15
|
+
"button--destructive": "_button--destructive_aa8j5_141",
|
|
16
|
+
"button--appearance-inverted": "_button--appearance-inverted_aa8j5_204"
|
|
16
17
|
};
|
|
17
18
|
export {
|
|
18
19
|
t as button,
|
|
19
|
-
|
|
20
|
+
a as button__label,
|
|
20
21
|
_ as default
|
|
21
22
|
};
|
|
22
23
|
//# sourceMappingURL=Button.module.scss.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.module.scss.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Button.module.scss.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { default as Button } from './Button';
|
|
2
|
-
export type { ButtonProps, ButtonEmphasis, ButtonSize, ButtonAppearance, } from './Button';
|
|
2
|
+
export type { ButtonProps, ButtonAsChildProps, ButtonEmphasis, ButtonSize, ButtonAppearance, } from './Button';
|
|
3
3
|
export { default as btnStyles } from './Button.module.scss';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/button/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EACV,WAAW,EACX,cAAc,EACd,UAAU,EACV,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/button/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("react/jsx-runtime"),V=require("react"),x=require("../icon/Icon.cjs"),j=require("../spinner/Spinner.cjs"),W=require("../../utils/slot.cjs"),X=require("../../utils/string.cjs"),e=require("./IconButton.module.scss.cjs"),b={"x-small":"12",small:"16",medium:"20",large:"24"};function I({className:m="",count:a,destructive:i=!1,padding:o="default",rounded:l=!1,size:n="medium",style:u="default",active:c=!1,toggled:s}){return[e.default["icon-button"],e.default[`icon-button--size-${X.toKebab(n)}`],o==="compact"?e.default["icon-button--padding-compact"]:"",u==="inverted"?e.default["icon-button--style-inverted"]:"",i?e.default["icon-button--destructive"]:"",l?e.default["icon-button--rounded"]:"",s?e.default["icon-button--toggled"]:"",c?e.default["icon-button--active"]:"",a!==void 0?e.default["icon-button--has-count"]:"",m].filter(Boolean).join(" ")}const B=V.forwardRef(function(a,i){if(a.asChild){const{active:h=!1,className:E="",count:f,destructive:L=!1,icon:M,loading:d=!1,padding:U="default",rounded:Z=!1,size:N="medium",style:C="default",unreadBadge:A=!1,disabled:F,children:K,"aria-label":$,asChild:ee,...k}=a,G=I({className:E,count:f,destructive:L,padding:U,rounded:Z,size:N,style:C,active:h}),p=b[N],H=!!(F||d),J=f!==void 0,Q=t.jsxs(t.Fragment,{children:[t.jsxs("span",{className:e.default["icon-button__icon-slot"],"aria-hidden":!0,children:[d?t.jsx(j.default,{size:p,inverted:C==="inverted"}):t.jsx(x.IconSlotContext.Provider,{value:{size:p},children:M}),A&&!d&&t.jsx("span",{className:e.default["icon-button__unread-badge"]})]}),J&&t.jsx("span",{className:e.default["icon-button__count"],children:f})]});return W.renderAsChild({child:K,props:{...k,className:G,"aria-label":$,"data-active":h?"true":void 0,...d?{"aria-busy":!0}:null},ref:i,content:Q,disabled:H,disabledClassName:e.default["icon-button--disabled"],warnOnChildContent:!0})}const{active:o=!1,className:l="",count:n,destructive:u=!1,icon:c,loading:s=!1,padding:z="default",rounded:S=!1,size:v="medium",style:g="default",toggled:r,unreadBadge:y=!1,disabled:O,type:q="button","aria-label":T,asChild:Y,...R}=a,P=I({className:l,count:n,destructive:u,padding:z,rounded:S,size:v,style:g,active:o,toggled:r}),_=b[v],w=!!(O||s),D=n!==void 0;return t.jsxs("button",{ref:i,className:P,type:q,disabled:w,"aria-label":T,"aria-pressed":r===void 0?void 0:r,"data-active":o?"true":void 0,...R,children:[t.jsxs("span",{className:e.default["icon-button__icon-slot"],"aria-hidden":!0,children:[s?t.jsx(j.default,{size:_,inverted:g==="inverted"}):t.jsx(x.IconSlotContext.Provider,{value:{size:_},children:c}),y&&!s&&t.jsx("span",{className:e.default["icon-button__unread-badge"]})]}),D&&t.jsx("span",{className:e.default["icon-button__count"],children:n})]})});B.displayName="IconButton";exports.ICON_BUTTON_ICON_SIZES=b;exports.default=B;
|
|
2
2
|
//# sourceMappingURL=IconButton.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconButton.cjs","sources":["../../../src/components/icon-button/IconButton.tsx"],"sourcesContent":["import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';\nimport { IconSlotContext } from '@/components/icon/Icon';\nimport Spinner from '@/components/spinner/Spinner';\nimport { toKebab } from '@/utils/string';\nimport styles from './IconButton.module.scss';\n\nexport type IconButtonSize = 'x-small' | 'small' | 'medium' | 'large';\n\n/** Figma \"Style\": Default (light context) | Inverted (dark context). */\nexport type IconButtonStyle = 'default' | 'inverted';\n\nexport type IconButtonPadding = 'default' | 'compact';\n\nexport interface IconButtonProps extends Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n 'style'\n> {\n /** When true, forces the subtler pressed/active visual (lighter than toggled). */\n active?: boolean;\n /** Optional CSS class name. */\n className?: string;\n /** Numeric count shown inline after the icon. Figma: Count. */\n count?: number;\n /** When true, uses destructive (danger) styling. Figma: Destructive. */\n destructive?: boolean;\n /** Icon to show. Pass `<Icon glyph={<YourIcon />} />` — IconButton provides the correct size via context; no `size` prop needed on the Icon. */\n icon: ReactNode;\n /** When true, shows a Spinner in place of the icon and disables the button. */\n loading?: boolean;\n /** Padding variant. Figma: Padding = Default | Compact. */\n padding?: IconButtonPadding;\n /** When true, uses full border radius (pill). Figma: Rounded = On. */\n rounded?: boolean;\n /** Size variant. Figma: Size. Default: Medium. */\n size?: IconButtonSize;\n /** Default | Inverted. Figma: Style (for light vs dark backgrounds). */\n style?: IconButtonStyle;\n /** When true, shows toggled/selected state. Figma: Toggled = On. When omitted, the control is not a toggle. */\n toggled?: boolean;\n /** When true, shows a small unread dot over the icon. Figma: Unread Badge. */\n unreadBadge?: boolean;\n}\n\n/**\n * @deprecated No longer needed — IconButton sets the icon size via context.\n * Pass `<Icon glyph={<YourIcon />} />` without a size prop.\n */\nexport const ICON_BUTTON_ICON_SIZES: Record<\n IconButtonSize,\n '12' | '16' | '20' | '24'\n> = {\n 'x-small': '12',\n small: '16',\n medium: '20',\n large: '24',\n};\n\n/**\n * Icon Buttons are compact, label-free actions for tight surfaces — channel headers, message\n * hover actions, modal dismissals, toolbar slots. They lean on the icon to communicate\n * intent, so every Icon Button must pair with a tooltip or `aria-label` that makes the\n * action explicit.\n */\nconst IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(\n function IconButton(\n {\n active = false,\n className = '',\n count,\n destructive = false,\n icon,\n loading = false,\n padding = 'default',\n rounded = false,\n size = 'medium',\n style = 'default',\n toggled,\n unreadBadge = false,\n disabled,\n type = 'button',\n 'aria-label': ariaLabel,\n ...rest\n },\n ref,\n ) {\n const sizeClass = styles[`icon-button--size-${toKebab(size)}`];\n const paddingClass =\n padding === 'compact' ? styles['icon-button--padding-compact'] : '';\n const styleClass =\n style === 'inverted' ? styles['icon-button--style-inverted'] : '';\n const destructiveClass = destructive\n ? styles['icon-button--destructive']\n : '';\n const roundedClass = rounded ? styles['icon-button--rounded'] : '';\n const toggledClass = toggled ? styles['icon-button--toggled'] : '';\n const activeClass = active ? styles['icon-button--active'] : '';\n const hasCount = count !== undefined;\n const hasCountClass = hasCount ? styles['icon-button--has-count'] : '';\n\n const rootClass = [\n styles['icon-button'],\n sizeClass,\n paddingClass,\n styleClass,\n destructiveClass,\n roundedClass,\n toggledClass,\n activeClass,\n hasCountClass,\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const spinnerSize = ICON_BUTTON_ICON_SIZES[size];\n\n return (\n <button\n ref={ref}\n className={rootClass}\n type={type}\n disabled={disabled || loading}\n aria-label={ariaLabel}\n aria-pressed={toggled === undefined ? undefined : toggled}\n data-active={active ? 'true' : undefined}\n {...rest}\n >\n <span className={styles['icon-button__icon-slot']} aria-hidden>\n {loading ? (\n <Spinner size={spinnerSize} inverted={style === 'inverted'} />\n ) : (\n <IconSlotContext.Provider value={{ size: spinnerSize }}>\n {icon}\n </IconSlotContext.Provider>\n )}\n {unreadBadge && !loading && (\n <span className={styles['icon-button__unread-badge']} />\n )}\n </span>\n {hasCount && (\n <span className={styles['icon-button__count']}>{count}</span>\n )}\n </button>\n );\n },\n);\n\nIconButton.displayName = 'IconButton';\n\nexport default IconButton;\n"],"names":["ICON_BUTTON_ICON_SIZES","IconButton","forwardRef","active","className","count","destructive","icon","loading","padding","rounded","size","style","toggled","unreadBadge","disabled","type","ariaLabel","rest","ref","sizeClass","styles","toKebab","paddingClass","styleClass","destructiveClass","roundedClass","toggledClass","activeClass","hasCount","hasCountClass","rootClass","spinnerSize","jsxs","Spinner","jsx","IconSlotContext"],"mappings":"oTA+CaA,EAGT,CACF,UAAW,KACX,MAAO,KACP,OAAQ,KACR,MAAO,IACT,EAQMC,EAAaC,EAAAA,WACjB,SACE,CACE,OAAAC,EAAS,GACT,UAAAC,EAAY,GACZ,MAAAC,EACA,YAAAC,EAAc,GACd,KAAAC,EACA,QAAAC,EAAU,GACV,QAAAC,EAAU,UACV,QAAAC,EAAU,GACV,KAAAC,EAAO,SACP,MAAAC,EAAQ,UACR,QAAAC,EACA,YAAAC,EAAc,GACd,SAAAC,EACA,KAAAC,EAAO,SACP,aAAcC,EACd,GAAGC,CAAA,EAELC,EACA,CACA,MAAMC,EAAYC,EAAAA,QAAO,qBAAqBC,EAAAA,QAAQX,CAAI,CAAC,EAAE,EACvDY,EACJd,IAAY,UAAYY,EAAAA,QAAO,8BAA8B,EAAI,GAC7DG,EACJZ,IAAU,WAAaS,EAAAA,QAAO,6BAA6B,EAAI,GAC3DI,EAAmBnB,EACrBe,UAAO,0BAA0B,EACjC,GACEK,EAAehB,EAAUW,UAAO,sBAAsB,EAAI,GAC1DM,EAAed,EAAUQ,UAAO,sBAAsB,EAAI,GAC1DO,EAAczB,EAASkB,UAAO,qBAAqB,EAAI,GACvDQ,EAAWxB,IAAU,OACrByB,EAAgBD,EAAWR,UAAO,wBAAwB,EAAI,GAE9DU,EAAY,CAChBV,EAAAA,QAAO,aAAa,EACpBD,EACAG,EACAC,EACAC,EACAC,EACAC,EACAC,EACAE,EACA1B,CAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG,EAEL4B,EAAchC,EAAuBW,CAAI,EAE/C,OACEsB,EAAAA,KAAC,SAAA,CACC,IAAAd,EACA,UAAWY,EACX,KAAAf,EACA,SAAUD,GAAYP,EACtB,aAAYS,EACZ,eAAcJ,IAAY,OAAY,OAAYA,EAClD,cAAaV,EAAS,OAAS,OAC9B,GAAGe,EAEJ,SAAA,CAAAe,OAAC,QAAK,UAAWZ,EAAAA,QAAO,wBAAwB,EAAG,cAAW,GAC3D,SAAA,CAAAb,QACE0B,EAAAA,QAAA,CAAQ,KAAMF,EAAa,SAAUpB,IAAU,WAAY,EAE5DuB,EAAAA,IAACC,kBAAgB,SAAhB,CAAyB,MAAO,CAAE,KAAMJ,CAAA,EACtC,SAAAzB,EACH,EAEDO,GAAe,CAACN,GACf2B,MAAC,QAAK,UAAWd,EAAAA,QAAO,2BAA2B,CAAA,CAAG,CAAA,EAE1D,EACCQ,GACCM,EAAAA,IAAC,OAAA,CAAK,UAAWd,EAAAA,QAAO,oBAAoB,EAAI,SAAAhB,CAAA,CAAM,CAAA,CAAA,CAAA,CAI9D,CACF,EAEAJ,EAAW,YAAc"}
|
|
1
|
+
{"version":3,"file":"IconButton.cjs","sources":["../../../src/components/icon-button/IconButton.tsx"],"sourcesContent":["import {\n forwardRef,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefAttributes,\n} from 'react';\nimport { IconSlotContext } from '@/components/icon/Icon';\nimport Spinner from '@/components/spinner/Spinner';\nimport { renderAsChild } from '@/utils/slot';\nimport { toKebab } from '@/utils/string';\nimport styles from './IconButton.module.scss';\n\nexport type IconButtonSize = 'x-small' | 'small' | 'medium' | 'large';\n\n/** Figma \"Style\": Default (light context) | Inverted (dark context). */\nexport type IconButtonStyle = 'default' | 'inverted';\n\nexport type IconButtonPadding = 'default' | 'compact';\n\ninterface IconButtonOwnProps {\n /** When true, forces the subtler pressed/active visual (lighter than toggled). */\n active?: boolean;\n /** Optional CSS class name. */\n className?: string;\n /** Numeric count shown inline after the icon. Figma: Count. */\n count?: number;\n /** When true, uses destructive (danger) styling. Figma: Destructive. */\n destructive?: boolean;\n /** Icon to show. Pass `<Icon glyph={<YourIcon />} />` — IconButton provides the correct size via context; no `size` prop needed on the Icon. */\n icon: ReactNode;\n /** When true, shows a Spinner in place of the icon and disables the button (or blocks navigation when `asChild`). */\n loading?: boolean;\n /** Padding variant. Figma: Padding = Default | Compact. */\n padding?: IconButtonPadding;\n /** When true, uses full border radius (pill). Figma: Rounded = On. */\n rounded?: boolean;\n /** Size variant. Figma: Size. Default: Medium. */\n size?: IconButtonSize;\n /** Default | Inverted. Figma: Style (for light vs dark backgrounds). Replaces the HTML `style` attribute. */\n style?: IconButtonStyle;\n /** When true, shows a small unread dot over the icon. Figma: Unread Badge. */\n unreadBadge?: boolean;\n /**\n * When true, disables the control. On a native `<button>`, sets the `disabled`\n * attribute. With `asChild`, sets `aria-disabled`, applies disabled styles, and\n * blocks click / middle-click navigation (the link stays focusable).\n */\n disabled?: boolean;\n}\n\nexport interface IconButtonProps\n extends\n IconButtonOwnProps,\n Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'style'> {\n /**\n * When true, merges IconButton props onto the single child element instead of\n * rendering a `<button>`. Use with `<a>` or a router `Link`. Default: false.\n */\n asChild?: false;\n /**\n * When true, shows toggled/selected state. Figma: Toggled = On. When omitted,\n * the control is not a toggle. Only applies to the native `<button>` (maps to\n * `aria-pressed`); not available with `asChild`.\n */\n toggled?: boolean;\n}\n\nexport interface IconButtonAsChildProps\n extends\n IconButtonOwnProps,\n Omit<HTMLAttributes<HTMLElement>, 'children' | 'color' | 'style'> {\n /**\n * Merges IconButton props onto the single child element instead of rendering a\n * `<button>`. The child's own props (`href`, `to`, `target`, …) stay on the\n * child. Do not pass `type` or `toggled` — they are not available on links.\n * Pass an empty child; IconButton supplies the icon anatomy.\n */\n asChild: true;\n /** Single empty element to render as the IconButton (e.g. `<a href=\"…\" />`). */\n children: ReactElement;\n /**\n * Accessible name for the icon-only link. Required with `asChild`. An\n * `aria-label` on the child also satisfies this (child props win).\n */\n 'aria-label': string;\n}\n\n/**\n * @deprecated No longer needed — IconButton sets the icon size via context.\n * Pass `<Icon glyph={<YourIcon />} />` without a size prop.\n */\nexport const ICON_BUTTON_ICON_SIZES: Record<\n IconButtonSize,\n '12' | '16' | '20' | '24'\n> = {\n 'x-small': '12',\n small: '16',\n medium: '20',\n large: '24',\n};\n\ntype IconButtonComponent = {\n (\n props: IconButtonAsChildProps & RefAttributes<HTMLElement>,\n ): ReactElement | null;\n (\n props: IconButtonProps & RefAttributes<HTMLButtonElement>,\n ): ReactElement | null;\n displayName?: string;\n};\n\nfunction buildRootClass({\n className = '',\n count,\n destructive = false,\n padding = 'default',\n rounded = false,\n size = 'medium',\n style = 'default',\n active = false,\n toggled,\n}: {\n className?: string;\n count?: number;\n destructive?: boolean;\n padding?: IconButtonPadding;\n rounded?: boolean;\n size?: IconButtonSize;\n style?: IconButtonStyle;\n active?: boolean;\n toggled?: boolean;\n}): string {\n return [\n styles['icon-button'],\n styles[`icon-button--size-${toKebab(size)}`],\n padding === 'compact' ? styles['icon-button--padding-compact'] : '',\n style === 'inverted' ? styles['icon-button--style-inverted'] : '',\n destructive ? styles['icon-button--destructive'] : '',\n rounded ? styles['icon-button--rounded'] : '',\n toggled ? styles['icon-button--toggled'] : '',\n active ? styles['icon-button--active'] : '',\n count !== undefined ? styles['icon-button--has-count'] : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n}\n\n/**\n * Icon Buttons are compact, label-free actions for tight surfaces — channel headers, message\n * hover actions, modal dismissals, toolbar slots. They lean on the icon to communicate\n * intent, so every Icon Button must pair with a tooltip or `aria-label` that makes the\n * action explicit.\n *\n * Pass `asChild` with a single empty `<a>` or router `Link` child to render a navigational\n * icon control with Icon Button styling (no nested `<button>`).\n */\nconst IconButton = forwardRef(function IconButton(\n props: IconButtonProps | IconButtonAsChildProps,\n ref: Ref<HTMLButtonElement | HTMLElement>,\n) {\n if (props.asChild) {\n const {\n active = false,\n className = '',\n count,\n destructive = false,\n icon,\n loading = false,\n padding = 'default',\n rounded = false,\n size = 'medium',\n style = 'default',\n unreadBadge = false,\n disabled,\n children,\n 'aria-label': ariaLabel,\n asChild,\n ...rest\n } = props;\n void asChild;\n\n const rootClass = buildRootClass({\n className,\n count,\n destructive,\n padding,\n rounded,\n size,\n style,\n active,\n });\n const spinnerSize = ICON_BUTTON_ICON_SIZES[size];\n const isDisabled = Boolean(disabled || loading);\n const hasCount = count !== undefined;\n\n const anatomy = (\n <>\n <span className={styles['icon-button__icon-slot']} aria-hidden>\n {loading ? (\n <Spinner size={spinnerSize} inverted={style === 'inverted'} />\n ) : (\n <IconSlotContext.Provider value={{ size: spinnerSize }}>\n {icon}\n </IconSlotContext.Provider>\n )}\n {unreadBadge && !loading && (\n <span className={styles['icon-button__unread-badge']} />\n )}\n </span>\n {hasCount && (\n <span className={styles['icon-button__count']}>{count}</span>\n )}\n </>\n );\n\n return renderAsChild({\n child: children,\n props: {\n ...rest,\n className: rootClass,\n 'aria-label': ariaLabel,\n 'data-active': active ? 'true' : undefined,\n ...(loading ? { 'aria-busy': true } : null),\n },\n ref,\n content: anatomy,\n disabled: isDisabled,\n disabledClassName: styles['icon-button--disabled'],\n warnOnChildContent: true,\n });\n }\n\n const {\n active = false,\n className = '',\n count,\n destructive = false,\n icon,\n loading = false,\n padding = 'default',\n rounded = false,\n size = 'medium',\n style = 'default',\n toggled,\n unreadBadge = false,\n disabled,\n type = 'button',\n 'aria-label': ariaLabel,\n asChild,\n ...rest\n } = props;\n void asChild;\n\n const rootClass = buildRootClass({\n className,\n count,\n destructive,\n padding,\n rounded,\n size,\n style,\n active,\n toggled,\n });\n const spinnerSize = ICON_BUTTON_ICON_SIZES[size];\n const isDisabled = Boolean(disabled || loading);\n const hasCount = count !== undefined;\n\n return (\n <button\n ref={ref as Ref<HTMLButtonElement>}\n className={rootClass}\n type={type}\n disabled={isDisabled}\n aria-label={ariaLabel}\n aria-pressed={toggled === undefined ? undefined : toggled}\n data-active={active ? 'true' : undefined}\n {...rest}\n >\n <span className={styles['icon-button__icon-slot']} aria-hidden>\n {loading ? (\n <Spinner size={spinnerSize} inverted={style === 'inverted'} />\n ) : (\n <IconSlotContext.Provider value={{ size: spinnerSize }}>\n {icon}\n </IconSlotContext.Provider>\n )}\n {unreadBadge && !loading && (\n <span className={styles['icon-button__unread-badge']} />\n )}\n </span>\n {hasCount && (\n <span className={styles['icon-button__count']}>{count}</span>\n )}\n </button>\n );\n}) as IconButtonComponent;\n\nIconButton.displayName = 'IconButton';\n\nexport default IconButton;\n"],"names":["ICON_BUTTON_ICON_SIZES","buildRootClass","className","count","destructive","padding","rounded","size","style","active","toggled","styles","toKebab","IconButton","forwardRef","props","ref","icon","loading","unreadBadge","disabled","children","ariaLabel","asChild","rest","rootClass","spinnerSize","isDisabled","hasCount","anatomy","jsxs","Fragment","jsx","Spinner","IconSlotContext","renderAsChild","type"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
._icon-
|
|
1
|
+
._icon-button_13ryy_2{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;font-family:var(--font-family-body);border-radius:var(--radius-s);border:0;cursor:pointer;text-decoration:none;transition:background-color var(--duration-quick) var(--ease-transition),color var(--duration-quick) var(--ease-transition),outline-color var(--duration-quick) var(--ease-transition),outline-offset var(--duration-quick) var(--ease-transition);background-color:transparent;--icon-button-fg: rgba(var(--center-channel-color-rgb), .64);color:var(--icon-button-fg);outline:2px solid color-mix(in srgb,var(--focus-ring-color) 0%,transparent);outline-offset:0}._icon-button_13ryy_2:any-link,._icon-button_13ryy_2:hover,._icon-button_13ryy_2:focus,._icon-button_13ryy_2:active,._icon-button_13ryy_2:visited{color:var(--icon-button-fg);text-decoration:none}._icon-button_13ryy_2:focus-visible{outline-color:var(--focus-ring-color);outline-offset:3px}._icon-button_13ryy_2:is(:disabled,._icon-button--disabled_13ryy_27){cursor:not-allowed;opacity:.5}._icon-button_13ryy_2:hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active):not(._icon-button--active_13ryy_31):not(._icon-button--toggled_13ryy_31){background-color:rgba(var(--center-channel-color-rgb),.08);--icon-button-fg: rgba(var(--center-channel-color-rgb), .75);color:rgba(var(--center-channel-color-rgb),.75)}._icon-button_13ryy_2:active:not(:disabled,._icon-button--disabled_13ryy_27):not(._icon-button--toggled_13ryy_31){background-color:rgba(var(--button-bg-rgb),.08);--icon-button-fg: var(--link-color);color:var(--link-color)}._icon-button__icon-slot_13ryy_41{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}._icon-button__unread-badge_13ryy_48{position:absolute;top:-1px;right:-1px;width:6px;height:6px;border-radius:var(--radius-pill);background-color:var(--sidebar-text-active-border);box-shadow:0 0 0 2px var(--center-channel-bg);pointer-events:none}._icon-button__count_13ryy_59{font-weight:var(--font-weight-semibold);color:inherit}._icon-button--size-x-small_13ryy_63{width:24px;height:24px;padding:var(--spacing-xxs)}._icon-button--size-x-small_13ryy_63 ._icon-button__count_13ryy_59{font-size:var(--font-size-75);line-height:12px}._icon-button--size-x-small_13ryy_63._icon-button--padding-compact_13ryy_72{width:20px;height:20px;padding:var(--spacing-xxxs)}._icon-button--size-small_13ryy_77{width:32px;height:32px;padding:var(--spacing-xs)}._icon-button--size-small_13ryy_77 ._icon-button__count_13ryy_59{font-size:var(--font-size-100);line-height:14px}._icon-button--size-small_13ryy_77._icon-button--padding-compact_13ryy_72{width:28px;height:28px;padding:var(--spacing-xxs)}._icon-button--size-medium_13ryy_91{width:40px;height:40px;padding:var(--spacing-s)}._icon-button--size-medium_13ryy_91 ._icon-button__count_13ryy_59{font-size:var(--font-size-200);line-height:16px}._icon-button--size-medium_13ryy_91._icon-button--padding-compact_13ryy_72{width:36px;height:36px;padding:var(--spacing-xs)}._icon-button--size-large_13ryy_105{width:48px;height:48px;padding:var(--spacing-m)}._icon-button--size-large_13ryy_105 ._icon-button__count_13ryy_59{font-size:var(--font-size-300);line-height:18px}._icon-button--size-large_13ryy_105._icon-button--padding-compact_13ryy_72{width:44px;height:44px;padding:var(--spacing-s)}._icon-button--has-count_13ryy_119{width:auto;gap:var(--spacing-xxxs)}._icon-button--rounded_13ryy_123{border-radius:var(--radius-pill)}._icon-button--active_13ryy_31:not(:disabled,._icon-button--disabled_13ryy_27){background-color:rgba(var(--button-bg-rgb),.08);--icon-button-fg: var(--link-color);color:var(--link-color)}._icon-button--active_13ryy_31:not(:disabled,._icon-button--disabled_13ryy_27):hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active){background-color:rgba(var(--button-bg-rgb),.12);--icon-button-fg: var(--link-color);color:var(--link-color)}._icon-button--active_13ryy_31:not(:disabled,._icon-button--disabled_13ryy_27):active:not(:disabled,._icon-button--disabled_13ryy_27){background-color:rgba(var(--button-bg-rgb),.16);--icon-button-fg: var(--link-color);color:var(--link-color)}._icon-button--toggled_13ryy_31{background-color:var(--button-bg);--icon-button-fg: var(--button-color);color:var(--button-color)}._icon-button--toggled_13ryy_31:hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active){background-color:color-mix(in srgb,black 8%,var(--button-bg));--icon-button-fg: var(--button-color);color:var(--button-color)}._icon-button--toggled_13ryy_31:active:not(:disabled,._icon-button--disabled_13ryy_27){background-color:color-mix(in srgb,black 16%,var(--button-bg));--icon-button-fg: var(--button-color);color:var(--button-color)}._icon-button--toggled_13ryy_31 ._icon-button__unread-badge_13ryy_48{box-shadow:0 0 0 2px var(--button-bg)}._icon-button--style-inverted_13ryy_159{background-color:transparent;--icon-button-fg: rgba(var(--sidebar-text-rgb), .64);color:rgba(var(--sidebar-text-rgb),.64)}._icon-button--style-inverted_13ryy_159 ._icon-button__unread-badge_13ryy_48{box-shadow:0 0 0 2px var(--sidebar-header-bg)}._icon-button--style-inverted_13ryy_159:hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active):not(._icon-button--toggled_13ryy_31):not(._icon-button--active_13ryy_31){background-color:rgba(var(--sidebar-text-rgb),.08);--icon-button-fg: var(--sidebar-text);color:var(--sidebar-text)}._icon-button--style-inverted_13ryy_159:active:not(:disabled,._icon-button--disabled_13ryy_27):not(._icon-button--toggled_13ryy_31){background-color:rgba(var(--sidebar-text-rgb),.16);--icon-button-fg: var(--sidebar-text);color:var(--sidebar-text)}._icon-button--style-inverted_13ryy_159._icon-button--active_13ryy_31:not(:disabled,._icon-button--disabled_13ryy_27){background-color:rgba(var(--sidebar-text-rgb),.16);--icon-button-fg: var(--sidebar-text);color:var(--sidebar-text)}._icon-button--style-inverted_13ryy_159._icon-button--active_13ryy_31:not(:disabled,._icon-button--disabled_13ryy_27):hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active){background-color:rgba(var(--sidebar-text-rgb),.2);--icon-button-fg: var(--sidebar-text);color:var(--sidebar-text)}._icon-button--style-inverted_13ryy_159._icon-button--active_13ryy_31:not(:disabled,._icon-button--disabled_13ryy_27):active:not(:disabled,._icon-button--disabled_13ryy_27){background-color:rgba(var(--sidebar-text-rgb),.24);--icon-button-fg: var(--sidebar-text);color:var(--sidebar-text)}._icon-button--style-inverted_13ryy_159._icon-button--toggled_13ryy_31{background-color:var(--sidebar-text);--icon-button-fg: var(--sidebar-bg);color:var(--sidebar-bg)}._icon-button--style-inverted_13ryy_159._icon-button--toggled_13ryy_31:hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active){background-color:rgba(var(--sidebar-text-rgb),.92);--icon-button-fg: var(--sidebar-bg);color:var(--sidebar-bg)}._icon-button--style-inverted_13ryy_159._icon-button--toggled_13ryy_31:active:not(:disabled,._icon-button--disabled_13ryy_27){background-color:rgba(var(--sidebar-text-rgb),.88);--icon-button-fg: var(--sidebar-bg);color:var(--sidebar-bg)}._icon-button--style-inverted_13ryy_159._icon-button--toggled_13ryy_31 ._icon-button__unread-badge_13ryy_48{box-shadow:0 0 0 2px var(--sidebar-text)}._icon-button--style-inverted_13ryy_159._icon-button--destructive_13ryy_210{--focus-ring-color: var(--error-text, var(--color-danger));background-color:transparent;--icon-button-fg: var(--error-text, var(--color-danger));color:var(--error-text, var(--color-danger))}._icon-button--style-inverted_13ryy_159._icon-button--destructive_13ryy_210:hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active){background-color:rgba(var(--error-text-color-rgb, var(--color-danger-rgb)),.08);--icon-button-fg: var(--error-text, var(--color-danger));color:var(--error-text, var(--color-danger))}._icon-button--style-inverted_13ryy_159._icon-button--destructive_13ryy_210:active:not(:disabled,._icon-button--disabled_13ryy_27):not(._icon-button--toggled_13ryy_31){background-color:rgba(var(--error-text-color-rgb, var(--color-danger-rgb)),.16);--icon-button-fg: var(--error-text, var(--color-danger));color:var(--error-text, var(--color-danger))}._icon-button--destructive_13ryy_210{--focus-ring-color: var(--error-text, var(--color-danger));background-color:transparent;--icon-button-fg: var(--error-text, var(--color-danger));color:var(--error-text, var(--color-danger))}._icon-button--destructive_13ryy_210:hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active){background-color:rgba(var(--error-text-color-rgb, var(--color-danger-rgb)),.08);--icon-button-fg: var(--error-text, var(--color-danger));color:var(--error-text, var(--color-danger))}._icon-button--destructive_13ryy_210:active:not(:disabled,._icon-button--disabled_13ryy_27):not(._icon-button--toggled_13ryy_31){background-color:rgba(var(--error-text-color-rgb, var(--color-danger-rgb)),.16);--icon-button-fg: var(--error-text, var(--color-danger));color:var(--error-text, var(--color-danger))}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ButtonHTMLAttributes, ReactNode } from 'react';
|
|
1
|
+
import { ButtonHTMLAttributes, HTMLAttributes, ReactElement, ReactNode, RefAttributes } from 'react';
|
|
2
2
|
export type IconButtonSize = 'x-small' | 'small' | 'medium' | 'large';
|
|
3
3
|
/** Figma "Style": Default (light context) | Inverted (dark context). */
|
|
4
4
|
export type IconButtonStyle = 'default' | 'inverted';
|
|
5
5
|
export type IconButtonPadding = 'default' | 'compact';
|
|
6
|
-
|
|
6
|
+
interface IconButtonOwnProps {
|
|
7
7
|
/** When true, forces the subtler pressed/active visual (lighter than toggled). */
|
|
8
8
|
active?: boolean;
|
|
9
9
|
/** Optional CSS class name. */
|
|
@@ -14,7 +14,7 @@ export interface IconButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonEle
|
|
|
14
14
|
destructive?: boolean;
|
|
15
15
|
/** Icon to show. Pass `<Icon glyph={<YourIcon />} />` — IconButton provides the correct size via context; no `size` prop needed on the Icon. */
|
|
16
16
|
icon: ReactNode;
|
|
17
|
-
/** When true, shows a Spinner in place of the icon and disables the button. */
|
|
17
|
+
/** When true, shows a Spinner in place of the icon and disables the button (or blocks navigation when `asChild`). */
|
|
18
18
|
loading?: boolean;
|
|
19
19
|
/** Padding variant. Figma: Padding = Default | Compact. */
|
|
20
20
|
padding?: IconButtonPadding;
|
|
@@ -22,24 +22,65 @@ export interface IconButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonEle
|
|
|
22
22
|
rounded?: boolean;
|
|
23
23
|
/** Size variant. Figma: Size. Default: Medium. */
|
|
24
24
|
size?: IconButtonSize;
|
|
25
|
-
/** Default | Inverted. Figma: Style (for light vs dark backgrounds). */
|
|
25
|
+
/** Default | Inverted. Figma: Style (for light vs dark backgrounds). Replaces the HTML `style` attribute. */
|
|
26
26
|
style?: IconButtonStyle;
|
|
27
|
-
/** When true, shows toggled/selected state. Figma: Toggled = On. When omitted, the control is not a toggle. */
|
|
28
|
-
toggled?: boolean;
|
|
29
27
|
/** When true, shows a small unread dot over the icon. Figma: Unread Badge. */
|
|
30
28
|
unreadBadge?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* When true, disables the control. On a native `<button>`, sets the `disabled`
|
|
31
|
+
* attribute. With `asChild`, sets `aria-disabled`, applies disabled styles, and
|
|
32
|
+
* blocks click / middle-click navigation (the link stays focusable).
|
|
33
|
+
*/
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface IconButtonProps extends IconButtonOwnProps, Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'style'> {
|
|
37
|
+
/**
|
|
38
|
+
* When true, merges IconButton props onto the single child element instead of
|
|
39
|
+
* rendering a `<button>`. Use with `<a>` or a router `Link`. Default: false.
|
|
40
|
+
*/
|
|
41
|
+
asChild?: false;
|
|
42
|
+
/**
|
|
43
|
+
* When true, shows toggled/selected state. Figma: Toggled = On. When omitted,
|
|
44
|
+
* the control is not a toggle. Only applies to the native `<button>` (maps to
|
|
45
|
+
* `aria-pressed`); not available with `asChild`.
|
|
46
|
+
*/
|
|
47
|
+
toggled?: boolean;
|
|
48
|
+
}
|
|
49
|
+
export interface IconButtonAsChildProps extends IconButtonOwnProps, Omit<HTMLAttributes<HTMLElement>, 'children' | 'color' | 'style'> {
|
|
50
|
+
/**
|
|
51
|
+
* Merges IconButton props onto the single child element instead of rendering a
|
|
52
|
+
* `<button>`. The child's own props (`href`, `to`, `target`, …) stay on the
|
|
53
|
+
* child. Do not pass `type` or `toggled` — they are not available on links.
|
|
54
|
+
* Pass an empty child; IconButton supplies the icon anatomy.
|
|
55
|
+
*/
|
|
56
|
+
asChild: true;
|
|
57
|
+
/** Single empty element to render as the IconButton (e.g. `<a href="…" />`). */
|
|
58
|
+
children: ReactElement;
|
|
59
|
+
/**
|
|
60
|
+
* Accessible name for the icon-only link. Required with `asChild`. An
|
|
61
|
+
* `aria-label` on the child also satisfies this (child props win).
|
|
62
|
+
*/
|
|
63
|
+
'aria-label': string;
|
|
31
64
|
}
|
|
32
65
|
/**
|
|
33
66
|
* @deprecated No longer needed — IconButton sets the icon size via context.
|
|
34
67
|
* Pass `<Icon glyph={<YourIcon />} />` without a size prop.
|
|
35
68
|
*/
|
|
36
69
|
export declare const ICON_BUTTON_ICON_SIZES: Record<IconButtonSize, '12' | '16' | '20' | '24'>;
|
|
70
|
+
type IconButtonComponent = {
|
|
71
|
+
(props: IconButtonAsChildProps & RefAttributes<HTMLElement>): ReactElement | null;
|
|
72
|
+
(props: IconButtonProps & RefAttributes<HTMLButtonElement>): ReactElement | null;
|
|
73
|
+
displayName?: string;
|
|
74
|
+
};
|
|
37
75
|
/**
|
|
38
76
|
* Icon Buttons are compact, label-free actions for tight surfaces — channel headers, message
|
|
39
77
|
* hover actions, modal dismissals, toolbar slots. They lean on the icon to communicate
|
|
40
78
|
* intent, so every Icon Button must pair with a tooltip or `aria-label` that makes the
|
|
41
79
|
* action explicit.
|
|
80
|
+
*
|
|
81
|
+
* Pass `asChild` with a single empty `<a>` or router `Link` child to render a navigational
|
|
82
|
+
* icon control with Icon Button styling (no nested `<button>`).
|
|
42
83
|
*/
|
|
43
|
-
declare const IconButton:
|
|
84
|
+
declare const IconButton: IconButtonComponent;
|
|
44
85
|
export default IconButton;
|
|
45
86
|
//# sourceMappingURL=IconButton.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconButton.d.ts","sourceRoot":"","sources":["../../../src/components/icon-button/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"IconButton.d.ts","sourceRoot":"","sources":["../../../src/components/icon-button/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,SAAS,EAEd,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAOf,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtE,wEAAwE;AACxE,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,UAAU,CAAC;AAErD,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,CAAC;AAEtD,UAAU,kBAAkB;IAC1B,kFAAkF;IAClF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gJAAgJ;IAChJ,IAAI,EAAE,SAAS,CAAC;IAChB,qHAAqH;IACrH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,6GAA6G;IAC7G,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eACf,SACE,kBAAkB,EAClB,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACxD;;;OAGG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,sBACf,SACE,kBAAkB,EAClB,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;IACnE;;;;;OAKG;IACH,OAAO,EAAE,IAAI,CAAC;IACd,gFAAgF;IAChF,QAAQ,EAAE,YAAY,CAAC;IACvB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CACzC,cAAc,EACd,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAM1B,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,CACE,KAAK,EAAE,sBAAsB,GAAG,aAAa,CAAC,WAAW,CAAC,GACzD,YAAY,GAAG,IAAI,CAAC;IACvB,CACE,KAAK,EAAE,eAAe,GAAG,aAAa,CAAC,iBAAiB,CAAC,GACxD,YAAY,GAAG,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAuCF;;;;;;;;GAQG;AACH,QAAA,MAAM,UAAU,EA4IV,mBAAmB,CAAC;AAI1B,eAAe,UAAU,CAAC"}
|