@gnome-ui/react 1.43.0 → 1.45.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.
Files changed (59) hide show
  1. package/README.md +8 -1
  2. package/dist/components/Badge/Badge.module.css.cjs +1 -1
  3. package/dist/components/Badge/Badge.module.css.cjs.map +1 -1
  4. package/dist/components/Badge/Badge.module.css.js +9 -9
  5. package/dist/components/Badge/Badge.module.css.js.map +1 -1
  6. package/dist/components/ContributionGraph/ContributionGraph.cjs +1 -1
  7. package/dist/components/ContributionGraph/ContributionGraph.cjs.map +1 -1
  8. package/dist/components/ContributionGraph/ContributionGraph.d.ts +11 -6
  9. package/dist/components/ContributionGraph/ContributionGraph.js +211 -130
  10. package/dist/components/ContributionGraph/ContributionGraph.js.map +1 -1
  11. package/dist/components/ContributionGraph/ContributionGraph.module.css.cjs +1 -1
  12. package/dist/components/ContributionGraph/ContributionGraph.module.css.cjs.map +1 -1
  13. package/dist/components/ContributionGraph/ContributionGraph.module.css.js +9 -8
  14. package/dist/components/ContributionGraph/ContributionGraph.module.css.js.map +1 -1
  15. package/dist/components/ContributionGraph/index.d.ts +1 -1
  16. package/dist/components/Drawer/Drawer.cjs +2 -0
  17. package/dist/components/Drawer/Drawer.cjs.map +1 -0
  18. package/dist/components/Drawer/Drawer.d.ts +28 -0
  19. package/dist/components/Drawer/Drawer.js +66 -0
  20. package/dist/components/Drawer/Drawer.js.map +1 -0
  21. package/dist/components/Drawer/Drawer.module.css.cjs +2 -0
  22. package/dist/components/Drawer/Drawer.module.css.cjs.map +1 -0
  23. package/dist/components/Drawer/Drawer.module.css.js +19 -0
  24. package/dist/components/Drawer/Drawer.module.css.js.map +1 -0
  25. package/dist/components/Drawer/index.d.ts +2 -0
  26. package/dist/components/Drawer.cjs +1 -0
  27. package/dist/components/Drawer.d.ts +2 -0
  28. package/dist/components/Drawer.js +2 -0
  29. package/dist/components/SegmentedBar/SegmentedBar.cjs +2 -0
  30. package/dist/components/SegmentedBar/SegmentedBar.cjs.map +1 -0
  31. package/dist/components/SegmentedBar/SegmentedBar.d.ts +42 -0
  32. package/dist/components/SegmentedBar/SegmentedBar.js +40 -0
  33. package/dist/components/SegmentedBar/SegmentedBar.js.map +1 -0
  34. package/dist/components/SegmentedBar/SegmentedBar.module.css.cjs +2 -0
  35. package/dist/components/SegmentedBar/SegmentedBar.module.css.cjs.map +1 -0
  36. package/dist/components/SegmentedBar/SegmentedBar.module.css.js +18 -0
  37. package/dist/components/SegmentedBar/SegmentedBar.module.css.js.map +1 -0
  38. package/dist/components/SegmentedBar/index.d.ts +2 -0
  39. package/dist/components/SegmentedBar.cjs +1 -0
  40. package/dist/components/SegmentedBar.d.ts +2 -0
  41. package/dist/components/SegmentedBar.js +2 -0
  42. package/dist/components/StatusBadge/StatusBadge.module.css.cjs +1 -1
  43. package/dist/components/StatusBadge/StatusBadge.module.css.cjs.map +1 -1
  44. package/dist/components/StatusBadge/StatusBadge.module.css.js +7 -7
  45. package/dist/components/StatusBadge/StatusBadge.module.css.js.map +1 -1
  46. package/dist/components/Tabs/TabItem.cjs +1 -1
  47. package/dist/components/Tabs/TabItem.cjs.map +1 -1
  48. package/dist/components/Tabs/TabItem.d.ts +3 -1
  49. package/dist/components/Tabs/TabItem.js +34 -32
  50. package/dist/components/Tabs/TabItem.js.map +1 -1
  51. package/dist/components/Tabs/Tabs.module.css.cjs +1 -1
  52. package/dist/components/Tabs/Tabs.module.css.cjs.map +1 -1
  53. package/dist/components/Tabs/Tabs.module.css.js +10 -9
  54. package/dist/components/Tabs/Tabs.module.css.js.map +1 -1
  55. package/dist/index.cjs +1 -1
  56. package/dist/index.d.ts +5 -1
  57. package/dist/index.js +65 -63
  58. package/dist/style.css +1 -1
  59. package/package.json +11 -1
@@ -0,0 +1,28 @@
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
+ export type DrawerSide = "left" | "right";
3
+ export type DrawerSize = "classic" | "wide";
4
+ export interface DrawerProps extends Omit<HTMLAttributes<HTMLDivElement>, "content" | "title"> {
5
+ /** Whether the drawer is visible. */
6
+ open: boolean;
7
+ /** Edge that the drawer slides in from. Defaults to `"right"`. */
8
+ side?: DrawerSide;
9
+ /** Preset drawer width. Defaults to `"classic"`. */
10
+ size?: DrawerSize;
11
+ /** Optional drawer heading. */
12
+ title?: ReactNode;
13
+ /** Drawer content when a prop is preferred over `children`. */
14
+ content?: ReactNode;
15
+ /** Drawer content. Used when `content` is not provided. */
16
+ children?: ReactNode;
17
+ /** Called when the user dismisses the drawer with Escape or the backdrop. */
18
+ onClose?: () => void;
19
+ /** Whether clicking the backdrop closes the drawer. Defaults to `true`. */
20
+ closeOnBackdrop?: boolean;
21
+ }
22
+ /**
23
+ * Slide-over panel for supplementary content.
24
+ *
25
+ * The drawer is controlled through `open`, renders into `document.body`, and
26
+ * accepts its body as either `content` or `children`.
27
+ */
28
+ export declare function Drawer({ open, side, size, title, content, children, onClose, closeOnBackdrop, className, ...props }: DrawerProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,66 @@
1
+ import { FOCUSABLE as e, trapFocus as t, useVisualViewport as n } from "../Dialog/dialogUtils.js";
2
+ import { Button as r } from "../Button/Button.js";
3
+ import i from "./Drawer.module.css.js";
4
+ import { useCallback as a, useEffect as o, useId as s, useRef as c } from "react";
5
+ import { createPortal as l } from "react-dom";
6
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
7
+ //#region src/components/Drawer/Drawer.tsx
8
+ function f({ open: f, side: p = "right", size: m = "classic", title: h, content: g, children: _, onClose: v, closeOnBackdrop: y = !0, className: b, ...x }) {
9
+ let S = c(null), C = s(), w = c(null), T = n(), E = g === void 0 ? _ : g;
10
+ o(() => {
11
+ f ? (w.current = document.activeElement, S.current?.querySelector(e)?.focus()) : w.current?.focus();
12
+ }, [f]);
13
+ let D = a((e) => {
14
+ if (e.key === "Escape") {
15
+ e.preventDefault(), v?.();
16
+ return;
17
+ }
18
+ t(e, S);
19
+ }, [v]);
20
+ if (!f) return null;
21
+ let O = /* @__PURE__ */ u("div", {
22
+ className: i.backdrop,
23
+ style: T,
24
+ onClick: y ? v : void 0,
25
+ children: /* @__PURE__ */ d("div", {
26
+ ref: S,
27
+ role: "dialog",
28
+ "aria-modal": "true",
29
+ "aria-labelledby": h ? C : void 0,
30
+ "data-side": p,
31
+ "data-size": m,
32
+ className: [
33
+ i.drawer,
34
+ p === "left" ? i.left : i.right,
35
+ m === "wide" ? i.wide : i.classic,
36
+ b
37
+ ].filter(Boolean).join(" "),
38
+ onKeyDown: D,
39
+ onClick: (e) => e.stopPropagation(),
40
+ ...x,
41
+ children: [h && /* @__PURE__ */ d("div", {
42
+ id: C,
43
+ className: i.title,
44
+ children: [/* @__PURE__ */ u("span", {
45
+ className: i.titleText,
46
+ children: h
47
+ }), v && /* @__PURE__ */ u(r, {
48
+ variant: "flat",
49
+ shape: "circular",
50
+ size: "sm",
51
+ "aria-label": "Close",
52
+ onClick: v,
53
+ children: "✕"
54
+ })]
55
+ }), E !== void 0 && /* @__PURE__ */ u("div", {
56
+ className: i.content,
57
+ children: E
58
+ })]
59
+ })
60
+ });
61
+ return typeof document > "u" ? O : l(O, document.body);
62
+ }
63
+ //#endregion
64
+ export { f as Drawer };
65
+
66
+ //# sourceMappingURL=Drawer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Drawer.js","names":[],"sources":["../../../src/components/Drawer/Drawer.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useId,\n useRef,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Button } from \"../Button/Button\";\nimport { FOCUSABLE, trapFocus, useVisualViewport } from \"../Dialog/dialogUtils\";\nimport styles from \"./Drawer.module.css\";\n\nexport type DrawerSide = \"left\" | \"right\";\nexport type DrawerSize = \"classic\" | \"wide\";\n\nexport interface DrawerProps extends Omit<HTMLAttributes<HTMLDivElement>, \"content\" | \"title\"> {\n /** Whether the drawer is visible. */\n open: boolean;\n /** Edge that the drawer slides in from. Defaults to `\"right\"`. */\n side?: DrawerSide;\n /** Preset drawer width. Defaults to `\"classic\"`. */\n size?: DrawerSize;\n /** Optional drawer heading. */\n title?: ReactNode;\n /** Drawer content when a prop is preferred over `children`. */\n content?: ReactNode;\n /** Drawer content. Used when `content` is not provided. */\n children?: ReactNode;\n /** Called when the user dismisses the drawer with Escape or the backdrop. */\n onClose?: () => void;\n /** Whether clicking the backdrop closes the drawer. Defaults to `true`. */\n closeOnBackdrop?: boolean;\n}\n\n/**\n * Slide-over panel for supplementary content.\n *\n * The drawer is controlled through `open`, renders into `document.body`, and\n * accepts its body as either `content` or `children`.\n */\nexport function Drawer({\n open,\n side = \"right\",\n size = \"classic\",\n title,\n content,\n children,\n onClose,\n closeOnBackdrop = true,\n className,\n ...props\n}: DrawerProps) {\n const drawerRef = useRef<HTMLDivElement>(null);\n const titleId = useId();\n const previouslyFocused = useRef<Element | null>(null);\n const viewportStyle = useVisualViewport();\n const body = content !== undefined ? content : children;\n\n useEffect(() => {\n if (open) {\n previouslyFocused.current = document.activeElement;\n drawerRef.current?.querySelector<HTMLElement>(FOCUSABLE)?.focus();\n } else {\n (previouslyFocused.current as HTMLElement | null)?.focus();\n }\n }, [open]);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n onClose?.();\n return;\n }\n\n trapFocus(event, drawerRef);\n },\n [onClose],\n );\n\n if (!open) return null;\n\n const node = (\n <div\n className={styles.backdrop}\n style={viewportStyle}\n onClick={closeOnBackdrop ? onClose : undefined}\n >\n <div\n ref={drawerRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n data-side={side}\n data-size={size}\n className={[\n styles.drawer,\n side === \"left\" ? styles.left : styles.right,\n size === \"wide\" ? styles.wide : styles.classic,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n onKeyDown={handleKeyDown}\n onClick={(event) => event.stopPropagation()}\n {...props}\n >\n {title && (\n <div id={titleId} className={styles.title}>\n <span className={styles.titleText}>{title}</span>\n {onClose && (\n <Button\n variant=\"flat\"\n shape=\"circular\"\n size=\"sm\"\n aria-label=\"Close\"\n onClick={onClose}\n >\n ✕\n </Button>\n )}\n </div>\n )}\n {body !== undefined && <div className={styles.content}>{body}</div>}\n </div>\n </div>\n );\n\n if (typeof document === \"undefined\") return node;\n return createPortal(node, document.body);\n}\n"],"mappings":";;;;;;;AA0CA,SAAgB,EAAO,EACrB,SACA,UAAO,SACP,UAAO,WACP,UACA,YACA,aACA,YACA,qBAAkB,IAClB,cACA,GAAG,KACW;CACd,IAAM,IAAY,EAAuB,KAAK,EACxC,IAAU,GAAO,EACjB,IAAoB,EAAuB,KAAK,EAChD,IAAgB,GAAmB,EACnC,IAAO,MAAY,KAAA,IAAsB,IAAV;AAErC,SAAgB;AACd,EAAI,KACF,EAAkB,UAAU,SAAS,eACrC,EAAU,SAAS,cAA2B,EAAU,EAAE,OAAO,IAEhE,EAAkB,SAAgC,OAAO;IAE3D,CAAC,EAAK,CAAC;CAEV,IAAM,IAAgB,GACnB,MAAyC;AACxC,MAAI,EAAM,QAAQ,UAAU;AAE1B,GADA,EAAM,gBAAgB,EACtB,KAAW;AACX;;AAGF,IAAU,GAAO,EAAU;IAE7B,CAAC,EAAQ,CACV;AAED,KAAI,CAAC,EAAM,QAAO;CAElB,IAAM,IACJ,kBAAC,OAAD;EACE,WAAW,EAAO;EAClB,OAAO;EACP,SAAS,IAAkB,IAAU,KAAA;YAErC,kBAAC,OAAD;GACE,KAAK;GACL,MAAK;GACL,cAAW;GACX,mBAAiB,IAAQ,IAAU,KAAA;GACnC,aAAW;GACX,aAAW;GACX,WAAW;IACT,EAAO;IACP,MAAS,SAAS,EAAO,OAAO,EAAO;IACvC,MAAS,SAAS,EAAO,OAAO,EAAO;IACvC;IACD,CACE,OAAO,QAAQ,CACf,KAAK,IAAI;GACZ,WAAW;GACX,UAAU,MAAU,EAAM,iBAAiB;GAC3C,GAAI;aAjBN,CAmBG,KACC,kBAAC,OAAD;IAAK,IAAI;IAAS,WAAW,EAAO;cAApC,CACE,kBAAC,QAAD;KAAM,WAAW,EAAO;eAAY;KAAa,CAAA,EAChD,KACC,kBAAC,GAAD;KACE,SAAQ;KACR,OAAM;KACN,MAAK;KACL,cAAW;KACX,SAAS;eACV;KAEQ,CAAA,CAEP;OAEP,MAAS,KAAA,KAAa,kBAAC,OAAD;IAAK,WAAW,EAAO;cAAU;IAAW,CAAA,CAC/D;;EACF,CAAA;AAIR,QADI,OAAO,WAAa,MAAoB,IACrC,EAAa,GAAM,SAAS,KAAK"}
@@ -0,0 +1,2 @@
1
+ var e=`_backdrop_om06g_3`,t=`_drawer_om06g_24`,n=`_classic_om06g_36`,r=`_wide_om06g_40`,i=`_left_om06g_44`,a=`_right_om06g_53`,o=`_title_om06g_72`,s=`_titleText_om06g_80`,c=`_content_om06g_90`,l={backdrop:e,"backdrop-in":`_backdrop-in_om06g_1`,drawer:t,classic:n,wide:r,left:i,"drawer-in-left":`_drawer-in-left_om06g_1`,right:a,"drawer-in-right":`_drawer-in-right_om06g_1`,title:o,titleText:s,content:c};exports.default=l;
2
+ //# sourceMappingURL=Drawer.module.css.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Drawer.module.css.cjs","names":[],"sources":["../../../src/components/Drawer/Drawer.module.css"],"sourcesContent":["/* ─── Backdrop ─────────────────────────────────────────────────────────────── */\n\n.backdrop {\n position: fixed;\n inset: 0;\n z-index: 10000;\n\n display: flex;\n\n background-color: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n\n animation: backdrop-in var(--gnome-duration-normal, 200ms) var(--gnome-easing-default, ease) both;\n}\n\n@keyframes backdrop-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* ─── Drawer ──────────────────────────────────────────────────────────────── */\n\n.drawer {\n display: flex;\n flex-direction: column;\n width: min(var(--gnome-drawer-width, var(--gnome-drawer-preset-width, 420px)), 100vw);\n height: 100dvh;\n min-width: 0;\n overflow: hidden;\n\n background-color: var(--gnome-dialog-bg-color, var(--gnome-window-bg-color, #fafafa));\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n}\n\n.classic {\n --gnome-drawer-preset-width: 420px;\n}\n\n.wide {\n --gnome-drawer-preset-width: 640px;\n}\n\n.left {\n margin-right: auto;\n border-radius: 0 var(--gnome-radius-xl, 16px) var(--gnome-radius-xl, 16px) 0;\n box-shadow:\n 4px 0 24px rgba(0, 0, 0, 0.18),\n 0 0 0 1px rgba(0, 0, 0, 0.06);\n animation: drawer-in-left var(--gnome-duration-normal, 200ms) var(--gnome-easing-default, ease) both;\n}\n\n.right {\n margin-left: auto;\n border-radius: var(--gnome-radius-xl, 16px) 0 0 var(--gnome-radius-xl, 16px);\n box-shadow:\n -4px 0 24px rgba(0, 0, 0, 0.18),\n 0 0 0 1px rgba(0, 0, 0, 0.06);\n animation: drawer-in-right var(--gnome-duration-normal, 200ms) var(--gnome-easing-default, ease) both;\n}\n\n@keyframes drawer-in-left {\n from { transform: translateX(-100%); }\n to { transform: translateX(0); }\n}\n\n@keyframes drawer-in-right {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.title {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n gap: var(--gnome-space-2, 12px);\n padding: var(--gnome-space-4, 24px) var(--gnome-space-4, 24px) var(--gnome-space-2, 12px);\n}\n\n.titleText {\n flex: 1;\n min-width: 0;\n\n font-family: var(--gnome-font-family);\n font-size: var(--gnome-font-size-title-4, 1.125rem);\n font-weight: var(--gnome-font-weight-bold, 700);\n line-height: var(--gnome-line-height-title, 1.3);\n}\n\n.content {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: var(--gnome-space-4, 24px);\n}\n\n.title + .content {\n padding-top: 0;\n}\n\n/* ─── Dark mode ────────────────────────────────────────────────────────────── */\n\n@media (prefers-color-scheme: dark) {\n .backdrop {\n background-color: rgba(0, 0, 0, 0.65);\n }\n\n .drawer {\n background-color: var(--gnome-dialog-bg-color, var(--gnome-window-bg-color, #242424));\n }\n\n\n .left {\n box-shadow:\n 4px 0 24px rgba(0, 0, 0, 0.45),\n 0 0 0 1px rgba(255, 255, 255, 0.06);\n }\n\n .right {\n box-shadow:\n -4px 0 24px rgba(0, 0, 0, 0.45),\n 0 0 0 1px rgba(255, 255, 255, 0.06);\n }\n}\n\n/* ─── Reduced motion ──────────────────────────────────────────────────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .backdrop,\n .left,\n .right {\n animation: none;\n }\n}\n"],"mappings":""}
@@ -0,0 +1,19 @@
1
+ //#region src/components/Drawer/Drawer.module.css
2
+ var e = "_backdrop_om06g_3", t = "_drawer_om06g_24", n = "_classic_om06g_36", r = "_wide_om06g_40", i = "_left_om06g_44", a = "_right_om06g_53", o = "_title_om06g_72", s = "_titleText_om06g_80", c = "_content_om06g_90", l = {
3
+ backdrop: e,
4
+ "backdrop-in": "_backdrop-in_om06g_1",
5
+ drawer: t,
6
+ classic: n,
7
+ wide: r,
8
+ left: i,
9
+ "drawer-in-left": "_drawer-in-left_om06g_1",
10
+ right: a,
11
+ "drawer-in-right": "_drawer-in-right_om06g_1",
12
+ title: o,
13
+ titleText: s,
14
+ content: c
15
+ };
16
+ //#endregion
17
+ export { l as default };
18
+
19
+ //# sourceMappingURL=Drawer.module.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Drawer.module.css.js","names":[],"sources":["../../../src/components/Drawer/Drawer.module.css"],"sourcesContent":["/* ─── Backdrop ─────────────────────────────────────────────────────────────── */\n\n.backdrop {\n position: fixed;\n inset: 0;\n z-index: 10000;\n\n display: flex;\n\n background-color: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n\n animation: backdrop-in var(--gnome-duration-normal, 200ms) var(--gnome-easing-default, ease) both;\n}\n\n@keyframes backdrop-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* ─── Drawer ──────────────────────────────────────────────────────────────── */\n\n.drawer {\n display: flex;\n flex-direction: column;\n width: min(var(--gnome-drawer-width, var(--gnome-drawer-preset-width, 420px)), 100vw);\n height: 100dvh;\n min-width: 0;\n overflow: hidden;\n\n background-color: var(--gnome-dialog-bg-color, var(--gnome-window-bg-color, #fafafa));\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n}\n\n.classic {\n --gnome-drawer-preset-width: 420px;\n}\n\n.wide {\n --gnome-drawer-preset-width: 640px;\n}\n\n.left {\n margin-right: auto;\n border-radius: 0 var(--gnome-radius-xl, 16px) var(--gnome-radius-xl, 16px) 0;\n box-shadow:\n 4px 0 24px rgba(0, 0, 0, 0.18),\n 0 0 0 1px rgba(0, 0, 0, 0.06);\n animation: drawer-in-left var(--gnome-duration-normal, 200ms) var(--gnome-easing-default, ease) both;\n}\n\n.right {\n margin-left: auto;\n border-radius: var(--gnome-radius-xl, 16px) 0 0 var(--gnome-radius-xl, 16px);\n box-shadow:\n -4px 0 24px rgba(0, 0, 0, 0.18),\n 0 0 0 1px rgba(0, 0, 0, 0.06);\n animation: drawer-in-right var(--gnome-duration-normal, 200ms) var(--gnome-easing-default, ease) both;\n}\n\n@keyframes drawer-in-left {\n from { transform: translateX(-100%); }\n to { transform: translateX(0); }\n}\n\n@keyframes drawer-in-right {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.title {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n gap: var(--gnome-space-2, 12px);\n padding: var(--gnome-space-4, 24px) var(--gnome-space-4, 24px) var(--gnome-space-2, 12px);\n}\n\n.titleText {\n flex: 1;\n min-width: 0;\n\n font-family: var(--gnome-font-family);\n font-size: var(--gnome-font-size-title-4, 1.125rem);\n font-weight: var(--gnome-font-weight-bold, 700);\n line-height: var(--gnome-line-height-title, 1.3);\n}\n\n.content {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: var(--gnome-space-4, 24px);\n}\n\n.title + .content {\n padding-top: 0;\n}\n\n/* ─── Dark mode ────────────────────────────────────────────────────────────── */\n\n@media (prefers-color-scheme: dark) {\n .backdrop {\n background-color: rgba(0, 0, 0, 0.65);\n }\n\n .drawer {\n background-color: var(--gnome-dialog-bg-color, var(--gnome-window-bg-color, #242424));\n }\n\n\n .left {\n box-shadow:\n 4px 0 24px rgba(0, 0, 0, 0.45),\n 0 0 0 1px rgba(255, 255, 255, 0.06);\n }\n\n .right {\n box-shadow:\n -4px 0 24px rgba(0, 0, 0, 0.45),\n 0 0 0 1px rgba(255, 255, 255, 0.06);\n }\n}\n\n/* ─── Reduced motion ──────────────────────────────────────────────────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .backdrop,\n .left,\n .right {\n animation: none;\n }\n}\n"],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export { Drawer } from './Drawer';
2
+ export type { DrawerProps, DrawerSide, DrawerSize } from './Drawer';
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./Drawer/Drawer.cjs`);exports.Drawer=e.Drawer;
@@ -0,0 +1,2 @@
1
+ export * from './Drawer/index'
2
+ export {}
@@ -0,0 +1,2 @@
1
+ import { Drawer as e } from "./Drawer/Drawer.js";
2
+ export { e as Drawer };
@@ -0,0 +1,2 @@
1
+ const e=require(`../Tooltip/Tooltip.cjs`),t=require(`./SegmentedBar.module.css.cjs`);let n=require(`react`),r=require(`react/jsx-runtime`);var i=8,a=(0,n.memo)(function({values:a,className:o,"aria-label":s,...c}){let[l,u]=(0,n.useState)(null),d=a.reduce((e,t)=>e+t.value,0)||100,f=a.map(e=>`${e.label} ${e.value}%`).join(`, `);return(0,r.jsx)(`div`,{role:`img`,"aria-label":s??f,className:[t.default.track,o].filter(Boolean).join(` `),...c,children:a.map((n,a)=>{let o=`${n.value/d*100}%`,s=n.value%1==0?n.value:n.value.toFixed(1);return(0,r.jsx)(e.Tooltip,{label:`${n.label}: ${s}%`,placement:`top`,delay:200,children:(0,r.jsx)(`div`,{className:[t.default.segment,n.color?null:t.default[`color${a%i}`],l!==null&&l!==a?t.default.dimmed:null,l===a?t.default.highlighted:null].filter(Boolean).join(` `),style:{width:o,...n.color?{backgroundColor:n.color}:{}},onMouseEnter:()=>u(a),onMouseLeave:()=>u(null)})},n.label)})})});exports.SegmentedBar=a;
2
+ //# sourceMappingURL=SegmentedBar.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SegmentedBar.cjs","names":[],"sources":["../../../src/components/SegmentedBar/SegmentedBar.tsx"],"sourcesContent":["import { useState, memo } from \"react\";\nimport type { HTMLAttributes } from \"react\";\nimport { Tooltip } from \"../Tooltip\";\nimport styles from \"./SegmentedBar.module.css\";\n\nexport interface SegmentedBarSegment {\n /** Category name shown in the tooltip. */\n label: string;\n /**\n * Percentage value 0–100.\n * The sum of all segments should equal 100.\n * If it does not, values are redistributed proportionally.\n */\n value: number;\n /**\n * CSS color string for this segment.\n * When omitted, a cycling palette of GNOME design tokens is used.\n */\n color?: string;\n}\n\nexport interface SegmentedBarProps extends HTMLAttributes<HTMLDivElement> {\n /** Segments to display. Each segment contributes its share of the full bar width. */\n values: SegmentedBarSegment[];\n /**\n * Accessible label for the bar as a whole.\n * Auto-generated from `values` when omitted (e.g. \"TypeScript 45%, JavaScript 30%\").\n */\n \"aria-label\"?: string;\n}\n\nconst COLOR_COUNT = 8;\n\n/**\n * Horizontal bar split into proportional segments, one per category.\n *\n * Hover a segment to highlight it and see its tooltip with label and percentage.\n * Typical use case: repository language distribution.\n *\n * ```tsx\n * <SegmentedBar\n * values={[\n * { label: \"TypeScript\", value: 60, color: \"#3178c6\" },\n * { label: \"JavaScript\", value: 30, color: \"#f7df1e\" },\n * { label: \"CSS\", value: 10, color: \"#563d7c\" },\n * ]}\n * />\n * ```\n */\nexport const SegmentedBar = memo(function SegmentedBar({\n values,\n className,\n \"aria-label\": ariaLabel,\n ...props\n}: SegmentedBarProps) {\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n\n const total = values.reduce((sum, s) => sum + s.value, 0) || 100;\n\n const defaultLabel = values.map((s) => `${s.label} ${s.value}%`).join(\", \");\n\n return (\n <div\n role=\"img\"\n aria-label={ariaLabel ?? defaultLabel}\n className={[styles.track, className].filter(Boolean).join(\" \")}\n {...props}\n >\n {values.map((segment, i) => {\n const width = `${(segment.value / total) * 100}%`;\n const pct = segment.value % 1 === 0 ? segment.value : segment.value.toFixed(1);\n const tooltipLabel = `${segment.label}: ${pct}%`;\n\n return (\n <Tooltip key={segment.label} label={tooltipLabel} placement=\"top\" delay={200}>\n <div\n className={[\n styles.segment,\n !segment.color ? styles[`color${i % COLOR_COUNT}`] : null,\n activeIndex !== null && activeIndex !== i ? styles.dimmed : null,\n activeIndex === i ? styles.highlighted : null,\n ]\n .filter(Boolean)\n .join(\" \")}\n style={{\n width,\n ...(segment.color ? { backgroundColor: segment.color } : {}),\n }}\n onMouseEnter={() => setActiveIndex(i)}\n onMouseLeave={() => setActiveIndex(null)}\n />\n </Tooltip>\n );\n })}\n </div>\n );\n});\n"],"mappings":"2IA+BA,IAAM,EAAc,EAkBP,GAAA,EAAA,EAAA,MAAoB,SAAsB,CACrD,SACA,YACA,aAAc,EACd,GAAG,GACiB,CACpB,GAAM,CAAC,EAAa,IAAA,EAAA,EAAA,UAA0C,KAAK,CAE7D,EAAQ,EAAO,QAAQ,EAAK,IAAM,EAAM,EAAE,MAAO,EAAE,EAAI,IAEvD,EAAe,EAAO,IAAK,GAAM,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG,CAAC,KAAK,KAAK,CAE3E,OACE,EAAA,EAAA,KAAC,MAAD,CACE,KAAK,MACL,aAAY,GAAa,EACzB,UAAW,CAAC,EAAA,QAAO,MAAO,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI,CAC9D,GAAI,WAEH,EAAO,KAAK,EAAS,IAAM,CAC1B,IAAM,EAAQ,GAAI,EAAQ,MAAQ,EAAS,IAAI,GACzC,EAAM,EAAQ,MAAQ,GAAM,EAAI,EAAQ,MAAQ,EAAQ,MAAM,QAAQ,EAAE,CAG9E,OACE,EAAA,EAAA,KAAC,EAAA,QAAD,CAA6B,MAHV,GAAG,EAAQ,MAAM,IAAI,EAAI,GAGM,UAAU,MAAM,MAAO,cACvE,EAAA,EAAA,KAAC,MAAD,CACE,UAAW,CACT,EAAA,QAAO,QACN,EAAQ,MAA4C,KAApC,EAAA,QAAO,QAAQ,EAAI,KACpC,IAAgB,MAAQ,IAAgB,EAAI,EAAA,QAAO,OAAS,KAC5D,IAAgB,EAAI,EAAA,QAAO,YAAc,KAC1C,CACE,OAAO,QAAQ,CACf,KAAK,IAAI,CACZ,MAAO,CACL,QACA,GAAI,EAAQ,MAAQ,CAAE,gBAAiB,EAAQ,MAAO,CAAG,EAAE,CAC5D,CACD,iBAAoB,EAAe,EAAE,CACrC,iBAAoB,EAAe,KAAK,CACxC,CAAA,CACM,CAjBI,EAAQ,MAiBZ,EAEZ,CACE,CAAA,EAER"}
@@ -0,0 +1,42 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export interface SegmentedBarSegment {
3
+ /** Category name shown in the tooltip. */
4
+ label: string;
5
+ /**
6
+ * Percentage value 0–100.
7
+ * The sum of all segments should equal 100.
8
+ * If it does not, values are redistributed proportionally.
9
+ */
10
+ value: number;
11
+ /**
12
+ * CSS color string for this segment.
13
+ * When omitted, a cycling palette of GNOME design tokens is used.
14
+ */
15
+ color?: string;
16
+ }
17
+ export interface SegmentedBarProps extends HTMLAttributes<HTMLDivElement> {
18
+ /** Segments to display. Each segment contributes its share of the full bar width. */
19
+ values: SegmentedBarSegment[];
20
+ /**
21
+ * Accessible label for the bar as a whole.
22
+ * Auto-generated from `values` when omitted (e.g. "TypeScript 45%, JavaScript 30%").
23
+ */
24
+ "aria-label"?: string;
25
+ }
26
+ /**
27
+ * Horizontal bar split into proportional segments, one per category.
28
+ *
29
+ * Hover a segment to highlight it and see its tooltip with label and percentage.
30
+ * Typical use case: repository language distribution.
31
+ *
32
+ * ```tsx
33
+ * <SegmentedBar
34
+ * values={[
35
+ * { label: "TypeScript", value: 60, color: "#3178c6" },
36
+ * { label: "JavaScript", value: 30, color: "#f7df1e" },
37
+ * { label: "CSS", value: 10, color: "#563d7c" },
38
+ * ]}
39
+ * />
40
+ * ```
41
+ */
42
+ export declare const SegmentedBar: import('react').NamedExoticComponent<SegmentedBarProps>;
@@ -0,0 +1,40 @@
1
+ import { Tooltip as e } from "../Tooltip/Tooltip.js";
2
+ import t from "./SegmentedBar.module.css.js";
3
+ import { memo as n, useState as r } from "react";
4
+ import { jsx as i } from "react/jsx-runtime";
5
+ //#region src/components/SegmentedBar/SegmentedBar.tsx
6
+ var a = 8, o = n(function({ values: n, className: o, "aria-label": s, ...c }) {
7
+ let [l, u] = r(null), d = n.reduce((e, t) => e + t.value, 0) || 100, f = n.map((e) => `${e.label} ${e.value}%`).join(", ");
8
+ return /* @__PURE__ */ i("div", {
9
+ role: "img",
10
+ "aria-label": s ?? f,
11
+ className: [t.track, o].filter(Boolean).join(" "),
12
+ ...c,
13
+ children: n.map((n, r) => {
14
+ let o = `${n.value / d * 100}%`, s = n.value % 1 == 0 ? n.value : n.value.toFixed(1);
15
+ return /* @__PURE__ */ i(e, {
16
+ label: `${n.label}: ${s}%`,
17
+ placement: "top",
18
+ delay: 200,
19
+ children: /* @__PURE__ */ i("div", {
20
+ className: [
21
+ t.segment,
22
+ n.color ? null : t[`color${r % a}`],
23
+ l !== null && l !== r ? t.dimmed : null,
24
+ l === r ? t.highlighted : null
25
+ ].filter(Boolean).join(" "),
26
+ style: {
27
+ width: o,
28
+ ...n.color ? { backgroundColor: n.color } : {}
29
+ },
30
+ onMouseEnter: () => u(r),
31
+ onMouseLeave: () => u(null)
32
+ })
33
+ }, n.label);
34
+ })
35
+ });
36
+ });
37
+ //#endregion
38
+ export { o as SegmentedBar };
39
+
40
+ //# sourceMappingURL=SegmentedBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SegmentedBar.js","names":[],"sources":["../../../src/components/SegmentedBar/SegmentedBar.tsx"],"sourcesContent":["import { useState, memo } from \"react\";\nimport type { HTMLAttributes } from \"react\";\nimport { Tooltip } from \"../Tooltip\";\nimport styles from \"./SegmentedBar.module.css\";\n\nexport interface SegmentedBarSegment {\n /** Category name shown in the tooltip. */\n label: string;\n /**\n * Percentage value 0–100.\n * The sum of all segments should equal 100.\n * If it does not, values are redistributed proportionally.\n */\n value: number;\n /**\n * CSS color string for this segment.\n * When omitted, a cycling palette of GNOME design tokens is used.\n */\n color?: string;\n}\n\nexport interface SegmentedBarProps extends HTMLAttributes<HTMLDivElement> {\n /** Segments to display. Each segment contributes its share of the full bar width. */\n values: SegmentedBarSegment[];\n /**\n * Accessible label for the bar as a whole.\n * Auto-generated from `values` when omitted (e.g. \"TypeScript 45%, JavaScript 30%\").\n */\n \"aria-label\"?: string;\n}\n\nconst COLOR_COUNT = 8;\n\n/**\n * Horizontal bar split into proportional segments, one per category.\n *\n * Hover a segment to highlight it and see its tooltip with label and percentage.\n * Typical use case: repository language distribution.\n *\n * ```tsx\n * <SegmentedBar\n * values={[\n * { label: \"TypeScript\", value: 60, color: \"#3178c6\" },\n * { label: \"JavaScript\", value: 30, color: \"#f7df1e\" },\n * { label: \"CSS\", value: 10, color: \"#563d7c\" },\n * ]}\n * />\n * ```\n */\nexport const SegmentedBar = memo(function SegmentedBar({\n values,\n className,\n \"aria-label\": ariaLabel,\n ...props\n}: SegmentedBarProps) {\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n\n const total = values.reduce((sum, s) => sum + s.value, 0) || 100;\n\n const defaultLabel = values.map((s) => `${s.label} ${s.value}%`).join(\", \");\n\n return (\n <div\n role=\"img\"\n aria-label={ariaLabel ?? defaultLabel}\n className={[styles.track, className].filter(Boolean).join(\" \")}\n {...props}\n >\n {values.map((segment, i) => {\n const width = `${(segment.value / total) * 100}%`;\n const pct = segment.value % 1 === 0 ? segment.value : segment.value.toFixed(1);\n const tooltipLabel = `${segment.label}: ${pct}%`;\n\n return (\n <Tooltip key={segment.label} label={tooltipLabel} placement=\"top\" delay={200}>\n <div\n className={[\n styles.segment,\n !segment.color ? styles[`color${i % COLOR_COUNT}`] : null,\n activeIndex !== null && activeIndex !== i ? styles.dimmed : null,\n activeIndex === i ? styles.highlighted : null,\n ]\n .filter(Boolean)\n .join(\" \")}\n style={{\n width,\n ...(segment.color ? { backgroundColor: segment.color } : {}),\n }}\n onMouseEnter={() => setActiveIndex(i)}\n onMouseLeave={() => setActiveIndex(null)}\n />\n </Tooltip>\n );\n })}\n </div>\n );\n});\n"],"mappings":";;;;;AA+BA,IAAM,IAAc,GAkBP,IAAe,EAAK,SAAsB,EACrD,WACA,cACA,cAAc,GACd,GAAG,KACiB;CACpB,IAAM,CAAC,GAAa,KAAkB,EAAwB,KAAK,EAE7D,IAAQ,EAAO,QAAQ,GAAK,MAAM,IAAM,EAAE,OAAO,EAAE,IAAI,KAEvD,IAAe,EAAO,KAAK,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG,CAAC,KAAK,KAAK;AAE3E,QACE,kBAAC,OAAD;EACE,MAAK;EACL,cAAY,KAAa;EACzB,WAAW,CAAC,EAAO,OAAO,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;EAC9D,GAAI;YAEH,EAAO,KAAK,GAAS,MAAM;GAC1B,IAAM,IAAQ,GAAI,EAAQ,QAAQ,IAAS,IAAI,IACzC,IAAM,EAAQ,QAAQ,KAAM,IAAI,EAAQ,QAAQ,EAAQ,MAAM,QAAQ,EAAE;AAG9E,UACE,kBAAC,GAAD;IAA6B,OAHV,GAAG,EAAQ,MAAM,IAAI,EAAI;IAGM,WAAU;IAAM,OAAO;cACvE,kBAAC,OAAD;KACE,WAAW;MACT,EAAO;MACN,EAAQ,QAA4C,OAApC,EAAO,QAAQ,IAAI;MACpC,MAAgB,QAAQ,MAAgB,IAAI,EAAO,SAAS;MAC5D,MAAgB,IAAI,EAAO,cAAc;MAC1C,CACE,OAAO,QAAQ,CACf,KAAK,IAAI;KACZ,OAAO;MACL;MACA,GAAI,EAAQ,QAAQ,EAAE,iBAAiB,EAAQ,OAAO,GAAG,EAAE;MAC5D;KACD,oBAAoB,EAAe,EAAE;KACrC,oBAAoB,EAAe,KAAK;KACxC,CAAA;IACM,EAjBI,EAAQ,MAiBZ;IAEZ;EACE,CAAA;EAER"}
@@ -0,0 +1,2 @@
1
+ var e={track:`_track_1ahtp_3`,segment:`_segment_1ahtp_16`,dimmed:`_dimmed_1ahtp_24`,highlighted:`_highlighted_1ahtp_25`,color0:`_color0_1ahtp_29`,color1:`_color1_1ahtp_30`,color2:`_color2_1ahtp_31`,color3:`_color3_1ahtp_32`,color4:`_color4_1ahtp_33`,color5:`_color5_1ahtp_34`,color6:`_color6_1ahtp_35`,color7:`_color7_1ahtp_36`};exports.default=e;
2
+ //# sourceMappingURL=SegmentedBar.module.css.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SegmentedBar.module.css.cjs","names":[],"sources":["../../../src/components/SegmentedBar/SegmentedBar.module.css"],"sourcesContent":["/* ─── Track ─────────────────────────────────────────────────────────────────── */\n\n.track {\n display: flex;\n width: 100%;\n height: 8px;\n border-radius: var(--gnome-radius-pill);\n overflow: hidden;\n gap: 2px;\n /* Track color is visible in the 2 px gaps between segments */\n background-color: var(--gnome-light-3, #deddda);\n}\n\n/* ─── Segment ───────────────────────────────────────────────────────────────── */\n\n.segment {\n height: 100%;\n cursor: default;\n transition:\n opacity var(--gnome-duration-fast, 150ms) var(--gnome-easing-default, ease),\n filter var(--gnome-duration-fast, 150ms) var(--gnome-easing-default, ease);\n}\n\n.dimmed { opacity: 0.35; }\n.highlighted { filter: brightness(1.15); }\n\n/* ─── Default palette (GNOME tokens, cycling across color families) ─────────── */\n\n.color0 { background-color: var(--gnome-blue-3, #3584e4); }\n.color1 { background-color: var(--gnome-green-3, #33d17a); }\n.color2 { background-color: var(--gnome-purple-3, #9141ac); }\n.color3 { background-color: var(--gnome-orange-3, #ff7800); }\n.color4 { background-color: var(--gnome-red-3, #e01b24); }\n.color5 { background-color: var(--gnome-brown-3, #986a44); }\n.color6 { background-color: var(--gnome-blue-5, #1a5fb4); }\n.color7 { background-color: var(--gnome-green-5, #26a269); }\n\n/* ─── Dark mode ─────────────────────────────────────────────────────────────── */\n\n@media (prefers-color-scheme: dark) {\n .track {\n background-color: var(--gnome-dark-2, #5e5c64);\n }\n}\n\n/* ─── Reduced motion ────────────────────────────────────────────────────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .segment {\n transition: none;\n }\n}\n"],"mappings":""}
@@ -0,0 +1,18 @@
1
+ var e = {
2
+ track: "_track_1ahtp_3",
3
+ segment: "_segment_1ahtp_16",
4
+ dimmed: "_dimmed_1ahtp_24",
5
+ highlighted: "_highlighted_1ahtp_25",
6
+ color0: "_color0_1ahtp_29",
7
+ color1: "_color1_1ahtp_30",
8
+ color2: "_color2_1ahtp_31",
9
+ color3: "_color3_1ahtp_32",
10
+ color4: "_color4_1ahtp_33",
11
+ color5: "_color5_1ahtp_34",
12
+ color6: "_color6_1ahtp_35",
13
+ color7: "_color7_1ahtp_36"
14
+ };
15
+ //#endregion
16
+ export { e as default };
17
+
18
+ //# sourceMappingURL=SegmentedBar.module.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SegmentedBar.module.css.js","names":[],"sources":["../../../src/components/SegmentedBar/SegmentedBar.module.css"],"sourcesContent":["/* ─── Track ─────────────────────────────────────────────────────────────────── */\n\n.track {\n display: flex;\n width: 100%;\n height: 8px;\n border-radius: var(--gnome-radius-pill);\n overflow: hidden;\n gap: 2px;\n /* Track color is visible in the 2 px gaps between segments */\n background-color: var(--gnome-light-3, #deddda);\n}\n\n/* ─── Segment ───────────────────────────────────────────────────────────────── */\n\n.segment {\n height: 100%;\n cursor: default;\n transition:\n opacity var(--gnome-duration-fast, 150ms) var(--gnome-easing-default, ease),\n filter var(--gnome-duration-fast, 150ms) var(--gnome-easing-default, ease);\n}\n\n.dimmed { opacity: 0.35; }\n.highlighted { filter: brightness(1.15); }\n\n/* ─── Default palette (GNOME tokens, cycling across color families) ─────────── */\n\n.color0 { background-color: var(--gnome-blue-3, #3584e4); }\n.color1 { background-color: var(--gnome-green-3, #33d17a); }\n.color2 { background-color: var(--gnome-purple-3, #9141ac); }\n.color3 { background-color: var(--gnome-orange-3, #ff7800); }\n.color4 { background-color: var(--gnome-red-3, #e01b24); }\n.color5 { background-color: var(--gnome-brown-3, #986a44); }\n.color6 { background-color: var(--gnome-blue-5, #1a5fb4); }\n.color7 { background-color: var(--gnome-green-5, #26a269); }\n\n/* ─── Dark mode ─────────────────────────────────────────────────────────────── */\n\n@media (prefers-color-scheme: dark) {\n .track {\n background-color: var(--gnome-dark-2, #5e5c64);\n }\n}\n\n/* ─── Reduced motion ────────────────────────────────────────────────────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .segment {\n transition: none;\n }\n}\n"],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export { SegmentedBar } from './SegmentedBar';
2
+ export type { SegmentedBarProps, SegmentedBarSegment } from './SegmentedBar';
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./SegmentedBar/SegmentedBar.cjs`);exports.SegmentedBar=e.SegmentedBar;
@@ -0,0 +1,2 @@
1
+ export * from './SegmentedBar/index'
2
+ export {}
@@ -0,0 +1,2 @@
1
+ import { SegmentedBar as e } from "./SegmentedBar/SegmentedBar.js";
2
+ export { e as SegmentedBar };
@@ -1,2 +1,2 @@
1
- var e={badge:`_badge_yj13e_3`,success:`_success_yj13e_18`,warning:`_warning_yj13e_23`,error:`_error_yj13e_28`,new:`_new_yj13e_33`,accent:`_accent_yj13e_38`,neutral:`_neutral_yj13e_43`};exports.default=e;
1
+ var e={badge:`_badge_mc2uh_3`,success:`_success_mc2uh_19`,warning:`_warning_mc2uh_24`,error:`_error_mc2uh_29`,new:`_new_mc2uh_34`,accent:`_accent_mc2uh_39`,neutral:`_neutral_mc2uh_44`};exports.default=e;
2
2
  //# sourceMappingURL=StatusBadge.module.css.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBadge.module.css.cjs","names":[],"sources":["../../../src/components/StatusBadge/StatusBadge.module.css"],"sourcesContent":["/* ─── Base ────────────────────────────────────────────────────────────────── */\n\n.badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: var(--gnome-radius-pill, 9999px);\n font-family: var(--gnome-font-family);\n font-size: 0.6875rem;\n font-weight: 600;\n line-height: 1.4;\n white-space: nowrap;\n letter-spacing: 0.02em;\n}\n\n/* ─── Variants ────────────────────────────────────────────────────────────── */\n\n.success {\n background-color: var(--gnome-success-bg-color, #2ec27e);\n color: var(--gnome-success-fg-color, #ffffff);\n}\n\n.warning {\n background-color: var(--gnome-warning-bg-color, #f6d32d);\n color: var(--gnome-warning-fg-color, rgba(0, 0, 0, 0.8));\n}\n\n.error {\n background-color: var(--gnome-error-bg-color, #e01b24);\n color: var(--gnome-error-fg-color, #ffffff);\n}\n\n.new {\n background-color: var(--gnome-new-bg-color, #9141ac);\n color: var(--gnome-new-fg-color, #ffffff);\n}\n\n.accent {\n background-color: var(--gnome-accent-bg-color, #3584e4);\n color: var(--gnome-accent-fg-color, #ffffff);\n}\n\n.neutral {\n background-color: var(--gnome-hover-overlay, rgba(0, 0, 0, 0.08));\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n}\n"],"mappings":""}
1
+ {"version":3,"file":"StatusBadge.module.css.cjs","names":[],"sources":["../../../src/components/StatusBadge/StatusBadge.module.css"],"sourcesContent":["/* ─── Base ────────────────────────────────────────────────────────────────── */\n\n.badge {\n display: inline-flex;\n align-items: center;\n vertical-align: middle;\n padding: 2px 8px;\n border-radius: var(--gnome-radius-pill, 9999px);\n font-family: var(--gnome-font-family);\n font-size: 0.6875rem;\n font-weight: 600;\n line-height: 1.4;\n white-space: nowrap;\n letter-spacing: 0.02em;\n}\n\n/* ─── Variants ────────────────────────────────────────────────────────────── */\n\n.success {\n background-color: var(--gnome-success-bg-color, #2ec27e);\n color: var(--gnome-success-fg-color, #ffffff);\n}\n\n.warning {\n background-color: var(--gnome-warning-bg-color, #f6d32d);\n color: var(--gnome-warning-fg-color, rgba(0, 0, 0, 0.8));\n}\n\n.error {\n background-color: var(--gnome-error-bg-color, #e01b24);\n color: var(--gnome-error-fg-color, #ffffff);\n}\n\n.new {\n background-color: var(--gnome-new-bg-color, #9141ac);\n color: var(--gnome-new-fg-color, #ffffff);\n}\n\n.accent {\n background-color: var(--gnome-accent-bg-color, #3584e4);\n color: var(--gnome-accent-fg-color, #ffffff);\n}\n\n.neutral {\n background-color: var(--gnome-hover-overlay, rgba(0, 0, 0, 0.08));\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n}\n"],"mappings":""}
@@ -1,11 +1,11 @@
1
1
  var e = {
2
- badge: "_badge_yj13e_3",
3
- success: "_success_yj13e_18",
4
- warning: "_warning_yj13e_23",
5
- error: "_error_yj13e_28",
6
- new: "_new_yj13e_33",
7
- accent: "_accent_yj13e_38",
8
- neutral: "_neutral_yj13e_43"
2
+ badge: "_badge_mc2uh_3",
3
+ success: "_success_mc2uh_19",
4
+ warning: "_warning_mc2uh_24",
5
+ error: "_error_mc2uh_29",
6
+ new: "_new_mc2uh_34",
7
+ accent: "_accent_mc2uh_39",
8
+ neutral: "_neutral_mc2uh_44"
9
9
  };
10
10
  //#endregion
11
11
  export { e as default };
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBadge.module.css.js","names":[],"sources":["../../../src/components/StatusBadge/StatusBadge.module.css"],"sourcesContent":["/* ─── Base ────────────────────────────────────────────────────────────────── */\n\n.badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: var(--gnome-radius-pill, 9999px);\n font-family: var(--gnome-font-family);\n font-size: 0.6875rem;\n font-weight: 600;\n line-height: 1.4;\n white-space: nowrap;\n letter-spacing: 0.02em;\n}\n\n/* ─── Variants ────────────────────────────────────────────────────────────── */\n\n.success {\n background-color: var(--gnome-success-bg-color, #2ec27e);\n color: var(--gnome-success-fg-color, #ffffff);\n}\n\n.warning {\n background-color: var(--gnome-warning-bg-color, #f6d32d);\n color: var(--gnome-warning-fg-color, rgba(0, 0, 0, 0.8));\n}\n\n.error {\n background-color: var(--gnome-error-bg-color, #e01b24);\n color: var(--gnome-error-fg-color, #ffffff);\n}\n\n.new {\n background-color: var(--gnome-new-bg-color, #9141ac);\n color: var(--gnome-new-fg-color, #ffffff);\n}\n\n.accent {\n background-color: var(--gnome-accent-bg-color, #3584e4);\n color: var(--gnome-accent-fg-color, #ffffff);\n}\n\n.neutral {\n background-color: var(--gnome-hover-overlay, rgba(0, 0, 0, 0.08));\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n}\n"],"mappings":""}
1
+ {"version":3,"file":"StatusBadge.module.css.js","names":[],"sources":["../../../src/components/StatusBadge/StatusBadge.module.css"],"sourcesContent":["/* ─── Base ────────────────────────────────────────────────────────────────── */\n\n.badge {\n display: inline-flex;\n align-items: center;\n vertical-align: middle;\n padding: 2px 8px;\n border-radius: var(--gnome-radius-pill, 9999px);\n font-family: var(--gnome-font-family);\n font-size: 0.6875rem;\n font-weight: 600;\n line-height: 1.4;\n white-space: nowrap;\n letter-spacing: 0.02em;\n}\n\n/* ─── Variants ────────────────────────────────────────────────────────────── */\n\n.success {\n background-color: var(--gnome-success-bg-color, #2ec27e);\n color: var(--gnome-success-fg-color, #ffffff);\n}\n\n.warning {\n background-color: var(--gnome-warning-bg-color, #f6d32d);\n color: var(--gnome-warning-fg-color, rgba(0, 0, 0, 0.8));\n}\n\n.error {\n background-color: var(--gnome-error-bg-color, #e01b24);\n color: var(--gnome-error-fg-color, #ffffff);\n}\n\n.new {\n background-color: var(--gnome-new-bg-color, #9141ac);\n color: var(--gnome-new-fg-color, #ffffff);\n}\n\n.accent {\n background-color: var(--gnome-accent-bg-color, #3584e4);\n color: var(--gnome-accent-fg-color, #ffffff);\n}\n\n.neutral {\n background-color: var(--gnome-hover-overlay, rgba(0, 0, 0, 0.08));\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n}\n"],"mappings":""}
@@ -1,2 +1,2 @@
1
- const e=require(`../Icon/Icon.cjs`),t=require(`./Tabs.module.css.cjs`);let n=require(`react/jsx-runtime`);function r({label:r,icon:i,active:a=!1,panelId:o,onClose:s,closeLabel:c=`Close tab`,className:l,disabled:u,...d}){return(0,n.jsxs)(`button`,{role:`tab`,type:`button`,"aria-selected":a,"aria-controls":o,tabIndex:a?0:-1,disabled:u,className:[t.default.tab,a?t.default.active:null,s?t.default.closeable:null,l].filter(Boolean).join(` `),...d,children:[i&&(0,n.jsx)(`span`,{className:t.default.tabIcon,children:(0,n.jsx)(e.Icon,{icon:i,size:`sm`,"aria-hidden":!0})}),(0,n.jsx)(`span`,{className:t.default.tabLabel,children:r}),s&&(0,n.jsx)(`span`,{role:`button`,tabIndex:0,"aria-label":c,className:t.default.closeBtn,onClick:e=>{e.stopPropagation(),s()},onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),e.stopPropagation(),s())},children:`×`})]})}exports.TabItem=r;
1
+ const e=require(`../Badge/Badge.cjs`),t=require(`../Icon/Icon.cjs`),n=require(`./Tabs.module.css.cjs`);let r=require(`react`),i=require(`react/jsx-runtime`);var a=(0,r.memo)(function({label:r,icon:a,active:o=!1,panelId:s,onClose:c,closeLabel:l=`Close tab`,count:u,className:d,disabled:f,...p}){return(0,i.jsxs)(`button`,{role:`tab`,type:`button`,"aria-selected":o,"aria-controls":s,tabIndex:o?0:-1,disabled:f,className:[n.default.tab,o?n.default.active:null,c?n.default.closeable:null,d].filter(Boolean).join(` `),...p,children:[a&&(0,i.jsx)(`span`,{className:n.default.tabIcon,children:(0,i.jsx)(t.Icon,{icon:a,size:`sm`,"aria-hidden":!0})}),(0,i.jsx)(`span`,{className:n.default.tabLabel,children:r}),u!==void 0&&(0,i.jsx)(e.Badge,{className:n.default.tabBadge,children:u>99?`99+`:u}),c&&(0,i.jsx)(`button`,{type:`button`,"aria-label":l,className:n.default.closeBtn,onClick:e=>{e.stopPropagation(),c()},children:`×`})]})});exports.TabItem=a;
2
2
  //# sourceMappingURL=TabItem.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"TabItem.cjs","names":[],"sources":["../../../src/components/Tabs/TabItem.tsx"],"sourcesContent":["import type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport type { IconDefinition } from \"@gnome-ui/icons\";\nimport { Icon } from \"../Icon\";\nimport styles from \"./Tabs.module.css\";\n\nexport interface TabItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** Tab label. */\n label: string;\n /** Optional icon from `@gnome-ui/icons`. */\n icon?: IconDefinition;\n /** Marks this tab as the currently selected one. */\n active?: boolean;\n /**\n * id of the `TabPanel` this tab controls.\n * Sets `aria-controls` automatically.\n */\n panelId?: string;\n /**\n * When provided, a close (×) button is rendered at the trailing edge.\n * Called when the user clicks the close button.\n */\n onClose?: () => void;\n /** Accessible label for the close button. Defaults to `\"Close tab\"`. */\n closeLabel?: string;\n children?: ReactNode;\n}\n\n/**\n * Individual tab button inside a `TabBar`.\n */\nexport function TabItem({\n label,\n icon,\n active = false,\n panelId,\n onClose,\n closeLabel = \"Close tab\",\n className,\n disabled,\n ...props\n}: TabItemProps) {\n return (\n <button\n role=\"tab\"\n type=\"button\"\n aria-selected={active}\n aria-controls={panelId}\n tabIndex={active ? 0 : -1}\n disabled={disabled}\n className={[\n styles.tab,\n active ? styles.active : null,\n onClose ? styles.closeable : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n {...props}\n >\n {icon && (\n <span className={styles.tabIcon}>\n <Icon icon={icon} size=\"sm\" aria-hidden />\n </span>\n )}\n <span className={styles.tabLabel}>{label}</span>\n\n {onClose && (\n <span\n role=\"button\"\n tabIndex={0}\n aria-label={closeLabel}\n className={styles.closeBtn}\n onClick={(e) => { e.stopPropagation(); onClose(); }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n e.stopPropagation();\n onClose();\n }\n }}\n >\n ×\n </span>\n )}\n </button>\n );\n}\n"],"mappings":"0GA8BA,SAAgB,EAAQ,CACtB,QACA,OACA,SAAS,GACT,UACA,UACA,aAAa,YACb,YACA,WACA,GAAG,GACY,CACf,OACE,EAAA,EAAA,MAAC,SAAD,CACE,KAAK,MACL,KAAK,SACL,gBAAe,EACf,gBAAe,EACf,SAAU,EAAS,EAAI,GACb,WACV,UAAW,CACT,EAAA,QAAO,IACP,EAAS,EAAA,QAAO,OAAS,KACzB,EAAU,EAAA,QAAO,UAAY,KAC7B,EACD,CACE,OAAO,QAAQ,CACf,KAAK,IAAI,CACZ,GAAI,WAfN,CAiBG,IACC,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,QAAO,kBACtB,EAAA,EAAA,KAAC,EAAA,KAAD,CAAY,OAAM,KAAK,KAAK,cAAA,GAAc,CAAA,CACrC,CAAA,EAET,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,QAAO,kBAAW,EAAa,CAAA,CAE/C,IACC,EAAA,EAAA,KAAC,OAAD,CACE,KAAK,SACL,SAAU,EACV,aAAY,EACZ,UAAW,EAAA,QAAO,SAClB,QAAU,GAAM,CAAE,EAAE,iBAAiB,CAAE,GAAS,EAChD,UAAY,GAAM,EACZ,EAAE,MAAQ,SAAW,EAAE,MAAQ,OACjC,EAAE,gBAAgB,CAClB,EAAE,iBAAiB,CACnB,GAAS,YAGd,IAEM,CAAA,CAEF"}
1
+ {"version":3,"file":"TabItem.cjs","names":[],"sources":["../../../src/components/Tabs/TabItem.tsx"],"sourcesContent":["import { memo } from \"react\";\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport type { IconDefinition } from \"@gnome-ui/icons\";\nimport { Icon } from \"../Icon\";\nimport { Badge } from \"../Badge\";\nimport styles from \"./Tabs.module.css\";\n\nexport interface TabItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** Tab label. */\n label: string;\n /** Optional icon from `@gnome-ui/icons`. */\n icon?: IconDefinition;\n /** Marks this tab as the currently selected one. */\n active?: boolean;\n /**\n * id of the `TabPanel` this tab controls.\n * Sets `aria-controls` automatically.\n */\n panelId?: string;\n /**\n * When provided, a close (×) button is rendered at the trailing edge.\n * Called when the user clicks the close button.\n */\n onClose?: () => void;\n /** Accessible label for the close button. Defaults to `\"Close tab\"`. */\n closeLabel?: string;\n /** Optional count shown as a badge next to the label (e.g. unread messages). Values above 99 render as \"99+\". */\n count?: number;\n children?: ReactNode;\n}\n\n/**\n * Individual tab button inside a `TabBar`.\n */\nexport const TabItem = memo(function TabItem({\n label,\n icon,\n active = false,\n panelId,\n onClose,\n closeLabel = \"Close tab\",\n count,\n className,\n disabled,\n ...props\n}: TabItemProps) {\n return (\n <button\n role=\"tab\"\n type=\"button\"\n aria-selected={active}\n aria-controls={panelId}\n tabIndex={active ? 0 : -1}\n disabled={disabled}\n className={[\n styles.tab,\n active ? styles.active : null,\n onClose ? styles.closeable : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n {...props}\n >\n {icon && (\n <span className={styles.tabIcon}>\n <Icon icon={icon} size=\"sm\" aria-hidden />\n </span>\n )}\n <span className={styles.tabLabel}>{label}</span>\n\n {count !== undefined && (\n <Badge className={styles.tabBadge}>\n {count > 99 ? \"99+\" : count}\n </Badge>\n )}\n\n {onClose && (\n <button\n type=\"button\"\n aria-label={closeLabel}\n className={styles.closeBtn}\n onClick={(e) => { e.stopPropagation(); onClose(); }}\n >\n ×\n </button>\n )}\n </button>\n );\n});\n"],"mappings":"6JAkCA,IAAa,GAAA,EAAA,EAAA,MAAe,SAAiB,CAC3C,QACA,OACA,SAAS,GACT,UACA,UACA,aAAa,YACb,QACA,YACA,WACA,GAAG,GACY,CACf,OACE,EAAA,EAAA,MAAC,SAAD,CACE,KAAK,MACL,KAAK,SACL,gBAAe,EACf,gBAAe,EACf,SAAU,EAAS,EAAI,GACb,WACV,UAAW,CACT,EAAA,QAAO,IACP,EAAS,EAAA,QAAO,OAAS,KACzB,EAAU,EAAA,QAAO,UAAY,KAC7B,EACD,CACE,OAAO,QAAQ,CACf,KAAK,IAAI,CACZ,GAAI,WAfN,CAiBG,IACC,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,QAAO,kBACtB,EAAA,EAAA,KAAC,EAAA,KAAD,CAAY,OAAM,KAAK,KAAK,cAAA,GAAc,CAAA,CACrC,CAAA,EAET,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,QAAO,kBAAW,EAAa,CAAA,CAE/C,IAAU,IAAA,KACT,EAAA,EAAA,KAAC,EAAA,MAAD,CAAO,UAAW,EAAA,QAAO,kBACtB,EAAQ,GAAK,MAAQ,EAChB,CAAA,CAGT,IACC,EAAA,EAAA,KAAC,SAAD,CACE,KAAK,SACL,aAAY,EACZ,UAAW,EAAA,QAAO,SAClB,QAAU,GAAM,CAAE,EAAE,iBAAiB,CAAE,GAAS,WACjD,IAEQ,CAAA,CAEJ,IAEX"}
@@ -19,9 +19,11 @@ export interface TabItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {
19
19
  onClose?: () => void;
20
20
  /** Accessible label for the close button. Defaults to `"Close tab"`. */
21
21
  closeLabel?: string;
22
+ /** Optional count shown as a badge next to the label (e.g. unread messages). Values above 99 render as "99+". */
23
+ count?: number;
22
24
  children?: ReactNode;
23
25
  }
24
26
  /**
25
27
  * Individual tab button inside a `TabBar`.
26
28
  */
27
- export declare function TabItem({ label, icon, active, panelId, onClose, closeLabel, className, disabled, ...props }: TabItemProps): import("react/jsx-runtime").JSX.Element;
29
+ export declare const TabItem: import('react').NamedExoticComponent<TabItemProps>;
@@ -1,52 +1,54 @@
1
- import { Icon as e } from "../Icon/Icon.js";
2
- import t from "./Tabs.module.css.js";
3
- import { jsx as n, jsxs as r } from "react/jsx-runtime";
1
+ import { Badge as e } from "../Badge/Badge.js";
2
+ import { Icon as t } from "../Icon/Icon.js";
3
+ import n from "./Tabs.module.css.js";
4
+ import { memo as r } from "react";
5
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
4
6
  //#region src/components/Tabs/TabItem.tsx
5
- function i({ label: i, icon: a, active: o = !1, panelId: s, onClose: c, closeLabel: l = "Close tab", className: u, disabled: d, ...f }) {
6
- return /* @__PURE__ */ r("button", {
7
+ var o = r(function({ label: r, icon: o, active: s = !1, panelId: c, onClose: l, closeLabel: u = "Close tab", count: d, className: f, disabled: p, ...m }) {
8
+ return /* @__PURE__ */ a("button", {
7
9
  role: "tab",
8
10
  type: "button",
9
- "aria-selected": o,
10
- "aria-controls": s,
11
- tabIndex: o ? 0 : -1,
12
- disabled: d,
11
+ "aria-selected": s,
12
+ "aria-controls": c,
13
+ tabIndex: s ? 0 : -1,
14
+ disabled: p,
13
15
  className: [
14
- t.tab,
15
- o ? t.active : null,
16
- c ? t.closeable : null,
17
- u
16
+ n.tab,
17
+ s ? n.active : null,
18
+ l ? n.closeable : null,
19
+ f
18
20
  ].filter(Boolean).join(" "),
19
- ...f,
21
+ ...m,
20
22
  children: [
21
- a && /* @__PURE__ */ n("span", {
22
- className: t.tabIcon,
23
- children: /* @__PURE__ */ n(e, {
24
- icon: a,
23
+ o && /* @__PURE__ */ i("span", {
24
+ className: n.tabIcon,
25
+ children: /* @__PURE__ */ i(t, {
26
+ icon: o,
25
27
  size: "sm",
26
28
  "aria-hidden": !0
27
29
  })
28
30
  }),
29
- /* @__PURE__ */ n("span", {
30
- className: t.tabLabel,
31
- children: i
31
+ /* @__PURE__ */ i("span", {
32
+ className: n.tabLabel,
33
+ children: r
32
34
  }),
33
- c && /* @__PURE__ */ n("span", {
34
- role: "button",
35
- tabIndex: 0,
36
- "aria-label": l,
37
- className: t.closeBtn,
35
+ d !== void 0 && /* @__PURE__ */ i(e, {
36
+ className: n.tabBadge,
37
+ children: d > 99 ? "99+" : d
38
+ }),
39
+ l && /* @__PURE__ */ i("button", {
40
+ type: "button",
41
+ "aria-label": u,
42
+ className: n.closeBtn,
38
43
  onClick: (e) => {
39
- e.stopPropagation(), c();
40
- },
41
- onKeyDown: (e) => {
42
- (e.key === "Enter" || e.key === " ") && (e.preventDefault(), e.stopPropagation(), c());
44
+ e.stopPropagation(), l();
43
45
  },
44
46
  children: "×"
45
47
  })
46
48
  ]
47
49
  });
48
- }
50
+ });
49
51
  //#endregion
50
- export { i as TabItem };
52
+ export { o as TabItem };
51
53
 
52
54
  //# sourceMappingURL=TabItem.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TabItem.js","names":[],"sources":["../../../src/components/Tabs/TabItem.tsx"],"sourcesContent":["import type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport type { IconDefinition } from \"@gnome-ui/icons\";\nimport { Icon } from \"../Icon\";\nimport styles from \"./Tabs.module.css\";\n\nexport interface TabItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** Tab label. */\n label: string;\n /** Optional icon from `@gnome-ui/icons`. */\n icon?: IconDefinition;\n /** Marks this tab as the currently selected one. */\n active?: boolean;\n /**\n * id of the `TabPanel` this tab controls.\n * Sets `aria-controls` automatically.\n */\n panelId?: string;\n /**\n * When provided, a close (×) button is rendered at the trailing edge.\n * Called when the user clicks the close button.\n */\n onClose?: () => void;\n /** Accessible label for the close button. Defaults to `\"Close tab\"`. */\n closeLabel?: string;\n children?: ReactNode;\n}\n\n/**\n * Individual tab button inside a `TabBar`.\n */\nexport function TabItem({\n label,\n icon,\n active = false,\n panelId,\n onClose,\n closeLabel = \"Close tab\",\n className,\n disabled,\n ...props\n}: TabItemProps) {\n return (\n <button\n role=\"tab\"\n type=\"button\"\n aria-selected={active}\n aria-controls={panelId}\n tabIndex={active ? 0 : -1}\n disabled={disabled}\n className={[\n styles.tab,\n active ? styles.active : null,\n onClose ? styles.closeable : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n {...props}\n >\n {icon && (\n <span className={styles.tabIcon}>\n <Icon icon={icon} size=\"sm\" aria-hidden />\n </span>\n )}\n <span className={styles.tabLabel}>{label}</span>\n\n {onClose && (\n <span\n role=\"button\"\n tabIndex={0}\n aria-label={closeLabel}\n className={styles.closeBtn}\n onClick={(e) => { e.stopPropagation(); onClose(); }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n e.stopPropagation();\n onClose();\n }\n }}\n >\n ×\n </span>\n )}\n </button>\n );\n}\n"],"mappings":";;;;AA8BA,SAAgB,EAAQ,EACtB,UACA,SACA,YAAS,IACT,YACA,YACA,gBAAa,aACb,cACA,aACA,GAAG,KACY;AACf,QACE,kBAAC,UAAD;EACE,MAAK;EACL,MAAK;EACL,iBAAe;EACf,iBAAe;EACf,UAAU,IAAS,IAAI;EACb;EACV,WAAW;GACT,EAAO;GACP,IAAS,EAAO,SAAS;GACzB,IAAU,EAAO,YAAY;GAC7B;GACD,CACE,OAAO,QAAQ,CACf,KAAK,IAAI;EACZ,GAAI;YAfN;GAiBG,KACC,kBAAC,QAAD;IAAM,WAAW,EAAO;cACtB,kBAAC,GAAD;KAAY;KAAM,MAAK;KAAK,eAAA;KAAc,CAAA;IACrC,CAAA;GAET,kBAAC,QAAD;IAAM,WAAW,EAAO;cAAW;IAAa,CAAA;GAE/C,KACC,kBAAC,QAAD;IACE,MAAK;IACL,UAAU;IACV,cAAY;IACZ,WAAW,EAAO;IAClB,UAAU,MAAM;AAAuB,KAArB,EAAE,iBAAiB,EAAE,GAAS;;IAChD,YAAY,MAAM;AAChB,MAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,gBAAgB,EAClB,EAAE,iBAAiB,EACnB,GAAS;;cAGd;IAEM,CAAA;GAEF"}
1
+ {"version":3,"file":"TabItem.js","names":[],"sources":["../../../src/components/Tabs/TabItem.tsx"],"sourcesContent":["import { memo } from \"react\";\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport type { IconDefinition } from \"@gnome-ui/icons\";\nimport { Icon } from \"../Icon\";\nimport { Badge } from \"../Badge\";\nimport styles from \"./Tabs.module.css\";\n\nexport interface TabItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** Tab label. */\n label: string;\n /** Optional icon from `@gnome-ui/icons`. */\n icon?: IconDefinition;\n /** Marks this tab as the currently selected one. */\n active?: boolean;\n /**\n * id of the `TabPanel` this tab controls.\n * Sets `aria-controls` automatically.\n */\n panelId?: string;\n /**\n * When provided, a close (×) button is rendered at the trailing edge.\n * Called when the user clicks the close button.\n */\n onClose?: () => void;\n /** Accessible label for the close button. Defaults to `\"Close tab\"`. */\n closeLabel?: string;\n /** Optional count shown as a badge next to the label (e.g. unread messages). Values above 99 render as \"99+\". */\n count?: number;\n children?: ReactNode;\n}\n\n/**\n * Individual tab button inside a `TabBar`.\n */\nexport const TabItem = memo(function TabItem({\n label,\n icon,\n active = false,\n panelId,\n onClose,\n closeLabel = \"Close tab\",\n count,\n className,\n disabled,\n ...props\n}: TabItemProps) {\n return (\n <button\n role=\"tab\"\n type=\"button\"\n aria-selected={active}\n aria-controls={panelId}\n tabIndex={active ? 0 : -1}\n disabled={disabled}\n className={[\n styles.tab,\n active ? styles.active : null,\n onClose ? styles.closeable : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n {...props}\n >\n {icon && (\n <span className={styles.tabIcon}>\n <Icon icon={icon} size=\"sm\" aria-hidden />\n </span>\n )}\n <span className={styles.tabLabel}>{label}</span>\n\n {count !== undefined && (\n <Badge className={styles.tabBadge}>\n {count > 99 ? \"99+\" : count}\n </Badge>\n )}\n\n {onClose && (\n <button\n type=\"button\"\n aria-label={closeLabel}\n className={styles.closeBtn}\n onClick={(e) => { e.stopPropagation(); onClose(); }}\n >\n ×\n </button>\n )}\n </button>\n );\n});\n"],"mappings":";;;;;;AAkCA,IAAa,IAAU,EAAK,SAAiB,EAC3C,UACA,SACA,YAAS,IACT,YACA,YACA,gBAAa,aACb,UACA,cACA,aACA,GAAG,KACY;AACf,QACE,kBAAC,UAAD;EACE,MAAK;EACL,MAAK;EACL,iBAAe;EACf,iBAAe;EACf,UAAU,IAAS,IAAI;EACb;EACV,WAAW;GACT,EAAO;GACP,IAAS,EAAO,SAAS;GACzB,IAAU,EAAO,YAAY;GAC7B;GACD,CACE,OAAO,QAAQ,CACf,KAAK,IAAI;EACZ,GAAI;YAfN;GAiBG,KACC,kBAAC,QAAD;IAAM,WAAW,EAAO;cACtB,kBAAC,GAAD;KAAY;KAAM,MAAK;KAAK,eAAA;KAAc,CAAA;IACrC,CAAA;GAET,kBAAC,QAAD;IAAM,WAAW,EAAO;cAAW;IAAa,CAAA;GAE/C,MAAU,KAAA,KACT,kBAAC,GAAD;IAAO,WAAW,EAAO;cACtB,IAAQ,KAAK,QAAQ;IAChB,CAAA;GAGT,KACC,kBAAC,UAAD;IACE,MAAK;IACL,cAAY;IACZ,WAAW,EAAO;IAClB,UAAU,MAAM;AAAuB,KAArB,EAAE,iBAAiB,EAAE,GAAS;;cACjD;IAEQ,CAAA;GAEJ;;EAEX"}
@@ -1,2 +1,2 @@
1
- var e={bar:`_bar_12ars_3`,list:`_list_12ars_10`,tab:`_tab_12ars_26`,active:`_active_12ars_81`,tabIcon:`_tabIcon_12ars_102`,tabLabel:`_tabLabel_12ars_110`,closeBtn:`_closeBtn_12ars_119`,panel:`_panel_12ars_148`,inline:`_inline_12ars_158`};exports.default=e;
1
+ var e={bar:`_bar_1qubq_3`,list:`_list_1qubq_10`,tab:`_tab_1qubq_26`,active:`_active_1qubq_81`,tabIcon:`_tabIcon_1qubq_102`,tabLabel:`_tabLabel_1qubq_110`,tabBadge:`_tabBadge_1qubq_119`,closeBtn:`_closeBtn_1qubq_126`,panel:`_panel_1qubq_163`,inline:`_inline_1qubq_173`};exports.default=e;
2
2
  //# sourceMappingURL=Tabs.module.css.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.module.css.cjs","names":[],"sources":["../../../src/components/Tabs/Tabs.module.css"],"sourcesContent":["/* ─── Bar (outer wrapper) ──────────────────────────────────────────────────── */\n\n.bar {\n background-color: var(--gnome-headerbar-bg-color, #ebebeb);\n border-bottom: 1px solid var(--gnome-headerbar-border-color, rgba(0, 0, 0, 0.12));\n}\n\n/* ─── Tab list ─────────────────────────────────────────────────────────────── */\n\n.list {\n display: flex;\n align-items: stretch;\n overflow-x: auto;\n scrollbar-width: none;\n padding: 0 var(--gnome-space-1, 6px);\n gap: 2px;\n min-height: 40px;\n}\n\n.list::-webkit-scrollbar {\n display: none;\n}\n\n/* ─── Tab button ───────────────────────────────────────────────────────────── */\n\n.tab {\n appearance: none;\n -webkit-appearance: none;\n border: none;\n background: transparent;\n font: inherit;\n cursor: pointer;\n outline: none;\n\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--gnome-space-1, 6px);\n padding: 0 var(--gnome-space-2, 12px);\n min-width: 80px;\n max-width: 200px;\n white-space: nowrap;\n\n font-family: var(--gnome-font-family);\n font-size: var(--gnome-font-size-body, 1rem);\n font-weight: var(--gnome-font-weight-normal, 400);\n color: var(--gnome-headerbar-fg-color, rgba(0, 0, 0, 0.8));\n opacity: 0.7;\n\n border-radius: var(--gnome-radius-md, 8px) var(--gnome-radius-md, 8px) 0 0;\n transition:\n background-color var(--gnome-duration-fast) var(--gnome-easing-default),\n opacity var(--gnome-duration-fast) var(--gnome-easing-default);\n}\n\n.tab::after {\n content: \"\";\n position: absolute;\n bottom: 0;\n left: var(--gnome-space-2, 12px);\n right: var(--gnome-space-2, 12px);\n height: 2px;\n border-radius: 1px 1px 0 0;\n background-color: var(--gnome-accent-bg-color, #3584e4);\n opacity: 0;\n transition: opacity var(--gnome-duration-fast) var(--gnome-easing-default);\n}\n\n.tab:hover {\n opacity: 1;\n background-color: var(--gnome-hover-overlay);\n}\n\n.tab:disabled {\n opacity: var(--gnome-opacity-disabled, 0.5);\n cursor: not-allowed;\n}\n\n/* ─── Active tab ───────────────────────────────────────────────────────────── */\n\n.active {\n opacity: 1;\n font-weight: var(--gnome-font-weight-semibold, 600);\n background-color: var(--gnome-active-overlay);\n}\n\n.active::after {\n opacity: 1;\n}\n\n/* ─── Focus ────────────────────────────────────────────────────────────────── */\n\n.tab:focus-visible {\n box-shadow:\n inset 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-headerbar-bg-color, #ebebeb),\n inset 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 3px))\n var(--gnome-focus-ring-color, #3584e4);\n}\n\n/* ─── Icon inside tab ──────────────────────────────────────────────────────── */\n\n.tabIcon {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n/* ─── Label inside tab ─────────────────────────────────────────────────────── */\n\n.tabLabel {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ─── Close button ─────────────────────────────────────────────────────────── */\n\n.closeBtn {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: var(--gnome-radius-sm, 4px);\n font-size: 1rem;\n line-height: 1;\n opacity: 0.5;\n margin-left: 2px;\n transition: opacity var(--gnome-duration-fast) var(--gnome-easing-default),\n background-color var(--gnome-duration-fast) var(--gnome-easing-default);\n}\n\n.closeBtn:hover {\n opacity: 1;\n background-color: var(--gnome-active-overlay);\n}\n\n.closeBtn:focus-visible {\n outline: 2px solid var(--gnome-focus-ring-color, #3584e4);\n outline-offset: 1px;\n opacity: 1;\n}\n\n/* ─── Panel ────────────────────────────────────────────────────────────────── */\n\n.panel {\n outline: none;\n}\n\n.panel:focus-visible {\n box-shadow: inset 0 0 0 2px var(--gnome-focus-ring-color, #3584e4);\n}\n\n/* ─── Inline variant ───────────────────────────────────────────────────────── */\n\n.inline {\n background-color: transparent;\n border-bottom-color: transparent;\n}\n\n.inline .tab:focus-visible {\n box-shadow:\n inset 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-window-bg-color, #fafafa),\n inset 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 3px))\n var(--gnome-focus-ring-color, #3584e4);\n}\n\n/* ─── High contrast ────────────────────────────────────────────────────────── */\n\n@media (prefers-contrast: more) {\n .bar {\n border-bottom-width: 2px;\n }\n\n .tab::after {\n height: 3px;\n }\n}\n\n/* ─── Reduced motion ───────────────────────────────────────────────────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .tab,\n .tab::after,\n .closeBtn {\n transition: none;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Tabs.module.css.cjs","names":[],"sources":["../../../src/components/Tabs/Tabs.module.css"],"sourcesContent":["/* ─── Bar (outer wrapper) ──────────────────────────────────────────────────── */\n\n.bar {\n background-color: var(--gnome-headerbar-bg-color, #ebebeb);\n border-bottom: 1px solid var(--gnome-headerbar-border-color, rgba(0, 0, 0, 0.12));\n}\n\n/* ─── Tab list ─────────────────────────────────────────────────────────────── */\n\n.list {\n display: flex;\n align-items: stretch;\n overflow-x: auto;\n scrollbar-width: none;\n padding: 0 var(--gnome-space-1, 6px);\n gap: 2px;\n min-height: 40px;\n}\n\n.list::-webkit-scrollbar {\n display: none;\n}\n\n/* ─── Tab button ───────────────────────────────────────────────────────────── */\n\n.tab {\n appearance: none;\n -webkit-appearance: none;\n border: none;\n background: transparent;\n font: inherit;\n cursor: pointer;\n outline: none;\n\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--gnome-space-1, 6px);\n padding: 0 var(--gnome-space-2, 12px);\n min-width: 80px;\n max-width: 200px;\n white-space: nowrap;\n\n font-family: var(--gnome-font-family);\n font-size: var(--gnome-font-size-body, 1rem);\n font-weight: var(--gnome-font-weight-normal, 400);\n color: var(--gnome-headerbar-fg-color, rgba(0, 0, 0, 0.8));\n opacity: 0.7;\n\n border-radius: var(--gnome-radius-md, 8px) var(--gnome-radius-md, 8px) 0 0;\n transition:\n background-color var(--gnome-duration-fast) var(--gnome-easing-default),\n opacity var(--gnome-duration-fast) var(--gnome-easing-default);\n}\n\n.tab::after {\n content: \"\";\n position: absolute;\n bottom: 0;\n left: var(--gnome-space-2, 12px);\n right: var(--gnome-space-2, 12px);\n height: 2px;\n border-radius: 1px 1px 0 0;\n background-color: var(--gnome-accent-bg-color, #3584e4);\n opacity: 0;\n transition: opacity var(--gnome-duration-fast) var(--gnome-easing-default);\n}\n\n.tab:hover {\n opacity: 1;\n background-color: var(--gnome-hover-overlay);\n}\n\n.tab:disabled {\n opacity: var(--gnome-opacity-disabled, 0.5);\n cursor: not-allowed;\n}\n\n/* ─── Active tab ───────────────────────────────────────────────────────────── */\n\n.active {\n opacity: 1;\n font-weight: var(--gnome-font-weight-semibold, 600);\n background-color: var(--gnome-active-overlay);\n}\n\n.active::after {\n opacity: 1;\n}\n\n/* ─── Focus ────────────────────────────────────────────────────────────────── */\n\n.tab:focus-visible {\n box-shadow:\n inset 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-headerbar-bg-color, #ebebeb),\n inset 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 3px))\n var(--gnome-focus-ring-color, #3584e4);\n}\n\n/* ─── Icon inside tab ──────────────────────────────────────────────────────── */\n\n.tabIcon {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n/* ─── Label inside tab ─────────────────────────────────────────────────────── */\n\n.tabLabel {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ─── Badge inside tab ─────────────────────────────────────────────────────── */\n\n.tabBadge {\n margin-inline-start: var(--gnome-space-1, 6px);\n flex-shrink: 0;\n}\n\n/* ─── Close button ─────────────────────────────────────────────────────────── */\n\n.closeBtn {\n appearance: none;\n -webkit-appearance: none;\n border: none;\n background: transparent;\n font: inherit;\n cursor: pointer;\n padding: 0;\n\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: var(--gnome-radius-sm, 4px);\n font-size: 1rem;\n line-height: 1;\n opacity: 0.5;\n margin-left: 2px;\n transition: opacity var(--gnome-duration-fast) var(--gnome-easing-default),\n background-color var(--gnome-duration-fast) var(--gnome-easing-default);\n}\n\n.closeBtn:hover {\n opacity: 1;\n background-color: var(--gnome-active-overlay);\n}\n\n.closeBtn:focus-visible {\n outline: 2px solid var(--gnome-focus-ring-color, #3584e4);\n outline-offset: 1px;\n opacity: 1;\n}\n\n/* ─── Panel ────────────────────────────────────────────────────────────────── */\n\n.panel {\n outline: none;\n}\n\n.panel:focus-visible {\n box-shadow: inset 0 0 0 2px var(--gnome-focus-ring-color, #3584e4);\n}\n\n/* ─── Inline variant ───────────────────────────────────────────────────────── */\n\n.inline {\n background-color: transparent;\n border-bottom-color: transparent;\n}\n\n.inline .tab:focus-visible {\n box-shadow:\n inset 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-window-bg-color, #fafafa),\n inset 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 3px))\n var(--gnome-focus-ring-color, #3584e4);\n}\n\n/* ─── High contrast ────────────────────────────────────────────────────────── */\n\n@media (prefers-contrast: more) {\n .bar {\n border-bottom-width: 2px;\n }\n\n .tab::after {\n height: 3px;\n }\n}\n\n/* ─── Reduced motion ───────────────────────────────────────────────────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .tab,\n .tab::after,\n .closeBtn {\n transition: none;\n }\n}\n"],"mappings":""}