Skip to content

feat: Improved color scales + example app - #565

Merged
ilyabo merged 2 commits into
mainfrom
feat/improved-colorscales
Apr 25, 2026
Merged

ilyabo merged 2 commits into
mainfrom
feat/improved-colorscales

Conversation

@ilyabo

@ilyabo ilyabo commented Apr 25, 2026 •

Copy link
Copy Markdown
Collaborator
image

Summary by CodeRabbit

  • New Features

    • Added a new color-scales example application demonstrating multiple legend rendering styles: sequential, diverging, quantile, quantize, threshold, and categorical legends loaded from a sample dataset.
    • Enhanced color legend component with customizable width and swatch column options for flexible legend presentation and styling.
  • Documentation

    • Updated color-scales package documentation with expanded legend model descriptions and detailed rendering specifications.

@coderabbitai

coderabbitai Bot commented Apr 25, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@ilyabo has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 28 minutes and 17 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 28 minutes and 17 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c0d8fbdb-ba8a-433a-87a2-4229ab40f133

📥 Commits

Reviewing files that changed from the base of the PR and between 93fc5fd and c13ad93.

📒 Files selected for processing (3)
  • packages/color-scales/src/legend/LegendTicks.tsx
  • packages/color-scales/src/legend/SteppedLegend.tsx
  • packages/color-scales/src/legend/utils.ts
📝 Walkthrough

Walkthrough

This PR introduces a new Vite + React example application demonstrating color scale legends, adds five specialized legend rendering components (continuous, stepped, categorical with tick positioning), updates the ColorScaleLegend component with new sizing props, enhances README documentation, and extends the legend configuration type system to support tick data for stepped legends.

Changes

Cohort / File(s) Summary
Example App Configuration
examples/color-scales/README.md, examples/color-scales/eslint.config.js, examples/color-scales/index.html, examples/color-scales/package.json, examples/color-scales/tsconfig*.json, examples/color-scales/vite.config.ts
Establishes new Vite + React TypeScript example project structure with ESLint, TypeScript, and Tailwind configuration.
Example App Source Code
examples/color-scales/src/main.tsx, examples/color-scales/src/room.tsx, examples/color-scales/src/index.css, examples/color-scales/src/vite-env.d.ts
Implements example application that loads cars.parquet dataset into DuckDB, generates multiple color scale legend variations, and renders them in a responsive grid with theme switching.
Color Scales Library - Documentation
packages/color-scales/README.md
Expands legend documentation with visual semantics for legend variants and introduces optional width and swatchColumns props with usage examples.
Color Scales Library - Legend Components
packages/color-scales/src/legend/CategoricalLegend.tsx, packages/color-scales/src/legend/ContinuousLegend.tsx, packages/color-scales/src/legend/SteppedLegend.tsx, packages/color-scales/src/legend/LegendTicks.tsx, packages/color-scales/src/legend/utils.ts
Introduces specialized legend rendering components with tick positioning logic, overlap detection, and utility functions (rgba formatter, getRampStyle, LegendTick type).
Color Scales Library - Core Updates
packages/color-scales/src/ColorScaleLegend.tsx, packages/color-scales/src/config.ts, packages/color-scales/src/scale.ts
Refactors ColorScaleLegend to delegate rendering to subcomponents, adds optional ticks field to stepped legend config, and generates stepped legend ticks from scale bins.

Sequence Diagram

sequenceDiagram
    participant Browser as Browser/UI
    participant Room as Room Component
    participant RoomStore as Room Store
    participant DuckDB as DuckDB
    participant LegendBuilder as Legend Builder
    participant Legends as Legend Components

    Browser->>Room: Mount Room component
    Room->>RoomStore: Initialize store with cars.parquet
    RoomStore->>DuckDB: Load parquet dataset
    DuckDB-->>RoomStore: cars table ready
    Room->>DuckDB: Query cars table
    DuckDB-->>Room: Query results
    Room->>LegendBuilder: Build color scale legends<br/>(sequential, diverging, etc.)
    LegendBuilder-->>Room: Resolved legend configs
    Room->>Legends: Render ColorScaleLegend<br/>+ ContinuousLegend<br/>+ SteppedLegend<br/>+ CategoricalLegend
    Legends->>Legends: Position ticks,<br/>detect overlap,<br/>build swatches
    Legends-->>Browser: Render legend UI +<br/>colored sample rows
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • bdjulbic
  • mihajlo-stojkovic

Poem

