@tea-ui/core 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/LICENSE +21 -0
- package/README.md +33 -0
- package/dist/card.d.ts +60 -0
- package/dist/card.js +116 -0
- package/dist/card.js.map +1 -0
- package/dist/feedback/alert.d.ts +57 -0
- package/dist/feedback/alert.js +104 -0
- package/dist/feedback/alert.js.map +1 -0
- package/dist/feedback/badge.d.ts +34 -0
- package/dist/feedback/badge.js +62 -0
- package/dist/feedback/badge.js.map +1 -0
- package/dist/feedback/index.d.ts +13 -0
- package/dist/feedback/index.js +62 -0
- package/dist/feedback/index.js.map +1 -0
- package/dist/feedback/progress.d.ts +25 -0
- package/dist/feedback/progress.js +49 -0
- package/dist/feedback/progress.js.map +1 -0
- package/dist/feedback/skeleton.d.ts +38 -0
- package/dist/feedback/skeleton.js +49 -0
- package/dist/feedback/skeleton.js.map +1 -0
- package/dist/feedback/spinner.d.ts +31 -0
- package/dist/feedback/spinner.js +55 -0
- package/dist/feedback/spinner.js.map +1 -0
- package/dist/feedback/status.d.ts +63 -0
- package/dist/feedback/status.js +156 -0
- package/dist/feedback/status.js.map +1 -0
- package/dist/feedback/toast.d.ts +72 -0
- package/dist/feedback/toast.js +211 -0
- package/dist/feedback/toast.js.map +1 -0
- package/dist/format/index.d.ts +63 -0
- package/dist/format/index.js +84 -0
- package/dist/format/index.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +163 -0
- package/dist/index.js.map +1 -0
- package/dist/inputs/button-group.d.ts +70 -0
- package/dist/inputs/button-group.js +59 -0
- package/dist/inputs/button-group.js.map +1 -0
- package/dist/inputs/button.d.ts +52 -0
- package/dist/inputs/button.js +84 -0
- package/dist/inputs/button.js.map +1 -0
- package/dist/inputs/checkbox.d.ts +48 -0
- package/dist/inputs/checkbox.js +74 -0
- package/dist/inputs/checkbox.js.map +1 -0
- package/dist/inputs/combobox.d.ts +77 -0
- package/dist/inputs/combobox.js +273 -0
- package/dist/inputs/combobox.js.map +1 -0
- package/dist/inputs/field.d.ts +220 -0
- package/dist/inputs/field.js +183 -0
- package/dist/inputs/field.js.map +1 -0
- package/dist/inputs/icon-button.d.ts +44 -0
- package/dist/inputs/icon-button.js +30 -0
- package/dist/inputs/icon-button.js.map +1 -0
- package/dist/inputs/index.d.ts +22 -0
- package/dist/inputs/index.js +92 -0
- package/dist/inputs/index.js.map +1 -0
- package/dist/inputs/input-group.d.ts +77 -0
- package/dist/inputs/input-group.js +76 -0
- package/dist/inputs/input-group.js.map +1 -0
- package/dist/inputs/input.d.ts +58 -0
- package/dist/inputs/input.js +68 -0
- package/dist/inputs/input.js.map +1 -0
- package/dist/inputs/label.d.ts +47 -0
- package/dist/inputs/label.js +29 -0
- package/dist/inputs/label.js.map +1 -0
- package/dist/inputs/number-input.d.ts +62 -0
- package/dist/inputs/number-input.js +86 -0
- package/dist/inputs/number-input.js.map +1 -0
- package/dist/inputs/password-input.d.ts +66 -0
- package/dist/inputs/password-input.js +73 -0
- package/dist/inputs/password-input.js.map +1 -0
- package/dist/inputs/radio.d.ts +66 -0
- package/dist/inputs/radio.js +96 -0
- package/dist/inputs/radio.js.map +1 -0
- package/dist/inputs/search-input.d.ts +66 -0
- package/dist/inputs/search-input.js +76 -0
- package/dist/inputs/search-input.js.map +1 -0
- package/dist/inputs/select.d.ts +65 -0
- package/dist/inputs/select.js +139 -0
- package/dist/inputs/select.js.map +1 -0
- package/dist/inputs/slider.d.ts +67 -0
- package/dist/inputs/slider.js +107 -0
- package/dist/inputs/slider.js.map +1 -0
- package/dist/inputs/switch.d.ts +42 -0
- package/dist/inputs/switch.js +69 -0
- package/dist/inputs/switch.js.map +1 -0
- package/dist/inputs/textarea.d.ts +51 -0
- package/dist/inputs/textarea.js +82 -0
- package/dist/inputs/textarea.js.map +1 -0
- package/dist/inputs/toggle.d.ts +57 -0
- package/dist/inputs/toggle.js +91 -0
- package/dist/inputs/toggle.js.map +1 -0
- package/dist/internal/index.d.ts +5 -0
- package/dist/internal/index.js +19 -0
- package/dist/internal/index.js.map +1 -0
- package/dist/internal/refs.d.ts +31 -0
- package/dist/internal/refs.js +34 -0
- package/dist/internal/refs.js.map +1 -0
- package/dist/internal/slot.d.ts +76 -0
- package/dist/internal/slot.js +40 -0
- package/dist/internal/slot.js.map +1 -0
- package/dist/internal/use-controllable-state.d.ts +25 -0
- package/dist/internal/use-controllable-state.js +38 -0
- package/dist/internal/use-controllable-state.js.map +1 -0
- package/dist/layout/index.d.ts +131 -0
- package/dist/layout/index.js +212 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/navigation/index.d.ts +114 -0
- package/dist/navigation/index.js +523 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/overlays/alert-dialog.d.ts +75 -0
- package/dist/overlays/alert-dialog.js +163 -0
- package/dist/overlays/alert-dialog.js.map +1 -0
- package/dist/overlays/dialog.d.ts +44 -0
- package/dist/overlays/dialog.js +121 -0
- package/dist/overlays/dialog.js.map +1 -0
- package/dist/overlays/drawer.d.ts +49 -0
- package/dist/overlays/drawer.js +125 -0
- package/dist/overlays/drawer.js.map +1 -0
- package/dist/overlays/dropdown-menu.d.ts +53 -0
- package/dist/overlays/dropdown-menu.js +192 -0
- package/dist/overlays/dropdown-menu.js.map +1 -0
- package/dist/overlays/index.d.ts +10 -0
- package/dist/overlays/index.js +169 -0
- package/dist/overlays/index.js.map +1 -0
- package/dist/overlays/popover.d.ts +58 -0
- package/dist/overlays/popover.js +105 -0
- package/dist/overlays/popover.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/typography/index.d.ts +79 -0
- package/dist/typography/index.js +280 -0
- package/dist/typography/index.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Slot } from "radix-ui";
|
|
4
|
+
import { ArrowRight, Copy, Check } from "@tea-ui/icons";
|
|
5
|
+
import { cn, cva } from "@tea-ui/utils";
|
|
6
|
+
import { COPY } from "@tea-ui/ux-standards";
|
|
7
|
+
import { dataSlot } from "../internal/index.js";
|
|
8
|
+
const textVariants = cva("", {
|
|
9
|
+
variants: {
|
|
10
|
+
size: {
|
|
11
|
+
label: "text-label",
|
|
12
|
+
micro: "text-micro",
|
|
13
|
+
ui: "text-ui",
|
|
14
|
+
body: "text-body",
|
|
15
|
+
lead: "text-lead",
|
|
16
|
+
title: "text-title",
|
|
17
|
+
section: "text-section",
|
|
18
|
+
display: "text-display",
|
|
19
|
+
hero: "text-hero"
|
|
20
|
+
},
|
|
21
|
+
tone: {
|
|
22
|
+
default: "text-fg",
|
|
23
|
+
muted: "text-fg-muted",
|
|
24
|
+
subtle: "text-fg-subtle",
|
|
25
|
+
inverse: "text-fg-inverse",
|
|
26
|
+
accent: "text-primary"
|
|
27
|
+
},
|
|
28
|
+
weight: {
|
|
29
|
+
normal: "font-normal",
|
|
30
|
+
medium: "font-medium",
|
|
31
|
+
semibold: "font-semibold",
|
|
32
|
+
bold: "font-bold"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
defaultVariants: { size: "ui", tone: "default" }
|
|
36
|
+
});
|
|
37
|
+
const Text = React.forwardRef(function Text2({
|
|
38
|
+
asChild = false,
|
|
39
|
+
as,
|
|
40
|
+
size,
|
|
41
|
+
tone,
|
|
42
|
+
weight,
|
|
43
|
+
align,
|
|
44
|
+
truncate = false,
|
|
45
|
+
balance = false,
|
|
46
|
+
className,
|
|
47
|
+
...props
|
|
48
|
+
}, ref) {
|
|
49
|
+
const Component = asChild ? Slot.Root : as ?? "p";
|
|
50
|
+
return /* @__PURE__ */ jsx(
|
|
51
|
+
Component,
|
|
52
|
+
{
|
|
53
|
+
ref,
|
|
54
|
+
className: cn(
|
|
55
|
+
textVariants({ size, tone, weight }),
|
|
56
|
+
align === "center" && "text-center",
|
|
57
|
+
align === "end" && "text-end",
|
|
58
|
+
align === "justify" && "text-justify",
|
|
59
|
+
truncate && "truncate",
|
|
60
|
+
balance && "text-balance",
|
|
61
|
+
className
|
|
62
|
+
),
|
|
63
|
+
...dataSlot("text"),
|
|
64
|
+
...props
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
const HEADING_SIZE = {
|
|
69
|
+
1: "text-display",
|
|
70
|
+
2: "text-section",
|
|
71
|
+
3: "text-title",
|
|
72
|
+
4: "text-lead",
|
|
73
|
+
5: "text-ui",
|
|
74
|
+
6: "text-label"
|
|
75
|
+
};
|
|
76
|
+
const Heading = React.forwardRef(function Heading2({ level, tone = "default", weight = "semibold", balance = true, className, ...props }, ref) {
|
|
77
|
+
const Tag = `h${level}`;
|
|
78
|
+
return /* @__PURE__ */ jsx(
|
|
79
|
+
Tag,
|
|
80
|
+
{
|
|
81
|
+
ref,
|
|
82
|
+
className: cn(
|
|
83
|
+
HEADING_SIZE[level],
|
|
84
|
+
level >= 4 && "font-medium",
|
|
85
|
+
level <= 2 && (weight === "bold" ? "font-bold" : "font-semibold"),
|
|
86
|
+
tone === "muted" && "text-fg-muted",
|
|
87
|
+
tone === "accent" && "text-primary",
|
|
88
|
+
balance && "text-balance",
|
|
89
|
+
className
|
|
90
|
+
),
|
|
91
|
+
...dataSlot("heading", `h${level}`),
|
|
92
|
+
...props
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
});
|
|
96
|
+
const Eyebrow = React.forwardRef(function Eyebrow2({ className, ...props }, ref) {
|
|
97
|
+
return /* @__PURE__ */ jsx(
|
|
98
|
+
"span",
|
|
99
|
+
{
|
|
100
|
+
ref,
|
|
101
|
+
className: cn("text-label font-semibold uppercase tracking-widest text-fg-muted", className),
|
|
102
|
+
...dataSlot("eyebrow"),
|
|
103
|
+
...props
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
const Caption = React.forwardRef(
|
|
108
|
+
function Caption2({ className, ...props }, ref) {
|
|
109
|
+
return /* @__PURE__ */ jsx(
|
|
110
|
+
"span",
|
|
111
|
+
{
|
|
112
|
+
ref,
|
|
113
|
+
className: cn("text-micro text-fg-subtle", className),
|
|
114
|
+
...dataSlot("caption"),
|
|
115
|
+
...props
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
const InlineCode = React.forwardRef(
|
|
121
|
+
function InlineCode2({ className, ...props }, ref) {
|
|
122
|
+
return /* @__PURE__ */ jsx(
|
|
123
|
+
"code",
|
|
124
|
+
{
|
|
125
|
+
ref,
|
|
126
|
+
className: cn(
|
|
127
|
+
"border border-line bg-surface-2 px-1 py-0.5 font-mono text-micro text-primary",
|
|
128
|
+
className
|
|
129
|
+
),
|
|
130
|
+
...dataSlot("code", "inline"),
|
|
131
|
+
...props
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
const Preformatted = React.forwardRef(function Preformatted2({ maxHeight, copyable = false, className, children, ...props }, ref) {
|
|
137
|
+
const [copied, setCopied] = React.useState(false);
|
|
138
|
+
const copy = React.useCallback(() => {
|
|
139
|
+
const text = typeof children === "string" ? children : event_text(children);
|
|
140
|
+
void navigator.clipboard?.writeText(text).then(() => {
|
|
141
|
+
setCopied(true);
|
|
142
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
143
|
+
});
|
|
144
|
+
}, [children]);
|
|
145
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), ...dataSlot("code", "block-wrapper"), children: [
|
|
146
|
+
/* @__PURE__ */ jsx(
|
|
147
|
+
"pre",
|
|
148
|
+
{
|
|
149
|
+
ref,
|
|
150
|
+
style: { maxHeight },
|
|
151
|
+
className: cn(
|
|
152
|
+
"overflow-auto border border-line bg-surface-2 p-3 font-mono text-mono text-fg",
|
|
153
|
+
maxHeight && "overflow-y-auto"
|
|
154
|
+
),
|
|
155
|
+
tabIndex: 0,
|
|
156
|
+
...dataSlot("code", "block"),
|
|
157
|
+
...props,
|
|
158
|
+
children
|
|
159
|
+
}
|
|
160
|
+
),
|
|
161
|
+
copyable ? /* @__PURE__ */ jsx(
|
|
162
|
+
"button",
|
|
163
|
+
{
|
|
164
|
+
type: "button",
|
|
165
|
+
onClick: copy,
|
|
166
|
+
"aria-label": copied ? COPY.actions.copied : COPY.actions.copy,
|
|
167
|
+
className: "absolute end-2 top-2 border border-line bg-surface p-1 text-fg-muted transition-colors hover:text-fg",
|
|
168
|
+
...dataSlot("code", "copy"),
|
|
169
|
+
children: copied ? /* @__PURE__ */ jsx(Check, { size: 14, "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Copy, { size: 14, "aria-hidden": "true" })
|
|
170
|
+
}
|
|
171
|
+
) : null
|
|
172
|
+
] });
|
|
173
|
+
});
|
|
174
|
+
function event_text(node) {
|
|
175
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
176
|
+
if (Array.isArray(node)) return node.map(event_text).join("");
|
|
177
|
+
return "";
|
|
178
|
+
}
|
|
179
|
+
const Kbd = React.forwardRef(function Kbd2({ className, ...props }, ref) {
|
|
180
|
+
return /* @__PURE__ */ jsx(
|
|
181
|
+
"kbd",
|
|
182
|
+
{
|
|
183
|
+
ref,
|
|
184
|
+
className: cn(
|
|
185
|
+
"inline-flex h-5 min-w-5 items-center justify-center border border-line-strong bg-surface-3 px-1",
|
|
186
|
+
"font-mono text-label text-fg-muted",
|
|
187
|
+
className
|
|
188
|
+
),
|
|
189
|
+
...dataSlot("kbd"),
|
|
190
|
+
...props
|
|
191
|
+
}
|
|
192
|
+
);
|
|
193
|
+
});
|
|
194
|
+
const Link = React.forwardRef(function Link2({ asChild = false, external = false, subtle = false, className, children, ...props }, ref) {
|
|
195
|
+
const Component = asChild ? Slot.Root : "a";
|
|
196
|
+
return /* @__PURE__ */ jsxs(
|
|
197
|
+
Component,
|
|
198
|
+
{
|
|
199
|
+
ref,
|
|
200
|
+
className: cn(
|
|
201
|
+
"text-primary underline-offset-4 transition-colors hover:underline",
|
|
202
|
+
subtle && "no-underline hover:underline",
|
|
203
|
+
className
|
|
204
|
+
),
|
|
205
|
+
...external ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
206
|
+
...dataSlot("link"),
|
|
207
|
+
...props,
|
|
208
|
+
children: [
|
|
209
|
+
children,
|
|
210
|
+
external ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
211
|
+
/* @__PURE__ */ jsx(ArrowRight, { size: 14, "aria-hidden": "true", className: "ms-1 inline-block align-[-2px]" }),
|
|
212
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: " (externer Link, \xF6ffnet in neuem Tab)" })
|
|
213
|
+
] }) : null
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
);
|
|
217
|
+
});
|
|
218
|
+
const Blockquote = React.forwardRef(
|
|
219
|
+
function Blockquote2({ className, ...props }, ref) {
|
|
220
|
+
return /* @__PURE__ */ jsx(
|
|
221
|
+
"blockquote",
|
|
222
|
+
{
|
|
223
|
+
ref,
|
|
224
|
+
className: cn("border-s-2 border-primary ps-4 text-lead text-fg-muted italic", className),
|
|
225
|
+
...dataSlot("blockquote"),
|
|
226
|
+
...props
|
|
227
|
+
}
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
);
|
|
231
|
+
const List = React.forwardRef(function List2({ ordered = false, className, children, ...props }, ref) {
|
|
232
|
+
const Tag = ordered ? "ol" : "ul";
|
|
233
|
+
return /* @__PURE__ */ jsx(
|
|
234
|
+
Tag,
|
|
235
|
+
{
|
|
236
|
+
ref,
|
|
237
|
+
className: cn(
|
|
238
|
+
"ms-5 flex flex-col gap-1.5 text-ui text-fg-muted",
|
|
239
|
+
ordered ? "list-decimal" : "list-disc",
|
|
240
|
+
"marker:text-fg-subtle",
|
|
241
|
+
className
|
|
242
|
+
),
|
|
243
|
+
...dataSlot("list"),
|
|
244
|
+
...props,
|
|
245
|
+
children
|
|
246
|
+
}
|
|
247
|
+
);
|
|
248
|
+
});
|
|
249
|
+
const DefinitionList = React.forwardRef(
|
|
250
|
+
function DefinitionList2({ className, ...props }, ref) {
|
|
251
|
+
return /* @__PURE__ */ jsx("dl", { ref, className: cn("grid gap-1", className), ...dataSlot("definition-list"), ...props });
|
|
252
|
+
}
|
|
253
|
+
);
|
|
254
|
+
const DefinitionTerm = React.forwardRef(
|
|
255
|
+
function DefinitionTerm2({ className, ...props }, ref) {
|
|
256
|
+
return /* @__PURE__ */ jsx("dt", { ref, className: cn("text-ui font-medium text-fg", className), ...dataSlot("definition-term"), ...props });
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
const DefinitionDetail = React.forwardRef(
|
|
260
|
+
function DefinitionDetail2({ className, ...props }, ref) {
|
|
261
|
+
return /* @__PURE__ */ jsx("dd", { ref, className: cn("ms-0 text-ui text-fg-muted", className), ...dataSlot("definition-detail"), ...props });
|
|
262
|
+
}
|
|
263
|
+
);
|
|
264
|
+
export {
|
|
265
|
+
Blockquote,
|
|
266
|
+
Caption,
|
|
267
|
+
DefinitionDetail,
|
|
268
|
+
DefinitionList,
|
|
269
|
+
DefinitionTerm,
|
|
270
|
+
Eyebrow,
|
|
271
|
+
Heading,
|
|
272
|
+
InlineCode,
|
|
273
|
+
Kbd,
|
|
274
|
+
Link,
|
|
275
|
+
List,
|
|
276
|
+
Preformatted,
|
|
277
|
+
Text,
|
|
278
|
+
textVariants
|
|
279
|
+
};
|
|
280
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/typography/index.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Slot } from \"radix-ui\";\nimport { ArrowRight, Copy, Check } from \"@tea-ui/icons\";\nimport { cn, cva, type VariantProps } from \"@tea-ui/utils\";\nimport { COPY } from \"@tea-ui/ux-standards\";\n\nimport { dataSlot } from \"../internal\";\n\n/**\n * TEA UI — typography.\n *\n * One type scale, used everywhere. The audit found the two source projects\n * between them rendering real UI text at **9px and 10px** — sizes that fail\n * legibility for anyone with reduced acuity and fail outright for anyone with a\n * low-vision condition. This scale has no step below 11px, and the 11px step is\n * reserved for uppercase micro-labels, where the letterforms are short and the\n * extra weight compensates.\n *\n * `Heading` renders a **real heading element** at the level it is given. The\n * audit found a `CardTitle` rendering a `<div>`, which silently flattened the\n * heading structure of every page that used it — a screen-reader user navigating\n * by heading had nothing to navigate by. `level` is therefore required and has\n * no default guess.\n */\n\nexport const textVariants = cva(\"\", {\n variants: {\n size: {\n label: \"text-label\",\n micro: \"text-micro\",\n ui: \"text-ui\",\n body: \"text-body\",\n lead: \"text-lead\",\n title: \"text-title\",\n section: \"text-section\",\n display: \"text-display\",\n hero: \"text-hero\",\n },\n tone: {\n default: \"text-fg\",\n muted: \"text-fg-muted\",\n subtle: \"text-fg-subtle\",\n inverse: \"text-fg-inverse\",\n accent: \"text-primary\",\n },\n weight: {\n normal: \"font-normal\",\n medium: \"font-medium\",\n semibold: \"font-semibold\",\n bold: \"font-bold\",\n },\n },\n defaultVariants: { size: \"ui\", tone: \"default\" },\n});\n\nexport interface TextProps\n extends Omit<React.ComponentProps<\"p\">, \"color\">,\n VariantProps<typeof textVariants> {\n asChild?: boolean | undefined;\n /** The element to render. Ignored when `asChild` is set. */\n as?: React.ElementType | undefined;\n align?: \"start\" | \"center\" | \"end\" | \"justify\" | undefined;\n truncate?: boolean | undefined;\n /** Opt into `text-wrap: balance` for headlines only. */\n balance?: boolean | undefined;\n}\n\nexport const Text = React.forwardRef<HTMLParagraphElement, TextProps>(function Text(\n {\n asChild = false,\n as,\n size,\n tone,\n weight,\n align,\n truncate = false,\n balance = false,\n className,\n ...props\n },\n ref,\n) {\n const Component = (asChild ? Slot.Root : (as ?? \"p\")) as React.ElementType;\n return (\n <Component\n ref={ref}\n className={cn(\n textVariants({ size, tone, weight }),\n align === \"center\" && \"text-center\",\n align === \"end\" && \"text-end\",\n align === \"justify\" && \"text-justify\",\n truncate && \"truncate\",\n balance && \"text-balance\",\n className,\n )}\n {...dataSlot(\"text\")}\n {...props}\n />\n );\n});\n\nexport interface HeadingProps extends Omit<React.ComponentProps<\"h1\">, \"color\"> {\n /** The heading level. Required — there is no safe default for a document. */\n level: 1 | 2 | 3 | 4 | 5 | 6;\n tone?: \"default\" | \"muted\" | \"accent\" | undefined;\n weight?: \"semibold\" | \"bold\" | undefined;\n balance?: boolean | undefined;\n className?: string | undefined;\n}\n\nconst HEADING_SIZE: Record<HeadingProps[\"level\"], string> = {\n 1: \"text-display\",\n 2: \"text-section\",\n 3: \"text-title\",\n 4: \"text-lead\",\n 5: \"text-ui\",\n 6: \"text-label\",\n};\n\nexport const Heading = React.forwardRef<HTMLHeadingElement, HeadingProps>(function Heading(\n { level, tone = \"default\", weight = \"semibold\", balance = true, className, ...props },\n ref,\n) {\n const Tag = `h${level}` as \"h1\";\n return (\n <Tag\n ref={ref}\n className={cn(\n HEADING_SIZE[level],\n level >= 4 && \"font-medium\",\n level <= 2 && (weight === \"bold\" ? \"font-bold\" : \"font-semibold\"),\n tone === \"muted\" && \"text-fg-muted\",\n tone === \"accent\" && \"text-primary\",\n balance && \"text-balance\",\n className,\n )}\n {...dataSlot(\"heading\", `h${level}`)}\n {...props}\n />\n );\n});\n\n/**\n * The TEA micro-label. This exact class string appeared verbatim twenty times\n * across one source project. It is a token, not a class.\n */\nexport const Eyebrow = React.forwardRef<HTMLSpanElement, React.ComponentProps<\"span\">>(function Eyebrow(\n { className, ...props },\n ref,\n) {\n return (\n <span\n ref={ref}\n className={cn(\"text-label font-semibold uppercase tracking-widest text-fg-muted\", className)}\n {...dataSlot(\"eyebrow\")}\n {...props}\n />\n );\n});\n\nexport const Caption = React.forwardRef<HTMLSpanElement, React.ComponentProps<\"span\">>(\n function Caption({ className, ...props }, ref) {\n return (\n <span\n ref={ref}\n className={cn(\"text-micro text-fg-subtle\", className)}\n {...dataSlot(\"caption\")}\n {...props}\n />\n );\n },\n);\n\nexport const InlineCode = React.forwardRef<HTMLElement, React.ComponentProps<\"code\">>(\n function InlineCode({ className, ...props }, ref) {\n return (\n <code\n ref={ref as React.Ref<HTMLElement>}\n className={cn(\n \"border border-line bg-surface-2 px-1 py-0.5 font-mono text-micro text-primary\",\n className,\n )}\n {...dataSlot(\"code\", \"inline\")}\n {...props}\n />\n );\n },\n);\n\nexport interface PreformattedProps extends React.ComponentProps<\"pre\"> {\n /** Clip instead of growing, with a scrollbar. */\n maxHeight?: number | string | undefined;\n /** A copy button, labelled in German from the shared copy deck. */\n copyable?: boolean | undefined;\n className?: string | undefined;\n}\n\nexport const Preformatted = React.forwardRef<HTMLPreElement, PreformattedProps>(function Preformatted(\n { maxHeight, copyable = false, className, children, ...props },\n ref,\n) {\n const [copied, setCopied] = React.useState(false);\n\n const copy = React.useCallback(() => {\n const text = typeof children === \"string\" ? children : (event_text(children));\n void navigator.clipboard?.writeText(text).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }, [children]);\n\n return (\n <div className={cn(\"relative\", className)} {...dataSlot(\"code\", \"block-wrapper\")}>\n <pre\n ref={ref}\n style={{ maxHeight }}\n className={cn(\n \"overflow-auto border border-line bg-surface-2 p-3 font-mono text-mono text-fg\",\n maxHeight && \"overflow-y-auto\",\n )}\n tabIndex={0}\n {...dataSlot(\"code\", \"block\")}\n {...props}\n >\n {children}\n </pre>\n {copyable ? (\n <button\n type=\"button\"\n onClick={copy}\n aria-label={copied ? COPY.actions.copied : COPY.actions.copy}\n className=\"absolute end-2 top-2 border border-line bg-surface p-1 text-fg-muted transition-colors hover:text-fg\"\n {...dataSlot(\"code\", \"copy\")}\n >\n {copied ? <Check size={14} aria-hidden=\"true\" /> : <Copy size={14} aria-hidden=\"true\" />}\n </button>\n ) : null}\n </div>\n );\n});\n\nfunction event_text(node: React.ReactNode): string {\n if (typeof node === \"string\" || typeof node === \"number\") return String(node);\n if (Array.isArray(node)) return node.map(event_text).join(\"\");\n return \"\";\n}\n\nexport const Kbd = React.forwardRef<HTMLElement, React.ComponentProps<\"kbd\">>(function Kbd(\n { className, ...props },\n ref,\n) {\n return (\n <kbd\n ref={ref as React.Ref<HTMLElement>}\n className={cn(\n \"inline-flex h-5 min-w-5 items-center justify-center border border-line-strong bg-surface-3 px-1\",\n \"font-mono text-label text-fg-muted\",\n className,\n )}\n {...dataSlot(\"kbd\")}\n {...props}\n />\n );\n});\n\nexport interface LinkProps extends Omit<React.ComponentProps<\"a\">, \"color\"> {\n asChild?: boolean | undefined;\n /** Opens in a new tab. Adds `rel` and an accessible hint. */\n external?: boolean | undefined;\n /** Suppress the underline until hover. */\n subtle?: boolean | undefined;\n className?: string | undefined;\n}\n\nexport const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(function Link(\n { asChild = false, external = false, subtle = false, className, children, ...props },\n ref,\n) {\n const Component = (asChild ? Slot.Root : \"a\") as React.ElementType;\n return (\n <Component\n ref={ref}\n className={cn(\n \"text-primary underline-offset-4 transition-colors hover:underline\",\n subtle && \"no-underline hover:underline\",\n className,\n )}\n {...(external ? { target: \"_blank\", rel: \"noopener noreferrer\" } : {})}\n {...dataSlot(\"link\")}\n {...props}\n >\n {children}\n {external ? (\n <>\n <ArrowRight size={14} aria-hidden=\"true\" className=\"ms-1 inline-block align-[-2px]\" />\n <span className=\"sr-only\"> (externer Link, öffnet in neuem Tab)</span>\n </>\n ) : null}\n </Component>\n );\n});\n\nexport const Blockquote = React.forwardRef<HTMLQuoteElement, React.ComponentProps<\"blockquote\">>(\n function Blockquote({ className, ...props }, ref) {\n return (\n <blockquote\n ref={ref}\n className={cn(\"border-s-2 border-primary ps-4 text-lead text-fg-muted italic\", className)}\n {...dataSlot(\"blockquote\")}\n {...props}\n />\n );\n },\n);\n\nexport interface ListProps extends React.ComponentProps<\"ul\"> {\n ordered?: boolean | undefined;\n}\n\nexport const List = React.forwardRef<HTMLUListElement, ListProps>(function List(\n { ordered = false, className, children, ...props },\n ref,\n) {\n const Tag = (ordered ? \"ol\" : \"ul\") as \"ul\";\n return (\n <Tag\n ref={ref}\n className={cn(\n \"ms-5 flex flex-col gap-1.5 text-ui text-fg-muted\",\n ordered ? \"list-decimal\" : \"list-disc\",\n \"marker:text-fg-subtle\",\n className,\n )}\n {...dataSlot(\"list\")}\n {...props}\n >\n {children}\n </Tag>\n );\n});\n\nexport const DefinitionList = React.forwardRef<HTMLDListElement, React.ComponentProps<\"dl\">>(\n function DefinitionList({ className, ...props }, ref) {\n return <dl ref={ref} className={cn(\"grid gap-1\", className)} {...dataSlot(\"definition-list\")} {...props} />;\n },\n);\n\nexport const DefinitionTerm = React.forwardRef<HTMLElement, React.ComponentProps<\"dt\">>(\n function DefinitionTerm({ className, ...props }, ref) {\n return <dt ref={ref} className={cn(\"text-ui font-medium text-fg\", className)} {...dataSlot(\"definition-term\")} {...props} />;\n },\n);\n\nexport const DefinitionDetail = React.forwardRef<HTMLElement, React.ComponentProps<\"dd\">>(\n function DefinitionDetail({ className, ...props }, ref) {\n return <dd ref={ref} className={cn(\"ms-0 text-ui text-fg-muted\", className)} {...dataSlot(\"definition-detail\")} {...props} />;\n },\n);\n"],"mappings":"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","names":["Text","Heading","Eyebrow","Caption","InlineCode","Preformatted","Kbd","Link","Blockquote","List","DefinitionList","DefinitionTerm","DefinitionDetail"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tea-ui/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The primitive layer: layout, typography, inputs, feedback, overlays, navigation.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md",
|
|
11
|
+
"LICENSE"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./package.json": "./package.json",
|
|
20
|
+
"./styles.css": "./dist/styles.css"
|
|
21
|
+
},
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"module": "./dist/index.js",
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsup && node ../../scripts/fix-esm-extensions.mjs core && node ../../scripts/sync-styles.mjs",
|
|
29
|
+
"prepublishOnly": "node ../../scripts/prepublish-guard.mjs"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@tea-ui/icons": "^0.1.0",
|
|
33
|
+
"@tea-ui/tokens": "^0.1.0",
|
|
34
|
+
"@tea-ui/ux-standards": "^0.1.0",
|
|
35
|
+
"@tea-ui/utils": "^0.1.0",
|
|
36
|
+
"radix-ui": "^1.4.3"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": ">=18.2.0 <20.0.0",
|
|
40
|
+
"react-dom": ">=18.2.0 <20.0.0"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"react",
|
|
44
|
+
"components",
|
|
45
|
+
"design-system",
|
|
46
|
+
"wcag",
|
|
47
|
+
"a11y",
|
|
48
|
+
"tea-ui"
|
|
49
|
+
],
|
|
50
|
+
"author": "landnevermore",
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "git+https://github.com/landnevermore/TEAui.git",
|
|
54
|
+
"directory": "packages/core"
|
|
55
|
+
},
|
|
56
|
+
"homepage": "https://landnevermore.github.io/TEAui/docs/",
|
|
57
|
+
"bugs": {
|
|
58
|
+
"url": "https://github.com/landnevermore/TEAui/issues"
|
|
59
|
+
}
|
|
60
|
+
}
|