Skip to content

Extract color input UI into reusable ColorInput component - #440

Merged
jackgranatowski merged 3 commits into
mainfrom
claude/color-swatches-variables-yyd22f
Jun 28, 2026
Merged

Extract color input UI into reusable ColorInput component#440
jackgranatowski merged 3 commits into
mainfrom
claude/color-swatches-variables-yyd22f

Conversation

@jackgranatowski

@jackgranatowski jackgranatowski commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Refactors repeated color picker UI patterns across multiple panels into a new reusable ColorInput component. This eliminates code duplication and provides a consistent color input experience throughout the configurator.

Changes

  • New component: ColorInput.svelte — a unified color input with:

    • Native color picker swatch (disabled for CSS variable references)
    • Editable text field with inline editing mode
    • Automatic color resolution and preview via resolveColor()
    • Reset button for overridden values
    • Support for CSS variables, hex, and rgb() color formats
  • Refactored panels to use ColorInput:

    • MiscPanel.svelte — selection background/text, caret color
    • BordersPanel.svelte — border color, divider color, focus ring color
    • ShadowsPanel.svelte — shadow color, glow color
    • EffectsPanel.svelte — scrim color, scrollbar thumb/track
    • ColorsPanel.svelte — semantic color swatches
  • Enhanced TokenRow.svelte — improved swatch color resolution to handle CSS variable fallbacks

Implementation Details

  • The component intelligently detects CSS variable references (var(...) or --*) and disables the native color picker for those cases, allowing manual entry instead
  • Color hex conversion handles rgb/rgba formats for native picker seeding
  • Integrates with the existing previewResolver to resolve and display actual computed colors
  • Maintains consistent styling and interaction patterns across all color inputs

https://claude.ai/code/session_01EyxX99kENNBAiWeZvLQNBT

Summary by CodeRabbit

  • New Features

    • Added a reusable color picker input with swatch preview, text editing, and reset support.
    • Color editing across the configurator now uses the same shared control for a more consistent experience.
  • Bug Fixes

    • Color previews now better reflect resolved CSS values, including variable-based colors and preview updates.
    • Several color fields now handle overridden and default values more reliably.

… variables

Replace all <input type="color"> occurrences across Effects, Misc, Borders,
Shadows, and Colors panels with a new ColorInput component that:

- Resolves the actual displayed color via resolveColor() from the live preview
  iframe so swatches show the real computed value instead of hardcoded fallbacks
- Accepts CSS variable syntax (var(--token)) as text input; hides the native
  color picker when a variable is entered since type="color" can't handle them
- Clicking the swatch still opens the native picker for concrete color values,
  seeded with the resolved hex

Also fixes TokenRow swatch to use resolveColor() so tokens whose values
reference CSS variables (not in the configurator DOM scope) render correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EyxX99kENNBAiWeZvLQNBT
@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jackgranatowski, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 52 minutes and 37 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d0bec404-dcc1-4d57-8f10-41c09521d194

📥 Commits

Reviewing files that changed from the base of the PR and between bbbe2a2 and 0c2d8d6.

📒 Files selected for processing (2)
  • configurator/src/components/inputs/ColorInput.svelte
  • configurator/src/components/inputs/TokenRow.svelte
📝 Walkthrough

Walkthrough

Introduces a new reusable ColorInput Svelte component that combines a color swatch, conditional native color picker, and free-form text editing with override/reset support. All six configurator panels (BordersPanel, ColorsPanel, EffectsPanel, MiscPanel, ShadowsPanel, and TokenRow) replace their inline color picker markup with this component.

Changes

ColorInput Component and Panel Adoption

Layer / File(s) Summary
ColorInput component
configurator/src/components/inputs/ColorInput.svelte
New component with typed $props(), local editing state, resolveColor-based swatch derivation, CSS variable detection, toHex seeding for the native picker, dual-mode text/display UI, and conditional reset button.
TokenRow swatch resolution
configurator/src/components/inputs/TokenRow.svelte
Adds resolveColor/previewVersion imports, a paintSwatch helper with fallback chain, and switches the color swatch style.background from raw displayValue to a derived swatchColor.
Panel adoption
configurator/src/components/panels/BordersPanel.svelte, ColorsPanel.svelte, EffectsPanel.svelte, MiscPanel.svelte, ShadowsPanel.svelte
Each panel imports ColorInput and replaces inline <input type="color"> blocks (with per-token reset/label logic) with ColorInput wired to token, value, placeholder, isOverridden, onSet, and onReset.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • codeslash-dev/SLASHED#429: Also modifies ColorsPanel.svelte to use preview-resolved colors via resolveColor/previewVersion, which is the same resolution mechanism now used inside ColorInput and TokenRow.

