Compare commits
18 Commits
jazz-bette
...
gio/chat-q
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d10111117 | ||
|
|
511ae983d5 | ||
|
|
f61a120560 | ||
|
|
2f1307a0ba | ||
|
|
fa15ea56d1 | ||
|
|
ceeabfaf89 | ||
|
|
b0b2b85a6f | ||
|
|
28c19c134f | ||
|
|
0924c9baaa | ||
|
|
b2712e18a2 | ||
|
|
66894b63d7 | ||
|
|
b1a05143e3 | ||
|
|
fb761ce66d | ||
|
|
07a6c340dc | ||
|
|
0fea904dd0 | ||
|
|
373aef313f | ||
|
|
efff4d0f4f | ||
|
|
ea2b01d8a2 |
5
.changeset/cuddly-lemons-perform.md
Normal file
5
.changeset/cuddly-lemons-perform.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"quint-ui": patch
|
||||
---
|
||||
|
||||
Initial Quint-UI release
|
||||
@@ -12,10 +12,10 @@
|
||||
"test:e2e:ui": "playwright test --ui"
|
||||
},
|
||||
"dependencies": {
|
||||
"clsx": "^2.0.0",
|
||||
"hash-slash": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"lucide-react": "^0.274.0",
|
||||
"quint-ui": "workspace:*",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"zod": "3.25.28"
|
||||
@@ -32,4 +32,4 @@
|
||||
"typescript": "5.6.2",
|
||||
"vite": "^6.3.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useIframeHashRouter } from "hash-slash";
|
||||
import { Group } from "jazz-tools";
|
||||
import { JazzInspector } from "jazz-tools/inspector";
|
||||
import { JazzReactProvider, useAccount } from "jazz-tools/react";
|
||||
import { Button } from "quint-ui";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { ChatScreen } from "./chatScreen.tsx";
|
||||
@@ -39,7 +40,11 @@ export function App() {
|
||||
}}
|
||||
placeholder="Set username"
|
||||
/>
|
||||
{!inIframe && <button onClick={logOut}>Log out</button>}
|
||||
{!inIframe && (
|
||||
<Button intent="danger" onClick={logOut} variant="outline">
|
||||
Log out
|
||||
</Button>
|
||||
)}
|
||||
</TopBar>
|
||||
{router.route({
|
||||
"/": () => createChat() as never,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
@import "tailwindcss";
|
||||
@import "quint-ui/styles.css";
|
||||
/* We need to tell tailwind to detect classes from quint components */
|
||||
@source "../node_modules/quint-ui";
|
||||
|
||||
/* Custom stone color palette */
|
||||
@theme {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import clsx from "clsx";
|
||||
import { CoPlainText, ImageDefinition } from "jazz-tools";
|
||||
import type { CoPlainText, ImageDefinition } from "jazz-tools";
|
||||
import { ProgressiveImg } from "jazz-tools/react";
|
||||
import { ImageIcon } from "lucide-react";
|
||||
import { cn } from "quint-ui";
|
||||
import { useId, useRef } from "react";
|
||||
|
||||
export function AppContainer(props: { children: React.ReactNode }) {
|
||||
@@ -57,7 +57,7 @@ export function BubbleBody(props: {
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"line-clamp-10 text-ellipsis whitespace-pre-wrap",
|
||||
"rounded-2xl overflow-hidden max-w-[calc(100%-5rem)] shadow-sm p-1",
|
||||
props.fromMe
|
||||
@@ -75,9 +75,7 @@ export function BubbleText(props: {
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<p className={clsx("px-2 leading-relaxed", props.className)}>
|
||||
{props.text}
|
||||
</p>
|
||||
<p className={cn("px-2 leading-relaxed", props.className)}>{props.text}</p>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,31 +59,36 @@ describe("loading coValues from server", () => {
|
||||
connected: true,
|
||||
});
|
||||
|
||||
expect(async () => await node.load("test" as any)).rejects.toThrow(
|
||||
await expect(async () => await node.load("test" as any)).rejects.toThrow(
|
||||
"Trying to load CoValue with invalid id test",
|
||||
);
|
||||
expect(async () => await node.load(null as any)).rejects.toThrow(
|
||||
await expect(async () => await node.load(null as any)).rejects.toThrow(
|
||||
"Trying to load CoValue with invalid id null",
|
||||
);
|
||||
expect(async () => await node.load(undefined as any)).rejects.toThrow(
|
||||
await expect(async () => await node.load(undefined as any)).rejects.toThrow(
|
||||
"Trying to load CoValue with invalid id undefined",
|
||||
);
|
||||
expect(async () => await node.load(1 as any)).rejects.toThrow(
|
||||
await expect(async () => await node.load(1 as any)).rejects.toThrow(
|
||||
"Trying to load CoValue with invalid id 1",
|
||||
);
|
||||
expect(async () => await node.load({} as any)).rejects.toThrow(
|
||||
await expect(async () => await node.load({} as any)).rejects.toThrow(
|
||||
"Trying to load CoValue with invalid id [object Object]",
|
||||
);
|
||||
expect(async () => await node.load([] as any)).rejects.toThrow(
|
||||
await expect(async () => await node.load([] as any)).rejects.toThrow(
|
||||
"Trying to load CoValue with invalid id []",
|
||||
);
|
||||
expect(async () => await node.load(["test"] as any)).rejects.toThrow(
|
||||
await expect(async () => await node.load(["test"] as any)).rejects.toThrow(
|
||||
'Trying to load CoValue with invalid id ["test"]',
|
||||
);
|
||||
expect(async () => await node.load((() => {}) as any)).rejects.toThrow(
|
||||
"Trying to load CoValue with invalid id () => {\n }",
|
||||
);
|
||||
expect(async () => await node.load(new Date() as any)).rejects.toThrow();
|
||||
await expect(
|
||||
async () => await node.load((() => {}) as any),
|
||||
).rejects.toMatchInlineSnapshot(`
|
||||
[TypeError: Trying to load CoValue with invalid id () => {
|
||||
}]
|
||||
`);
|
||||
await expect(
|
||||
async () => await node.load(new Date() as any),
|
||||
).rejects.toThrow();
|
||||
});
|
||||
|
||||
test("unavailable coValue retry with skipRetry set to true", async () => {
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { defineProject } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
export default defineProject({
|
||||
test: {
|
||||
workspace: [
|
||||
{
|
||||
test: {
|
||||
typecheck: {
|
||||
enabled: true,
|
||||
checker: "tsc",
|
||||
},
|
||||
include: ["src/**/*.test.ts"],
|
||||
name: "unit",
|
||||
},
|
||||
},
|
||||
name: "jazz-tools",
|
||||
typecheck: {
|
||||
enabled: true,
|
||||
checker: "tsc",
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
test: {
|
||||
include: ["src/**/*.test.browser.ts"],
|
||||
name: "browser",
|
||||
browser: {
|
||||
enabled: true,
|
||||
provider: "playwright",
|
||||
@@ -24,6 +18,13 @@ export default defineConfig({
|
||||
screenshotFailures: false,
|
||||
instances: [{ browser: "chromium" }],
|
||||
},
|
||||
name: "browser",
|
||||
},
|
||||
},
|
||||
{
|
||||
test: {
|
||||
include: ["src/**/*.test.{js,ts,svelte}"],
|
||||
name: "unit",
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
1
packages/quint-ui/.gitignore
vendored
Normal file
1
packages/quint-ui/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
next-env.d.ts
|
||||
69
packages/quint-ui/README.md
Normal file
69
packages/quint-ui/README.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Quint UI
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
pnpm add quint-ui tailwindcss
|
||||
```
|
||||
|
||||
then in your tailwind styles (ie. `styles.css`) add:
|
||||
```css
|
||||
@import "quint-ui/styles.css";
|
||||
@source "../node_modules/quint-ui";
|
||||
```
|
||||
> [!TIP]
|
||||
> There's no need to do
|
||||
> ```css
|
||||
> @import "tailwindcss";
|
||||
> ```
|
||||
> Quint does this for you.
|
||||
|
||||
|
||||
### Usage
|
||||
|
||||
```tsx
|
||||
import { Button } from "quint-ui";
|
||||
|
||||
<Button>Click me</Button>
|
||||
```
|
||||
|
||||
## Development workflow
|
||||
|
||||
### In Quint
|
||||
|
||||
In this directory, run:
|
||||
```sh
|
||||
pnpm dev:docs
|
||||
```
|
||||
This starts a nextjs app you can use to write docs and/or test components.
|
||||
|
||||
### In example apps
|
||||
|
||||
In this directory, run:
|
||||
```sh
|
||||
pnpm dev
|
||||
```
|
||||
This starts typescript in watch mode.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Make sure quint-ui is installed in the example via
|
||||
> ```json
|
||||
> "dependencies": {
|
||||
> "quint-ui": "workspace:*"
|
||||
> }
|
||||
> ```
|
||||
|
||||
## Building
|
||||
|
||||
### Docs website
|
||||
|
||||
```sh
|
||||
pnpm build:docs
|
||||
```
|
||||
|
||||
### Package
|
||||
|
||||
```sh
|
||||
pnpm build
|
||||
```
|
||||
|
||||
25
packages/quint-ui/app/docs/button/page.tsx
Normal file
25
packages/quint-ui/app/docs/button/page.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Button } from "@/src/components/button";
|
||||
|
||||
export default function ButtonDocsPage() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold">Button</h1>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<Button intent="primary">Default</Button>
|
||||
<Button intent="primary" variant="outline">
|
||||
Outline
|
||||
</Button>
|
||||
<Button intent="primary" variant="ghost">
|
||||
Ghost
|
||||
</Button>
|
||||
<Button intent="primary" variant="link">
|
||||
Link
|
||||
</Button>
|
||||
<Button intent="primary" variant="inverted">
|
||||
Inverted
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
14
packages/quint-ui/app/docs/page.tsx
Normal file
14
packages/quint-ui/app/docs/page.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import Link from "next/link";
|
||||
|
||||
export default function DocsPage() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold">Components</h1>
|
||||
<ul>
|
||||
<li>
|
||||
<Link href="/docs/button">Button</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
18
packages/quint-ui/app/layout.tsx
Normal file
18
packages/quint-ui/app/layout.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import "@/src/globals.css";
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Quint UI</title>
|
||||
</head>
|
||||
<body>
|
||||
<div className="container mx-auto">{children}</div>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
22
packages/quint-ui/app/page.tsx
Normal file
22
packages/quint-ui/app/page.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Button } from "@/src/components/button";
|
||||
import { BookIcon } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="flex flex-col gap-8">
|
||||
<h1 className="text-3xl font-bold tracking-tight">Quint UI</h1>
|
||||
|
||||
{/* Example usage of the button component with an icon and rendered as a nextjs link */}
|
||||
<Button
|
||||
variant="default"
|
||||
intent="primary"
|
||||
size="lg"
|
||||
render={<Link href="/docs" />}
|
||||
>
|
||||
<BookIcon />
|
||||
Read the docs!
|
||||
</Button>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
6
packages/quint-ui/next.config.ts
Normal file
6
packages/quint-ui/next.config.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
export default {
|
||||
typescript: {
|
||||
ignoreBuildErrors: true,
|
||||
},
|
||||
};
|
||||
44
packages/quint-ui/package.json
Normal file
44
packages/quint-ui/package.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "quint-ui",
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".":{
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./styles.css": "./src/globals.css"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "pnpm clean && tsc --project tsconfig.build.json --watch",
|
||||
"dev:website": "next dev --turbopack",
|
||||
"build": "pnpm clean && tsc --project tsconfig.build.json",
|
||||
"build:website": "next build",
|
||||
"clean": "rm -rf ./dist",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@base-ui-components/react": "1.0.0-beta.1",
|
||||
"clsx": "^2.1.1",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"tailwind-variants": "^1.0.0",
|
||||
"tw-animate-css": "^1.3.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=19.0.0",
|
||||
"react-dom": ">=19.0.0",
|
||||
"tailwindcss": ">=4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"next": "15.4.2",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"@tailwindcss/postcss": "^4.1.11",
|
||||
"@types/node": "^22.16.5",
|
||||
"@types/react": "19.1.8",
|
||||
"@types/react-dom": "19.1.6",
|
||||
"lucide-react": "^0.525.0",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
||||
6
packages/quint-ui/postcss.config.mjs
Normal file
6
packages/quint-ui/postcss.config.mjs
Normal file
@@ -0,0 +1,6 @@
|
||||
const config = {
|
||||
plugins: {
|
||||
"@tailwindcss/postcss": {},
|
||||
},
|
||||
};
|
||||
export default config;
|
||||
160
packages/quint-ui/src/components/button.tsx
Normal file
160
packages/quint-ui/src/components/button.tsx
Normal file
@@ -0,0 +1,160 @@
|
||||
import { mergeProps } from "@base-ui-components/react/merge-props";
|
||||
import { useRender } from "@base-ui-components/react/use-render";
|
||||
import { type VariantProps, tv } from "tailwind-variants";
|
||||
|
||||
const button = tv({
|
||||
base: "inline-flex items-center justify-center gap-2 rounded-sm text-center transition-colors w-fit text-nowrap disabled:pointer-events-none disabled:opacity-70 disabled:cursor-not-allowed disabled:pointer-events-none font-medium",
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"focus:outline-none focus-visible:ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-opacity-10",
|
||||
ghost: "",
|
||||
outline: "shadow-sm border",
|
||||
link: "",
|
||||
inverted: "",
|
||||
},
|
||||
intent: {
|
||||
default: "border-secondary",
|
||||
primary: "border-primary",
|
||||
success: "border-success",
|
||||
danger: "border-danger",
|
||||
},
|
||||
size: {
|
||||
sm: "text-sm py-1 px-2 [&>svg]:size-4",
|
||||
md: "py-1.5 px-3 h-[36px] [&>svg]:size-4",
|
||||
lg: "py-2 px-5 md:px-6 md:py-2.5 [&>svg]:size-5",
|
||||
icon: "p-2 [&>svg]:size-4",
|
||||
},
|
||||
},
|
||||
compoundVariants: [
|
||||
// Default Variants
|
||||
{
|
||||
variant: "default",
|
||||
intent: ["primary", "success", "danger", "default"],
|
||||
className: "bg-gradient-to-t from-7% via-50% to-95%",
|
||||
},
|
||||
{
|
||||
variant: "default",
|
||||
intent: "primary",
|
||||
className: [
|
||||
"text-primary-foreground",
|
||||
"from-primary-dark via-primary to-primary-light",
|
||||
"hover:from-primary-brightLight hover:to-primary-light",
|
||||
"active:from-primary-brightDark active:to-primary-light active:border-primary-transparent ",
|
||||
"focus:ring-primary focus:border-primary-transparent",
|
||||
],
|
||||
},
|
||||
{
|
||||
variant: "default",
|
||||
intent: "success",
|
||||
className: [
|
||||
"text-success-foreground",
|
||||
"from-success-dark via-success to-success-light",
|
||||
"hover:from-success-brightLight hover:to-success-light",
|
||||
"active:from-success-brightDark active:to-success-light",
|
||||
"focus:ring-success",
|
||||
],
|
||||
},
|
||||
{
|
||||
variant: "default",
|
||||
intent: "danger",
|
||||
className: [
|
||||
"text-danger-foreground",
|
||||
"from-danger-dark via-danger to-danger-light",
|
||||
"hover:from-danger-brightLight hover:to-danger-light",
|
||||
"active:from-danger-brightDark active:to-danger-light",
|
||||
"focus:ring-danger",
|
||||
],
|
||||
},
|
||||
// Outline Variants
|
||||
{
|
||||
variant: "outline",
|
||||
intent: "primary",
|
||||
className: [
|
||||
"text-primary",
|
||||
"active:bg-primary/30",
|
||||
"hover:text-primary-light hover:border-primary-light",
|
||||
],
|
||||
},
|
||||
{
|
||||
variant: "outline",
|
||||
intent: "danger",
|
||||
className: [
|
||||
"text-danger",
|
||||
"active:bg-danger/30",
|
||||
"hover:text-danger-light hover:border-danger-light",
|
||||
],
|
||||
},
|
||||
{
|
||||
variant: "outline",
|
||||
intent: "success",
|
||||
className: [
|
||||
"text-success-dark",
|
||||
"active:bg-success/30",
|
||||
"hover:text-success-light hover:border-success-light",
|
||||
],
|
||||
},
|
||||
// Ghost Variants
|
||||
{
|
||||
variant: "ghost",
|
||||
intent: "primary",
|
||||
className: [
|
||||
"text-primary",
|
||||
"hover:bg-primary/10",
|
||||
"active:bg-primary/30",
|
||||
],
|
||||
},
|
||||
{
|
||||
variant: "ghost",
|
||||
intent: "primary",
|
||||
className: [
|
||||
"text-primary",
|
||||
"hover:bg-primary/10",
|
||||
"active:bg-primary/30",
|
||||
],
|
||||
},
|
||||
{
|
||||
variant: "ghost",
|
||||
intent: "danger",
|
||||
className: ["text-danger", "hover:bg-danger/10", "active:bg-danger/30"],
|
||||
},
|
||||
{
|
||||
variant: "ghost",
|
||||
intent: "success",
|
||||
className: [
|
||||
"text-success",
|
||||
"hover:bg-success/10",
|
||||
"active:bg-success/30",
|
||||
],
|
||||
},
|
||||
],
|
||||
defaultVariants: {
|
||||
size: "md",
|
||||
variant: "default",
|
||||
intent: "default",
|
||||
},
|
||||
});
|
||||
|
||||
type ButtonVariants = VariantProps<typeof button>;
|
||||
|
||||
interface ButtonProps
|
||||
extends Omit<useRender.ComponentProps<"button">, keyof ButtonVariants>,
|
||||
ButtonVariants {}
|
||||
|
||||
export function Button({ render = <button />, ...props }: ButtonProps) {
|
||||
const element = useRender({
|
||||
render,
|
||||
props: mergeProps<"button">(
|
||||
{
|
||||
className: button({
|
||||
size: props.size,
|
||||
variant: props.variant,
|
||||
intent: props.intent,
|
||||
}),
|
||||
},
|
||||
props,
|
||||
),
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
152
packages/quint-ui/src/globals.css
Normal file
152
packages/quint-ui/src/globals.css
Normal file
@@ -0,0 +1,152 @@
|
||||
@import "tailwindcss";
|
||||
@import "tw-animate-css";
|
||||
|
||||
/* Dark mode. If you want to use dark mode, you can add the dark class to the body/head element. */
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
@theme inline {
|
||||
--color-primary: var(--primary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-primary-transparent: var(--primary-transparent);
|
||||
--color-primary-dark: var(--primary-dark);
|
||||
--color-primary-light: var(--primary-light);
|
||||
--color-primary-brightLight: var(--primary-brightLight);
|
||||
--color-primary-brightDark: var(--primary-brightDark);
|
||||
|
||||
--color-alert: var(--alert);
|
||||
--color-alert-foreground: var(--alert-foreground);
|
||||
--color-alert-transparent: var(--alert-transparent);
|
||||
--color-alert-dark: var(--alert-dark);
|
||||
--color-alert-light: var(--alert-light);
|
||||
--color-alert-brightLight: var(--alert-brightLight);
|
||||
--color-alert-brightDark: var(--alert-brightDark);
|
||||
|
||||
--color-success: var(--success);
|
||||
--color-success-foreground: var(--success-foreground);
|
||||
--color-success-transparent: var(--success-transparent);
|
||||
--color-success-dark: var(--success-dark);
|
||||
--color-success-light: var(--success-light);
|
||||
--color-success-brightLight: var(--success-brightLight);
|
||||
--color-success-brightDark: var(--success-brightDark);
|
||||
|
||||
--color-info: var(--info);
|
||||
--color-info-foreground: var(--info-foreground);
|
||||
--color-info-transparent: var(--info-transparent);
|
||||
--color-info-dark: var(--info-dark);
|
||||
--color-info-light: var(--info-light);
|
||||
--color-info-brightLight: var(--info-brightLight);
|
||||
--color-info-brightDark: var(--info-brightDark);
|
||||
|
||||
--color-warning: var(--warning);
|
||||
--color-warning-foreground: var(--warning-foreground);
|
||||
--color-warning-transparent: var(--warning-transparent);
|
||||
--color-warning-light: var(--warning-light);
|
||||
--color-warning-dark: var(--warning-dark);
|
||||
--color-warning-brightLight: var(--warning-brightLight);
|
||||
--color-warning-brightDark: var(--warning-brightDark);
|
||||
|
||||
--color-tip: var(--tip);
|
||||
--color-tip-foreground: var(--tip-foreground);
|
||||
--color-tip-transparent: var(--tip-transparent);
|
||||
--color-tip-dark: var(--tip-dark);
|
||||
--color-tip-light: var(--tip-light);
|
||||
--color-tip-brightLight: var(--tip-brightLight);
|
||||
--color-tip-brightDark: var(--tip-brightDark);
|
||||
|
||||
--color-danger: var(--danger);
|
||||
--color-danger-foreground: var(--danger-foreground);
|
||||
--color-danger-transparent: var(--danger-transparent);
|
||||
--color-danger-dark: var(--danger-dark);
|
||||
--color-danger-light: var(--danger-light);
|
||||
--color-danger-brightLight: var(--danger-brightLight);
|
||||
--color-danger-brightDark: var(--danger-brightDark);
|
||||
}
|
||||
|
||||
:root {
|
||||
--primary: oklch(57.29% 0.235 261.2);
|
||||
--primary-transparent: lch(from var(--color-primary) l c h / 0.1);
|
||||
--primary-dark: lch(
|
||||
from var(--color-primary) calc(l - 10) calc(c - 1) calc(h + 5)
|
||||
);
|
||||
--primary-light: lch(
|
||||
from var(--color-primary) calc(l + 10) calc(c + 1) calc(h - 5)
|
||||
);
|
||||
--primary-brightLight: lch(
|
||||
from var(--color-primary) calc(l - 1) calc(c + 20) calc(h + 5)
|
||||
);
|
||||
--primary-brightDark: lch(
|
||||
from var(--color-primary) calc(l - 6) calc(c + 20) calc(h + 5)
|
||||
);
|
||||
--primary-foreground: oklch(0.985 0.045 264.32);
|
||||
|
||||
--alert: oklch(80.54% 0.169 76.45);
|
||||
--alert-transparent: oklch(0.843 0.222 85.04 / 0.3);
|
||||
--alert-dark: oklch(0.773 0.212 90.04);
|
||||
--alert-light: oklch(0.883 0.232 80.04);
|
||||
--alert-brightLight: oklch(0.833 0.522 100.04);
|
||||
--alert-brightDark: oklch(0.803 0.522 100.04);
|
||||
--alert-foreground: oklch(0.28 0.07 46);
|
||||
|
||||
--success: oklch(70.49% 0.16 150.62);
|
||||
--success-transparent: lch(from var(--color-success) l c h / 0.3);
|
||||
--success-dark: lch(
|
||||
from var(--color-success) calc(l - 7) calc(c - 1) calc(h + 5)
|
||||
);
|
||||
--success-light: lch(
|
||||
from var(--color-success) calc(l + 4) calc(c + 1) calc(h - 5)
|
||||
);
|
||||
--success-brightLight: lch(
|
||||
from var(--color-success) calc(l - 1) calc(c + 20) calc(h + 10)
|
||||
);
|
||||
--success-brightDark: lch(
|
||||
from var(--color-success) calc(l - 6) calc(c + 20) calc(h + 10)
|
||||
);
|
||||
--success-foreground: oklch(0.28 0.07 46);
|
||||
|
||||
--info: oklch(61.13% 0.248 312.2);
|
||||
--info-transparent: oklch(0.514 0.247 291.21 / 0.3);
|
||||
--info-dark: oklch(0.444 0.237 296.21);
|
||||
--info-light: oklch(0.554 0.257 286.21);
|
||||
--info-brightLight: oklch(0.504 0.447 296.21);
|
||||
--info-brightDark: oklch(0.474 0.447 296.21);
|
||||
--info-foreground: oklch(0.28 0.07 46);
|
||||
|
||||
--warning: oklch(68.92% 0.206 39.71);
|
||||
--warning-transparent: oklch(0.661 0.372 75.45 / 0.3);
|
||||
--warning-dark: oklch(0.591 0.362 80.45);
|
||||
--warning-light: oklch(0.701 0.382 70.45);
|
||||
--warning-brightLight: oklch(0.651 0.672 90.45);
|
||||
--warning-brightDark: oklch(0.621 0.672 90.45);
|
||||
--warning-foreground: oklch(0.28 0.07 46);
|
||||
|
||||
--tip: oklch(76.08% 0.122 194.9);
|
||||
--tip-transparent: oklch(0.595 0.317 176.3 / 0.3);
|
||||
--tip-dark: oklch(0.525 0.307 181.3);
|
||||
--tip-light: oklch(0.635 0.327 171.3);
|
||||
--tip-brightLight: oklch(0.585 0.617 186.3);
|
||||
--tip-brightDark: oklch(0.555 0.617 186.3);
|
||||
--tip-foreground: oklch(0.28 0.07 46);
|
||||
|
||||
--danger: oklch(64.11% 0.202 23.95);
|
||||
--danger-transparent: lch(from var(--color-danger) l c h / 0.3);
|
||||
--danger-dark: lch(
|
||||
from var(--color-danger) calc(l - 7) calc(c - 1) calc(h + 5)
|
||||
);
|
||||
--danger-light: lch(
|
||||
from var(--color-danger) calc(l + 4) calc(c + 1) calc(h - 5)
|
||||
);
|
||||
--danger-brightLight: lch(
|
||||
from var(--color-danger) calc(l - 2) calc(c + 20) calc(h + 10)
|
||||
);
|
||||
--danger-brightDark: lch(
|
||||
from var(--color-danger) calc(l - 6) calc(c + 10) calc(h + 10)
|
||||
);
|
||||
--danger-foreground: oklch(0.28 0.07 46);
|
||||
}
|
||||
|
||||
.dark {
|
||||
/*
|
||||
* Dark mode styles.
|
||||
* Here you can override the css variables above for dark mode.
|
||||
*/
|
||||
}
|
||||
5
packages/quint-ui/src/index.ts
Normal file
5
packages/quint-ui/src/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// COMPONENTS
|
||||
export { Button } from "./components/button.js";
|
||||
|
||||
// UTILS
|
||||
export { cn } from "./lib/utils.js";
|
||||
7
packages/quint-ui/src/lib/utils.ts
Normal file
7
packages/quint-ui/src/lib/utils.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { ClassValue } from "clsx";
|
||||
import { clsx } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
21
packages/quint-ui/tsconfig.build.json
Normal file
21
packages/quint-ui/tsconfig.build.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"declaration": true,
|
||||
"jsx": "react-jsx",
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
35
packages/quint-ui/tsconfig.json
Normal file
35
packages/quint-ui/tsconfig.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./*"],
|
||||
"react": ["./node_modules/@types/react"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts",
|
||||
"next.config.mjs"
|
||||
],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
1792
pnpm-lock.yaml
generated
1792
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -8,8 +8,8 @@ catalog:
|
||||
"@biomejs/biome": 1.9.4
|
||||
typescript: 5.6.2
|
||||
vite: 6.3.5
|
||||
vitest: 3.1.3
|
||||
"@vitest/browser": 3.1.3
|
||||
"@vitest/coverage-istanbul": 3.1.3
|
||||
"@vitest/coverage-v8": 3.1.3
|
||||
"@vitest/ui": 3.1.3
|
||||
vitest: 3.2.4
|
||||
"@vitest/browser": 3.2.4
|
||||
"@vitest/coverage-istanbul": 3.2.4
|
||||
"@vitest/coverage-v8": 3.2.4
|
||||
"@vitest/ui": 3.2.4
|
||||
|
||||
@@ -33,7 +33,7 @@ describe("Images upload", () => {
|
||||
|
||||
await userEvent.upload(
|
||||
page.getByRole("textbox"),
|
||||
"./fixtures/jazz-icon.png",
|
||||
"./src/fixtures/jazz-icon.png",
|
||||
);
|
||||
|
||||
assert(file);
|
||||
|
||||
8
tests/cloudflare-workers/vitest.config.ts
Normal file
8
tests/cloudflare-workers/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { defineProject } from "vitest/config";
|
||||
|
||||
export default defineProject({
|
||||
test: {
|
||||
name: "cloudflare-workers",
|
||||
testTimeout: 10_000,
|
||||
},
|
||||
});
|
||||
@@ -9,22 +9,6 @@ export default defineConfig({
|
||||
"tests/browser-integration",
|
||||
"tests/cloudflare-workers",
|
||||
],
|
||||
coverage: {
|
||||
enabled: false,
|
||||
provider: "istanbul",
|
||||
include: ["packages/*/src/**/*.ts"],
|
||||
exclude: ["packages/*/src/tests", "packages/jazz-svelte/**"],
|
||||
reporter: ["html"],
|
||||
thresholds: {
|
||||
global: {
|
||||
branches: 80,
|
||||
functions: 80,
|
||||
lines: 80,
|
||||
statements: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
include: ["packages/*/tests/**/*.test.{js,ts,svelte}"],
|
||||
maxConcurrency: 5,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user