@xyd-js/source-react-runtime 0.0.0-build-23166ce-20260423151359

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +121 -0
  4. package/__fixtures__/-1.vite-lib.custom-property/input/package.json +8 -0
  5. package/__fixtures__/-1.vite-lib.custom-property/input/src/UserCard.tsx +27 -0
  6. package/__fixtures__/-1.vite-lib.custom-property/input/src/index.ts +1 -0
  7. package/__fixtures__/-1.vite-lib.custom-property/input/tsconfig.json +12 -0
  8. package/__fixtures__/-1.vite-lib.custom-property/input/vite.config.ts +22 -0
  9. package/__fixtures__/-1.vite-lib.custom-property/output.js +10 -0
  10. package/__fixtures__/1.vite-lib.user-card/input/package.json +8 -0
  11. package/__fixtures__/1.vite-lib.user-card/input/src/UserCard.tsx +27 -0
  12. package/__fixtures__/1.vite-lib.user-card/input/src/index.ts +1 -0
  13. package/__fixtures__/1.vite-lib.user-card/input/tsconfig.json +12 -0
  14. package/__fixtures__/1.vite-lib.user-card/input/vite.config.ts +22 -0
  15. package/__fixtures__/1.vite-lib.user-card/output.js +10 -0
  16. package/__fixtures__/2.vite-lib.sample-app/input/package.json +8 -0
  17. package/__fixtures__/2.vite-lib.sample-app/input/src/components/UserProfile.tsx +42 -0
  18. package/__fixtures__/2.vite-lib.sample-app/input/src/contexts/UserContext.tsx +27 -0
  19. package/__fixtures__/2.vite-lib.sample-app/input/src/index.ts +3 -0
  20. package/__fixtures__/2.vite-lib.sample-app/input/src/types/user.ts +18 -0
  21. package/__fixtures__/2.vite-lib.sample-app/input/tsconfig.json +12 -0
  22. package/__fixtures__/2.vite-lib.sample-app/input/vite.config.ts +22 -0
  23. package/__fixtures__/2.vite-lib.sample-app/output.js +27 -0
  24. package/__fixtures__/3.vite-lib.sample-real-app/input/package.json +8 -0
  25. package/__fixtures__/3.vite-lib.sample-real-app/input/src/components/AddTodoForm.tsx +51 -0
  26. package/__fixtures__/3.vite-lib.sample-real-app/input/src/components/FilterBar.tsx +56 -0
  27. package/__fixtures__/3.vite-lib.sample-real-app/input/src/components/StatsPanel.tsx +44 -0
  28. package/__fixtures__/3.vite-lib.sample-real-app/input/src/components/TodoItem.tsx +54 -0
  29. package/__fixtures__/3.vite-lib.sample-real-app/input/src/index.ts +6 -0
  30. package/__fixtures__/3.vite-lib.sample-real-app/input/src/types/todo.ts +23 -0
  31. package/__fixtures__/3.vite-lib.sample-real-app/input/tsconfig.json +12 -0
  32. package/__fixtures__/3.vite-lib.sample-real-app/input/vite.config.ts +22 -0
  33. package/__fixtures__/3.vite-lib.sample-real-app/output.js +63 -0
  34. package/__fixtures__/4.vite-app.user-card/input/package.json +8 -0
  35. package/__fixtures__/4.vite-app.user-card/input/src/UserCard.tsx +27 -0
  36. package/__fixtures__/4.vite-app.user-card/input/src/index.ts +1 -0
  37. package/__fixtures__/4.vite-app.user-card/input/tsconfig.json +12 -0
  38. package/__fixtures__/4.vite-app.user-card/input/vite.config.ts +23 -0
  39. package/__fixtures__/4.vite-app.user-card/output.js +10 -0
  40. package/__fixtures__/5.rollup.user-card/input/package.json +8 -0
  41. package/__fixtures__/5.rollup.user-card/input/rollup.config.mjs +20 -0
  42. package/__fixtures__/5.rollup.user-card/input/src/UserCard.tsx +27 -0
  43. package/__fixtures__/5.rollup.user-card/input/src/index.ts +1 -0
  44. package/__fixtures__/5.rollup.user-card/input/tsconfig.json +12 -0
  45. package/__fixtures__/5.rollup.user-card/output.js +11 -0
  46. package/__fixtures__/6.esbuild.user-card/input/esbuild.config.mjs +19 -0
  47. package/__fixtures__/6.esbuild.user-card/input/package.json +8 -0
  48. package/__fixtures__/6.esbuild.user-card/input/src/UserCard.tsx +27 -0
  49. package/__fixtures__/6.esbuild.user-card/input/src/index.ts +1 -0
  50. package/__fixtures__/6.esbuild.user-card/input/tsconfig.json +12 -0
  51. package/__fixtures__/6.esbuild.user-card/output.js +11 -0
  52. package/__fixtures__/7.react-router.app/input/app/components/ProductCard.tsx +26 -0
  53. package/__fixtures__/7.react-router.app/input/app/entry.server.tsx +36 -0
  54. package/__fixtures__/7.react-router.app/input/app/root.tsx +23 -0
  55. package/__fixtures__/7.react-router.app/input/app/routes/cart.tsx +16 -0
  56. package/__fixtures__/7.react-router.app/input/app/routes/home.tsx +29 -0
  57. package/__fixtures__/7.react-router.app/input/app/routes/product.tsx +6 -0
  58. package/__fixtures__/7.react-router.app/input/app/routes.ts +7 -0
  59. package/__fixtures__/7.react-router.app/input/app/types/product.ts +12 -0
  60. package/__fixtures__/7.react-router.app/input/package.json +8 -0
  61. package/__fixtures__/7.react-router.app/input/react-router.config.ts +2 -0
  62. package/__fixtures__/7.react-router.app/input/tsconfig.json +13 -0
  63. package/__fixtures__/7.react-router.app/input/vite.config.ts +14 -0
  64. package/__fixtures__/7.react-router.app/output.js +44 -0
  65. package/__fixtures__/8.tanstack-router.app/input/index.html +5 -0
  66. package/__fixtures__/8.tanstack-router.app/input/package.json +8 -0
  67. package/__fixtures__/8.tanstack-router.app/input/src/components/EmployeeTable.tsx +45 -0
  68. package/__fixtures__/8.tanstack-router.app/input/src/main.tsx +19 -0
  69. package/__fixtures__/8.tanstack-router.app/input/src/routeTree.gen.ts +77 -0
  70. package/__fixtures__/8.tanstack-router.app/input/src/routes/__root.tsx +13 -0
  71. package/__fixtures__/8.tanstack-router.app/input/src/routes/employees.tsx +23 -0
  72. package/__fixtures__/8.tanstack-router.app/input/src/routes/index.tsx +5 -0
  73. package/__fixtures__/8.tanstack-router.app/input/src/types/employee.ts +13 -0
  74. package/__fixtures__/8.tanstack-router.app/input/tsconfig.json +12 -0
  75. package/__fixtures__/8.tanstack-router.app/input/vite.config.ts +21 -0
  76. package/__fixtures__/8.tanstack-router.app/output.js +63 -0
  77. package/__tests__/source-react-runtime.test.ts +61 -0
  78. package/__tests__/utils.ts +100 -0
  79. package/dist/esbuild.d.ts +20 -0
  80. package/dist/esbuild.js +378 -0
  81. package/dist/esbuild.js.map +1 -0
  82. package/dist/index.d.ts +53 -0
  83. package/dist/index.js +348 -0
  84. package/dist/index.js.map +1 -0
  85. package/package.json +47 -0
  86. package/src/esbuild.ts +45 -0
  87. package/src/index.ts +437 -0
  88. package/src/json-schema-to-uniform.ts +108 -0
  89. package/tsconfig.json +16 -0
  90. package/tsconfig.tsup.json +6 -0
  91. package/tsup.config.ts +23 -0
  92. package/vitest.config.ts +7 -0