Suggested labels

codex

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main refactor: extracting repeated color input UI into a reusable ColorInput component.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/color-swatches-variables-yyd22f

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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Extract reusable ColorInput component for consistent token color editing
✨ Enhancement 🐞 Bug fix 🕐 40+ Minutes

Grey Divider

Description

• Introduce a reusable ColorInput for swatch + text editing + reset behavior.
• Replace duplicated  patterns across configurator panels.
• Resolve swatch colors via preview resolver so CSS-variable tokens render correctly.
Diagram

graph TD
  P["Configurator panels"] --> CI["ColorInput (Svelte)"] --> PR["previewResolver"] --> IF{{"Preview iframe"}}
  TR["TokenRow"] --> PR
  subgraph Legend
    direction LR
    _c["Component"] ~~~ _e{{"External"}}
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use a dedicated color picker library (supports CSS vars)
  • ➕ Native support for richer parsing (hex/rgb/hsl/var()) and alpha controls
  • ➕ More consistent UX across browsers than
  • ➖ Adds dependency weight and maintenance surface area
  • ➖ Harder to keep styling aligned with the existing compact configurator UI
2. Keep native and add a separate 'var()' toggle
  • ➕ Minimal new component logic
  • ➕ Keeps existing behavior nearly unchanged
  • ➖ UX becomes inconsistent across panels unless all adopt the same toggle pattern
  • ➖ Still leaves duplicated boilerplate (swatch, label, reset, resolution) in each panel

Recommendation: Proceed with the current approach: a single ColorInput consolidates the repeated UI patterns and centralizes the tricky parts (preview-based resolution and CSS-variable handling) without introducing new dependencies. The chosen design keeps the native picker for concrete colors while gracefully falling back to text entry for var(...) values, which matches platform constraints.

Files changed (7) +188 / -128

Enhancement (1) +89 / -0
ColorInput.svelteAdd reusable ColorInput with preview-resolved swatch + inline editing +89/-0

Add reusable ColorInput with preview-resolved swatch + inline editing

• Introduces a shared color input component that shows a resolved swatch, supports inline text editing, and offers reset for overridden values. Disables the native color picker when the value is a CSS variable reference and seeds the picker by converting resolved rgb(...) to hex.

configurator/src/components/inputs/ColorInput.svelte

Bug fix (1) +8 / -1
TokenRow.svelteFix token swatch painting via preview-based resolveColor +8/-1

Fix token swatch painting via preview-based resolveColor

• Updates the color swatch rendering to resolve token expressions through the preview resolver, including a fallback to var(token.name). This improves swatch accuracy for tokens whose values rely on CSS variables outside the configurator DOM scope.

configurator/src/components/inputs/TokenRow.svelte

Refactor (5) +91 / -127
BordersPanel.svelteReplace border/divider/focus ring color pickers with ColorInput +23/-30

Replace border/divider/focus ring color pickers with ColorInput

• Refactors border-related color overrides to use ColorInput, standardizing swatch behavior, placeholder text, and reset handling. Removes duplicated native color input markup for border color, divider color, and focus ring color.

configurator/src/components/panels/BordersPanel.svelte

ColorsPanel.svelteUse ColorInput for semantic swatch overrides +9/-17

Use ColorInput for semantic swatch overrides

• Replaces the per-swatch inline color-picker UI with ColorInput. Preserves the existing resolved/auto-derived display by passing a computed placeholder string into the shared component.

configurator/src/components/panels/ColorsPanel.svelte

EffectsPanel.svelteStandardize scrim and scrollbar colors via ColorInput +17/-20

Standardize scrim and scrollbar colors via ColorInput

