Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "xyd-fixture-rt-9-vite-lib-react-types-resilience",
"private": true,
"type": "module",
"scripts": {
"build": "vite build"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from "react";

interface CardWrapperProps {
/** Card title */
title: string;

/** Card content — React types that typia cannot resolve */
children: React.ReactNode;

/** Optional icon element */
icon?: React.ReactElement;

/** Optional footer element */
footer?: React.ReactNode;

/** Whether the card has a border */
bordered?: boolean;
}

export function CardWrapper({ title, children, icon, footer, bordered }: CardWrapperProps) {
return (
<div className={`card ${bordered ? "bordered" : ""}`}>
<div className="card-header">
{icon && <span className="card-icon">{icon}</span>}
<h3>{title}</h3>
</div>
<div className="card-body">{children}</div>
{footer && <div className="card-footer">{footer}</div>}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
interface StatusBadgeProps {
/** Current status label */
label: string;

/** Visual variant */
variant: "success" | "warning" | "error" | "info";

/** Size of the badge */
size?: "small" | "medium" | "large";

/** Whether the badge should pulse */
animated?: boolean;
}

export function StatusBadge({ label, variant, size = "medium", animated }: StatusBadgeProps) {
return (
<span className={`badge badge-${variant} badge-${size} ${animated ? "pulse" : ""}`}>
{label}
</span>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { StatusBadge } from "./StatusBadge";
export { CardWrapper } from "./CardWrapper";
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"outDir": "./dist",
"jsx": "react-jsx",
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"target": "ES2020",
"strict": true
},
"include": ["src/**/*.ts", "src/**/*.tsx"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {defineConfig} from 'vite';
import react from '@vitejs/plugin-react';
import {xydSourceReactRuntime} from '@xyd-js/source-react-runtime';

export default defineConfig({
plugins: [
xydSourceReactRuntime(),
react(),
],
build: {
lib: {
entry: 'src/index.ts',
formats: ['es'],
fileName: 'index',
},
rollupOptions: {
external: ['react', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'react-dom'],
},
minify: false,
},
});

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Main App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "xyd-fixture-rt-neg3-vite-app-iframe-multi-entry",
"private": true,
"type": "module",
"scripts": {
"build": "vite build"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/sample-app-entry.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { createRoot } from "react-dom/client";

interface NavBarProps {
/** Application title */
title: string;
/** Navigation links */
links: string[];
/** Whether to use dark theme */
dark?: boolean;
}

export function NavBar({ title, links, dark }: NavBarProps) {
return (
<nav style={{ background: dark ? "#222" : "#f5f5f5", padding: 8 }}>
<strong>{title}</strong>
<ul>
{links.map((link) => (
<li key={link}>{link}</li>
))}
</ul>
</nav>
);
}

function App() {
return (
<div>
<NavBar title="Playground" links={["Home", "About"]} />
<iframe
src="/sample-app.html"
style={{ width: "100%", height: 400, border: "none" }}
/>
</div>
);
}

const root = createRoot(document.getElementById("root")!);
root.render(<App />);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import("./sample-app").then(async ({ SampleApp }) => {
const React = await import("react");
const { createRoot } = await import("react-dom/client");

const root = createRoot(document.getElementById("root")!);
root.render(React.createElement(SampleApp));
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { createContext, useContext, useState } from "react";

// --- Types ---

interface ThemeContextValue {
mode: "light" | "dark";
setMode: (mode: "light" | "dark") => void;
}

const ThemeContext = createContext<ThemeContextValue | null>(null);

// --- Provider with React.ReactNode children ---

function ThemeProvider({ children }: { children: React.ReactNode }) {
const [mode, setMode] = useState<"light" | "dark">("light");
return (
<ThemeContext.Provider value={{ mode, setMode }}>
{children}
</ThemeContext.Provider>
);
}

// --- Component with mixed props (simple + React types) ---

interface User {
name: string;
email: string;
id: number;
joinedAt: Date;
}

interface UserCardProps {
user: User;
role: "admin" | "editor" | "viewer";
permissions: string[];
onEdit: (id: number) => void;
tags: Map<string, boolean>;
statusIndicator: React.ReactElement;
actionBar?: React.ReactNode;
}

function UserCard({ user, role, permissions, onEdit, tags, statusIndicator, actionBar }: UserCardProps) {
const [expanded, setExpanded] = useState(false);
const theme = useContext(ThemeContext);

return (
<div style={{ border: "1px solid #eee", padding: 12, borderRadius: 8, marginBottom: 8 }}>
<strong>{user.name}</strong> ({role})
<div style={{ fontSize: 12 }}>{user.email}</div>
<div>{permissions.join(", ")}</div>
<div>{statusIndicator}</div>
{actionBar}
<button type="button" onClick={() => setExpanded(!expanded)}>
{expanded ? "Hide" : "Show"}
</button>
{expanded && (
<div>
<div>ID: {user.id}</div>
<button type="button" onClick={() => onEdit(user.id)}>Edit</button>
</div>
)}
</div>
);
}

// --- Simple component (no React types) ---

interface TodoItemProps {
id: number;
title: string;
completed: boolean;
priority: "low" | "medium" | "high";
onToggle: (id: number) => void;
}

function TodoItem({ id, title, completed, priority, onToggle }: TodoItemProps) {
return (
<div style={{ display: "flex", gap: 8, padding: 4 }}>
<input type="checkbox" checked={completed} onChange={() => onToggle(id)} />
<span style={{ textDecoration: completed ? "line-through" : "none" }}>{title}</span>
<span>({priority})</span>
</div>
);
}

// --- Main sample app ---

function SampleApp() {
return (
<ThemeProvider>
<h3>Sample App (iframe)</h3>
<UserCard
user={{ name: "Alice", email: "alice@test.com", id: 1, joinedAt: new Date() }}
role="admin"
permissions={["read", "write"]}
onEdit={(id) => console.log("edit", id)}
tags={new Map([["verified", true]])}
statusIndicator={<span>Active</span>}
/>
<TodoItem id={1} title="Write docs" completed={false} priority="high" onToggle={() => {}} />
</ThemeProvider>
);
}

export { ThemeProvider, ThemeContext, UserCard, TodoItem, SampleApp };
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"outDir": "./dist",
"jsx": "react-jsx",
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"target": "ES2020",
"strict": true
},
"include": ["src/**/*.ts", "src/**/*.tsx"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {defineConfig} from 'vite';
import {resolve} from 'node:path';
import react from '@vitejs/plugin-react';
import {xydSourceReactRuntime} from '@xyd-js/source-react-runtime';

export default defineConfig({
plugins: [
xydSourceReactRuntime(),
react(),
],
build: {
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
'sample-app': resolve(__dirname, 'sample-app.html'),
},
},
minify: false,
},
});

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading