docs: add WASM library demo using Vite & React

This commit is contained in:
rzmk 2024-06-20 20:13:34 -04:00
parent bc05a9f46e
commit 93bc82bd36
27 changed files with 534 additions and 111 deletions

View file

@ -0,0 +1,42 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}

View file

@ -0,0 +1,80 @@
import "./App.css";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import init, * as czv from "czv-wasm";
import React, { useState } from "react";
function App() {
const [initDone, setInitDone] = useState(false);
const [loading, setLoading] = useState(false);
const [rowCount, setRowCount] = useState<number | undefined>(undefined);
const [columnCount, setColumnCount] = useState<number | undefined>(
undefined
);
const handleFile = async (e: React.ChangeEvent<HTMLInputElement>) => {
setLoading(true);
if (!initDone) {
await init();
setInitDone(true);
}
if (e.target.files && e.target.files.length === 1) {
const rowCountOutput = czv.rowCount({
file_data: await e.target.files[0].text(),
});
setRowCount(rowCountOutput);
const columnCountOutput = czv.columnCount({
file_data: await e.target.files[0].text(),
});
setColumnCount(columnCountOutput);
}
setLoading(false);
};
return (
<>
<div className="grid text-left w-full gap-1.5">
<hgroup>
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
czv - WebAssembly library demo using Vite & React
</h1>
<p className="text-xl text-muted-foreground mb-4">
Visit{" "}
<a
className="text-cyan-400"
href="https://github.com/rzmk/czv"
>
here
</a>{" "}
for the czv source code and{" "}
<a
className="text-cyan-400"
href="https://github.com/rzmk/czv/tree/main/czv-wasm/examples/web-demo"
>
here
</a>{" "}
for this site's source code.
</p>
</hgroup>
<Label htmlFor="csv">Import your CSV file</Label>
<Input onChange={handleFile} id="csv" type="file" />
{loading && <p>Loading...</p>}
{rowCount && (
<p>
<strong>Row count (excluding header row)</strong>:{" "}
{rowCount}
</p>
)}
{columnCount && (
<p>
<strong>Column count</strong>: {columnCount}
</p>
)}
</div>
</>
);
}
export default App;

View file

@ -0,0 +1,25 @@
import * as React from "react"
import { cn } from "@/lib/utils"
export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}
const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
{...props}
/>
)
}
)
Input.displayName = "Input"
export { Input }

View file

@ -0,0 +1,24 @@
import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
)
const Label = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
VariantProps<typeof labelVariants>
>(({ className, ...props }, ref) => (
<LabelPrimitive.Root
ref={ref}
className={cn(labelVariants(), className)}
{...props}
/>
))
Label.displayName = LabelPrimitive.Root.displayName
export { Label }

View file

@ -0,0 +1,76 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 10% 3.9%;
--radius: 0.5rem;
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--ring: 240 4.9% 83.9%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}

View file

@ -0,0 +1,6 @@
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

View file

@ -0,0 +1,10 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)

View file

@ -0,0 +1 @@
/// <reference types="vite/client" />