• Migrates scrim and scrollbar thumb/track color controls to ColorInput, removing per-row default-seeding logic in favor of shared resolution and display behavior. Keeps existing override/reset semantics via component callbacks.

configurator/src/components/panels/EffectsPanel.svelte

MiscPanel.svelteRefactor selection and caret color controls to ColorInput +25/-36

Refactor selection and caret color controls to ColorInput

• Replaces selection background/text and caret color picker blocks with the shared ColorInput component. This unifies placeholder display and reset behavior while supporting CSS variable entry where needed.

configurator/src/components/panels/MiscPanel.svelte

ShadowsPanel.svelteMove shadow and glow color editing to ColorInput +17/-24

Move shadow and glow color editing to ColorInput

• Refactors shadow color and glow color controls to use ColorInput. Removes duplicated swatch/value/reset UI while retaining the existing descriptive placeholders.

configurator/src/components/panels/ShadowsPanel.svelte

@coderabbitai coderabbitai Bot added the codex label Jun 28, 2026
@qodo-code-review

qodo-code-review Bot commented Jun 28, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 6 rules

Grey Divider


Action required

1. Bare var shorthand breaks CSS ✓ Resolved 🐞 Bug ≡ Correctness
Description
ColorInput treats values starting with "--" as CSS variable references but forwards them unchanged
to onSet and resolveColor, so an entered "--sf-color-…" gets serialized as a literal string and
becomes an invalid color at runtime. This makes saved/imported overrides unusable and prevents
correct swatch resolution for that shorthand.
Code

configurator/src/components/inputs/ColorInput.svelte[R22-64]

