Skip to content
Open
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
12 changes: 12 additions & 0 deletions packages/framework-playground/index.html
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>Framework Playground</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
25 changes: 25 additions & 0 deletions packages/framework-playground/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "@react-grab/framework-playground",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"react": "latest",
"react-dom": "latest",
"react-grab": "workspace:*",
"solid-js": "latest",
"svelte": "latest",
"vue": "latest"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "latest",
"@vitejs/plugin-react": "latest",
"@vitejs/plugin-vue": "latest",
"vite": "latest",
"vite-plugin-solid": "latest"
}
}
100 changes: 100 additions & 0 deletions packages/framework-playground/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React from "react";
import { createRoot } from "react-dom/client";
import { createApp } from "vue";
import { render } from "solid-js/web";
import { mount } from "svelte";
import { ReactLogoCard } from "./react-logo-card.react.jsx";
import { SolidLogoCard } from "./solid-logo-card.solid.jsx";
import VueLogoCard from "./vue-logo-card.vue";
import SvelteLogoCard from "./svelte-logo-card.svelte";
import "./styles.css";

if (import.meta.env.DEV) {
import("react-grab").then(({ registerPlugin }) => {
const sourceBar = document.getElementById("source-bar");

registerPlugin({
name: "source-bar",
hooks: {
onCopySuccess: async (elements) => {
if (!sourceBar || elements.length < 1) return;
const api = window.__REACT_GRAB__;
if (!api) return;

const source = await api.getSource(elements[0]);
const stackContext = await api.getStackContext(elements[0]);

if (source) {
const location = source.lineNumber
? `${source.filePath}:${source.lineNumber}`
: source.filePath;

sourceBar.textContent = source.componentName
? `${source.componentName} → ${location}`
: location;
} else if (stackContext) {
sourceBar.textContent = stackContext.replace(/^\n\s*in\s*/, "");
} else {
sourceBar.textContent = "";
sourceBar.classList.remove("source-bar--visible");
return;
}

sourceBar.classList.add("source-bar--visible");
},
},
});
});
}

const APPLICATION_MOUNT_ELEMENT_ID = "app";
const FRAMEWORK_MOUNT_IDS = {
react: "react-logo-root",
vue: "vue-logo-root",
solid: "solid-logo-root",
svelte: "svelte-logo-root",
};

const applicationMountElement = document.getElementById(
APPLICATION_MOUNT_ELEMENT_ID,
);

if (!applicationMountElement) {
throw new Error("Framework playground root element is missing.");
}

applicationMountElement.innerHTML = `
<main class="framework-playground">
<section class="framework-playground__grid">
<div id="${FRAMEWORK_MOUNT_IDS.react}"></div>
<div id="${FRAMEWORK_MOUNT_IDS.vue}"></div>
<div id="${FRAMEWORK_MOUNT_IDS.solid}"></div>
<div id="${FRAMEWORK_MOUNT_IDS.svelte}"></div>
</section>
<div id="source-bar" class="source-bar"></div>
</main>
`;

const getRequiredMountElement = (mountElementId) => {
const mountElement = document.getElementById(mountElementId);
if (!mountElement) {
throw new Error(`Missing framework mount element: ${mountElementId}`);
}
return mountElement;
};

createRoot(getRequiredMountElement(FRAMEWORK_MOUNT_IDS.react)).render(
React.createElement(ReactLogoCard),
);

createApp(VueLogoCard).mount(getRequiredMountElement(FRAMEWORK_MOUNT_IDS.vue));

render(
() => SolidLogoCard({}),
getRequiredMountElement(FRAMEWORK_MOUNT_IDS.solid),
);

mount(SvelteLogoCard, {
target: getRequiredMountElement(FRAMEWORK_MOUNT_IDS.svelte),
});

34 changes: 34 additions & 0 deletions packages/framework-playground/src/react-logo-card.react.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export const ReactLogoCard = () => {
return (
<button
id="react-logo-button"
type="button"
className="framework-logo-button"
>
<svg
viewBox="0 0 100 100"
className="framework-logo"
data-framework-logo="react"
>
<g fill="none" stroke="#61dafb" strokeWidth="4">
<ellipse cx="50" cy="50" rx="34" ry="14" />
<ellipse
cx="50"
cy="50"
rx="34"
ry="14"
transform="rotate(60 50 50)"
/>
<ellipse
cx="50"
cy="50"
rx="34"
ry="14"
transform="rotate(120 50 50)"
/>
</g>
<circle cx="50" cy="50" r="7" fill="#61dafb" />
</svg>
</button>
);
};
38 changes: 38 additions & 0 deletions packages/framework-playground/src/solid-logo-card.solid.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { createSignal } from "solid-js";

export const SolidLogoCard = () => {
const [isSelected, setIsSelected] = createSignal(false);

return (
<button
id="solid-logo-button"
type="button"
class="framework-logo-button"
onClick={() => setIsSelected((previous) => !previous)}
aria-pressed={isSelected()}
>
<svg
viewBox="0 0 166 155.3"
class="framework-logo"
data-framework-logo="solid"
>
<path
d="M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z"
fill="#76b3e1"
/>
<path
d="M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z"
fill="#518ac8"
/>
<path
d="M134 80a45 45 0 00-48-15L24 85 4 120l112 19 20-36c4-7 3-15-2-23z"
fill="#4377bb"
/>
<path
d="M114 115a45 45 0 00-48-15L4 120s53 40 94 30l3-1c17-5 23-21 13-34z"
fill="#1a336b"
/>
</svg>
</button>
);
};
51 changes: 51 additions & 0 deletions packages/framework-playground/src/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
* {
box-sizing: border-box;
margin: 0;
}