🐰 Whiskers twitching with delight,
New legends bloom in colors bright!
Continuous ramps and stepped scales dance,
While categorical swatches prance.
DuckDB's cars now show their hue,
A rainbow palette born anew! 🎨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: Improved color scales + example app' accurately summarizes the main changes: enhancements to color scale functionality and a new example application demonstrating it.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/improved-colorscales

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (4)
examples/color-scales/README.md (1)

17-20: Consider documenting pnpm instead of npm for in-repo usage.

This monorepo uses pnpm with workspace:* links, and per the repo's guidance the example must be run after pnpm build from the repo root (e.g., pnpm dev color-scales-example). Running npm install inside examples/color-scales will not resolve those workspace dependencies the same way. Other examples in the repo also document pnpm install && pnpm dev for the in-repo flow.

If this README is intended for users scaffolding a standalone copy via giget (where deps are real published versions), the npm form is fine — in that case it might be worth a one-line note clarifying the two contexts.

📝 Suggested doc tweak
 ## Running locally

+From the repo root (workspace dev flow):
+
+```sh
+pnpm install
+pnpm build
+pnpm dev color-scales-example
+```
+
+Or, if you've scaffolded this example as a standalone project:
+
 ```sh
 npm install
 npm run dev

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @examples/color-scales/README.md around lines 17 - 20, Update the README in
examples/color-scales to document the in-repo pnpm workflow: replace or augment
the existing npm snippet so it instructs users to run "pnpm install" at the repo
root (or in the example), then "pnpm build" from the repo root, and then "pnpm
dev color-scales-example" to run the example using workspace:* dependencies;
also keep a short one-line alternative explaining that if the example was
scaffolded standalone (via giget) they can use the existing "npm install" / "npm
run dev" commands.


</details>

</blockquote></details>
<details>
<summary>packages/color-scales/src/legend/LegendTicks.tsx (2)</summary><blockquote>

`15-17`: **Hard‑coded glyph width is fragile.**

`label.length * 5.6 + 8` assumes 10px tabular-nums Latin glyphs. It will under/over-estimate for non‑Latin labels (e.g., categorical with CJK characters) and any future font/size change in `LegendTicks`, causing either overlapping labels or unnecessary thinning. Consider measuring with a hidden canvas/`measureText` once per render, or accepting it as a known limitation in a comment.

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @packages/color-scales/src/legend/LegendTicks.tsx around lines 15 - 17, The
hard-coded width heuristic in estimateTickLabelWidth is fragile for non-Latin
glyphs and font changes; replace the multiplication with a real text measurement
using a Canvas 2D context: create or reuse a hidden/offscreen canvas context in
LegendTicks (e.g., per render or memoized), call context.font to match the
legend label font and use context.measureText(label).width for the width
(optionally add a small padding like +8), and cache measurements per-label to
avoid repeated work; update estimateTickLabelWidth to use this measured width so
labels don't overlap across scripts and font changes.


</details>

---

`34-50`: **Greedy filtering can drop the domain‑max tick.**

`getVisibleTicks` walks ticks in ascending offset and drops any that overlap. When labels are wide (e.g., long formatted numbers) the trailing tick at offset 100 — which conveys the domain maximum — can be the one filtered out, while a less informative mid‑range tick is kept. Consider always preserving the first and last ticks (endpoints) and only thinning interior ticks, or running the greedy pass from both ends.

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @packages/color-scales/src/legend/LegendTicks.tsx around lines 34 - 50,
getVisibleTicks currently greedily removes overlapping ticks by scanning sorted
offsets and can drop important endpoints; modify getVisibleTicks (which uses
getTickBounds, LegendTick and width) to always preserve the first and last tick:
compute sortedTicks, always include sortedTicks[0] and sortedTicks[last], then
run the greedy overlap removal only on the interior ticks (or alternatively
perform two-pass greedy from both ends) so that domain-min and domain-max ticks
are never removed while still thinning overlapping interior labels.


</details>

</blockquote></details>
<details>
<summary>examples/color-scales/src/room.tsx (1)</summary><blockquote>

`183-188`: **Duplicates the `rgba` helper from the package.**

The same `rgba(...)` formatting (with `color[3] / 255`) already lives in `packages/color-scales/src/legend/utils.ts` and is used by `CategoricalLegend`/`SteppedLegend`. Consider exporting that helper from `@sqlrooms/color-scales` so example/consumer code doesn't have to reimplement the alpha-normalization rule.

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @examples/color-scales/src/room.tsx around lines 183 - 188, This duplicates
the inline RGBA formatting; instead import and use the shared helper (export the
helper from packages/color-scales/src/legend/utils.ts and consume it in this
file) rather than reimplementing alpha normalization—replace the inline style
construction for backgroundColor in room.tsx with a call to the exported helper
(the same function used by CategoricalLegend/SteppedLegend) so the example
relies on the package utility.


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Inline comments:
In @examples/color-scales/src/index.css:

  • Around line 5-8: The @source entry "'src//*.{ts,tsx}'" is wrong because
    paths are resolved relative to this CSS file; replace it with a relative pattern
    that points to the files in the same directory (e.g. "./
    /.{ts,tsx}") so
    Tailwind picks up the local TypeScript/TSX sources; update the @source line in
    this file to use "./**/
    .{ts,tsx}" (or "./.{ts,tsx}" if you only want top-level
    files) and remove the erroneous 'src/**/
    .{ts,tsx}' entry.

In @examples/color-scales/src/room.tsx:

  • Line 178: The key generation for the list item uses
    ${colorScale.field}-${row.Car} which can collide when row.Car values repeat;
    update the key used in the mapped element (the expression producing
    key={${colorScale.field}-${row.Car}``) to append a stable per-item identifier
    such as the iteration index or a unique id (e.g.,
    ${colorScale.field}-${row.Car}-${index}) so keys are guaranteed unique across
    rendered rows.
  • Around line 229-245: The code ignores queryResult.error causing silent
    failures; update the component after the useSql/queryResult usage to handle
    errors by checking queryResult.error and rendering an error state or at minimum
    logging the error (e.g., when !isTableReady is false && queryResult.isLoading is
    false && queryResult.error is set). Locate the queryResult reference returned by
    useSql and the existing loading branch that checks isTableReady and
    queryResult.isLoading; add a conditional branch that renders a simple error
    message or a console.error including queryResult.error.message (or error object)
    before rendering the gallery so failures are visible.

In @packages/color-scales/src/ColorScaleLegend.tsx:

  • Around line 26-29: The current key for the legend items in ColorScaleLegend
    (inside the legends.map(...) JSX) uses ${legend.title}-${legend.type} which
    can collide when multiple legends share the same title and type; update the map
    callback to include the array index (e.g., map((legend, index) => ...) and set
    the key to include the index like ${legend.title}-${legend.type}-${index}) so
    each rendered
    is unconditionally unique.

In @packages/color-scales/src/legend/SteppedLegend.tsx:

  • Around line 25-29: The spacer used when legend.ticks is empty in SteppedLegend
    doesn't match the height of LegendTicks (h-2 vs h-8) causing misalignment;
    update the empty branch in SteppedLegend to use the same height as LegendTicks
    (h-8) or extract a shared constant (e.g., TICKS_HEIGHT) used by both LegendTicks
    and SteppedLegend so both render the same vertical space when ticks are
    absent/present.

Nitpick comments:
In @examples/color-scales/README.md:

  • Around line 17-20: Update the README in examples/color-scales to document the
    in-repo pnpm workflow: replace or augment the existing npm snippet so it
    instructs users to run "pnpm install" at the repo root (or in the example), then
    "pnpm build" from the repo root, and then "pnpm dev color-scales-example" to run
    the example using workspace:* dependencies; also keep a short one-line
    alternative explaining that if the example was scaffolded standalone (via giget)
    they can use the existing "npm install" / "npm run dev" commands.

In @examples/color-scales/src/room.tsx:

  • Around line 183-188: This duplicates the inline RGBA formatting; instead
    import and use the shared helper (export the helper from
    packages/color-scales/src/legend/utils.ts and consume it in this file) rather
    than reimplementing alpha normalization—replace the inline style construction
    for backgroundColor in room.tsx with a call to the exported helper (the same
    function used by CategoricalLegend/SteppedLegend) so the example relies on the
    package utility.

In @packages/color-scales/src/legend/LegendTicks.tsx:

  • Around line 15-17: The hard-coded width heuristic in estimateTickLabelWidth is
    fragile for non-Latin glyphs and font changes; replace the multiplication with a
    real text measurement using a Canvas 2D context: create or reuse a
    hidden/offscreen canvas context in LegendTicks (e.g., per render or memoized),
    call context.font to match the legend label font and use
    context.measureText(label).width for the width (optionally add a small padding
    like +8), and cache measurements per-label to avoid repeated work; update
    estimateTickLabelWidth to use this measured width so labels don't overlap across
    scripts and font changes.
  • Around line 34-50: getVisibleTicks currently greedily removes overlapping
    ticks by scanning sorted offsets and can drop important endpoints; modify
    getVisibleTicks (which uses getTickBounds, LegendTick and width) to always
    preserve the first and last tick: compute sortedTicks, always include
    sortedTicks[0] and sortedTicks[last], then run the greedy overlap removal only
    on the interior ticks (or alternatively perform two-pass greedy from both ends)
    so that domain-min and domain-max ticks are never removed while still thinning
    overlapping interior labels.

</details>

<details>
<summary>🪄 Autofix (Beta)</summary>

Fix all unresolved CodeRabbit comments on this PR:

- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `7f6e8bf9-e3e1-4fe4-8411-9791bb05c4be`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 1dd3153efb958b57227f8702967c3ed967a90375 and 93fc5fdb8ecd926cc8f205d60d8900b58e63092d.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `pnpm-lock.yaml` is excluded by `!**/pnpm-lock.yaml`

</details>

<details>
<summary>📒 Files selected for processing (21)</summary>

* `examples/color-scales/README.md`
* `examples/color-scales/eslint.config.js`
* `examples/color-scales/index.html`
* `examples/color-scales/package.json`
* `examples/color-scales/src/index.css`
* `examples/color-scales/src/main.tsx`
* `examples/color-scales/src/room.tsx`
* `examples/color-scales/src/vite-env.d.ts`
* `examples/color-scales/tsconfig.app.json`
* `examples/color-scales/tsconfig.json`
* `examples/color-scales/tsconfig.node.json`
* `examples/color-scales/vite.config.ts`
* `packages/color-scales/README.md`
* `packages/color-scales/src/ColorScaleLegend.tsx`
* `packages/color-scales/src/config.ts`
* `packages/color-scales/src/legend/CategoricalLegend.tsx`
* `packages/color-scales/src/legend/ContinuousLegend.tsx`
* `packages/color-scales/src/legend/LegendTicks.tsx`
* `packages/color-scales/src/legend/SteppedLegend.tsx`
* `packages/color-scales/src/legend/utils.ts`
* `packages/color-scales/src/scale.ts`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment on lines +5 to +8
@source '../index.html';
@source 'src/**/*.{ts,tsx}';
@source '../../../packages/*/src/**/*.{ts,tsx}';
@source '../node_modules/@sqlrooms/*/dist/';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

Tailwind CSS v4 @source directive path resolution relative to CSS file

💡 Result:

In Tailwind CSS v4, the @source directive resolves paths relative to the CSS file containing the directive. This applies even in imported CSS files, where paths are correctly resolved relative to the importing file's location due to Tailwind's core handling of @import statements, which preserves the base path for each CSS file during processing. For example, in ./src/input.css: @import "tailwindcss"; @source "../resources/views//.blade.php"; The path "../resources/views//.blade.php" is relative to ./src/input.css. This behavior is confirmed in official Tailwind CSS documentation and development pull requests. Paths support glob patterns and work across different operating systems (tested on Linux and Windows). Quoted paths are required for globs. Note: Absolute paths are not supported; paths must be relative. For node_modules or external libs, use relative paths like "../node_modules/@my-company/ui-lib".

Citations:


🏁 Script executed:

# Check the structure of examples/color-scales directory
find examples/color-scales -type f -name '*.ts' -o -name '*.tsx' | head -20

Repository: sqlrooms/sqlrooms

Length of output: 208


🏁 Script executed:

# List the directory structure
tree -L 3 examples/color-scales/ 2>/dev/null || find examples/color-scales -type d | head -20

Repository: sqlrooms/sqlrooms

Length of output: 340


🏁 Script executed:

# Check if src/src exists
ls -la examples/color-scales/src/ 2>/dev/null || echo "Directory not found"

Repository: sqlrooms/sqlrooms

Length of output: 411


Incorrect @source path on line 6.

In Tailwind v4, @source paths are resolved relative to the CSS file. Since this file lives at examples/color-scales/src/index.css, 'src/**/*.{ts,tsx}' resolves to examples/color-scales/src/src/**/*.{ts,tsx}, which doesn't exist. The actual TypeScript files are in examples/color-scales/src/ itself. Tailwind's automatic content detection will likely still pick up the local sources, but the explicit directive is dead.

🛠️ Proposed fix
 `@source` '../index.html';
-@source 'src/**/*.{ts,tsx}';
+@source './**/*.{ts,tsx}';
 `@source` '../../../packages/*/src/**/*.{ts,tsx}';
 `@source` '../node_modules/@sqlrooms/*/dist/';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@source '../index.html';
@source 'src/**/*.{ts,tsx}';
@source '../../../packages/*/src/**/*.{ts,tsx}';
@source '../node_modules/@sqlrooms/*/dist/';
`@source` '../index.html';
`@source` './**/*.{ts,tsx}';
`@source` '../../../packages/*/src/**/*.{ts,tsx}';
`@source` '../node_modules/@sqlrooms/*/dist/';
🧰 Tools
🪛 Stylelint (17.9.0)

[error] 5-5: Unexpected unknown at-rule "@source" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)


[error] 6-6: Unexpected unknown at-rule "@source" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)


[error] 7-7: Unexpected unknown at-rule "@source" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)


[error] 8-8: Unexpected unknown at-rule "@source" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/color-scales/src/index.css` around lines 5 - 8, The `@source` entry
"'src/**/*.{ts,tsx}'" is wrong because paths are resolved relative to this CSS
file; replace it with a relative pattern that points to the files in the same
directory (e.g. "./**/*.{ts,tsx}") so Tailwind picks up the local TypeScript/TSX
sources; update the `@source` line in this file to use "./**/*.{ts,tsx}" (or
"./*.{ts,tsx}" if you only want top-level files) and remove the erroneous
'src/**/*.{ts,tsx}' entry.

Comment thread examples/color-scales/src/room.tsx
Comment on lines +229 to +245
const queryResult = useSql<CarRow>({
query: `SELECT * FROM cars ORDER BY Model, Car`,
enabled: isTableReady,
});
const rows = useMemo(
() => queryResult.data?.toArray() ?? [],
[queryResult.data],
);
const legends = useMemo(() => buildLegends(rows), [rows]);

if (!isTableReady || queryResult.isLoading) {
return (
<div className="flex h-full w-full items-center justify-center">
<Spinner />
</div>
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

queryResult.error is silently ignored.

If the parquet fetch or SQL query fails, isLoading becomes false but queryResult.data stays undefined → the gallery renders an empty grid with no feedback. For an example app this is acceptable, but a small error state (or at least logging the error) would make the demo more obvious to debug when network/CORS issues arise.

Suggested addition
   if (!isTableReady || queryResult.isLoading) {
     return (
       <div className="flex h-full w-full items-center justify-center">
         <Spinner />
       </div>
     );
   }
+
+  if (queryResult.error) {
+    return (
+      <div className="text-destructive flex h-full w-full items-center justify-center text-sm">
+        Failed to load cars dataset: {String(queryResult.error)}
+      </div>
+    );
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const queryResult = useSql<CarRow>({
query: `SELECT * FROM cars ORDER BY Model, Car`,
enabled: isTableReady,
});
const rows = useMemo(
() => queryResult.data?.toArray() ?? [],
[queryResult.data],
);
const legends = useMemo(() => buildLegends(rows), [rows]);
if (!isTableReady || queryResult.isLoading) {
return (
<div className="flex h-full w-full items-center justify-center">
<Spinner />
</div>
);
}
const queryResult = useSql<CarRow>({
query: `SELECT * FROM cars ORDER BY Model, Car`,
enabled: isTableReady,
});
const rows = useMemo(
() => queryResult.data?.toArray() ?? [],
[queryResult.data],
);
const legends = useMemo(() => buildLegends(rows), [rows]);
if (!isTableReady || queryResult.isLoading) {
return (
<div className="flex h-full w-full items-center justify-center">
<Spinner />
</div>
);
}
if (queryResult.error) {
return (
<div className="text-destructive flex h-full w-full items-center justify-center text-sm">
Failed to load cars dataset: {String(queryResult.error)}
</div>
);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/color-scales/src/room.tsx` around lines 229 - 245, The code ignores
queryResult.error causing silent failures; update the component after the
useSql/queryResult usage to handle errors by checking queryResult.error and
rendering an error state or at minimum logging the error (e.g., when
!isTableReady is false && queryResult.isLoading is false && queryResult.error is
set). Locate the queryResult reference returned by useSql<CarRow> and the
existing loading branch that checks isTableReady and queryResult.isLoading; add
a conditional branch that renders a simple error message or a console.error
including queryResult.error.message (or error object) before rendering the
gallery so failures are visible.

Comment thread packages/color-scales/src/ColorScaleLegend.tsx
Comment thread packages/color-scales/src/legend/SteppedLegend.tsx
@ilyabo
ilyabo merged commit 6fb92e7 into main Apr 25, 2026
3 checks passed
@ilyabo
ilyabo deleted the feat/improved-colorscales branch April 25, 2026 08:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant