Compare commits
22 Commits
jazz-react
...
jazz-bette
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ceaa555e83 | ||
|
|
03229b2ea9 | ||
|
|
e2737d44b6 | ||
|
|
4b73834883 | ||
|
|
1b3d43d5f4 | ||
|
|
9c9a689879 | ||
|
|
2fd88b938c | ||
|
|
d1f955006f | ||
|
|
bb3d5f1f87 | ||
|
|
26ce61ab78 | ||
|
|
1f300114d5 | ||
|
|
da69f812f8 | ||
|
|
0bcbf551ca | ||
|
|
6b3d5b5560 | ||
|
|
d1bdbf5d49 | ||
|
|
9b22fc74cd | ||
|
|
1bebe3c6c8 | ||
|
|
e1bd16d08b | ||
|
|
0967c2ee5a | ||
|
|
72b5542130 | ||
|
|
5fd9225a54 | ||
|
|
9138d30208 |
@@ -1,5 +1,14 @@
|
||||
# passkey-svelte
|
||||
|
||||
## 0.0.114
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [0bcbf55]
|
||||
- Updated dependencies [d1bdbf5]
|
||||
- Updated dependencies [4b73834]
|
||||
- jazz-tools@0.17.1
|
||||
|
||||
## 0.0.113
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-svelte",
|
||||
"version": "0.0.113",
|
||||
"version": "0.0.114",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"@vitest/coverage-v8": "catalog:",
|
||||
"@vitest/ui": "catalog:",
|
||||
"happy-dom": "^17.4.4",
|
||||
"jazz-run": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"lefthook": "^1.8.2",
|
||||
"pkg-pr-new": "^0.0.39",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# cojson-storage-indexeddb
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2fd88b9]
|
||||
- cojson@0.17.1
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cojson-storage-indexeddb",
|
||||
"version": "0.17.0",
|
||||
"version": "0.17.1",
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"types": "dist/index.d.ts",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# cojson-storage-sqlite
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2fd88b9]
|
||||
- cojson@0.17.1
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "cojson-storage-sqlite",
|
||||
"type": "module",
|
||||
"version": "0.17.0",
|
||||
"version": "0.17.1",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# cojson-transport-nodejs-ws
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2fd88b9]
|
||||
- cojson@0.17.1
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "cojson-transport-ws",
|
||||
"type": "module",
|
||||
"version": "0.17.0",
|
||||
"version": "0.17.1",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# cojson
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2fd88b9: Add debug info to sync correction errors
|
||||
|
||||
## 0.17.0
|
||||
|
||||
## 0.16.6
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "0.17.0",
|
||||
"version": "0.17.1",
|
||||
"devDependencies": {
|
||||
"@opentelemetry/sdk-metrics": "^2.0.0",
|
||||
"libsql": "^0.5.13",
|
||||
|
||||
@@ -84,3 +84,10 @@ export function getContentMessageSize(msg: NewContentMessage) {
|
||||
);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
export function getContenDebugInfo(msg: NewContentMessage) {
|
||||
return Object.entries(msg.new).map(
|
||||
([sessionID, sessionNewContent]) =>
|
||||
`Session: ${sessionID} After: ${sessionNewContent.after} New: ${sessionNewContent.newTransactions.length}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -208,7 +208,6 @@ export class StorageApiSync implements StorageAPI {
|
||||
if (!correction) {
|
||||
logger.error("Correction callback returned undefined", {
|
||||
knownState,
|
||||
correction: correction ?? null,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Histogram, ValueType, metrics } from "@opentelemetry/api";
|
||||
import { PeerState } from "./PeerState.js";
|
||||
import { SyncStateManager } from "./SyncStateManager.js";
|
||||
import {
|
||||
getContenDebugInfo,
|
||||
getTransactionSize,
|
||||
knownStateFromContent,
|
||||
} from "./coValueContentMessage.js";
|
||||
@@ -673,6 +674,8 @@ export class SyncManager {
|
||||
"Invalid state assumed when handling new content from storage",
|
||||
{
|
||||
id: msg.id,
|
||||
content: getContenDebugInfo(msg),
|
||||
knownState: coValue.knownState(),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -803,7 +806,20 @@ export class SyncManager {
|
||||
// Try to store the content as-is for performance
|
||||
// In case that some transactions are missing, a correction will be requested, but it's an edge case
|
||||
storage.store(content, (correction) => {
|
||||
return value.verified?.newContentSince(correction);
|
||||
if (!value.verified) {
|
||||
logger.error(
|
||||
"Correction requested for a CoValue with no verified content",
|
||||
{
|
||||
id: content.id,
|
||||
content: getContenDebugInfo(content),
|
||||
correction,
|
||||
state: value.loadingState,
|
||||
},
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return value.verified.newContentSince(correction);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -382,7 +382,6 @@ describe("StorageApiSync", () => {
|
||||
"Correction callback returned undefined",
|
||||
{
|
||||
knownState: expect.any(Object),
|
||||
correction: null,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -413,7 +412,6 @@ describe("StorageApiSync", () => {
|
||||
"Correction callback returned undefined",
|
||||
{
|
||||
knownState: expect.any(Object),
|
||||
correction: null,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# jazz-auth-betterauth
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [0bcbf55]
|
||||
- Updated dependencies [2fd88b9]
|
||||
- Updated dependencies [d1bdbf5]
|
||||
- Updated dependencies [4b73834]
|
||||
- jazz-tools@0.17.1
|
||||
- cojson@0.17.1
|
||||
- jazz-betterauth-client-plugin@0.17.1
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-auth-betterauth",
|
||||
"version": "0.17.0",
|
||||
"version": "0.17.1",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# jazz-betterauth-client-plugin
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-betterauth-server-plugin@0.17.1
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-betterauth-client-plugin",
|
||||
"version": "0.17.0",
|
||||
"version": "0.17.1",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# jazz-betterauth-server-plugin
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [0bcbf55]
|
||||
- Updated dependencies [2fd88b9]
|
||||
- Updated dependencies [d1bdbf5]
|
||||
- Updated dependencies [4b73834]
|
||||
- jazz-tools@0.17.1
|
||||
- cojson@0.17.1
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-betterauth-server-plugin",
|
||||
"version": "0.17.0",
|
||||
"version": "0.17.1",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# jazz-react-auth-betterauth
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [0bcbf55]
|
||||
- Updated dependencies [2fd88b9]
|
||||
- Updated dependencies [d1bdbf5]
|
||||
- Updated dependencies [4b73834]
|
||||
- jazz-tools@0.17.1
|
||||
- cojson@0.17.1
|
||||
- jazz-auth-betterauth@0.17.1
|
||||
- jazz-betterauth-client-plugin@0.17.1
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-react-auth-betterauth",
|
||||
"version": "0.17.0",
|
||||
"version": "0.17.1",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.tsx",
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# jazz-run
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [0bcbf55]
|
||||
- Updated dependencies [2fd88b9]
|
||||
- Updated dependencies [d1bdbf5]
|
||||
- Updated dependencies [4b73834]
|
||||
- jazz-tools@0.17.1
|
||||
- cojson@0.17.1
|
||||
- cojson-storage-sqlite@0.17.1
|
||||
- cojson-transport-ws@0.17.1
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"bin": "./dist/index.js",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "0.17.0",
|
||||
"version": "0.17.1",
|
||||
"exports": {
|
||||
"./startSyncServer": {
|
||||
"types": "./dist/startSyncServer.d.ts",
|
||||
@@ -28,11 +28,11 @@
|
||||
"@effect/printer-ansi": "^0.34.5",
|
||||
"@effect/schema": "^0.71.1",
|
||||
"@effect/typeclass": "^0.25.5",
|
||||
"cojson": "workspace:0.17.0",
|
||||
"cojson-storage-sqlite": "workspace:0.17.0",
|
||||
"cojson-transport-ws": "workspace:0.17.0",
|
||||
"cojson": "workspace:0.17.1",
|
||||
"cojson-storage-sqlite": "workspace:0.17.1",
|
||||
"cojson-transport-ws": "workspace:0.17.1",
|
||||
"effect": "^3.6.5",
|
||||
"jazz-tools": "workspace:0.17.0",
|
||||
"jazz-tools": "workspace:0.17.1",
|
||||
"ws": "^8.14.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# jazz-tools
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 0bcbf55: Export the HttpRoute type
|
||||
- d1bdbf5: fix: ensure file downloaded in loadImageBySize
|
||||
- 4b73834: fix(jazz-tools/svelte): Make Image reactive to imageId change
|
||||
- Updated dependencies [2fd88b9]
|
||||
- cojson@0.17.1
|
||||
- cojson-storage-indexeddb@0.17.1
|
||||
- cojson-transport-ws@0.17.1
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
},
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "0.17.0",
|
||||
"version": "0.17.1",
|
||||
"dependencies": {
|
||||
"@manuscripts/prosemirror-recreate-steps": "^0.1.4",
|
||||
"@scure/base": "1.2.1",
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { Account, FileStream, ImageDefinition } from "jazz-tools";
|
||||
import { highestResAvailable, loadImageBySize } from "jazz-tools/media";
|
||||
import { createJazzTestAccount, setupJazzTestSync } from "jazz-tools/testing";
|
||||
import { Account, FileStream, Group, ImageDefinition } from "jazz-tools";
|
||||
import {
|
||||
createJazzTestAccount,
|
||||
setActiveAccount,
|
||||
setupJazzTestSync,
|
||||
} from "jazz-tools/testing";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { highestResAvailable, loadImageBySize } from "./utils.js";
|
||||
|
||||
const createFileStream = (account: any, blobSize?: number) => {
|
||||
return FileStream.createFromBlob(
|
||||
@@ -209,23 +213,21 @@ describe("highestResAvailable", async () => {
|
||||
describe("loadImageBySize", async () => {
|
||||
let account: Account;
|
||||
beforeEach(async () => {
|
||||
account = await createJazzTestAccount({
|
||||
isCurrentActiveAccount: true,
|
||||
});
|
||||
vi.spyOn(Account, "getMe").mockReturnValue(account);
|
||||
await setupJazzTestSync();
|
||||
account = await setupJazzTestSync();
|
||||
setActiveAccount(account);
|
||||
});
|
||||
|
||||
const createImageDef = async (
|
||||
sizes: Array<[number, number]>,
|
||||
progressive = true,
|
||||
owner: Account | Group = account,
|
||||
) => {
|
||||
if (sizes.length === 0) throw new Error("sizes array must not be empty");
|
||||
|
||||
const originalSize = sizes[sizes.length - 1]!;
|
||||
sizes = sizes.slice(0, -1);
|
||||
|
||||
const original = await createFileStream(account, 1);
|
||||
const original = await createFileStream(owner, 1);
|
||||
// Ensure sizes array is not empty
|
||||
const imageDef = ImageDefinition.create(
|
||||
{
|
||||
@@ -233,14 +235,14 @@ describe("loadImageBySize", async () => {
|
||||
progressive,
|
||||
original,
|
||||
},
|
||||
{ owner: account },
|
||||
{ owner },
|
||||
);
|
||||
imageDef[`${originalSize[0]}x${originalSize[1]}`] = original;
|
||||
|
||||
for (const size of sizes) {
|
||||
if (!size) continue;
|
||||
const [w, h] = size;
|
||||
imageDef[`${w}x${h}`] = await createFileStream(account, 1);
|
||||
imageDef[`${w}x${h}`] = await createFileStream(owner, 1);
|
||||
}
|
||||
return imageDef;
|
||||
};
|
||||
@@ -251,6 +253,24 @@ describe("loadImageBySize", async () => {
|
||||
expect(result?.image.id).toBe(imageDef["1920x1080"]!.id);
|
||||
});
|
||||
|
||||
it("returns the original image already loaded", async () => {
|
||||
const account = await setupJazzTestSync({ asyncPeers: true });
|
||||
const account2 = await createJazzTestAccount();
|
||||
|
||||
setActiveAccount(account);
|
||||
|
||||
const group = Group.create();
|
||||
group.addMember("everyone", "reader");
|
||||
|
||||
const imageDef = await createImageDef([[1920, 1080]], false, group);
|
||||
setActiveAccount(account2);
|
||||
|
||||
const result = await loadImageBySize(imageDef, 256, 256);
|
||||
expect(result?.image.id).toBe(imageDef["1920x1080"]!.id);
|
||||
expect(result?.image.isBinaryStreamEnded()).toBe(true);
|
||||
expect(result?.image.asBase64()).toStrictEqual(expect.any(String));
|
||||
});
|
||||
|
||||
it("returns null if no sizes are available", async () => {
|
||||
const original = await createFileStream(account._owner, 1);
|
||||
const imageDef = ImageDefinition.create(
|
||||
@@ -324,4 +344,30 @@ describe("loadImageBySize", async () => {
|
||||
expect(result?.width).toBe(1024);
|
||||
expect(result?.height).toBe(1024);
|
||||
});
|
||||
|
||||
it("returns the image already loaded", async () => {
|
||||
const account = await setupJazzTestSync({ asyncPeers: true });
|
||||
const account2 = await createJazzTestAccount();
|
||||
|
||||
setActiveAccount(account);
|
||||
|
||||
const group = Group.create();
|
||||
group.addMember("everyone", "reader");
|
||||
|
||||
const imageDef = await createImageDef(
|
||||
[
|
||||
[512, 512],
|
||||
[1024, 1024],
|
||||
],
|
||||
undefined,
|
||||
group,
|
||||
);
|
||||
|
||||
setActiveAccount(account2);
|
||||
|
||||
const result = await loadImageBySize(imageDef, 1024, 1024);
|
||||
expect(result?.image.id).toBe(imageDef["1024x1024"]!.id);
|
||||
expect(result?.image.isBinaryStreamEnded()).toBe(true);
|
||||
expect(result?.image.asBase64()).toStrictEqual(expect.any(String));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -126,21 +126,22 @@ export async function loadImage(
|
||||
};
|
||||
}
|
||||
|
||||
await imageOrId.ensureLoaded({
|
||||
resolve: {
|
||||
original: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!imageOrId.original) {
|
||||
console.warn("Unable to find the original image");
|
||||
return null;
|
||||
}
|
||||
|
||||
const loadedOriginal = await FileStream.load(imageOrId.original.id);
|
||||
|
||||
if (!loadedOriginal) {
|
||||
console.warn("Unable to find the original image");
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
width: imageOrId.originalSize[0],
|
||||
height: imageOrId.originalSize[1],
|
||||
image: imageOrId.original,
|
||||
image: loadedOriginal,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -149,7 +150,7 @@ export async function loadImageBySize(
|
||||
wantedWidth: number,
|
||||
wantedHeight: number,
|
||||
): Promise<{ width: number; height: number; image: FileStream } | null> {
|
||||
const image =
|
||||
const image: ImageDefinition | null =
|
||||
typeof imageOrId === "string"
|
||||
? await ImageDefinition.load(imageOrId)
|
||||
: imageOrId;
|
||||
@@ -184,19 +185,21 @@ export async function loadImageBySize(
|
||||
const bestTarget =
|
||||
sortedSizes.find((el) => el.match > 0.95) || sortedSizes.at(-1)!;
|
||||
|
||||
const deepLoaded = await ImageDefinition.load(image.id, {
|
||||
resolve: {
|
||||
[bestTarget.size[2]]: true,
|
||||
},
|
||||
});
|
||||
const file = image[bestTarget.size[2]];
|
||||
|
||||
if (deepLoaded === null || deepLoaded[bestTarget.size[2]] === undefined) {
|
||||
if (!file) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const loadedFile = await FileStream.load(file.id);
|
||||
|
||||
if (!loadedFile) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
width: bestTarget.size[0],
|
||||
height: bestTarget.size[1],
|
||||
image: deepLoaded[bestTarget.size[2]]!,
|
||||
image: loadedFile,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ interface ImageProps extends Omit<HTMLImgAttributes, "width" | "height"> {
|
||||
|
||||
const { imageId, width, height, ...rest }: ImageProps = $props();
|
||||
|
||||
const imageState = new CoState(ImageDefinition, imageId);
|
||||
const imageState = new CoState(ImageDefinition, () => imageId);
|
||||
let lastBestImage: [string, string] | null = null;
|
||||
|
||||
/**
|
||||
|
||||
@@ -330,7 +330,7 @@ function parseSchemaAndResolve<
|
||||
};
|
||||
}
|
||||
|
||||
class HttpRoute<
|
||||
export class HttpRoute<
|
||||
RequestShape extends MessageShape = z.core.$ZodLooseShape,
|
||||
RequestResolve extends ResolveQuery<CoMapSchema<RequestShape>> = any,
|
||||
ResponseShape extends MessageShape = z.core.$ZodLooseShape,
|
||||
|
||||
@@ -113,4 +113,5 @@ export {
|
||||
experimental_defineRequest,
|
||||
JazzRequestError,
|
||||
isJazzRequestError,
|
||||
type HttpRoute,
|
||||
} from "./coValues/request.js";
|
||||
|
||||
63
packages/quint-ui/app/docs/input/page.tsx
Normal file
63
packages/quint-ui/app/docs/input/page.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import Input from "@/src/components/input";
|
||||
import Label from "@/src/components/label";
|
||||
import { SearchIcon } from "lucide-react";
|
||||
|
||||
export default function InputPage() {
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
<h2 className="text-2xl mb-2 font-bold">Input</h2>
|
||||
<p className="mb-3">
|
||||
Inputs are used in conjunction with a label and can be styled with the
|
||||
intent and size props.
|
||||
</p>
|
||||
<div className="flex flex-row gap-2">
|
||||
<Label htmlFor="input">Label</Label>
|
||||
<Input id="input" />
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<Label htmlFor="input">Label</Label>
|
||||
<Input id="input" intent="primary" />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row gap-2">
|
||||
<Label htmlFor="input" size="sm">
|
||||
Label
|
||||
</Label>
|
||||
<Input id="input" intent="tip" sizeStyle="sm" />
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<Label htmlFor="input" size="sm">
|
||||
Label
|
||||
</Label>
|
||||
<Input id="input" intent="info" sizeStyle="sm" />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row gap-2">
|
||||
<Label htmlFor="input" size="lg">
|
||||
Label
|
||||
</Label>
|
||||
<Input id="input" intent="warning" sizeStyle="lg" />
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<Label htmlFor="input" size="lg">
|
||||
Label
|
||||
</Label>
|
||||
<Input id="input" intent="danger" sizeStyle="lg" />
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Labels should alway be used with an input, but can be hidden with the
|
||||
isHiddenVisually prop.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-row gap-2 items-center">
|
||||
<Label htmlFor="input" isHiddenVisually>
|
||||
Label
|
||||
</Label>
|
||||
<SearchIcon />
|
||||
|
||||
<Input id="input" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -8,6 +8,7 @@ export default function DocsPage() {
|
||||
<li>
|
||||
<Link href="/docs/button">Button</Link>
|
||||
<Link href="/docs/icon">Icon</Link>
|
||||
<Link href="/docs/input">Input</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
39
packages/quint-ui/src/components/input.tsx
Normal file
39
packages/quint-ui/src/components/input.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import { Input as BaseUiInput } from "@base-ui-components/react/input";
|
||||
import * as React from "react";
|
||||
import { ComponentProps } from "react";
|
||||
import { VariantProps, tv } from "tailwind-variants";
|
||||
|
||||
type InputVariants = VariantProps<typeof input>;
|
||||
|
||||
interface InputProps extends ComponentProps<"input">, InputVariants {}
|
||||
|
||||
export default function Input({ sizeStyle, intent, ...props }: InputProps) {
|
||||
return <BaseUiInput className={input({ sizeStyle, intent })} {...props} />;
|
||||
}
|
||||
|
||||
const input = tv({
|
||||
base: "w-full rounded-md border pl-3.5 text-base text-gray-900",
|
||||
variants: {
|
||||
base: "w-full rounded-md border px-2.5 py-1 shadow-sm h-[36px] font-medium text-stone-900 dark:text-white dark:bg-stone-925",
|
||||
intent: {
|
||||
default: "border-stone-500/50 focus:ring-stone-800/50",
|
||||
primary: "border-primary focus:ring-blue/50",
|
||||
success: "border-success focus:ring-green/50",
|
||||
warning: "border-warning focus:ring-yellow/50",
|
||||
danger: "border-danger focus:ring-red/50",
|
||||
info: "border-info focus:ring-blue/50",
|
||||
tip: "border-tip focus:ring-cyan/50",
|
||||
muted: "border-muted focus:ring-gray/50",
|
||||
strong: "border-strong focus:ring-stone-900/50",
|
||||
},
|
||||
sizeStyle: {
|
||||
sm: "text-sm py-1 px-2 [&>svg]:size-4 h-7",
|
||||
md: "py-1.5 px-3 h-[36px] [&>svg]:size-5 h-9",
|
||||
lg: "py-2 px-5 md:px-6 md:py-2.5 [&>svg]:size-6 h-10",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
sizeStyle: "md",
|
||||
intent: "default",
|
||||
},
|
||||
});
|
||||
45
packages/quint-ui/src/components/label.tsx
Normal file
45
packages/quint-ui/src/components/label.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import { ComponentProps } from "react";
|
||||
import { VariantProps, tv } from "tailwind-variants";
|
||||
// biome-ignore lint/correctness/useImportExtensions: <explanation>
|
||||
import { cn } from "../lib/utils";
|
||||
|
||||
type LabelVariants = VariantProps<typeof label>;
|
||||
|
||||
interface LabelProps extends ComponentProps<"label">, LabelVariants {}
|
||||
|
||||
export default function Label({
|
||||
size,
|
||||
isHiddenVisually,
|
||||
...props
|
||||
}: LabelProps) {
|
||||
return (
|
||||
<label
|
||||
className={cn(
|
||||
label({
|
||||
isHiddenVisually: isHiddenVisually,
|
||||
size: size,
|
||||
}),
|
||||
props.className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const label = tv({
|
||||
base: "block text-sm font-medium text-stone-900 dark:text-white flex items-center",
|
||||
variants: {
|
||||
isHiddenVisually: {
|
||||
true: "sr-only",
|
||||
},
|
||||
size: {
|
||||
sm: "text-sm",
|
||||
md: "text-base",
|
||||
lg: "text-lg",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
size: "md",
|
||||
isHiddenVisually: false,
|
||||
},
|
||||
});
|
||||
11
pnpm-lock.yaml
generated
11
pnpm-lock.yaml
generated
@@ -67,6 +67,9 @@ importers:
|
||||
happy-dom:
|
||||
specifier: ^17.4.4
|
||||
version: 17.4.4
|
||||
jazz-run:
|
||||
specifier: workspace:*
|
||||
version: link:packages/jazz-run
|
||||
jazz-tools:
|
||||
specifier: workspace:*
|
||||
version: link:packages/jazz-tools
|
||||
@@ -1851,19 +1854,19 @@ importers:
|
||||
specifier: ^0.25.5
|
||||
version: 0.25.8(effect@3.11.9)
|
||||
cojson:
|
||||
specifier: workspace:0.17.0
|
||||
specifier: workspace:0.17.1
|
||||
version: link:../cojson
|
||||
cojson-storage-sqlite:
|
||||
specifier: workspace:0.17.0
|
||||
specifier: workspace:0.17.1
|
||||
version: link:../cojson-storage-sqlite
|
||||
cojson-transport-ws:
|
||||
specifier: workspace:0.17.0
|
||||
specifier: workspace:0.17.1
|
||||
version: link:../cojson-transport-ws
|
||||
effect:
|
||||
specifier: ^3.6.5
|
||||
version: 3.11.9
|
||||
jazz-tools:
|
||||
specifier: workspace:0.17.0
|
||||
specifier: workspace:0.17.1
|
||||
version: link:../jazz-tools
|
||||
ws:
|
||||
specifier: ^8.14.2
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# jazz-react-tailwind-starter
|
||||
|
||||
## 0.0.145
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [0bcbf55]
|
||||
- Updated dependencies [d1bdbf5]
|
||||
- Updated dependencies [4b73834]
|
||||
- jazz-tools@0.17.1
|
||||
|
||||
## 0.0.144
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-react-passkey-auth-starter",
|
||||
"private": true,
|
||||
"version": "0.0.144",
|
||||
"version": "0.0.145",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# svelte-passkey-auth
|
||||
|
||||
## 0.0.119
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [0bcbf55]
|
||||
- Updated dependencies [d1bdbf5]
|
||||
- Updated dependencies [4b73834]
|
||||
- jazz-tools@0.17.1
|
||||
|
||||
## 0.0.118
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "svelte-passkey-auth",
|
||||
"version": "0.0.118",
|
||||
"version": "0.0.119",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
<a href="/costate">CoState</a>
|
||||
<a href="/media">Media</a>
|
||||
<a href="/virtual-list">Virtual List</a>
|
||||
|
||||
22
tests/jazz-svelte/src/routes/media/+layout.svelte
Normal file
22
tests/jazz-svelte/src/routes/media/+layout.svelte
Normal file
@@ -0,0 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { JazzSvelteProvider } from 'jazz-tools/svelte';
|
||||
import "jazz-tools/inspector/register-custom-element"
|
||||
import { TestAccount } from './schema.js';
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.clear(); // Want to start always from a fresh account
|
||||
}
|
||||
|
||||
let { children } = $props();
|
||||
|
||||
</script>
|
||||
|
||||
<JazzSvelteProvider
|
||||
AccountSchema={TestAccount}
|
||||
sync={{
|
||||
when: "never"
|
||||
}}
|
||||
>
|
||||
<jazz-inspector></jazz-inspector>
|
||||
{@render children()}
|
||||
</JazzSvelteProvider>
|
||||
63
tests/jazz-svelte/src/routes/media/+page.svelte
Normal file
63
tests/jazz-svelte/src/routes/media/+page.svelte
Normal file
@@ -0,0 +1,63 @@
|
||||
<script lang="ts">
|
||||
import type { ChangeEventHandler } from 'svelte/elements';
|
||||
import { AccountCoState, Image } from 'jazz-tools/svelte';
|
||||
import { createImage } from 'jazz-tools/media';
|
||||
import { TestAccount } from './schema.js';
|
||||
|
||||
const me = new AccountCoState(TestAccount, {
|
||||
resolve: {
|
||||
profile: {
|
||||
image: true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let input = $state<HTMLInputElement>();
|
||||
|
||||
const onUploadClick = () => {
|
||||
input?.click();
|
||||
};
|
||||
|
||||
const onImageChange: ChangeEventHandler<HTMLInputElement> = (event) => {
|
||||
const file = event.currentTarget.files?.[0];
|
||||
if (!file || !me.current?.profile) return;
|
||||
createImage(file, {
|
||||
owner: me.current?.profile._owner,
|
||||
maxSize: 400
|
||||
}).then((image) => {
|
||||
if (!me.current?.profile) return;
|
||||
me.current.profile.image = image;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<button onclick={onUploadClick}>
|
||||
{me.current?.profile?.image ? 'Change image' : 'Send image'}
|
||||
</button>
|
||||
|
||||
{#if me.current?.profile?.image}
|
||||
<Image imageId={me.current.profile.image.id} width={200} height="original" />
|
||||
{/if}
|
||||
|
||||
<label>
|
||||
<input
|
||||
bind:this={input}
|
||||
type="file"
|
||||
accept="image/png, image/jpeg, image/gif"
|
||||
onchange={onImageChange}
|
||||
/>
|
||||
</label>
|
||||
|
||||
<style>
|
||||
label {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border-width: 0;
|
||||
}
|
||||
</style>
|
||||
10
tests/jazz-svelte/src/routes/media/schema.ts
Normal file
10
tests/jazz-svelte/src/routes/media/schema.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { co } from "jazz-tools";
|
||||
|
||||
export const Profile = co.profile({
|
||||
image: co.optional(co.image()),
|
||||
});
|
||||
|
||||
export const TestAccount = co.account({
|
||||
profile: Profile,
|
||||
root: co.map({}),
|
||||
});
|
||||
Reference in New Issue
Block a user