@@ -0,0 +1,44 @@
1
+ import type { TodoStats } from "../types/todo";
2
+
3
+ interface StatCardProps {
4
+ /** Stat label displayed above the value */
5
+ label: string;
6
+ /** Numeric value to display */
7
+ value: number;
8
+ /** Color accent for the value */
9
+ color?: string;
10
+ }
11
+
12
+ interface StatsPanelProps {
13
+ /** Todo statistics to display */
14
+ stats: TodoStats;
15
+ /** Render in compact horizontal mode */
16
+ compact?: boolean;
17
+ }
18
+
19
+ function StatCard({ label, value, color }: StatCardProps) {
20
+ return (
21
+ <div className="stat-card">
22
+ <span className="stat-label">{label}</span>
23
+ <span className="stat-value" style={{ color }}>{value}</span>
24
+ </div>
25
+ );
26
+ }
27
+
28
+ export function StatsPanel({ stats, compact }: StatsPanelProps) {
29
+ const cards = [
30
+ { label: "Total", value: stats.total },
31
+ { label: "Active", value: stats.active, color: "#3b82f6" },
32
+ { label: "Done", value: stats.completed, color: "#22c55e" },
33
+ { label: "Overdue", value: stats.overdue, color: stats.overdue > 0 ? "#ef4444" : undefined },
34
+ ];
35
+
36
+ return (
37
+ <div className={`stats-panel ${compact ? "compact" : ""}`}>
38
+ {cards.map((c) => (
39
+ <StatCard key={c.label} label={c.label} value={c.value} color={c.color} />
40
+ ))}
41
+ </div>
42
+ );
43
+ }
44
+
@@ -0,0 +1,54 @@
1
+ import { useState } from "react";
2
+ import type { Todo, Priority } from "../types/todo";
3
+
4
+ interface TodoItemProps {
5
+ /** The todo data to render */
6
+ todo: Todo;
7
+
8
+ /** Called when the checkbox is toggled */
9
+ onToggle: (id: string) => void;
10
+
11
+ /** Called when the delete button is clicked */
12
+ onDelete: (id: string) => void;
13
+
14
+ /** Called when the todo is updated */
15
+ onUpdate: (id: string, updates: Partial<Pick<Todo, "title" | "description" | "priority" | "tags">>) => void;
16
+
17
+ /** Enable inline editing mode on mount */
18
+ autoEdit?: boolean;
19
+ }
20
+
21
+ export function TodoItem({ todo, onToggle, onDelete, onUpdate, autoEdit = false }: TodoItemProps) {
22
+ const [editing, setEditing] = useState(autoEdit);
23
+ const [editTitle, setEditTitle] = useState(todo.title);
24
+ const isOverdue = !todo.completed && todo.dueDate && new Date(todo.dueDate) < new Date();
25
+
26
+ const handleSave = () => {
27
+ if (editTitle.trim()) {
28
+ onUpdate(todo.id, { title: editTitle.trim() });
29
+ }
30
+ setEditing(false);
31
+ };
32
+
33
+ return (
34
+ <div className={`todo-item ${todo.completed ? "completed" : ""} ${isOverdue ? "overdue" : ""}`}>
35
+ <input type="checkbox" checked={todo.completed} onChange={() => onToggle(todo.id)} />
36
+ {editing ? (
37
+ <input value={editTitle} onChange={(e) => setEditTitle(e.target.value)} onBlur={handleSave} autoFocus />
38
+ ) : (
39
+ <span onDoubleClick={() => setEditing(true)}>{todo.title}</span>
40
+ )}
41
+ {todo.description && <p className="description">{todo.description}</p>}
42
+ <div className="tags">
43
+ <span className={`priority priority-${todo.priority}`}>{todo.priority}</span>
44
+ {todo.tags.map((tag) => <span key={tag} className="tag">{tag}</span>)}
45
+ {isOverdue && <span className="overdue-badge">overdue</span>}
46
+ </div>
47
+ <div className="actions">
48
+ <button type="button" onClick={() => setEditing(true)}>Edit</button>
49
+ <button type="button" onClick={() => onDelete(todo.id)}>Delete</button>
50
+ </div>
51
+ </div>
52
+ );
53
+ }
54
+
@@ -0,0 +1,6 @@
1
+ export { TodoItem } from "./components/TodoItem";
2
+ export { AddTodoForm } from "./components/AddTodoForm";
3
+ export { FilterBar } from "./components/FilterBar";
4
+ export { StatsPanel } from "./components/StatsPanel";
5
+
6
+ export type { Todo, TodoStats, Priority, FilterStatus } from "./types/todo";
@@ -0,0 +1,23 @@
1
+ export type Priority = "low" | "medium" | "high" | "urgent";
2
+
3
+ export type FilterStatus = "all" | "active" | "completed";
4
+
5
+ export interface Todo {
6
+ id: string;
7
+ title: string;
8
+ description?: string;
9
+ completed: boolean;
10
+ priority: Priority;
11
+ tags: string[];
12
+ createdAt: string;
13
+ completedAt?: string;
14
+ dueDate?: string;
15
+ }
16
+
17
+ export interface TodoStats {
18
+ total: number;
19
+ active: number;
20
+ completed: number;
21
+ overdue: number;
22
+ byPriority: Record<Priority, number>;
23
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "./dist",
4
+ "jsx": "react-jsx",
5
+ "skipLibCheck": true,
6
+ "module": "ESNext",
7
+ "moduleResolution": "bundler",
8
+ "target": "ES2020",
9
+ "strict": true
10
+ },
11
+ "include": ["src/**/*.ts", "src/**/*.tsx"]
12
+ }
@@ -0,0 +1,22 @@
1
+ import {defineConfig} from 'vite';
2
+ import {resolve} from 'node:path';
3
+ import react from '@vitejs/plugin-react';
4
+ import {xydSourceReactRuntime} from '@xyd-js/source-react-runtime';
5
+
6
+ export default defineConfig({
7
+ plugins: [
8
+ xydSourceReactRuntime(),
9
+ react(),
10
+ ],
11
+ build: {
12
+ lib: {
13
+ entry: 'src/index.ts',
14
+ formats: ['es'],
15
+ fileName: 'index',
16
+ },
17
+ rollupOptions: {
18
+ external: ['react', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'react-dom'],
19
+ },
20
+ minify: false,
21
+ },
22
+ });
@@ -0,0 +1,63 @@
1
+ // === index.js ===
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ function TodoItem({ todo, onToggle, onDelete, onUpdate, autoEdit = false }) {
5
+ const [editing, setEditing] = useState(autoEdit);
6
+ const [editTitle, setEditTitle] = useState(todo.title);
7
+ const isOverdue = !todo.completed && todo.dueDate && new Date(todo.dueDate) < /* @__PURE__ */ new Date();
8
+ const handleSave = () => {
9
+ if (editTitle.trim()) {
10
+ onUpdate(todo.id, { title: editTitle.trim() });
11
+ }
12
+ setEditing(false);
13
+ };
14
+ return jsxs("div", { className: `todo-item ${todo.completed ? "completed" : ""} ${isOverdue ? "overdue" : ""}`, children: [jsx("input", { type: "checkbox", checked: todo.completed, onChange: () => onToggle(todo.id) }), editing ? jsx("input", { value: editTitle, onChange: (e) => setEditTitle(e.target.value), onBlur: handleSave, autoFocus: true }) : jsx("span", { onDoubleClick: () => setEditing(true), children: todo.title }), todo.description && jsx("p", { className: "description", children: todo.description }), jsxs("div", { className: "tags", children: [jsx("span", { className: `priority priority-${todo.priority}`, children: todo.priority }), todo.tags.map((tag) => jsx("span", { className: "tag", children: tag }, tag)), isOverdue && jsx("span", { className: "overdue-badge", children: "overdue" })] }), jsxs("div", { className: "actions", children: [jsx("button", { type: "button", onClick: () => setEditing(true), children: "Edit" }), jsx("button", { type: "button", onClick: () => onDelete(todo.id), children: "Delete" })] })] });
15
+ }
16
+ TodoItem.__xydUniform = JSON.parse('{"title":"TodoItem","canonical":"","description":"","definitions":[{"title":"Props","properties":[{"name":"todo","type":"object","description":"","meta":[{"name":"required","value":"true"}],"properties":[{"name":"id","type":"string","description":"","meta":[{"name":"required","value":"true"}]},{"name":"title","type":"string","description":"","meta":[{"name":"required","value":"true"}]},{"name":"description","type":"string","description":"","meta":[]},{"name":"completed","type":"boolean","description":"","meta":[{"name":"required","value":"true"}]},{"name":"priority","type":"$xor","description":"","properties":[{"name":"priority","type":"object","description":"","meta":[{"name":"required","value":"true"}]},{"name":"priority","type":"object","description":"","meta":[{"name":"required","value":"true"}]},{"name":"priority","type":"object","description":"","meta":[{"name":"required","value":"true"}]},{"name":"priority","type":"object","description":"","meta":[{"name":"required","value":"true"}]}],"meta":[{"name":"required","value":"true"}]},{"name":"tags","type":"$array","description":"","meta":[{"name":"required","value":"true"}],"properties":[],"ofProperty":{"name":"","type":"string","properties":[],"description":"","meta":[{"name":"required","value":"true"}]}},{"name":"createdAt","type":"string","description":"","meta":[{"name":"required","value":"true"}]},{"name":"completedAt","type":"string","description":"","meta":[]},{"name":"dueDate","type":"string","description":"","meta":[]}]},{"name":"autoEdit","type":"boolean","description":"Enable inline editing mode on mount","meta":[]}],"meta":[{"name":"type","value":"parameters"}]}],"examples":{"groups":[]}}');
17
+ function AddTodoForm({ onAdd, defaultPriority = "medium", placeholder = "What needs to be done?" }) {
18
+ const [title, setTitle] = useState("");
19
+ const [priority, setPriority] = useState(defaultPriority);
20
+ const [description, setDescription] = useState("");
21
+ const [tags, setTags] = useState("");
22
+ const handleSubmit = (e) => {
23
+ e.preventDefault();
24
+ if (!title.trim())
25
+ return;
26
+ onAdd(title.trim(), priority, description.trim() || void 0, tags.split(",").map((t) => t.trim()).filter(Boolean));
27
+ setTitle("");
28
+ setDescription("");
29
+ setTags("");
30
+ setPriority(defaultPriority);
31
+ };
32
+ return jsxs("form", { onSubmit: handleSubmit, className: "add-todo-form", children: [jsx("input", { type: "text", value: title, onChange: (e) => setTitle(e.target.value), placeholder }), jsxs("select", { value: priority, onChange: (e) => setPriority(e.target.value), children: [jsx("option", { value: "low", children: "Low" }), jsx("option", { value: "medium", children: "Medium" }), jsx("option", { value: "high", children: "High" }), jsx("option", { value: "urgent", children: "Urgent" })] }), jsx("textarea", { value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Description (optional)" }), jsx("input", { type: "text", value: tags, onChange: (e) => setTags(e.target.value), placeholder: "Tags (comma separated)" }), jsx("button", { type: "submit", disabled: !title.trim(), children: "Add" })] });
33
+ }
34
+ AddTodoForm.__xydUniform = JSON.parse('{"title":"AddTodoForm","canonical":"","description":"","definitions":[{"title":"Props","properties":[{"name":"defaultPriority","type":"$xor","description":"Default priority for new todos","properties":[{"name":"defaultPriority","type":"object","description":"","meta":[]},{"name":"defaultPriority","type":"object","description":"","meta":[]},{"name":"defaultPriority","type":"object","description":"","meta":[]},{"name":"defaultPriority","type":"object","description":"","meta":[]}],"meta":[]},{"name":"placeholder","type":"string","description":"Placeholder text for the title input","meta":[]}],"meta":[{"name":"type","value":"parameters"}]}],"examples":{"groups":[]}}');
35
+ function FilterBar({ filter, onFilterChange, searchQuery, onSearchChange, stats, onClearCompleted, className }) {
36
+ const tabs = [
37
+ { value: "all", label: `All (${stats.total})` },
38
+ { value: "active", label: `Active (${stats.active})` },
39
+ { value: "completed", label: `Done (${stats.completed})` }
40
+ ];
41
+ return jsxs("div", { className: `filter-bar ${className || ""}`, children: [jsx("div", { className: "tabs", children: tabs.map((tab) => jsx("button", { type: "button", className: filter === tab.value ? "active" : "", onClick: () => onFilterChange(tab.value), children: tab.label }, tab.value)) }), jsx("input", { type: "search", value: searchQuery, onChange: (e) => onSearchChange(e.target.value), placeholder: "Search..." }), stats.completed > 0 && jsx("button", { type: "button", onClick: onClearCompleted, className: "clear-btn", children: "Clear completed" })] });
42
+ }
43
+ FilterBar.__xydUniform = JSON.parse('{"title":"FilterBar","canonical":"","description":"","definitions":[{"title":"Props","properties":[{"name":"filter","type":"$xor","description":"","properties":[{"name":"filter","type":"object","description":"","meta":[{"name":"required","value":"true"}]},{"name":"filter","type":"object","description":"","meta":[{"name":"required","value":"true"}]},{"name":"filter","type":"object","description":"","meta":[{"name":"required","value":"true"}]}],"meta":[{"name":"required","value":"true"}]},{"name":"searchQuery","type":"string","description":"Current search query","meta":[{"name":"required","value":"true"}]},{"name":"stats","type":"object","description":"","meta":[{"name":"required","value":"true"}],"properties":[{"name":"total","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"active","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"completed","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"overdue","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"byPriority","type":"object","description":"Construct a type with a set of properties K of type T","meta":[{"name":"required","value":"true"}],"properties":[{"name":"low","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"medium","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"high","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"urgent","type":"number","description":"","meta":[{"name":"required","value":"true"}]}]}]},{"name":"className","type":"string","description":"Additional CSS classes","meta":[]}],"meta":[{"name":"type","value":"parameters"}]}],"examples":{"groups":[]}}');
44
+ function StatCard({ label, value, color }) {
45
+ return jsxs("div", { className: "stat-card", children: [jsx("span", { className: "stat-label", children: label }), jsx("span", { className: "stat-value", style: { color }, children: value })] });
46
+ }
47
+ function StatsPanel({ stats, compact }) {
48
+ const cards = [
49
+ { label: "Total", value: stats.total },
50
+ { label: "Active", value: stats.active, color: "#3b82f6" },
51
+ { label: "Done", value: stats.completed, color: "#22c55e" },
52
+ { label: "Overdue", value: stats.overdue, color: stats.overdue > 0 ? "#ef4444" : void 0 }
53
+ ];
54
+ return jsx("div", { className: `stats-panel ${compact ? "compact" : ""}`, children: cards.map((c) => jsx(StatCard, { label: c.label, value: c.value, color: c.color }, c.label)) });
55
+ }
56
+ StatsPanel.__xydUniform = JSON.parse('{"title":"StatsPanel","canonical":"","description":"","definitions":[{"title":"Props","properties":[{"name":"stats","type":"object","description":"","meta":[{"name":"required","value":"true"}],"properties":[{"name":"total","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"active","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"completed","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"overdue","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"byPriority","type":"object","description":"Construct a type with a set of properties K of type T","meta":[{"name":"required","value":"true"}],"properties":[{"name":"low","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"medium","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"high","type":"number","description":"","meta":[{"name":"required","value":"true"}]},{"name":"urgent","type":"number","description":"","meta":[{"name":"required","value":"true"}]}]}]},{"name":"compact","type":"boolean","description":"Render in compact horizontal mode","meta":[]}],"meta":[{"name":"type","value":"parameters"}]}],"examples":{"groups":[]}}');
57
+ export {
58
+ AddTodoForm,
59
+ FilterBar,
60
+ StatsPanel,
61
+ TodoItem
62
+ };
63
+
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "xyd-fixture-rt-4-vite-app-user-card",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "build": "vite build"
7
+ }
8
+ }
@@ -0,0 +1,27 @@
1
+ interface UserCardProps {
2
+ /** Full name of the user */
3
+ name: string;
4
+
5
+ /** Email address of the user */
6
+ email: string;
7
+
8
+ /** URL to the user's avatar image */
9
+ avatarUrl?: string;
10
+
11
+ /** Role or title of the user */
12
+ role?: "admin" | "editor" | "viewer";
13
+
14
+ /** Whether the card is in a loading state */
15
+ loading?: boolean;
16
+ }
17
+
18
+ export function UserCard(props: UserCardProps) {
19
+ return (
20
+ <div>
21
+ {props.avatarUrl && <img src={props.avatarUrl} alt={props.name} />}
22
+ <h3>{props.name}</h3>
23
+ <p>{props.email}</p>
24
+ {props.role && <span>{props.role}</span>}
25
+ </div>
26
+ );
27
+ }
@@ -0,0 +1 @@
1
+ export {UserCard} from './UserCard';
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "./dist",
4
+ "jsx": "react-jsx",
5
+ "skipLibCheck": true,
6
+ "module": "ESNext",
7
+ "moduleResolution": "bundler",
8
+ "target": "ES2020",
9
+ "strict": true
10
+ },
11
+ "include": ["src/**/*.ts", "src/**/*.tsx"]
12
+ }
@@ -0,0 +1,23 @@
1
+ import {defineConfig} from 'vite';
2
+ import {resolve} from 'node:path';
3
+ import react from '@vitejs/plugin-react';
4
+ import {xydSourceReactRuntime} from '@xyd-js/source-react-runtime';
5
+
6
+ export default defineConfig({
7
+ plugins: [
8
+ xydSourceReactRuntime(),
9
+ react({jsxRuntime: 'automatic'}),
10
+ ],
11
+ build: {
12
+ lib: {
13
+ entry: 'src/index.ts',
14
+ formats: ['es'],
15
+ fileName: 'index',
16
+ },
17
+ rollupOptions: {
18
+ external: ['react', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'react-dom'],
19
+ },
20
+ minify: false,
21
+ sourcemap: false,
22
+ },
23
+ });
@@ -0,0 +1,10 @@
1
+ // === index.js ===
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ function UserCard(props) {
4
+ return jsxs("div", { children: [props.avatarUrl && jsx("img", { src: props.avatarUrl, alt: props.name }), jsx("h3", { children: props.name }), jsx("p", { children: props.email }), props.role && jsx("span", { children: props.role })] });
5
+ }
6
+ UserCard.__xydUniform = JSON.parse(`{"title":"UserCard","canonical":"","description":"","definitions":[{"title":"Props","properties":[{"name":"name","type":"string","description":"Full name of the user","meta":[{"name":"required","value":"true"}]},{"name":"email","type":"string","description":"Email address of the user","meta":[{"name":"required","value":"true"}]},{"name":"avatarUrl","type":"string","description":"URL to the user's avatar image","meta":[]},{"name":"role","type":"$xor","description":"Role or title of the user","properties":[{"name":"role","type":"object","description":"","meta":[]},{"name":"role","type":"object","description":"","meta":[]},{"name":"role","type":"object","description":"","meta":[]}],"meta":[]},{"name":"loading","type":"boolean","description":"Whether the card is in a loading state","meta":[]}],"meta":[{"name":"type","value":"parameters"}]}],"examples":{"groups":[]}}`);
7
+ export {
8
+ UserCard
9
+ };
10
+
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "xyd-fixture-rt-5-rollup-user-card",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "build": "rollup -c rollup.config.mjs"
7
+ }
8
+ }
@@ -0,0 +1,20 @@
1
+ import {resolve, dirname} from 'node:path';
2
+ import {fileURLToPath} from 'node:url';
3
+ import typescript from '@rollup/plugin-typescript';
4
+ import {xydSourceReactRuntime} from '@xyd-js/source-react-runtime';
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+
8
+ export default {
9
+ input: 'src/index.ts',
10
+ external: ['react', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'react-dom'],
11
+ output: {
12
+ dir: 'dist',
13
+ format: 'es',
14
+ entryFileNames: 'index.js',
15
+ },
16
+ plugins: [
17
+ xydSourceReactRuntime(),
18
+ typescript({tsconfig: resolve(__dirname, 'tsconfig.json'), compilerOptions: {declaration: false}}),
19
+ ],
20
+ };
@@ -0,0 +1,27 @@
1
+ interface UserCardProps {
2
+ /** Full name of the user */
3
+ name: string;
4
+
5
+ /** Email address of the user */
6
+ email: string;
7
+
8
+ /** URL to the user's avatar image */
9
+ avatarUrl?: string;
10
+
11
+ /** Role or title of the user */
12
+ role?: "admin" | "editor" | "viewer";
13
+
14
+ /** Whether the card is in a loading state */
15
+ loading?: boolean;
16
+ }
17
+
18
+ export function UserCard(props: UserCardProps) {
19
+ return (
20
+ <div>
21
+ {props.avatarUrl && <img src={props.avatarUrl} alt={props.name} />}
22
+ <h3>{props.name}</h3>
23
+ <p>{props.email}</p>
24
+ {props.role && <span>{props.role}</span>}
25
+ </div>
26
+ );
27
+ }
@@ -0,0 +1 @@
1
+ export {UserCard} from './UserCard';
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "./dist",
4
+ "jsx": "react-jsx",
5
+ "skipLibCheck": true,
6
+ "module": "ESNext",
7
+ "moduleResolution": "bundler",
8
+ "target": "ES2020",
9
+ "strict": true
10
+ },
11
+ "include": ["src/**/*.ts", "src/**/*.tsx"]
12
+ }
@@ -0,0 +1,11 @@
1
+ // === index.js ===
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import 'typia';
4
+
5
+ function UserCard(props) {
6
+ return (jsxs("div", { children: [props.avatarUrl && jsx("img", { src: props.avatarUrl, alt: props.name }), jsx("h3", { children: props.name }), jsx("p", { children: props.email }), props.role && jsx("span", { children: props.role })] }));
7
+ }
8
+ UserCard.__xydUniform = JSON.parse('{"title":"UserCard","canonical":"","description":"","definitions":[{"title":"Props","properties":[{"name":"name","type":"string","description":"Full name of the user","meta":[{"name":"required","value":"true"}]},{"name":"email","type":"string","description":"Email address of the user","meta":[{"name":"required","value":"true"}]},{"name":"avatarUrl","type":"string","description":"URL to the user\'s avatar image","meta":[]},{"name":"role","type":"$xor","description":"Role or title of the user","properties":[{"name":"role","type":"object","description":"","meta":[]},{"name":"role","type":"object","description":"","meta":[]},{"name":"role","type":"object","description":"","meta":[]}],"meta":[]},{"name":"loading","type":"boolean","description":"Whether the card is in a loading state","meta":[]}],"meta":[{"name":"type","value":"parameters"}]}],"examples":{"groups":[]}}');
9
+
10
+ export { UserCard };
11
+
@@ -0,0 +1,19 @@
1
+ import {resolve, dirname} from 'node:path';
2
+ import {fileURLToPath} from 'node:url';
3
+ import * as esbuild from 'esbuild';
4
+ import {xydSourceReactRuntimeEsbuild} from '@xyd-js/source-react-runtime/esbuild';
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+
8
+ await esbuild.build({
9
+ entryPoints: [resolve(__dirname, 'src/index.ts')],
10
+ outfile: resolve(__dirname, 'dist/index.js'),
11
+ bundle: true,
12
+ format: 'esm',
13
+ platform: 'browser',
14
+ external: ['react', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'react-dom'],
15
+ minify: false,
16
+ plugins: [
17
+ xydSourceReactRuntimeEsbuild(),
18
+ ],
19
+ });
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "xyd-fixture-rt-6-esbuild-user-card",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "build": "node esbuild.config.mjs"
7
+ }
8
+ }
@@ -0,0 +1,27 @@
1
+ interface UserCardProps {
2
+ /** Full name of the user */
3
+ name: string;
4
+
5
+ /** Email address of the user */
6
+ email: string;
7
+
8
+ /** URL to the user's avatar image */
9
+ avatarUrl?: string;
10
+
11
+ /** Role or title of the user */
12
+ role?: "admin" | "editor" | "viewer";
13
+
14
+ /** Whether the card is in a loading state */
15
+ loading?: boolean;
16
+ }
17
+
18
+ export function UserCard(props: UserCardProps) {
19
+ return (
20
+ <div>
21
+ {props.avatarUrl && <img src={props.avatarUrl} alt={props.name} />}
22
+ <h3>{props.name}</h3>
23
+ <p>{props.email}</p>
24
+ {props.role && <span>{props.role}</span>}
25
+ </div>
26
+ );
27
+ }
@@ -0,0 +1 @@
1
+ export {UserCard} from './UserCard';
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "./dist",
4
+ "jsx": "react-jsx",
5
+ "skipLibCheck": true,
6
+ "module": "ESNext",
7
+ "moduleResolution": "bundler",
8
+ "target": "ES2020",
9
+ "strict": true
10
+ },
11
+ "include": ["src/**/*.ts", "src/**/*.tsx"]
12
+ }
@@ -0,0 +1,11 @@
1
+ // === index.js ===
2
+ // src/UserCard.tsx
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ function UserCard(props) {
5
+ return _jsxs("div", { children: [props.avatarUrl && _jsx("img", { src: props.avatarUrl, alt: props.name }), _jsx("h3", { children: props.name }), _jsx("p", { children: props.email }), props.role && _jsx("span", { children: props.role })] });
6
+ }
7
+ UserCard.__xydUniform = JSON.parse(`{"title":"UserCard","canonical":"","description":"","definitions":[{"title":"Props","properties":[{"name":"name","type":"string","description":"Full name of the user","meta":[{"name":"required","value":"true"}]},{"name":"email","type":"string","description":"Email address of the user","meta":[{"name":"required","value":"true"}]},{"name":"avatarUrl","type":"string","description":"URL to the user's avatar image","meta":[]},{"name":"role","type":"$xor","description":"Role or title of the user","properties":[{"name":"role","type":"object","description":"","meta":[]},{"name":"role","type":"object","description":"","meta":[]},{"name":"role","type":"object","description":"","meta":[]}],"meta":[]},{"name":"loading","type":"boolean","description":"Whether the card is in a loading state","meta":[]}],"meta":[{"name":"type","value":"parameters"}]}],"examples":{"groups":[]}}`);
8
+ export {
9
+ UserCard
10
+ };
11
+
@@ -0,0 +1,26 @@
1
+ import { Link } from "react-router";
2
+ import type { Product } from "../types/product";
3
+
4
+ interface ProductCardProps {
5
+ product: Product;
6
+ onAddToCart: (productId: string) => void;
7
+ layout?: "grid" | "list";
8
+ }
9
+
10
+ export function ProductCard({ product, onAddToCart, layout = "grid" }: ProductCardProps) {
11
+ return (
12
+ <div className={`product-card product-card--${layout}`}>
13
+ <Link to={`/products/${product.id}`}>
14
+ <h3>{product.name}</h3>
15
+ </Link>
16
+ <span>${product.price}</span>
17
+ <button
18
+ type="button"
19
+ disabled={!product.inStock}
20
+ onClick={() => onAddToCart(product.id)}
21
+ >
22
+ {product.inStock ? "Add to Cart" : "Out of Stock"}
23
+ </button>
24
+ </div>
25
+ );
26
+ }
@@ -0,0 +1,36 @@
1
+ import { PassThrough } from "node:stream";
2
+ import { createReadableStreamFromReadable } from "@react-router/node";
3
+ import { ServerRouter } from "react-router";
4
+ import { renderToPipeableStream } from "react-dom/server";
5
+ import type { EntryContext } from "react-router";
6
+
7
+ export default function handleRequest(
8
+ request: Request,
9
+ responseStatusCode: number,
10
+ responseHeaders: Headers,
11
+ routerContext: EntryContext,
12
+ ) {
13
+ return new Promise((resolve, reject) => {
14
+ const { pipe } = renderToPipeableStream(
15
+ <ServerRouter context={routerContext} url={request.url} />,
16
+ {
17
+ onShellReady() {
18
+ const body = new PassThrough();
19
+ const stream = createReadableStreamFromReadable(body);
20
+
21
+ responseHeaders.set("Content-Type", "text/html");
22
+ resolve(
23
+ new Response(stream, {
24
+ headers: responseHeaders,
25
+ status: responseStatusCode,
26
+ }),
27
+ );
28
+ pipe(body);
29
+ },
30
+ onShellError(error: unknown) {
31
+ reject(error);
32
+ },
33
+ },
34
+ );
35
+ });
36
+ }
@@ -0,0 +1,23 @@
1
+ import { Links, Meta, Outlet, Scripts, ScrollRestoration } from "react-router";
2
+
3
+ export function Layout({ children }: { children: React.ReactNode }) {
4
+ return (
5
+ <html lang="en">
6
+ <head>
7
+ <meta charSet="utf-8" />
8
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
9
+ <Meta />
10
+ <Links />
11
+ </head>
12
+ <body>
13
+ {children}
14
+ <ScrollRestoration />
15
+ <Scripts />
16
+ </body>
17
+ </html>
18
+ );
19
+ }
20
+
21
+ export default function Root() {
22
+ return <Outlet />;
23
+ }
@@ -0,0 +1,16 @@
1
+ import { Link } from "react-router";
2
+ import type { CartItem } from "../types/product";
3
+
4
+ interface CartRouteProps {
5
+ items: CartItem[];
6
+ onRemove: (productId: string) => void;
7
+ }
8
+
9
+ export default function CartRoute() {
10
+ return (
11
+ <div>
12
+ <h1>Cart</h1>
13
+ <Link to="/">Continue Shopping</Link>
14
+ </div>
15
+ );
16
+ }