@reacteditor/field-tailwind 0.0.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/dist/index.mjs ADDED
@@ -0,0 +1,542 @@
1
+ // ../tsup-config/react-import.js
2
+ import React from "react";
3
+
4
+ // index.tsx
5
+ import { FieldLabel } from "@reacteditor/core";
6
+
7
+ // combobox.tsx
8
+ import * as React2 from "react";
9
+ import { useMemo, useRef, useState } from "react";
10
+ import { Combobox } from "@base-ui/react/combobox";
11
+ import { Check, X } from "lucide-react";
12
+ import { jsx, jsxs } from "react/jsx-runtime";
13
+ var STYLE_ID = "reacteditor-field-tailwind";
14
+ var STYLES = `
15
+ .rtw-chips:focus-within { border-color: #6366f1; box-shadow: 0 0 0 3px rgba(99,102,241,0.2); }
16
+ .rtw-input:focus { outline: none; }
17
+ .rtw-input::placeholder { color: #9ca3af; }
18
+ .rtw-item[data-highlighted] { background: #eef2ff; }
19
+ .rtw-item[data-selected] { font-weight: 500; }
20
+ .rtw-chip-remove:hover { opacity: 1; }
21
+ .rtw-list { scrollbar-width: thin; }
22
+ `;
23
+ var ensureStyles = () => {
24
+ if (typeof document === "undefined") return;
25
+ if (document.getElementById(STYLE_ID)) return;
26
+ const el = document.createElement("style");
27
+ el.id = STYLE_ID;
28
+ el.textContent = STYLES;
29
+ document.head.appendChild(el);
30
+ };
31
+ var s = {
32
+ chips: {
33
+ display: "flex",
34
+ flexWrap: "wrap",
35
+ alignItems: "center",
36
+ gap: 4,
37
+ minHeight: 34,
38
+ width: "100%",
39
+ padding: "4px 6px",
40
+ borderRadius: 6,
41
+ border: "1px solid #d1d5db",
42
+ background: "#fff",
43
+ boxSizing: "border-box",
44
+ transition: "border-color 120ms, box-shadow 120ms"
45
+ },
46
+ chip: {
47
+ display: "inline-flex",
48
+ alignItems: "center",
49
+ gap: 4,
50
+ height: 22,
51
+ padding: "0 4px 0 8px",
52
+ borderRadius: 4,
53
+ background: "#f1f5f9",
54
+ color: "#111827",
55
+ fontSize: 12,
56
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
57
+ whiteSpace: "nowrap"
58
+ },
59
+ chipRemove: {
60
+ display: "inline-flex",
61
+ alignItems: "center",
62
+ justifyContent: "center",
63
+ width: 16,
64
+ height: 16,
65
+ padding: 0,
66
+ border: "none",
67
+ background: "transparent",
68
+ color: "inherit",
69
+ cursor: "pointer",
70
+ opacity: 0.5,
71
+ transition: "opacity 120ms"
72
+ },
73
+ input: {
74
+ flex: 1,
75
+ minWidth: 80,
76
+ height: 22,
77
+ border: "none",
78
+ background: "transparent",
79
+ fontSize: 13,
80
+ color: "#111827",
81
+ padding: 0
82
+ },
83
+ popup: {
84
+ boxSizing: "border-box",
85
+ width: "var(--anchor-width)",
86
+ maxHeight: "min(280px, var(--available-height))",
87
+ overflowY: "auto",
88
+ background: "#fff",
89
+ border: "1px solid #e5e7eb",
90
+ borderRadius: 8,
91
+ boxShadow: "0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1)",
92
+ padding: 4,
93
+ zIndex: 9999
94
+ },
95
+ list: { display: "flex", flexDirection: "column" },
96
+ item: {
97
+ display: "flex",
98
+ alignItems: "center",
99
+ justifyContent: "space-between",
100
+ gap: 8,
101
+ padding: "6px 8px",
102
+ borderRadius: 4,
103
+ fontSize: 13,
104
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
105
+ color: "#111827",
106
+ cursor: "default",
107
+ userSelect: "none"
108
+ },
109
+ indicator: {
110
+ display: "inline-flex",
111
+ alignItems: "center",
112
+ color: "#6366f1"
113
+ },
114
+ empty: {
115
+ padding: "8px",
116
+ fontSize: 13,
117
+ color: "#6b7280",
118
+ textAlign: "center"
119
+ },
120
+ create: { color: "#6366f1" }
121
+ };
122
+ function TailwindCombobox({
123
+ value,
124
+ onValueChange,
125
+ items,
126
+ placeholder = "Add classes\u2026",
127
+ disabled,
128
+ id
129
+ }) {
130
+ ensureStyles();
131
+ const anchor = useRef(null);
132
+ const [query, setQuery] = useState("");
133
+ const filteredItems = useMemo(() => {
134
+ const q = query.trim();
135
+ const lower = q.toLowerCase();
136
+ const matches = items.filter((c) => c.toLowerCase().includes(lower));
137
+ const isKnown = items.includes(q) || value.includes(q);
138
+ return q && !isKnown ? [q, ...matches] : matches;
139
+ }, [query, items, value]);
140
+ const isCreate = (item) => !items.includes(item);
141
+ return /* @__PURE__ */ jsxs(
142
+ Combobox.Root,
143
+ {
144
+ multiple: true,
145
+ items,
146
+ value,
147
+ filteredItems,
148
+ onValueChange: (next) => onValueChange(next != null ? next : []),
149
+ onInputValueChange: (next) => setQuery(next),
150
+ children: [
151
+ /* @__PURE__ */ jsx(Combobox.Chips, { ref: anchor, className: "rtw-chips", style: s.chips, children: /* @__PURE__ */ jsx(Combobox.Value, { children: (values) => /* @__PURE__ */ jsxs(React2.Fragment, { children: [
152
+ values.map((v) => /* @__PURE__ */ jsxs(Combobox.Chip, { style: s.chip, children: [
153
+ v,
154
+ /* @__PURE__ */ jsx(
155
+ Combobox.ChipRemove,
156
+ {
157
+ className: "rtw-chip-remove",
158
+ style: s.chipRemove,
159
+ "aria-label": `Remove ${v}`,
160
+ children: /* @__PURE__ */ jsx(X, { size: 12 })
161
+ }
162
+ )
163
+ ] }, v)),
164
+ /* @__PURE__ */ jsx(
165
+ Combobox.Input,
166
+ {
167
+ id,
168
+ disabled,
169
+ placeholder: values.length === 0 ? placeholder : "",
170
+ className: "rtw-input",
171
+ style: s.input
172
+ }
173
+ )
174
+ ] }) }) }),
175
+ /* @__PURE__ */ jsx(Combobox.Portal, { children: /* @__PURE__ */ jsx(Combobox.Positioner, { anchor, sideOffset: 4, style: { zIndex: 9999 }, children: /* @__PURE__ */ jsxs(Combobox.Popup, { style: s.popup, children: [
176
+ /* @__PURE__ */ jsx(Combobox.Empty, { style: s.empty, children: "No classes found." }),
177
+ /* @__PURE__ */ jsx(Combobox.List, { className: "rtw-list", style: s.list, children: (item) => /* @__PURE__ */ jsxs(
178
+ Combobox.Item,
179
+ {
180
+ value: item,
181
+ className: "rtw-item",
182
+ style: s.item,
183
+ children: [
184
+ /* @__PURE__ */ jsx("span", { style: isCreate(item) ? s.create : void 0, children: isCreate(item) ? `Add "${item}"` : item }),
185
+ /* @__PURE__ */ jsx(Combobox.ItemIndicator, { style: s.indicator, children: /* @__PURE__ */ jsx(Check, { size: 14 }) })
186
+ ]
187
+ },
188
+ item
189
+ ) })
190
+ ] }) }) })
191
+ ]
192
+ }
193
+ );
194
+ }
195
+
196
+ // tailwind-classes.ts
197
+ var COLORS = [
198
+ "slate",
199
+ "gray",
200
+ "zinc",
201
+ "neutral",
202
+ "stone",
203
+ "red",
204
+ "orange",
205
+ "amber",
206
+ "yellow",
207
+ "lime",
208
+ "green",
209
+ "emerald",
210
+ "teal",
211
+ "cyan",
212
+ "sky",
213
+ "blue",
214
+ "indigo",
215
+ "violet",
216
+ "purple",
217
+ "fuchsia",
218
+ "pink",
219
+ "rose"
220
+ ];
221
+ var COLOR_STEPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
222
+ var SPACING = [
223
+ "0",
224
+ "0.5",
225
+ "1",
226
+ "1.5",
227
+ "2",
228
+ "2.5",
229
+ "3",
230
+ "4",
231
+ "5",
232
+ "6",
233
+ "8",
234
+ "10",
235
+ "12",
236
+ "16",
237
+ "20",
238
+ "24",
239
+ "px"
240
+ ];
241
+ var expand = (prefixes, values) => prefixes.flatMap((prefix) => values.map((value) => `${prefix}-${value}`));
242
+ var colorUtilities = (prefixes) => prefixes.flatMap((prefix) => [
243
+ `${prefix}-white`,
244
+ `${prefix}-black`,
245
+ `${prefix}-transparent`,
246
+ `${prefix}-current`,
247
+ ...COLORS.flatMap(
248
+ (color) => COLOR_STEPS.map((step) => `${prefix}-${color}-${step}`)
249
+ )
250
+ ]);
251
+ var layout = [
252
+ "block",
253
+ "inline-block",
254
+ "inline",
255
+ "flex",
256
+ "inline-flex",
257
+ "grid",
258
+ "inline-grid",
259
+ "hidden",
260
+ "table",
261
+ "contents"
262
+ ];
263
+ var flexbox = [
264
+ "flex-row",
265
+ "flex-row-reverse",
266
+ "flex-col",
267
+ "flex-col-reverse",
268
+ "flex-wrap",
269
+ "flex-nowrap",
270
+ "flex-1",
271
+ "flex-auto",
272
+ "flex-initial",
273
+ "flex-none",
274
+ "grow",
275
+ "grow-0",
276
+ "shrink",
277
+ "shrink-0",
278
+ "items-start",
279
+ "items-center",
280
+ "items-end",
281
+ "items-stretch",
282
+ "items-baseline",
283
+ "justify-start",
284
+ "justify-center",
285
+ "justify-end",
286
+ "justify-between",
287
+ "justify-around",
288
+ "justify-evenly",
289
+ "content-start",
290
+ "content-center",
291
+ "content-end",
292
+ "content-between",
293
+ "self-start",
294
+ "self-center",
295
+ "self-end",
296
+ "self-stretch"
297
+ ];
298
+ var grid = [
299
+ "grid-cols-1",
300
+ "grid-cols-2",
301
+ "grid-cols-3",
302
+ "grid-cols-4",
303
+ "grid-cols-5",
304
+ "grid-cols-6",
305
+ "grid-cols-12",
306
+ "col-span-1",
307
+ "col-span-2",
308
+ "col-span-3",
309
+ "col-span-full",
310
+ "grid-rows-1",
311
+ "grid-rows-2",
312
+ "grid-rows-3",
313
+ "place-items-center",
314
+ "place-content-center"
315
+ ];
316
+ var sizing = [
317
+ "w-full",
318
+ "w-auto",
319
+ "w-screen",
320
+ "w-fit",
321
+ "w-min",
322
+ "w-max",
323
+ "w-1/2",
324
+ "w-1/3",
325
+ "w-2/3",
326
+ "w-1/4",
327
+ "w-3/4",
328
+ "h-full",
329
+ "h-auto",
330
+ "h-screen",
331
+ "h-fit",
332
+ "min-h-screen",
333
+ "min-h-full",
334
+ "min-w-0",
335
+ "min-w-full",
336
+ "max-w-xs",
337
+ "max-w-sm",
338
+ "max-w-md",
339
+ "max-w-lg",
340
+ "max-w-xl",
341
+ "max-w-2xl",
342
+ "max-w-3xl",
343
+ "max-w-4xl",
344
+ "max-w-5xl",
345
+ "max-w-6xl",
346
+ "max-w-7xl",
347
+ "max-w-prose",
348
+ "max-w-full",
349
+ "max-w-none",
350
+ "size-full",
351
+ "size-4",
352
+ "size-6",
353
+ "size-8"
354
+ ];
355
+ var typography = [
356
+ "text-xs",
357
+ "text-sm",
358
+ "text-base",
359
+ "text-lg",
360
+ "text-xl",
361
+ "text-2xl",
362
+ "text-3xl",
363
+ "text-4xl",
364
+ "text-5xl",
365
+ "text-6xl",
366
+ "font-thin",
367
+ "font-light",
368
+ "font-normal",
369
+ "font-medium",
370
+ "font-semibold",
371
+ "font-bold",
372
+ "font-extrabold",
373
+ "font-black",
374
+ "text-left",
375
+ "text-center",
376
+ "text-right",
377
+ "text-justify",
378
+ "leading-none",
379
+ "leading-tight",
380
+ "leading-snug",
381
+ "leading-normal",
382
+ "leading-relaxed",
383
+ "leading-loose",
384
+ "tracking-tighter",
385
+ "tracking-tight",
386
+ "tracking-normal",
387
+ "tracking-wide",
388
+ "tracking-wider",
389
+ "uppercase",
390
+ "lowercase",
391
+ "capitalize",
392
+ "normal-case",
393
+ "italic",
394
+ "not-italic",
395
+ "underline",
396
+ "line-through",
397
+ "no-underline",
398
+ "truncate"
399
+ ];
400
+ var borders = [
401
+ "border",
402
+ "border-0",
403
+ "border-2",
404
+ "border-4",
405
+ "border-8",
406
+ "border-t",
407
+ "border-r",
408
+ "border-b",
409
+ "border-l",
410
+ "border-solid",
411
+ "border-dashed",
412
+ "border-dotted",
413
+ "rounded-none",
414
+ "rounded-sm",
415
+ "rounded",
416
+ "rounded-md",
417
+ "rounded-lg",
418
+ "rounded-xl",
419
+ "rounded-2xl",
420
+ "rounded-3xl",
421
+ "rounded-full",
422
+ "divide-y",
423
+ "divide-x"
424
+ ];
425
+ var effects = [
426
+ "shadow-none",
427
+ "shadow-sm",
428
+ "shadow",
429
+ "shadow-md",
430
+ "shadow-lg",
431
+ "shadow-xl",
432
+ "shadow-2xl",
433
+ "shadow-inner",
434
+ "opacity-0",
435
+ "opacity-25",
436
+ "opacity-50",
437
+ "opacity-75",
438
+ "opacity-100",
439
+ "ring",
440
+ "ring-0",
441
+ "ring-1",
442
+ "ring-2",
443
+ "ring-inset",
444
+ "blur",
445
+ "blur-sm",
446
+ "backdrop-blur"
447
+ ];
448
+ var positioning = [
449
+ "static",
450
+ "relative",
451
+ "absolute",
452
+ "fixed",
453
+ "sticky",
454
+ "inset-0",
455
+ "inset-x-0",
456
+ "inset-y-0",
457
+ "top-0",
458
+ "right-0",
459
+ "bottom-0",
460
+ "left-0",
461
+ "z-0",
462
+ "z-10",
463
+ "z-20",
464
+ "z-30",
465
+ "z-40",
466
+ "z-50",
467
+ "overflow-auto",
468
+ "overflow-hidden",
469
+ "overflow-scroll",
470
+ "overflow-x-auto",
471
+ "overflow-y-auto"
472
+ ];
473
+ var misc = [
474
+ "object-contain",
475
+ "object-cover",
476
+ "object-fill",
477
+ "object-center",
478
+ "cursor-pointer",
479
+ "cursor-default",
480
+ "select-none",
481
+ "pointer-events-none",
482
+ "transition",
483
+ "transition-all",
484
+ "transition-colors",
485
+ "duration-150",
486
+ "duration-300",
487
+ "ease-in-out",
488
+ "antialiased",
489
+ "container",
490
+ "mx-auto",
491
+ "my-auto"
492
+ ];
493
+ var TAILWIND_CLASSES = Array.from(
494
+ /* @__PURE__ */ new Set([
495
+ ...layout,
496
+ ...flexbox,
497
+ ...grid,
498
+ ...sizing,
499
+ ...typography,
500
+ ...borders,
501
+ ...effects,
502
+ ...positioning,
503
+ ...misc,
504
+ // spacing scales
505
+ ...expand(["p", "px", "py", "pt", "pr", "pb", "pl"], SPACING),
506
+ ...expand(["m", "mx", "my", "mt", "mr", "mb", "ml"], SPACING),
507
+ ...expand(["gap", "gap-x", "gap-y", "space-x", "space-y"], SPACING),
508
+ // colors
509
+ ...colorUtilities(["text", "bg", "border", "ring", "from", "to", "via"])
510
+ ])
511
+ );
512
+
513
+ // index.tsx
514
+ import { jsx as jsx2 } from "react/jsx-runtime";
515
+ var splitClasses = (value) => (value != null ? value : "").split(/\s+/).filter(Boolean);
516
+ function createFieldTailwind(options = {}) {
517
+ const { classes, extraClasses, placeholder, label } = options;
518
+ const items = classes ? classes : Array.from(/* @__PURE__ */ new Set([...TAILWIND_CLASSES, ...extraClasses != null ? extraClasses : []]));
519
+ return {
520
+ type: "custom",
521
+ label,
522
+ render: ({ value, onChange, readOnly, id }) => {
523
+ const combobox = /* @__PURE__ */ jsx2(
524
+ TailwindCombobox,
525
+ {
526
+ id,
527
+ items,
528
+ placeholder,
529
+ disabled: readOnly,
530
+ value: splitClasses(value),
531
+ onValueChange: (tags) => onChange(tags.join(" "))
532
+ }
533
+ );
534
+ return label ? /* @__PURE__ */ jsx2(FieldLabel, { label, readOnly, el: "div", children: combobox }) : combobox;
535
+ }
536
+ };
537
+ }
538
+ export {
539
+ TAILWIND_CLASSES,
540
+ TailwindCombobox,
541
+ createFieldTailwind
542
+ };
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@reacteditor/field-tailwind",
3
+ "version": "0.0.1",
4
+ "author": "Frontend AI, Inc.",
5
+ "repository": "reacteditor/editor",
6
+ "bugs": "https://github.com/reacteditor/editor/issues",
7
+ "homepage": "https://reacteditor.dev",
8
+ "private": false,
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ "import": "./dist/index.mjs",
16
+ "types": "./dist/index.d.ts"
17
+ },
18
+ "license": "MIT",
19
+ "scripts": {
20
+ "lint": "eslint \"**/*.ts*\"",
21
+ "build": "rm -rf dist && tsup index.tsx",
22
+ "prepare": "yarn build"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "devDependencies": {
28
+ "@base-ui/react": "^1.4.1",
29
+ "@reacteditor/core": "*",
30
+ "@types/react": "^19.2.7",
31
+ "@types/react-dom": "^19.2.3",
32
+ "eslint": "^7.32.0",
33
+ "eslint-config-custom": "*",
34
+ "lucide-react": "^0.468.0",
35
+ "tsconfig": "*",
36
+ "tsup-config": "*",
37
+ "typescript": "^5.5.4"
38
+ },
39
+ "peerDependencies": {
40
+ "@base-ui/react": "^1.4.1",
41
+ "@reacteditor/core": "*",
42
+ "lucide-react": ">=0.400.0",
43
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
44
+ }
45
+ }