@ai-matrx/tap-target 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/LICENSE +21 -0
- package/README.md +127 -0
- package/dist/buttons.cjs +1155 -0
- package/dist/buttons.cjs.map +1 -0
- package/dist/buttons.d.cts +109 -0
- package/dist/buttons.d.ts +109 -0
- package/dist/buttons.js +1127 -0
- package/dist/buttons.js.map +1 -0
- package/dist/index.cjs +581 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +108 -0
- package/dist/index.d.ts +108 -0
- package/dist/index.js +553 -0
- package/dist/index.js.map +1 -0
- package/dist/link-CkRpHgou.d.cts +40 -0
- package/dist/link-CkRpHgou.d.ts +40 -0
- package/dist/styles.css +110 -0
- package/package.json +96 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ComponentType, ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The injectable link seam — the package's replacement for the original
|
|
5
|
+
* hard `next/link` import.
|
|
6
|
+
*
|
|
7
|
+
* Internal hrefs (anything NOT matching `http(s):`, `mailto:`, `tel:`) render
|
|
8
|
+
* through the link component resolved here; external hrefs always render a
|
|
9
|
+
* plain `<a target="_blank" rel="noopener noreferrer">`, exactly like the
|
|
10
|
+
* original. When nothing is registered and no per-instance `linkComponent`
|
|
11
|
+
* prop is given, internal hrefs fall back to a plain `<a>` (no prefetch, no
|
|
12
|
+
* client-side routing — still a working link).
|
|
13
|
+
*/
|
|
14
|
+
interface TapTargetLinkProps {
|
|
15
|
+
href: string;
|
|
16
|
+
target?: "_blank" | "_self" | "_parent" | "_top" | undefined;
|
|
17
|
+
rel?: string | undefined;
|
|
18
|
+
/** Router prefetch hint (next/link semantics). Plain `<a>` fallback ignores it. */
|
|
19
|
+
prefetch?: boolean | null | undefined;
|
|
20
|
+
"aria-label"?: string | undefined;
|
|
21
|
+
className?: string | undefined;
|
|
22
|
+
children?: ReactNode;
|
|
23
|
+
}
|
|
24
|
+
type TapTargetLinkComponent = ComponentType<TapTargetLinkProps>;
|
|
25
|
+
/**
|
|
26
|
+
* Register the app's link component once at startup (e.g. `next/link`):
|
|
27
|
+
*
|
|
28
|
+
* ```tsx
|
|
29
|
+
* import Link from "next/link";
|
|
30
|
+
* import { setTapTargetLinkComponent } from "@ai-matrx/tap-target";
|
|
31
|
+
* setTapTargetLinkComponent(Link);
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* Pass `null` to unregister (plain `<a>` fallback resumes).
|
|
35
|
+
*/
|
|
36
|
+
declare function setTapTargetLinkComponent(component: TapTargetLinkComponent | null): void;
|
|
37
|
+
/** The currently registered link component, or `null` when none is set. */
|
|
38
|
+
declare function getTapTargetLinkComponent(): TapTargetLinkComponent | null;
|
|
39
|
+
|
|
40
|
+
export { type TapTargetLinkComponent as T, type TapTargetLinkProps as a, getTapTargetLinkComponent as g, setTapTargetLinkComponent as s };
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/* @ai-matrx/tap-target — REQUIRED stylesheet. Import once at your app root:
|
|
2
|
+
import "@ai-matrx/tap-target/styles.css";
|
|
3
|
+
Extracted VERBATIM from matrx-frontend app/globals.css (where it lives inside
|
|
4
|
+
`@layer components`; shipped unlayered here so it wins against unlayered host
|
|
5
|
+
CSS without requiring a layer-order declaration). Until the C9 swap removes
|
|
6
|
+
the matrx-frontend originals, any change here ships in BOTH places. */
|
|
7
|
+
|
|
8
|
+
/* =========================================================================
|
|
9
|
+
TapTargetButton — SINGLE SOURCE OF TRUTH for tap-button geometry + feedback.
|
|
10
|
+
This is the ONLY place these are defined (previously also duplicated in
|
|
11
|
+
styles/shell.css, which caused the same button to resolve differently
|
|
12
|
+
inside vs outside the shell). Consumed exclusively by
|
|
13
|
+
components/icons/TapTargetButton.tsx. To resize or retune EVERY tap button
|
|
14
|
+
in the app, edit HERE — nowhere else.
|
|
15
|
+
|
|
16
|
+
Structure per button:
|
|
17
|
+
.matrx-tap-target — outer 44px invisible touch target = the interactive
|
|
18
|
+
element (<button>/<a>/<label>). It owns the tap
|
|
19
|
+
hygiene (touch-action + tap-highlight) so it applies
|
|
20
|
+
to the WHOLE 44px target AND to the link variants —
|
|
21
|
+
the iOS gray flash paints on the anchor, not the
|
|
22
|
+
inner pill, so putting it on the pill never worked.
|
|
23
|
+
.matrx-tap-pill — inner 28px visible pill. Geometry + press feedback.
|
|
24
|
+
Each variant layers ONLY its decoration on top (glass
|
|
25
|
+
border / solid fill / hover bg) — the size is identical
|
|
26
|
+
across glass / transparent / solid, guaranteed here.
|
|
27
|
+
.matrx-tap-icon — 14px icon.
|
|
28
|
+
.matrx-tap-*-inline — wider auto-width geometry when `label` is set on
|
|
29
|
+
TapTargetButton (icon + caption on one row).
|
|
30
|
+
The `-sm` classes (32 / 20px) are the slimmer geometry used inside groups.
|
|
31
|
+
========================================================================= */
|
|
32
|
+
.matrx-tap-target {
|
|
33
|
+
display: flex;
|
|
34
|
+
height: 2.75rem; /* 44px outer tap target */
|
|
35
|
+
width: 2.75rem;
|
|
36
|
+
flex-shrink: 0; /* a tap target never squishes under flex pressure —
|
|
37
|
+
flexible neighbors (truncating labels) absorb it */
|
|
38
|
+
align-items: center;
|
|
39
|
+
justify-content: center;
|
|
40
|
+
background-color: transparent;
|
|
41
|
+
cursor: pointer;
|
|
42
|
+
outline: none;
|
|
43
|
+
touch-action: manipulation; /* kills the 300ms mobile tap delay */
|
|
44
|
+
-webkit-tap-highlight-color: transparent; /* kills the iOS gray tap flash */
|
|
45
|
+
}
|
|
46
|
+
.matrx-tap-target:disabled {
|
|
47
|
+
opacity: 0.4;
|
|
48
|
+
pointer-events: none;
|
|
49
|
+
}
|
|
50
|
+
.matrx-tap-target-sm {
|
|
51
|
+
height: 2rem; /* 32px */
|
|
52
|
+
width: 2rem;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.matrx-tap-pill {
|
|
56
|
+
display: flex;
|
|
57
|
+
height: 1.75rem; /* 28px visible pill */
|
|
58
|
+
width: 1.75rem;
|
|
59
|
+
align-items: center;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
border-radius: 9999px;
|
|
62
|
+
transition:
|
|
63
|
+
background-color 150ms ease,
|
|
64
|
+
transform 100ms ease;
|
|
65
|
+
}
|
|
66
|
+
.matrx-tap-pill:active {
|
|
67
|
+
transform: scale(0.92);
|
|
68
|
+
}
|
|
69
|
+
.matrx-tap-pill-sm {
|
|
70
|
+
height: 1.25rem; /* 20px */
|
|
71
|
+
width: 1.25rem;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.matrx-tap-icon {
|
|
75
|
+
height: 0.875rem; /* 14px */
|
|
76
|
+
width: 0.875rem;
|
|
77
|
+
flex-shrink: 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Inline label — icon + text on one row inside the pill */
|
|
81
|
+
.matrx-tap-target-inline {
|
|
82
|
+
width: auto;
|
|
83
|
+
min-width: 2.75rem;
|
|
84
|
+
padding-inline: 0.25rem;
|
|
85
|
+
}
|
|
86
|
+
.matrx-tap-pill-inline {
|
|
87
|
+
width: auto;
|
|
88
|
+
gap: 0.375rem;
|
|
89
|
+
padding-inline: 0.625rem;
|
|
90
|
+
}
|
|
91
|
+
.matrx-tap-label {
|
|
92
|
+
font-size: 0.75rem;
|
|
93
|
+
font-weight: 500;
|
|
94
|
+
line-height: 1;
|
|
95
|
+
white-space: nowrap;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.matrx-tap-target-inline-sm {
|
|
99
|
+
width: auto;
|
|
100
|
+
min-width: 2rem;
|
|
101
|
+
padding-inline: 0.125rem;
|
|
102
|
+
}
|
|
103
|
+
.matrx-tap-pill-inline-sm {
|
|
104
|
+
width: auto;
|
|
105
|
+
gap: 0.25rem;
|
|
106
|
+
padding-inline: 0.5rem;
|
|
107
|
+
}
|
|
108
|
+
.matrx-tap-pill-inline-sm .matrx-tap-label {
|
|
109
|
+
font-size: 0.625rem;
|
|
110
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ai-matrx/tap-target",
|
|
3
|
+
"version": "0.1.0",
|
|
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
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"tap-target",
|
|
12
|
+
"touch-target",
|
|
13
|
+
"icon-button",
|
|
14
|
+
"react",
|
|
15
|
+
"radix",
|
|
16
|
+
"a11y",
|
|
17
|
+
"ai-matrx"
|
|
18
|
+
],
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/AI-Matrix-Engine/aidream.git",
|
|
22
|
+
"directory": "apps/shared/tap-target"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/AI-Matrix-Engine/aidream/tree/main/apps/shared/tap-target#readme",
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/AI-Matrix-Engine/aidream/issues"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md",
|
|
31
|
+
"LICENSE",
|
|
32
|
+
"CHANGELOG.md"
|
|
33
|
+
],
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"default": "./dist/index.js"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/index.d.cts",
|
|
42
|
+
"default": "./dist/index.cjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"./buttons": {
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./dist/buttons.d.ts",
|
|
48
|
+
"default": "./dist/buttons.js"
|
|
49
|
+
},
|
|
50
|
+
"require": {
|
|
51
|
+
"types": "./dist/buttons.d.cts",
|
|
52
|
+
"default": "./dist/buttons.cjs"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"./styles.css": "./dist/styles.css",
|
|
56
|
+
"./package.json": "./package.json"
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@radix-ui/react-tooltip": "^1.2.8"
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"react": ">=18.0.0"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
66
|
+
"@testing-library/react": "^16.3.0",
|
|
67
|
+
"@types/node": "^22.20.0",
|
|
68
|
+
"@types/react": "^19.1.0",
|
|
69
|
+
"jsdom": "^25.0.1",
|
|
70
|
+
"publint": "^0.3.24",
|
|
71
|
+
"react": "^19.1.0",
|
|
72
|
+
"react-dom": "^19.1.0",
|
|
73
|
+
"tsup": "^8.5.1",
|
|
74
|
+
"typescript": "^5.9.3",
|
|
75
|
+
"vitest": "^4.1.6"
|
|
76
|
+
},
|
|
77
|
+
"publishConfig": {
|
|
78
|
+
"access": "public",
|
|
79
|
+
"registry": "https://registry.npmjs.org/"
|
|
80
|
+
},
|
|
81
|
+
"engines": {
|
|
82
|
+
"node": ">=20"
|
|
83
|
+
},
|
|
84
|
+
"sideEffects": [
|
|
85
|
+
"*.css"
|
|
86
|
+
],
|
|
87
|
+
"scripts": {
|
|
88
|
+
"build": "tsup",
|
|
89
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
90
|
+
"check:package": "pnpm build && publint && pnpm verify:tarball",
|
|
91
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
92
|
+
"test": "vitest run",
|
|
93
|
+
"test:watch": "vitest",
|
|
94
|
+
"verify:tarball": "node ./scripts/verify-tarball.mjs"
|
|
95
|
+
}
|
|
96
|
+
}
|