body {
margin: 0;
background: #000;
}

.framework-playground {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 48px;
}

.framework-playground__grid {
display: flex;
gap: 64px;
}

.framework-logo-button {
display: flex;
align-items: center;
justify-content: center;
border: none;
background: transparent;
padding: 0;
cursor: pointer;
}

.framework-logo {
width: 120px;
height: 120px;
}

.source-bar {
font-family: "SF Mono", "Fira Code", "Cascadia Code", monospace;
font-size: 13px;
color: #a1a1aa;
height: 20px;
opacity: 0;
transition: opacity 0.15s ease;
}

.source-bar--visible {
opacity: 1;
}
20 changes: 20 additions & 0 deletions packages/framework-playground/src/svelte-logo-card.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<button
id="svelte-logo-button"
type="button"
class="framework-logo-button"
>
<svg
viewBox="0 0 107 128"
class="framework-logo"
data-framework-logo="svelte"
>
<path
d="M94.1566,22.8189c-10.4-14.8851-30.94-19.2971-45.7914-9.8348L22.2825,29.6078A29.9234,29.9234,0,0,0,8.7639,49.6506a31.5136,31.5136,0,0,0,3.1076,20.2318A30.0061,30.0061,0,0,0,7.3953,81.0653a31.8886,31.8886,0,0,0,5.4473,24.1157c10.4022,14.8865,30.9423,19.2966,45.7914,9.8348L84.7167,98.3921A29.9177,29.9177,0,0,0,98.2353,78.3493,31.5263,31.5263,0,0,0,95.13,58.117a30,30,0,0,0,4.4743-11.1824,31.88,31.88,0,0,0-5.4473-24.1157"
fill="#ff3e00"
/>
<path
d="M45.8171,106.5815A20.7182,20.7182,0,0,1,23.58,98.3389a19.1739,19.1739,0,0,1-3.2766-14.5025,18.1886,18.1886,0,0,1,.6233-2.4357l.4912-1.4978,1.3363.9815a33.6443,33.6443,0,0,0,10.203,5.0978l.9694.2941-.0893.9675a5.8474,5.8474,0,0,0,1.052,3.8781,6.2389,6.2389,0,0,0,6.6952,2.485,5.7449,5.7449,0,0,0,1.6021-.7041L69.27,76.281a5.4306,5.4306,0,0,0,2.4506-3.631,5.7948,5.7948,0,0,0-.9875-4.3712,6.2436,6.2436,0,0,0-6.6978-2.4864,5.7427,5.7427,0,0,0-1.6.7036l-9.9532,6.3449a19.0329,19.0329,0,0,1-5.2965,2.3259,20.7181,20.7181,0,0,1-22.2368-8.2427,19.1725,19.1725,0,0,1-3.2766-14.5024,17.9885,17.9885,0,0,1,8.13-12.0513L55.8833,23.7472a19.0038,19.0038,0,0,1,5.3-2.3287A20.7182,20.7182,0,0,1,83.42,29.6611a19.1739,19.1739,0,0,1,3.2766,14.5025,18.4,18.4,0,0,1-.6233,2.4357l-.4912,1.4978-1.3356-.98a33.6175,33.6175,0,0,0-10.2037-5.1l-.9694-.2942.0893-.9675a5.8588,5.8588,0,0,0-1.052-3.878,6.2389,6.2389,0,0,0-6.6952-2.485,5.7449,5.7449,0,0,0-1.6021.7041L37.73,51.719a5.4218,5.4218,0,0,0-2.4487,3.63,5.7862,5.7862,0,0,0,.9856,4.3717,6.2437,6.2437,0,0,0,6.6978,2.4864,5.7652,5.7652,0,0,0,1.602-.7041l9.9519-6.3425a18.978,18.978,0,0,1,5.2959-2.3278,20.7181,20.7181,0,0,1,22.2368,8.2427,19.1725,19.1725,0,0,1,3.2766,14.5024,17.9977,17.9977,0,0,1-8.13,12.0532L51.1167,104.2528a19.0038,19.0038,0,0,1-5.3,2.3287"
fill="#fff"
/>
</svg>
</button>
8 changes: 8 additions & 0 deletions packages/framework-playground/src/vue-logo-card.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<template>
<button id="vue-logo-button" type="button" class="framework-logo-button">
<svg viewBox="0 0 100 100" class="framework-logo" data-framework-logo="vue">
<path d="M10 10H31L50 42L69 10H90L50 78Z" fill="#41b883" />
<path d="M24 10H40L50 28L60 10H76L50 55Z" fill="#35495e" />
</svg>
</button>
</template>
21 changes: 21 additions & 0 deletions packages/framework-playground/vite.config.js
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 vue from "@vitejs/plugin-vue";
import solid from "vite-plugin-solid";
import { svelte } from "@sveltejs/vite-plugin-svelte";

const REACT_COMPONENT_INCLUDE_PATTERN = /\.react\.jsx$/;
const SOLID_COMPONENT_INCLUDE_PATTERN = /\.solid\.jsx$/;

export default defineConfig({
plugins: [
react({
include: REACT_COMPONENT_INCLUDE_PATTERN,
}),
solid({
include: SOLID_COMPONENT_INCLUDE_PATTERN,
}),
vue(),
svelte(),
],
});
Loading
Loading