From e4e0de85c53d4cd441f9166d87679a267d047427 Mon Sep 17 00:00:00 2001
From: Kevin Longe <273747162+kvlonge@users.noreply.github.com>
Date: Sat, 7 Nov 2026 08:52:27 +0000
Subject: [PATCH] playground: show the examples as chips grouped by what
SQLQuack does
The six examples were hidden in a dropdown. They are now buttons above
the editor, in three groups that echo the tagline: "Runs it" (verified
results), "Catches the mistake" and "Says no, clearly" (a clear no).
Each chip names the stage where its example stops; the test derives
each example's actual stop stage from the engine and, for the ones
that translate, a DuckDB-WASM run, and fails when a label drifts.
A click loads and runs the example, marks the chip pressed and puts
?example= in the address with history.replaceState, so each
example can be shared. A link with a slug, or an earlier example key,
opens that example; an unknown one opens the default. Editing the SQL
clears the chip and the slug.
---
website/public/playground/examples.js | 36 ++++++++++
website/public/playground/index.html | 14 +---
website/public/playground/playground.js | 62 ++++++++++++++---
website/public/styles.css | 89 ++++++++++++++++++++++++-
website/tests/playground.test.mjs | 45 ++++++++-----
5 files changed, 209 insertions(+), 37 deletions(-)
diff --git a/website/public/playground/examples.js b/website/public/playground/examples.js
index 66c294d93..89a02049e 100644
--- a/website/public/playground/examples.js
+++ b/website/public/playground/examples.js
@@ -86,6 +86,42 @@ FROM orders`,
FROM orders`,
};
+// The example chips above the editor, grouped by what SQLQuack does with them. `slug` is the
+// example's `?example=` link and `stops` the stage where its run stops (null when all four pass);
+// tests/playground.test.mjs checks each `stops` against the engine and DuckDB-WASM.
+export const EXAMPLE_GROUPS = [
+ {
+ title: 'Runs it',
+ tagline: 'verified results',
+ examples: [
+ { key: 'valid', slug: 'converts-and-runs', name: 'Converts and runs', stops: null },
+ { key: 'decimal', slug: 'decimal-division', name: 'Decimal division', stops: null },
+ ],
+ },
+ {
+ title: 'Catches the mistake',
+ tagline: 'a clear no',
+ examples: [
+ { key: 'syntax', slug: 'syntax-error', name: 'Syntax error', stops: 'parse' },
+ { key: 'rejected', slug: 'snowflake-rejects-it', name: 'Snowflake rejects it', stops: 'checks' },
+ { key: 'unknown', slug: 'unknown-column', name: 'Unknown column', stops: 'checks' },
+ ],
+ },
+ {
+ title: 'Says no, clearly',
+ tagline: 'a clear no',
+ examples: [{ key: 'refused', slug: 'translation-refused', name: 'Translation refused', stops: 'translate' }],
+ },
+];
+
+export const STOP_LABELS = {
+ parse: 'stops at Parse',
+ checks: 'stops at Check',
+ translate: 'stops at Translate',
+ run: 'stops at Run',
+};
+export const stopLabel = (stops) => (stops ? STOP_LABELS[stops] : 'all four pass');
+
// Shown under the editor while an example is loaded and unedited.
export const CAPTIONS = {
refused:
diff --git a/website/public/playground/index.html b/website/public/playground/index.html
index 387a8e4f1..ba67fd8e8 100644
--- a/website/public/playground/index.html
+++ b/website/public/playground/index.html
@@ -66,20 +66,10 @@ Playground
your browser. Each stage passes or fails on its own, so you can see which step stopped and where.
+