+  function paint(expr: string): string {
+    void previewVersion.value;
+    return resolveColor(expr) || expr || "transparent";
+  }
+
+  let swatchColor = $derived(paint(value || `var(${token})`));
+
+  // Detect if the current value is a CSS variable reference (can't use native picker)
+  let isVar = $derived(value.trim().startsWith("var(") || value.trim().startsWith("--"));
+
+  // Convert rgb(...) string to hex for native picker seed
+  function toHex(rgb: string): string {
+    const m = rgb.match(/rgb\w*\((\d+)[,\s]+(\d+)[,\s]+(\d+)/);
+    if (!m) return "#6366f1";
+    return "#" + [m[1], m[2], m[3]].map(n => parseInt(n).toString(16).padStart(2, "0")).join("");
+  }
+</script>
+
+<div class="flex items-center gap-2">
+  <!-- Swatch / native picker trigger -->
+  <div class="relative shrink-0 w-7 h-7 rounded border border-white/10 overflow-hidden cursor-pointer">
+    <div class="absolute inset-0" style={`background: ${swatchColor}`}></div>
+    {#if !isVar}
+      <input
+        type="color"
+        value={toHex(swatchColor)}
+        oninput={(e) => onSet((e.target as HTMLInputElement).value)}
+        class="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
+        tabindex="-1"
+      />
+    {/if}
+  </div>
+
+  <!-- Text display / editable input -->
+  {#if editing}
+    <input
+      value={value}
+      autofocus
+      onblur={(e) => {
+        const v = (e.target as HTMLInputElement).value.trim();
+        if (!v) onReset();
+        else onSet(v);
+        editing = false;
Relevance

⭐⭐ Medium

No close historical precedent on supporting bare "--token" as var(); team fixes correctness, but
evidence is indirect.

PR-#434
PR-#429

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
ColorInput explicitly treats --* as a variable reference but does not wrap it in var(...) when
setting/saving or resolving, while the override CSS generator writes values verbatim into `:root {
--name: value; }. This combination makes bare --token` values invalid color overrides and
unresolvable by the preview probe.

configurator/src/components/inputs/ColorInput.svelte[22-65]
configurator/src/lib/codec.ts[187-204]
configurator/src/components/shell/PreviewPanel.svelte[463-567]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`ColorInput` claims to support CSS variable references entered as either `var(--token)` or bare `--token`, but the bare form is currently stored and resolved as-is. Persisting `--token` produces override CSS like `--sf-some-color: --sf-other-color;`, which is not a valid color value when later consumed via `var(--sf-some-color)`.

### Issue Context
- `ColorInput` explicitly detects `--*` as a var reference (`isVar`), but `paint()` and the `onblur` handler pass the raw string through unchanged.
- Overrides are emitted verbatim into `:root { --token: <value>; }`, so the invalid value is persisted into the preview iframe and export output.

### Fix Focus Areas
- configurator/src/components/inputs/ColorInput.svelte[22-65]
- configurator/src/lib/codec.ts[187-204]

### Implementation guidance
- In `ColorInput`, introduce a small normalization helper:
 - If trimmed input starts with `--`, convert to `var(${trimmed})`.
 - If it already starts with `var(`, keep as-is.
- Apply normalization in both places:
 - In `paint(expr)` (or before calling it) so the swatch preview resolves correctly.
 - In the `onblur` path before calling `onSet(v)` so persisted overrides are valid.
- Add a couple of inline comments clarifying that bare `--token` is a UI shorthand that is normalized before storage.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Unneeded resolveColor for non-colors ✓ Resolved 🐞 Bug ➹ Performance
Description
TokenRow now computes swatchColor via resolveColor() for every token row even when the token isn’t a
color, creating extra work and making all rows depend on previewVersion bumps. In large token lists,
this adds avoidable recomputation on every preview update despite swatchColor only being rendered
for color tokens.
Code

configurator/src/components/inputs/TokenRow.svelte[R26-32]

+  function paintSwatch(expr: string): string {
+    void previewVersion.value;
+    return resolveColor(expr) || resolveColor(`var(${token.name})`) || expr;
+  }
+  let swatchColor = $derived(paintSwatch(displayValue));
  let type = $derived(guessType(token));
  let shortName = $derived(token.name.replace("--sf-", ""));
Relevance

⭐⭐⭐ High

Performance work around previewVersion/resolveColor recomputation is commonly accepted (caching and
gated effects in PRs #430/#433).

PR-#430
PR-#433

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
TokenRow defines swatchColor using paintSwatch() before any type-based rendering branch;
paintSwatch() reads previewVersion and calls resolveColor(), and AllTokensTab instantiates TokenRow
for every token in the list (many of which are non-color).

configurator/src/components/inputs/TokenRow.svelte[23-33]
configurator/src/components/panels/AllTokensTab.svelte[115-129]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`swatchColor = $derived(paintSwatch(displayValue))` runs for every `TokenRow`, even when the token isn’t a color. `paintSwatch()` reads `previewVersion.value` and calls `resolveColor()`, so non-color rows unnecessarily subscribe to preview bumps and do extra work.

### Issue Context
`AllTokensTab` renders `TokenRow` for all tokens in the filtered list, so this overhead scales with token count.

### Fix Focus Areas
- configurator/src/components/inputs/TokenRow.svelte[14-33]
- configurator/src/components/panels/AllTokensTab.svelte[115-129]

### Implementation guidance
- Compute `type` first, then gate swatch resolution:
 - `let swatchColor = $derived(type === "color" ? paintSwatch(displayValue) : "");`
- Alternatively, move the `previewVersion` read and `resolveColor()` calls behind a `type === "color"` guard so non-color rows don’t subscribe to previewVersion at all.
- Keep behavior unchanged for color tokens.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Picker seed falls back indigo ✓ Resolved 🐞 Bug ≡ Correctness
Description
When resolveColor() returns an empty string (before the preview iframe is registered), ColorInput
falls back to the raw expression and toHex() then returns a hard-coded "#6366f1" for any non-rgb()
string (including valid hex). This causes the native color picker to open at an unrelated color even
when an override is already set.
Code

configurator/src/components/inputs/ColorInput.svelte[R22-37]

+  function paint(expr: string): string {
+    void previewVersion.value;
+    return resolveColor(expr) || expr || "transparent";
+  }
+
+  let swatchColor = $derived(paint(value || `var(${token})`));
+
+  // Detect if the current value is a CSS variable reference (can't use native picker)
+  let isVar = $derived(value.trim().startsWith("var(") || value.trim().startsWith("--"));
+
+  // Convert rgb(...) string to hex for native picker seed
+  function toHex(rgb: string): string {
+    const m = rgb.match(/rgb\w*\((\d+)[,\s]+(\d+)[,\s]+(\d+)/);
+    if (!m) return "#6366f1";
+    return "#" + [m[1], m[2], m[3]].map(n => parseInt(n).toString(16).padStart(2, "0")).join("");
+  }
Relevance

⭐⭐⭐ High

Team previously accepted resolveColor("" ) fallback fixes to avoid wrong swatches before preview is
ready (see PR #434).

PR-#434

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
ColorInput’s paint() returns the original expression when resolveColor() yields ""; resolveColor()
explicitly returns "" when no preview doc exists yet; toHex() then fails to parse hex/non-rgb
expressions and returns a hard-coded fallback.

configurator/src/components/inputs/ColorInput.svelte[22-37]
configurator/src/lib/previewResolver.svelte.ts[91-109]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`toHex()` only understands computed `rgb(...)`/`rgba(...)` strings. When the preview resolver is unavailable, `paint()` returns the raw input expression (often a hex string), which causes `toHex()` to return the default `#6366f1` and mis-seed the native `<input type="color">`.

### Issue Context
`resolveColor()` returns `""` until the preview document is registered, so this behavior happens on initial load / iframe reload windows.

### Fix Focus Areas
- configurator/src/components/inputs/ColorInput.svelte[22-37]
- configurator/src/lib/previewResolver.svelte.ts[91-109]

### Implementation guidance
- Extend `toHex()` to:
 - Return the input directly if it already matches `#RRGGBB` (and optionally expand `#RGB` to `#RRGGBB`).
 - Otherwise, keep the current `rgb(...)` parsing.
 - Only fall back to the default when the string is neither hex nor rgb/rgba.
- Consider special-casing `transparent`/`rgba(..., 0)` to a reasonable seed (since native pickers can’t represent alpha), but keep it simple if you prefer.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread configurator/src/components/inputs/ColorInput.svelte
- Normalize bare "--token" input to "var(--token)" before storing or
  resolving so overrides emit valid CSS instead of a literal string
- Extend toHex() to pass through hex strings (#RGB / #RRGGBB) so the
  native picker is seeded correctly when the preview resolver is not yet
  available
- Gate TokenRow's swatchColor resolution behind type === "color" so
  non-color rows don't subscribe to previewVersion bumps unnecessarily

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EyxX99kENNBAiWeZvLQNBT

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@configurator/src/components/inputs/ColorInput.svelte`:
- Around line 22-30: Normalize bare custom-property values in ColorInput.svelte
before they are used by paint(), swatchColor, or saved from the input. Treat
inputs starting with -- the same as var(...) by converting them to a proper
var(--name) expression, and then use that normalized value in the derived swatch
and any save/update path so resolveColor can paint it correctly and the stored
value is a valid CSS color. Focus the fix around the paint function, the
swatchColor derivation, and the value handling used for saving.
- Around line 57-69: Escape in ColorInput.svelte is still committing changes
because the input’s blur handler runs after editing is set to false. Update the
input’s onkeydown/onblur flow so Escape cancels the draft without calling onSet
or onReset, while Enter still commits via blur; use the ColorInput component’s
editing state and blur handler to distinguish cancel vs save.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c880ab87-236f-43da-94e7-da5f19b3b1ec

📥 Commits

Reviewing files that changed from the base of the PR and between 3ab425f and bbbe2a2.

📒 Files selected for processing (7)
  • configurator/src/components/inputs/ColorInput.svelte
  • configurator/src/components/inputs/TokenRow.svelte
  • configurator/src/components/panels/BordersPanel.svelte
  • configurator/src/components/panels/ColorsPanel.svelte
  • configurator/src/components/panels/EffectsPanel.svelte
  • configurator/src/components/panels/MiscPanel.svelte
  • configurator/src/components/panels/ShadowsPanel.svelte

Comment thread configurator/src/components/inputs/ColorInput.svelte
Comment thread configurator/src/components/inputs/ColorInput.svelte
Setting editing = false on Escape caused the input to unmount, firing
blur and committing the draft value. Use a cancelBlur flag to suppress
the blur handler when Escape is pressed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EyxX99kENNBAiWeZvLQNBT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants