@ai-matrx/tap-target 0.1.2 → 0.2.1
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/CHANGELOG.md +82 -0
- package/README.md +6 -0
- package/dist/buttons.cjs +255 -289
- package/dist/buttons.cjs.map +1 -1
- package/dist/buttons.js +215 -235
- package/dist/buttons.js.map +1 -1
- package/dist/index.cjs +28 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -19
- package/dist/index.d.ts +1 -19
- package/dist/index.js +41 -62
- package/dist/index.js.map +1 -1
- package/dist/styles.css +15 -0
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -3,43 +3,20 @@
|
|
|
3
3
|
// src/tap-target-button.tsx
|
|
4
4
|
import {
|
|
5
5
|
cloneElement,
|
|
6
|
-
forwardRef
|
|
6
|
+
forwardRef,
|
|
7
7
|
isValidElement
|
|
8
8
|
} from "react";
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
import {
|
|
10
|
+
Tooltip,
|
|
11
|
+
TooltipContent,
|
|
12
|
+
TooltipTrigger
|
|
13
|
+
} from "@ai-matrx/design-system";
|
|
14
14
|
|
|
15
15
|
// src/cn.ts
|
|
16
16
|
function cn(...values) {
|
|
17
17
|
return values.filter(Boolean).join(" ").trim();
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
// src/tooltip.tsx
|
|
21
|
-
import { jsx } from "react/jsx-runtime";
|
|
22
|
-
var TooltipProvider = TooltipPrimitive.Provider;
|
|
23
|
-
var Tooltip = TooltipPrimitive.Root;
|
|
24
|
-
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
25
|
-
var TooltipContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
26
|
-
TooltipPrimitive.Content,
|
|
27
|
-
{
|
|
28
|
-
ref,
|
|
29
|
-
sideOffset,
|
|
30
|
-
className: cn(
|
|
31
|
-
// Neutral, theme-aware surface (popover tokens) so tooltip text is
|
|
32
|
-
// ALWAYS legible in both light and dark mode — including rich content
|
|
33
|
-
// that uses `text-muted-foreground`. A brand-colored `bg-primary`
|
|
34
|
-
// background broke legibility for any non-default content.
|
|
35
|
-
"z-[10001] overflow-hidden rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
36
|
-
className
|
|
37
|
-
),
|
|
38
|
-
...props
|
|
39
|
-
}
|
|
40
|
-
) }));
|
|
41
|
-
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
42
|
-
|
|
43
20
|
// src/link.ts
|
|
44
21
|
var LINK_SLOT = /* @__PURE__ */ Symbol.for("@ai-matrx/tap-target:link-component");
|
|
45
22
|
function setTapTargetLinkComponent(component) {
|
|
@@ -50,7 +27,7 @@ function getTapTargetLinkComponent() {
|
|
|
50
27
|
}
|
|
51
28
|
|
|
52
29
|
// src/tap-target-button.tsx
|
|
53
|
-
import { jsx
|
|
30
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
54
31
|
var EXTERNAL_RE = /^(https?:|mailto:|tel:)/i;
|
|
55
32
|
var TAP_OUTER_CLASS = "matrx-tap-target group";
|
|
56
33
|
var TAP_GROUP_OUTER_CLASS = "matrx-tap-target matrx-tap-target-sm group";
|
|
@@ -66,9 +43,9 @@ function IconContent({
|
|
|
66
43
|
className: cn(className, icon.props.className)
|
|
67
44
|
});
|
|
68
45
|
}
|
|
69
|
-
return /* @__PURE__ */
|
|
46
|
+
return /* @__PURE__ */ jsx("span", { className, children: icon });
|
|
70
47
|
}
|
|
71
|
-
return /* @__PURE__ */
|
|
48
|
+
return /* @__PURE__ */ jsx(
|
|
72
49
|
"svg",
|
|
73
50
|
{
|
|
74
51
|
className,
|
|
@@ -103,7 +80,7 @@ function buildTapInner({
|
|
|
103
80
|
children,
|
|
104
81
|
strokeWidth = 2
|
|
105
82
|
}) {
|
|
106
|
-
const iconEl = /* @__PURE__ */
|
|
83
|
+
const iconEl = /* @__PURE__ */ jsx(
|
|
107
84
|
IconContent,
|
|
108
85
|
{
|
|
109
86
|
icon,
|
|
@@ -114,11 +91,11 @@ function buildTapInner({
|
|
|
114
91
|
);
|
|
115
92
|
const pillClasses = label ? `${pillClassName} ${inlineModifier}`.trim() : pillClassName;
|
|
116
93
|
if (!label) {
|
|
117
|
-
return /* @__PURE__ */
|
|
94
|
+
return /* @__PURE__ */ jsx("div", { className: pillClasses, children: iconEl });
|
|
118
95
|
}
|
|
119
96
|
return /* @__PURE__ */ jsxs("div", { className: pillClasses, children: [
|
|
120
97
|
iconEl,
|
|
121
|
-
/* @__PURE__ */
|
|
98
|
+
/* @__PURE__ */ jsx("span", { className: labelClassName ?? "matrx-tap-label", children: label })
|
|
122
99
|
] });
|
|
123
100
|
}
|
|
124
101
|
function renderTapTarget({
|
|
@@ -206,7 +183,7 @@ function renderTrigger({
|
|
|
206
183
|
buttonRef
|
|
207
184
|
}) {
|
|
208
185
|
if (disabled && href) {
|
|
209
|
-
return /* @__PURE__ */
|
|
186
|
+
return /* @__PURE__ */ jsx(
|
|
210
187
|
"span",
|
|
211
188
|
{
|
|
212
189
|
"aria-disabled": "true",
|
|
@@ -219,7 +196,7 @@ function renderTrigger({
|
|
|
219
196
|
if (href) {
|
|
220
197
|
const isExternal = EXTERNAL_RE.test(href);
|
|
221
198
|
if (isExternal) {
|
|
222
|
-
return /* @__PURE__ */
|
|
199
|
+
return /* @__PURE__ */ jsx(
|
|
223
200
|
"a",
|
|
224
201
|
{
|
|
225
202
|
href,
|
|
@@ -233,7 +210,7 @@ function renderTrigger({
|
|
|
233
210
|
}
|
|
234
211
|
const Link = linkComponent ?? getTapTargetLinkComponent();
|
|
235
212
|
if (Link) {
|
|
236
|
-
return /* @__PURE__ */
|
|
213
|
+
return /* @__PURE__ */ jsx(
|
|
237
214
|
Link,
|
|
238
215
|
{
|
|
239
216
|
href,
|
|
@@ -246,7 +223,7 @@ function renderTrigger({
|
|
|
246
223
|
}
|
|
247
224
|
);
|
|
248
225
|
}
|
|
249
|
-
return /* @__PURE__ */
|
|
226
|
+
return /* @__PURE__ */ jsx(
|
|
250
227
|
"a",
|
|
251
228
|
{
|
|
252
229
|
href,
|
|
@@ -259,7 +236,7 @@ function renderTrigger({
|
|
|
259
236
|
);
|
|
260
237
|
}
|
|
261
238
|
if (as === "label") {
|
|
262
|
-
return /* @__PURE__ */
|
|
239
|
+
return /* @__PURE__ */ jsx(
|
|
263
240
|
"label",
|
|
264
241
|
{
|
|
265
242
|
htmlFor,
|
|
@@ -269,7 +246,7 @@ function renderTrigger({
|
|
|
269
246
|
}
|
|
270
247
|
);
|
|
271
248
|
}
|
|
272
|
-
return /* @__PURE__ */
|
|
249
|
+
return /* @__PURE__ */ jsx(
|
|
273
250
|
"button",
|
|
274
251
|
{
|
|
275
252
|
ref: buttonRef,
|
|
@@ -293,17 +270,17 @@ function withTooltip(trigger, {
|
|
|
293
270
|
if (tooltip === false) return trigger;
|
|
294
271
|
const label = typeof tooltip === "string" && tooltip.length > 0 ? tooltip : ariaLabel;
|
|
295
272
|
if (!label) return trigger;
|
|
296
|
-
return /* @__PURE__ */ jsxs(
|
|
297
|
-
/* @__PURE__ */
|
|
273
|
+
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
274
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: disabled ? (
|
|
298
275
|
// Radix Tooltip triggers need a hoverable element; a disabled button
|
|
299
276
|
// does not dispatch pointer events, so we wrap in a span for the
|
|
300
277
|
// trigger target while keeping the disabled visual state.
|
|
301
|
-
/* @__PURE__ */
|
|
278
|
+
/* @__PURE__ */ jsx("span", { className: "inline-flex", children: trigger })
|
|
302
279
|
) : trigger }),
|
|
303
|
-
/* @__PURE__ */
|
|
280
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: tooltipSide, align: tooltipAlign, children: label })
|
|
304
281
|
] });
|
|
305
282
|
}
|
|
306
|
-
var TapTargetButton =
|
|
283
|
+
var TapTargetButton = forwardRef(function TapTargetButton2({
|
|
307
284
|
icon,
|
|
308
285
|
children,
|
|
309
286
|
strokeWidth = 2,
|
|
@@ -351,7 +328,7 @@ var TapTargetButton = forwardRef2(function TapTargetButton2({
|
|
|
351
328
|
buttonRef: ref
|
|
352
329
|
});
|
|
353
330
|
});
|
|
354
|
-
var TapTargetButtonTransparent =
|
|
331
|
+
var TapTargetButtonTransparent = forwardRef(function TapTargetButtonTransparent2({
|
|
355
332
|
icon,
|
|
356
333
|
children,
|
|
357
334
|
strokeWidth = 2,
|
|
@@ -399,7 +376,7 @@ var TapTargetButtonTransparent = forwardRef2(function TapTargetButtonTransparent
|
|
|
399
376
|
buttonRef: ref
|
|
400
377
|
});
|
|
401
378
|
});
|
|
402
|
-
var TapTargetButtonSolid =
|
|
379
|
+
var TapTargetButtonSolid = forwardRef(function TapTargetButtonSolid2({
|
|
403
380
|
icon,
|
|
404
381
|
children,
|
|
405
382
|
strokeWidth = 2,
|
|
@@ -450,13 +427,13 @@ var TapTargetButtonSolid = forwardRef2(function TapTargetButtonSolid2({
|
|
|
450
427
|
buttonRef: ref
|
|
451
428
|
});
|
|
452
429
|
});
|
|
453
|
-
var TapTargetButtonDestructive =
|
|
430
|
+
var TapTargetButtonDestructive = forwardRef(function TapTargetButtonDestructive2({
|
|
454
431
|
bgColor = "bg-destructive",
|
|
455
432
|
iconColor = "text-destructive-foreground",
|
|
456
433
|
hoverBgColor = "hover:bg-destructive/90",
|
|
457
434
|
...rest
|
|
458
435
|
}, ref) {
|
|
459
|
-
return /* @__PURE__ */
|
|
436
|
+
return /* @__PURE__ */ jsx(
|
|
460
437
|
TapTargetButtonSolid,
|
|
461
438
|
{
|
|
462
439
|
ref,
|
|
@@ -467,7 +444,7 @@ var TapTargetButtonDestructive = forwardRef2(function TapTargetButtonDestructive
|
|
|
467
444
|
}
|
|
468
445
|
);
|
|
469
446
|
});
|
|
470
|
-
var TapTargetButtonForGroup =
|
|
447
|
+
var TapTargetButtonForGroup = forwardRef(function TapTargetButtonForGroup2({
|
|
471
448
|
icon,
|
|
472
449
|
children,
|
|
473
450
|
strokeWidth = 2,
|
|
@@ -526,27 +503,33 @@ function TapTargetButtonGroup({
|
|
|
526
503
|
{
|
|
527
504
|
className: className ? `relative inline-flex h-9 items-center ${className}` : "relative inline-flex h-9 items-center",
|
|
528
505
|
children: [
|
|
529
|
-
/* @__PURE__ */
|
|
530
|
-
/* @__PURE__ */
|
|
506
|
+
/* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-1/2 -translate-y-1/2 h-7 rounded-full matrx-glass-thin-border" }),
|
|
507
|
+
/* @__PURE__ */ jsx("div", { className: "relative flex min-w-0 items-center", children })
|
|
531
508
|
]
|
|
532
509
|
}
|
|
533
510
|
);
|
|
534
511
|
}
|
|
535
512
|
|
|
536
513
|
// src/tap-target-labeled.tsx
|
|
537
|
-
import {
|
|
514
|
+
import {
|
|
515
|
+
TooltipProvider,
|
|
516
|
+
Tooltip as Tooltip2,
|
|
517
|
+
TooltipTrigger as TooltipTrigger2,
|
|
518
|
+
TooltipContent as TooltipContent2
|
|
519
|
+
} from "@ai-matrx/design-system";
|
|
520
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
538
521
|
function TapTargetLabeled({
|
|
539
522
|
label,
|
|
540
523
|
children,
|
|
541
524
|
hideLabel = false,
|
|
542
525
|
toolTipSide = "bottom"
|
|
543
526
|
}) {
|
|
544
|
-
return /* @__PURE__ */
|
|
545
|
-
/* @__PURE__ */
|
|
527
|
+
return /* @__PURE__ */ jsx2(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs2(Tooltip2, { children: [
|
|
528
|
+
/* @__PURE__ */ jsx2(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center p-0 gap-0 space-y-0 space-x-0 shrink-0", children: [
|
|
546
529
|
children,
|
|
547
|
-
!hideLabel && /* @__PURE__ */
|
|
530
|
+
!hideLabel && /* @__PURE__ */ jsx2("span", { className: "text-[10px] text-muted-foreground/70 leading-tight max-w-[52px] text-center truncate", children: label })
|
|
548
531
|
] }) }),
|
|
549
|
-
/* @__PURE__ */
|
|
532
|
+
/* @__PURE__ */ jsx2(TooltipContent2, { side: toolTipSide, children: /* @__PURE__ */ jsx2("span", { className: "font-mono text-xs max-w-[280px] break-all", children: label }) })
|
|
550
533
|
] }) });
|
|
551
534
|
}
|
|
552
535
|
export {
|
|
@@ -557,10 +540,6 @@ export {
|
|
|
557
540
|
TapTargetButtonSolid,
|
|
558
541
|
TapTargetButtonTransparent,
|
|
559
542
|
TapTargetLabeled,
|
|
560
|
-
Tooltip,
|
|
561
|
-
TooltipContent,
|
|
562
|
-
TooltipProvider,
|
|
563
|
-
TooltipTrigger,
|
|
564
543
|
getTapTargetLinkComponent,
|
|
565
544
|
setTapTargetLinkComponent
|
|
566
545
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tap-target-button.tsx","../src/tooltip.tsx","../src/cn.ts","../src/link.ts","../src/tap-target-labeled.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n cloneElement,\n forwardRef,\n isValidElement,\n type ButtonHTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport { TooltipContent, TooltipTrigger } from \"./tooltip\";\nimport { cn } from \"./cn\";\nimport {\n getTapTargetLinkComponent,\n type TapTargetLinkComponent,\n} from \"./link\";\n\nexport interface TapTargetButtonProps {\n icon?: React.ReactNode;\n children?: React.ReactNode;\n strokeWidth?: number | undefined;\n onClick?: (() => void) | undefined;\n className?: string | undefined;\n as?: \"button\" | \"label\" | undefined;\n htmlFor?: string | undefined;\n ariaLabel?: string | undefined;\n disabled?: boolean | undefined;\n /**\n * When set, the tap button renders as a link instead of a button.\n * - Internal hrefs (e.g. \"/tasks\") render via the injected link component\n * (`setTapTargetLinkComponent` / the `linkComponent` prop), falling back\n * to a plain `<a>` when none is registered.\n * - External hrefs (http://, https://, mailto:, tel:) render as `<a>`\n * with `target=\"_blank\"` and `rel=\"noopener noreferrer\"` by default.\n * - When combined with `disabled`, the trigger renders as a non-navigable\n * `<span aria-disabled=\"true\">` with the same visual styling.\n */\n href?: string | undefined;\n /** Override target. Works on both internal links and external anchors. */\n target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\" | undefined;\n /** Override rel. Works on both internal links and external anchors. */\n rel?: string | undefined;\n /** Forwarded to the injected link component. Pass `false` to disable prefetching. */\n prefetch?: boolean | null | undefined;\n /**\n * Per-instance link component for internal hrefs — overrides the\n * module-level `setTapTargetLinkComponent` registration.\n */\n linkComponent?: TapTargetLinkComponent | undefined;\n /**\n * Tooltip text. Defaults to `ariaLabel` when omitted.\n * Pass `false` to explicitly disable the tooltip.\n */\n tooltip?: string | false | undefined;\n /** Tooltip placement. Defaults to \"top\". */\n tooltipSide?: \"top\" | \"right\" | \"bottom\" | \"left\" | undefined;\n /** Tooltip alignment along its side. Defaults to \"center\". */\n tooltipAlign?: \"start\" | \"center\" | \"end\" | undefined;\n /**\n * Visible caption rendered inline after the icon (`[icon Label]`).\n * Widens the pill automatically. Tooltip defaults to off when set — the\n * label is self-describing. Visible text becomes the accessible name.\n */\n label?: string | undefined;\n /**\n * Collapse an icon + caption pill to its icon-only 44px tap target below\n * the `sm` breakpoint. The caption and inline geometry return at `sm+`;\n * `ariaLabel` (falling back to `label`) remains the accessible name.\n */\n mobileIconOnly?: boolean | undefined;\n}\n\nexport interface TapTargetButtonSolidProps extends TapTargetButtonProps {\n bgColor?: string | undefined;\n iconColor?: string | undefined;\n hoverBgColor?: string | undefined;\n /**\n * Press-state background. Defaults to `active:brightness-90` which works on\n * any color. Override when using a custom `bgColor` that should darken to a\n * specific shade on press (e.g. `active:bg-primary/60`).\n */\n activeBgColor?: string | undefined;\n}\n\nconst EXTERNAL_RE = /^(https?:|mailto:|tel:)/i;\n\n// Geometry + press feedback + tap hygiene are the SINGLE SOURCE OF TRUTH in\n// the shipped stylesheet (the `.matrx-tap-*` family in styles.css — import\n// \"@ai-matrx/tap-target/styles.css\" once at app root). This component only\n// picks the right class and layers each variant's decoration on top.\nconst TAP_OUTER_CLASS = \"matrx-tap-target group\";\nconst TAP_GROUP_OUTER_CLASS = \"matrx-tap-target matrx-tap-target-sm group\";\n\nfunction IconContent({\n icon,\n children,\n strokeWidth = 2,\n className,\n}: Pick<\n TapTargetButtonProps,\n \"icon\" | \"children\" | \"strokeWidth\" | \"className\"\n>) {\n if (icon) {\n if (isValidElement<{ className?: string }>(icon)) {\n return cloneElement(icon, {\n className: cn(className, icon.props.className),\n });\n }\n return <span className={className}>{icon}</span>;\n }\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n >\n {children}\n </svg>\n );\n}\n\ntype TapTargetSize = \"default\" | \"sm\";\n\nfunction resolveTapGeometry(\n label: string | undefined,\n size: TapTargetSize,\n mobileIconOnly: boolean,\n) {\n const inline = Boolean(label);\n if (size === \"sm\") {\n return {\n outerClassName:\n inline && mobileIconOnly\n ? \"matrx-tap-target matrx-tap-target-sm matrx-tap-target-mobile-icon-only-sm group\"\n : inline\n ? \"matrx-tap-target matrx-tap-target-sm matrx-tap-target-inline-sm group\"\n : TAP_GROUP_OUTER_CLASS,\n inlineModifier: mobileIconOnly\n ? \"matrx-tap-pill-mobile-icon-only-sm\"\n : \"matrx-tap-pill-inline-sm\",\n };\n }\n return {\n outerClassName:\n inline && mobileIconOnly\n ? `${TAP_OUTER_CLASS} matrx-tap-target-mobile-icon-only`\n : inline\n ? `${TAP_OUTER_CLASS} matrx-tap-target-inline`\n : TAP_OUTER_CLASS,\n inlineModifier: mobileIconOnly\n ? \"matrx-tap-pill-mobile-icon-only\"\n : \"matrx-tap-pill-inline\",\n };\n}\n\nfunction buildTapInner({\n label,\n pillClassName,\n iconClassName,\n labelClassName,\n inlineModifier,\n icon,\n children,\n strokeWidth = 2,\n}: {\n label?: string | undefined;\n pillClassName: string;\n iconClassName: string;\n labelClassName?: string | undefined;\n inlineModifier: string;\n icon?: React.ReactNode;\n children?: React.ReactNode;\n strokeWidth?: number | undefined;\n}) {\n const iconEl = (\n <IconContent\n icon={icon}\n strokeWidth={strokeWidth}\n className={iconClassName}\n >\n {children}\n </IconContent>\n );\n const pillClasses = label\n ? `${pillClassName} ${inlineModifier}`.trim()\n : pillClassName;\n\n if (!label) {\n return <div className={pillClasses}>{iconEl}</div>;\n }\n\n return (\n <div className={pillClasses}>\n {iconEl}\n <span className={labelClassName ?? \"matrx-tap-label\"}>{label}</span>\n </div>\n );\n}\n\ninterface RenderTapTargetArgs extends Pick<\n TapTargetButtonProps,\n | \"icon\"\n | \"children\"\n | \"strokeWidth\"\n | \"label\"\n | \"mobileIconOnly\"\n | \"onClick\"\n | \"as\"\n | \"htmlFor\"\n | \"ariaLabel\"\n | \"disabled\"\n | \"href\"\n | \"target\"\n | \"rel\"\n | \"prefetch\"\n | \"linkComponent\"\n | \"tooltip\"\n | \"tooltipSide\"\n | \"tooltipAlign\"\n> {\n size?: TapTargetSize;\n pillClassName: string;\n iconClassName: string;\n labelClassName?: string | undefined;\n rest?: ButtonHTMLAttributes<HTMLButtonElement> | undefined;\n buttonRef?: Ref<HTMLButtonElement> | undefined;\n}\n\nfunction renderTapTarget({\n size = \"default\",\n pillClassName,\n iconClassName,\n labelClassName,\n icon,\n children,\n strokeWidth,\n label,\n mobileIconOnly = false,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n rest,\n buttonRef,\n}: RenderTapTargetArgs): ReactElement {\n const { outerClassName, inlineModifier } = resolveTapGeometry(\n label,\n size,\n mobileIconOnly,\n );\n const responsiveLabelClassName = mobileIconOnly\n ? `${labelClassName ?? \"matrx-tap-label\"} matrx-tap-label-mobile-icon-only`\n : labelClassName;\n const inner = buildTapInner({\n label,\n pillClassName,\n iconClassName,\n labelClassName: responsiveLabelClassName,\n inlineModifier: label ? inlineModifier : \"\",\n icon,\n children,\n strokeWidth,\n });\n const resolvedTooltip =\n tooltip !== undefined ? tooltip : label ? false : undefined;\n const triggerAriaLabel =\n label && !mobileIconOnly ? undefined : (ariaLabel ?? label);\n const trigger = renderTrigger({\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n as,\n htmlFor,\n onClick,\n ariaLabel: triggerAriaLabel,\n disabled,\n outerClassName,\n children: inner,\n rest,\n buttonRef,\n });\n return withTooltip(trigger, {\n tooltip: resolvedTooltip,\n ariaLabel: triggerAriaLabel,\n disabled,\n tooltipSide,\n tooltipAlign,\n });\n}\n\ninterface RenderTriggerArgs {\n href?: string | undefined;\n target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\" | undefined;\n rel?: string | undefined;\n prefetch?: boolean | null | undefined;\n linkComponent?: TapTargetLinkComponent | undefined;\n as?: \"button\" | \"label\" | undefined;\n htmlFor?: string | undefined;\n onClick?: (() => void) | undefined;\n ariaLabel?: string | undefined;\n disabled?: boolean | undefined;\n outerClassName: string;\n children: ReactNode;\n rest?: ButtonHTMLAttributes<HTMLButtonElement> | undefined;\n buttonRef?: Ref<HTMLButtonElement> | undefined;\n}\n\n/**\n * Resolves the correct trigger element based on the props passed.\n *\n * - `href` + `disabled` → unclickable `<span aria-disabled>`\n * - `href` matching `http(s):|mailto:|tel:` → `<a target=\"_blank\" rel=\"noopener noreferrer\">`\n * - `href` (internal) → the injected link component (per-instance\n * `linkComponent` prop, else `setTapTargetLinkComponent` registration),\n * falling back to a plain `<a>` when none is registered\n * - `as=\"label\"` → `<label htmlFor=...>`\n * - default → `<button>`\n */\nfunction renderTrigger({\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n as,\n htmlFor,\n onClick,\n ariaLabel,\n disabled,\n outerClassName,\n children,\n rest,\n buttonRef,\n}: RenderTriggerArgs): ReactElement {\n if (disabled && href) {\n return (\n <span\n aria-disabled=\"true\"\n aria-label={ariaLabel}\n className={`${outerClassName} opacity-40 pointer-events-none`}\n >\n {children}\n </span>\n );\n }\n if (href) {\n const isExternal = EXTERNAL_RE.test(href);\n if (isExternal) {\n return (\n <a\n href={href}\n target={target ?? \"_blank\"}\n rel={rel ?? \"noopener noreferrer\"}\n aria-label={ariaLabel}\n className={outerClassName}\n >\n {children}\n </a>\n );\n }\n const Link = linkComponent ?? getTapTargetLinkComponent();\n if (Link) {\n return (\n <Link\n href={href}\n target={target}\n rel={rel}\n prefetch={prefetch}\n aria-label={ariaLabel}\n className={outerClassName}\n >\n {children}\n </Link>\n );\n }\n // No link component registered — plain <a>. `prefetch` is a router hint,\n // not a DOM attribute, so it is deliberately dropped here.\n return (\n <a\n href={href}\n target={target}\n rel={rel}\n aria-label={ariaLabel}\n className={outerClassName}\n >\n {children}\n </a>\n );\n }\n if (as === \"label\") {\n return (\n <label\n htmlFor={htmlFor}\n aria-label={ariaLabel}\n className={outerClassName}\n >\n {children}\n </label>\n );\n }\n return (\n <button\n ref={buttonRef}\n type=\"button\"\n onClick={onClick}\n aria-label={ariaLabel}\n disabled={disabled}\n {...rest}\n className={outerClassName}\n >\n {children}\n </button>\n );\n}\n\n/**\n * Wraps a trigger element in a Tooltip when a tooltip label is available.\n * Falls back to `ariaLabel` when `tooltip` is not explicitly set. If both\n * are absent (or `tooltip === false`), the trigger is returned unwrapped.\n */\nfunction withTooltip(\n trigger: ReactElement,\n {\n tooltip,\n ariaLabel,\n disabled,\n tooltipSide = \"top\",\n tooltipAlign = \"center\",\n }: {\n tooltip?: string | false | undefined;\n ariaLabel?: string | undefined;\n disabled?: boolean | undefined;\n tooltipSide?: \"top\" | \"right\" | \"bottom\" | \"left\" | undefined;\n tooltipAlign?: \"start\" | \"center\" | \"end\" | undefined;\n },\n): ReactElement {\n if (tooltip === false) return trigger;\n const label =\n typeof tooltip === \"string\" && tooltip.length > 0 ? tooltip : ariaLabel;\n if (!label) return trigger;\n return (\n <TooltipPrimitive.Root>\n <TooltipTrigger asChild>\n {disabled ? (\n // Radix Tooltip triggers need a hoverable element; a disabled button\n // does not dispatch pointer events, so we wrap in a span for the\n // trigger target while keeping the disabled visual state.\n <span className=\"inline-flex\">{trigger}</span>\n ) : (\n trigger\n )}\n </TooltipTrigger>\n <TooltipContent side={tooltipSide} align={tooltipAlign}>\n {label}\n </TooltipContent>\n </TooltipPrimitive.Root>\n );\n}\n\n// To resize/retune every tap button, edit styles.css — not here.\n\nexport const TapTargetButton = forwardRef<\n HTMLButtonElement,\n TapTargetButtonProps & ButtonHTMLAttributes<HTMLButtonElement>\n>(function TapTargetButton(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n className,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n const color = className ?? \"text-foreground\";\n return renderTapTarget({\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n pillClassName: \"matrx-tap-pill matrx-glass-thin-border\",\n iconClassName: `matrx-tap-icon ${color}`,\n rest,\n buttonRef: ref,\n });\n});\n\nexport const TapTargetButtonTransparent = forwardRef<\n HTMLButtonElement,\n TapTargetButtonProps & React.ButtonHTMLAttributes<HTMLButtonElement>\n>(function TapTargetButtonTransparent(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n className,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n const color = className ?? \"text-foreground\";\n return renderTapTarget({\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n pillClassName:\n \"matrx-tap-pill hover:bg-muted active:bg-muted-foreground/15\",\n iconClassName: `matrx-tap-icon ${color}`,\n rest,\n buttonRef: ref,\n });\n});\n\nexport const TapTargetButtonSolid = forwardRef<\n HTMLButtonElement,\n TapTargetButtonSolidProps & React.ButtonHTMLAttributes<HTMLButtonElement>\n>(function TapTargetButtonSolid(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n bgColor = \"bg-primary\",\n iconColor = \"text-primary-foreground\",\n hoverBgColor = \"hover:bg-primary/80\",\n activeBgColor = \"active:brightness-90\",\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n return renderTapTarget({\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n pillClassName: `matrx-tap-pill ${bgColor} ${iconColor} ${hoverBgColor} ${activeBgColor}`,\n iconClassName: `matrx-tap-icon ${iconColor}`,\n labelClassName: `matrx-tap-label ${iconColor}`,\n rest,\n buttonRef: ref,\n });\n});\n\n/** Solid destructive pill — delete/remove actions. White-on-red like the\n * primary solid is white-on-blue. Use THIS, never hand-pass bg-destructive\n * with the default (dark) icon color. */\nexport const TapTargetButtonDestructive = forwardRef<\n HTMLButtonElement,\n TapTargetButtonSolidProps & React.ButtonHTMLAttributes<HTMLButtonElement>\n>(function TapTargetButtonDestructive(\n {\n bgColor = \"bg-destructive\",\n iconColor = \"text-destructive-foreground\",\n hoverBgColor = \"hover:bg-destructive/90\",\n ...rest\n },\n ref,\n) {\n return (\n <TapTargetButtonSolid\n ref={ref}\n bgColor={bgColor}\n iconColor={iconColor}\n hoverBgColor={hoverBgColor}\n {...rest}\n />\n );\n});\n\nexport const TapTargetButtonForGroup = forwardRef<\n HTMLButtonElement,\n TapTargetButtonProps & ButtonHTMLAttributes<HTMLButtonElement>\n>(function TapTargetButtonForGroup(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n className,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n const color = className ?? \"text-foreground\";\n return renderTapTarget({\n size: \"sm\",\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n pillClassName: \"matrx-tap-pill matrx-tap-pill-sm matrx-glass-interactive\",\n iconClassName: `matrx-tap-icon ${color}`,\n labelClassName: `matrx-tap-label ${color}`,\n rest,\n buttonRef: ref,\n });\n});\n\nexport function TapTargetButtonGroup({\n children,\n className,\n}: {\n children: React.ReactNode;\n className?: string | undefined;\n}) {\n return (\n <div\n className={\n className\n ? `relative inline-flex h-9 items-center ${className}`\n : \"relative inline-flex h-9 items-center\"\n }\n >\n <div className=\"pointer-events-none absolute inset-x-0 top-1/2 -translate-y-1/2 h-7 rounded-full matrx-glass-thin-border\" />\n {/* min-w-0 lets flexible children (e.g. a truncating filename) shrink\n under container pressure; fixed-size tap buttons are unaffected. */}\n <div className=\"relative flex min-w-0 items-center\">{children}</div>\n </div>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport { cn } from \"./cn\";\n\n/**\n * Inlined port of matrx-frontend `components/ui/tooltip.tsx` — the one `@/`\n * import the tap-target components consumed beyond `cn` and `next/link`.\n * Behavior deltas vs. the original, both documented in FEATURE.md:\n * - `useNestedPortalContainer` (a host-specific nested-overlay portal context)\n * is dropped: content portals to the Radix default (document.body).\n * - Everything else — unconditional Root render, popover-token styling — is\n * verbatim.\n *\n * Hosts must mount `TooltipProvider` once near the app root (matrx-frontend\n * already does); `TapTargetLabeled` brings its own provider like the original.\n */\nconst TooltipProvider = TooltipPrimitive.Provider;\n\nconst Tooltip = TooltipPrimitive.Root;\n\nconst TooltipTrigger = TooltipPrimitive.Trigger;\n\nconst TooltipContent = React.forwardRef<\n React.ComponentRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n // Neutral, theme-aware surface (popover tokens) so tooltip text is\n // ALWAYS legible in both light and dark mode — including rich content\n // that uses `text-muted-foreground`. A brand-colored `bg-primary`\n // background broke legibility for any non-default content.\n \"z-[10001] overflow-hidden rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className,\n )}\n {...props}\n />\n </TooltipPrimitive.Portal>\n));\nTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","/**\n * Minimal className join — the only piece of `cn` this package needs.\n * No tailwind-merge / clsx dependency by design: callers pass literal strings.\n */\nexport function cn(\n ...values: Array<string | null | undefined | false>\n): string {\n return values.filter(Boolean).join(\" \").trim();\n}\n","import type { ComponentType, ReactNode } from \"react\";\n\n/**\n * The injectable link seam — the package's replacement for the original\n * hard `next/link` import.\n *\n * Internal hrefs (anything NOT matching `http(s):`, `mailto:`, `tel:`) render\n * through the link component resolved here; external hrefs always render a\n * plain `<a target=\"_blank\" rel=\"noopener noreferrer\">`, exactly like the\n * original. When nothing is registered and no per-instance `linkComponent`\n * prop is given, internal hrefs fall back to a plain `<a>` (no prefetch, no\n * client-side routing — still a working link).\n */\nexport interface TapTargetLinkProps {\n href: string;\n target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\" | undefined;\n rel?: string | undefined;\n /** Router prefetch hint (next/link semantics). Plain `<a>` fallback ignores it. */\n prefetch?: boolean | null | undefined;\n \"aria-label\"?: string | undefined;\n className?: string | undefined;\n children?: ReactNode;\n}\n\nexport type TapTargetLinkComponent = ComponentType<TapTargetLinkProps>;\n\n/**\n * The registered component lives in a `Symbol.for` slot on `globalThis` — NOT\n * in module state — so it survives the module graph being instantiated more\n * than once: the `.` and `./buttons` dist bundles each inline the primitives\n * (tsup `splitting: false`), and a consumer may even mix `import` and\n * `require`. One registration must reach every copy.\n */\nconst LINK_SLOT = Symbol.for(\"@ai-matrx/tap-target:link-component\");\n\ntype GlobalWithLinkSlot = typeof globalThis & {\n [LINK_SLOT]?: TapTargetLinkComponent | null;\n};\n\n/**\n * Register the app's link component once at startup (e.g. `next/link`):\n *\n * ```tsx\n * import Link from \"next/link\";\n * import { setTapTargetLinkComponent } from \"@ai-matrx/tap-target\";\n * setTapTargetLinkComponent(Link);\n * ```\n *\n * Pass `null` to unregister (plain `<a>` fallback resumes).\n */\nexport function setTapTargetLinkComponent(\n component: TapTargetLinkComponent | null,\n): void {\n (globalThis as GlobalWithLinkSlot)[LINK_SLOT] = component;\n}\n\n/** The currently registered link component, or `null` when none is set. */\nexport function getTapTargetLinkComponent(): TapTargetLinkComponent | null {\n return (globalThis as GlobalWithLinkSlot)[LINK_SLOT] ?? null;\n}\n","\"use client\";\n\nimport {\n TooltipProvider,\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n} from \"./tooltip\";\n\n/**\n * Wraps a TapTargetButton (or any tap control) like the button-demo page:\n * no extra padding on the control — only `gap-0.5` before the caption.\n * Tooltip shows the full `label`; the caption truncates at max-w-[52px].\n */\nexport function TapTargetLabeled({\n label,\n children,\n hideLabel = false,\n toolTipSide = \"bottom\",\n}: {\n label: string;\n children: React.ReactNode;\n hideLabel?: boolean | undefined;\n toolTipSide?: \"top\" | \"bottom\" | \"left\" | \"right\" | undefined;\n}) {\n return (\n <TooltipProvider delayDuration={200}>\n <Tooltip>\n <TooltipTrigger asChild>\n <div className=\"flex flex-col items-center p-0 gap-0 space-y-0 space-x-0 shrink-0\">\n {children}\n {!hideLabel && (\n <span className=\"text-[10px] text-muted-foreground/70 leading-tight max-w-[52px] text-center truncate\">\n {label}\n </span>\n )}\n </div>\n </TooltipTrigger>\n <TooltipContent side={toolTipSide}>\n <span className=\"font-mono text-xs max-w-[280px] break-all\">\n {label}\n </span>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n"],"mappings":"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","names":["forwardRef","TooltipPrimitive","jsx","forwardRef","TapTargetButton","TapTargetButtonTransparent","TapTargetButtonSolid","TapTargetButtonDestructive","TapTargetButtonForGroup","jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":["../src/tap-target-button.tsx","../src/cn.ts","../src/link.ts","../src/tap-target-labeled.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n cloneElement,\n forwardRef,\n isValidElement,\n type ButtonHTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\n\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@ai-matrx/design-system\";\nimport { cn } from \"./cn\";\nimport {\n getTapTargetLinkComponent,\n type TapTargetLinkComponent,\n} from \"./link\";\n\nexport interface TapTargetButtonProps {\n icon?: React.ReactNode;\n children?: React.ReactNode;\n strokeWidth?: number | undefined;\n onClick?: (() => void) | undefined;\n className?: string | undefined;\n as?: \"button\" | \"label\" | undefined;\n htmlFor?: string | undefined;\n ariaLabel?: string | undefined;\n disabled?: boolean | undefined;\n /**\n * When set, the tap button renders as a link instead of a button.\n * - Internal hrefs (e.g. \"/tasks\") render via the injected link component\n * (`setTapTargetLinkComponent` / the `linkComponent` prop), falling back\n * to a plain `<a>` when none is registered.\n * - External hrefs (http://, https://, mailto:, tel:) render as `<a>`\n * with `target=\"_blank\"` and `rel=\"noopener noreferrer\"` by default.\n * - When combined with `disabled`, the trigger renders as a non-navigable\n * `<span aria-disabled=\"true\">` with the same visual styling.\n */\n href?: string | undefined;\n /** Override target. Works on both internal links and external anchors. */\n target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\" | undefined;\n /** Override rel. Works on both internal links and external anchors. */\n rel?: string | undefined;\n /** Forwarded to the injected link component. Pass `false` to disable prefetching. */\n prefetch?: boolean | null | undefined;\n /**\n * Per-instance link component for internal hrefs — overrides the\n * module-level `setTapTargetLinkComponent` registration.\n */\n linkComponent?: TapTargetLinkComponent | undefined;\n /**\n * Tooltip text. Defaults to `ariaLabel` when omitted.\n * Pass `false` to explicitly disable the tooltip.\n */\n tooltip?: string | false | undefined;\n /** Tooltip placement. Defaults to \"top\". */\n tooltipSide?: \"top\" | \"right\" | \"bottom\" | \"left\" | undefined;\n /** Tooltip alignment along its side. Defaults to \"center\". */\n tooltipAlign?: \"start\" | \"center\" | \"end\" | undefined;\n /**\n * Visible caption rendered inline after the icon (`[icon Label]`).\n * Widens the pill automatically. Tooltip defaults to off when set — the\n * label is self-describing. Visible text becomes the accessible name.\n */\n label?: string | undefined;\n /**\n * Collapse an icon + caption pill to its icon-only 44px tap target below\n * the `sm` breakpoint. The caption and inline geometry return at `sm+`;\n * `ariaLabel` (falling back to `label`) remains the accessible name.\n */\n mobileIconOnly?: boolean | undefined;\n}\n\nexport interface TapTargetButtonSolidProps extends TapTargetButtonProps {\n bgColor?: string | undefined;\n iconColor?: string | undefined;\n hoverBgColor?: string | undefined;\n /**\n * Press-state background. Defaults to `active:brightness-90` which works on\n * any color. Override when using a custom `bgColor` that should darken to a\n * specific shade on press (e.g. `active:bg-primary/60`).\n */\n activeBgColor?: string | undefined;\n}\n\nconst EXTERNAL_RE = /^(https?:|mailto:|tel:)/i;\n\n// Geometry + press feedback + tap hygiene are the SINGLE SOURCE OF TRUTH in\n// the shipped stylesheet (the `.matrx-tap-*` family in styles.css — import\n// \"@ai-matrx/tap-target/styles.css\" once at app root). This component only\n// picks the right class and layers each variant's decoration on top.\nconst TAP_OUTER_CLASS = \"matrx-tap-target group\";\nconst TAP_GROUP_OUTER_CLASS = \"matrx-tap-target matrx-tap-target-sm group\";\n\nfunction IconContent({\n icon,\n children,\n strokeWidth = 2,\n className,\n}: Pick<\n TapTargetButtonProps,\n \"icon\" | \"children\" | \"strokeWidth\" | \"className\"\n>) {\n if (icon) {\n if (isValidElement<{ className?: string }>(icon)) {\n return cloneElement(icon, {\n className: cn(className, icon.props.className),\n });\n }\n return <span className={className}>{icon}</span>;\n }\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n >\n {children}\n </svg>\n );\n}\n\ntype TapTargetSize = \"default\" | \"sm\";\n\nfunction resolveTapGeometry(\n label: string | undefined,\n size: TapTargetSize,\n mobileIconOnly: boolean,\n) {\n const inline = Boolean(label);\n if (size === \"sm\") {\n return {\n outerClassName:\n inline && mobileIconOnly\n ? \"matrx-tap-target matrx-tap-target-sm matrx-tap-target-mobile-icon-only-sm group\"\n : inline\n ? \"matrx-tap-target matrx-tap-target-sm matrx-tap-target-inline-sm group\"\n : TAP_GROUP_OUTER_CLASS,\n inlineModifier: mobileIconOnly\n ? \"matrx-tap-pill-mobile-icon-only-sm\"\n : \"matrx-tap-pill-inline-sm\",\n };\n }\n return {\n outerClassName:\n inline && mobileIconOnly\n ? `${TAP_OUTER_CLASS} matrx-tap-target-mobile-icon-only`\n : inline\n ? `${TAP_OUTER_CLASS} matrx-tap-target-inline`\n : TAP_OUTER_CLASS,\n inlineModifier: mobileIconOnly\n ? \"matrx-tap-pill-mobile-icon-only\"\n : \"matrx-tap-pill-inline\",\n };\n}\n\nfunction buildTapInner({\n label,\n pillClassName,\n iconClassName,\n labelClassName,\n inlineModifier,\n icon,\n children,\n strokeWidth = 2,\n}: {\n label?: string | undefined;\n pillClassName: string;\n iconClassName: string;\n labelClassName?: string | undefined;\n inlineModifier: string;\n icon?: React.ReactNode;\n children?: React.ReactNode;\n strokeWidth?: number | undefined;\n}) {\n const iconEl = (\n <IconContent\n icon={icon}\n strokeWidth={strokeWidth}\n className={iconClassName}\n >\n {children}\n </IconContent>\n );\n const pillClasses = label\n ? `${pillClassName} ${inlineModifier}`.trim()\n : pillClassName;\n\n if (!label) {\n return <div className={pillClasses}>{iconEl}</div>;\n }\n\n return (\n <div className={pillClasses}>\n {iconEl}\n <span className={labelClassName ?? \"matrx-tap-label\"}>{label}</span>\n </div>\n );\n}\n\ninterface RenderTapTargetArgs extends Pick<\n TapTargetButtonProps,\n | \"icon\"\n | \"children\"\n | \"strokeWidth\"\n | \"label\"\n | \"mobileIconOnly\"\n | \"onClick\"\n | \"as\"\n | \"htmlFor\"\n | \"ariaLabel\"\n | \"disabled\"\n | \"href\"\n | \"target\"\n | \"rel\"\n | \"prefetch\"\n | \"linkComponent\"\n | \"tooltip\"\n | \"tooltipSide\"\n | \"tooltipAlign\"\n> {\n size?: TapTargetSize;\n pillClassName: string;\n iconClassName: string;\n labelClassName?: string | undefined;\n rest?: ButtonHTMLAttributes<HTMLButtonElement> | undefined;\n buttonRef?: Ref<HTMLButtonElement> | undefined;\n}\n\nfunction renderTapTarget({\n size = \"default\",\n pillClassName,\n iconClassName,\n labelClassName,\n icon,\n children,\n strokeWidth,\n label,\n mobileIconOnly = false,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n rest,\n buttonRef,\n}: RenderTapTargetArgs): ReactElement {\n const { outerClassName, inlineModifier } = resolveTapGeometry(\n label,\n size,\n mobileIconOnly,\n );\n const responsiveLabelClassName = mobileIconOnly\n ? `${labelClassName ?? \"matrx-tap-label\"} matrx-tap-label-mobile-icon-only`\n : labelClassName;\n const inner = buildTapInner({\n label,\n pillClassName,\n iconClassName,\n labelClassName: responsiveLabelClassName,\n inlineModifier: label ? inlineModifier : \"\",\n icon,\n children,\n strokeWidth,\n });\n const resolvedTooltip =\n tooltip !== undefined ? tooltip : label ? false : undefined;\n const triggerAriaLabel =\n label && !mobileIconOnly ? undefined : (ariaLabel ?? label);\n const trigger = renderTrigger({\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n as,\n htmlFor,\n onClick,\n ariaLabel: triggerAriaLabel,\n disabled,\n outerClassName,\n children: inner,\n rest,\n buttonRef,\n });\n return withTooltip(trigger, {\n tooltip: resolvedTooltip,\n ariaLabel: triggerAriaLabel,\n disabled,\n tooltipSide,\n tooltipAlign,\n });\n}\n\ninterface RenderTriggerArgs {\n href?: string | undefined;\n target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\" | undefined;\n rel?: string | undefined;\n prefetch?: boolean | null | undefined;\n linkComponent?: TapTargetLinkComponent | undefined;\n as?: \"button\" | \"label\" | undefined;\n htmlFor?: string | undefined;\n onClick?: (() => void) | undefined;\n ariaLabel?: string | undefined;\n disabled?: boolean | undefined;\n outerClassName: string;\n children: ReactNode;\n rest?: ButtonHTMLAttributes<HTMLButtonElement> | undefined;\n buttonRef?: Ref<HTMLButtonElement> | undefined;\n}\n\n/**\n * Resolves the correct trigger element based on the props passed.\n *\n * - `href` + `disabled` → unclickable `<span aria-disabled>`\n * - `href` matching `http(s):|mailto:|tel:` → `<a target=\"_blank\" rel=\"noopener noreferrer\">`\n * - `href` (internal) → the injected link component (per-instance\n * `linkComponent` prop, else `setTapTargetLinkComponent` registration),\n * falling back to a plain `<a>` when none is registered\n * - `as=\"label\"` → `<label htmlFor=...>`\n * - default → `<button>`\n */\nfunction renderTrigger({\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n as,\n htmlFor,\n onClick,\n ariaLabel,\n disabled,\n outerClassName,\n children,\n rest,\n buttonRef,\n}: RenderTriggerArgs): ReactElement {\n if (disabled && href) {\n return (\n <span\n aria-disabled=\"true\"\n aria-label={ariaLabel}\n className={`${outerClassName} opacity-40 pointer-events-none`}\n >\n {children}\n </span>\n );\n }\n if (href) {\n const isExternal = EXTERNAL_RE.test(href);\n if (isExternal) {\n return (\n <a\n href={href}\n target={target ?? \"_blank\"}\n rel={rel ?? \"noopener noreferrer\"}\n aria-label={ariaLabel}\n className={outerClassName}\n >\n {children}\n </a>\n );\n }\n const Link = linkComponent ?? getTapTargetLinkComponent();\n if (Link) {\n return (\n <Link\n href={href}\n target={target}\n rel={rel}\n prefetch={prefetch}\n aria-label={ariaLabel}\n className={outerClassName}\n >\n {children}\n </Link>\n );\n }\n // No link component registered — plain <a>. `prefetch` is a router hint,\n // not a DOM attribute, so it is deliberately dropped here.\n return (\n <a\n href={href}\n target={target}\n rel={rel}\n aria-label={ariaLabel}\n className={outerClassName}\n >\n {children}\n </a>\n );\n }\n if (as === \"label\") {\n return (\n <label\n htmlFor={htmlFor}\n aria-label={ariaLabel}\n className={outerClassName}\n >\n {children}\n </label>\n );\n }\n return (\n <button\n ref={buttonRef}\n type=\"button\"\n onClick={onClick}\n aria-label={ariaLabel}\n disabled={disabled}\n {...rest}\n className={outerClassName}\n >\n {children}\n </button>\n );\n}\n\n/**\n * Wraps a trigger element in a Tooltip when a tooltip label is available.\n * Falls back to `ariaLabel` when `tooltip` is not explicitly set. If both\n * are absent (or `tooltip === false`), the trigger is returned unwrapped.\n */\nfunction withTooltip(\n trigger: ReactElement,\n {\n tooltip,\n ariaLabel,\n disabled,\n tooltipSide = \"top\",\n tooltipAlign = \"center\",\n }: {\n tooltip?: string | false | undefined;\n ariaLabel?: string | undefined;\n disabled?: boolean | undefined;\n tooltipSide?: \"top\" | \"right\" | \"bottom\" | \"left\" | undefined;\n tooltipAlign?: \"start\" | \"center\" | \"end\" | undefined;\n },\n): ReactElement {\n if (tooltip === false) return trigger;\n const label =\n typeof tooltip === \"string\" && tooltip.length > 0 ? tooltip : ariaLabel;\n if (!label) return trigger;\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n {disabled ? (\n // Radix Tooltip triggers need a hoverable element; a disabled button\n // does not dispatch pointer events, so we wrap in a span for the\n // trigger target while keeping the disabled visual state.\n <span className=\"inline-flex\">{trigger}</span>\n ) : (\n trigger\n )}\n </TooltipTrigger>\n <TooltipContent side={tooltipSide} align={tooltipAlign}>\n {label}\n </TooltipContent>\n </Tooltip>\n );\n}\n\n// To resize/retune every tap button, edit styles.css — not here.\n\nexport const TapTargetButton = forwardRef<\n HTMLButtonElement,\n TapTargetButtonProps & ButtonHTMLAttributes<HTMLButtonElement>\n>(function TapTargetButton(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n className,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n const color = className ?? \"text-foreground\";\n return renderTapTarget({\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n pillClassName: \"matrx-tap-pill matrx-glass-thin-border\",\n iconClassName: `matrx-tap-icon ${color}`,\n rest,\n buttonRef: ref,\n });\n});\n\nexport const TapTargetButtonTransparent = forwardRef<\n HTMLButtonElement,\n TapTargetButtonProps & React.ButtonHTMLAttributes<HTMLButtonElement>\n>(function TapTargetButtonTransparent(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n className,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n const color = className ?? \"text-foreground\";\n return renderTapTarget({\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n pillClassName:\n \"matrx-tap-pill hover:bg-muted active:bg-muted-foreground/15\",\n iconClassName: `matrx-tap-icon ${color}`,\n rest,\n buttonRef: ref,\n });\n});\n\nexport const TapTargetButtonSolid = forwardRef<\n HTMLButtonElement,\n TapTargetButtonSolidProps & React.ButtonHTMLAttributes<HTMLButtonElement>\n>(function TapTargetButtonSolid(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n bgColor = \"bg-primary\",\n iconColor = \"text-primary-foreground\",\n hoverBgColor = \"hover:bg-primary/80\",\n activeBgColor = \"active:brightness-90\",\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n return renderTapTarget({\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n pillClassName: `matrx-tap-pill ${bgColor} ${iconColor} ${hoverBgColor} ${activeBgColor}`,\n iconClassName: `matrx-tap-icon ${iconColor}`,\n labelClassName: `matrx-tap-label ${iconColor}`,\n rest,\n buttonRef: ref,\n });\n});\n\n/** Solid destructive pill — delete/remove actions. White-on-red like the\n * primary solid is white-on-blue. Use THIS, never hand-pass bg-destructive\n * with the default (dark) icon color. */\nexport const TapTargetButtonDestructive = forwardRef<\n HTMLButtonElement,\n TapTargetButtonSolidProps & React.ButtonHTMLAttributes<HTMLButtonElement>\n>(function TapTargetButtonDestructive(\n {\n bgColor = \"bg-destructive\",\n iconColor = \"text-destructive-foreground\",\n hoverBgColor = \"hover:bg-destructive/90\",\n ...rest\n },\n ref,\n) {\n return (\n <TapTargetButtonSolid\n ref={ref}\n bgColor={bgColor}\n iconColor={iconColor}\n hoverBgColor={hoverBgColor}\n {...rest}\n />\n );\n});\n\nexport const TapTargetButtonForGroup = forwardRef<\n HTMLButtonElement,\n TapTargetButtonProps & ButtonHTMLAttributes<HTMLButtonElement>\n>(function TapTargetButtonForGroup(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n className,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n const color = className ?? \"text-foreground\";\n return renderTapTarget({\n size: \"sm\",\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n pillClassName: \"matrx-tap-pill matrx-tap-pill-sm matrx-glass-interactive\",\n iconClassName: `matrx-tap-icon ${color}`,\n labelClassName: `matrx-tap-label ${color}`,\n rest,\n buttonRef: ref,\n });\n});\n\nexport function TapTargetButtonGroup({\n children,\n className,\n}: {\n children: React.ReactNode;\n className?: string | undefined;\n}) {\n return (\n <div\n className={\n className\n ? `relative inline-flex h-9 items-center ${className}`\n : \"relative inline-flex h-9 items-center\"\n }\n >\n <div className=\"pointer-events-none absolute inset-x-0 top-1/2 -translate-y-1/2 h-7 rounded-full matrx-glass-thin-border\" />\n {/* min-w-0 lets flexible children (e.g. a truncating filename) shrink\n under container pressure; fixed-size tap buttons are unaffected. */}\n <div className=\"relative flex min-w-0 items-center\">{children}</div>\n </div>\n );\n}\n","/**\n * Minimal className join — the only piece of `cn` this package needs.\n * No tailwind-merge / clsx dependency by design: callers pass literal strings.\n */\nexport function cn(\n ...values: Array<string | null | undefined | false>\n): string {\n return values.filter(Boolean).join(\" \").trim();\n}\n","import type { ComponentType, ReactNode } from \"react\";\n\n/**\n * The injectable link seam — the package's replacement for the original\n * hard `next/link` import.\n *\n * Internal hrefs (anything NOT matching `http(s):`, `mailto:`, `tel:`) render\n * through the link component resolved here; external hrefs always render a\n * plain `<a target=\"_blank\" rel=\"noopener noreferrer\">`, exactly like the\n * original. When nothing is registered and no per-instance `linkComponent`\n * prop is given, internal hrefs fall back to a plain `<a>` (no prefetch, no\n * client-side routing — still a working link).\n */\nexport interface TapTargetLinkProps {\n href: string;\n target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\" | undefined;\n rel?: string | undefined;\n /** Router prefetch hint (next/link semantics). Plain `<a>` fallback ignores it. */\n prefetch?: boolean | null | undefined;\n \"aria-label\"?: string | undefined;\n className?: string | undefined;\n children?: ReactNode;\n}\n\nexport type TapTargetLinkComponent = ComponentType<TapTargetLinkProps>;\n\n/**\n * The registered component lives in a `Symbol.for` slot on `globalThis` — NOT\n * in module state — so it survives the module graph being instantiated more\n * than once: the `.` and `./buttons` dist bundles each inline the primitives\n * (tsup `splitting: false`), and a consumer may even mix `import` and\n * `require`. One registration must reach every copy.\n */\nconst LINK_SLOT = Symbol.for(\"@ai-matrx/tap-target:link-component\");\n\ntype GlobalWithLinkSlot = typeof globalThis & {\n [LINK_SLOT]?: TapTargetLinkComponent | null;\n};\n\n/**\n * Register the app's link component once at startup (e.g. `next/link`):\n *\n * ```tsx\n * import Link from \"next/link\";\n * import { setTapTargetLinkComponent } from \"@ai-matrx/tap-target\";\n * setTapTargetLinkComponent(Link);\n * ```\n *\n * Pass `null` to unregister (plain `<a>` fallback resumes).\n */\nexport function setTapTargetLinkComponent(\n component: TapTargetLinkComponent | null,\n): void {\n (globalThis as GlobalWithLinkSlot)[LINK_SLOT] = component;\n}\n\n/** The currently registered link component, or `null` when none is set. */\nexport function getTapTargetLinkComponent(): TapTargetLinkComponent | null {\n return (globalThis as GlobalWithLinkSlot)[LINK_SLOT] ?? null;\n}\n","\"use client\";\n\nimport {\n TooltipProvider,\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n} from \"@ai-matrx/design-system\";\n\n/**\n * Wraps a TapTargetButton (or any tap control) like the button-demo page:\n * no extra padding on the control — only `gap-0.5` before the caption.\n * Tooltip shows the full `label`; the caption truncates at max-w-[52px].\n */\nexport function TapTargetLabeled({\n label,\n children,\n hideLabel = false,\n toolTipSide = \"bottom\",\n}: {\n label: string;\n children: React.ReactNode;\n hideLabel?: boolean | undefined;\n toolTipSide?: \"top\" | \"bottom\" | \"left\" | \"right\" | undefined;\n}) {\n return (\n <TooltipProvider delayDuration={200}>\n <Tooltip>\n <TooltipTrigger asChild>\n <div className=\"flex flex-col items-center p-0 gap-0 space-y-0 space-x-0 shrink-0\">\n {children}\n {!hideLabel && (\n <span className=\"text-[10px] text-muted-foreground/70 leading-tight max-w-[52px] text-center truncate\">\n {label}\n </span>\n )}\n </div>\n </TooltipTrigger>\n <TooltipContent side={toolTipSide}>\n <span className=\"font-mono text-xs max-w-[280px] break-all\">\n {label}\n </span>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n"],"mappings":"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","names":["TapTargetButton","TapTargetButtonTransparent","TapTargetButtonSolid","TapTargetButtonDestructive","TapTargetButtonForGroup","Tooltip","TooltipTrigger","TooltipContent","jsx","jsxs"]}
|
package/dist/styles.css
CHANGED
|
@@ -5,6 +5,21 @@
|
|
|
5
5
|
CSS without requiring a layer-order declaration). Until the C9 swap removes
|
|
6
6
|
the matrx-frontend originals, any change here ships in BOTH places. */
|
|
7
7
|
|
|
8
|
+
/* @ai-matrx/design-system's stylesheet is REQUIRED by this one, not merely
|
|
9
|
+
recommended (0.2.1). Two reasons, and neither is optional:
|
|
10
|
+
1. `LoadingTapButton`'s spinner wears `matrx-spin`, whose keyframe and rule
|
|
11
|
+
are DEFINED THERE. Copying those four lines here would make a second
|
|
12
|
+
source of truth for one animation — the exact twin census row 19i
|
|
13
|
+
exists to kill — so the sheet is imported instead.
|
|
14
|
+
2. This package already renders design-system components (Tooltip), so
|
|
15
|
+
every correct host loads it anyway.
|
|
16
|
+
`@ai-matrx/design-system` is a real `dependencies` entry of this package, so
|
|
17
|
+
this bare specifier resolves from a plain `npm install @ai-matrx/tap-target`
|
|
18
|
+
with nothing else in the host's manifest. A host that already imports the
|
|
19
|
+
design-system sheet itself loses nothing: bundlers resolve both to one file.
|
|
20
|
+
NOTE: `@import` must lead the file — keep any future rules BELOW it. */
|
|
21
|
+
@import "@ai-matrx/design-system/styles.css";
|
|
22
|
+
|
|
8
23
|
/* =========================================================================
|
|
9
24
|
TapTargetButton — SINGLE SOURCE OF TRUTH for tap-button geometry + feedback.
|
|
10
25
|
This is the ONLY place these are defined (previously also duplicated in
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-matrx/tap-target",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "The AI Matrx tap-target button system: an invisible 44x44 touch ring over a 32x32 visible pill, glass/transparent/solid/group variants with correct ref forwarding for Radix asChild triggers, inline labels, link/label/button trigger resolution with an injectable link component, tooltip wiring, and ~60 pre-composed one-tag buttons.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -56,7 +56,8 @@
|
|
|
56
56
|
"./package.json": "./package.json"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@radix-ui/react-tooltip": "^1.2.8"
|
|
59
|
+
"@radix-ui/react-tooltip": "^1.2.8",
|
|
60
|
+
"@ai-matrx/design-system": "0.11.2"
|
|
60
61
|
},
|
|
61
62
|
"peerDependencies": {
|
|
62
63
|
"react": ">=18.0.0"
|