Skip to content

fix: update for version 2#1887

Merged
shinokada merged 31 commits intothemesberg:version-2from
shinokada:v2-next
Dec 24, 2025
Merged

fix: update for version 2#1887
shinokada merged 31 commits intothemesberg:version-2from
shinokada:v2-next

Conversation

@shinokada
Copy link
Collaborator

@shinokada shinokada commented Dec 18, 2025

Related to #1614

🔗 Related issue (optional)

Closes #


📑 Description

  • accordion
  • alert
  • avatar
  • badge
  • banner
  • bottom-navigation
  • breadcrumb
  • button-group
  • buttons
  • card
  • carousel
  • clipboard
  • clipboard-manager
  • command-palette
  • context.ts
  • darkmode
  • datepicker
  • device-mockups
  • dialog
  • drawer
  • dropdown
  • footer
  • button-toggle
  • checkbox
  • dropzone
  • fileupload
  • floating-label

🔍 PR Type

  • Bug fix
  • Feature
  • Documentation
  • Refactor / Code cleanup
  • Build / Tooling
  • Other (please describe)

🚦 PR Status

  • Draft (work in progress, not ready for review)
  • Ready for review ✅

✅ Checklist

  • My code follows the existing code style
  • I have run pnpm lint && pnpm check && pnpm test:e2e and all tests pass
  • CoderabbitAI review has been completed and actionable suggestions were reviewed
  • I have updated documentation if my changes require it
  • My PR is based on the latest main branch (not the published npm version)
  • I have checked accessibility where applicable (ARIA, keyboard nav, etc.)
  • I have reviewed the rendered component in the browser

🧪 Screenshots / Demos (optional)


⚠️ Breaking Changes (optional)


ℹ️ Additional Information

Summary by CodeRabbit

  • New Features

    • Theme selector (multiple runtime themes), validation states for floating-label inputs, new button shadow demo, unified classes prop for several components.
  • Bug Fixes & Improvements

    • Semantic color tokens (brand/danger/success/warning) applied across UI; many default colors updated to "brand"; switched many icons to outline variants; improved pagination/radius styling and hover/hoverable card behavior.
  • Tests

    • Added comprehensive component test suites for Accordion, Alert, Badge, Banner, Avatar, Card, and more.
  • Chores

    • Dev tooling scripts and package scripts added; updated Flowbite dependency to 4.0.1.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 18, 2025

@shinokada is attempting to deploy a commit to the Themesberg Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 18, 2025

📝 Walkthrough

Walkthrough

Large refactor migrating per-element class props to a unified classes pattern, introducing theme utilities (getTheme, Classes), adding a runtime theme selector/store, updating many components' props/defaults (primary → brand), replacing deprecated theming flows, and adding extensive tests and docs updates.

Changes

Cohort / File(s) Summary
Theming Core & Utilities
src/lib/theme/themeUtils.ts, src/lib/theme/themes.ts
Added getTheme() and exported Classes<T> type; expanded theme exports (defaultMockup, laptop, smartwatch, drawerhead, inputAddon).
Runtime Theme & UI
src/routes/utils/themeStore.svelte.ts, src/routes/utils/ThemeSelector.svelte, src/routes/+layout.svelte, src/routes/layout.css
New theme store with dynamic CSS/font loading and persistence; ThemeSelector component; layout loads saved theme and injects runtime stylesheet.
Classes Prop Migration (multiple components)
src/lib/** (accordion, carousel, carousel/*, dropdown, footer, badge, banner, badge, bottom-navigation, breadcrumb, dialog, drawer, device-mockups, footer, form components, etc.)
Replaced many per-element props (e.g., activeClass, imgClass, aClass, olClass, divClass*, btnClass, spanClass) with unified classes props; removed deprecation flows and untrack usage; adjusted derived styling to use $derived(classes).
Accordion Suite & Examples
src/lib/accordion/*, src/routes/docs-examples/components/accordion/*, src/routes/docs/components/accordion.md
Accordion and AccordionItem now accept classes (button, contentWrapper, content, active, inactive); theme variants and docs/examples updated; added dynamic example routes.
Alert Suite
src/lib/alert/Alert.svelte, src/lib/alert/theme.ts, src/routes/docs-examples/components/alert/*, src/tests/alert/*
Added props closeColor, listContent, borderAccent; changed default color from primarybrand; theme reorganized to semantic tokens; examples/tests added/updated.
Badge / Button / Card / Carousel / Checkbox / Datepicker / etc.
src/lib/badge/*, src/lib/buttons/*, src/lib/card/*, src/lib/carousel/*, src/lib/forms/checkbox/*, src/lib/datepicker/*
Wide signature and theme updates: defaults changed to brand, new props (e.g., hoverable, imgAlt, closeBtnColor), removed many legacy class props, new variant axes added; theme slot strings adjusted (rounded-lg → rounded-base etc.).
Device Mockups & Drawer
src/lib/device-mockups/*, src/lib/drawer/*
Removed many divClass* props; components now use getTheme + classes derived styling; Drawer removed hidden/activateClickOutside props; Drawerhead button/svg props removed.
Type Changes
src/lib/types.ts
Large TypeScript surface update: removed/renamed many props/types, added variant imports (CarouselIndicatorsVariants, ControlButtonVariants, ThumbnailsVariants), corrected typos (GradientButtonVariants).
Examples, Docs & Builders
src/routes/docs/**, src/routes/docs-examples/**, src/routes/builder/**
Massive docs simplification, example updates (image paths, icon swaps Solid→Outline), builder pages adjusted to new defaults and emit behaviors.
Tests
src/tests/accordion/*, src/tests/alert/*, src/tests/avatar/*, src/tests/badge/*, src/tests/banner/*
Added 40+ tests and fixtures exercising Accordion, Alert, Avatar, Badge, Banner behaviours and accessibility.
Scripts & Misc
scripts/sync-plugin-utilities-export.sh, convertThemes.js, clear-cache.sh, .coderabbit.yml, .prettierignore, package.json
New utility scripts for sync/convert/clear cache; package.json scripts updated; prettierignore broadened; CodeRabbit auto_review enabled.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User as ThemeSelector UI
  participant ThemeStore as themeStore (client)
  participant Head as <head> (runtime)
  participant Layout as +layout.svelte
  Note over User,ThemeStore: User selects a theme via ThemeSelector
  User->>ThemeStore: loadTheme(themeId)
  activate ThemeStore
  ThemeStore->>Head: remove existing theme links
  ThemeStore->>Head: inject font link (if needed)
  ThemeStore->>Head: inject runtime theme CSS link (onload/onerror handlers)
  Head-->>ThemeStore: onload -> confirm
  ThemeStore->>ThemeStore: persist selection to localStorage
  ThemeStore->>Layout: update currentTheme reactive store
  Layout->>Layout: apply theme variables / reflow styles
  ThemeStore-->>User: selected theme reflected in UI
  deactivate ThemeStore
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Poem

🐰 I hopped through themes and classes bright,
Swapping "primary" for "brand" in morning light.
Props retired, new utilities sing,
Tests applaud — a tidy spring! 🌷
Docs trimmed, examples gleam, our garden grows light.

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'fix: update for version 2' is too vague and does not accurately reflect the extensive refactoring across multiple components. Revise the title to be more specific, such as 'refactor: migrate components to version 2 design system with semantic color tokens' or 'refactor(v2): update accordion, alert, badge, banner, and other components with new styling API'.
Description check ⚠️ Warning The PR description is largely incomplete, containing only a vague title reference, a checklist of completed components, and incomplete contributor checklist boxes without explaining the actual changes, rationale, or migration path. Expand the description to include: (1) summary of changes (semantic color palette, removal of deprecated props, theme-driven styling), (2) rationale for the refactoring, (3) migration guide for users, (4) confirmation that tests pass and code style is followed.
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@shinokada
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 18, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/accordion/AccordionItem.svelte (1)

91-110: Update stale documentation - removed props still listed.

The component documentation lists props that were removed in this refactor:

  • activeClass (line 102)
  • inactiveClass (line 103)
  • headerClass (line 108)
  • contentClass (line 109)

These should be removed to match the updated AccordionItemProps type.

🔎 Apply this diff:
 @prop arrowdown
 @prop open = $bindable(false)
-@prop activeClass
-@prop inactiveClass
 @prop transitionType = slide
 @prop transitionParams
 @prop class: className
 @prop classes
-@prop headerClass
-@prop contentClass
 -->
🧹 Nitpick comments (2)
src/lib/pagination/theme.ts (1)

49-67: Consider removing redundant compound variant.

The group: false variant (line 51) already applies rounded-base. The compound variant (lines 62-67) that applies rounded-base when group: false and table: false is redundant since the base variant already covers this case.

The same redundancy exists in paginationItem (lines 88-102).

🔎 Suggested simplification:
  compoundVariants: [
-   {
-     group: false,
-     table: false,
-     class: "rounded-base"
-   }
  ],
src/lib/accordion/AccordionItem.svelte (1)

16-23: Clarify the priority comment.

The comment states "Priority: theme < context < local classes" but finalClasses only merges context and local classes. Theme is applied separately in the template via clsx (e.g., line 53). Consider updating the comment to accurately describe this two-stage merge.

🔎 Suggested clarification:
-  // Priority: theme < context < local classes
+  // Merge context and local classes (local overrides context).
+  // Theme is applied in template via clsx with lowest priority.
   const finalClasses = $derived({
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df3404b and 91424ba.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (29)
  • package.json (2 hunks)
  • src/app.css (1 hunks)
  • src/lib/accordion/Accordion.svelte (2 hunks)
  • src/lib/accordion/AccordionItem.svelte (3 hunks)
  • src/lib/accordion/theme.ts (1 hunks)
  • src/lib/alert/theme.ts (1 hunks)
  • src/lib/pagination/Pagination.svelte (2 hunks)
  • src/lib/pagination/theme.ts (5 hunks)
  • src/lib/types.ts (2 hunks)
  • src/routes/docs-examples/components/accordion/AdvancedClasses.svelte (1 hunks)
  • src/routes/docs-examples/components/accordion/Color.svelte (1 hunks)
  • src/routes/docs-examples/components/accordion/Icon.svelte (0 hunks)
  • src/routes/docs-examples/components/accordion/MultipleMode2.svelte (1 hunks)
  • src/routes/docs-examples/components/accordion/Nesting.svelte (2 hunks)
  • src/routes/docs-examples/components/accordion/[slug]/+page.svelte (1 hunks)
  • src/routes/docs-examples/components/accordion/[slug]/+page.ts (1 hunks)
  • src/routes/docs-examples/components/accordion/index.ts (2 hunks)
  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte (1 hunks)
  • src/routes/docs/components/accordion.md (6 hunks)
  • src/routes/landing/Hero.svelte (1 hunks)
  • src/tests/accordion/Accordion.test.ts (1 hunks)
  • src/tests/accordion/basic-accordion.test.svelte (1 hunks)
  • src/tests/accordion/classes-accordion.test.svelte (1 hunks)
  • src/tests/accordion/custom-arrows-accordion.test.svelte (1 hunks)
  • src/tests/accordion/flush-accordion.test.svelte (1 hunks)
  • src/tests/accordion/multiple-accordion.test.svelte (1 hunks)
  • src/tests/accordion/no-transition-accordion.test.svelte (1 hunks)
  • src/tests/accordion/open-accordion.test.svelte (1 hunks)
  • workflow.md (1 hunks)
💤 Files with no reviewable changes (1)
  • src/routes/docs-examples/components/accordion/Icon.svelte
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/tests/accordion/flush-accordion.test.svelte
  • src/routes/docs-examples/components/accordion/index.ts
  • src/routes/docs-examples/components/accordion/AdvancedClasses.svelte
  • src/routes/landing/Hero.svelte
  • src/tests/accordion/basic-accordion.test.svelte
  • src/lib/alert/theme.ts
  • src/lib/pagination/Pagination.svelte
  • src/routes/docs-examples/components/accordion/MultipleMode2.svelte
  • src/routes/docs-examples/components/accordion/[slug]/+page.svelte
  • src/tests/accordion/classes-accordion.test.svelte
  • src/lib/types.ts
  • src/tests/accordion/Accordion.test.ts
  • src/lib/accordion/theme.ts
  • src/lib/pagination/theme.ts
  • src/routes/docs-examples/components/accordion/[slug]/+page.ts
  • src/tests/accordion/no-transition-accordion.test.svelte
  • src/tests/accordion/custom-arrows-accordion.test.svelte
  • src/tests/accordion/multiple-accordion.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte
  • src/routes/docs-examples/components/accordion/Nesting.svelte
  • src/lib/accordion/AccordionItem.svelte
  • src/tests/accordion/open-accordion.test.svelte
  • src/lib/accordion/Accordion.svelte
  • src/routes/docs-examples/components/accordion/Color.svelte
🧠 Learnings (15)
📓 Common learnings
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/tests/accordion/flush-accordion.test.svelte
  • src/routes/docs-examples/components/accordion/AdvancedClasses.svelte
  • src/routes/landing/Hero.svelte
  • src/tests/accordion/basic-accordion.test.svelte
  • src/lib/pagination/Pagination.svelte
  • src/routes/docs-examples/components/accordion/MultipleMode2.svelte
  • src/routes/docs-examples/components/accordion/[slug]/+page.svelte
  • src/tests/accordion/classes-accordion.test.svelte
  • src/tests/accordion/no-transition-accordion.test.svelte
  • src/tests/accordion/custom-arrows-accordion.test.svelte
  • src/tests/accordion/multiple-accordion.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte
  • src/routes/docs-examples/components/accordion/Nesting.svelte
  • src/lib/accordion/AccordionItem.svelte
  • src/tests/accordion/open-accordion.test.svelte
  • src/lib/accordion/Accordion.svelte
  • src/routes/docs-examples/components/accordion/Color.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

Applied to files:

  • src/routes/docs-examples/components/accordion/index.ts
  • src/app.css
  • package.json
  • src/routes/docs-examples/components/accordion/AdvancedClasses.svelte
  • src/routes/landing/Hero.svelte
  • src/routes/docs-examples/components/accordion/Nesting.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation

Applied to files:

  • src/routes/docs-examples/components/accordion/index.ts
  • src/app.css
  • src/routes/landing/Hero.svelte
  • src/routes/docs-examples/components/accordion/Nesting.svelte
📚 Learning: 2025-12-16T13:21:28.743Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:28.743Z
Learning: In flowbite-svelte, when using ThemeProvider with reactive themes, `getTheme("componentName")` calls must be placed inside `$derived()` expressions (not at module scope) to ensure components react to dynamic theme changes. This pattern is intentional for reactive theming support.

Applied to files:

  • src/app.css
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use searchDocs tool for full-text search across Flowbite-Svelte documentation when looking for specific information that might span multiple components or when users ask about features or patterns

Applied to files:

  • src/app.css
  • src/routes/landing/Hero.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/docs-examples/components/accordion/AdvancedClasses.svelte
  • src/routes/landing/Hero.svelte
  • src/routes/docs-examples/components/accordion/[slug]/+page.svelte
  • src/routes/docs-examples/components/accordion/Nesting.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/docs-examples/components/accordion/AdvancedClasses.svelte
  • src/routes/landing/Hero.svelte
  • src/routes/docs-examples/components/accordion/Nesting.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Use getComponentList tool to discover available Flowbite-Svelte components or help users explore component options

Applied to files:

  • src/routes/docs-examples/components/accordion/AdvancedClasses.svelte
  • src/routes/landing/Hero.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use the Flowbite-Svelte MCP server to access comprehensive component documentation

Applied to files:

  • src/routes/landing/Hero.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use getComponentList tool to discover available Flowbite-Svelte components with their categories or to help users explore component options

Applied to files:

  • src/routes/landing/Hero.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Use searchDocs tool when finding specific information that might span multiple Flowbite-Svelte components or when exploring features and patterns across the documentation

Applied to files:

  • src/routes/landing/Hero.svelte
📚 Learning: 2025-12-11T12:35:41.602Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-11T12:35:41.602Z
Learning: Use the Flowbite-Svelte MCP server's `searchDocs` tool when finding specific information spanning multiple components or when users ask about features or patterns

Applied to files:

  • src/routes/landing/Hero.svelte
📚 Learning: 2024-11-22T08:37:27.996Z
Learnt from: mrh1997
Repo: themesberg/flowbite-svelte PR: 1442
File: src/lib/utils/Popper.svelte:144-145
Timestamp: 2024-11-22T08:37:27.996Z
Learning: In `src/lib/utils/Popper.svelte`, inconsistencies in event handling (e.g., using both `mouseenter`/`mouseleave` and `pointerenter`/`pointerleave`) may be intentional to minimize modifications and reduce the risk of new problems.

Applied to files:

  • src/routes/docs-examples/components/accordion/Nesting.svelte
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/routes/docs-examples/components/accordion/Color.svelte
🧬 Code graph analysis (2)
src/tests/accordion/Accordion.test.ts (1)
src/lib/accordion/theme.ts (1)
  • accordion (22-30)
src/lib/accordion/theme.ts (1)
src/lib/accordion/index.ts (2)
  • accordion (3-3)
  • accordionItem (3-3)
🔇 Additional comments (30)
src/routes/docs-examples/components/accordion/[slug]/+page.svelte (1)

1-8: LGTM! Clean implementation of dynamic content loading.

The component correctly uses Svelte 5 runes ($props and $derived) to load and render dynamic accordion examples based on the route slug.

workflow.md (1)

3-11: LGTM! Documentation cleanup.

Removed inline comments from git commands without affecting their functionality.

src/app.css (1)

1-29: LGTM! Proper Flowbite 4.0 theme setup.

The changes correctly configure Flowbite 4.0:

  • Imports Inter font for default theme
  • Includes default Flowbite theme
  • Provides commented alternative themes (MINIMAL, ENTERPRISE, PLAYFUL, MONO)
  • Adds Flowbite to @source for Tailwind CSS to scan

This aligns with the package.json upgrade to Flowbite 4.0.1.

src/routes/docs/components/accordion.md (2)

35-189: LGTM! Comprehensive documentation updates.

The documentation properly reflects the new classes-based styling API and includes:

  • Consistent height constraints for all example containers
  • New "Advanced styling" section demonstrating the classes prop
  • Clear "Component Props" section documenting both Accordion and AccordionItem props
  • Examples showing global and per-item styling overrides

This aligns well with the refactored accordion API.


192-209: LGTM! Clear component props documentation.

The new Component Props section provides a concise overview of both Accordion and AccordionItem props, making it easy for developers to understand the available options without diving into the full component data section below.

src/lib/alert/theme.ts (1)

33-33: rounded-base is a valid Flowbite 4.0 class.

The class rounded-base is used extensively in official Flowbite 4.0 documentation and is provided by the Flowbite plugin as part of the design system. The change from rounded-lg to rounded-base aligns with Flowbite 4.0 standards and requires no additional configuration.

package.json (1)

158-158: Verify JavaScript API compatibility for Carousel, Accordion, and Tabs components.

Flowbite 4.0 introduces breaking changes to the JavaScript API: Carousel, Accordion, and Tabs objects now require the HTML element as the first parameter instead of just the ID. If the codebase programmatically creates these components via JavaScript (rather than using data attributes), updates are necessary. The data attributes interface remains unchanged.

src/routes/landing/Hero.svelte (1)

13-13: text-heading is a valid Flowbite semantic color class and is properly configured.

The text-heading class is part of the Flowbite design system's semantic color palette, automatically generated from the --color-heading CSS variable via the Flowbite plugin imported in your app.css. No custom CSS definition is required—the class is provided by the Flowbite theme and is already in use elsewhere in the codebase.

src/lib/types.ts (1)

350-361: Context type properly aligned with props.

The AccordionContextType correctly mirrors the new classes structure from AccordionProps, ensuring consistent typing throughout the context chain.

src/lib/accordion/theme.ts (3)

7-20: Helpful documentation comment.

The inline type documentation for AccordionItemVariants clearly shows the structure of the classes prop, making it easier for developers to understand the API without referring to separate type files.


22-30: Clean accordion base styling.

The updated base classes provide a consistent container style with rounded corners, borders, and overflow handling. The flush variant appropriately removes borders or adds shadows based on the variant.


32-79: Comprehensive item theming with proper variants.

The slot-based theme configuration with open and flush variants, along with compound variants for state combinations, provides excellent flexibility for styling accordion items. The default variants ensure sensible defaults.

src/routes/docs-examples/components/accordion/Nesting.svelte (1)

1-24: Consistent use of typography component.

The refactor to use the P component for text content provides better consistency with the library's typography system. The change is straightforward and maintains the existing accordion structure.

src/tests/accordion/basic-accordion.test.svelte (1)

1-14: Good baseline test for accordion.

This test file provides a simple, foundational test case for the accordion component with proper data-testid attributes for querying elements during testing.

src/routes/docs-examples/components/bottom-navigation/Pagination.svelte (1)

19-35: Consistent border radius standardization.

The update from rounded-lg variants to rounded-base variants aligns with the broader theme standardization across the library, maintaining visual consistency.

src/tests/accordion/classes-accordion.test.svelte (1)

1-16: Excellent test coverage for new classes prop.

This test validates the new classes prop API with concrete examples of active and inactive state styling. The test clearly demonstrates how developers should use the new prop structure.

src/tests/accordion/flush-accordion.test.svelte (1)

1-10: Focused test for flush variant.

This test appropriately validates the flush variant of the accordion, providing clear coverage for this styling option.

src/routes/docs-examples/components/accordion/index.ts (1)

1-19: New example exports added.

The addition of AdvancedClasses and Snapshot exports expands the documentation examples for the accordion component. All referenced files exist and exports are valid.

src/tests/accordion/no-transition-accordion.test.svelte (1)

1-10: LGTM!

The test structure is clean and appropriately exercises the no-transition scenario with proper data-testid attributes for assertions.

src/tests/accordion/open-accordion.test.svelte (1)

1-14: LGTM!

The test correctly validates both open and closed states of accordion items with appropriate test identifiers.

src/tests/accordion/multiple-accordion.test.svelte (1)

1-14: LGTM!

The test appropriately validates the multiple-open accordion mode with clear test identifiers.

src/tests/accordion/custom-arrows-accordion.test.svelte (1)

1-17: LGTM!

The test correctly demonstrates custom arrow icon usage via snippets with appropriate test identifiers for validation.

src/routes/docs-examples/components/accordion/MultipleMode2.svelte (1)

14-14: LGTM!

The content simplification improves documentation clarity while maintaining the same component usage pattern.

Also applies to: 18-18

src/routes/docs-examples/components/accordion/AdvancedClasses.svelte (1)

1-21: LGTM!

This example effectively demonstrates the new unified classes prop API with clear per-part styling for button, content, active, and inactive states. The purple-themed example provides good visual contrast between active and inactive states.

src/lib/accordion/Accordion.svelte (2)

22-24: LGTM!

The new classes getter in the reactive context correctly provides the unified classes object to child components through context, aligning with the broader API refactoring.


10-10: The activeClass/inactiveClass props work correctly with backward compatibility maintained.

The AccordionItem component accepts both individual activeClass/inactiveClass props and a newer classes prop, with a fallback hierarchy: when classes is provided it's used, otherwise individual props are applied, and if neither is provided, default styles are used. The Accordion component passes activeClass and inactiveClass to context, allowing them to apply to all child AccordionItems.

The documentation explicitly supports both patterns: "You can control the look and feel of AccordionItems by overwriting the activeClass and inactiveClass properties. You can define them in Accordion so that they will apply to all children or set them individually on each AccordionItem."

The props are not deprecated—they coexist intentionally. No migration needed; existing code continues to work.

src/lib/pagination/theme.ts (1)

28-29: LGTM! Consistent border radius token update.

The navigation layout variants correctly use rounded-s-base and rounded-e-base for start/end rounding, aligning with the project's design token standardization.

src/routes/docs-examples/components/accordion/Color.svelte (1)

5-24: LGTM! Clear demonstration of the new classes-based API.

This example effectively showcases:

  1. Global styling via the parent Accordion's classes prop (lines 7-10)
  2. Per-item overrides via AccordionItem's classes prop (lines 17-20)

The distinction between parent-provided and item-specific styling is well-documented in the content text.

src/tests/accordion/Accordion.test.ts (1)

204-244: Good accessibility test coverage.

The accessibility tests validate essential patterns: proper button roles, type="button" attribute, aria-expanded state tracking, and keyboard navigation (Tab, Enter, Space). This provides a solid baseline for WCAG compliance.

src/lib/accordion/AccordionItem.svelte (1)

29-30: LGTM! Correct reactive theme pattern.

The getTheme call is correctly wrapped in $derived(), ensuring the component reacts to dynamic theme changes from ThemeProvider. Based on learnings, this is the correct pattern.

Comment on lines 199 to 212
export interface AccordionProps extends AccordionVariants, Omit<HTMLAttributes<HTMLDivElement>, "color"> {
children: Snippet;
multiple?: boolean;
activeClass?: string;
inactiveClass?: string;
activeClass?: ClassValue;
inactiveClass?: ClassValue;
transitionType?: TransitionFunc | "none";
classes?: Partial<{
button?: ClassValue;
contentWrapper?: ClassValue;
content?: ClassValue;
active?: ClassValue;
inactive?: ClassValue;
}>;
}
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 18, 2025

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

🏁 Script executed:

# First, let's see the exact content of src/lib/types.ts around lines 199-212
sed -n '195,215p' src/lib/types.ts

Repository: themesberg/flowbite-svelte

Length of output: 776


🏁 Script executed:

# Also search for all occurrences of AccordionProps, AccordionContextType, and AccordionItemProps
rg -n 'interface.*Accordion.*Props|type.*Accordion.*Type' src/lib/types.ts

Repository: themesberg/flowbite-svelte

Length of output: 284


🏁 Script executed:

# Search for any remaining usage of activeClass/inactiveClass in Accordion components
rg -n 'activeClass|inactiveClass' src/lib/accordion/ --type svelte --type ts

Repository: themesberg/flowbite-svelte

Length of output: 100


🏁 Script executed:

# Search for Accordion component usage in example files or tests
find src -type f \( -name "*.svelte" -o -name "*.ts" \) ! -path "*/node_modules/*" | head -20 | xargs rg "activeClass|inactiveClass" 2>/dev/null | head -20

Repository: themesberg/flowbite-svelte

Length of output: 1029


Well-structured API expansion for improved customization.

The addition of the classes object alongside existing activeClass/inactiveClass props provides better organization and scalability while maintaining backward compatibility. The nested structure (button, contentWrapper, content, active, inactive) and use of ClassValue improve flexibility.

To complete this API modernization, add deprecation notices to activeClass and inactiveClass in the JSDoc comments, and update documentation to guide users toward the classes object pattern. Ensure AccordionItemProps receives the same treatment for consistency.

🤖 Prompt for AI Agents
In src/lib/types.ts around lines 199 to 212, add JSDoc deprecation notes for the
legacy props activeClass and inactiveClass on AccordionProps and apply the same
JSDoc changes to AccordionItemProps: mark each as @deprecated, provide the
recommended replacement (use classes.active / classes.inactive) and a short
migration hint; also update the project documentation/README to mention the new
classes object pattern and show a small example migrating from
activeClass/inactiveClass to classes.{active,inactive} for consistency across
the API.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Since it is a breaking change, it will be in announcement.

Copy link
Contributor

Choose a reason for hiding this comment

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

@shinokada, that makes perfect sense! Since this is a breaking change for version 2, documenting it in the announcement and migration guide is the right approach. Deprecation warnings are typically used for gradual transitions within the same major version, but for a major version bump, a clear announcement with migration examples will serve users better.

Thank you for clarifying the versioning strategy! 👍

@shinokada
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
ALERT_FIXES_SUMMARY.md (1)

1-120: Consider relocating documentation to a standard location.

This summary document is helpful for understanding the Alert component changes. However, placing it in src/ is unconventional. Consider moving it to:

  • Project root for visibility (e.g., MIGRATION.md or CHANGELOG.md)
  • docs/ directory if one exists
  • Or remove it before merging if it's only for review purposes
src/routes/docs/components/alert.md (1)

95-99: Consider minor grammar improvement.

The documentation accurately describes the closeColor prop functionality.

Consider the grammar improvement suggested by LanguageTool:

Optional grammar fix
-Use the `class` prop with `color="none"` to create fully custom styled alerts. The `closeColor` prop allows independent control of the close button styling, letting you mix custom alert colors with predefined close button colors or use `closeColor="none"` for complete customization.
+Use the `class` prop with `color="none"` to create fully custom-styled alerts. The `closeColor` prop allows independent control of the close button styling, letting you mix custom alert colors with predefined close button colors or use `closeColor="none"` for complete customization.
src/tests/alert/alert.test.ts (1)

20-176: Test suite is comprehensive and well-structured.

The tests properly validate the updated Alert API with new design tokens. All major functionality is covered: basic rendering, color variants, dismissible behavior, icons, borders, visibility, custom styling, and events.

💡 Optional: Expand test coverage for closeColor prop

The AI summary indicates that the Alert component now includes a closeColor prop (referenced in the relevant code snippets from src/lib/utils/theme.ts). Consider adding a test to verify that the close button renders with the correct color classes when closeColor is specified:

+  describe("Close Button Color", () => {
+    test("renders close button with specified closeColor classes", () => {
+      // Create a test component that uses Alert with closeColor prop
+      render(CloseColorAlertTest);
+      const closeButton = screen.getByRole("button");
+
+      // Verify closeButton has the appropriate color classes
+      expect(closeButton).toHaveClass("text-fg-success-strong");
+      expect(closeButton).toHaveClass("bg-success-soft");
+    });
+  });

This would ensure the close button styling API is working correctly.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 91424ba and ccf9128.

📒 Files selected for processing (33)
  • ALERT_FIXES_SUMMARY.md (1 hunks)
  • src/lib/accordion/AccordionItem.svelte (3 hunks)
  • src/lib/alert/Alert.svelte (3 hunks)
  • src/lib/alert/theme.ts (2 hunks)
  • src/lib/pagination/Pagination.svelte (2 hunks)
  • src/lib/pagination/theme.ts (5 hunks)
  • src/lib/types.ts (3 hunks)
  • src/lib/utils/theme.ts (3 hunks)
  • src/routes/builder/alert/+page.svelte (3 hunks)
  • src/routes/docs-examples/components/accordion/[slug]/+page.ts (1 hunks)
  • src/routes/docs-examples/components/alert/AdditionalContent.svelte (2 hunks)
  • src/routes/docs-examples/components/alert/AlertWithList.svelte (2 hunks)
  • src/routes/docs-examples/components/alert/BorderAccent.svelte (1 hunks)
  • src/routes/docs-examples/components/alert/Bordered.svelte (1 hunks)
  • src/routes/docs-examples/components/alert/CustomColor.svelte (1 hunks)
  • src/routes/docs-examples/components/alert/Default.svelte (1 hunks)
  • src/routes/docs-examples/components/alert/Dismissable.svelte (1 hunks)
  • src/routes/docs-examples/components/alert/Icon.svelte (1 hunks)
  • src/routes/docs-examples/extend/scroll-spy/+page.svelte (1 hunks)
  • src/routes/docs/components/alert.md (2 hunks)
  • src/tests/accordion/Accordion.test.ts (1 hunks)
  • src/tests/alert/README.md (1 hunks)
  • src/tests/alert/alert.test.ts (1 hunks)
  • src/tests/alert/basic-alert.test.svelte (1 hunks)
  • src/tests/alert/border-accent-alert.test.svelte (1 hunks)
  • src/tests/alert/bordered-alert.test.svelte (1 hunks)
  • src/tests/alert/close-event-alert.test.svelte (1 hunks)
  • src/tests/alert/colored-alert.test.svelte (1 hunks)
  • src/tests/alert/custom-close-icon-alert.test.svelte (1 hunks)
  • src/tests/alert/custom-color-alert.test.svelte (1 hunks)
  • src/tests/alert/dismissable-alert.test.svelte (1 hunks)
  • src/tests/alert/hidden-alert.test.svelte (1 hunks)
  • src/tests/alert/icon-alert.test.svelte (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/tests/alert/icon-alert.test.svelte
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/tests/accordion/Accordion.test.ts
  • src/lib/pagination/Pagination.svelte
  • src/routes/docs-examples/components/accordion/[slug]/+page.ts
  • src/lib/pagination/theme.ts
  • src/lib/types.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/tests/alert/border-accent-alert.test.svelte
  • src/routes/builder/alert/+page.svelte
  • src/routes/docs-examples/components/alert/Default.svelte
  • src/tests/alert/alert.test.ts
  • src/tests/alert/close-event-alert.test.svelte
  • src/tests/alert/hidden-alert.test.svelte
  • src/routes/docs-examples/extend/scroll-spy/+page.svelte
  • src/routes/docs-examples/components/alert/CustomColor.svelte
  • src/routes/docs-examples/components/alert/BorderAccent.svelte
  • src/routes/docs-examples/components/alert/AlertWithList.svelte
  • src/routes/docs-examples/components/alert/Icon.svelte
  • src/lib/accordion/AccordionItem.svelte
  • src/tests/alert/bordered-alert.test.svelte
  • src/routes/docs-examples/components/alert/Bordered.svelte
  • src/lib/alert/Alert.svelte
  • src/tests/alert/custom-close-icon-alert.test.svelte
  • src/tests/alert/colored-alert.test.svelte
  • src/tests/alert/basic-alert.test.svelte
  • src/tests/alert/custom-color-alert.test.svelte
  • src/tests/alert/dismissable-alert.test.svelte
  • src/lib/utils/theme.ts
  • src/lib/alert/theme.ts
  • src/routes/docs-examples/components/alert/Dismissable.svelte
  • src/routes/docs-examples/components/alert/AdditionalContent.svelte
🧠 Learnings (8)
📓 Common learnings
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/tests/alert/border-accent-alert.test.svelte
  • src/routes/builder/alert/+page.svelte
  • src/routes/docs-examples/components/alert/Default.svelte
  • src/tests/alert/close-event-alert.test.svelte
  • src/tests/alert/hidden-alert.test.svelte
  • src/routes/docs-examples/extend/scroll-spy/+page.svelte
  • src/routes/docs-examples/components/alert/CustomColor.svelte
  • src/routes/docs-examples/components/alert/BorderAccent.svelte
  • src/routes/docs-examples/components/alert/AlertWithList.svelte
  • src/routes/docs-examples/components/alert/Icon.svelte
  • src/lib/accordion/AccordionItem.svelte
  • src/tests/alert/bordered-alert.test.svelte
  • src/routes/docs-examples/components/alert/Bordered.svelte
  • src/lib/alert/Alert.svelte
  • src/tests/alert/custom-close-icon-alert.test.svelte
  • src/tests/alert/colored-alert.test.svelte
  • src/tests/alert/basic-alert.test.svelte
  • src/tests/alert/custom-color-alert.test.svelte
  • src/tests/alert/dismissable-alert.test.svelte
  • src/routes/docs-examples/components/alert/Dismissable.svelte
  • src/routes/docs-examples/components/alert/AdditionalContent.svelte
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/routes/docs-examples/components/alert/Default.svelte
  • src/routes/docs-examples/components/alert/CustomColor.svelte
  • src/routes/docs-examples/components/alert/BorderAccent.svelte
  • src/routes/docs-examples/components/alert/Icon.svelte
  • src/routes/docs-examples/components/alert/Bordered.svelte
  • src/lib/alert/theme.ts
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.

Applied to files:

  • src/routes/docs-examples/components/alert/BorderAccent.svelte
📚 Learning: 2025-03-20T11:11:53.952Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.952Z
Learning: In the Flowbite Svelte library, when implementing components with validation states, the 'inputInvalid' property should be explicitly defined and passed to the Wrapper component. When inputInvalid=true, the color should be set to "red" to ensure the ring/border styling is applied correctly.

Applied to files:

  • src/routes/docs-examples/components/alert/BorderAccent.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/docs/components/alert.md
📚 Learning: 2024-11-12T10:36:34.807Z
Learnt from: LahTeuto
Repo: themesberg/flowbite-svelte PR: 1484
File: src/lib/navbar/NavLi.svelte:34-34
Timestamp: 2024-11-12T10:36:34.807Z
Learning: When enhancing ARIA roles in Svelte components, avoid setting `role="presentation"` on elements that should retain the `link` role, as it can diminish ARIA role coverage and negatively affect accessibility.

Applied to files:

  • src/routes/docs/components/alert.md
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/docs/components/alert.md
🧬 Code graph analysis (1)
src/tests/alert/alert.test.ts (2)
src/lib/alert/theme.ts (1)
  • alert (6-61)
src/lib/utils/theme.ts (1)
  • closeButton (7-85)
🪛 LanguageTool
src/routes/docs/components/alert.md

[grammar] ~95-~95: Use a hyphen to join words.
Context: ...th color="none" to create fully custom styled alerts. The closeColor prop all...

(QB_NEW_EN_HYPHEN)

🔇 Additional comments (35)
src/lib/accordion/AccordionItem.svelte (3)

3-3: LGTM! Props refactoring aligns with the new API.

The import and props destructuring correctly reflect the migration to a consolidated classes object, replacing the removed individual class props (headerClass, contentClass, activeClass, inactiveClass).

Also applies to: 10-10


29-29: LGTM! Correct reactive theme pattern.

The getTheme() call is properly wrapped in $derived(), ensuring the component reacts to dynamic theme changes via ThemeProvider.

Based on learnings, this is the correct pattern for theme-aware components.


52-52: Button and content rendering logic is correct.

The class merging strategy properly prioritizes user overrides (finalClasses) over theme defaults for both the button (line 52) and content div (lines 77, 84). The rendering structure correctly handles both transition and non-transition cases.

Also applies to: 76-80, 83-87

src/lib/utils/theme.ts (4)

8-8: LGTM: Correct usage of Tailwind v4 outline utilities.

The use of focus:outline-hidden is correct for Tailwind v4, which distinguishes between outline-none (removes outline style only) and outline-hidden (removes outline completely).


40-43: LGTM: Explicit size mappings improve consistency.

The explicit padding and fixed height/width values for each size variant provide clearer, more predictable sizing behavior compared to relative sizing.


68-72: Unable to verify the md size variant change in src/lib/utils/theme.ts without access to the repository code and git history. Automated verification requires examining the actual theme configuration before and after this change to confirm whether the md size was previously handled differently and assess impact on existing CloseButton implementations.


11-15: Flowbite v4 design tokens confirmed as official and correctly used.

Flowbite v4 uses native CSS theme variables to customize colors and create utility classes. The design tokens including bg-brand-softer, text-fg-brand-strong, and focus:ring-brand-medium are documented official Flowbite v4 color variables. The color variants shown in lines 11-15 (brand, danger, success, warning, dark) align with standard Flowbite v4 semantic color naming conventions and are extensively used throughout official Flowbite components (badges, alerts, buttons, forms).

src/tests/alert/border-accent-alert.test.svelte (1)

1-5: LGTM: Clear and focused test component.

This test component correctly demonstrates the border accent functionality with appropriate props.

src/routes/docs-examples/components/alert/Default.svelte (1)

5-24: LGTM: Color prop updates align with new semantic token system.

The updated color values correctly map to the new semantic color system:

  • bluebrand
  • reddanger
  • greensuccess
  • yellowwarning
  • secondarydark

These changes are consistent with the Alert component's updated color variants.

src/tests/alert/custom-close-icon-alert.test.svelte (1)

1-6: LGTM: Proper demonstration of custom close icon functionality.

This test correctly shows how to override the default close icon with a custom component.

src/routes/docs-examples/extend/scroll-spy/+page.svelte (1)

90-90: LGTM: Alert color updated to match new semantic token system.

The color prop correctly changes from "red" to "danger" to align with the Alert component's updated color variants.

src/tests/alert/dismissable-alert.test.svelte (1)

1-5: LGTM: Clear demonstration of dismissable functionality.

This test component correctly demonstrates the dismissable Alert variant.

src/tests/alert/custom-color-alert.test.svelte (1)

1-5: LGTM: Proper demonstration of custom color styling.

This test correctly shows how to use color="none" to bypass built-in color variants and apply custom styling via the class prop.

src/tests/alert/bordered-alert.test.svelte (1)

1-5: LGTM! Clean border variant test.

The test file is appropriately minimal and focused on verifying the border prop functionality.

src/routes/docs-examples/components/alert/Bordered.svelte (1)

6-30: LGTM! Consistent semantic color token migration.

The migration from concrete color names (blue, red, green, yellow, secondary) to semantic tokens (brand, danger, success, warning, dark) improves code readability and aligns with the updated Alert API surface.

src/routes/builder/alert/+page.svelte (3)

21-21: LGTM! Default color updated to semantic token.

The default color change from "primary" to "brand" aligns with the semantic color token migration across the codebase.


77-77: LGTM! Code generation correctly omits default value.

The code generation logic now omits the color prop when it equals "brand" (the new default), which produces cleaner generated code.


156-156: LGTM! Radio component usage simplified.

The removal of the color prop from individual Radio elements simplifies the markup. The Radio component will use its default styling.

src/tests/alert/colored-alert.test.svelte (1)

1-5: LGTM! Clean color variant test.

The test correctly uses the new semantic color token "danger" to verify colored alert functionality.

src/tests/alert/close-event-alert.test.svelte (1)

1-14: LGTM! Well-structured close event test.

The test properly demonstrates:

  • Svelte 5 $state rune usage
  • Event handler implementation with onclose
  • Testable output with data-testid attribute
src/routes/docs-examples/components/alert/Icon.svelte (1)

6-30: LGTM! Consistent semantic color token migration.

The color prop updates mirror the changes in other documentation examples, maintaining consistency across the codebase with the new semantic tokens (brand, danger, success, warning, dark).

src/tests/alert/hidden-alert.test.svelte (1)

1-7: LGTM! Clean visibility binding test.

The test correctly demonstrates Alert visibility control via bind:alertStatus with proper Svelte 5 $state usage.

src/tests/alert/basic-alert.test.svelte (1)

1-5: LGTM! Essential baseline test.

The basic alert test provides a minimal baseline for verifying core Alert component functionality without any props.

src/routes/docs-examples/components/alert/BorderAccent.svelte (1)

6-30: LGTM! Color token migration is consistent.

The updates correctly map old color values to the new semantic token system:

  • color="brand" for info/blue context
  • color="danger" for red context
  • color="success" for green context
  • color="warning" for yellow context
  • color="dark" for dark/secondary context

The border accent styling (border-t-4) and component structure remain unchanged.

src/routes/docs-examples/components/alert/AlertWithList.svelte (1)

6-31: LGTM! Tailwind v4 syntax and color tokens are correct.

The changes properly implement:

  • New semantic color tokens (brand, danger)
  • Tailwind v4-compliant important modifier syntax (items-start! with ! at the end)
src/tests/alert/README.md (1)

1-83: Excellent test documentation!

This README provides comprehensive documentation for the Alert component test suite, including:

  • Clear test file organization
  • Test execution commands
  • Coverage checklist
  • Props reference table
  • Accessibility notes

The documentation aligns well with the Alert component's public API and supports the expanded test coverage in this PR.

src/routes/docs-examples/components/alert/AdditionalContent.svelte (1)

6-31: LGTM! Color tokens and text content are properly aligned.

The changes correctly update:

  • First alert to color="brand" with "info alert" messaging
  • Second alert to color="success" (from color="green") with matching "success alert" text

The updates maintain semantic consistency between color tokens and text content.

src/routes/docs-examples/components/alert/CustomColor.svelte (1)

6-35: Excellent showcase of custom styling capabilities!

The expanded examples effectively demonstrate:

  • Simple custom color overrides with Tailwind classes
  • Dark mode variants
  • Border styling integration
  • The new closeColor prop with both closeColor="none" (full control) and closeColor="danger" (mixed approach)
  • Proper usage of color="none" for custom styling

The examples align with the new Alert API and provide clear guidance for users implementing custom color schemes.

src/lib/alert/Alert.svelte (2)

67-72: Consistent close button color logic.

Both CloseButton instances (with and without custom CloseIcon) correctly use the same fallback logic: color={closeColor ?? color}. This ensures consistent behavior across both rendering paths.


15-16: New closeColor prop and default color change require verification.

The review claims default color changed from "primary" to "brand" and introduces a new closeColor prop. However, the official Flowbite-Svelte Alert component uses color="primary" as its default and does not expose a closeColor prop. If this is a custom implementation, verify that:

  • The default color change to "brand" is intentional and backward compatibility is addressed
  • The closeColor prop type correctly aligns with the close button's color variant support
  • The fallback logic (closeColor ?? color) is properly implemented in both CloseButton instances

Manual verification against the actual repository file is needed.

src/routes/docs/components/alert.md (2)

21-39: Clear and accurate color variant documentation.

The updated documentation effectively describes:

  • Semantic color tokens with clear use cases
  • Color variant purposes (brand for info, danger for errors, etc.)

The descriptions align with the component implementation and help users choose appropriate colors.


110-123: Excellent addition of accessibility and best practices sections.

The new sections provide valuable guidance:

  • Accessibility: Correctly references ARIA roles, keyboard interactions, and focus management
  • Best Practices: Offers practical, actionable guidance for alert usage

These additions enhance the documentation quality and help users implement alerts effectively.

src/routes/docs-examples/components/alert/Dismissable.svelte (1)

7-32: LGTM! Dismissable alerts correctly updated to new color tokens.

The changes properly migrate all color props to the new semantic token system:

  • brand, danger, success, warning, dark

Text content updates align with the new color semantics, and dismissable functionality with transitions and custom close icons is preserved.

src/tests/alert/alert.test.ts (1)

1-18: LGTM! Test setup is clean and follows best practices.

The imports are well-organized, and the global cleanup after each test ensures proper test isolation.

src/lib/alert/theme.ts (1)

10-60: LGTM! Color variants and theme structure align well with the v4 upgrade.

The updated color variants use the new design token system consistently:

  • Color options reduced to a focused set (brand, danger, success, warning, dark, none)
  • Design tokens follow a clear naming pattern
  • The none option provides flexibility for custom styling
  • Compound variants properly map border colors with the -subtle suffix
  • Default color changed from primary to brand aligns with the new token system

@shinokada
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/lib/accordion/theme.ts (2)

7-20: Helpful JSDoc documentation for variant structure.

The inline documentation clarifies the shape of AccordionItemVariants for consumers. Consider using ClassValue instead of string in the JSDoc to match the actual type from tailwind-variants.

🔎 Suggested improvement
 /**
  AccordionItemVariants:
 {
   flush?: boolean;
   open?: boolean;
   classes?: {
-    button?: string;
-    contentWrapper?: string;
-    content?: string;
-    active?: string;
-    inactive?: string;
+    button?: ClassValue;
+    contentWrapper?: ClassValue;
+    content?: ClassValue;
+    active?: ClassValue;
+    inactive?: ClassValue;
   }
 }
   */

59-74: Consider using design tokens for compound variant colors.

The compoundVariants use hardcoded Tailwind colors (text-gray-900, text-gray-500, etc.) while the base and other variants use design tokens (text-body, text-heading, border-default). For consistency with the theming system, consider using semantic tokens here as well.

🔎 Suggested improvement
   compoundVariants: [
     {
       flush: true,
       open: true,
       class: {
-        button: "text-gray-900 dark:text-white"
+        button: "text-heading"
       }
     },
     {
       flush: true,
       open: false,
       class: {
-        button: "text-gray-500 dark:text-gray-400"
+        button: "text-body"
       }
     }
   ],
src/routes/docs-examples/components/alert/Event.svelte (1)

14-24: Consider using {:else} for cleaner conditional rendering.

The two separate {#if} blocks can be simplified to a single {#if}/{:else} block for improved readability and slightly better performance.

🔎 Suggested improvement
 {#if alertStatus}
   <Alert dismissable onclick={closeAlert}>
     <span class="font-medium">Info alert!</span> You can close this alert by clicking the close button.
   </Alert>
-{/if}
-
-{#if !alertStatus}
+{:else}
   <div class="mt-4">
     <Button onclick={showAlert}>Show Alert Again</Button>
   </div>
 {/if}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ccf9128 and 3a54cfa.

📒 Files selected for processing (15)
  • .coderabbit.yml (1 hunks)
  • src/lib/accordion/AccordionItem.svelte (3 hunks)
  • src/lib/accordion/theme.ts (1 hunks)
  • src/lib/alert/Alert.svelte (4 hunks)
  • src/lib/alert/theme.ts (2 hunks)
  • src/lib/buttons/theme.ts (3 hunks)
  • src/lib/types.ts (3 hunks)
  • src/routes/docs-examples/components/alert/AdditionalContent.svelte (1 hunks)
  • src/routes/docs-examples/components/alert/AlertWithList.svelte (2 hunks)
  • src/routes/docs-examples/components/alert/BorderAccent.svelte (1 hunks)
  • src/routes/docs-examples/components/alert/Event.svelte (1 hunks)
  • src/routes/docs/components/alert.md (2 hunks)
  • src/routes/docs/components/buttons.md (11 hunks)
  • src/tests/alert/alert.test.ts (1 hunks)
  • src/tests/alert/close-color-alert.test.svelte (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/routes/docs-examples/components/alert/BorderAccent.svelte
  • src/tests/alert/alert.test.ts
  • src/lib/accordion/AccordionItem.svelte
  • src/routes/docs-examples/components/alert/AlertWithList.svelte
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/routes/docs-examples/components/alert/Event.svelte
  • src/lib/buttons/theme.ts
  • src/tests/alert/close-color-alert.test.svelte
  • src/lib/alert/theme.ts
  • src/lib/types.ts
  • src/lib/alert/Alert.svelte
  • src/routes/docs-examples/components/alert/AdditionalContent.svelte
  • src/lib/accordion/theme.ts
🧠 Learnings (11)
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/routes/docs-examples/components/alert/Event.svelte
  • src/tests/alert/close-color-alert.test.svelte
  • src/lib/alert/Alert.svelte
  • src/routes/docs-examples/components/alert/AdditionalContent.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Use getComponentList tool to discover available Flowbite-Svelte components or help users explore component options

Applied to files:

  • src/routes/docs/components/buttons.md
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use the Flowbite-Svelte MCP server to access comprehensive component documentation

Applied to files:

  • src/routes/docs/components/buttons.md
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/routes/docs/components/buttons.md
  • src/lib/alert/theme.ts
  • src/routes/docs-examples/components/alert/AdditionalContent.svelte
📚 Learning: 2024-11-12T10:36:34.807Z
Learnt from: LahTeuto
Repo: themesberg/flowbite-svelte PR: 1484
File: src/lib/navbar/NavLi.svelte:34-34
Timestamp: 2024-11-12T10:36:34.807Z
Learning: When enhancing ARIA roles in Svelte components, avoid setting `role="presentation"` on elements that should retain the `link` role, as it can diminish ARIA role coverage and negatively affect accessibility.

Applied to files:

  • src/routes/docs/components/buttons.md
  • src/routes/docs/components/alert.md
📚 Learning: 2025-09-04T10:33:41.720Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1751
File: src/lib/tabs/TabItem.svelte:33-33
Timestamp: 2025-09-04T10:33:41.720Z
Learning: In Svelte 5, DOM event handlers should use function props like `onclick`, `onchange`, `oninput` etc. The `on:click`, `on:change` syntax from previous Svelte versions is deprecated/obsolete in Svelte 5.

Applied to files:

  • src/routes/docs/components/buttons.md
📚 Learning: 2025-08-31T14:31:57.582Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1745
File: src/lib/forms/checkbox/CheckboxButton.svelte:16-17
Timestamp: 2025-08-31T14:31:57.582Z
Learning: In Svelte 5, the `on:event` syntax for event forwarding is obsolete. Event handlers are passed as callback props (e.g., `onchange`, `oninput`) through `{...restProps}` instead of using `on:change`, `on:input` etc.

Applied to files:

  • src/routes/docs/components/buttons.md
📚 Learning: 2024-11-22T08:37:27.996Z
Learnt from: mrh1997
Repo: themesberg/flowbite-svelte PR: 1442
File: src/lib/utils/Popper.svelte:144-145
Timestamp: 2024-11-22T08:37:27.996Z
Learning: In `src/lib/utils/Popper.svelte`, inconsistencies in event handling (e.g., using both `mouseenter`/`mouseleave` and `pointerenter`/`pointerleave`) may be intentional to minimize modifications and reduce the risk of new problems.

Applied to files:

  • src/routes/docs/components/buttons.md
📚 Learning: 2025-11-03T10:08:17.733Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1819
File: src/lib/tour/Tour.svelte:21-24
Timestamp: 2025-11-03T10:08:17.733Z
Learning: In Svelte 5 components, custom event handler props should follow the lowercase naming convention (e.g., `oncomplete`, `onskip`, `onopen`) rather than camelCase (e.g., `onComplete`, `onSkip`, `onOpen`), consistent with DOM event handlers like `onclick`, `onchange`, etc.

Applied to files:

  • src/routes/docs/components/buttons.md
📚 Learning: 2025-08-31T13:01:17.658Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1745
File: src/lib/forms/checkbox/Checkbox.svelte:22-27
Timestamp: 2025-08-31T13:01:17.658Z
Learning: createEventDispatcher is deprecated in Svelte 5. Components should use callback props instead of event dispatchers for event handling.

Applied to files:

  • src/routes/docs/components/buttons.md
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/docs/components/alert.md
🧬 Code graph analysis (2)
src/lib/types.ts (1)
src/lib/utils/theme.ts (1)
  • CloseButtonVariants (5-5)
src/lib/accordion/theme.ts (1)
src/lib/accordion/index.ts (2)
  • accordion (3-3)
  • accordionItem (3-3)
🔇 Additional comments (21)
src/routes/docs/components/buttons.md (1)

59-59: LGTM! Documentation improvements are clear and concise.

The editorial changes improve readability by simplifying explanations while maintaining accuracy. The update on Line 179 correctly uses lowercase onclick syntax, which aligns with Svelte 5 conventions for event handlers.

Based on learnings, the lowercase event handler syntax (onclick, onchange, etc.) is the correct pattern for Svelte 5.

Also applies to: 79-79, 99-99, 109-109, 119-119, 129-129, 139-139, 149-149, 159-159, 169-169, 179-179

src/lib/buttons/theme.ts (1)

150-150: Ensure rounded-base is defined in your Tailwind configuration.

The changes use rounded-base for non-pill button variants across multiple components (buttons, pagination, accordion, alert). This is not a standard Tailwind CSS utility class and must be defined as a custom design token in your project's Tailwind configuration (tailwind.config.js, tailwind.config.ts, or in your main CSS file for Tailwind v4 via the @theme directive). If this token is not defined, buttons will render without the intended border radius styling.

src/lib/types.ts (4)

199-212: Well-structured props consolidation for Accordion.

The classes object provides a clean API for customizing accordion sub-components while maintaining the individual activeClass/inactiveClass props. The structure aligns with the AccordionContextType definition below.


214-221: LGTM!

AccordionItemProps correctly extends AccordionItemVariants which includes the classes structure via Classes<typeof accordionItem>, allowing per-item styling overrides.


224-235: LGTM!

The new closeColor, listContent, and borderAccent props extend the Alert API appropriately. Using CloseButtonVariants["color"] for closeColor ensures type consistency with the CloseButton component.


353-364: LGTM!

The AccordionContextType now mirrors the classes structure from AccordionProps, providing a clean mechanism for passing styling configuration to child AccordionItem components via context.

src/lib/accordion/theme.ts (2)

22-30: LGTM!

The updated base styling uses design tokens (rounded-base, border-default) for better theming consistency. The simplified flush variants are cleaner and more maintainable.


75-79: LGTM!

Sensible default variants ensure accordions render in the non-flush, closed state by default.

src/tests/alert/close-color-alert.test.svelte (1)

1-5: LGTM!

Clean test fixture for validating the new closeColor prop on the Alert component. The component correctly uses the dismissable prop alongside closeColor="success".

src/routes/docs/components/alert.md (3)

21-40: LGTM! Clear semantic color guidance.

The documentation provides clear, action-oriented descriptions and well-defined use cases for each color variant. The semantic naming (brand, danger, success, warning, dark) aligns with the updated theme tokens.


95-95: Excellent documentation of the closeColor prop.

The explanation clearly describes the flexibility of independent close button styling and the ability to mix custom alert colors with predefined close button colors.


111-114: LGTM! Solid accessibility guidance.

The accessibility section properly emphasizes multi-sensory feedback (not relying on color alone), keyboard interactions, and focus management, which aligns with WCAG best practices.

src/lib/alert/Alert.svelte (3)

15-24: LGTM! New props align with v2 theme system.

The addition of closeColor, listContent, and borderAccent props provides fine-grained control over alert styling. The default color change from "primary" to "brand" is a breaking change but aligns with the v2 semantic token system documented in the PR.


29-42: LGTM! Proper reactive theme integration.

The use of $derived for both theme and divCls ensures the component reacts to dynamic theme changes, which is the correct pattern for ThemeProvider integration in Flowbite-Svelte (as per learnings).


69-76: LGTM! Consistent closeColor fallback logic.

Both dismissible alert paths (with and without custom close icon) correctly use closeColor ?? color, providing consistent fallback behavior and independent close button styling control.

src/routes/docs-examples/components/alert/AdditionalContent.svelte (2)

6-17: LGTM! Correct usage of listContent with brand color.

The first alert properly demonstrates the listContent prop with color="brand". The text "info alert" is semantically appropriate since the brand color is documented as being for "General information or tips."


18-27: LGTM! Consistent usage pattern.

The second alert correctly demonstrates listContent with color="success", maintaining consistency with the updated semantic color system.

src/lib/alert/theme.ts (4)

7-16: LGTM! Clean token-based color system.

The color variants use consistent semantic tokens with appropriate text and background classes. The none variant provides an escape hatch for fully custom styling, which aligns with the documentation.


17-34: LGTM! Well-structured variant system.

The variants are properly defined with listContent and borderAccent being handled primarily through compound variants (empty string base + specific compound classes), while borderAccent.true correctly adds the top border accent.


36-86: LGTM! Complete compound variant coverage.

All color variants are properly covered for both listContent and border combinations. The token naming is consistent (e.g., bg-brand-softer, border-brand-subtle) and provides appropriate visual distinction.


87-117: LGTM! Complete theme configuration.

The borderAccent compound variants cover all color combinations with consistent token usage. The default color change to "brand" (line 114) is a documented breaking change that aligns with the v2 semantic token system.

@shinokada
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 17

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/lib/indicator/Indicator.svelte (1)

39-39: Update outdated documentation comment.

The inline documentation still references the old default value "primary". Update to "brand" to match the current implementation.

🔎 Proposed fix
-@prop color = "primary"
+@prop color = "brand"
src/routes/builder/avatar/+page.svelte (1)

79-79: Update generated code example to use semantic token.

The generatedCode template still references the old "green" color token. This creates inconsistency with the actual implementation and may confuse users copying the generated code.

🔎 Proposed fix
-      if (dotStatus) props.push('dot={{ placement: "bottom-right", color: "green" }}');
+      if (dotStatus) props.push('dot={{ placement: "bottom-right", color: "success" }}');
♻️ Duplicate comments (4)
src/routes/builder/popover/+page.svelte (1)

119-119: Consistent with Radio refactor across builder pages.

The change to classes={{ label: "w-24" }} is consistent with the broader migration pattern seen across multiple builder pages.

src/routes/builder/floating-label/+page.svelte (1)

86-86: Consistent Radio migration pattern.

src/routes/builder/input-field/+page.svelte (1)

94-94: Consistent Radio migration pattern.

src/routes/builder/button-group/+page.svelte (1)

102-102: Consistent Radio migration pattern.

🧹 Nitpick comments (4)
src/routes/docs-examples/extend/step-indicator/Colors.svelte (1)

4-4: Consider explicitly typing the colors array for better type safety.

The colors array is inferred as string[], which means TypeScript won't catch typos or invalid color values at compile time. Consider typing it explicitly to ensure all values are valid:

🔎 Proposed improvement
-const colors = ["primary", "secondary", "gray", "red", "yellow", "green", "indigo", "purple", "pink", "blue"];
+const colors: StepIndicatorProps["color"][] = ["primary", "secondary", "gray", "red", "yellow", "green", "indigo", "purple", "pink", "blue"];

Alternatively, use a const assertion to preserve literal types:

-const colors = ["primary", "secondary", "gray", "red", "yellow", "green", "indigo", "purple", "pink", "blue"];
+const colors = ["primary", "secondary", "gray", "red", "yellow", "green", "indigo", "purple", "pink", "blue"] as const;

Note: The const assertion approach would require adjusting line 17 to handle readonly tuple types.

src/lib/accordion/theme.ts (1)

48-52: Consider deduplicating border classes.

The flush: false button includes border border-t-0 border-x-0 border-b-default, which duplicates the same classes in the base button slot (line 35). While tailwind-variants merges these correctly, this redundancy creates maintenance overhead.

🔎 Suggested refactor to remove redundant classes

Since the border styling is already defined in the base button slot (line 35), you can remove it from the flush: false variant:

      false: {
-        button: "rounded-t-base border border-t-0 border-x-0 border-b-default hover:text-heading hover:bg-neutral-secondary-medium",
+        button: "rounded-t-base hover:text-heading hover:bg-neutral-secondary-medium",
        contentWrapper: "border border-s-0 border-e-0 border-t-0 border-b-default",
        content: "p-4 md:p-5"
      }

This reduces duplication and makes future border styling changes easier to maintain.

src/plugin-utilities.js (1)

11-146: Consider programmatic generation for maintainability.

The 135-line static object is verbose and repetitive. Consider generating these utilities programmatically to improve maintainability and reduce duplication.

🔎 Proposed refactor using programmatic generation
-  const colorUtilities = {
-    // Success colors
-    ".bg-success-soft": { backgroundColor: "var(--color-success-soft)" },
-    ".bg-success": { backgroundColor: "var(--color-success)" },
-    ".bg-success-medium": { backgroundColor: "var(--color-success-medium)" },
-    ".bg-success-strong": { backgroundColor: "var(--color-success-strong)" },
-
-    ".text-success-soft": { color: "var(--color-success-soft)" },
-    // ... (130+ more lines)
-  };
+  const colorGroups = {
+    success: ['soft', 'medium', 'strong'],
+    danger: ['soft', 'medium', 'strong'],
+    warning: ['soft', 'medium', 'strong'],
+    dark: ['soft', 'strong'],
+    brand: ['softer', 'soft', 'medium', 'strong']
+  };
+
+  const singleColors = ['purple', 'sky', 'teal', 'pink', 'cyan', 'fuchsia', 'indigo', 'orange'];
+  
+  const fgColors = {
+    'fg-brand': ['subtle', '', 'strong'],
+    'fg-success': ['', 'strong'],
+    'fg-danger': ['', 'strong'],
+    'fg-warning': ['', 'subtle'],
+    'fg-purple': [''],
+    'fg-cyan': [''],
+    'fg-indigo': [''],
+    'fg-pink': ['']
+  };
+
+  const colorUtilities = {};
+  const prefixes = ['bg', 'text', 'border'];
+
+  // Generate grouped color utilities
+  for (const [group, variants] of Object.entries(colorGroups)) {
+    // Base color
+    for (const prefix of prefixes) {
+      colorUtilities[`.${prefix}-${group}`] = { 
+        [prefix === 'bg' ? 'backgroundColor' : prefix === 'text' ? 'color' : 'borderColor']: 
+          `var(--color-${group})` 
+      };
+    }
+    
+    // Variants
+    for (const variant of variants) {
+      const token = variant ? `${group}-${variant}` : group;
+      for (const prefix of prefixes) {
+        colorUtilities[`.${prefix}-${token}`] = {
+          [prefix === 'bg' ? 'backgroundColor' : prefix === 'text' ? 'color' : 'borderColor']:
+            `var(--color-${token})`
+        };
+      }
+    }
+    
+    // Ring utilities
+    colorUtilities[`.ring-${group}-subtle`] = { 
+      '--tw-ring-color': `var(--color-${group}-subtle)` 
+    };
+  }
+
+  // Generate single color utilities
+  for (const color of singleColors) {
+    for (const prefix of prefixes) {
+      colorUtilities[`.${prefix}-${color}`] = {
+        [prefix === 'bg' ? 'backgroundColor' : prefix === 'text' ? 'color' : 'borderColor']:
+          `var(--color-${color})`
+      };
+    }
+  }
+
+  // Generate foreground utilities
+  for (const [color, variants] of Object.entries(fgColors)) {
+    for (const variant of variants) {
+      const token = variant ? `${color}-${variant}` : color;
+      colorUtilities[`.text-${token}`] = { color: `var(--color-${token})` };
+    }
+  }
+  
+  // Add special utilities
+  colorUtilities['.bg-disabled'] = { backgroundColor: 'var(--color-disabled)' };
+  colorUtilities['.text-disabled'] = { color: 'var(--color-disabled)' };
src/lib/forms/radio/theme.ts (1)

7-57: Consider validation state focus styling based on learnings.

Based on retrieved learnings, form components in Flowbite Svelte need dynamic focus-within styling for validation states. The current implementation only defines base focus styles but doesn't account for validation scenarios where inputInvalid=true.

Consider adding focusWithinClasses that dynamically adjust based on validation state, ensuring proper color coordination when errors occur.

Based on learnings: In the Flowbite Svelte library's form components, both regular focus styling and focus-within styling need dynamic adjustment based on validation state.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a54cfa and f46178b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (59)
  • .coderabbit.yml (1 hunks)
  • BRAND-COLOR-OVERRIDE-GUIDE.md (1 hunks)
  • BRAND-OVERRIDE-SUMMARY.md (1 hunks)
  • QUICK-REFERENCE.md (1 hunks)
  • SOLUTION-SUMMARY.md (1 hunks)
  • TESTING-AND-PR-GUIDE.md (1 hunks)
  • src/app.css (3 hunks)
  • src/lib/accordion/theme.ts (2 hunks)
  • src/lib/avatar/Avatar.svelte (1 hunks)
  • src/lib/forms/radio/Radio.svelte (1 hunks)
  • src/lib/forms/radio/theme.ts (2 hunks)
  • src/lib/indicator/Indicator.svelte (1 hunks)
  • src/lib/indicator/theme.ts (2 hunks)
  • src/plugin-utilities.js (1 hunks)
  • src/routes/admin-dashboard/(sidebar)/crud/users/+page.svelte (1 hunks)
  • src/routes/builder/avatar/+page.svelte (3 hunks)
  • src/routes/builder/badge/+page.svelte (1 hunks)
  • src/routes/builder/banner/+page.svelte (1 hunks)
  • src/routes/builder/button-group/+page.svelte (1 hunks)
  • src/routes/builder/button/+page.svelte (1 hunks)
  • src/routes/builder/card/+page.svelte (1 hunks)
  • src/routes/builder/checkbox/+page.svelte (1 hunks)
  • src/routes/builder/floating-label/+page.svelte (1 hunks)
  • src/routes/builder/indicators/+page.svelte (2 hunks)
  • src/routes/builder/input-field/+page.svelte (1 hunks)
  • src/routes/builder/label/+page.svelte (1 hunks)
  • src/routes/builder/link/+page.svelte (1 hunks)
  • src/routes/builder/popover/+page.svelte (1 hunks)
  • src/routes/builder/progress/+page.svelte (1 hunks)
  • src/routes/builder/radio/+page.svelte (4 hunks)
  • src/routes/builder/range/+page.svelte (1 hunks)
  • src/routes/builder/span/+page.svelte (0 hunks)
  • src/routes/builder/spinner/+page.svelte (1 hunks)
  • src/routes/builder/table/+page.svelte (1 hunks)
  • src/routes/builder/toast/+page.svelte (1 hunks)
  • src/routes/builder/toggle/+page.svelte (1 hunks)
  • src/routes/builder/tooltip/+page.svelte (1 hunks)
  • src/routes/docs-examples/components/alert/AdditionalContent.svelte (1 hunks)
  • src/routes/docs-examples/components/alert/Event.svelte (1 hunks)
  • src/routes/docs-examples/components/avatar/CustomDot.svelte (1 hunks)
  • src/routes/docs-examples/components/avatar/DotIndicator.svelte (1 hunks)
  • src/routes/docs-examples/components/avatar/UserDropdown.svelte (1 hunks)
  • src/routes/docs-examples/components/badge/Notification.svelte (1 hunks)
  • src/routes/docs-examples/components/carousel/Advanced.svelte (1 hunks)
  • src/routes/docs-examples/components/dropdown/Notification.svelte (3 hunks)
  • src/routes/docs-examples/components/dropdown/User.svelte (1 hunks)
  • src/routes/docs-examples/components/indicators/Badge.svelte (2 hunks)
  • src/routes/docs-examples/components/indicators/Count.svelte (1 hunks)
  • src/routes/docs-examples/components/indicators/Default.svelte (1 hunks)
  • src/routes/docs-examples/components/indicators/Legend.svelte (1 hunks)
  • src/routes/docs-examples/components/indicators/Position.svelte (1 hunks)
  • src/routes/docs-examples/components/indicators/Status.svelte (1 hunks)
  • src/routes/docs-examples/components/indicators/Stepper.svelte (2 hunks)
  • src/routes/docs-examples/extend/step-indicator/Colors.svelte (1 hunks)
  • src/routes/docs-examples/forms/radio/Colors.svelte (1 hunks)
  • src/routes/docs-examples/pages/theme-provider/Theme2.svelte (1 hunks)
  • src/routes/docs/components/indicators.md (1 hunks)
  • src/routes/landing/Hero.svelte (1 hunks)
  • src/tests/alert/alert.test.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • src/routes/builder/span/+page.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/routes/docs-examples/components/alert/Event.svelte
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/routes/builder/button-group/+page.svelte
  • src/routes/builder/avatar/+page.svelte
  • src/routes/builder/indicators/+page.svelte
  • src/routes/docs-examples/components/dropdown/User.svelte
  • src/routes/docs-examples/forms/radio/Colors.svelte
  • src/routes/builder/input-field/+page.svelte
  • src/routes/builder/badge/+page.svelte
  • src/routes/docs-examples/pages/theme-provider/Theme2.svelte
  • src/routes/docs-examples/components/indicators/Badge.svelte
  • src/lib/forms/radio/Radio.svelte
  • src/routes/docs-examples/components/indicators/Status.svelte
  • src/routes/builder/checkbox/+page.svelte
  • src/routes/docs-examples/components/carousel/Advanced.svelte
  • src/plugin-utilities.js
  • src/routes/docs-examples/components/avatar/UserDropdown.svelte
  • src/routes/builder/table/+page.svelte
  • src/routes/builder/range/+page.svelte
  • src/routes/docs-examples/components/badge/Notification.svelte
  • src/routes/builder/toast/+page.svelte
  • src/routes/builder/popover/+page.svelte
  • src/routes/docs-examples/components/avatar/CustomDot.svelte
  • src/routes/builder/link/+page.svelte
  • src/routes/docs-examples/components/indicators/Count.svelte
  • src/routes/docs-examples/components/dropdown/Notification.svelte
  • src/routes/docs-examples/components/indicators/Legend.svelte
  • src/routes/docs-examples/components/indicators/Default.svelte
  • src/routes/admin-dashboard/(sidebar)/crud/users/+page.svelte
  • src/lib/avatar/Avatar.svelte
  • src/routes/builder/label/+page.svelte
  • src/routes/builder/tooltip/+page.svelte
  • src/routes/builder/progress/+page.svelte
  • src/routes/builder/button/+page.svelte
  • src/routes/docs-examples/components/indicators/Position.svelte
  • src/routes/builder/toggle/+page.svelte
  • src/routes/docs-examples/extend/step-indicator/Colors.svelte
  • src/lib/indicator/Indicator.svelte
  • src/routes/builder/card/+page.svelte
  • src/routes/builder/banner/+page.svelte
  • src/routes/builder/radio/+page.svelte
  • src/tests/alert/alert.test.ts
  • src/lib/indicator/theme.ts
  • src/lib/accordion/theme.ts
  • src/routes/landing/Hero.svelte
  • src/routes/docs-examples/components/avatar/DotIndicator.svelte
  • src/routes/docs-examples/components/indicators/Stepper.svelte
  • src/routes/docs-examples/components/alert/AdditionalContent.svelte
  • src/routes/builder/floating-label/+page.svelte
  • src/lib/forms/radio/theme.ts
  • src/routes/builder/spinner/+page.svelte
🧠 Learnings (18)
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

Applied to files:

  • src/routes/builder/button-group/+page.svelte
  • src/app.css
  • src/routes/builder/popover/+page.svelte
  • src/routes/builder/link/+page.svelte
  • src/routes/landing/Hero.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/builder/button-group/+page.svelte
  • src/app.css
  • src/routes/builder/link/+page.svelte
  • src/routes/landing/Hero.svelte
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/routes/builder/button-group/+page.svelte
  • src/routes/builder/avatar/+page.svelte
  • src/routes/builder/indicators/+page.svelte
  • src/routes/docs-examples/components/dropdown/User.svelte
  • src/routes/docs-examples/forms/radio/Colors.svelte
  • src/routes/builder/input-field/+page.svelte
  • src/routes/builder/badge/+page.svelte
  • src/routes/docs-examples/pages/theme-provider/Theme2.svelte
  • src/routes/docs-examples/components/indicators/Badge.svelte
  • src/lib/forms/radio/Radio.svelte
  • src/routes/docs-examples/components/indicators/Status.svelte
  • src/routes/builder/checkbox/+page.svelte
  • src/routes/docs-examples/components/carousel/Advanced.svelte
  • src/routes/docs-examples/components/avatar/UserDropdown.svelte
  • src/routes/builder/table/+page.svelte
  • src/routes/builder/range/+page.svelte
  • src/routes/docs-examples/components/badge/Notification.svelte
  • src/routes/builder/toast/+page.svelte
  • src/routes/builder/popover/+page.svelte
  • src/routes/docs-examples/components/avatar/CustomDot.svelte
  • src/routes/builder/link/+page.svelte
  • src/routes/docs-examples/components/indicators/Count.svelte
  • src/routes/docs-examples/components/dropdown/Notification.svelte
  • src/routes/docs-examples/components/indicators/Legend.svelte
  • src/routes/docs-examples/components/indicators/Default.svelte
  • src/routes/admin-dashboard/(sidebar)/crud/users/+page.svelte
  • src/lib/avatar/Avatar.svelte
  • src/routes/builder/label/+page.svelte
  • src/routes/builder/tooltip/+page.svelte
  • src/routes/builder/progress/+page.svelte
  • src/routes/builder/button/+page.svelte
  • src/routes/docs-examples/components/indicators/Position.svelte
  • src/routes/builder/toggle/+page.svelte
  • src/routes/docs-examples/extend/step-indicator/Colors.svelte
  • src/lib/indicator/Indicator.svelte
  • src/routes/builder/card/+page.svelte
  • src/routes/builder/banner/+page.svelte
  • src/routes/builder/radio/+page.svelte
  • src/routes/landing/Hero.svelte
  • src/routes/docs-examples/components/avatar/DotIndicator.svelte
  • src/routes/docs-examples/components/indicators/Stepper.svelte
  • src/routes/docs-examples/components/alert/AdditionalContent.svelte
  • src/routes/builder/floating-label/+page.svelte
  • src/routes/builder/spinner/+page.svelte
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/routes/builder/input-field/+page.svelte
  • src/app.css
  • src/routes/docs-examples/components/indicators/Default.svelte
  • src/lib/forms/radio/theme.ts
📚 Learning: 2025-08-31T12:56:05.074Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1745
File: src/lib/types.ts:677-686
Timestamp: 2025-08-31T12:56:05.074Z
Learning: HTMLInputAttributes includes a `group` property that can be used for grouping form controls like checkboxes and radio buttons, so interfaces extending HTMLInputAttributes don't need to explicitly declare `group` unless they want to override its type.

Applied to files:

  • src/lib/forms/radio/Radio.svelte
  • src/routes/builder/radio/+page.svelte
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1465
File: src/lib/forms/Timepicker.svelte:105-116
Timestamp: 2024-10-18T09:38:03.879Z
Learning: In `Timepicker.svelte`, the `Dropdown` opens as intended and is used exclusively with the 'dropdown' and 'timerange-dropdown' Timepicker types.

Applied to files:

  • src/routes/docs-examples/components/avatar/UserDropdown.svelte
  • src/routes/builder/range/+page.svelte
  • src/routes/builder/popover/+page.svelte
📚 Learning: 2025-12-16T13:21:28.743Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:28.743Z
Learning: In flowbite-svelte, when using ThemeProvider with reactive themes, `getTheme("componentName")` calls must be placed inside `$derived()` expressions (not at module scope) to ensure components react to dynamic theme changes. This pattern is intentional for reactive theming support.

Applied to files:

  • src/app.css
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation

Applied to files:

  • src/app.css
  • src/routes/builder/link/+page.svelte
  • src/routes/landing/Hero.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use searchDocs tool for full-text search across Flowbite-Svelte documentation when looking for specific information that might span multiple components or when users ask about features or patterns

Applied to files:

  • src/app.css
  • src/routes/landing/Hero.svelte
📚 Learning: 2024-11-22T08:37:27.996Z
Learnt from: mrh1997
Repo: themesberg/flowbite-svelte PR: 1442
File: src/lib/utils/Popper.svelte:144-145
Timestamp: 2024-11-22T08:37:27.996Z
Learning: In `src/lib/utils/Popper.svelte`, inconsistencies in event handling (e.g., using both `mouseenter`/`mouseleave` and `pointerenter`/`pointerleave`) may be intentional to minimize modifications and reduce the risk of new problems.

Applied to files:

  • src/routes/builder/popover/+page.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use the Flowbite-Svelte MCP server to access comprehensive component documentation

Applied to files:

  • src/routes/landing/Hero.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Use getComponentList tool to discover available Flowbite-Svelte components or help users explore component options

Applied to files:

  • src/routes/landing/Hero.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/landing/Hero.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use getComponentList tool to discover available Flowbite-Svelte components with their categories or to help users explore component options

Applied to files:

  • src/routes/landing/Hero.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Use searchDocs tool when finding specific information that might span multiple Flowbite-Svelte components or when exploring features and patterns across the documentation

Applied to files:

  • src/routes/landing/Hero.svelte
📚 Learning: 2025-12-11T12:35:41.602Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-11T12:35:41.602Z
Learning: Use the Flowbite-Svelte MCP server's `searchDocs` tool when finding specific information spanning multiple components or when users ask about features or patterns

Applied to files:

  • src/routes/landing/Hero.svelte
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.

Applied to files:

  • src/lib/forms/radio/theme.ts
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.

Applied to files:

  • src/lib/forms/radio/theme.ts
🧬 Code graph analysis (1)
src/tests/alert/alert.test.ts (2)
src/lib/alert/theme.ts (1)
  • alert (6-117)
src/lib/utils/theme.ts (1)
  • closeButton (7-85)
🪛 LanguageTool
TESTING-AND-PR-GUIDE.md

[style] ~231-~231: Consider using a less common alternative to make your writing sound more unique and professional.
Context: ...PR process - Tailwind CSS v4 specifics Feel free to ask!

(FEEL_FREE_TO_STYLE_ME)

🪛 markdownlint-cli2 (0.18.1)
BRAND-COLOR-OVERRIDE-GUIDE.md

5-5: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

SOLUTION-SUMMARY.md

59-59: Bare URL used

(MD034, no-bare-urls)

BRAND-OVERRIDE-SUMMARY.md

5-5: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

QUICK-REFERENCE.md

5-5: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

TESTING-AND-PR-GUIDE.md

144-144: Bare URL used

(MD034, no-bare-urls)


151-151: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (74)
TESTING-AND-PR-GUIDE.md (1)

1-231: Clarify the purpose and placement of this documentation file.

This guide reads as step-by-step instructions for local development and PR submission to the Flowbite main repository. Before merging, clarify:

  1. Is this meant to be committed to flowbite-svelte? If yes, it should be generic and installable documentation. If no, consider whether it belongs in a CONTRIBUTING.md or separate onboarding guide.
  2. Is it intended as temporary guidance to help with this specific PR, or ongoing documentation? The local setup instructions suggest it may be temporary.
  3. Should it reference the actual Flowbite repository or focus on flowbite-svelte? The heavy focus on "Creating a Pull Request to Flowbite" (lines 90–189) suggests this may be out of scope for the flowbite-svelte repo.

Consider moving Flowbite-specific PR instructions to a separate document or linking to the Flowbite project's contribution guide instead.

src/routes/docs-examples/components/alert/AdditionalContent.svelte (2)

6-15: Verify the listContent prop and color token with component documentation.

The new listContent prop and color="brand" token align with the v4 upgrade mentioned in the PR summary. However, per the coding guidelines, please verify these props using the Flowbite-Svelte MCP server to ensure correct API usage.

As per coding guidelines, use the MCP server tools to verify:

// First, locate the Alert component
findComponent("Alert")

// Then fetch its documentation
getComponentDoc("Alert")

This will confirm:

  • The listContent prop is correctly named and used
  • color="brand" is a valid color token in v4
  • Any additional props or usage patterns for this variant

16-25: Verify color consistency between Alert and Button.

The Alert now uses color="success" (line 16), aligned with the new consolidated token system. However, the Button uses color="green" (line 24).

Please verify whether:

  1. Button component supports the same color tokens as Alert (e.g., color="success"), or if it has a separate color palette
  2. The color mismatch is intentional for visual differentiation or should be aligned for consistency

Use the MCP server to verify Button color options:

// Fetch Button component documentation
getComponentDoc("Button")

This will confirm the valid color values for Button in v4 and whether they align with Alert's token system.

src/tests/alert/alert.test.ts (13)

1-15: LGTM!

The imports are well-organized, covering all necessary testing utilities and fixture components.


17-19: LGTM!

Proper use of afterEach cleanup to ensure test isolation.


21-45: LGTM!

The basic functionality tests properly verify default behavior including role, text content, default brand color classes, and rounded corners. These align well with the theme defaults shown in src/lib/alert/theme.ts.


47-56: LGTM!

The color variant test correctly verifies danger color classes matching the theme definition.


58-86: LGTM!

The dismissable functionality tests are well-structured with proper async handling, accessibility checks (aria-label), and correct use of waitForElementToBeRemoved to handle transitions.


88-100: LGTM!

The icon test appropriately verifies SVG presence within the alert using querySelector.


102-110: LGTM!

The border variant test correctly verifies the presence of the border class.


112-119: LGTM!

The visibility control test correctly uses queryByRole to verify the alert is not rendered when alertStatus is false.


121-135: LGTM!

The custom close icon test appropriately verifies the custom SVG renders within the close button.


137-147: LGTM!

The border accent test correctly verifies the new borderAccent prop functionality, checking for both the border and border-t-4 classes as defined in the theme.


149-158: LGTM!

The custom colors test correctly verifies that color="none" allows custom classes to be applied, aligning with the theme definition.


160-177: LGTM!

The close event test properly verifies event firing using a test indicator with appropriate async handling.


179-189: No action needed. The closeColor classes in the test correctly align with the closeButton theme definition. The success variant in src/lib/utils/theme.ts includes both text-fg-success-strong and bg-success-soft as expected.

src/lib/accordion/theme.ts (3)

7-20: LGTM: Clear type documentation.

The JSDoc comment effectively documents the structure of AccordionItemVariants, showing all available props and class override slots for consumers.


33-40: LGTM: Well-structured slot definitions.

The base slot definitions are comprehensive with good RTL support (rtl:text-right) and appropriate use of group-first/group-last pseudo-classes for boundary styling.


54-74: LGTM: Effective compound variant logic.

The compound variants appropriately handle the interaction between flush and open states, adjusting text color to provide clear visual feedback for accordion state. The empty open variant branches allow state tracking without forcing unwanted base styles.

src/routes/docs-examples/components/dropdown/User.svelte (1)

5-5: LGTM! Semantic color token alignment.

The Avatar dot color update from "green" to "neutral" aligns with the broader semantic color token refactor across the codebase.

src/lib/avatar/Avatar.svelte (1)

13-13: LGTM! Semantic default color update.

The default dot color update from "gray" to "neutral" improves semantic clarity and aligns with the project's color token system. Theme reactivity is correctly implemented using $derived().

src/routes/builder/badge/+page.svelte (1)

174-174: Radio color prop removed - verify appearance.

The color prop has been removed from the Radio component, aligning with the broader simplification across builder pages. Since Radio.svelte's default color changed to "brand", ensure the visual appearance matches the intended design.

src/routes/docs-examples/components/dropdown/Notification.svelte (1)

16-16: LGTM! Consistent semantic color token updates.

All three Avatar dot color updates align with the semantic color token system:

  • gray → neutral
  • red → danger
  • green → success

These changes improve semantic clarity across the notification items.

Also applies to: 26-26, 38-38

src/routes/builder/toast/+page.svelte (1)

107-107: Radio simplified - verify appearance.

The Radio component no longer uses an explicit color prop, relying on the new "brand" default. Ensure the visual appearance is correct in the toast builder interface.

src/lib/forms/radio/Radio.svelte (1)

16-16: No action needed. The Radio component's default color of "brand" is correct and not a breaking change. The color option "primary" does not exist in the Radio component's theme—only brand, dark, danger, neutral, warning, success, teal, indigo, and purple are valid options. The current default is intentional and properly supported across the 8+ existing Radio usages in the codebase.

Likely an incorrect or invalid review comment.

src/routes/landing/Hero.svelte (1)

13-15: Typography refinement aligns with v4 upgrade.

The changes consolidate heading styles with a custom text-heading class and simplify the responsive layout by using consistent block display. The removal of leading-none and xl:inline appears intentional for the Flowbite v4 design system.

src/routes/docs-examples/components/badge/Notification.svelte (2)

9-9: Flexible Indicator styling with utility classes.

The first indicator uses a utility class (bg-blue-500) for background color, demonstrating the v4 approach of combining semantic props with Tailwind utilities. This provides more styling flexibility.


15-15: Semantic color token migration completed.

The indicators now use semantic color tokens (danger, dark) instead of literal color names, aligning with Flowbite v4's token system.

Also applies to: 21-21

src/routes/builder/avatar/+page.svelte (1)

117-117: Avatar dot color migrated to semantic token.

The dot color correctly uses the semantic "success" token, aligning with Flowbite v4 standards.

Also applies to: 130-130, 143-143

src/routes/docs-examples/pages/theme-provider/Theme2.svelte (1)

96-96: Semantic token migration for Avatar dot.

The dot color correctly uses the semantic "danger" token, maintaining consistency with the v4 color system.

src/routes/docs-examples/components/avatar/CustomDot.svelte (1)

8-8: Custom indicator color demonstrates flexibility.

The change to "purple" showcases the variety of color options available in the Flowbite v4 token system. This is appropriate for a custom dot example.

.coderabbit.yml (1)

2-5: Auto-review configuration correctly implemented.

The auto_review configuration uses the correct regex pattern ".*" for base_branches, which matches all branches as intended. This addresses the previous review feedback.

src/routes/docs-examples/components/indicators/Badge.svelte (1)

14-14: Status indicators use appropriate semantic tokens.

The indicators correctly use "success" for "Available" and "danger" for "Unavailable" statuses, providing clear semantic meaning that aligns with Flowbite v4 standards.

Also applies to: 28-28

src/routes/docs-examples/components/carousel/Advanced.svelte (1)

12-12: Carousel indicators use semantic color tokens.

The conditional color assignment correctly uses "danger" and "success" semantic tokens to distinguish between selected and unselected states, aligning with Flowbite v4 standards.

src/routes/builder/button/+page.svelte (1)

158-158: LGTM: Radio component simplified.

The removal of the explicit color prop and RadioColorType type assertion aligns with the broader refactoring across builder routes. The Radio component now relies on value binding without per-color prop casting, consistent with the semantic token approach.

src/routes/builder/table/+page.svelte (1)

79-79: LGTM: Consistent Radio component update.

The removal of the color prop from the Radio component is consistent with the broader pattern of simplifying Radio usage across all builder routes.

src/routes/docs-examples/components/avatar/UserDropdown.svelte (1)

5-5: LGTM: Semantic token migration.

The update from "green" to "success" aligns with the broader semantic color token refactoring across the codebase, replacing literal color names with intent-based tokens.

src/routes/builder/card/+page.svelte (1)

103-103: LGTM: Radio component simplified.

Consistent removal of the color prop, matching the pattern across all builder routes.

src/routes/builder/indicators/+page.svelte (1)

19-19: LGTM: Consistent semantic token update.

The default color change from "primary" to "brand" (line 19) is properly reflected in the code generation logic (line 38), ensuring the builder generates correct code when using the new default color token.

Also applies to: 38-38

src/routes/docs-examples/components/indicators/Status.svelte (1)

5-6: LGTM: Semantic token migration.

Both Avatar dot colors updated from literal color names ("green", "red") to semantic tokens ("success", "danger"), aligning with the broader token refactoring.

src/routes/builder/checkbox/+page.svelte (1)

81-81: LGTM: Radio component simplified.

The removal of the color prop is consistent with the pattern across all builder routes, while preserving the onchange handler functionality.

src/routes/docs-examples/components/indicators/Legend.svelte (1)

5-8: The mixed approach is intentional and correct. The Indicator component supports the color variants "purple", "indigo", and "teal", but "orange" is not a supported color variant. Therefore, line 5 correctly uses the Tailwind class bg-orange-400 as a custom override, while lines 6-8 properly use the color prop for the supported variants. This pattern is the appropriate way to handle colors: use the component's color prop when available, and fall back to custom Tailwind classes for unsupported colors.

src/routes/docs/components/indicators.md (1)

29-29: Documentation accurately reflects semantic color tokens.

The updated documentation correctly describes the new semantic color system with 'brand' as the default and lists the available preset colors. The instruction to use the class prop for custom colors is appropriate.

src/routes/admin-dashboard/(sidebar)/crud/users/+page.svelte (1)

101-101: Semantic color tokens correctly applied.

The migration from "green"/"red" to "success"/"danger" aligns with the broader color token refactor and maintains the correct visual semantics for user status indicators.

src/routes/builder/label/+page.svelte (1)

51-51: Radio refactor correctly applied.

The removal of the explicit color prop binding on Radio components is consistent with the broader migration to a token-based styling approach across builder pages. The classes prop usage with label: "w-24" is appropriate.

src/routes/builder/range/+page.svelte (1)

96-96: Type simplification correctly implemented.

The removal of both the RangeColorType import and the explicit color prop on Radio aligns with the broader type simplification and token-based styling migration.

src/routes/docs-examples/components/indicators/Count.svelte (1)

10-10: Semantic token correctly applied.

The migration from "red" to "danger" correctly uses the new semantic color token system for the Indicator component.

src/routes/builder/progress/+page.svelte (1)

119-119: Refactor consistently applied.

The removal of the RadioColorType import and explicit color prop on Radio is consistent with the project-wide migration to simplified, token-based styling.

src/routes/builder/toggle/+page.svelte (1)

86-86: Type simplification and refactor correct.

The removal of the ToggleColor type import and explicit color prop aligns with the project-wide simplification of Radio usage and the shift to semantic color tokens.

src/routes/builder/link/+page.svelte (1)

81-81: Refactor pattern consistently applied across all builder pages.

The removal of AnchorColorType and the explicit color prop completes the consistent refactor pattern applied across all builder pages in this PR. The migration to simplified Radio usage with token-based styling is complete and correct.

src/routes/docs-examples/components/indicators/Stepper.svelte (1)

12-12: Semantic color token update: "gray" → "dark".

The migration to semantic color tokens aligns with Flowbite v4's color system.

Also applies to: 37-37

src/routes/docs-examples/forms/radio/Colors.svelte (1)

8-9: Semantic color updates: "red" → "danger", "green" → "success".

These semantic token updates align with Flowbite v4's color system and improve clarity.

src/routes/docs-examples/components/avatar/DotIndicator.svelte (1)

5-7: Semantic color token updates for Avatar dot indicators.

The migration to semantic tokens ("danger", "warning", "success") improves clarity and aligns with Flowbite v4's color system. The varied colors across different dot placements effectively demonstrate the component's flexibility.

src/routes/builder/spinner/+page.svelte (1)

78-78: Radio component's classes prop with label key is properly supported in Flowbite v4.

The code correctly uses classes={{ label: "w-24" }} to style the label wrapper. The Radio component implementation in src/lib/forms/radio/Radio.svelte explicitly handles the classes prop (line 32: const styling = $derived(classes ?? { label: labelClass });) and applies it to the label element. This pattern is documented and consistent with Flowbite v4's class-based styling approach.

BRAND-COLOR-OVERRIDE-GUIDE.md (1)

1-189: Excellent documentation for brand color overrides!

This guide provides clear, comprehensive documentation for implementing brand color overrides with Flowbite v4. The structure covers all essential aspects: implementation, testing, color mappings, and advanced usage scenarios.

The CSS variable override approach is clean and aligns perfectly with Tailwind CSS v4's theming architecture.

src/routes/docs-examples/components/indicators/Position.svelte (1)

6-14: LGTM! Semantic color tokens properly applied.

The indicator colors have been successfully updated to use the new semantic token system (danger, warning, success, dark, neutral) while maintaining backward compatibility for special colors (purple, indigo, teal). The mix of color props and class-based styling for the yellow indicator is intentional per the new architecture.

BRAND-OVERRIDE-SUMMARY.md (1)

1-141: Clear and concise summary documentation.

This summary provides a well-structured overview of the brand color override implementation, complementing the detailed guide nicely.

src/routes/builder/banner/+page.svelte (1)

131-131: LGTM! Radio color prop correctly removed.

The removal of the explicit color prop from the Radio component aligns with the new architecture where Radio defaults to the "brand" color token. The component still functions correctly with value binding and group management.

src/routes/builder/tooltip/+page.svelte (1)

83-83: LGTM! Consistent Radio component update.

The removal of the color prop is consistent with the broader architectural change to default Radio components to the "brand" color token. The classes prop provides the necessary styling customization.

src/routes/docs-examples/components/indicators/Default.svelte (1)

5-15: LGTM! Comprehensive coverage of semantic color tokens.

The updated examples effectively demonstrate:

  • Default indicator state (no props)
  • New semantic color tokens (neutral, dark, success, danger, warning)
  • Backward compatibility with special colors (purple, indigo, teal)
  • Class-based styling approach for custom colors

This provides excellent documentation coverage of the new color system.

src/routes/builder/radio/+page.svelte (5)

18-20: LGTM! Default color properly updated to "brand".

The change from "primary" to "brand" aligns with the Flowbite v4 semantic color token system. Both the main color state and demo color state are consistently updated.


43-43: Helper color default correctly updated.

The helperColor default now uses "brand" token, maintaining consistency with the broader color system changes.


54-54: Code generation logic properly adjusted.

The generated code now omits the color prop when it's "brand" (the new default), preventing redundant prop emission. This is correct behavior for the builder.


89-89: Helper component simplified correctly.

Removing the color prop from the Helper component aligns with the new architecture where components use default semantic tokens. The class prop provides sufficient styling control.


95-97: Radio color selection simplified.

The removal of the color prop from the color option Radio components is correct - these are UI controls for selecting colors, not instances that need their own color styling. The value binding remains intact for proper functionality.

src/app.css (5)

1-13: Font imports properly configured.

The Inter font import is correctly added for the default theme, with alternative theme font imports appropriately commented out. This follows a clean conditional approach for theme switching.


27-34: Source declarations properly configured.

The @source directives correctly point to Flowbite and related dependencies, enabling Tailwind v4 to scan for utility class usage in these packages.


50-90: Brand color overrides correctly implemented.

The brand color override strategy properly maps Flowbite's brand tokens to the custom primary palette:

  • Background colors (softer, soft, base, medium, strong)
  • Foreground/text colors (subtle, base, strong)
  • Border colors (subtle, light)

The implementation leverages Tailwind CSS v4's CSS variable cascade to override Flowbite's default blue brand colors with the orange/fuchsia primary palette. The token mappings are well-chosen for visual consistency across light mode.


99-127: Dark mode overrides properly scoped.

The dark mode brand color overrides are correctly placed in @layer base within the .dark selector, ensuring they cascade appropriately. The shade mappings (using darker/lighter primary tones) are well-balanced for dark mode contrast.

Note: This section also includes the Tailwind v4 border compatibility block (lines 99-110), which properly addresses the currentColor default change.


15-23: Flowbite v4 integration correctly implemented.

The imports follow proper structure:

  • Default theme imported from Flowbite v4
  • Alternative themes commented for easy switching
  • Plugin utilities correctly wired via @plugin "./plugin-utilities" (file exists at ./src/plugin-utilities.js)
src/plugin-utilities.js (1)

1-1: No changes required — the import path is compatible with Tailwind CSS v4. The plugin function can be imported from tailwindcss/plugin in v4, and ES6 module syntax is fully supported. This import statement requires no modification.

src/lib/indicator/theme.ts (2)

10-18: Verify that custom color utilities are properly defined in your Tailwind configuration.

The theme references custom utility classes like bg-brand, bg-success, bg-neutral-quaternary, and others. These must be defined either in your tailwind.config.js (via theme.extend.colors or a registered plugin) or through a Tailwind plugin using addUtilities(). Ensure:

  1. Your Tailwind configuration file imports and registers any custom plugin
  2. All referenced color utilities are defined in the theme or plugin
  3. The app CSS file contains the proper @tailwind directives (base, components, utilities) and is imported in your root layout

9-19: Document breaking change: "primary" color removed from Indicator component.

The color variant set has been refactored to semantic colors, and "primary" is no longer available (replaced with "brand" as the default). Update code using color="primary" to use "brand" or another supported color: neutral, dark, success, danger, purple, indigo, warning, or teal.

Note: This is a project-specific change; the upstream Flowbite-Svelte library still supports "primary" as a color option.

src/lib/forms/radio/theme.ts (1)

14-39: Address breaking change and document color design intent.

The radio component removes "primary" color support and defaults to "brand" instead, which creates a breaking change for external code. Additionally, several color design choices lack clear semantic justification:

  • Breaking change: "primary" color variant removed; no migration path documented.
  • Color mismatches: brand uses text-brand (primary-700) but focus ring is fuchsia-500; neutral uses orange-500 which contradicts its semantic meaning.
  • Focus rings are hardcoded: Each variant's focus ring doesn't match its text color, creating inconsistent visual feedback across variants.

Clarify the design intent: why brand maps to primary colors via CSS variables, why fuchsia was chosen for focus ring, and why neutral is orange. Document this color mapping strategy and consider adding a migration guide if this change affects public API.

⛔ Skipped due to learnings
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.952Z
Learning: In the Flowbite Svelte library, when implementing components with validation states, the 'inputInvalid' property should be explicitly defined and passed to the Wrapper component. When inputInvalid=true, the color should be set to "red" to ensure the ring/border styling is applied correctly.

Comment on lines 56 to 66
### `/Users/shinichiokada/Flowbite/flowbite-svelte-local-development/src/app.css`

**Added to @theme block:**
- Brand color overrides (5 variants)
- Brand foreground color overrides (3 variants)
- Brand border color overrides (2 variants)

**Added to @layer base:**
- Dark mode brand color overrides (same set)

### `/Users/shinichiokada/Flowbite/flowbite-svelte-local-development/src/routes/testdir/flowbite/+page.svelte`
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 19, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove absolute file paths from documentation.

The documentation contains absolute file paths that expose local system structure. Replace these with relative paths or generic placeholders for better portability and security.

🔎 Proposed fix
-### `/Users/shinichiokada/Flowbite/flowbite-svelte-local-development/src/app.css`
+### `src/app.css`

 **Added to @theme block:**
 - Brand color overrides (5 variants)
 - Brand foreground color overrides (3 variants)
 - Brand border color overrides (2 variants)

 **Added to @layer base:**
 - Dark mode brand color overrides (same set)

-### `/Users/shinichiokada/Flowbite/flowbite-svelte-local-development/src/routes/testdir/flowbite/+page.svelte`
+### `src/routes/testdir/flowbite/+page.svelte`
📝 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
### `/Users/shinichiokada/Flowbite/flowbite-svelte-local-development/src/app.css`
**Added to @theme block:**
- Brand color overrides (5 variants)
- Brand foreground color overrides (3 variants)
- Brand border color overrides (2 variants)
**Added to @layer base:**
- Dark mode brand color overrides (same set)
### `/Users/shinichiokada/Flowbite/flowbite-svelte-local-development/src/routes/testdir/flowbite/+page.svelte`
### `src/app.css`
**Added to @theme block:**
- Brand color overrides (5 variants)
- Brand foreground color overrides (3 variants)
- Brand border color overrides (2 variants)
**Added to @layer base:**
- Dark mode brand color overrides (same set)
### `src/routes/testdir/flowbite/+page.svelte`
🤖 Prompt for AI Agents
In BRAND-OVERRIDE-SUMMARY.md around lines 56 to 66, the doc lists absolute local
file paths; replace each absolute path (e.g. /Users/yourname/...) with
project-relative paths or generic placeholders (e.g. src/app.css or
<project_root>/src/app.css) and update any occurrences to use consistent
relative formatting (or a placeholder like {PROJECT_ROOT}/src/...) so the
documentation no longer exposes local system structure.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

N/A since the file will be deleted.

Copy link
Contributor

Choose a reason for hiding this comment

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

@shinokada, understood! Since the file will be deleted, there's no need to fix the absolute paths. Thanks for clarifying.

Comment on lines 5 to 16
```
flowbite/
├── plugin-utilities.js [NEW] - Generates color utilities
├── package.json [MODIFIED] - Added plugin to files array
└── PLUGIN-UTILITIES-README.md [NEW] - Documentation

flowbite-svelte-local-development/
├── package.json [MODIFIED] - Linked to local flowbite
├── src/app.css [MODIFIED] - Added plugin line
├── TESTING-AND-PR-GUIDE.md [NEW] - How to test and create PR
└── SOLUTION-SUMMARY.md [NEW] - Complete explanation
```
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 19, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add language specifier to fenced code block.

The fenced code block showing the file tree should specify a language for proper syntax highlighting and to satisfy linting rules.

🔎 Proposed fix
-```
+```text
 flowbite/
 ├── plugin-utilities.js          [NEW] - Generates color utilities
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

5-5: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In QUICK-REFERENCE.md around lines 5 to 16, the fenced code block showing the
file tree lacks a language specifier which triggers linting and prevents proper
syntax highlighting; update the opening fence to include a language (for example
"text" or "diff") so the block becomes ```text (or ```diff) and leave the
content unchanged, then save to satisfy the linter and enable correct
highlighting.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

N/A since the file will be deleted.

Copy link
Contributor

Choose a reason for hiding this comment

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

@shinokada, understood! Since the file will be deleted, there's no need to address the linting issue. Thanks for clarifying.


🧠 Learnings used
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation

Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

## To Test Now

```bash
cd /Users/shinichiokada/Flowbite/flowbite-svelte-local-development
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 19, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Replace hardcoded local paths with generic placeholders.

The documentation contains hardcoded paths specific to your local environment (/Users/shinichiokada/Flowbite/...). Replace these with generic placeholders or relative paths to make the documentation portable for other contributors.

For example:

  • Line 21: cd /Users/shinichiokada/Flowbite/flowbite-svelte-local-development
  • Line 101: Similar path references
  • Line 103: Similar path references
🔎 Proposed fix
-cd /Users/shinichiokada/Flowbite/flowbite-svelte-local-development
+cd /path/to/flowbite-svelte-local-development
-2. **Commit your changes** in `/Users/shinichiokada/Flowbite/flowbite`:
+2. **Commit your changes** in your local `flowbite` directory:
    ```bash
-   cd /Users/shinichiokada/Flowbite/flowbite
+   cd /path/to/flowbite

Also applies to: 101-103

🤖 Prompt for AI Agents
In QUICK-REFERENCE.md around lines 21 and 101-103, the doc uses hardcoded local
paths (e.g. /Users/shinichiokada/Flowbite/flowbite-svelte-local-development);
replace those absolute, user-specific paths with a generic placeholder or
relative path (for example /path/to/flowbite or ./flowbite) so the instructions
are portable for other contributors, update any matching occurrences for
consistency, and ensure any examples mention that users should substitute their
own project path.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

N/A since the file will be deleted.

Copy link
Contributor

Choose a reason for hiding this comment

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

@shinokada, understood! If the file is being deleted, there's no need to update the paths. Thanks for clarifying.


🧠 Learnings used
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation

Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-11T12:35:41.602Z
Learning: Use the Flowbite-Svelte MCP server's `searchDocs` tool when finding specific information spanning multiple components or when users ask about features or patterns

Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use searchDocs tool for full-text search across Flowbite-Svelte documentation when looking for specific information that might span multiple components or when users ask about features or patterns

<Label class="mb-4 w-full font-bold">Color</Label>
{#each colors as colorOption}
<Radio class="my-1" classes={{ label: "w-24" }} name="color" bind:group={color} color={colorOption as SimpleRadioColor} value={colorOption as StepIndicatorProps["color"]}>
<Radio class="my-1" classes={{ label: "w-24" }} name="color" bind:group={color} value={colorOption as StepIndicatorProps["color"]}>
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 19, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Type cast is safe for the color values shown, but consider the underlying type safety issue.

The color values in the array (gray, blue, red, green, yellow) are all valid members of StepIndicatorProps["color"], so the type cast works at runtime. However, the cast masks a type safety issue—the underlying colors array lacks explicit typing. Rather than verifying hardcoded values, improve type safety by typing the array itself as const colors: StepIndicatorProps["color"][] = [...]. This prevents invalid colors from being added and eliminates the need for a runtime cast.

🤖 Prompt for AI Agents
In src/routes/docs-examples/extend/step-indicator/Colors.svelte around line 17,
the Radio value uses a runtime type cast (value={colorOption as
StepIndicatorProps["color"]}) because the underlying colors array is untyped;
this masks potential type errors. Fix by giving the colors array an explicit
type annotation (const colors: StepIndicatorProps["color"][] = [...]) so each
entry is type-checked and you can remove the cast on value, ensuring invalid
colors cannot be added at compile time.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

skipped.

Copy link
Contributor

Choose a reason for hiding this comment

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

@shinokada, understood. I'll skip this suggestion.


🧠 Learnings used
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Comment on lines +12 to +13
<Radio bind:group={colors} color="warning" value="text-yellow-500">Yellow</Radio>
<Radio bind:group={colors} color="warning" value="text-orange-500">Orange</Radio>
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 19, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use separate color values for Yellow and Orange radio buttons.

Lines 12 and 13 both use color="warning", but the Radio component does not have a "warning" color variant. The documented color options are: primary, secondary, gray, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, and rose. Use color="yellow" for the Yellow radio and color="orange" for the Orange radio to display the correct distinct colors.

🤖 Prompt for AI Agents
In src/routes/docs-examples/forms/radio/Colors.svelte around lines 12 to 13,
both Radio components use color="warning" which is not a valid variant; change
the Yellow radio to color="yellow" and the Orange radio to color="orange" so
each uses the documented distinct color variants (primary, secondary, gray, red,
orange, amber, yellow, etc.).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is not correct. The theme.ts is updated with new color variants.

Copy link
Contributor

Choose a reason for hiding this comment

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

Rate Limit Exceeded

@shinokada have exceeded the limit for the number of chat messages per hour. Please wait 0 minutes and 4 seconds before sending another message.


### 3. Test the Colors

Navigate to: `http://localhost:5173/testdir/flowbite`
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 19, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix markdown formatting: bare URL and missing code block language specifiers.

  • Line 44: Bare URL should be formatted as a markdown link.
  • Lines 151, 156, 176: Fenced code blocks are missing language identifiers (use ```markdown, ```bash, etc.).
🔎 Proposed fixes
- Navigate to: `http://localhost:5173/testdir/flowbite`
+ Navigate to: [`http://localhost:5173/testdir/flowbite`](http://localhost:5173/testdir/flowbite)

- **Title:**
- ```
- feat: Add utilities plugin for Tailwind CSS v4 compatibility
- ```
+ **Title:**
+ ```markdown
+ feat: Add utilities plugin for Tailwind CSS v4 compatibility
+ ```

- **Description:**
- ```markdown
+ **Description:**
+ ```markdown
  ## Problem
  ...

Also applies to: 151-151, 156-156, 176-176

🤖 Prompt for AI Agents
TESTING-AND-PR-GUIDE.md lines 44, 151, 156, 176: replace the bare URL on line 44
with a markdown link (e.g.
[http://localhost:5173/testdir/flowbite](http://localhost:5173/testdir/flowbite))
and add language specifiers to the fenced code blocks at lines 151 and 176 as
```markdown and to the fenced block at line 156 as ```bash so syntax
highlighting and proper formatting are applied.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

N/A since this file will be deleted.

Copy link
Contributor

Choose a reason for hiding this comment

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

@shinokada, understood! No changes needed if the file will be deleted. Thanks for clarifying.


🧠 Learnings used
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

@shinokada
Copy link
Collaborator Author

@coderabbitai review

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/lib/accordion/theme.ts (1)

7-20: Consider enhancing the JSDoc with field descriptions.

The type documentation is helpful, but could be more informative with brief descriptions of what each class controls:

 /**
  AccordionItemVariants:
 {
-  flush?: boolean;
-  open?: boolean;
+  flush?: boolean;  // When true, removes borders and rounded corners
+  open?: boolean;   // Controls accordion item expanded state
   classes?: {
-    button?: ClassValue;
-    contentWrapper?: ClassValue;
-    content?: ClassValue;
-    active?: ClassValue;
-    inactive?: ClassValue;
+    button?: ClassValue;         // Styles for the accordion trigger button
+    contentWrapper?: ClassValue; // Wrapper around the collapsible content
+    content?: ClassValue;        // Styles for the content area
+    active?: ClassValue;         // Applied when accordion item is open
+    inactive?: ClassValue;       // Applied when accordion item is closed
   }
 }
   */
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f46178b and db924fe.

📒 Files selected for processing (11)
  • src/app.css (3 hunks)
  • src/lib/accordion/theme.ts (2 hunks)
  • src/lib/indicator/Indicator.svelte (2 hunks)
  • src/lib/plugin-utilities.js (1 hunks)
  • src/routes/builder/indicators/+page.svelte (3 hunks)
  • src/routes/docs-examples/components/indicators/Position.svelte (1 hunks)
  • src/routes/docs-examples/components/indicators/Stepper.svelte (2 hunks)
  • src/routes/llm/components/indicators.md (1 hunks)
  • src/routes/llm/context-full.txt (1 hunks)
  • src/tests/alert/alert.test.ts (1 hunks)
  • src/tests/alert/list-content-alert.test.svelte (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/app.css
  • src/routes/builder/indicators/+page.svelte
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/routes/docs-examples/components/indicators/Stepper.svelte
  • src/lib/plugin-utilities.js
  • src/tests/alert/list-content-alert.test.svelte
  • src/tests/alert/alert.test.ts
  • src/lib/accordion/theme.ts
  • src/lib/indicator/Indicator.svelte
  • src/routes/docs-examples/components/indicators/Position.svelte
🧠 Learnings (7)
📓 Common learnings
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.
📚 Learning: 2025-03-20T11:11:53.952Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.952Z
Learning: In the Flowbite Svelte library, when implementing components with validation states, the 'inputInvalid' property should be explicitly defined and passed to the Wrapper component. When inputInvalid=true, the color should be set to "red" to ensure the ring/border styling is applied correctly.

Applied to files:

  • src/routes/docs-examples/components/indicators/Stepper.svelte
📚 Learning: 2025-03-20T11:11:53.953Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.953Z
Learning: In the Flowbite Svelte library's MultiInput component, the 'inputInvalid' property should be exported and passed to the Wrapper component to properly style the component's ring with red color when validation fails, similar to how the Input component handles validation states.

Applied to files:

  • src/routes/docs-examples/components/indicators/Stepper.svelte
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.

Applied to files:

  • src/routes/docs-examples/components/indicators/Stepper.svelte
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/routes/docs-examples/components/indicators/Stepper.svelte
  • src/routes/docs-examples/components/indicators/Position.svelte
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.

Applied to files:

  • src/routes/docs-examples/components/indicators/Stepper.svelte
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/routes/docs-examples/components/indicators/Stepper.svelte
  • src/tests/alert/list-content-alert.test.svelte
  • src/lib/indicator/Indicator.svelte
  • src/routes/docs-examples/components/indicators/Position.svelte
🧬 Code graph analysis (2)
src/tests/alert/alert.test.ts (2)
src/lib/alert/theme.ts (1)
  • alert (6-117)
src/lib/utils/theme.ts (1)
  • closeButton (7-85)
src/lib/accordion/theme.ts (1)
src/lib/accordion/index.ts (2)
  • accordion (3-3)
  • accordionItem (3-3)
🔇 Additional comments (16)
src/routes/llm/context-full.txt (1)

9798-9798: Good catch on the typo fix.

Correcting "borer" to "border" restores the intended Tailwind CSS class for proper border styling on the container element.

src/tests/alert/list-content-alert.test.svelte (1)

1-5: LGTM! Test fixture correctly implements the listContent prop.

The test fixture is well-structured and correctly uses the new listContent prop with color="success". This aligns with the Alert component's updated API and will properly exercise the compound variant classes defined in theme.ts.

src/tests/alert/alert.test.ts (1)

1-206: LGTM! Comprehensive test suite with excellent coverage.

The test suite is well-structured and thoroughly covers the Alert component's functionality:

✅ All class assertions match the theme definitions in src/lib/alert/theme.ts and src/lib/utils/theme.ts
✅ Proper use of accessibility queries (getByRole) and appropriate query methods
✅ Correct async patterns with waitForElementToBeRemoved for transitions
✅ Addresses the previously requested listContent test coverage (lines 192-205)
✅ Tests all major variants: colors, dismissable, icons, borders, border accent, custom styling, and list content

The test fixtures are properly imported and the suite follows testing best practices throughout.

src/routes/docs-examples/components/indicators/Position.svelte (2)

6-14: All colors in the code are valid for the Indicator component in v4.0.1. The theme.ts file confirms the complete set of supported colors: 'neutral' | 'dark' | 'brand' | 'success' | 'danger' | 'purple' | 'indigo' | 'warning' | 'teal'. The code uses all valid semantic tokens—danger, warning, success, dark, neutral, purple, indigo, and teal—with no incomplete migration. No changes are required.


13-13: Verify if "yellow" is a supported Indicator color in v4 or add an explanatory comment.

Line 13 uses class="bg-yellow-400" while all other indicators use the color prop. Official Flowbite-Svelte documentation references color="yellow" as valid. Either:

  1. Update line 13 to color="yellow" to align with the documented API and consistent pattern, or
  2. If "yellow" is unsupported in v4, add a comment explaining why the class override is necessary for this placement.
src/routes/llm/components/indicators.md (1)

191-191: LGTM! Typo corrected.

The CSS class typo "borer" has been correctly fixed to "border".

src/lib/indicator/Indicator.svelte (1)

7-7: Changes already reviewed and addressed.

The default color change from "primary" to "brand" and the corresponding JSDoc update were reviewed in a previous commit and confirmed as fixed by @shinokada.

Also applies to: 39-39

src/routes/docs-examples/components/indicators/Stepper.svelte (2)

12-13: LGTM! Semantic color migration is correct.

The update from "gray" to "neutral" aligns with the new semantic color system introduced in this PR. The dark mode background adjustments are appropriate.

Also applies to: 37-38


40-40: LGTM! Semantic color tokens are correct.

The migration from "orange"/"secondary" to "warning"/"success" is correct and aligns with the updated theme.ts that includes these semantic color variants.

src/lib/plugin-utilities.js (3)

1-11: LGTM! Plugin structure is correct.

The plugin follows Tailwind CSS v4 plugin API correctly, and the JSDoc clearly explains why explicit utility generation is needed for custom CSS properties.


15-275: LGTM! Comprehensive color utilities with correct syntax.

The color utility definitions are well-organized and use the correct --tw-ring-color CSS variable syntax for Tailwind v4 ring utilities. The naming conventions are consistent across text, background, border, and ring utilities.


276-298: LGTM! Foreground colors and plugin registration are correct.

The foreground semantic color utilities provide good coverage for text styling needs, and the plugin correctly registers all utilities using addUtilities().

src/lib/accordion/theme.ts (4)

41-58: LGTM! Flush and open variants are well-structured.

The variant structure is clean and logical:

  • flush:true provides minimal styling with simple borders
  • flush:false adds visual polish with hover states, shadows, and rounded corners
  • Empty open variant objects serve as placeholders for compoundVariants to reference

The use of semantic tokens (text-heading, text-body, neutral-secondary-medium) aligns well with the PR's migration to a unified theming system.


59-74: LGTM! Compound variants correctly handle flush + open state combinations.

The compound variants provide appropriate visual feedback:

  • When flush is enabled and the item is open, the button uses text-heading (darker/more prominent)
  • When flush is enabled and the item is closed, the button uses text-body (lighter)

This creates a clear visual hierarchy where open accordion items stand out, which is good for UX.


35-40: The empty active and inactive definitions are intentional and correct.

The component uses a fallback pattern: styling.active || ctx.activeClass || active(). Empty strings serve as explicit defaults in this chain, allowing consumers to control appearance by overwriting activeClass and inactiveClass properties either globally on Accordion or individually on each AccordionItem. When no custom styling is provided, the component relies on the CVA's compoundVariants for state-based styling rather than theme slot values.


22-30: Accordion theme refactoring is correctly implemented without breaking changes.

The removal of w-full from the base styling is intentional and correct. The accordion container should inherit width from its parent context rather than imposing a fixed full-width constraint. Users needing full-width behavior can apply it via the class prop on individual accordion instances. The flush variant change from color control to border/shadow control aligns with the Flowbite design pattern where flush removes borders and styling. No breaking changes are introduced by this refactoring.

Comment on lines +23 to 29
base: "rounded-base border border-default overflow-hidden",
variants: {
color: {
primary: "text-primary-500 dark:text-primary-400",
secondary: "text-secondary-500 dark:text-secondary-400"
},
flush: {
true: "",
false: "border border-gray-200 dark:border-gray-700 rounded-t-xl"
true: "border-0",
false: "shadow-xs"
}
}
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 20, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for CSS files and token definitions

echo "=== Finding CSS files in src/ ==="
find src -name "*.css" -type f

echo -e "\n=== Checking for @theme directives ==="
rg "@theme" --type css

echo -e "\n=== Searching for custom token definitions ==="
rg "rounded-base|border-default|shadow-xs|text-body|text-heading|neutral-secondary" -t css

echo -e "\n=== Checking Tailwind config ==="
fd -t f "tailwind" | head -20

Repository: themesberg/flowbite-svelte

Length of output: 16894


🏁 Script executed:

#!/bin/bash
# Read the app.css file to see current theme definitions

echo "=== Content of src/app.css ==="
cat -n src/app.css

Repository: themesberg/flowbite-svelte

Length of output: 29400


🏁 Script executed:

#!/bin/bash
# Read the accordion theme file to see token usage

echo "=== Content of src/lib/accordion/theme.ts ==="
cat -n src/lib/accordion/theme.ts | head -80

Repository: themesberg/flowbite-svelte

Length of output: 2540


🏁 Script executed:

#!/bin/bash
# Search for Flowbite theme definitions

echo "=== Searching for Flowbite theme files ==="
find node_modules/flowbite -name "*.css" -type f 2>/dev/null | head -20

echo -e "\n=== Searching for custom token definitions in node_modules ==="
rg "rounded-base|text-body|text-heading|neutral-secondary-medium" node_modules/flowbite --type css 2>/dev/null | head -20

echo -e "\n=== Checking if tokens exist in current @theme block ==="
grep -E "rounded-base|text-body|text-heading|border-default|shadow-xs|neutral-secondary" src/app.css

Repository: themesberg/flowbite-svelte

Length of output: 234


Add missing semantic theme tokens to the @theme block in src/app.css

The accordion component references custom tokens that are not defined: rounded-base, rounded-t-base, border-default, border-b-default, border-t-default, shadow-xs, text-body, text-heading, and neutral-secondary-medium. These must be added to the @theme block in src/app.css using proper Tailwind v4 CSS variable syntax (e.g., --radius-base, --color-default, --shadow-xs, --color-body, --color-heading, --color-neutral-secondary-medium) for the utility classes to be generated and the component styling to work correctly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This will be handled by src/lib/plugin-utilities.js in src/app.css.

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Comment on lines +16 to 18
<CheckCircleSolid class="h-6 w-6" />
{:else}
<CheckCircleSolid class="text-primary-600 dark:text-primary-300 h-6 w-6" />
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 20, 2025

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

🏁 Script executed:

cd src/routes/docs-examples/components/indicators && pwd && ls -la

Repository: themesberg/flowbite-svelte

Length of output: 758


🏁 Script executed:

find . -name "Stepper.svelte" -type f

Repository: themesberg/flowbite-svelte

Length of output: 166


🏁 Script executed:

cat -n src/routes/docs-examples/components/indicators/Stepper.svelte

Repository: themesberg/flowbite-svelte

Length of output: 2195


🏁 Script executed:

find ./src/lib -name "Indicator.svelte" -o -name "*Indicator*" | head -20

Repository: themesberg/flowbite-svelte

Length of output: 197


🏁 Script executed:

cat -n ./src/lib/indicator/Indicator.svelte

Repository: themesberg/flowbite-svelte

Length of output: 1514


🏁 Script executed:

cat -n ./src/lib/indicator/theme.ts

Repository: themesberg/flowbite-svelte

Length of output: 3612


🏁 Script executed:

# Check if there are other uses of neutral indicators with icons to see the pattern
rg -n "color=.*neutral" src/routes/docs-examples/components/indicators/ -A 5 -B 5

Repository: themesberg/flowbite-svelte

Length of output: 4746


🏁 Script executed:

# Also check the colors used in the Flowbite theme config
grep -n "neutral" src/lib/indicator/theme.ts

Repository: themesberg/flowbite-svelte

Length of output: 218


Add explicit color classes to the completed step icon for consistency.

Line 16: When i === 3, the CheckCircleSolid icon lacks explicit text color classes while incomplete steps (line 18) have text-primary-600 dark:text-primary-300. The completed step's neutral indicator background has no corresponding icon color styling, causing potential visual inconsistency. Add appropriate text color classes to match the neutral design (e.g., text-gray-600 dark:text-gray-400 or similar).

🤖 Prompt for AI Agents
In src/routes/docs-examples/components/indicators/Stepper.svelte around lines 16
to 18, the CheckCircleSolid icon rendered when i === 3 is missing explicit text
color classes while the other state uses text-primary-600 dark:text-primary-300;
update the completed-step icon to include neutral color classes (for example
text-gray-600 dark:text-gray-400) to match the neutral indicator background so
the icon color is consistent across themes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

skipped.

Copy link
Contributor

Choose a reason for hiding this comment

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

@shinokada, understood! I'll skip this suggestion. Feel free to revisit if needed in the future.


🧠 Learnings used
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.

Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.

Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.952Z
Learning: In the Flowbite Svelte library, when implementing components with validation states, the 'inputInvalid' property should be explicitly defined and passed to the Wrapper component. When inputInvalid=true, the color should be set to "red" to ensure the ring/border styling is applied correctly.

Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 20, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/routes/docs-examples/components/badge/Dismissable2.svelte (1)

10-11: Update hardcoded color classes to align with semantic token migration.

The custom icon button still references primary-* color classes (bg-primary-500, dark:bg-primary-400, hover:bg-primary-900), but the PR migrates semantic colors from "primary" to "brand". These hardcoded classes should be updated to use brand-* prefixes for consistency with the broader token migration.

🔎 Suggested update to use brand tokens
-      class="bg-primary-500 dark:bg-primary-400 dark:text-primary-800 hover:bg-primary-900 my-0.5 ms-1.5 -me-1.5 inline-flex items-center rounded-full p-0.5 text-sm text-white hover:text-white dark:hover:bg-red-900 dark:hover:text-yellow-300"
+      class="bg-brand-500 dark:bg-brand-400 dark:text-brand-800 hover:bg-brand-900 my-0.5 ms-1.5 -me-1.5 inline-flex items-center rounded-full p-0.5 text-sm text-white hover:text-white dark:hover:bg-red-900 dark:hover:text-yellow-300"
src/lib/badge/Badge.svelte (1)

90-90: Remove stale aClass from documentation comment.

The component documentation comment at line 90 still mentions @prop aClass, but this prop has been removed from the component's API (not present in the props destructuring at lines 11-28). Remove this outdated documentation.

🔎 Proposed fix
 @prop transition = fade
 @prop params
-@prop aClass
+@prop closeBtnColor
 @prop ...restProps
🧹 Nitpick comments (4)
src/tests/alert/alert.test.ts (1)

48-57: Consider expanding color variant coverage.

The Color Variants suite currently only tests the danger color explicitly. While other colors are indirectly tested in other suites (brand in Basic Functionality, success in Border Accent/List Content), explicitly testing warning and dark colors here would provide more comprehensive coverage of the color variant API surface.

💡 Optional expansion for Color Variants suite
  describe("Color Variants", () => {
    test("renders danger alert with correct color classes", () => {
      render(ColoredAlertTest);
      const alert = screen.getByRole("alert");

      expect(alert).toHaveTextContent("Danger alert");
      expect(alert).toHaveClass("text-fg-danger-strong");
      expect(alert).toHaveClass("bg-danger-soft");
    });
+
+    test("renders warning alert with correct color classes", () => {
+      // Add WarningAlertTest component
+      render(WarningAlertTest);
+      const alert = screen.getByRole("alert");
+
+      expect(alert).toHaveClass("text-fg-warning-strong");
+      expect(alert).toHaveClass("bg-warning-soft");
+    });
+
+    test("renders dark alert with correct color classes", () => {
+      // Add DarkAlertTest component
+      render(DarkAlertTest);
+      const alert = screen.getByRole("alert");
+
+      expect(alert).toHaveClass("text-fg-dark-strong");
+      expect(alert).toHaveClass("bg-dark-soft");
+    });
  });

Note: This would require creating the corresponding test fixture components.

src/lib/utils/theme.ts (1)

46-50: Consider removing unused href default variant.

The defaultVariants includes href: null, but there's no href variant defined in this theme. This appears to be dead code.

🔎 Proposed fix
  defaultVariants: {
    color: "gray",
-   size: "md",
-   href: null
+   size: "md"
  },
src/lib/badge/theme.ts (1)

46-49: Consider documenting the purpose of empty href variant objects.

The href variant with empty true/false objects exists solely for compound variant matching. A brief comment would clarify this intent for future maintainers.

🔎 Proposed enhancement
+   // Used for compound variant matching (hover states)
    href: {
      true: {},
      false: {}
    }
src/lib/badge/Badge.svelte (1)

9-9: Remove commented-out import.

The commented untrack import is no longer needed and should be deleted rather than left commented out.

🔎 Proposed fix
-  // import { untrack } from "svelte";
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db924fe and c6a461c.

📒 Files selected for processing (23)
  • src/lib/badge/Badge.svelte (5 hunks)
  • src/lib/badge/theme.ts (4 hunks)
  • src/lib/types.ts (5 hunks)
  • src/lib/utils/theme.ts (4 hunks)
  • src/routes/blocks/utils/api-check/HighlightCompo.svelte (1 hunks)
  • src/routes/builder/badge/+page.svelte (3 hunks)
  • src/routes/builder/indicators/+page.svelte (3 hunks)
  • src/routes/builder/utils/DynamicCodeBlockHighlight.svelte (1 hunks)
  • src/routes/builder/utils/HighlightCompo.svelte (1 hunks)
  • src/routes/docs-examples/components/badge/BadgeLocalStorage.svelte (1 hunks)
  • src/routes/docs-examples/components/badge/Bordered.svelte (1 hunks)
  • src/routes/docs-examples/components/badge/Default.svelte (1 hunks)
  • src/routes/docs-examples/components/badge/Dismissable.svelte (1 hunks)
  • src/routes/docs-examples/components/badge/Dismissable2.svelte (1 hunks)
  • src/routes/docs-examples/components/badge/Dynamic.svelte (1 hunks)
  • src/routes/docs-examples/components/badge/Large.svelte (1 hunks)
  • src/routes/docs-examples/components/badge/Pills.svelte (1 hunks)
  • src/routes/docs-examples/components/indicators/Badge.svelte (2 hunks)
  • src/routes/docs-examples/components/indicators/Position.svelte (1 hunks)
  • src/routes/docs-examples/components/indicators/Stepper.svelte (2 hunks)
  • src/routes/docs/components/badge.md (4 hunks)
  • src/routes/illustrations/utils/DynamicCodeBlockHighlight.svelte (1 hunks)
  • src/tests/alert/alert.test.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/routes/docs-examples/components/indicators/Badge.svelte
  • src/routes/docs-examples/components/indicators/Position.svelte
  • src/routes/builder/badge/+page.svelte
  • src/routes/builder/indicators/+page.svelte
  • src/lib/types.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/routes/blocks/utils/api-check/HighlightCompo.svelte
  • src/routes/docs-examples/components/badge/Dismissable.svelte
  • src/routes/illustrations/utils/DynamicCodeBlockHighlight.svelte
  • src/routes/docs-examples/components/badge/Default.svelte
  • src/routes/builder/utils/DynamicCodeBlockHighlight.svelte
  • src/routes/docs-examples/components/badge/Bordered.svelte
  • src/routes/docs-examples/components/badge/Pills.svelte
  • src/routes/docs-examples/components/badge/Large.svelte
  • src/lib/utils/theme.ts
  • src/routes/builder/utils/HighlightCompo.svelte
  • src/routes/docs-examples/components/badge/Dismissable2.svelte
  • src/routes/docs-examples/components/badge/Dynamic.svelte
  • src/routes/docs-examples/components/badge/BadgeLocalStorage.svelte
  • src/tests/alert/alert.test.ts
  • src/lib/badge/theme.ts
  • src/routes/docs-examples/components/indicators/Stepper.svelte
  • src/lib/badge/Badge.svelte
🧠 Learnings (8)
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/routes/blocks/utils/api-check/HighlightCompo.svelte
  • src/routes/docs-examples/components/badge/Dismissable.svelte
  • src/routes/illustrations/utils/DynamicCodeBlockHighlight.svelte
  • src/routes/docs-examples/components/badge/Default.svelte
  • src/routes/builder/utils/DynamicCodeBlockHighlight.svelte
  • src/routes/docs-examples/components/badge/Bordered.svelte
  • src/routes/docs-examples/components/badge/Pills.svelte
  • src/routes/docs-examples/components/badge/Large.svelte
  • src/routes/builder/utils/HighlightCompo.svelte
  • src/routes/docs-examples/components/badge/Dismissable2.svelte
  • src/routes/docs-examples/components/badge/Dynamic.svelte
  • src/routes/docs-examples/components/badge/BadgeLocalStorage.svelte
  • src/routes/docs-examples/components/indicators/Stepper.svelte
  • src/lib/badge/Badge.svelte
📚 Learning: 2024-11-12T10:36:34.807Z
Learnt from: LahTeuto
Repo: themesberg/flowbite-svelte PR: 1484
File: src/lib/navbar/NavLi.svelte:34-34
Timestamp: 2024-11-12T10:36:34.807Z
Learning: When enhancing ARIA roles in Svelte components, avoid setting `role="presentation"` on elements that should retain the `link` role, as it can diminish ARIA role coverage and negatively affect accessibility.

Applied to files:

  • src/routes/docs/components/badge.md
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/lib/badge/theme.ts
  • src/routes/docs-examples/components/indicators/Stepper.svelte
📚 Learning: 2025-03-20T11:11:53.952Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.952Z
Learning: In the Flowbite Svelte library, when implementing components with validation states, the 'inputInvalid' property should be explicitly defined and passed to the Wrapper component. When inputInvalid=true, the color should be set to "red" to ensure the ring/border styling is applied correctly.

Applied to files:

  • src/routes/docs-examples/components/indicators/Stepper.svelte
📚 Learning: 2025-03-20T11:11:53.953Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.953Z
Learning: In the Flowbite Svelte library's MultiInput component, the 'inputInvalid' property should be exported and passed to the Wrapper component to properly style the component's ring with red color when validation fails, similar to how the Input component handles validation states.

Applied to files:

  • src/routes/docs-examples/components/indicators/Stepper.svelte
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.

Applied to files:

  • src/routes/docs-examples/components/indicators/Stepper.svelte
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.

Applied to files:

  • src/routes/docs-examples/components/indicators/Stepper.svelte
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles, ensure both the container (with focus-within) and the inner input element (with direct focus) have dynamic styling based on the validation state. The input element needs its own focus styles that change to red when inputInvalid=true.

Applied to files:

  • src/routes/docs-examples/components/indicators/Stepper.svelte
🧬 Code graph analysis (1)
src/tests/alert/alert.test.ts (2)
src/lib/alert/theme.ts (1)
  • alert (6-117)
src/lib/utils/theme.ts (1)
  • closeButton (7-85)
🔇 Additional comments (22)
src/tests/alert/alert.test.ts (3)

1-20: LGTM! Imports and setup are clean.

The imports are well-organized with testing utilities and all required test fixtures. The afterEach cleanup ensures proper test isolation.


192-205: Excellent coverage of the listContent prop!

The List Content test suite properly validates the listContent prop behavior, checking for the appropriate border and color-specific classes. This addresses the previous review feedback comprehensively.


22-206: Well-structured and comprehensive test suite!

The test suite demonstrates excellent coverage of the Alert component's functionality:

  • ✅ Accessibility: Proper use of role="alert" and aria-label checks
  • ✅ Async handling: Correct use of waitForElementToBeRemoved for transitions
  • ✅ Test isolation: Each test renders its own fixture component
  • ✅ API surface coverage: Tests all major props (dismissable, icon, border, borderAccent, closeColor, listContent, color variants, custom colors)
  • ✅ Event handling: Close event properly tested with indicator pattern

The tests follow Vitest and Testing Library best practices throughout.

src/routes/docs-examples/components/indicators/Stepper.svelte (2)

10-16: Color migration aligns with semantic token system.

The update from "gray" to "neutral" and the corresponding dark mode background adjustments are consistent with the semantic color token migration described in the PR objectives. The conditional color logic correctly applies "neutral" for completed steps.


31-32: Semantic color tokens correctly applied.

The migration from "orange"/"secondary" to "warning"/"success" is consistent with the new semantic color system confirmed in theme.ts. The conditional color logic properly differentiates between in-progress and completed steps.

src/routes/builder/utils/HighlightCompo.svelte (1)

60-60: LGTM! Consistent semantic color token migration.

The change from green to success aligns with the broader semantic color palette refactor across the codebase.

src/routes/blocks/utils/api-check/HighlightCompo.svelte (1)

60-60: LGTM! Matches the semantic color token update.

Consistent with the parallel change in the builder utils variant.

src/routes/illustrations/utils/DynamicCodeBlockHighlight.svelte (1)

52-52: LGTM! Semantic color token applied consistently.

The success color token is correctly applied for the copied-to-clipboard feedback badge.

src/routes/builder/utils/DynamicCodeBlockHighlight.svelte (1)

53-53: LGTM! Completes the consistent color token update across highlight components.

All four highlight component variants now use the semantic success token for the copied-to-clipboard badge.

src/lib/badge/theme.ts (1)

7-38: Clean semantic color palette migration.

The refactored color variants with semantic tokens (brand, alternative, gray, danger, success, warning) alongside the extended Tailwind palette provides a solid foundation. The slot-based structure is well-organized.

src/lib/utils/theme.ts (1)

7-44: Semantic color tokens require verification in Tailwind configuration.

The semantic color migration approach using brand, danger, success, warning, and dark tokens is sound and follows design system best practices. However, these custom tokens (bg-brand-softer, text-fg-brand-strong, bg-danger-soft, bg-success-soft, bg-warning-soft, etc.) must be explicitly defined in your Tailwind config or CSS to function. Verify these token definitions exist before merging.

Additionally, check whether defaultVariants includes any unused keys (e.g., href: null) that lack corresponding variant definitions.

src/routes/docs-examples/components/badge/Dismissable2.svelte (1)

6-6: LGTM! Addition of large attribute is consistent with the example pattern.

The large attribute enhances the badge variant demonstration in this dismissable example.

src/routes/docs-examples/components/badge/Dynamic.svelte (1)

6-8: LGTM! Color token migration is correct.

The update from "primary"/"secondary" to "brand"/"alternative" correctly reflects the semantic color token migration in version 2.

src/routes/docs-examples/components/badge/BadgeLocalStorage.svelte (1)

41-41: LGTM! Removal of explicit color prop aligns with new default.

Since the Badge component's default color is now "brand" in version 2, removing the explicit color="primary" prop is the correct migration approach.

src/routes/docs-examples/components/badge/Default.svelte (1)

5-10: LGTM! Semantic color token migration is consistent.

The update to the new semantic color palette (brand, alternative, danger, success, warning) correctly reflects the version 2 badge color system.

src/routes/docs-examples/components/badge/Dismissable.svelte (1)

5-12: LGTM! Border attribute and semantic colors applied consistently.

All dismissable badges now use the border attribute with the updated semantic color tokens, creating a uniform set of examples.

src/routes/docs-examples/components/badge/Large.svelte (1)

5-10: LGTM! Large badge examples updated with semantic color tokens.

The color token migration is correctly applied to all large badge variants, maintaining consistency with the version 2 color system.

src/routes/docs-examples/components/badge/Bordered.svelte (1)

5-24: Restructured bordered badge examples with semantic colors.

The two-group presentation effectively demonstrates both standard and large bordered badge variants with the new semantic color tokens.

src/routes/docs-examples/components/badge/Pills.svelte (1)

5-10: LGTM! Pill badge examples updated with semantic color tokens.

The rounded (pill) badge variants correctly use the new semantic color palette, maintaining consistency across all badge example files.

src/routes/docs/components/badge.md (1)

39-39: Documentation improvements look good.

The text simplifications make the documentation more concise while maintaining clarity and technical accuracy.

Also applies to: 47-47, 55-55, 63-63, 71-71, 81-81, 97-97, 105-105, 113-113, 125-125, 133-133

src/lib/badge/Badge.svelte (2)

33-33: Correct usage of getTheme with $derived().

The theme is properly derived using $derived(getTheme("badge")), which ensures the component reacts to dynamic theme changes. This follows the established pattern for theme reactivity in Flowbite-Svelte.

Based on learnings, getTheme calls should be placed inside a $derived() expression for reactive theme updates.


30-30: Simplified styling derivation.

The direct derivation from classes simplifies the styling logic and aligns with the removal of the deprecated aClass prop.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/badge/Badge.svelte (1)

89-89: Remove stale documentation reference.

The documentation comment on line 89 references an aClass prop that no longer exists in the component's prop destructuring. According to the AI summary, aClass was removed in favor of the new classes and styling structure.

🔎 Proposed fix
 @prop rounded
 @prop transition = fade
 @prop params
-@prop aClass
+@prop closeBtnColor = 'gray'
 @prop ...restProps
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6a461c and 7ff797c.

📒 Files selected for processing (4)
  • src/lib/badge/Badge.svelte (5 hunks)
  • src/lib/badge/theme.ts (4 hunks)
  • src/lib/utils/theme.ts (4 hunks)
  • src/routes/docs-examples/components/badge/Bordered.svelte (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/routes/docs-examples/components/badge/Bordered.svelte
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/lib/badge/theme.ts
  • src/lib/utils/theme.ts
  • src/lib/badge/Badge.svelte
🧠 Learnings (4)
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/lib/badge/theme.ts
📚 Learning: 2025-03-20T11:11:53.952Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.952Z
Learning: In the Flowbite Svelte library, when implementing components with validation states, the 'inputInvalid' property should be explicitly defined and passed to the Wrapper component. When inputInvalid=true, the color should be set to "red" to ensure the ring/border styling is applied correctly.

Applied to files:

  • src/lib/badge/Badge.svelte
📚 Learning: 2025-03-20T11:11:53.953Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.953Z
Learning: In the Flowbite Svelte library's MultiInput component, the 'inputInvalid' property should be exported and passed to the Wrapper component to properly style the component's ring with red color when validation fails, similar to how the Input component handles validation states.

Applied to files:

  • src/lib/badge/Badge.svelte
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/lib/badge/Badge.svelte
🔇 Additional comments (15)
src/lib/utils/theme.ts (5)

40-40: Consider accessibility implications of the xs size.

The xs size (16x16px) is below the recommended minimum touch target size of 24x24px per WCAG 2.5.5 (Level AAA) and many platform guidelines. Ensure this size is only used in contexts where touch interaction is not expected or where adequate spacing around the button provides a larger effective touch area.


40-43: Size variants implementation looks good.

The explicit sizing with padding and dimensions is clear and maintainable. The progression from xs to lg is logical, and the default of "md" (32x32px) provides a good balance between usability and visual design.

Also applies to: 48-48


53-77: SVG sizing in compound variants looks well-proportioned.

The icon sizes relative to button sizes are appropriate:

  • xs: 10px icon in 16px button (62.5%)
  • sm: 14px icon in 24px button (58.3%)
  • md: 16px icon in 32px button (50%)
  • lg: 20px icon in 40px button (50%)

Splitting md and lg into separate compound variant entries improves clarity and maintainability.


8-8: No issues found. The focus:outline-hidden class is a standard Tailwind CSS utility that properly hides the outline while preserving it in forced colors mode for accessibility, paired appropriately with focus:ring-2 for visible focus indication.


11-15: The semantic design tokens (bg-danger-soft, text-fg-danger-strong, bg-success-soft, bg-warning-soft, text-heading, bg-neutral-secondary-medium, bg-neutral-tertiary, etc.) are already defined through the Flowbite default theme import in src/app.css. The brand color tokens are explicitly overridden in the @theme block, while the remaining semantic tokens (danger, success, warning, neutral) are provided by Flowbite's theme system. These tokens are used across multiple components and have passing tests, confirming they are available and functional.

Likely an incorrect or invalid review comment.

src/lib/badge/Badge.svelte (4)

4-4: LGTM!

The getTheme import is correctly used on line 32 within a $derived() expression, ensuring the component reacts to dynamic theme changes.


10-27: LGTM!

Props are well-structured with appropriate defaults. The closeBtnColor = 'gray' default ensures consistent styling with CloseButton's default, and the color = "brand" default aligns with the semantic color migration in the theme.


29-34: LGTM!

The styling and theme derivations are correctly implemented. The getTheme call is properly placed inside $derived() to ensure reactivity with ThemeProvider changes, consistent with the project's reactive theme pattern.


47-67: LGTM!

The conditional rendering logic correctly handles both link and non-link badge variants, with proper prop spreading and theme class composition. The CloseButton integration uses the closeBtnColor prop consistently.

src/lib/badge/theme.ts (6)

9-10: LGTM!

The slot class updates are correct. Using items-center instead of align-middle is the proper Flexbox utility, and the base slot now includes comprehensive styling with rounded and leading-none for consistent badge appearance.


37-50: LGTM!

The size variants are clearly defined with appropriate text and padding values. The addition of the href boolean variant for compound matching is a good pattern that enables hover state customization when badges are used as links.


52-152: LGTM!

Border compound variants are comprehensive, covering all color options with appropriate border classes. The semantic colors use semantic border tokens (border-brand-subtle, border-danger-subtle, etc.), while the extended palette includes dark mode overrides, maintaining consistency with the base color approach.


153-253: LGTM!

Hover compound variants provide interactive states for all badge colors when used as links. The semantic colors consistently use semantic hover tokens (hover:bg-brand-medium, hover:bg-danger-medium, etc.), while the extended palette uses numeric hover tokens (hover:bg-orange-200, etc.), maintaining the same pattern as the base colors.


256-259: LGTM!

Default variants are correctly set with color: "brand" aligning with the semantic color migration, size: "small" for compact badges, and rounded: false for standard rectangular badges.


14-34: This mixed approach is intentional and consistent across the library. Semantic tokens in app.css are defined only for core, meaning-bearing colors (brand, danger, success, warning, and neutral variations), while the extended palette colors (orange through rose) have no semantic token definitions. Other components like Button and Banner follow the same pattern, using semantic tokens for primary colors and traditional Tailwind utilities for the extended palette. The extended palette is treated as an aesthetic option layer rather than semantically meaningful, so using traditional Tailwind tokens is the correct approach.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (2)
src/lib/badge/Badge.svelte (1)

25-25: closeBtnColor default properly added.

The closeBtnColor = "gray" default has been added, addressing the previous review feedback. This ensures consistent styling when the prop is not explicitly provided, matching CloseButton's expected default.

src/lib/types.ts (1)

214-221: AccordionItemProps is missing styling props required for per-item customization.

The interface is missing activeClass, inactiveClass, classes, headerClass, and contentClass—properties that allow controlling AccordionItem appearance both at the parent level (applying to all children) or individually on each AccordionItem. If per-item styling is needed, add these properties to the interface to match the Flowbite-Svelte component API and enable style overrides.

🧹 Nitpick comments (14)
src/tests/TEST-DOCUMENTATION.md (1)

152-152: Consider using a proper heading instead of bold emphasis.

Line 152 uses bold emphasis (**Total: 33 test cases across 3 components**) to introduce the summary statistic. This would be better formatted as a proper Markdown heading (e.g., ### Total Test Cases) for semantic clarity and consistency with the document structure.

🔎 Proposed fix
-**Total: 33 test cases across 3 components**
+### Total: 33 test cases across 3 components
src/tests/badge/badge-link.test.svelte (1)

1-5: Consider adding test assertions for href behavior.

The test renders a Badge with the href prop, which aligns with the new API. However, there are no explicit assertions to verify the link behavior (e.g., checking that an <a> element is rendered with the correct href attribute).

Example: Adding assertions
<script lang="ts">
  import { render, screen } from '@testing-library/svelte';
  import Badge from "$lib/badge/Badge.svelte";
  
  // Test that href renders as link
  const { container } = render(Badge, { props: { href: "/link" }, slots: { default: "Link Badge" } });
  const link = container.querySelector('a[href="/link"]');
  expect(link).toBeTruthy();
</script>

Note: If these files are intentionally used as visual regression fixtures or snapshots, this suggestion may not apply.

src/tests/badge/badge-colors.test.svelte (1)

1-9: Test covers semantic color variants; consider adding visual assertions.

The test renders Badge instances with the new semantic color palette (brand, gray, red, green, yellow), which aligns with the theme updates in this PR. Consider adding assertions to verify that the correct color classes are applied.

src/tests/badge/dismissable-badge.test.svelte (1)

1-5: Test covers dismissable variant; consider verifying dismiss behavior.

The test renders a dismissable Badge. Consider adding assertions to verify the close button is rendered and that clicking it dismisses the badge.

src/tests/banner/banner.test.ts (1)

127-133: Brittle selector couples test to implementation.

Line 130 uses querySelector("div.flex.items-center.justify-end") which tightly couples the test to the internal DOM structure and styling classes. If the implementation changes these classes, the test breaks even though the functionality remains correct.

🔎 Suggested improvement

Use semantic queries or add a data-testid:

-    test("dismissable banner has close button container", () => {
-      const { container } = render(BasicBannerTest);
-      const banner = container.querySelector("div[tabindex='-1']");
-      const closeContainer = banner?.querySelector("div.flex.items-center.justify-end");
-
-      expect(closeContainer).toBeInTheDocument();
-    });
+    test("dismissable banner has close button", () => {
+      render(BasicBannerTest);
+      const closeButton = screen.getByRole("button", { name: /remove banner/i });
+
+      expect(closeButton).toBeInTheDocument();
+    });

This tests the same functionality (presence of dismissal UI) without coupling to styling classes.

src/tests/bottom-navigation/README.md (2)

47-47: Consider using a heading instead of emphasis.

Line 47 uses bold text for emphasis. For better document structure and accessibility, consider using a heading (e.g., ### Total: 17 test cases across 4 components).

🔎 Suggested fix
-**Total: 17 test cases across 4 components**
+### Total: 17 test cases across 4 components

Based on static analysis hints.


148-160: Add language specifiers to fenced code blocks.

The code blocks at lines 148-160 and 276-283 are missing language identifiers. Adding language specifiers improves syntax highlighting and readability.

🔎 Suggested fixes

For the file structure block (line 148):

-```
+```text
 src/tests/bottom-navigation/

For the component relationship diagram (line 276):

-```
+```text
 BottomNav (Context Provider)

Based on static analysis hints.

Also applies to: 276-283

src/tests/bottom-navigation/bottom-navigation.test.ts (2)

117-129: Active state test could be more thorough.

The test comment on line 126 acknowledges that active state is applied through classes but only verifies button existence. Consider adding an assertion that actually checks for the active class on the element to ensure the styling is applied correctly.

     // Active state is applied through classes, we just verify the buttons exist
-    expect(homeButton.tagName).toBe("BUTTON");
-    expect(walletButton.tagName).toBe("BUTTON");
+    expect(homeButton.tagName).toBe("BUTTON");
+    expect(walletButton.tagName).toBe("BUTTON");
+    // Optionally verify active class is applied to the expected button
+    // expect(homeButton).toHaveClass("expected-active-class");

213-221: Test name doesn't match behavior being tested.

The test "activeUrl prop affects link rendering" only verifies href attributes exist, but doesn't actually test that activeUrl affects anything. Consider renaming the test to match what it actually validates, or enhance it to verify active state based on URL matching.

src/lib/bottom-navigation/theme.ts (1)

110-125: Consider migrating header components to semantic tokens.

The bottomNavHeader and bottomNavHeaderItem variants still use hardcoded gray color classes (bg-gray-100, dark:bg-gray-600, text-gray-900, etc.) while the main components have been migrated to semantic tokens. If this is intentional (perhaps header wasn't in scope), this is fine. Otherwise, consider aligning these with the neutral/semantic token system for consistency.

src/lib/bottom-navigation/CHANGES-SUMMARY.md (1)

1-194: Consider whether this internal documentation file should be committed.

This CHANGES-SUMMARY.md file documents internal refactoring decisions and a testing checklist. While useful during development, consider whether it should:

  1. Remain in the codebase as reference documentation
  2. Be moved to a docs/ or CONTRIBUTING.md location
  3. Be removed before merging (keeping only MIGRATION-GUIDE.md for users)
src/lib/badge/theme.ts (1)

13-27: Minor: Comment listing colors is incomplete.

The comment on line 14 lists brand, alternative, gray, danger, success, warning, orange, amber, lime, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose but doesn't distinguish between semantic (new) and legacy colors. Consider updating the comment to clearly separate the two categories or removing it since the code is self-documenting.

🔎 Proposed fix
   color: {
-     // brand, alternative, gray, danger, success, warning, orange, amber, lime, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose
+     // Semantic colors
      brand: { base: "bg-brand-softer text-fg-brand-strong " },
      alternative: { base: "bg-neutral-primary-soft text-heading" },
      gray: { base: "bg-neutral-secondary-medium text-heading " },
      danger: { base: "bg-danger-soft text-fg-danger-strong" },
      success: { base: "bg-success-soft text-fg-success-strong" },
      warning: { base: "bg-warning-soft text-fg-warning" },
      // Legacy colors for backward compatibility
src/tests/avatar/avatar.test.ts (2)

46-46: Consider a more robust indicator selector.

The selector [class*="absolute"] is brittle and couples the test to implementation details. If the indicator styling changes (e.g., positioning strategy), this test could break.

🔎 Alternative approaches

Consider one of these options:

  1. Check by role or test-id (if indicator has semantic meaning):
-const indicator = button.querySelector('[class*="absolute"]');
+const indicator = button.querySelector('[data-testid="avatar-indicator"]');
  1. Check for presence of dot/indicator component by structure (if structure is stable):
-const indicator = button.querySelector('[class*="absolute"]');
+// Check that button contains both img and an additional child (the indicator)
+expect(button.children.length).toBeGreaterThan(1);
  1. If absolute positioning is part of the public contract, document it and keep the current approach.

63-71: Comment mentions specific ring class but assertion is generic.

Line 70 comment states "The border class (ring-2) should be applied" but the assertion at line 70 only checks for substring "ring", which would pass with any ring-related class.

🔎 More specific assertion

If ring-2 is the expected class:

-expect(img.className).toContain("ring");
+expect(img.className).toContain("ring-2");

Or if any ring class is acceptable, update the comment:

-// The border class (ring-2) should be applied
+// A ring class should be applied for the border
 expect(img.className).toContain("ring");
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ff797c and ab80826.

📒 Files selected for processing (56)
  • package.json (3 hunks)
  • src/lib/alert/theme.ts (3 hunks)
  • src/lib/badge/Badge.svelte (6 hunks)
  • src/lib/badge/theme.ts (4 hunks)
  • src/lib/banner/Banner.svelte (4 hunks)
  • src/lib/banner/theme.ts (1 hunks)
  • src/lib/bottom-navigation/BottomNav.svelte (3 hunks)
  • src/lib/bottom-navigation/BottomNavHeader.svelte (1 hunks)
  • src/lib/bottom-navigation/BottomNavItem.svelte (3 hunks)
  • src/lib/bottom-navigation/CHANGES-SUMMARY.md (1 hunks)
  • src/lib/bottom-navigation/MIGRATION-GUIDE.md (1 hunks)
  • src/lib/bottom-navigation/theme.ts (4 hunks)
  • src/lib/types.ts (6 hunks)
  • src/routes/docs-examples/components/bottom-navigation/ActiveLink.svelte (1 hunks)
  • src/routes/docs-examples/components/bottom-navigation/Application.svelte (2 hunks)
  • src/routes/docs-examples/components/bottom-navigation/Border.svelte (1 hunks)
  • src/routes/docs-examples/components/bottom-navigation/Bottom.svelte (2 hunks)
  • src/routes/docs-examples/components/bottom-navigation/Card.svelte (2 hunks)
  • src/routes/docs-examples/components/bottom-navigation/Default.svelte (1 hunks)
  • src/routes/docs-examples/components/bottom-navigation/IconColor.svelte (2 hunks)
  • src/routes/docs-examples/components/bottom-navigation/Links.svelte (2 hunks)
  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte (3 hunks)
  • src/routes/docs/components/banner.md (4 hunks)
  • src/routes/docs/components/bottom-navigation.md (4 hunks)
  • src/tests/TEST-DOCUMENTATION.md (1 hunks)
  • src/tests/avatar/avatar-link.test.svelte (1 hunks)
  • src/tests/avatar/avatar-sizes.test.svelte (1 hunks)
  • src/tests/avatar/avatar-squared.test.svelte (1 hunks)
  • src/tests/avatar/avatar-with-border.test.svelte (1 hunks)
  • src/tests/avatar/avatar-with-dot.test.svelte (1 hunks)
  • src/tests/avatar/avatar-with-image.test.svelte (1 hunks)
  • src/tests/avatar/avatar.test.ts (1 hunks)
  • src/tests/avatar/basic-avatar.test.svelte (1 hunks)
  • src/tests/badge/badge-border.test.svelte (1 hunks)
  • src/tests/badge/badge-colors.test.svelte (1 hunks)
  • src/tests/badge/badge-link.test.svelte (1 hunks)
  • src/tests/badge/badge.test.ts (1 hunks)
  • src/tests/badge/basic-badge.test.svelte (1 hunks)
  • src/tests/badge/dismissable-badge.test.svelte (1 hunks)
  • src/tests/badge/large-badge.test.svelte (1 hunks)
  • src/tests/banner/banner-closed.test.svelte (1 hunks)
  • src/tests/banner/banner-colors.test.svelte (1 hunks)
  • src/tests/banner/banner.test.ts (1 hunks)
  • src/tests/banner/basic-banner.test.svelte (1 hunks)
  • src/tests/banner/non-dismissable-banner.test.svelte (1 hunks)
  • src/tests/bottom-navigation/README.md (1 hunks)
  • src/tests/bottom-navigation/basic-bottom-nav.test.svelte (1 hunks)
  • src/tests/bottom-navigation/bottom-nav-app-type.test.svelte (1 hunks)
  • src/tests/bottom-navigation/bottom-nav-header-item-clickable.test.svelte (1 hunks)
  • src/tests/bottom-navigation/bottom-nav-header.test.svelte (1 hunks)
  • src/tests/bottom-navigation/bottom-nav-item-active.test.svelte (1 hunks)
  • src/tests/bottom-navigation/bottom-nav-item-button.test.svelte (1 hunks)
  • src/tests/bottom-navigation/bottom-nav-item-link.test.svelte (1 hunks)
  • src/tests/bottom-navigation/bottom-nav-static.test.svelte (1 hunks)
  • src/tests/bottom-navigation/bottom-nav-with-header.test.svelte (1 hunks)
  • src/tests/bottom-navigation/bottom-navigation.test.ts (1 hunks)
✅ Files skipped from review due to trivial changes (5)
  • src/tests/banner/basic-banner.test.svelte
  • src/lib/bottom-navigation/MIGRATION-GUIDE.md
  • src/tests/avatar/avatar-with-image.test.svelte
  • src/tests/bottom-navigation/bottom-nav-static.test.svelte
  • src/tests/badge/badge-border.test.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/tests/banner/non-dismissable-banner.test.svelte
  • src/tests/badge/badge-link.test.svelte
  • src/tests/banner/banner-colors.test.svelte
  • src/tests/bottom-navigation/bottom-nav-item-active.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Card.svelte
  • src/tests/bottom-navigation/bottom-nav-app-type.test.svelte
  • src/tests/avatar/avatar-squared.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Links.svelte
  • src/tests/avatar/avatar.test.ts
  • src/lib/bottom-navigation/theme.ts
  • src/routes/docs-examples/components/bottom-navigation/IconColor.svelte
  • src/tests/badge/dismissable-badge.test.svelte
  • src/tests/badge/large-badge.test.svelte
  • src/tests/bottom-navigation/basic-bottom-nav.test.svelte
  • src/lib/banner/theme.ts
  • src/tests/bottom-navigation/bottom-navigation.test.ts
  • src/routes/docs-examples/components/bottom-navigation/Bottom.svelte
  • src/lib/banner/Banner.svelte
  • src/routes/docs-examples/components/bottom-navigation/Default.svelte
  • src/tests/banner/banner.test.ts
  • src/tests/avatar/avatar-with-dot.test.svelte
  • src/tests/badge/badge.test.ts
  • src/lib/bottom-navigation/BottomNav.svelte
  • src/lib/bottom-navigation/BottomNavHeader.svelte
  • src/routes/docs-examples/components/bottom-navigation/Application.svelte
  • src/lib/badge/Badge.svelte
  • src/tests/badge/basic-badge.test.svelte
  • src/tests/avatar/basic-avatar.test.svelte
  • src/lib/badge/theme.ts
  • src/tests/bottom-navigation/bottom-nav-item-link.test.svelte
  • src/tests/avatar/avatar-link.test.svelte
  • src/tests/avatar/avatar-sizes.test.svelte
  • src/tests/banner/banner-closed.test.svelte
  • src/tests/avatar/avatar-with-border.test.svelte
  • src/tests/bottom-navigation/bottom-nav-header-item-clickable.test.svelte
  • src/tests/bottom-navigation/bottom-nav-with-header.test.svelte
  • src/tests/bottom-navigation/bottom-nav-item-button.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Border.svelte
  • src/tests/badge/badge-colors.test.svelte
  • src/lib/alert/theme.ts
  • src/tests/bottom-navigation/bottom-nav-header.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte
  • src/routes/docs-examples/components/bottom-navigation/ActiveLink.svelte
  • src/lib/bottom-navigation/BottomNavItem.svelte
  • src/lib/types.ts
🧠 Learnings (12)
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/tests/banner/non-dismissable-banner.test.svelte
  • src/tests/badge/badge-link.test.svelte
  • src/tests/banner/banner-colors.test.svelte
  • src/tests/bottom-navigation/bottom-nav-item-active.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Card.svelte
  • src/tests/bottom-navigation/bottom-nav-app-type.test.svelte
  • src/tests/avatar/avatar-squared.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Links.svelte
  • src/routes/docs-examples/components/bottom-navigation/IconColor.svelte
  • src/tests/badge/dismissable-badge.test.svelte
  • src/tests/badge/large-badge.test.svelte
  • src/tests/bottom-navigation/basic-bottom-nav.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Bottom.svelte
  • src/lib/banner/Banner.svelte
  • src/routes/docs-examples/components/bottom-navigation/Default.svelte
  • src/tests/avatar/avatar-with-dot.test.svelte
  • src/lib/bottom-navigation/BottomNav.svelte
  • src/lib/bottom-navigation/BottomNavHeader.svelte
  • src/routes/docs-examples/components/bottom-navigation/Application.svelte
  • src/lib/badge/Badge.svelte
  • src/tests/badge/basic-badge.test.svelte
  • src/tests/avatar/basic-avatar.test.svelte
  • src/tests/bottom-navigation/bottom-nav-item-link.test.svelte
  • src/tests/avatar/avatar-link.test.svelte
  • src/tests/avatar/avatar-sizes.test.svelte
  • src/tests/banner/banner-closed.test.svelte
  • src/tests/avatar/avatar-with-border.test.svelte
  • src/tests/bottom-navigation/bottom-nav-header-item-clickable.test.svelte
  • src/tests/bottom-navigation/bottom-nav-with-header.test.svelte
  • src/tests/bottom-navigation/bottom-nav-item-button.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Border.svelte
  • src/tests/badge/badge-colors.test.svelte
  • src/tests/bottom-navigation/bottom-nav-header.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte
  • src/routes/docs-examples/components/bottom-navigation/ActiveLink.svelte
  • src/lib/bottom-navigation/BottomNavItem.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

Applied to files:

  • src/tests/bottom-navigation/bottom-nav-item-active.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Card.svelte
  • src/tests/bottom-navigation/bottom-nav-app-type.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Links.svelte
  • src/routes/docs-examples/components/bottom-navigation/IconColor.svelte
  • src/tests/bottom-navigation/basic-bottom-nav.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Bottom.svelte
  • src/routes/docs-examples/components/bottom-navigation/Default.svelte
  • src/routes/docs-examples/components/bottom-navigation/Application.svelte
  • src/tests/bottom-navigation/bottom-nav-item-link.test.svelte
  • src/routes/docs-examples/components/bottom-navigation/Border.svelte
  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte
  • src/routes/docs-examples/components/bottom-navigation/ActiveLink.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Use getComponentList tool to discover available Flowbite-Svelte components or help users explore component options

Applied to files:

  • src/routes/docs-examples/components/bottom-navigation/Card.svelte
  • src/routes/docs-examples/components/bottom-navigation/Bottom.svelte
  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use getComponentList tool to discover available Flowbite-Svelte components with their categories or to help users explore component options

Applied to files:

  • src/routes/docs-examples/components/bottom-navigation/Card.svelte
  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation

Applied to files:

  • src/routes/docs-examples/components/bottom-navigation/Links.svelte
  • src/routes/docs-examples/components/bottom-navigation/IconColor.svelte
  • src/routes/docs-examples/components/bottom-navigation/Bottom.svelte
  • src/routes/docs-examples/components/bottom-navigation/Application.svelte
  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/tests/TEST-DOCUMENTATION.md
  • src/routes/docs-examples/components/bottom-navigation/Bottom.svelte
  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/docs-examples/components/bottom-navigation/Bottom.svelte
  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte
📚 Learning: 2025-03-20T11:11:53.952Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.952Z
Learning: In the Flowbite Svelte library, when implementing components with validation states, the 'inputInvalid' property should be explicitly defined and passed to the Wrapper component. When inputInvalid=true, the color should be set to "red" to ensure the ring/border styling is applied correctly.

Applied to files:

  • src/lib/badge/Badge.svelte
📚 Learning: 2025-03-20T11:11:53.953Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.953Z
Learning: In the Flowbite Svelte library's MultiInput component, the 'inputInvalid' property should be exported and passed to the Wrapper component to properly style the component's ring with red color when validation fails, similar to how the Input component handles validation states.

Applied to files:

  • src/lib/badge/Badge.svelte
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/lib/badge/theme.ts
  • src/lib/alert/theme.ts
📚 Learning: 2024-11-12T10:36:34.807Z
Learnt from: LahTeuto
Repo: themesberg/flowbite-svelte PR: 1484
File: src/lib/navbar/NavLi.svelte:34-34
Timestamp: 2024-11-12T10:36:34.807Z
Learning: When enhancing ARIA roles in Svelte components, avoid setting `role="presentation"` on elements that should retain the `link` role, as it can diminish ARIA role coverage and negatively affect accessibility.

Applied to files:

  • src/routes/docs/components/bottom-navigation.md
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use searchDocs tool for full-text search across Flowbite-Svelte documentation when looking for specific information that might span multiple components or when users ask about features or patterns

Applied to files:

  • src/routes/docs-examples/components/bottom-navigation/Pagination.svelte
🧬 Code graph analysis (2)
src/tests/banner/banner.test.ts (1)
src/lib/banner/theme.ts (1)
  • banner (7-54)
src/lib/types.ts (3)
src/lib/utils/theme.ts (1)
  • CloseButtonVariants (5-5)
src/lib/badge/theme.ts (1)
  • BadgeVariants (5-5)
src/lib/banner/theme.ts (1)
  • BannerVariants (5-5)
🪛 LanguageTool
src/tests/TEST-DOCUMENTATION.md

[grammar] ~36-~36: Use a hyphen to join words.
Context: ...link - large-badge.test.svelte - Large size variant - `badge-colors.test.svelte...

(QB_NEW_EN_HYPHEN)

🪛 markdownlint-cli2 (0.18.1)
src/tests/TEST-DOCUMENTATION.md

105-105: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


152-152: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

src/tests/bottom-navigation/README.md

47-47: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


148-148: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


276-276: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (60)
src/tests/TEST-DOCUMENTATION.md (1)

1-221: Excellent documentation structure and content.

This is a well-organized, comprehensive guide covering test structure, running instructions, examples, and important behavioral notes. The separation of helper components from test assertions follows good practices, and the examples for adding new tests are clear and actionable. Once the markdown formatting issues are resolved, this will be a valuable reference for contributors.

src/routes/docs-examples/components/bottom-navigation/Pagination.svelte (3)

3-3: Icon migration to outline variants looks good.

The switch from solid to outline icons (BookmarkSolid → BookmarkOutline, UserCircleSolid → UserCircleOutline) is consistent with the broader icon modernization across bottom-navigation components mentioned in the PR summary.


15-15: Icon component usages updated correctly.

Both BookmarkOutline (line 15) and UserCircleOutline (line 42) are used consistently with the updated imports, maintaining the same class attributes and styling patterns.

Also applies to: 42-42


19-19: The CSS classes use rounded-base, rounded-s-base, and rounded-e-base, which are not standard Tailwind utilities. Tailwind's default border-radius values are: rounded-none, rounded-sm, rounded, rounded-md, rounded-lg, rounded-xl, rounded-2xl, rounded-3xl, rounded-full. These utilities are not defined anywhere in the codebase (not in the custom plugin, theme configuration, or Flowbite imports) and will not be recognized by Tailwind. Replace these with actual Tailwind utilities—for example, use rounded-md or rounded-lg instead of rounded-base.

Likely an incorrect or invalid review comment.

src/routes/docs/components/bottom-navigation.md (1)

42-96: LGTM: Documentation improvements enhance clarity.

The minor wording and formatting adjustments improve readability and consistency across the examples without changing the technical content.

src/tests/bottom-navigation/bottom-nav-header-item-clickable.test.svelte (1)

1-12: LGTM: Click handler test uses correct Svelte 5 syntax.

The test correctly uses Svelte 5's lowercase onclick event handler and exposes the clicked state via data-testid for assertion. The structure is appropriate for integration with testing libraries.

src/tests/badge/basic-badge.test.svelte (1)

1-5: LGTM: Tests default Badge rendering.

The test validates the Badge component's default behavior (which now uses "brand" as the default color per the API changes).

src/tests/banner/banner-colors.test.svelte (1)

1-8: LGTM: Banner color variant coverage added.

The test renders Banner instances with semantic color variants (brand, red, green, yellow), consistent with the updated theming introduced in this PR.

src/tests/badge/large-badge.test.svelte (1)

1-5: LGTM: Large Badge variant test added.

The test validates the large prop functionality for the Badge component.

src/tests/bottom-navigation/bottom-nav-header.test.svelte (1)

1-9: LGTM! Clean test implementation.

This test file provides clear coverage for the BottomNavHeader component with proper active state handling across multiple items.

src/routes/docs-examples/components/bottom-navigation/Card.svelte (1)

3-3: LGTM! Consistent icon variant migration.

The replacement of Solid icon variants with Outline variants aligns with the broader icon standardization across bottom-navigation examples in this PR.

Also applies to: 49-49, 55-55

src/tests/bottom-navigation/bottom-nav-item-link.test.svelte (1)

1-16: LGTM! Well-structured navigation test.

This test effectively demonstrates the link-based navigation pattern with proper activeUrl tracking and icon integration.

src/tests/banner/non-dismissable-banner.test.svelte (1)

1-5: LGTM! Clear non-dismissable banner test.

This test provides focused coverage for the non-dismissable banner scenario with correct prop usage.

src/routes/docs-examples/components/bottom-navigation/Border.svelte (1)

3-3: LGTM! Consistent icon standardization.

The migration to Outline icon variants maintains visual consistency with other bottom-navigation examples in this PR.

Also applies to: 11-11, 14-14, 20-20

src/tests/bottom-navigation/basic-bottom-nav.test.svelte (1)

1-16: LGTM! Clean basic test case.

This test provides clear coverage for the minimal BottomNav usage pattern without navigation features.

src/routes/docs-examples/components/bottom-navigation/Links.svelte (1)

3-3: LGTM! Icon updates align with standardization effort.

The Outline icon variants are correctly integrated with the existing link-based navigation and reactive activeUrl pattern.

Also applies to: 13-13, 16-16, 22-22

src/tests/bottom-navigation/bottom-nav-app-type.test.svelte (1)

1-22: LGTM! Comprehensive application nav test.

This test effectively demonstrates the application navType with a middle-positioned button, providing good coverage for the more complex bottom navigation layout.

src/routes/docs-examples/components/bottom-navigation/Bottom.svelte (2)

3-3: LGTM - Icon migration to outline variants.

The transition from solid icons (HomeSolid, BookmarkSolid) to outline variants (HomeOutline, BookmarkOutline) aligns with the broader icon standardization across BottomNav examples in this PR.

Also applies to: 19-19, 23-23


6-6: Verify padding removal intent.

The p-6 padding class was removed from the container. Ensure this styling change is intentional and doesn't negatively affect the visual layout or spacing in the documentation example.

src/tests/banner/banner-closed.test.svelte (1)

1-7: LGTM - Clean test for closed state.

The test correctly validates the Banner's initial closed state using two-way binding with bind:open. The implementation is simple and effective.

src/tests/bottom-navigation/bottom-nav-item-active.test.svelte (1)

1-13: LGTM - Active state test.

The test correctly validates the active prop behavior on BottomNavItem with both true and false states, using the updated outline icon variants.

src/lib/banner/theme.ts (1)

23-27: LGTM - Semantic color tokens with backward compatibility.

The addition of semantic color variants (brand, danger, success, warning) follows modern design token practices while maintaining backward compatibility with legacy color names. The new tokens use appropriate semantic class names like bg-brand-softer and bg-danger-soft.

src/tests/bottom-navigation/bottom-nav-with-header.test.svelte (1)

1-26: LGTM - Comprehensive header interaction test.

The test validates the combination of BottomNavHeader and BottomNavItem with reactive state management. The onclick handlers correctly update the activeHeader state to control which header item is active.

src/tests/bottom-navigation/bottom-nav-item-button.test.svelte (1)

1-17: LGTM - Click handler test.

The test correctly validates onclick event handling on BottomNavItem using Svelte 5's $state rune. The data-testid attribute makes the assertion target explicit and testable.

src/tests/badge/badge.test.ts (2)

16-53: LGTM - Solid rendering test coverage.

The Basic Rendering test suite provides good coverage of badge variants including text content, size variants, color variants, and border styling.


55-64: LGTM - Good coverage of link behavior, accessibility, and events.

The test suite appropriately validates:

  • Link rendering with href attribute
  • ARIA labels for accessibility
  • Content readability
  • Close event dispatching

Also applies to: 92-105, 107-124

src/tests/banner/banner.test.ts (1)

14-41: LGTM - Comprehensive test coverage.

The test suite provides excellent coverage of:

  • Basic rendering and color variants
  • Open/closed state handling
  • Dismissable functionality with proper conditional rendering
  • Accessibility attributes (tabindex, aria-label)
  • Event handling and dispatch
  • Internal structure validation

Also applies to: 43-58, 77-97, 99-116, 118-126

src/routes/docs/components/banner.md (1)

47-47: LGTM - Documentation streamlining.

The text updates successfully reduce verbosity while preserving the essential information. The changes make the documentation more concise and easier to scan.

Also applies to: 57-57, 87-87, 99-99

src/lib/banner/Banner.svelte (1)

7-7: LGTM - Proper theme reactivity and API improvements.

The changes correctly implement reactive theme handling using $derived(getTheme("banner")) as per established patterns. The addition of closeBtnColor prop and consolidation of styling through the classes prop improves the API surface.

Also applies to: 22-22, 26-26, 29-29, 45-45, 51-51

src/routes/docs-examples/components/bottom-navigation/ActiveLink.svelte (1)

3-3: LGTM - Consistent icon and API migration.

The migration from Solid to Outline icon variants and the shift from activeClass to the classes prop align with the broader v2 refactoring. The changes are consistent with updates across other bottom navigation examples.

Also applies to: 11-11, 13-13, 16-16, 22-22

src/routes/docs-examples/components/bottom-navigation/Default.svelte (1)

3-3: LGTM - Icon migration and positioning update.

The icon migration from Solid to Outline variants is consistent across examples. Note that the position change from "absolute" to "fixed" alters the navigation behavior—fixed keeps the navigation visible during scrolling, which is the typical bottom navigation pattern.

Also applies to: 7-7, 9-9, 11-11, 14-14, 20-20

src/lib/bottom-navigation/BottomNavHeader.svelte (1)

5-5: LGTM - Proper reactive theme usage and simplified API.

The component correctly implements reactive theme handling with $derived(getTheme("bottomNavHeader")) and consolidates styling through the classes prop, removing deprecated outerClass and innerClass props.

Also applies to: 7-7, 9-9, 12-12, 17-18

src/routes/docs-examples/components/bottom-navigation/IconColor.svelte (1)

4-4: LGTM - Consistent icon variant migration.

The migration from Solid to Outline icon variants maintains the existing conditional styling logic while aligning with the icon standardization across all bottom navigation examples.

Also applies to: 15-15, 18-18, 24-24

src/lib/bottom-navigation/BottomNav.svelte (1)

4-4: LGTM - Correct reactive theme usage and clarified API responsibilities.

The component properly implements reactive theme handling with $derived(getTheme("bottomNav")). The removal of activeClass, innerClass, and outerClass from the context clarifies component responsibilities—the classes prop now affects only BottomNav's own elements, while child items manage their own styling. The inline comments effectively document this architectural decision.

Also applies to: 9-9, 11-11, 14-14, 16-16, 19-32, 39-39, 44-44, 59-60

src/tests/bottom-navigation/bottom-navigation.test.ts (1)

1-17: LGTM on test setup and cleanup pattern.

The test file is well-structured with proper imports, cleanup after each test, and organized describe blocks for each component.

src/routes/docs-examples/components/bottom-navigation/Application.svelte (2)

3-3: Icon migration to outline variants looks good.

The icon imports have been consistently updated from solid to outline variants (HomeOutline, WalletOutline, UserCircleOutline), aligning with the broader icon suite migration across bottom navigation components.


9-34: Component structure is well-organized.

The BottomNav configuration with classes={{ inner: "grid-cols-5" }} and the various appBtnPosition values correctly implement the application nav type layout. The tooltip integration and custom center button styling are properly implemented.

src/lib/bottom-navigation/BottomNavItem.svelte (3)

14-16: Theme derivation correctly uses $derived() pattern.

The getTheme("bottomNavItem") call is properly placed inside a $derived() expression, ensuring the component reacts to dynamic theme changes. This aligns with the established pattern in this repository. Based on learnings.


35-56: Backward compatibility for deprecated props is well-implemented.

The class resolution logic correctly prioritizes:

  1. Theme base (lowest priority)
  2. className/btnClass for base, classes.span/spanClass for span
  3. Active class applied on top when active

The nullish coalescing (??) properly falls back to deprecated props only when new props are undefined, maintaining backward compatibility while encouraging migration.


97-100: Documentation clearly marks deprecated props.

The prop documentation appropriately marks btnClass and spanClass as deprecated with clear migration paths to class and classes.span respectively.

src/lib/bottom-navigation/theme.ts (2)

10-51: Semantic token migration for bottomNav looks good.

The styling has been updated to use consistent semantic tokens (border-default, bg-neutral-primary-soft, text-body, etc.) across the base and navType variants. This aligns with the broader design system consolidation.


53-108: bottomNavItem variants properly use semantic tokens.

The hover states (bg-neutral-secondary-medium) and text colors (text-body, text-fg-brand) are consistently applied across nav types. The simplified appBtnPosition variants correctly retain only positional/shape classes.

src/lib/badge/Badge.svelte (2)

14-14: Color default updated to semantic "brand" token.

The default color change from "primary" to "brand" aligns with the broader migration to semantic color naming in this PR.


31-34: Theme derivation and badge styling correctly implemented.

The getTheme("badge") call is properly inside $derived(), and the badge variant correctly receives the href: !!href boolean to conditionally apply link-specific styling.

src/lib/alert/theme.ts (1)

6-137: Well-structured semantic color system with backward compatibility.

The refactored alert theme introduces new semantic color tokens (brand, danger, success, warning, dark, none) while preserving legacy colors for backward compatibility. The listContent and borderAccent variants with corresponding compoundVariants provide flexible styling options.

The previous rounded-base duplication issue has been correctly addressed by removing it from the base class.

src/lib/badge/theme.ts (2)

53-57: Empty variant objects are correctly used for compound variant matching.

The href: { true: {}, false: {} } pattern is appropriate for enabling compound variant matching without adding base classes. This is a valid tailwind-variants pattern.


262-266: Default color updated to semantic brand token.

The default color variant change from primary to brand aligns with the semantic color system migration. This is a breaking change for consumers relying on the implicit default, which should be documented in migration guides.

Ensure this default change is documented in migration/release notes for version 2.

src/lib/types.ts (5)

199-212: Well-structured classes object for Accordion customization.

The addition of a classes object with granular keys (button, contentWrapper, content, active, inactive) provides a clean API for per-part styling. The activeClass and inactiveClass props are correctly typed as ClassValue for flexibility.


223-235: AlertProps additions align with theme changes.

The closeColor, listContent, and borderAccent props correctly extend AlertProps to support the new theme variants defined in src/lib/alert/theme.ts. The typing via CloseButtonVariants["color"] ensures type-safe close button color selection.


249-261: BadgeProps correctly extends BadgeVariants with href omission.

The Omit<BadgeVariants, "href"> pattern avoids conflicts since href is re-declared as an optional HTMLAnchorAttributes["href"]. The closeBtnColor addition provides consistent theming for dismissable badges.


282-292: Good use of JSDoc deprecation notices for BottomNavItemProps.

The @deprecated annotations on btnClass and spanClass with migration guidance (Use class prop instead, Use classes.span instead) follow best practices for API evolution while maintaining backward compatibility.


349-360: AccordionContextType updated to pass classes through context.

The context now includes a classes object matching AccordionProps, enabling consistent class inheritance from parent Accordion to child items. This follows the library's pattern of context-based configuration.

src/lib/bottom-navigation/CHANGES-SUMMARY.md (1)

176-183: The temporary file src/lib/bottom-navigation/BottomNavItem-updated.svelte mentioned in the cleanup section no longer exists in the repository, so this is already resolved and requires no action.

src/tests/avatar/basic-avatar.test.svelte (1)

1-5: LGTM!

Clean test component that renders a basic Avatar without an image source, properly exercising the default SVG placeholder scenario.

src/tests/avatar/avatar-sizes.test.svelte (1)

1-9: LGTM!

Comprehensive test component exercising all five Avatar size variants with proper accessibility attributes.

src/tests/avatar/avatar-with-dot.test.svelte (1)

1-5: LGTM!

Clean test component validating Avatar with dot indicator using the semantic "success" color token, aligning with the updated color semantics in this PR.

src/tests/avatar/avatar-link.test.svelte (1)

1-5: LGTM!

Proper test component validating Avatar link behavior with href prop, src, and accessibility text.

src/tests/avatar/avatar-with-border.test.svelte (1)

1-5: LGTM!

Clean test component validating Avatar with border styling.

src/tests/avatar/avatar.test.ts (1)

1-14: LGTM!

Clean test setup with proper imports, cleanup, and well-organized test structure using describe blocks for logical grouping.

src/tests/avatar/avatar-squared.test.svelte (1)

5-5: The test does not require any configuration changes. The Flowbite-Svelte Avatar component does not have a "squared" corner style option. The component uses a cornerStyle prop that defaults to "circular", with only two valid values: "circular" and "rounded". The test file and test description are misleading—the test name suggests it validates squared corners, but no such styling exists in the Avatar API. Either rename the test and component file to reflect the default circular style it actually tests, or update it to use cornerStyle="rounded" if the intent is to test non-circular avatars.

Likely an incorrect or invalid review comment.

Comment on lines +75 to +89
test("dismisses badge when close button is clicked", async () => {
const user = userEvent.setup();
render(DismissableBadgeTest);

const closeButton = screen.getByRole("button", { name: /remove badge/i });
expect(screen.getByText("Dismissable")).toBeInTheDocument();

await user.click(closeButton);

// After clicking, the badge should be removed from DOM (due to badgeStatus = false)
// Wait for transition to complete
await new Promise((resolve) => setTimeout(resolve, 100));

// Badge might still exist during transition, but should be hidden or removed
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Incomplete assertion after async dismissal.

The test clicks the close button and waits for the transition (line 86), but doesn't verify the expected outcome. After the timeout, the test should assert that the badge is either removed from the DOM or has appropriate hidden/opacity classes.

🔎 Suggested assertion to add

Add after line 86:

       // After clicking, the badge should be removed from DOM (due to badgeStatus = false)
       // Wait for transition to complete
       await new Promise((resolve) => setTimeout(resolve, 100));
 
-      // Badge might still exist during transition, but should be hidden or removed
+      // Badge should be removed or hidden after transition
+      expect(screen.queryByText("Dismissable")).not.toBeInTheDocument();
📝 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
test("dismisses badge when close button is clicked", async () => {
const user = userEvent.setup();
render(DismissableBadgeTest);
const closeButton = screen.getByRole("button", { name: /remove badge/i });
expect(screen.getByText("Dismissable")).toBeInTheDocument();
await user.click(closeButton);
// After clicking, the badge should be removed from DOM (due to badgeStatus = false)
// Wait for transition to complete
await new Promise((resolve) => setTimeout(resolve, 100));
// Badge might still exist during transition, but should be hidden or removed
});
test("dismisses badge when close button is clicked", async () => {
const user = userEvent.setup();
render(DismissableBadgeTest);
const closeButton = screen.getByRole("button", { name: /remove badge/i });
expect(screen.getByText("Dismissable")).toBeInTheDocument();
await user.click(closeButton);
// After clicking, the badge should be removed from DOM (due to badgeStatus = false)
// Wait for transition to complete
await new Promise((resolve) => setTimeout(resolve, 100));
// Badge should be removed or hidden after transition
expect(screen.queryByText("Dismissable")).not.toBeInTheDocument();
});

Comment on lines +60 to +74
test("dismisses banner when close button is clicked", async () => {
const user = userEvent.setup();
render(BasicBannerTest);

const closeButton = screen.getByRole("button", { name: /remove banner/i });
expect(screen.getByText("This is a basic banner message.")).toBeInTheDocument();

await user.click(closeButton);

// After clicking, the banner should be removed from DOM
// Wait for transition to complete
await new Promise((resolve) => setTimeout(resolve, 100));

// Due to transitions, banner might still exist in DOM but be hidden
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Incomplete assertion after async dismissal.

Similar to the badge test, this dismissal test clicks the close button and waits for transition completion (line 71) but doesn't verify the expected outcome. The test should assert that the banner is removed from the DOM or properly hidden after dismissal.

🔎 Suggested assertion to add

Add after line 71:

       // After clicking, the banner should be removed from DOM
       // Wait for transition to complete
       await new Promise((resolve) => setTimeout(resolve, 100));
 
-      // Due to transitions, banner might still exist in DOM but be hidden
+      // Banner should be removed or hidden after transition
+      expect(screen.queryByText("This is a basic banner message.")).not.toBeInTheDocument();
📝 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
test("dismisses banner when close button is clicked", async () => {
const user = userEvent.setup();
render(BasicBannerTest);
const closeButton = screen.getByRole("button", { name: /remove banner/i });
expect(screen.getByText("This is a basic banner message.")).toBeInTheDocument();
await user.click(closeButton);
// After clicking, the banner should be removed from DOM
// Wait for transition to complete
await new Promise((resolve) => setTimeout(resolve, 100));
// Due to transitions, banner might still exist in DOM but be hidden
});
test("dismisses banner when close button is clicked", async () => {
const user = userEvent.setup();
render(BasicBannerTest);
const closeButton = screen.getByRole("button", { name: /remove banner/i });
expect(screen.getByText("This is a basic banner message.")).toBeInTheDocument();
await user.click(closeButton);
// After clicking, the banner should be removed from DOM
// Wait for transition to complete
await new Promise((resolve) => setTimeout(resolve, 100));
// Banner should be removed or hidden after transition
expect(screen.queryByText("This is a basic banner message.")).not.toBeInTheDocument();
});
🤖 Prompt for AI Agents
In src/tests/banner/banner.test.ts around lines 60 to 74, the test clicks the
banner close button and waits for the transition but doesn't assert the outcome;
after the existing await that waits for the transition, add an assertion that
the banner text is no longer present (e.g. use screen.queryByText("This is a
basic banner message.") and expect it toBeNull or
expect(...).not.toBeInTheDocument()); to make it robust wrap the assertion in a
waitFor so it retries until the element is removed.

Comment on lines 105 to 111
```
src/tests/[component]/
├── [component].test.ts # Main test file with assertions
├── basic-[component].test.svelte # Helper: basic usage
├── [variant1].test.svelte # Helper: specific variant
└── [variant2].test.svelte # Helper: another variant
```
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 20, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add language identifiers to fenced code blocks.

Markdown linting requires language specifiers on fenced code blocks for consistency. Three code blocks need updates:

  1. Lines 105-111 (directory structure): Add text as language
  2. Lines 164-173 (helper component example): Should specify svelte
  3. Lines 176-188 (test file example): Should specify typescript
🔎 Proposed fixes

Fix 1: Lines 105-111

-```
+```text
 src/tests/[component]/
 ├── [component].test.ts           # Main test file with assertions
 ├── basic-[component].test.svelte # Helper: basic usage
 ├── [variant1].test.svelte        # Helper: specific variant
 └── [variant2].test.svelte        # Helper: another variant
-```
+```

Fix 2: Lines 164-173

-```svelte
+```svelte
 <script lang="ts">
   import Avatar from "$lib/avatar/Avatar.svelte";
   
   let clicked = $state(false);
   const handleClick = () => { clicked = true; };
 </script>
 
 <Avatar onclick={handleClick} alt="Clickable avatar" />
-```
+```

Fix 3: Lines 176-188

-```typescript
+```typescript
 import AvatarClickableTest from "./avatar-clickable.test.svelte";
 
 test("handles click events", async () => {
   const user = userEvent.setup();
   render(AvatarClickableTest);
   
   const button = screen.getByRole("button");
   await user.click(button);
   
   // Add your assertions
 });
-```
+```

Also applies to: 164-173, 176-188

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

105-105: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In src/tests/TEST-DOCUMENTATION.md around lines 105-111, 164-173, and 176-188,
three fenced code blocks lack language identifiers; update the opening fences to
include the appropriate languages so markdown linting passes: change the
directory-structure block (lines 105-111) to start with ```text, the helper
component example (lines 164-173) to start with ```svelte, and the test file
example (lines 176-188) to start with ```typescript, ensuring each block keeps
its existing content and closing ``` fence.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

N/A since this file will be removed.

Copy link
Contributor

Choose a reason for hiding this comment

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

@shinokada, understood! Since the file will be removed, the linting issues are not applicable. Thanks for clarifying.


🧠 Learnings used
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/lib/carousel/Thumbnails.svelte (1)

47-60: Stale documentation: imgClass prop reference should be removed.

The doc comment at line 57 lists @prop imgClass but this prop was removed in favor of the classes pattern. Update the documentation to reflect the current prop surface.

🔎 Proposed fix
 ## Props
 @prop children
 @prop images = []
 @prop index = $bindable()
 @prop ariaLabel = "Click to view image"
-@prop imgClass
 @prop throttleDelay = 650
 @prop class: className
+@prop classes
 -->
src/lib/card/Card.svelte (1)

55-71: Stale documentation: imgClass prop reference should be removed, hoverable and imgAlt should be added.

The doc comment lists @prop imgClass but this prop was removed. Additionally, the new hoverable and imgAlt props should be documented.

🔎 Proposed fix
 ## Props
 @prop children
+@prop hoverable = false
 @prop horizontal = false
 @prop shadow = "md"
 @prop reverse = false
 @prop img
+@prop imgAlt
 @prop size = "sm"
 @prop class: className
 @prop classes
-@prop imgClass
 @prop ...restProps
 -->
🧹 Nitpick comments (6)
src/lib/buttons/theme.ts (1)

148-148: Minor: Extra whitespace in focus ring class.

There's a double space before focus:ring-pink-300.

🔎 Proposed fix
-        base: "text-white bg-pink-700 enabled:hover:bg-pink-800 dark:bg-pink-600 dark:enabled:hover:bg-pink-700  focus:ring-pink-300 dark:focus:ring-pink-800",
+        base: "text-white bg-pink-700 enabled:hover:bg-pink-800 dark:bg-pink-600 dark:enabled:hover:bg-pink-700 focus:ring-pink-300 dark:focus:ring-pink-800",
package.json (1)

28-28: Clarify the purpose and usage of the test:unit-t script.

The -t flag in vitest filters tests by name pattern, but this script doesn't provide a pattern. Users would need to supply it at runtime (e.g., npm run test:unit-t "pattern"). Consider adding documentation or an example in the README, or providing a more descriptive script name that indicates pattern filtering is required.

src/tests/carousel/Controls.test.ts (4)

13-19: Consider using a more precise assertion for button count.

The current test uses toBeGreaterThanOrEqual(3), which would pass even with unexpected extra buttons. If the expected count is exactly 3 buttons, use toBe(3) for a stronger assertion.

🔎 Proposed refinement
       const buttons = screen.getAllByRole("button");
-      // Should have carousel button + 2 control buttons
-      expect(buttons.length).toBeGreaterThanOrEqual(3);
+      // Should have exactly: carousel button + 2 control buttons
+      expect(buttons).toHaveLength(3);

45-46: Use more descriptive assertions for button presence.

Replace toBeDefined() with toBeTruthy() or add toBeInTheDocument() for clearer intent when verifying element presence.

🔎 Proposed refinement
-      expect(leftButton).toBeDefined();
-      expect(rightButton).toBeDefined();
+      expect(leftButton).toBeTruthy();
+      expect(rightButton).toBeTruthy();

51-64: Enhance interaction test to verify actual carousel behavior.

The test currently only confirms that clicking control buttons doesn't throw errors and buttons remain in the DOM. Consider verifying the actual effect of the clicks, such as checking that the carousel advances to the next/previous slide or that slide indicators update accordingly.


67-80: Consider expanding accessibility test coverage.

The current accessibility tests only verify that controls are rendered as BUTTON elements. Consider adding tests for:

  • Appropriate aria-label or aria-labelledby attributes for screen readers
  • Keyboard navigation (Tab, Enter, Space key interactions)
  • Focus management when controls are activated
  • aria-controls attribute linking to carousel container
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 439a579 and 56a33a3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (18)
  • TEST_IMPROVEMENTS_SUMMARY.md (1 hunks)
  • package.json (5 hunks)
  • src/lib/buttons/theme.ts (5 hunks)
  • src/lib/card/Card.svelte (2 hunks)
  • src/lib/carousel/Thumbnails.svelte (2 hunks)
  • src/lib/indicator/theme.ts (2 hunks)
  • src/lib/types.ts (10 hunks)
  • src/routes/builder/indicators/+page.svelte (3 hunks)
  • src/tests/card/card-custom-image-class.test.svelte (1 hunks)
  • src/tests/card/card-horizontal-reverse.test.svelte (1 hunks)
  • src/tests/card/card-horizontal.test.svelte (1 hunks)
  • src/tests/card/card-image-error.test.svelte (1 hunks)
  • src/tests/card/card-reverse.test.svelte (1 hunks)
  • src/tests/card/card-with-image.test.svelte (1 hunks)
  • src/tests/card/card.test.ts (1 hunks)
  • src/tests/carousel/Carousel.test.ts (1 hunks)
  • src/tests/carousel/CarouselIndicators.test.ts (1 hunks)
  • src/tests/carousel/Controls.test.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
  • src/tests/carousel/Carousel.test.ts
  • src/tests/card/card-image-error.test.svelte
  • src/tests/carousel/CarouselIndicators.test.ts
  • src/tests/card/card-with-image.test.svelte
  • src/tests/card/card.test.ts
  • src/tests/card/card-horizontal.test.svelte
  • src/routes/builder/indicators/+page.svelte
  • src/tests/card/card-custom-image-class.test.svelte
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/lib/buttons/theme.ts
  • src/tests/carousel/Controls.test.ts
  • src/tests/card/card-reverse.test.svelte
  • src/lib/carousel/Thumbnails.svelte
  • src/lib/indicator/theme.ts
  • src/lib/card/Card.svelte
  • src/tests/card/card-horizontal-reverse.test.svelte
  • src/lib/types.ts
🧠 Learnings (11)
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/lib/buttons/theme.ts
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.

Applied to files:

  • src/lib/buttons/theme.ts
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.

Applied to files:

  • src/lib/buttons/theme.ts
📚 Learning: 2025-03-20T11:11:53.952Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.952Z
Learning: In the Flowbite Svelte library, when implementing components with validation states, the 'inputInvalid' property should be explicitly defined and passed to the Wrapper component. When inputInvalid=true, the color should be set to "red" to ensure the ring/border styling is applied correctly.

Applied to files:

  • src/lib/buttons/theme.ts
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles, ensure both the container (with focus-within) and the inner input element (with direct focus) have dynamic styling based on the validation state. The input element needs its own focus styles that change to red when inputInvalid=true.

Applied to files:

  • src/lib/buttons/theme.ts
📚 Learning: 2025-03-20T11:11:53.953Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.953Z
Learning: In the Flowbite Svelte library's MultiInput component, the 'inputInvalid' property should be exported and passed to the Wrapper component to properly style the component's ring with red color when validation fails, similar to how the Input component handles validation states.

Applied to files:

  • src/lib/buttons/theme.ts
📚 Learning: 2024-11-22T08:37:27.996Z
Learnt from: mrh1997
Repo: themesberg/flowbite-svelte PR: 1442
File: src/lib/utils/Popper.svelte:144-145
Timestamp: 2024-11-22T08:37:27.996Z
Learning: In `src/lib/utils/Popper.svelte`, inconsistencies in event handling (e.g., using both `mouseenter`/`mouseleave` and `pointerenter`/`pointerleave`) may be intentional to minimize modifications and reduce the risk of new problems.

Applied to files:

  • src/lib/buttons/theme.ts
📚 Learning: 2025-08-31T12:56:05.074Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1745
File: src/lib/types.ts:677-686
Timestamp: 2025-08-31T12:56:05.074Z
Learning: HTMLInputAttributes includes a `group` property that can be used for grouping form controls like checkboxes and radio buttons, so interfaces extending HTMLInputAttributes don't need to explicitly declare `group` unless they want to override its type.

Applied to files:

  • src/lib/buttons/theme.ts
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

Applied to files:

  • package.json
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation

Applied to files:

  • package.json
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/tests/card/card-reverse.test.svelte
  • src/lib/carousel/Thumbnails.svelte
  • src/lib/card/Card.svelte
  • src/tests/card/card-horizontal-reverse.test.svelte
🔇 Additional comments (16)
src/lib/carousel/Thumbnails.svelte (1)

8-11: LGTM!

The props destructuring and derived values are well-structured. The $derived(getTheme("thumbnails")) correctly follows the reactive theme pattern per learnings. Both render paths now consistently apply theme classes.

src/lib/buttons/theme.ts (2)

16-55: Well-organized semantic color system.

The new semantic color tokens (brand, alternative, gray, success, danger, warning, transparent, dark) are cleanly defined with consistent patterns for base, outline, and shadow slots. Focus ring styling is properly applied via the base slot definition.


188-226: LGTM!

The gradientButton theme is well-structured with proper slot-based styling for outline wrappers and consistent compound variants for shadow effects and grouped button styling.

src/lib/types.ts (4)

199-212: LGTM!

The AccordionProps interface is well-structured with the new classes object providing granular styling control. Using ClassValue types improves flexibility. The maintainer confirmed these breaking changes will be communicated in the v2 announcement.


287-292: Good use of JSDoc deprecation notices.

The deprecation comments on btnClass and spanClass clearly guide users toward the new patterns. This is helpful for migration.


338-342: LGTM!

The GradientButtonProps interface correctly extends GradientButtonVariants and HTMLButtonOrAnchorAttributes, providing a clean public API.


483-494: LGTM!

The carousel-related props (IndicatorsProps, ControlButtonProps) properly extend their respective variant types, ensuring type safety and consistency with the theme system.

src/lib/card/Card.svelte (2)

7-22: LGTM!

The props destructuring and derived values are well-structured. The hoverable prop integration and $derived(getTheme("card")) correctly follow the reactive theme pattern per learnings.


26-38: Good accessibility practice with alt text fallback.

The imgAlt || "Card image" fallback ensures images always have descriptive text. The error handler gracefully hides broken images.

src/lib/indicator/theme.ts (2)

115-122: LGTM!

The default color change from "primary" to "brand" aligns with the semantic color system migration. This is a consistent choice for the new design token approach.


9-17: > Likely an incorrect or invalid review comment.

src/tests/card/card-horizontal-reverse.test.svelte (1)

1-9: LGTM!

This test correctly exercises the horizontal + reverse layout combination using the centralized test fixture. The content structure with heading and paragraph provides good coverage for slot projection.

src/tests/card/card-reverse.test.svelte (1)

1-9: LGTM!

This test correctly exercises the reverse layout (image at bottom) using the centralized test fixture. Good test coverage for the Card component's layout variants.

TEST_IMPROVEMENTS_SUMMARY.md (1)

1-193: Consider whether this documentation file should remain in the repository long-term.

This is a well-written and comprehensive summary of test improvements. However, as a documentation artifact describing other changes, it raises a question: is this intended as permanent repo documentation, or is it a temporary PR artifact that should be removed after merge?

Rationale:

  • The detailed explanations and before/after examples are helpful for PR review, but they duplicate information that should live in the actual code files (docstrings, comments, README.md).
  • Once this PR is merged, maintainers reviewing the test suite later won't benefit as much from a separate summary; they'll look at the actual test code.
  • This content would be better preserved in the PR description/comments rather than committed to the repository.

Suggestion:
If this file is meant to be permanent, consider:

  1. Moving relevant best-practices guidance to src/tests/fixtures/README.md (already referenced at line 146).
  2. Keeping only essential sections (like the bug fix explanation) as code comments.
  3. Removing the file from the final commit and preserving it in the PR discussion instead.

If this is a temporary review aid, it can be safely removed before merge.

package.json (2)

57-57: Dependency updates look good.

The patch version updates for @testing-library/svelte and svelte-check are safe and should provide bug fixes and improvements.

Also applies to: 91-91


159-159: Address Flowbite v4.0 breaking changes before upgrading to 4.0.1.

Flowbite v4.0 introduced significant breaking changes: CSS variables-based theming (replacing utility classes), Tailwind v4 compatibility requirements, component HTML/CSS redesigns, and JavaScript API changes for programmatic usage. Verify that:

  • Component markup and classes have been updated to match v4 structure
  • Tailwind configuration has been migrated to v4 style if applicable
  • Any programmatic Flowbite object instantiation has been updated to new APIs
  • CSS variable-based theming is properly configured

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (7)
src/lib/carousel/Thumbnails.svelte (1)

10-10: Optional: simplify redundant $derived() wrapper.

Since classes is already a reactive prop in Svelte 5, wrapping it in $derived() without any transformation is redundant. You can simplify to:

const styling = classes;

However, if you plan to add transformations later, keeping $derived() is fine.

src/lib/card/Card.svelte (1)

9-9: Consider whether this derivation is necessary.

The $derived(classes) wrapper creates a reactive reference to the already-reactive classes prop. Unless this pattern is used for consistency across components or planned future logic, you could use classes directly.

🔎 Simplified alternative (if no pattern consistency needed)
-const styling = $derived(classes);
+const styling = classes;

Then reference styling?.image as-is on line 28.

scripts/sync-plugin-utilities-export.sh (2)

6-8: Fragile sed range pattern may delete too much.

The deletion pattern /^[[:space:]]*},/ matches any line that is just }, with optional whitespace—not specifically the closing brace of the "./plugin-utilities" block. If package.json has other export entries with similar structure, this could delete beyond the intended block.

Consider a more targeted approach using jq for reliable JSON manipulation:

🔎 Safer alternative using jq
# Remove existing and add new entry atomically
jq 'del(.exports["./plugin-utilities"]) | .exports["./plugin-utilities"] = {
  "types": "./dist/plugin-utilities.d.ts",
  "import": "./dist/plugin-utilities.js",
  "default": "./dist/plugin-utilities.js"
}' "$FILE" > tmp.$$.json && mv tmp.$$.json "$FILE"

11-24: Consider extracting the export block to reduce duplication.

The export JSON block is duplicated for macOS and GNU sed variants. If you stick with sed, you could define the block in a variable to reduce maintenance burden.

src/tests/button/button.test.ts (1)

156-165: Disabled button click test could be more robust.

The test verifies the button is disabled but doesn't confirm the click handler wasn't invoked. Consider using testState (like in the click test above) to verify no handler was called:

🔎 Proposed enhancement
     test("disabled button cannot be clicked", async () => {
       const user = userEvent.setup();
+      // Use a test component with click handler and testState
+      testState.clickCount = 0;
       render(DisabledButtonTest);
       const button = screen.getByRole("button");

       expect(button).toBeDisabled();
       await user.click(button);
-      // Button should remain disabled and not trigger click
-      expect(button).toBeDisabled();
+      // Verify click handler was not invoked
+      expect(testState.clickCount).toBe(0);
     });

This requires DisabledButtonTest to wire up testState like ClickButtonTest does.

src/routes/docs-examples/components/clipboard/Input.svelte (1)

11-11: Inconsistent border radius: rounded-sm vs rounded-base.

This uses rounded-sm while other clipboard components migrated to rounded-base (e.g., Source.svelte line 19, InputAddon.svelte line 44). Verify whether:

  1. rounded-sm is intentional for embedded clipboard buttons, or
  2. This should align with the broader rounded-base migration
🔎 If standardizing on rounded-base
-      <Clipboard bind:value embedded color="alternative" class="rounded-sm">
+      <Clipboard bind:value embedded color="alternative" class="rounded-base">
src/lib/plugin-utilities.ts (1)

11-295: Consider programmatic generation for maintainability.

The 280+ line color utilities map follows a highly repetitive pattern. Generating these utilities programmatically from a data structure would:

  • Reduce maintenance burden when adding/removing colors
  • Prevent copy-paste errors
  • Make the code more concise and readable
💡 Example approach
const colorGroups = {
  brand: ['softer', 'soft', '', 'medium', 'strong'],
  success: ['soft', '', 'medium', 'strong'],
  // ... other groups
};

const utilities: Record<string, any> = {};

Object.entries(colorGroups).forEach(([color, variants]) => {
  variants.forEach(variant => {
    const suffix = variant ? `-${variant}` : '';
    const varName = `--color-${color}${suffix}`;
    const className = `.text-${color}${suffix}`;
    utilities[className] = { color: `var(${varName})` };
    // ... repeat for bg, border, ring
  });
});
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 56a33a3 and 16b083a.

📒 Files selected for processing (23)
  • package.json (5 hunks)
  • scripts/sync-plugin-utilities-export.sh (1 hunks)
  • src/app.css (3 hunks)
  • src/lib/buttons/Button.svelte (2 hunks)
  • src/lib/buttons/theme.ts (5 hunks)
  • src/lib/card/Card.svelte (3 hunks)
  • src/lib/carousel/Thumbnails.svelte (2 hunks)
  • src/lib/forms/input-addon/InputAddon.svelte (1 hunks)
  • src/lib/forms/input-field/theme.ts (3 hunks)
  • src/lib/index.ts (1 hunks)
  • src/lib/plugin-utilities.d.ts (1 hunks)
  • src/lib/plugin-utilities.ts (1 hunks)
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte (2 hunks)
  • src/routes/docs-examples/components/clipboard/Contact.svelte (2 hunks)
  • src/routes/docs-examples/components/clipboard/CopyButton.svelte (2 hunks)
  • src/routes/docs-examples/components/clipboard/Default.svelte (1 hunks)
  • src/routes/docs-examples/components/clipboard/Input.svelte (1 hunks)
  • src/routes/docs-examples/components/clipboard/InputGroup.svelte (1 hunks)
  • src/routes/docs-examples/components/clipboard/Modal.svelte (2 hunks)
  • src/routes/docs-examples/components/clipboard/Source.svelte (3 hunks)
  • src/routes/docs-examples/components/clipboard/Textarea.svelte (2 hunks)
  • src/routes/docs-examples/components/clipboard/Url.svelte (1 hunks)
  • src/tests/button/button.test.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/routes/docs-examples/components/clipboard/Modal.svelte
  • src/lib/forms/input-addon/InputAddon.svelte
  • src/lib/plugin-utilities.d.ts
  • src/routes/docs-examples/components/clipboard/InputGroup.svelte
  • src/routes/docs-examples/components/clipboard/CopyButton.svelte
  • src/lib/buttons/Button.svelte
  • src/routes/docs-examples/components/clipboard/Contact.svelte
  • src/routes/docs-examples/components/clipboard/Default.svelte
  • src/lib/forms/input-field/theme.ts
  • src/tests/button/button.test.ts
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte
  • src/lib/carousel/Thumbnails.svelte
  • src/lib/card/Card.svelte
  • src/routes/docs-examples/components/clipboard/Url.svelte
  • src/lib/buttons/theme.ts
  • src/lib/index.ts
  • src/routes/docs-examples/components/clipboard/Textarea.svelte
  • src/routes/docs-examples/components/clipboard/Input.svelte
  • src/lib/plugin-utilities.ts
  • src/routes/docs-examples/components/clipboard/Source.svelte
🧠 Learnings (20)
📓 Common learnings
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

Applied to files:

  • src/routes/docs-examples/components/clipboard/Modal.svelte
  • src/routes/docs-examples/components/clipboard/CopyButton.svelte
  • src/routes/docs-examples/components/clipboard/Contact.svelte
  • src/routes/docs-examples/components/clipboard/Default.svelte
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte
  • src/routes/docs-examples/components/clipboard/Url.svelte
  • src/lib/index.ts
  • src/app.css
  • src/routes/docs-examples/components/clipboard/Textarea.svelte
  • src/routes/docs-examples/components/clipboard/Input.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Use getComponentList tool to discover available Flowbite-Svelte components or help users explore component options

Applied to files:

  • src/routes/docs-examples/components/clipboard/Modal.svelte
  • src/routes/docs-examples/components/clipboard/CopyButton.svelte
  • src/routes/docs-examples/components/clipboard/Default.svelte
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte
  • src/routes/docs-examples/components/clipboard/Input.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation

Applied to files:

  • src/routes/docs-examples/components/clipboard/Modal.svelte
  • src/routes/docs-examples/components/clipboard/CopyButton.svelte
  • src/routes/docs-examples/components/clipboard/Contact.svelte
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte
  • src/routes/docs-examples/components/clipboard/Url.svelte
  • src/app.css
  • src/routes/docs-examples/components/clipboard/Input.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/docs-examples/components/clipboard/Modal.svelte
  • src/routes/docs-examples/components/clipboard/Contact.svelte
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte
  • src/routes/docs-examples/components/clipboard/Input.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/docs-examples/components/clipboard/Modal.svelte
  • src/routes/docs-examples/components/clipboard/CopyButton.svelte
  • src/routes/docs-examples/components/clipboard/Contact.svelte
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte
  • src/app.css
  • src/routes/docs-examples/components/clipboard/Textarea.svelte
  • src/routes/docs-examples/components/clipboard/Input.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use getComponentList tool to discover available Flowbite-Svelte components with their categories or to help users explore component options

Applied to files:

  • src/routes/docs-examples/components/clipboard/Modal.svelte
  • src/routes/docs-examples/components/clipboard/CopyButton.svelte
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte
📚 Learning: 2025-03-20T11:11:53.953Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.953Z
Learning: In the Flowbite Svelte library's MultiInput component, the 'inputInvalid' property should be exported and passed to the Wrapper component to properly style the component's ring with red color when validation fails, similar to how the Input component handles validation states.

Applied to files:

  • src/routes/docs-examples/components/clipboard/Modal.svelte
  • src/routes/docs-examples/components/clipboard/InputGroup.svelte
  • src/routes/docs-examples/components/clipboard/CopyButton.svelte
  • src/routes/docs-examples/components/clipboard/Default.svelte
  • src/lib/forms/input-field/theme.ts
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte
  • src/lib/buttons/theme.ts
  • src/routes/docs-examples/components/clipboard/Input.svelte
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles, ensure both the container (with focus-within) and the inner input element (with direct focus) have dynamic styling based on the validation state. The input element needs its own focus styles that change to red when inputInvalid=true.

Applied to files:

  • src/routes/docs-examples/components/clipboard/Modal.svelte
  • src/routes/docs-examples/components/clipboard/InputGroup.svelte
  • src/routes/docs-examples/components/clipboard/CopyButton.svelte
  • src/routes/docs-examples/components/clipboard/Default.svelte
  • src/lib/forms/input-field/theme.ts
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte
  • src/lib/buttons/theme.ts
  • src/routes/docs-examples/components/clipboard/Input.svelte
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/routes/docs-examples/components/clipboard/Modal.svelte
  • src/lib/forms/input-addon/InputAddon.svelte
  • src/routes/docs-examples/components/clipboard/InputGroup.svelte
  • src/routes/docs-examples/components/clipboard/CopyButton.svelte
  • src/lib/buttons/Button.svelte
  • src/routes/docs-examples/components/clipboard/Contact.svelte
  • src/routes/docs-examples/components/clipboard/Default.svelte
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte
  • src/lib/carousel/Thumbnails.svelte
  • src/lib/card/Card.svelte
  • src/routes/docs-examples/components/clipboard/Url.svelte
  • src/routes/docs-examples/components/clipboard/Textarea.svelte
  • src/routes/docs-examples/components/clipboard/Input.svelte
  • src/routes/docs-examples/components/clipboard/Source.svelte
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.

Applied to files:

  • src/routes/docs-examples/components/clipboard/InputGroup.svelte
  • src/lib/forms/input-field/theme.ts
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte
  • src/lib/buttons/theme.ts
  • src/routes/docs-examples/components/clipboard/Input.svelte
📚 Learning: 2025-03-20T11:11:53.952Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.952Z
Learning: In the Flowbite Svelte library, when implementing components with validation states, the 'inputInvalid' property should be explicitly defined and passed to the Wrapper component. When inputInvalid=true, the color should be set to "red" to ensure the ring/border styling is applied correctly.

Applied to files:

  • src/routes/docs-examples/components/clipboard/InputGroup.svelte
  • src/lib/forms/input-field/theme.ts
  • src/routes/docs-examples/components/clipboard/ApiKeys.svelte
  • src/lib/buttons/theme.ts
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.

Applied to files:

  • src/lib/buttons/Button.svelte
  • src/lib/forms/input-field/theme.ts
  • src/lib/buttons/theme.ts
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/lib/forms/input-field/theme.ts
  • src/lib/buttons/theme.ts
  • src/app.css
  • src/routes/docs-examples/components/clipboard/Input.svelte
📚 Learning: 2024-11-22T08:37:27.996Z
Learnt from: mrh1997
Repo: themesberg/flowbite-svelte PR: 1442
File: src/lib/utils/Popper.svelte:144-145
Timestamp: 2024-11-22T08:37:27.996Z
Learning: In `src/lib/utils/Popper.svelte`, inconsistencies in event handling (e.g., using both `mouseenter`/`mouseleave` and `pointerenter`/`pointerleave`) may be intentional to minimize modifications and reduce the risk of new problems.

Applied to files:

  • src/lib/buttons/theme.ts
📚 Learning: 2025-08-31T12:56:05.074Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1745
File: src/lib/types.ts:677-686
Timestamp: 2025-08-31T12:56:05.074Z
Learning: HTMLInputAttributes includes a `group` property that can be used for grouping form controls like checkboxes and radio buttons, so interfaces extending HTMLInputAttributes don't need to explicitly declare `group` unless they want to override its type.

Applied to files:

  • src/lib/buttons/theme.ts
📚 Learning: 2025-12-16T13:21:28.743Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:28.743Z
Learning: In flowbite-svelte, when using ThemeProvider with reactive themes, `getTheme("componentName")` calls must be placed inside `$derived()` expressions (not at module scope) to ensure components react to dynamic theme changes. This pattern is intentional for reactive theming support.

Applied to files:

  • src/lib/index.ts
  • src/app.css
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use searchDocs tool for full-text search across Flowbite-Svelte documentation when looking for specific information that might span multiple components or when users ask about features or patterns

Applied to files:

  • src/app.css
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Use searchDocs tool when finding specific information that might span multiple Flowbite-Svelte components or when exploring features and patterns across the documentation

Applied to files:

  • src/app.css
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use the Flowbite-Svelte MCP server to access comprehensive component documentation

Applied to files:

  • src/app.css
🧬 Code graph analysis (2)
src/tests/button/button.test.ts (1)
src/lib/buttons/theme.ts (1)
  • button (7-186)
src/lib/buttons/theme.ts (1)
src/lib/buttons/index.ts (2)
  • button (3-3)
  • gradientButton (3-3)
🔇 Additional comments (31)
src/lib/carousel/Thumbnails.svelte (4)

8-8: Props updated correctly for unified classes pattern.

The addition of the classes prop aligns with the broader refactor to consolidate class props into a unified pattern across components.


11-11: Correct reactive theme pattern!

Using $derived(getTheme("thumbnails")) ensures the component reacts to dynamic theme changes from ThemeProvider. This follows the established best practice for this codebase.


34-34: Slot-based styling refactor applied correctly.

The container class assembly has been properly refactored to use the new slot-based styling pattern, composing base classes, theme overrides, and user classes in the correct order.


39-41: Past inconsistency resolved – both render paths now apply theme classes consistently.

Both the custom render path (line 39) and default render path (line 41) now consistently apply both theme?.img and styling?.img. This addresses the issue flagged in the previous review.

src/lib/forms/input-field/theme.ts (3)

27-27: Verify custom neutral/default semantic tokens.

The default color variant uses bg-neutral-secondary-medium and border-default-medium, which are custom tokens. Confirm these are defined in your Tailwind configuration alongside the other semantic tokens.

The verification script from the previous comment will also check for these tokens.


10-10: No action required. The custom semantic tokens (text-heading, text-body, ring-brand, border-brand, shadow-xs, rounded-base, rounded-s-base, rounded-e-base) are all properly defined in the Tailwind configuration—either via the custom plugin (src/lib/plugin-utilities.ts) or the imported Flowbite theme. Tests confirm these utilities work correctly.


114-117: Verify that rounded-base radius utilities are properly defined in your theme configuration.

The grouped variant and other components use rounded-base, rounded-s-base, and rounded-e-base, which are non-standard Tailwind utilities. These must be defined in your Flowbite theme configuration or as custom utilities; otherwise, elements will lose their border radius styling. Confirm these utilities are generated correctly in your compiled CSS output.

src/lib/card/Card.svelte (3)

3-3: LGTM: Correct theme usage for reactivity.

The getTheme("card") call is properly wrapped in $derived(), ensuring the component reacts to dynamic theme changes when using ThemeProvider. Based on learnings, this is the correct pattern for theme-derived values in Flowbite-Svelte.

Also applies to: 11-11


62-67: LGTM: Documentation aligned with prop changes.

The component documentation correctly reflects the updated prop surface, including the new hoverable and imgAlt props.


7-7: Breaking changes in Card component props are properly implemented.

The removal of color and imgClass props from CardProps represents intentional breaking API changes that are complete. The new hoverable prop correctly integrates with the theme function at line 19 via the card() utility, and imgAlt is properly implemented at line 7 for image accessibility. Image styling now uses styling?.image from the classes prop instead of imgClass. No remaining usage of removed props exists in the codebase.

Also applies to: 19-19, 28-28

src/lib/buttons/Button.svelte (1)

18-31: Default color migration to "brand" looks correct.

The default color change from "primary" to "brand" (line 18) and the corresponding fallback logic (line 31) align with the PR's semantic color migration. The $derived placement for theme access (line 28) follows the reactive theme pattern correctly.

src/tests/button/button.test.ts (1)

23-167: Solid test restructuring and coverage expansion.

The migration to a nested describe structure with focused test groups (Basic Rendering, Props, Size Variants, Color Variants, Interactions) improves readability and maintainability. The use of testState for click verification and userEvent for interactions follows testing best practices.

src/lib/buttons/theme.ts (4)

3-5: Type rename and comment update look good.

The typo fix from GradientButtonVariantes to GradientButtonVariants (line 5) is addressed, and the explanatory comment (line 3) clarifies the design decision about variants not needing to extend Classes.


16-55: Semantic color system is well-structured.

The new semantic colors (brand, alternative, gray, success, danger, warning, transparent, dark) provide a consistent theming approach with proper base/outline/shadow slot definitions. The use of semantic tokens (bg-brand, text-fg-brand, focus:ring-brand-medium) enables flexible theming.


188-216: Gradient button uses Tailwind v4 gradient syntax.

The bg-linear-to-r and bg-linear-to-br classes (lines 195-209) are Tailwind CSS v4 syntax replacing the v3 bg-gradient-to-r/bg-gradient-to-br utilities. Ensure this is intentional and consistent with your Tailwind configuration.


165-176: focus:outline-hidden is the correct Tailwind v4 syntax and appropriate for this use case.

Line 167 correctly uses focus:outline-hidden, which is the proper Tailwind v4 utility for hiding the default outline while preserving it in forced colors mode for accessibility. In v4, outline-hidden (renamed from v3's outline-none) maintains focus visibility in high-contrast modes, whereas the new outline-none utility completely removes the outline. Ensure your project uses custom focus styling alongside this utility, as recommended by Tailwind for accessibility.

src/routes/docs-examples/components/clipboard/Default.svelte (1)

9-15: Grid layout restructuring improves organization.

The 8-column grid with col-span-6 for the Input and w-24 for the Clipboard provides a clean, responsive layout. The sr-only Label is a good accessibility addition (once the id association is fixed).

src/routes/docs-examples/components/clipboard/CopyButton.svelte (1)

3-3: LGTM: Icon update aligns with design system refresh.

The migration from ClipboardCleanSolid to ClipboardCleanOutline with explicit h-4 w-4 sizing is consistent across all clipboard examples in this PR, improving visual consistency.

Also applies to: 14-14, 16-16

src/routes/docs-examples/components/clipboard/Modal.svelte (1)

3-3: LGTM: Consistent icon update.

Icon changes match the pattern established across other clipboard components.

Also applies to: 19-19

src/routes/docs-examples/components/clipboard/Contact.svelte (1)

3-3: LGTM: Consistent with clipboard UI standardization.

Icon update and color="alternative" addition align with the design refresh across clipboard components.

Also applies to: 32-32, 35-35

src/routes/docs-examples/components/clipboard/Source.svelte (1)

3-3: LGTM: Container styling updated for Tailwind v4.

The rounded-lgrounded-base change aligns with the design token migration. Icon size increases and text label additions improve clarity.

Also applies to: 19-19, 33-40

src/routes/docs-examples/components/clipboard/Textarea.svelte (1)

3-3: LGTM: Enhanced clipboard feedback with styled labels.

Icon and text label updates provide better user feedback and visual consistency.

Also applies to: 14-18

src/routes/docs-examples/components/clipboard/Input.svelte (2)

8-8: Note: Responsive behavior change from fixed to maximum width.

The change from w-64 (fixed 16rem) to max-w-[16rem] (maximum 16rem, can shrink) alters responsive behavior. The element can now be narrower than 16rem on smaller screens, which may improve mobile UX. Verify this change is intentional.


3-3: LGTM: Icon update matches design system.

Icon migration to ClipboardCleanOutline with h-4 w-4 sizing is consistent with other clipboard components.

Also applies to: 14-14

src/lib/index.ts (1)

6-6: All verification checks passed. The plugin export is properly configured:

  • plugin-utilities.ts exists with a complete Tailwind plugin implementation (302 lines)
  • TypeScript declarations (plugin-utilities.d.ts) are present
  • package.json exports map correctly includes "./plugin-utilities" with proper type and module paths
src/lib/forms/input-addon/InputAddon.svelte (1)

44-44: rounded-s-base and rounded-e-base are valid Flowbite custom utilities.

These utilities are not native Tailwind v4 features but custom size tokens provided by Flowbite's default theme, which is imported in src/app.css. Directional variants (s, e) are supported in Tailwind v4, and the base size is defined by Flowbite. No verification needed—the utilities are valid for this project.

src/routes/docs-examples/components/clipboard/InputGroup.svelte (1)

8-21: LGTM! Excellent accessibility and consistency improvements.

The addition of the sr-only Label (line 11) improves screen reader accessibility, the explicit icon sizing (line 16) ensures visual consistency, and the color="brand" prop (line 13) aligns with the v2 color scheme migration.

src/routes/docs-examples/components/clipboard/ApiKeys.svelte (1)

3-3: Consistent icon update aligns with PR pattern.

The switch from ClipboardCleanSolid to ClipboardCleanOutline with explicit sizing classes (line 12) is consistent with the clipboard icon updates across other examples in this PR.

src/routes/docs-examples/components/clipboard/Url.svelte (1)

11-11: Verify default Button color after removing explicit prop.

The removal of color="primary" means this Button now uses the default color. Ensure the default Button color in v2 provides the intended visual appearance.

src/lib/plugin-utilities.d.ts (1)

9-14: Remove the recommendation for stricter typing in Tailwind v4.

Using any types with ESLint suppressions is necessary for Tailwind v4 plugin compatibility. Tailwind v4 does not provide specific TypeScript types for plugin handlers and configuration, and has actually removed the type definitions that existed in v3. No stricter alternative exists.

src/app.css (1)

22-22: No action needed—the plugin utilities path is correct.

The relative path "./lib/plugin-utilities" from src/app.css correctly resolves to the existing src/lib/plugin-utilities.ts file. The @plugin directive handles relative path resolution from the CSS file's directory, so the import will work as expected during the build process.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

♻️ Duplicate comments (2)
src/plugin-utilities.js (2)

10-149: Critical issue from previous review remains unresolved.

The previous review identified that this plugin references 47 CSS variables, but 38 of them are missing from src/app.css. You marked this as "fixed" and stated the file was moved to src/lib/plugin-utilities.js, but verification shows:

  1. File not moved – still located at src/plugin-utilities.js (not in src/lib/)
  2. Variables still missing – 38 out of 47 CSS variables remain undefined in src/app.css

Missing variables include:

  • --color-success-* (soft, medium, strong, subtle)
  • --color-danger-* (soft, medium, strong, subtle)
  • --color-warning-* (soft, medium, strong, subtle)
  • --color-dark-* (soft, strong, subtle)
  • --color-disabled
  • Single colors: --color-purple, --color-sky, --color-teal, --color-pink, --color-cyan, --color-fuchsia, --color-indigo, --color-orange
  • All foreground variants: --color-fg-*

Utilities referencing undefined variables will render with no styles, breaking the design system.

Required actions:

  1. Add all 38 missing CSS variable definitions to the @theme block in src/app.css
  2. Move this file to src/lib/plugin-utilities.js as originally intended, or remove it entirely (see duplication concern)

1-149: Consolidate or remove duplicate plugin implementation.

This JavaScript plugin duplicates the functionality in src/lib/plugin-utilities.ts, creating the same issues noted in that file's review:

  1. Maintenance burden – two implementations must stay in sync
  2. Export conflicts – both export flowbitePlugin as default
  3. Inconsistent coverage – TS version has 100+ utilities, JS has 47
  4. Location mismatch – this file should be at src/lib/ per past review

Recommendation: Since the TypeScript version is more comprehensive and properly located in src/lib/, remove this JavaScript version to eliminate duplication. If both must coexist, document why and establish a sync mechanism (or generate one from the other).

🧹 Nitpick comments (4)
clear-cache.sh (1)

7-10: Consider adding basic error handling.

The rm -rf commands will silently succeed even if the directories don't exist (which is fine), but if they fail due to permissions or disk issues, the script will still report success on line 12, potentially misleading users.

🔎 Optional error handling enhancement
 # Remove .svelte-kit directory
-rm -rf .svelte-kit
+rm -rf .svelte-kit || echo "Warning: Failed to remove .svelte-kit"

 # Remove node_modules/.vite cache
-rm -rf node_modules/.vite
+rm -rf node_modules/.vite || echo "Warning: Failed to remove node_modules/.vite"

 echo "Caches cleared! Now restart your dev server with: pnpm dev"
src/routes/layout.css (1)

1-977: Significant code duplication with src/app.css.

This new file is nearly identical to src/app.css (~95% overlap). Maintaining two copies of the same styles will lead to drift and inconsistencies over time.

Consider one of these approaches:

  1. Extract shared styles into a common partial (e.g., _shared.css) and import it in both files
  2. Remove duplication entirely if only one file is needed going forward
#!/bin/bash
# Check the similarity between the two CSS files
echo "=== Lines in app.css ==="
wc -l src/app.css

echo "=== Lines in layout.css ==="
wc -l src/routes/layout.css

echo "=== Differences between files ==="
diff --side-by-side --suppress-common-lines src/app.css src/routes/layout.css | head -50
src/routes/color-test/+page.svelte (2)

59-66: Add flex layout to display swatches horizontally.

The color swatches are created in a loop (lines 62-66) but their parent container (line 59) has no flex or grid display mode. This causes the swatches to stack vertically instead of displaying in a row, which likely isn't the intended visual layout for a color test page.

🔎 Proposed fix
- <div class="mb-8">
+ <div class="mb-8 flex flex-wrap gap-2">
    <h3 class="mb-2 text-xl font-bold capitalize">{color}</h3>

Or if you want the heading on its own line:

  <div class="mb-8">
-   <h3 class="mb-2 text-xl font-bold capitalize">{color}</h3>
+   <h3 class="mb-2 w-full text-xl font-bold capitalize">{color}</h3>

-   {#each borders as borderSize}
+   <div class="flex flex-wrap gap-2">
+     {#each borders as borderSize}
-     <div class={["m-2 flex h-24 w-24 items-center justify-center font-semibold", borderSize, colorClasses[color].border, colorClasses[color].text].join(" ")}>
+       <div class={["flex h-24 w-24 items-center justify-center font-semibold", borderSize, colorClasses[color].border, colorClasses[color].text].join(" ")}>
-       {color}
+         {color}
+       </div>
+     {/each}
    </div>
-   {/each}
  </div>

63-63: Consider simplifying class composition.

The array-join pattern for composing classes is functional but verbose. Template literals offer cleaner readability.

🔎 Alternative approaches

Using template literal:

-<div class={["m-2 flex h-24 w-24 items-center justify-center font-semibold", borderSize, colorClasses[color].border, colorClasses[color].text].join(" ")}>
+<div class={`m-2 flex h-24 w-24 items-center justify-center font-semibold ${borderSize} ${colorClasses[color].border} ${colorClasses[color].text}`}>

Or using the clsx utility (if available in the project):

+import { clsx } from 'clsx';

-<div class={["m-2 flex h-24 w-24 items-center justify-center font-semibold", borderSize, colorClasses[color].border, colorClasses[color].text].join(" ")}>
+<div class={clsx("m-2 flex h-24 w-24 items-center justify-center font-semibold", borderSize, colorClasses[color].border, colorClasses[color].text)}>
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 16b083a and deaff2d.

📒 Files selected for processing (14)
  • AGENTS.md
  • clear-cache.sh
  • package.json
  • src/app.css
  • src/lib/card/Card.svelte
  • src/lib/index.ts
  • src/lib/plugin-utilities.d.ts
  • src/lib/plugin-utilities.ts
  • src/plugin-utilities.js
  • src/routes/+layout.svelte
  • src/routes/color-test/+page.svelte
  • src/routes/docs-examples/components/clipboard/Default.svelte
  • src/routes/layout.css
  • src/routes/theme-context-test/+page.svelte
💤 Files with no reviewable changes (2)
  • src/routes/theme-context-test/+page.svelte
  • AGENTS.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/routes/docs-examples/components/clipboard/Default.svelte
  • package.json
  • src/lib/index.ts
  • src/lib/plugin-utilities.d.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/routes/+layout.svelte
  • src/plugin-utilities.js
  • src/routes/color-test/+page.svelte
  • src/lib/card/Card.svelte
  • src/lib/plugin-utilities.ts
🧠 Learnings (7)
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.

Applied to files:

  • src/app.css
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/app.css
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

Applied to files:

  • src/app.css
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation

Applied to files:

  • src/app.css
📚 Learning: 2025-12-16T13:21:28.743Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:28.743Z
Learning: In flowbite-svelte, when using ThemeProvider with reactive themes, `getTheme("componentName")` calls must be placed inside `$derived()` expressions (not at module scope) to ensure components react to dynamic theme changes. This pattern is intentional for reactive theming support.

Applied to files:

  • src/app.css
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/routes/+layout.svelte
  • src/routes/color-test/+page.svelte
  • src/lib/card/Card.svelte
📚 Learning: 2024-11-12T10:36:34.807Z
Learnt from: LahTeuto
Repo: themesberg/flowbite-svelte PR: 1484
File: src/lib/navbar/NavLi.svelte:34-34
Timestamp: 2024-11-12T10:36:34.807Z
Learning: When enhancing ARIA roles in Svelte components, avoid setting `role="presentation"` on elements that should retain the `link` role, as it can diminish ARIA role coverage and negatively affect accessibility.

Applied to files:

  • src/lib/card/Card.svelte
🧬 Code graph analysis (1)
src/lib/plugin-utilities.ts (1)
src/plugin-utilities.js (1)
  • colorUtilities (11-146)
🪛 Biome (2.1.2)
src/routes/layout.css

[error] 120-120: This @import is in the wrong position.

Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.

(lint/correctness/noInvalidPositionAtImportRule)


[error] 137-137: Duplicate font names are redundant and unnecessary: Segoe

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)

🔇 Additional comments (8)
clear-cache.sh (1)

1-12: Script approach is appropriate for cache clearing.

The script correctly targets the two main cache directories for SvelteKit and Vite, and the completion message provides clear next steps. The use of rm -rf is safe for cache directories and handles non-existent paths gracefully.

src/lib/card/Card.svelte (3)

3-3: LGTM: Theme reactivity properly implemented.

The use of $derived(getTheme("card")) at line 11 correctly ensures the component reacts to dynamic theme changes from ThemeProvider. This follows the recommended pattern from the codebase learnings.

Based on learnings, this is the correct way to make theme-derived values reactive in Flowbite-Svelte components.

Also applies to: 11-11


7-7: LGTM: hoverable prop properly integrated.

The new hoverable prop is correctly added with a sensible default (false), properly passed to the card() styling function, and documented consistently.

Also applies to: 19-19, 62-62


7-7: No deprecated props remain in use—Card component migration is complete.

The removal of legacy color and imgClass props has been successfully verified across the codebase. The unified classes prop implementation with styling?.image is correctly in place, and no Card component usages reference the deprecated props. The v2 design system migration for this component is complete.

src/app.css (1)

103-117: Previous review concern has been addressed.

The dark mode brand color overrides are now properly commented out (lines 103-117), matching the light mode overrides (lines 73-87). Both modes now consistently use default Flowbite brand colors.

src/routes/+layout.svelte (1)

2-3: Remove or retain app.css intentionally.

The global app.css import is now commented out in favor of layout.css. The file still exists at src/app.css but is not imported by any active code—no other files reference it. If app.css is no longer needed, delete it; otherwise, add a comment explaining why it's kept for future use.

src/lib/plugin-utilities.ts (2)

1-9: LGTM: Proper typing and clear documentation.

The import statement correctly uses the PluginCreator type, and the documentation clearly explains why this plugin is necessary for Tailwind CSS v4 (custom properties in @theme don't auto-generate utilities).


300-300: LGTM: Clean default export.

The export is properly typed through the satisfies PluginCreator assertion on line 298, avoiding the type safety issues from previous versions.

Comment on lines 10 to 298
const flowbitePlugin = plugin(function ({ addUtilities }) {
const colorUtilities = {
// ===========================
// TEXT/BODY COLORS
// ===========================
".text-body": { color: "var(--color-body)" },
".text-body-subtle": { color: "var(--color-body-subtle)" },
".text-heading": { color: "var(--color-heading)" },

// ===========================
// NEUTRAL COLORS
// ===========================
// Neutral Primary
".bg-neutral-primary-soft": { backgroundColor: "var(--color-neutral-primary-soft)" },
".bg-neutral-primary": { backgroundColor: "var(--color-neutral-primary)" },
".bg-neutral-primary-medium": { backgroundColor: "var(--color-neutral-primary-medium)" },
".bg-neutral-primary-strong": { backgroundColor: "var(--color-neutral-primary-strong)" },

".text-neutral-primary-soft": { color: "var(--color-neutral-primary-soft)" },
".text-neutral-primary": { color: "var(--color-neutral-primary)" },
".text-neutral-primary-medium": { color: "var(--color-neutral-primary-medium)" },
".text-neutral-primary-strong": { color: "var(--color-neutral-primary-strong)" },

".border-neutral-primary-soft": { borderColor: "var(--color-neutral-primary-soft)" },
".border-neutral-primary": { borderColor: "var(--color-neutral-primary)" },
".border-neutral-primary-medium": { borderColor: "var(--color-neutral-primary-medium)" },
".border-neutral-primary-strong": { borderColor: "var(--color-neutral-primary-strong)" },

// Neutral Secondary
".bg-neutral-secondary-soft": { backgroundColor: "var(--color-neutral-secondary-soft)" },
".bg-neutral-secondary": { backgroundColor: "var(--color-neutral-secondary)" },
".bg-neutral-secondary-medium": { backgroundColor: "var(--color-neutral-secondary-medium)" },
".bg-neutral-secondary-strong": { backgroundColor: "var(--color-neutral-secondary-strong)" },
".bg-neutral-secondary-strongest": { backgroundColor: "var(--color-neutral-secondary-strongest)" },

".text-neutral-secondary-soft": { color: "var(--color-neutral-secondary-soft)" },
".text-neutral-secondary": { color: "var(--color-neutral-secondary)" },
".text-neutral-secondary-medium": { color: "var(--color-neutral-secondary-medium)" },
".text-neutral-secondary-strong": { color: "var(--color-neutral-secondary-strong)" },
".text-neutral-secondary-strongest": { color: "var(--color-neutral-secondary-strongest)" },

".border-neutral-secondary-soft": { borderColor: "var(--color-neutral-secondary-soft)" },
".border-neutral-secondary": { borderColor: "var(--color-neutral-secondary)" },
".border-neutral-secondary-medium": { borderColor: "var(--color-neutral-secondary-medium)" },
".border-neutral-secondary-strong": { borderColor: "var(--color-neutral-secondary-strong)" },
".border-neutral-secondary-strongest": { borderColor: "var(--color-neutral-secondary-strongest)" },

// Neutral Tertiary
".bg-neutral-tertiary-soft": { backgroundColor: "var(--color-neutral-tertiary-soft)" },
".bg-neutral-tertiary": { backgroundColor: "var(--color-neutral-tertiary)" },
".bg-neutral-tertiary-medium": { backgroundColor: "var(--color-neutral-tertiary-medium)" },

".text-neutral-tertiary-soft": { color: "var(--color-neutral-tertiary-soft)" },
".text-neutral-tertiary": { color: "var(--color-neutral-tertiary)" },
".text-neutral-tertiary-medium": { color: "var(--color-neutral-tertiary-medium)" },

".border-neutral-tertiary-soft": { borderColor: "var(--color-neutral-tertiary-soft)" },
".border-neutral-tertiary": { borderColor: "var(--color-neutral-tertiary)" },
".border-neutral-tertiary-medium": { borderColor: "var(--color-neutral-tertiary-medium)" },

// Neutral Quaternary
".bg-neutral-quaternary": { backgroundColor: "var(--color-neutral-quaternary)" },
".bg-neutral-quaternary-medium": { backgroundColor: "var(--color-neutral-quaternary-medium)" },

".text-neutral-quaternary": { color: "var(--color-neutral-quaternary)" },
".text-neutral-quaternary-medium": { color: "var(--color-neutral-quaternary-medium)" },

".border-neutral-quaternary": { borderColor: "var(--color-neutral-quaternary)" },
".border-neutral-quaternary-medium": { borderColor: "var(--color-neutral-quaternary-medium)" },

// Gray
".bg-gray": { backgroundColor: "var(--color-gray)" },
".text-gray": { color: "var(--color-gray)" },
".border-gray": { borderColor: "var(--color-gray)" },

// ===========================
// BORDER COLORS
// ===========================
// Buffer
".bg-buffer": { backgroundColor: "var(--color-buffer)" },
".bg-buffer-medium": { backgroundColor: "var(--color-buffer-medium)" },
".bg-buffer-strong": { backgroundColor: "var(--color-buffer-strong)" },

".text-buffer": { color: "var(--color-buffer)" },
".text-buffer-medium": { color: "var(--color-buffer-medium)" },
".text-buffer-strong": { color: "var(--color-buffer-strong)" },

".border-buffer": { borderColor: "var(--color-buffer)" },
".border-buffer-medium": { borderColor: "var(--color-buffer-medium)" },
".border-buffer-strong": { borderColor: "var(--color-buffer-strong)" },

// Muted
".bg-muted": { backgroundColor: "var(--color-muted)" },
".text-muted": { color: "var(--color-muted)" },
".border-muted": { borderColor: "var(--color-muted)" },

// Light
".bg-light-subtle": { backgroundColor: "var(--color-light-subtle)" },
".bg-light": { backgroundColor: "var(--color-light)" },
".bg-light-medium": { backgroundColor: "var(--color-light-medium)" },

".text-light-subtle": { color: "var(--color-light-subtle)" },
".text-light": { color: "var(--color-light)" },
".text-light-medium": { color: "var(--color-light-medium)" },

".border-light-subtle": { borderColor: "var(--color-light-subtle)" },
".border-light": { borderColor: "var(--color-light)" },
".border-light-medium": { borderColor: "var(--color-light-medium)" },

// Default
".bg-default-subtle": { backgroundColor: "var(--color-default-subtle)" },
".bg-default": { backgroundColor: "var(--color-default)" },
".bg-default-medium": { backgroundColor: "var(--color-default-medium)" },
".bg-default-strong": { backgroundColor: "var(--color-default-strong)" },

".text-default-subtle": { color: "var(--color-default-subtle)" },
".text-default": { color: "var(--color-default)" },
".text-default-medium": { color: "var(--color-default-medium)" },
".text-default-strong": { color: "var(--color-default-strong)" },

".border-default-subtle": { borderColor: "var(--color-default-subtle)" },
".border-default": { borderColor: "var(--color-default)" },
".border-default-medium": { borderColor: "var(--color-default-medium)" },
".border-default-strong": { borderColor: "var(--color-default-strong)" },

// ===========================
// SUCCESS COLORS
// ===========================
".bg-success-soft": { backgroundColor: "var(--color-success-soft)" },
".bg-success": { backgroundColor: "var(--color-success)" },
".bg-success-medium": { backgroundColor: "var(--color-success-medium)" },
".bg-success-strong": { backgroundColor: "var(--color-success-strong)" },

".text-success-soft": { color: "var(--color-success-soft)" },
".text-success": { color: "var(--color-success)" },
".text-success-medium": { color: "var(--color-success-medium)" },
".text-success-strong": { color: "var(--color-success-strong)" },

".border-success-soft": { borderColor: "var(--color-success-soft)" },
".border-success": { borderColor: "var(--color-success)" },
".border-success-medium": { borderColor: "var(--color-success-medium)" },
".border-success-strong": { borderColor: "var(--color-success-strong)" },
".border-success-subtle": { borderColor: "var(--color-success-subtle)" },

".ring-success-subtle": { "--tw-ring-color": "var(--color-success-subtle)" },

// ===========================
// DANGER COLORS
// ===========================
".bg-danger-soft": { backgroundColor: "var(--color-danger-soft)" },
".bg-danger": { backgroundColor: "var(--color-danger)" },
".bg-danger-medium": { backgroundColor: "var(--color-danger-medium)" },
".bg-danger-strong": { backgroundColor: "var(--color-danger-strong)" },

".text-danger-soft": { color: "var(--color-danger-soft)" },
".text-danger": { color: "var(--color-danger)" },
".text-danger-medium": { color: "var(--color-danger-medium)" },
".text-danger-strong": { color: "var(--color-danger-strong)" },

".border-danger-soft": { borderColor: "var(--color-danger-soft)" },
".border-danger": { borderColor: "var(--color-danger)" },
".border-danger-medium": { borderColor: "var(--color-danger-medium)" },
".border-danger-strong": { borderColor: "var(--color-danger-strong)" },
".border-danger-subtle": { borderColor: "var(--color-danger-subtle)" },

".ring-danger-subtle": { "--tw-ring-color": "var(--color-danger-subtle)" },

// ===========================
// WARNING COLORS
// ===========================
".bg-warning-soft": { backgroundColor: "var(--color-warning-soft)" },
".bg-warning": { backgroundColor: "var(--color-warning)" },
".bg-warning-medium": { backgroundColor: "var(--color-warning-medium)" },
".bg-warning-strong": { backgroundColor: "var(--color-warning-strong)" },

".text-warning-soft": { color: "var(--color-warning-soft)" },
".text-warning": { color: "var(--color-warning)" },
".text-warning-medium": { color: "var(--color-warning-medium)" },
".text-warning-strong": { color: "var(--color-warning-strong)" },

".border-warning-soft": { borderColor: "var(--color-warning-soft)" },
".border-warning": { borderColor: "var(--color-warning)" },
".border-warning-medium": { borderColor: "var(--color-warning-medium)" },
".border-warning-strong": { borderColor: "var(--color-warning-strong)" },
".border-warning-subtle": { borderColor: "var(--color-warning-subtle)" },

".ring-warning-subtle": { "--tw-ring-color": "var(--color-warning-subtle)" },

// ===========================
// DARK COLORS
// ===========================
".bg-dark-soft": { backgroundColor: "var(--color-dark-soft)" },
".bg-dark": { backgroundColor: "var(--color-dark)" },
".bg-dark-strong": { backgroundColor: "var(--color-dark-strong)" },
".bg-dark-backdrop": { backgroundColor: "var(--color-dark-backdrop)" },
".bg-disabled": { backgroundColor: "var(--color-disabled)" },

".text-dark-soft": { color: "var(--color-dark-soft)" },
".text-dark": { color: "var(--color-dark)" },
".text-dark-strong": { color: "var(--color-dark-strong)" },
".text-dark-backdrop": { color: "var(--color-dark-backdrop)" },
".text-disabled": { color: "var(--color-disabled)" },

".border-dark-soft": { borderColor: "var(--color-dark-soft)" },
".border-dark": { borderColor: "var(--color-dark)" },
".border-dark-strong": { borderColor: "var(--color-dark-strong)" },
".border-dark-subtle": { borderColor: "var(--color-dark-subtle)" },
".border-dark-backdrop": { borderColor: "var(--color-dark-backdrop)" },

".ring-dark-subtle": { "--tw-ring-color": "var(--color-dark-subtle)" },

// ===========================
// BRAND COLORS
// ===========================
".bg-brand-softer": { backgroundColor: "var(--color-brand-softer)" },
".bg-brand-soft": { backgroundColor: "var(--color-brand-soft)" },
".bg-brand": { backgroundColor: "var(--color-brand)" },
".bg-brand-medium": { backgroundColor: "var(--color-brand-medium)" },
".bg-brand-strong": { backgroundColor: "var(--color-brand-strong)" },

".text-brand-softer": { color: "var(--color-brand-softer)" },
".text-brand-soft": { color: "var(--color-brand-soft)" },
".text-brand": { color: "var(--color-brand)" },
".text-brand-medium": { color: "var(--color-brand-medium)" },
".text-brand-strong": { color: "var(--color-brand-strong)" },

".border-brand-softer": { borderColor: "var(--color-brand-softer)" },
".border-brand-soft": { borderColor: "var(--color-brand-soft)" },
".border-brand": { borderColor: "var(--color-brand)" },
".border-brand-medium": { borderColor: "var(--color-brand-medium)" },
".border-brand-strong": { borderColor: "var(--color-brand-strong)" },
".border-brand-subtle": { borderColor: "var(--color-brand-subtle)" },
".border-brand-light": { borderColor: "var(--color-brand-light)" },

".ring-brand-subtle": { "--tw-ring-color": "var(--color-brand-subtle)" },

// ===========================
// SINGLE COLORS
// ===========================
".bg-purple": { backgroundColor: "var(--color-purple)" },
".bg-sky": { backgroundColor: "var(--color-sky)" },
".bg-teal": { backgroundColor: "var(--color-teal)" },
".bg-pink": { backgroundColor: "var(--color-pink)" },
".bg-cyan": { backgroundColor: "var(--color-cyan)" },
".bg-fuchsia": { backgroundColor: "var(--color-fuchsia)" },
".bg-indigo": { backgroundColor: "var(--color-indigo)" },
".bg-orange": { backgroundColor: "var(--color-orange)" },

".text-purple": { color: "var(--color-purple)" },
".text-sky": { color: "var(--color-sky)" },
".text-teal": { color: "var(--color-teal)" },
".text-pink": { color: "var(--color-pink)" },
".text-cyan": { color: "var(--color-cyan)" },
".text-fuchsia": { color: "var(--color-fuchsia)" },
".text-indigo": { color: "var(--color-indigo)" },
".text-orange": { color: "var(--color-orange)" },

".border-purple": { borderColor: "var(--color-purple)" },
".border-sky": { borderColor: "var(--color-sky)" },
".border-teal": { borderColor: "var(--color-teal)" },
".border-pink": { borderColor: "var(--color-pink)" },
".border-cyan": { borderColor: "var(--color-cyan)" },
".border-fuchsia": { borderColor: "var(--color-fuchsia)" },
".border-indigo": { borderColor: "var(--color-indigo)" },
".border-orange": { borderColor: "var(--color-orange)" },

// ===========================
// FOREGROUND COLORS (text semantic colors)
// ===========================
".text-fg-brand-subtle": { color: "var(--color-fg-brand-subtle)" },
".text-fg-brand": { color: "var(--color-fg-brand)" },
".text-fg-brand-strong": { color: "var(--color-fg-brand-strong)" },
".text-fg-success": { color: "var(--color-fg-success)" },
".text-fg-success-strong": { color: "var(--color-fg-success-strong)" },
".text-fg-danger": { color: "var(--color-fg-danger)" },
".text-fg-danger-strong": { color: "var(--color-fg-danger-strong)" },
".text-fg-warning": { color: "var(--color-fg-warning)" },
".text-fg-warning-subtle": { color: "var(--color-fg-warning-subtle)" },
".text-fg-yellow": { color: "var(--color-fg-yellow)" },
".text-fg-disabled": { color: "var(--color-fg-disabled)" },
".text-fg-purple": { color: "var(--color-fg-purple)" },
".text-fg-cyan": { color: "var(--color-fg-cyan)" },
".text-fg-indigo": { color: "var(--color-fg-indigo)" },
".text-fg-pink": { color: "var(--color-fg-pink)" },
".text-fg-lime": { color: "var(--color-fg-lime)" }
};

addUtilities(colorUtilities);
} satisfies PluginCreator);
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 22, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Extract all unique CSS variable references from the TS plugin
echo "=== Extracting CSS variables from plugin ==="
rg 'var\(--color-([^)]+)\)' src/lib/plugin-utilities.ts -o -r '$1' | sort -u > /tmp/ts_plugin_vars.txt

echo "Total unique variables referenced in TS plugin:"
wc -l /tmp/ts_plugin_vars.txt

# First, find the app.css file
echo -e "\n=== Finding src/app.css ==="
find . -name "app.css" -type f 2>/dev/null | head -5

# Check if it exists and look for theme definitions
echo -e "\n=== Checking for theme definitions ==="
if [ -f src/app.css ]; then
  echo "File exists. Checking for @theme or variable definitions..."
  head -50 src/app.css
fi

Repository: themesberg/flowbite-svelte

Length of output: 1861


🏁 Script executed:

#!/bin/bash
# Search for files that might contain theme definitions
echo "=== Searching for theme/color definitions ==="
find . -type f \( -name "*.css" -o -name "*.scss" -o -name "tailwind.config.*" \) | grep -v node_modules | head -20

echo -e "\n=== Looking for @theme or --color definitions ==="
rg "@theme|--color-" . --type css --type scss -l | grep -v node_modules | head -20

Repository: themesberg/flowbite-svelte

Length of output: 1579


🏁 Script executed:

#!/bin/bash
# Check the flowbite theme file that's imported
echo "=== Checking imported flowbite theme ==="
find . -path "*/flowbite/src/themes/default*" -type f 2>/dev/null | head -5

# Also check what's in the app.css @theme block
echo -e "\n=== Full @theme block in app.css ==="
sed -n '/@theme/,/}/p' src/app.css | head -100

# Extract the referenced variables from plugin
echo -e "\n=== Sample of 15 referenced variables ==="
head -15 /tmp/ts_plugin_vars.txt

Repository: themesberg/flowbite-svelte

Length of output: 1932


🏁 Script executed:

#!/bin/bash
# Check if flowbite is a node module
echo "=== Checking flowbite package location ==="
find . -path "*/node_modules/flowbite/src/themes/default*" -type f 2>/dev/null | head -3

# If found, check what's in it
if [ -f "node_modules/flowbite/src/themes/default.css" ]; then
  echo -e "\n=== Content of flowbite default theme ==="
  cat node_modules/flowbite/src/themes/default.css | head -80
fi

Repository: themesberg/flowbite-svelte

Length of output: 112


🏁 Script executed:

#!/bin/bash
# Now let's check which of the 81 variables are actually defined
echo "=== Verifying variable definitions ==="
missing_count=0
found_count=0
missing_vars=()

while IFS= read -r var; do
  # Search in app.css and any imported files
  if rg "^\s*--color-$var\s*:" src/ 2>/dev/null | grep -q .; then
    found_count=$((found_count + 1))
  else
    missing_count=$((missing_count + 1))
    missing_vars+=("--color-$var")
  fi
done < /tmp/ts_plugin_vars.txt

echo "✓ Found in src: $found_count variables"
echo "✗ Missing from src: $missing_count variables"

if [ $missing_count -gt 0 ]; then
  echo -e "\n=== All missing variables ==="
  printf '%s\n' "${missing_vars[@]}" | sort
fi

Repository: themesberg/flowbite-svelte

Length of output: 1689


All 81 CSS color variables referenced in this plugin must be defined in src/app.css theme.

The plugin references 81 unique CSS color variables (e.g., --color-neutral-primary-soft, --color-buffer-medium, --color-body, etc.), but only 10 are currently defined in the @theme block of src/app.css (the --color-primary-* and --color-secondary-* variants). The remaining 71 variables are missing:

  • Text/body colors: --color-body, --color-body-subtle, --color-heading
  • Neutral system: all --color-neutral-primary-*, --color-neutral-secondary-*, --color-neutral-tertiary-*, --color-neutral-quaternary-* variants
  • Semantic colors: --color-danger-*, --color-success-*, --color-warning-*, --color-dark-* variants
  • System colors: --color-buffer-*, --color-muted, --color-light-*, --color-default-*, --color-disabled
  • Foreground text colors: all 11 --color-fg-* variants
  • Single colors: --color-cyan, --color-fuchsia, --color-indigo, --color-orange, --color-pink, --color-purple, --color-sky, --color-teal

Without these definitions, the generated utilities will have no effect at runtime—styles will fail silently and elements using these classes won't render correctly.

Add all missing variables to the @theme block in src/app.css, or remove the corresponding utilities from the plugin.

🤖 Prompt for AI Agents
In src/lib/plugin-utilities.ts around lines 10 to 298 the Tailwind plugin emits
utilities that reference 81 CSS variables which are not defined in your @theme
block in src/app.css; add the missing variables (or remove unused utilities) so
the classes actually apply. Open src/app.css and inside the @theme block add
definitions for the listed variables grouped by category (text/body:
--color-body, --color-body-subtle, --color-heading; neutral: all
--color-neutral-primary-*, -secondary-*, -tertiary-*, -quaternary-*; semantic:
--color-success-*, --color-danger-*, --color-warning-*, --color-dark-*; system:
--color-buffer-*, --color-muted, --color-light-*, --color-default-*,
--color-disabled; foreground: all --color-fg-*; singles: --color-cyan,
--color-fuchsia, --color-indigo, --color-orange, --color-pink, --color-purple,
--color-sky, --color-teal), provide sensible default hex values or reference
existing tokens, and ensure names exactly match the plugin; alternatively remove
any unused utility entries from plugin-utilities.ts to match what is defined in
src/app.css.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I moved it to src/routes/layout.css and since I have @import "flowbite/src/themes/default";, ignore this.

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the layout.css file and check for the flowbite import
echo "=== Checking src/routes/layout.css ==="
if [ -f src/routes/layout.css ]; then
  echo "File exists. Checking for flowbite theme import..."
  head -20 src/routes/layout.css | grep -A2 -B2 "flowbite"
else
  echo "File not found"
fi

echo -e "\n=== Checking if layout.css is being used ==="
rg "layout\.css" src/routes --type svelte -A2 -B2 | head -20

Length of output: 410


@shinokada, understood! I've confirmed that src/routes/layout.css contains the @import "flowbite/src/themes/default"; statement, which will provide all the CSS color variables (the 81 --color-* tokens) that the plugin references. Since the Flowbite default theme defines these variables, the utilities generated by plugin-utilities.ts will work correctly. The original concern about missing variables in src/app.css is resolved. ✓

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/types.ts (1)

586-620: Update prop interfaces for Desktop and Laptop to match their implementations.

The DesktopProps and LaptopProps interfaces (lines 586-600) declare unused props that are not consumed by their components:

  • Both declare divClass, div2Class, div3Class, div4Class properties
  • The actual component implementations ignore these props entirely
  • Both components only destructure children, class, classes, and restProps—matching the pattern used by Android, DefaultMockup, Ios, Smartwatch, and Tablet

Remove the unused class properties from DesktopProps and LaptopProps to align with their implementations and maintain consistency across all device mockup prop interfaces.

🧹 Nitpick comments (2)
src/lib/datepicker/Datepicker.svelte (1)

480-484: Inconsistent theme application in navigation section.

Unlike other elements in this component (e.g., lines 458, 492, 494), the nav and polite elements here don't include theme?.nav and theme?.polite in the class composition. This may be intentional for the non-month-selector view, but it creates an inconsistency with the month-selector view (lines 458, 460) which does include theme values.

Is this asymmetry intentional? If not, consider updating for consistency:

Suggested fix
-        <div class={nav({ class: clsx(styling?.nav) })}>
+        <div class={nav({ class: clsx(theme?.nav, styling?.nav) })}>
           {@render navButton(false)}
           <Button
             type="button"
-            class={polite({ class: clsx("cursor-pointer rounded px-2 py-1 hover:bg-gray-100 dark:hover:bg-gray-700", styling?.polite) })}
+            class={polite({ class: clsx("cursor-pointer rounded px-2 py-1 hover:bg-gray-100 dark:hover:bg-gray-700", theme?.polite, styling?.polite) })}
src/lib/device-mockups/DefaultMockup.svelte (1)

9-10: Consider whether wrapping classes in $derived is necessary.

In Svelte 5's runes mode, props are already reactive. The line const styling = $derived(classes); creates a derived reactive value from an already-reactive prop. Unless there's a specific reason for this indirection (e.g., future transformation logic), you could simplify to:

  const theme = $derived(getTheme("defaultMockup"));
- const styling = $derived(classes);
+ const styling = classes;

This applies to all device mockup components following the same pattern.

Based on learnings, getTheme() is correctly placed inside $derived() for reactive theme changes.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between deaff2d and 0efb5e7.

📒 Files selected for processing (11)
  • src/lib/datepicker/Datepicker.svelte
  • src/lib/device-mockups/Android.svelte
  • src/lib/device-mockups/DefaultMockup.svelte
  • src/lib/device-mockups/Desktop.svelte
  • src/lib/device-mockups/Ios.svelte
  • src/lib/device-mockups/Laptop.svelte
  • src/lib/device-mockups/Smartwatch.svelte
  • src/lib/device-mockups/Tablet.svelte
  • src/lib/theme/themes.ts
  • src/lib/types.ts
  • src/routes/color-test/+page.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/routes/color-test/+page.svelte
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/lib/datepicker/Datepicker.svelte
  • src/lib/device-mockups/Tablet.svelte
  • src/lib/device-mockups/Android.svelte
  • src/lib/device-mockups/Smartwatch.svelte
  • src/lib/device-mockups/Ios.svelte
  • src/lib/device-mockups/Desktop.svelte
  • src/lib/device-mockups/Laptop.svelte
  • src/lib/device-mockups/DefaultMockup.svelte
  • src/lib/theme/themes.ts
  • src/lib/types.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:28.743Z
Learning: In flowbite-svelte, when using ThemeProvider with reactive themes, `getTheme("componentName")` calls must be placed inside `$derived()` expressions (not at module scope) to ensure components react to dynamic theme changes. This pattern is intentional for reactive theming support.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
📚 Learning: 2024-10-15T22:41:47.429Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1464
File: src/routes/component-data/Datepicker.json:0-0
Timestamp: 2024-10-15T22:41:47.429Z
Learning: The component should be named 'Datepicker' (with lowercase 'p') throughout the codebase to maintain consistency.

Applied to files:

  • src/lib/datepicker/Datepicker.svelte
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1465
File: src/lib/forms/Timepicker.svelte:105-116
Timestamp: 2024-10-18T09:38:03.879Z
Learning: In `Timepicker.svelte`, the `Dropdown` opens as intended and is used exclusively with the 'dropdown' and 'timerange-dropdown' Timepicker types.

Applied to files:

  • src/lib/datepicker/Datepicker.svelte
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/lib/datepicker/Datepicker.svelte
  • src/lib/device-mockups/Tablet.svelte
  • src/lib/device-mockups/Android.svelte
  • src/lib/device-mockups/Smartwatch.svelte
  • src/lib/device-mockups/Ios.svelte
  • src/lib/device-mockups/Desktop.svelte
  • src/lib/device-mockups/Laptop.svelte
  • src/lib/device-mockups/DefaultMockup.svelte
🧬 Code graph analysis (1)
src/lib/types.ts (5)
src/lib/utils/theme.ts (1)
  • CloseButtonVariants (5-5)
src/lib/badge/theme.ts (1)
  • BadgeVariants (5-5)
src/lib/banner/theme.ts (1)
  • BannerVariants (5-5)
src/lib/buttons/theme.ts (1)
  • GradientButtonVariants (5-5)
src/lib/carousel/theme.ts (3)
  • CarouselIndicatorsVariants (5-5)
  • ControlButtonVariants (6-6)
  • ThumbnailsVariants (7-7)
🔇 Additional comments (12)
src/lib/device-mockups/Laptop.svelte (2)

9-11: Theme reactivity pattern correctly implemented.

The getTheme("laptop") call is properly wrapped in $derived() to ensure the component reacts to dynamic theme changes from ThemeProvider. Based on learnings, this is the correct pattern for Flowbite-Svelte components.

Minor observation: const styling = $derived(classes) appears redundant since classes is already reactive from $props(). However, if this is an intentional pattern for consistency across components, it's acceptable.


17-26: LGTM!

The template correctly merges theme-based classes with user-provided className and styling overrides using clsx. Optional chaining ensures graceful handling when theme or styling values are undefined.

src/lib/device-mockups/Desktop.svelte (2)

9-10: Theme reactivity correctly implemented.

The getTheme("desktop") is properly wrapped in $derived() for reactive theming support, following the established pattern. Based on learnings, this ensures the component reacts to dynamic theme changes.


15-23: LGTM!

The template correctly applies the theme-based styling pattern with proper class merging via clsx. The DOM structure maintains the desktop mockup's design with bot and botUnder elements as siblings to the main container.

src/lib/device-mockups/Tablet.svelte (2)

9-10: Theme reactivity correctly implemented.

The reactive theming pattern with $derived(getTheme("tablet")) is correctly applied, consistent with other device-mockup components in this PR.


15-25: LGTM!

The template correctly implements the theme-based styling for all tablet elements (leftTop, leftMid, leftBot, right, slot), with proper class merging and optional chaining for null safety.

src/lib/datepicker/Datepicker.svelte (3)

27-27: Color token migration from primary to brand.

This aligns with the broader v4 refactor migrating legacy color names to semantic tokens. The default color is updated to use the new brand token.


44-45: Theme reactivity correctly implemented.

The getTheme("datepicker") call is properly wrapped in $derived() for reactive theming support.


471-471: Hardcoded bg-brand class used for selected month.

The selected month styling uses a hardcoded bg-brand class. If the color prop is intended to influence this styling, consider making it dynamic. Otherwise, this is acceptable if brand is the standard selection color.

src/lib/device-mockups/Ios.svelte (2)

9-10: Theme reactivity correctly implemented.

The getTheme("ios") call is properly wrapped in $derived(), consistent with the reactive theming pattern used across all device-mockup components in this PR.


15-25: LGTM!

The template correctly implements the theme-based styling pattern for all iOS mockup elements with proper class merging and optional chaining. The migration from legacy divClass props to the unified classes prop is clean and consistent.

src/lib/theme/themes.ts (1)

16-16: LGTM!

The expanded exports align with the device-mockup component updates in this PR. The additions (defaultMockup, laptop, smartwatch) are properly included alongside the existing exports and correctly re-exported from the device-mockups barrel file.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/drawer/Drawer.svelte (1)

120-135: Remove stale prop documentation.

The inline documentation still references the removed props hidden (line 123) and activateClickOutside (line 133), which are no longer part of the component's public API. These should be removed to prevent confusion.

🔎 Proposed fix to remove outdated documentation
 ## Props
 @prop children
 @prop open = $bindable(false)
-@prop hidden = $bindable()
 @prop modal
 @prop offset
 @prop width
 @prop dismissable
 @prop placement = "left"
 @prop class: className
 @prop transitionParams
 @prop transition = fly
 @prop outsideclose
-@prop activateClickOutside
 @prop ...restProps
♻️ Duplicate comments (1)
clear-cache.sh (1)

3-3: Misleading comment still present.

The comment "Stop the dev server if running" on Line 3 remains in the code, even though this concern was previously flagged and marked as addressed. The script doesn't actually stop the dev server—it's just a reminder to the user. This placement continues to be confusing about what the script does.

Please move this to a usage comment at the top of the file or remove it entirely, since the completion message on Line 12 already instructs users to restart the dev server.

🔎 Suggested clarification
 #!/bin/bash
+# Usage: Stop your dev server before running this script.
+# This script clears build caches and requires a dev server restart.

-# Stop the dev server if running
 echo "Clearing build caches..."
🧹 Nitpick comments (4)
src/lib/dialog/Dialog.svelte (1)

35-35: Consider removing unnecessary aliasing.

The styling variable is simply an alias for the classes prop with no transformation. You can reference classes directly on lines 150 and 169 to reduce indirection, or clarify if this is a placeholder for future styling logic.

🔎 Proposed simplification
-  const styling = $derived(classes);

Then update lines 150 and 169:

-    <CloseButton type="submit" formnovalidate class={closeCls({ class: clsx(styling?.close) })} />
+    <CloseButton type="submit" formnovalidate class={closeCls({ class: clsx(classes?.close) })} />
-      <form method="dialog" class={formCls({ class: clsx(styling?.form) })}>
+      <form method="dialog" class={formCls({ class: clsx(classes?.form) })}>
src/routes/color-test/+page.svelte (1)

96-112: Consider using template literals for class composition.

The class composition using array.join(" ") works correctly but could be more concise.

🔎 Optional refactor using template literals
-        <div class={["m-2 flex h-24 w-24 items-center justify-center font-semibold", borderSize, colorClasses[color].border, colorClasses[color].text].join(" ")}>
+        <div class={`m-2 flex h-24 w-24 items-center justify-center font-semibold ${borderSize} ${colorClasses[color].border} ${colorClasses[color].text}`}>
           {color}
         </div>
       {/each}
 
       <div class="mt-4 flex flex-wrap">
-        <div class={["m-2 flex h-24 w-24 items-center justify-center font-semibold", bgColorClasses[color], "text-gray-900"].join(" ")}>bg</div>
+        <div class={`m-2 flex h-24 w-24 items-center justify-center font-semibold ${bgColorClasses[color]} text-gray-900`}>bg</div>
       </div>

Alternatively, consider using a utility like clsx if the project already includes it.

src/lib/datepicker/Datepicker.svelte (1)

44-44: Consider simplifying the styling derivation.

The styling object is simply derived from classes without any transformation. Consider using classes directly in your class bindings (e.g., classes?.input instead of styling?.input), or document why this indirection is needed if it's for consistency with other components in this refactor.

🔎 Proposed simplification
-  const styling = $derived(classes);
   const theme = $derived(getTheme("datepicker"));

Then update all usages to reference classes directly:

-        class={input({ color, class: clsx(theme?.input, styling?.input) })}
+        class={input({ color, class: clsx(theme?.input, classes?.input) })}
src/routes/layout.css (1)

21-22: Clarify plugin-utilities plugin usage.

The plugin import is commented out while a TypeScript version exists at src/routes/plugin-utilities.ts. If the custom color utilities defined in that plugin (e.g., .bg-success-soft, .text-danger, .border-brand-subtle) are intended for use in components, uncomment this line:

 @plugin "flowbite/plugin";
-/* @plugin "./plugin-utilities"; */
+@plugin "./plugin-utilities";
 @plugin "flowbite-typography";

Otherwise, if these utilities aren't needed, consider removing the plugin file to avoid maintaining unused code.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0efb5e7 and 4bd2a28.

📒 Files selected for processing (12)
  • clear-cache.sh
  • src/lib/card/Card.svelte
  • src/lib/datepicker/Datepicker.svelte
  • src/lib/dialog/Dialog.svelte
  • src/lib/drawer/Drawer.svelte
  • src/lib/drawer/DrawerHandle.svelte
  • src/lib/drawer/Drawerhead.svelte
  • src/lib/theme/themes.ts
  • src/lib/types.ts
  • src/routes/color-test/+page.svelte
  • src/routes/layout.css
  • src/routes/plugin-utilities.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/theme/themes.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/routes/plugin-utilities.ts
  • src/lib/dialog/Dialog.svelte
  • src/routes/color-test/+page.svelte
  • src/lib/drawer/Drawer.svelte
  • src/lib/card/Card.svelte
  • src/lib/drawer/DrawerHandle.svelte
  • src/lib/datepicker/Datepicker.svelte
  • src/lib/drawer/Drawerhead.svelte
  • src/lib/types.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles, ensure both the container (with focus-within) and the inner input element (with direct focus) have dynamic styling based on the validation state. The input element needs its own focus styles that change to red when inputInvalid=true.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.953Z
Learning: In the Flowbite Svelte library's MultiInput component, the 'inputInvalid' property should be exported and passed to the Wrapper component to properly style the component's ring with red color when validation fails, similar to how the Input component handles validation states.
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/lib/dialog/Dialog.svelte
  • src/routes/color-test/+page.svelte
  • src/lib/drawer/Drawer.svelte
  • src/lib/card/Card.svelte
  • src/lib/drawer/DrawerHandle.svelte
  • src/lib/datepicker/Datepicker.svelte
  • src/lib/drawer/Drawerhead.svelte
📚 Learning: 2024-11-22T08:37:27.996Z
Learnt from: mrh1997
Repo: themesberg/flowbite-svelte PR: 1442
File: src/lib/utils/Popper.svelte:144-145
Timestamp: 2024-11-22T08:37:27.996Z
Learning: In `src/lib/utils/Popper.svelte`, inconsistencies in event handling (e.g., using both `mouseenter`/`mouseleave` and `pointerenter`/`pointerleave`) may be intentional to minimize modifications and reduce the risk of new problems.

Applied to files:

  • src/lib/drawer/Drawer.svelte
📚 Learning: 2024-11-12T10:36:34.807Z
Learnt from: LahTeuto
Repo: themesberg/flowbite-svelte PR: 1484
File: src/lib/navbar/NavLi.svelte:34-34
Timestamp: 2024-11-12T10:36:34.807Z
Learning: When enhancing ARIA roles in Svelte components, avoid setting `role="presentation"` on elements that should retain the `link` role, as it can diminish ARIA role coverage and negatively affect accessibility.

Applied to files:

  • src/lib/card/Card.svelte
📚 Learning: 2024-10-15T22:41:47.429Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1464
File: src/routes/component-data/Datepicker.json:0-0
Timestamp: 2024-10-15T22:41:47.429Z
Learning: The component should be named 'Datepicker' (with lowercase 'p') throughout the codebase to maintain consistency.

Applied to files:

  • src/lib/datepicker/Datepicker.svelte
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1465
File: src/lib/forms/Timepicker.svelte:105-116
Timestamp: 2024-10-18T09:38:03.879Z
Learning: In `Timepicker.svelte`, the `Dropdown` opens as intended and is used exclusively with the 'dropdown' and 'timerange-dropdown' Timepicker types.

Applied to files:

  • src/lib/datepicker/Datepicker.svelte
🧬 Code graph analysis (2)
src/routes/plugin-utilities.ts (1)
src/plugin-utilities.js (1)
  • colorUtilities (11-146)
src/lib/types.ts (5)
src/lib/utils/theme.ts (1)
  • CloseButtonVariants (5-5)
src/lib/badge/theme.ts (1)
  • BadgeVariants (5-5)
src/lib/banner/theme.ts (1)
  • BannerVariants (5-5)
src/lib/buttons/theme.ts (1)
  • GradientButtonVariants (5-5)
src/lib/carousel/theme.ts (3)
  • CarouselIndicatorsVariants (5-5)
  • ControlButtonVariants (6-6)
  • ThumbnailsVariants (7-7)
🪛 Biome (2.1.2)
src/routes/layout.css

[error] 138-138: Duplicate font names are redundant and unnecessary: Segoe

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)

🔇 Additional comments (17)
clear-cache.sh (1)

4-12: LGTM! Clean and functional cache-clearing script.

The implementation is straightforward and appropriate:

  • Clear progress messages for the user
  • Lightweight error handling with fallback warnings
  • Safe, hardcoded paths for cache directories
  • Helpful final instruction to restart the dev server
src/lib/card/Card.svelte (3)

1-7: LGTM: Props correctly aligned with updated CardProps interface.

The addition of hoverable and imgAlt props matches the type definition changes in src/lib/types.ts. The getTheme import follows the established theme integration pattern.


9-22: Correct reactive theme usage following established patterns.

The $derived expressions for both styling and theme ensure reactivity to prop and theme changes. Passing hoverable to the card() function enables hover-specific styling variants.

Based on learnings, theme access via getTheme must be inside $derived() for reactive theme updates, which is correctly implemented here.


25-72: Well-implemented accessibility and documentation updates.

The empty string fallback for imgAlt on line 30 correctly handles decorative images per WCAG guidelines. The image class composition on line 28 properly merges theme-level and user-provided styling. Documentation accurately reflects the updated prop surface.

src/lib/drawer/Drawerhead.svelte (2)

9-10: LGTM! Proper reactive theme derivation.

The use of $derived() for both styling and theme ensures these values react to changes in classes and theme context, following the established pattern for reactive theming in this codebase. Based on learnings, placing getTheme() inside $derived() is the correct approach for ThemeProvider compatibility.


22-23: LGTM! Clean theme-aware class composition.

The combination of theme-level classes (theme?.button, theme?.svg) with component-level styling overrides (styling?.button, styling?.svg) provides a flexible theming mechanism. This aligns with the broader API consolidation described in the PR summary.

src/lib/drawer/DrawerHandle.svelte (2)

11-11: LGTM! Consistent styling derivation pattern.

The derived styling follows the same pattern established across drawer components, enabling unified class-based theming through the classes prop.


18-18: LGTM! Theme-aware handle styling.

The handle span properly combines theme defaults with component-specific styling overrides, maintaining consistency with the refactored drawer family.

src/lib/drawer/Drawer.svelte (1)

11-25: Implementation correctly handles v2 migration with proper deprecation strategy.

The component includes runtime deprecation warnings that alert developers when hidden or activateClickOutside are used, directing them to use open and outsideclose respectively. The TypeScript type definition marks both deprecated props with JSDoc @deprecated annotations noting they will be removed in the next minor version.

The inline JSDoc documentation (lines 120-135) intentionally includes the deprecated props to document the full API surface during the transition period. This gradual deprecation approach is appropriate for v2 migration and helps existing users understand the migration path.

src/routes/color-test/+page.svelte (4)

2-30: LGTM!

The color array definition is well-structured, placing the new semantic tokens (brand, danger, success, warning, dark, neutral) first, which aligns with the PR's migration goals.


32-34: LGTM!

The border sizes array and derived ColorName type are correctly implemented using TypeScript's indexed access type pattern.


65-93: Background color mapping follows consistent pattern.

The background color classes maintain consistency with the border/text mapping:

  • Semantic colors use -soft suffix (except neutral which uses -primary)
  • Traditional colors use the -100 shade

36-64: Verify semantic color tokens are defined in the Tailwind v4 theme.

The colorClasses mapping uses custom semantic color tokens (e.g., border-brand, text-brand-soft, border-neutral-primary, text-neutral-primary) that require explicit @theme definitions. In Tailwind v4, theme variables are special CSS variables defined using the @theme directive that influence which utility classes exist in your project. Ensure each referenced token is defined in your CSS @theme block:

  • --color-brand, --color-brand-soft
  • --color-danger, --color-danger-soft
  • --color-success, --color-success-soft
  • --color-warning, --color-warning-soft
  • --color-dark, --color-dark-soft
  • --color-neutral-primary

Without these definitions, Tailwind will not generate the corresponding utility classes, and these styles will fail at runtime.

src/lib/datepicker/Datepicker.svelte (1)

469-472: The hardcoded bg-brand text-white styling works as intended since bg-brand is properly defined in the project's plugin utilities. However, consider using the Button's color prop dynamically for better consistency—currently the button passes color="alternative" but overrides it with bg-brand classes, creating a visual state mismatch between selected and unselected months. A cleaner approach would pass the appropriate color value through the color prop instead of mixing class overrides.

Likely an incorrect or invalid review comment.

src/routes/layout.css (3)

41-91: Well-structured theming foundation with clear customization guidance.

The @theme block effectively defines custom color palettes (primary/secondary) and provides clear, documented override points for brand colors, foreground text, and borders. The commented examples (lines 76-90) make it easy for developers to customize the theme.


232-252: Comprehensive CSS variable definitions for Tiptap editor.

The :root variables establish a solid color system for the WYSIWYG editor with semantic naming (--black, --gray-*, --purple, --yellow, --red, etc.) and include the --red-dark variable that was previously missing (line 250), properly addressing the past review comment.


126-140: Remove duplicate font name from font-family stack.

The font-family declaration includes "Segoe UI" twice (lines 131 and 132), which is redundant.

🔎 Proposed fix
   html {
     -webkit-text-size-adjust: 100%;
     font-family:
       Inter,
       ui-sans-serif,
       system-ui,
       -apple-system,
-      Segoe UI,
       Roboto,
       Helvetica Neue,
       Arial,
       Noto Sans,
       sans-serif,
       Apple Color Emoji,
       Segoe UI Emoji,
       Segoe UI Symbol,
       Noto Color Emoji;
     line-height: 1.5;
     -moz-tab-size: 4;
     tab-size: 4;
   }

Note: "Segoe UI" is already covered by the system font keywords "system-ui" and "-apple-system", and will be included via "Segoe UI Emoji" and "Segoe UI Symbol" for emoji/symbol fallbacks.

Based on static analysis hints.

Likely an incorrect or invalid review comment.

Comment on lines 1 to 300
import plugin, { type PluginCreator } from "tailwindcss/plugin";

/**
* Flowbite Utilities Plugin for Tailwind CSS v4
*
* This plugin generates utility classes for Flowbite's custom color variables.
* In Tailwind v4, CSS custom properties defined in @theme are not automatically
* converted to utility classes, so this plugin explicitly creates them.
*/
const flowbitePlugin = plugin(function ({ addUtilities }) {
const colorUtilities = {
// ===========================
// TEXT/BODY COLORS
// ===========================
".text-body": { color: "var(--color-body)" },
".text-body-subtle": { color: "var(--color-body-subtle)" },
".text-heading": { color: "var(--color-heading)" },

// ===========================
// NEUTRAL COLORS
// ===========================
// Neutral Primary
".bg-neutral-primary-soft": { backgroundColor: "var(--color-neutral-primary-soft)" },
".bg-neutral-primary": { backgroundColor: "var(--color-neutral-primary)" },
".bg-neutral-primary-medium": { backgroundColor: "var(--color-neutral-primary-medium)" },
".bg-neutral-primary-strong": { backgroundColor: "var(--color-neutral-primary-strong)" },

".text-neutral-primary-soft": { color: "var(--color-neutral-primary-soft)" },
".text-neutral-primary": { color: "var(--color-neutral-primary)" },
".text-neutral-primary-medium": { color: "var(--color-neutral-primary-medium)" },
".text-neutral-primary-strong": { color: "var(--color-neutral-primary-strong)" },

".border-neutral-primary-soft": { borderColor: "var(--color-neutral-primary-soft)" },
".border-neutral-primary": { borderColor: "var(--color-neutral-primary)" },
".border-neutral-primary-medium": { borderColor: "var(--color-neutral-primary-medium)" },
".border-neutral-primary-strong": { borderColor: "var(--color-neutral-primary-strong)" },

// Neutral Secondary
".bg-neutral-secondary-soft": { backgroundColor: "var(--color-neutral-secondary-soft)" },
".bg-neutral-secondary": { backgroundColor: "var(--color-neutral-secondary)" },
".bg-neutral-secondary-medium": { backgroundColor: "var(--color-neutral-secondary-medium)" },
".bg-neutral-secondary-strong": { backgroundColor: "var(--color-neutral-secondary-strong)" },
".bg-neutral-secondary-strongest": { backgroundColor: "var(--color-neutral-secondary-strongest)" },

".text-neutral-secondary-soft": { color: "var(--color-neutral-secondary-soft)" },
".text-neutral-secondary": { color: "var(--color-neutral-secondary)" },
".text-neutral-secondary-medium": { color: "var(--color-neutral-secondary-medium)" },
".text-neutral-secondary-strong": { color: "var(--color-neutral-secondary-strong)" },
".text-neutral-secondary-strongest": { color: "var(--color-neutral-secondary-strongest)" },

".border-neutral-secondary-soft": { borderColor: "var(--color-neutral-secondary-soft)" },
".border-neutral-secondary": { borderColor: "var(--color-neutral-secondary)" },
".border-neutral-secondary-medium": { borderColor: "var(--color-neutral-secondary-medium)" },
".border-neutral-secondary-strong": { borderColor: "var(--color-neutral-secondary-strong)" },
".border-neutral-secondary-strongest": { borderColor: "var(--color-neutral-secondary-strongest)" },

// Neutral Tertiary
".bg-neutral-tertiary-soft": { backgroundColor: "var(--color-neutral-tertiary-soft)" },
".bg-neutral-tertiary": { backgroundColor: "var(--color-neutral-tertiary)" },
".bg-neutral-tertiary-medium": { backgroundColor: "var(--color-neutral-tertiary-medium)" },

".text-neutral-tertiary-soft": { color: "var(--color-neutral-tertiary-soft)" },
".text-neutral-tertiary": { color: "var(--color-neutral-tertiary)" },
".text-neutral-tertiary-medium": { color: "var(--color-neutral-tertiary-medium)" },

".border-neutral-tertiary-soft": { borderColor: "var(--color-neutral-tertiary-soft)" },
".border-neutral-tertiary": { borderColor: "var(--color-neutral-tertiary)" },
".border-neutral-tertiary-medium": { borderColor: "var(--color-neutral-tertiary-medium)" },

// Neutral Quaternary
".bg-neutral-quaternary": { backgroundColor: "var(--color-neutral-quaternary)" },
".bg-neutral-quaternary-medium": { backgroundColor: "var(--color-neutral-quaternary-medium)" },

".text-neutral-quaternary": { color: "var(--color-neutral-quaternary)" },
".text-neutral-quaternary-medium": { color: "var(--color-neutral-quaternary-medium)" },

".border-neutral-quaternary": { borderColor: "var(--color-neutral-quaternary)" },
".border-neutral-quaternary-medium": { borderColor: "var(--color-neutral-quaternary-medium)" },

// Gray
".bg-gray": { backgroundColor: "var(--color-gray)" },
".text-gray": { color: "var(--color-gray)" },
".border-gray": { borderColor: "var(--color-gray)" },

// ===========================
// BORDER COLORS
// ===========================
// Buffer
".bg-buffer": { backgroundColor: "var(--color-buffer)" },
".bg-buffer-medium": { backgroundColor: "var(--color-buffer-medium)" },
".bg-buffer-strong": { backgroundColor: "var(--color-buffer-strong)" },

".text-buffer": { color: "var(--color-buffer)" },
".text-buffer-medium": { color: "var(--color-buffer-medium)" },
".text-buffer-strong": { color: "var(--color-buffer-strong)" },

".border-buffer": { borderColor: "var(--color-buffer)" },
".border-buffer-medium": { borderColor: "var(--color-buffer-medium)" },
".border-buffer-strong": { borderColor: "var(--color-buffer-strong)" },

// Muted
".bg-muted": { backgroundColor: "var(--color-muted)" },
".text-muted": { color: "var(--color-muted)" },
".border-muted": { borderColor: "var(--color-muted)" },

// Light
".bg-light-subtle": { backgroundColor: "var(--color-light-subtle)" },
".bg-light": { backgroundColor: "var(--color-light)" },
".bg-light-medium": { backgroundColor: "var(--color-light-medium)" },

".text-light-subtle": { color: "var(--color-light-subtle)" },
".text-light": { color: "var(--color-light)" },
".text-light-medium": { color: "var(--color-light-medium)" },

".border-light-subtle": { borderColor: "var(--color-light-subtle)" },
".border-light": { borderColor: "var(--color-light)" },
".border-light-medium": { borderColor: "var(--color-light-medium)" },

// Default
".bg-default-subtle": { backgroundColor: "var(--color-default-subtle)" },
".bg-default": { backgroundColor: "var(--color-default)" },
".bg-default-medium": { backgroundColor: "var(--color-default-medium)" },
".bg-default-strong": { backgroundColor: "var(--color-default-strong)" },

".text-default-subtle": { color: "var(--color-default-subtle)" },
".text-default": { color: "var(--color-default)" },
".text-default-medium": { color: "var(--color-default-medium)" },
".text-default-strong": { color: "var(--color-default-strong)" },

".border-default-subtle": { borderColor: "var(--color-default-subtle)" },
".border-default": { borderColor: "var(--color-default)" },
".border-default-medium": { borderColor: "var(--color-default-medium)" },
".border-default-strong": { borderColor: "var(--color-default-strong)" },

// ===========================
// SUCCESS COLORS
// ===========================
".bg-success-soft": { backgroundColor: "var(--color-success-soft)" },
".bg-success": { backgroundColor: "var(--color-success)" },
".bg-success-medium": { backgroundColor: "var(--color-success-medium)" },
".bg-success-strong": { backgroundColor: "var(--color-success-strong)" },

".text-success-soft": { color: "var(--color-success-soft)" },
".text-success": { color: "var(--color-success)" },
".text-success-medium": { color: "var(--color-success-medium)" },
".text-success-strong": { color: "var(--color-success-strong)" },

".border-success-soft": { borderColor: "var(--color-success-soft)" },
".border-success": { borderColor: "var(--color-success)" },
".border-success-medium": { borderColor: "var(--color-success-medium)" },
".border-success-strong": { borderColor: "var(--color-success-strong)" },
".border-success-subtle": { borderColor: "var(--color-success-subtle)" },

".ring-success-subtle": { "--tw-ring-color": "var(--color-success-subtle)" },

// ===========================
// DANGER COLORS
// ===========================
".bg-danger-soft": { backgroundColor: "var(--color-danger-soft)" },
".bg-danger": { backgroundColor: "var(--color-danger)" },
".bg-danger-medium": { backgroundColor: "var(--color-danger-medium)" },
".bg-danger-strong": { backgroundColor: "var(--color-danger-strong)" },

".text-danger-soft": { color: "var(--color-danger-soft)" },
".text-danger": { color: "var(--color-danger)" },
".text-danger-medium": { color: "var(--color-danger-medium)" },
".text-danger-strong": { color: "var(--color-danger-strong)" },

".border-danger-soft": { borderColor: "var(--color-danger-soft)" },
".border-danger": { borderColor: "var(--color-danger)" },
".border-danger-medium": { borderColor: "var(--color-danger-medium)" },
".border-danger-strong": { borderColor: "var(--color-danger-strong)" },
".border-danger-subtle": { borderColor: "var(--color-danger-subtle)" },

".ring-danger-subtle": { "--tw-ring-color": "var(--color-danger-subtle)" },

// ===========================
// WARNING COLORS
// ===========================
".bg-warning-soft": { backgroundColor: "var(--color-warning-soft)" },
".bg-warning": { backgroundColor: "var(--color-warning)" },
".bg-warning-medium": { backgroundColor: "var(--color-warning-medium)" },
".bg-warning-strong": { backgroundColor: "var(--color-warning-strong)" },

".text-warning-soft": { color: "var(--color-warning-soft)" },
".text-warning": { color: "var(--color-warning)" },
".text-warning-medium": { color: "var(--color-warning-medium)" },
".text-warning-strong": { color: "var(--color-warning-strong)" },

".border-warning-soft": { borderColor: "var(--color-warning-soft)" },
".border-warning": { borderColor: "var(--color-warning)" },
".border-warning-medium": { borderColor: "var(--color-warning-medium)" },
".border-warning-strong": { borderColor: "var(--color-warning-strong)" },
".border-warning-subtle": { borderColor: "var(--color-warning-subtle)" },

".ring-warning-subtle": { "--tw-ring-color": "var(--color-warning-subtle)" },

// ===========================
// DARK COLORS
// ===========================
".bg-dark-soft": { backgroundColor: "var(--color-dark-soft)" },
".bg-dark": { backgroundColor: "var(--color-dark)" },
".bg-dark-strong": { backgroundColor: "var(--color-dark-strong)" },
".bg-dark-backdrop": { backgroundColor: "var(--color-dark-backdrop)" },
".bg-disabled": { backgroundColor: "var(--color-disabled)" },

".text-dark-soft": { color: "var(--color-dark-soft)" },
".text-dark": { color: "var(--color-dark)" },
".text-dark-strong": { color: "var(--color-dark-strong)" },
".text-dark-backdrop": { color: "var(--color-dark-backdrop)" },
".text-disabled": { color: "var(--color-disabled)" },

".border-dark-soft": { borderColor: "var(--color-dark-soft)" },
".border-dark": { borderColor: "var(--color-dark)" },
".border-dark-strong": { borderColor: "var(--color-dark-strong)" },
".border-dark-subtle": { borderColor: "var(--color-dark-subtle)" },
".border-dark-backdrop": { borderColor: "var(--color-dark-backdrop)" },

".ring-dark-subtle": { "--tw-ring-color": "var(--color-dark-subtle)" },

// ===========================
// BRAND COLORS
// ===========================
".bg-brand-softer": { backgroundColor: "var(--color-brand-softer)" },
".bg-brand-soft": { backgroundColor: "var(--color-brand-soft)" },
".bg-brand": { backgroundColor: "var(--color-brand)" },
".bg-brand-medium": { backgroundColor: "var(--color-brand-medium)" },
".bg-brand-strong": { backgroundColor: "var(--color-brand-strong)" },

".text-brand-softer": { color: "var(--color-brand-softer)" },
".text-brand-soft": { color: "var(--color-brand-soft)" },
".text-brand": { color: "var(--color-brand)" },
".text-brand-medium": { color: "var(--color-brand-medium)" },
".text-brand-strong": { color: "var(--color-brand-strong)" },

".border-brand-softer": { borderColor: "var(--color-brand-softer)" },
".border-brand-soft": { borderColor: "var(--color-brand-soft)" },
".border-brand": { borderColor: "var(--color-brand)" },
".border-brand-medium": { borderColor: "var(--color-brand-medium)" },
".border-brand-strong": { borderColor: "var(--color-brand-strong)" },
".border-brand-subtle": { borderColor: "var(--color-brand-subtle)" },
".border-brand-light": { borderColor: "var(--color-brand-light)" },

".ring-brand-subtle": { "--tw-ring-color": "var(--color-brand-subtle)" },

// ===========================
// SINGLE COLORS
// ===========================
".bg-purple": { backgroundColor: "var(--color-purple)" },
".bg-sky": { backgroundColor: "var(--color-sky)" },
".bg-teal": { backgroundColor: "var(--color-teal)" },
".bg-pink": { backgroundColor: "var(--color-pink)" },
".bg-cyan": { backgroundColor: "var(--color-cyan)" },
".bg-fuchsia": { backgroundColor: "var(--color-fuchsia)" },
".bg-indigo": { backgroundColor: "var(--color-indigo)" },
".bg-orange": { backgroundColor: "var(--color-orange)" },

".text-purple": { color: "var(--color-purple)" },
".text-sky": { color: "var(--color-sky)" },
".text-teal": { color: "var(--color-teal)" },
".text-pink": { color: "var(--color-pink)" },
".text-cyan": { color: "var(--color-cyan)" },
".text-fuchsia": { color: "var(--color-fuchsia)" },
".text-indigo": { color: "var(--color-indigo)" },
".text-orange": { color: "var(--color-orange)" },

".border-purple": { borderColor: "var(--color-purple)" },
".border-sky": { borderColor: "var(--color-sky)" },
".border-teal": { borderColor: "var(--color-teal)" },
".border-pink": { borderColor: "var(--color-pink)" },
".border-cyan": { borderColor: "var(--color-cyan)" },
".border-fuchsia": { borderColor: "var(--color-fuchsia)" },
".border-indigo": { borderColor: "var(--color-indigo)" },
".border-orange": { borderColor: "var(--color-orange)" },

// ===========================
// FOREGROUND COLORS (text semantic colors)
// ===========================
".text-fg-brand-subtle": { color: "var(--color-fg-brand-subtle)" },
".text-fg-brand": { color: "var(--color-fg-brand)" },
".text-fg-brand-strong": { color: "var(--color-fg-brand-strong)" },
".text-fg-success": { color: "var(--color-fg-success)" },
".text-fg-success-strong": { color: "var(--color-fg-success-strong)" },
".text-fg-danger": { color: "var(--color-fg-danger)" },
".text-fg-danger-strong": { color: "var(--color-fg-danger-strong)" },
".text-fg-warning": { color: "var(--color-fg-warning)" },
".text-fg-warning-subtle": { color: "var(--color-fg-warning-subtle)" },
".text-fg-yellow": { color: "var(--color-fg-yellow)" },
".text-fg-disabled": { color: "var(--color-fg-disabled)" },
".text-fg-purple": { color: "var(--color-fg-purple)" },
".text-fg-cyan": { color: "var(--color-fg-cyan)" },
".text-fg-indigo": { color: "var(--color-fg-indigo)" },
".text-fg-pink": { color: "var(--color-fg-pink)" },
".text-fg-lime": { color: "var(--color-fg-lime)" }
};

addUtilities(colorUtilities);
} satisfies PluginCreator);

export default flowbitePlugin;
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 22, 2025

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

🏁 Script executed:

#!/bin/bash
# Search for plugin-utilities files
fd plugin-utilities -t f

Repository: themesberg/flowbite-svelte

Length of output: 222


🏁 Script executed:

#!/bin/bash
# Compare the three plugin-utilities files
echo "=== src/lib/plugin-utilities.ts ===" 
head -20 src/lib/plugin-utilities.ts

echo -e "\n=== src/plugin-utilities.js ===" 
head -20 src/plugin-utilities.js

echo -e "\n=== src/routes/plugin-utilities.ts ===" 
head -20 src/routes/plugin-utilities.ts

# Check if they are identical
echo -e "\n=== File sizes ==="
wc -l src/lib/plugin-utilities.ts src/plugin-utilities.js src/routes/plugin-utilities.ts

Repository: themesberg/flowbite-svelte

Length of output: 2773


🏁 Script executed:

#!/bin/bash
# Check layout.css around line 22
echo "=== layout.css around line 22 ==="
sed -n '15,30p' src/routes/layout.css

echo -e "\n=== Check if plugin import is commented ==="
grep -n "plugin" src/routes/layout.css

Repository: themesberg/flowbite-svelte

Length of output: 833


🏁 Script executed:

#!/bin/bash
# Check the sync script
echo "=== sync-plugin-utilities-export.sh ==="
cat scripts/sync-plugin-utilities-export.sh

echo -e "\n\n=== Searching for actual usage of custom color utilities in components ==="
# Search for usage of the custom color utilities in components
rg -n '(bg|text|border|ring)-(success|danger|warning|brand|dark|neutral|buffer|muted|light|default|fg)' --type svelte --type tsx --type ts -C 1 | head -80

Repository: themesberg/flowbite-svelte

Length of output: 1034


🏁 Script executed:

#!/bin/bash
# Check what ./@plugin "./plugin-utilities" actually resolves to
echo "=== Directory structure around layout.css ==="
ls -la src/routes/*.ts src/routes/*.js 2>/dev/null | head -20

echo -e "\n=== Check if plugin-utilities.ts exists in routes ==="
ls -la src/routes/plugin-utilities.ts

echo -e "\n=== Check what plugin-utilities is being imported as ==="
file src/routes/plugin-utilities.ts

Repository: themesberg/flowbite-svelte

Length of output: 684


🏁 Script executed:

#!/bin/bash
# Compare full content of src/lib and src/routes versions
echo "=== Checking if src/lib/plugin-utilities.ts and src/routes/plugin-utilities.ts are identical ==="
diff src/lib/plugin-utilities.ts src/routes/plugin-utilities.ts
echo "Diff exit code: $?"

echo -e "\n=== Checking content of src/plugin-utilities.js ==="
wc -l src/plugin-utilities.js
tail -5 src/plugin-utilities.js

echo -e "\n=== Comparing lines in src/plugin-utilities.js vs src/lib/plugin-utilities.ts ==="
echo "JS version line 1:"
head -1 src/plugin-utilities.js
echo "TS version line 1:"
head -1 src/lib/plugin-utilities.ts

Repository: themesberg/flowbite-svelte

Length of output: 589


🏁 Script executed:

#!/bin/bash
# Compare the JS and TS versions line by line
echo "=== Comparing src/plugin-utilities.js vs src/lib/plugin-utilities.ts ==="
echo "Lines in JS: $(wc -l < src/plugin-utilities.js)"
echo "Lines in TS lib: $(wc -l < src/lib/plugin-utilities.ts)"

echo -e "\n=== First 50 lines of JS version ==="
head -50 src/plugin-utilities.js | tail -40

echo -e "\n=== First 50 lines of TS version ==="
head -50 src/lib/plugin-utilities.ts | tail -40

echo -e "\n=== Last 10 lines of JS version ==="
tail -10 src/plugin-utilities.js

echo -e "\n=== Last 10 lines of TS version ==="
tail -10 src/lib/plugin-utilities.ts

Repository: themesberg/flowbite-svelte

Length of output: 5537


🏁 Script executed:

#!/bin/bash
# Check package.json and build configuration
echo "=== Checking package.json for build steps ==="
jq '.scripts' package.json 2>/dev/null || grep -A 5 "scripts" package.json | head -20

echo -e "\n=== Check tailwind.config ==="
find . -maxdepth 2 -name "tailwind.config.*" -type f

echo -e "\n=== Check what's in tailwind.config.ts ==="
grep -A 5 -B 5 "plugin" tailwind.config.ts | head -30

Repository: themesberg/flowbite-svelte

Length of output: 1614


🏁 Script executed:

#!/bin/bash
# Check if src/routes/plugin-utilities resolves correctly
echo "=== Check if @plugin can resolve to ./plugin-utilities.ts from layout.css ==="
pwd
ls -la src/routes/plugin-utilities.ts

echo -e "\n=== tailwind.config.ts shows it loads from src/lib/plugin-utilities ==="
grep -n "plugin" tailwind.config.ts

echo -e "\n=== Check tsconfig and vite config to understand module resolution ==="
grep -A 3 "resolve" vite.config.ts 2>/dev/null | head -15

echo -e "\n=== Also check if src/lib/plugin-utilities exports a .d.ts file ==="
ls -la src/lib/plugin-utilities*

Repository: themesberg/flowbite-svelte

Length of output: 810


🏁 Script executed:

#!/bin/bash
# Search for actual usage of the custom color utilities
echo "=== Comprehensive search for color utility usage in .svelte files ==="
rg '(bg|text|border|ring)-(success|danger|warning|brand|dark|neutral|buffer|muted|light|default|fg|body|purple|sky|teal|pink|cyan|fuchsia|indigo|orange|gray)' src/lib/components --type svelte -c | head -30

Repository: themesberg/flowbite-svelte

Length of output: 187


🏁 Script executed:

#!/bin/bash
echo "=== FINAL VERIFICATION SUMMARY ==="
echo "1. File inventory:"
echo "   - src/lib/plugin-utilities.ts: EXISTS (1009 lines, TypeScript)"
echo "   - src/lib/plugin-utilities.d.ts: EXISTS (1009 lines, declaration file)"
echo "   - src/routes/plugin-utilities.ts: EXISTS (1000 lines, TypeScript)"
echo "   - src/plugin-utilities.js: EXISTS (280 lines, JavaScript, older version)"
echo ""

echo "2. Plugin usage:"
grep -n "@plugin\|plugins:" src/routes/layout.css tailwind.config.ts

echo -e "\n3. File sizes comparison:"
wc -l src/lib/plugin-utilities.ts src/routes/plugin-utilities.ts src/plugin-utilities.js

echo -e "\n4. Content comparison - are lib and routes versions identical?"
cmp -s src/lib/plugin-utilities.ts src/routes/plugin-utilities.ts && echo "YES - Identical" || echo "NO - Different"

echo -e "\n5. Sync script exists:"
ls -la scripts/sync-plugin-utilities-export.sh

Repository: themesberg/flowbite-svelte

Length of output: 1038


🏁 Script executed:

#!/bin/bash
# Search for actual usage of the custom color utilities in components
echo "=== Search for usage of custom colors in source files ==="
find src/lib/components -type f \( -name "*.svelte" -o -name "*.ts" -o -name "*.tsx" \) | head -5 | while read f; do
  if grep -l "bg-success\|text-danger\|border-brand\|bg-neutral" "$f" 2>/dev/null; then
    echo "Found in: $f"
  fi
done

echo -e "\n=== Check for any imports of plugin-utilities ==="
grep -r "plugin-utilities" src/lib src/routes --include="*.ts" --include="*.tsx" --include="*.svelte" 2>/dev/null | head -10

echo -e "\n=== Check if utilities are in the compiled CSS output ==="
find . -name "*.css" -path "*/dist/*" -o -name "*.css" -path "*/.svelte-kit/*" 2>/dev/null | head -5

echo -e "\n=== Look for how tailwind is configured in package.json ==="
grep -A 5 -B 5 "tailwindcss" package.json 2>/dev/null | head -20

Repository: themesberg/flowbite-svelte

Length of output: 1149


🏁 Script executed:

#!/bin/bash
# Check the actual svelte.config.js for Tailwind setup
echo "=== Check svelte.config.ts/js ==="
find . -maxdepth 2 -name "svelte.config.*" -type f -exec cat {} \; 2>/dev/null | head -50

echo -e "\n=== Check PostCSS config ==="
cat postcss.config.js postcss.config.ts 2>/dev/null | head -30

echo -e "\n=== Look for tailwind.config in different locations ==="
find . -name "tailwind.config.*" -type f 2>/dev/null

echo -e "\n=== Check if there's a .tailwindrc or similar ==="
find . -maxdepth 2 -name ".tailwindrc*" -o -name "tailwind.config*" 2>/dev/null

Repository: themesberg/flowbite-svelte

Length of output: 1401


🏁 Script executed:

#!/bin/bash
echo "=== Direct byte/size comparison ==="
ls -la src/lib/plugin-utilities.ts src/routes/plugin-utilities.ts

echo -e "\n=== Check if they have the same content ==="
if diff -q src/lib/plugin-utilities.ts src/routes/plugin-utilities.ts > /dev/null 2>&1; then
  echo "Files are IDENTICAL"
else
  echo "Files are DIFFERENT"
  echo "Showing first difference:"
  diff src/lib/plugin-utilities.ts src/routes/plugin-utilities.ts | head -20
fi

echo -e "\n=== Verify tailwind.config.cjs loads the plugin ==="
grep -n "plugin" tailwind.config.cjs

Repository: themesberg/flowbite-svelte

Length of output: 452


Consolidate duplicate plugin files and remove the redundant CSS import comment.

Three versions of the plugin utilities exist with overlapping purposes:

  1. Duplicate TypeScript versions: src/lib/plugin-utilities.ts and src/routes/plugin-utilities.ts are identical in content (15,752 bytes each). Since tailwind.config.cjs already loads src/lib/plugin-utilities, the routes version is unnecessary—remove it or clarify its purpose.

  2. Outdated JavaScript file: src/plugin-utilities.js is an older, incomplete version (with export commented in src/lib/index.ts) that should be deleted.

  3. Redundant CSS comment: The @plugin "./plugin-utilities" import is commented out in layout.css line 22, but this is redundant since the plugin is already loaded via Tailwind configuration. Remove the commented line to avoid confusion.

The custom color utilities are functioning correctly through the Tailwind configuration and actively used in components (Badge, Button, Breadcrumb, etc.).

🤖 Prompt for AI Agents
In src/routes/plugin-utilities.ts lines 1-300: this file is a duplicate of
src/lib/plugin-utilities.ts and is redundant because tailwind.config.cjs already
loads the lib version; delete src/routes/plugin-utilities.ts (or merge any
unique changes into src/lib/plugin-utilities.ts), remove the outdated
src/plugin-utilities.js file, and delete the commented import line "@plugin
\"./plugin-utilities\"" from layout.css line 22 to avoid confusion.

Copy link
Collaborator Author

@shinokada shinokada Dec 23, 2025

Choose a reason for hiding this comment

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

fixed.

Copy link
Contributor

Choose a reason for hiding this comment

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

@shinokada, thanks for addressing the issues! I've noted that we'll skip the duplicate TypeScript file concern for now. The fixes for the outdated JavaScript file and the commented CSS import line are appreciated. Feel free to reach out if you need any further assistance with the remaining items later.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/forms/button-toggle/ButtonToggle.svelte (1)

80-97: Update documentation to match the simplified API.

The documentation still lists the removed props (iconClass, txtClass, contentClass) on lines 92-94, which are no longer part of the component's public API.

🔎 Proposed fix
 ## Props
 @prop value
 @prop selected = false
 @prop children
 @prop iconSlot
 @prop color
 @prop class: className
-@prop iconClass
-@prop txtClass
-@prop contentClass
 @prop classes
 @prop ...restProps
♻️ Duplicate comments (1)
src/lib/dialog/Dialog.svelte (1)

35-35: LGTM: Correct theme reactivity pattern.

The use of $derived(dialog()) with destructuring ensures that theme values (base, formCls, closeCls) react to dynamic changes from ThemeProvider. This aligns with the reactive theming pattern used throughout flowbite-svelte.

Based on learnings, this is the correct approach for components that rely on theme-derived values.

🧹 Nitpick comments (7)
src/lib/dialog/Dialog.svelte (1)

34-34: Consider simplifying the derived expression.

Since classes is a prop and props are already reactive in Svelte 5, wrapping it in $derived() is technically redundant. A simple assignment const styling = classes; would provide identical reactivity.

However, if this pattern is intentional for consistency across the codebase (as suggested by the broader refactoring), it's acceptable to keep as-is.

🔎 Alternative (if consistency is not required)
-  const styling = $derived(classes);
+  const styling = classes;
src/routes/utils/ThemeSelector.svelte (2)

23-26: Consider adding accessibility attributes for dropdown trigger.

The Button acts as a dropdown trigger but lacks aria-haspopup and aria-expanded attributes. If the Dropdown component doesn't automatically handle this pairing, consider adding them for better screen reader support.

🔎 Suggested accessibility improvement
-<Button color="alternative" class="gap-2 rounded-xl border-0 focus:ring-gray-100 dark:focus:ring-gray-700">
+<Button color="alternative" class="gap-2 rounded-xl border-0 focus:ring-gray-100 dark:focus:ring-gray-700" aria-haspopup="true">

40-45: Consider using Tailwind's arbitrary value syntax instead of global CSS.

The custom width can be achieved inline with Tailwind's arbitrary value syntax w-[1.125rem], avoiding the need for a global style override.

🔎 Suggested refactor

Replace the global style with inline arbitrary values:

-         <div class="h-3.5 w-4.5 {color} {index === 0 ? 'rounded-s-xs' : ''} {index === theme.colors.length - 1 ? 'rounded-e-xs' : ''}"></div>
+         <div class="h-3.5 w-[1.125rem] {color} {index === 0 ? 'rounded-s-xs' : ''} {index === theme.colors.length - 1 ? 'rounded-e-xs' : ''}"></div>

Then remove the <style> block entirely.

src/routes/utils/themeStore.svelte.ts (4)

3-11: ThemeId type is defined but not enforced on Theme.id.

The ThemeId union type is declared but Theme.id is typed as string. Consider using ThemeId for Theme.id to ensure type safety and catch mismatches at compile time.

🔎 Suggested type improvement
 export interface Theme {
-  id: string;
+  id: ThemeId;
   name: string;
   cssPath: string;
   fontUrl: string;
   colors: string[];
 }
-
-export type ThemeId = "default" | "minimal" | "enterprise" | "playful" | "mono";

Move the ThemeId type definition before the interface:

export type ThemeId = "default" | "minimal" | "enterprise" | "playful" | "mono";

export interface Theme {
  id: ThemeId;
  name: string;
  cssPath: string;
  fontUrl: string;
  colors: string[];
}

78-78: Remove or conditionally enable console.log statements for production.

Multiple console.log and console.warn calls (lines 78, 113, 119, 128, 133) will output to the browser console in production. Consider removing these or wrapping them in a development-only check.

🔎 Suggested approach

Option 1: Remove debug logs entirely for production:

-  console.log(`Loading theme: ${themeId}`);

Option 2: Use a development flag:

import { dev } from "$app/environment";

// Then wrap logs:
if (dev) console.log(`Loading theme: ${themeId}`);

97-102: Consider adding error handling for font loading.

The font link doesn't have an onerror handler like the theme CSS link does. While font loading failures are typically non-critical, adding error handling would provide consistent observability.

🔎 Suggested addition
   fontLink.href = theme.fontUrl;
+  fontLink.onerror = () => {
+    console.warn(`Failed to load font for theme ${themeId}`);
+  };
   document.head.appendChild(fontLink);

114-116: Forced reflow technique is valid but worth documenting.

Reading document.body.offsetHeight to force a reflow is a known technique, but the standalone expression may confuse future maintainers. The comment helps, but consider adding a brief explanation of why this is needed.

🔎 Suggested comment enhancement
     // Force a reflow to apply the new styles
+    // Reading offsetHeight triggers synchronous layout recalculation
     document.body.offsetHeight;
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4bd2a28 and 1aec1de.

📒 Files selected for processing (25)
  • clear-cache.sh
  • src/lib/carousel/theme.ts
  • src/lib/darkmode/DarkMode.svelte
  • src/lib/darkmode/theme.ts
  • src/lib/datepicker/Datepicker.svelte
  • src/lib/datepicker/theme.ts
  • src/lib/dialog/Dialog.svelte
  • src/lib/dropdown/DropdownItem.svelte
  • src/lib/footer/FooterBrand.svelte
  • src/lib/footer/FooterCopyright.svelte
  • src/lib/footer/FooterLink.svelte
  • src/lib/forms/button-toggle/ButtonToggle.svelte
  • src/lib/index.ts
  • src/lib/types.ts
  • src/routes/+layout.svelte
  • src/routes/admin-dashboard/utils/dashboard/Transactions.svelte
  • src/routes/blocks/utils/Footer.svelte
  • src/routes/color-test/+page.svelte
  • src/routes/docs-examples/components/datepicker/Color.svelte
  • src/routes/layout.css
  • src/routes/layouts/ComponentsLayout.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/routes/theme-test/+page.svelte
  • src/routes/utils/ThemeSelector.svelte
  • src/routes/utils/themeStore.svelte.ts
💤 Files with no reviewable changes (2)
  • src/routes/docs-examples/components/datepicker/Color.svelte
  • src/lib/index.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/routes/layout.css
  • src/routes/color-test/+page.svelte
  • clear-cache.sh
  • src/lib/datepicker/Datepicker.svelte
  • src/lib/datepicker/theme.ts
  • src/routes/+layout.svelte
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/routes/admin-dashboard/utils/dashboard/Transactions.svelte
  • src/routes/blocks/utils/Footer.svelte
  • src/routes/utils/themeStore.svelte.ts
  • src/lib/forms/button-toggle/ButtonToggle.svelte
  • src/routes/layouts/ComponentsLayout.svelte
  • src/lib/dialog/Dialog.svelte
  • src/lib/footer/FooterLink.svelte
  • src/routes/theme-test/+page.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/lib/footer/FooterCopyright.svelte
  • src/lib/darkmode/theme.ts
  • src/routes/utils/ThemeSelector.svelte
  • src/lib/footer/FooterBrand.svelte
  • src/lib/carousel/theme.ts
  • src/lib/dropdown/DropdownItem.svelte
  • src/lib/darkmode/DarkMode.svelte
  • src/lib/types.ts
🧠 Learnings (11)
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1465
File: src/lib/forms/Timepicker.svelte:105-116
Timestamp: 2024-10-18T09:38:03.879Z
Learning: In `Timepicker.svelte`, the `Dropdown` opens as intended and is used exclusively with the 'dropdown' and 'timerange-dropdown' Timepicker types.

Applied to files:

  • src/routes/admin-dashboard/utils/dashboard/Transactions.svelte
  • src/routes/utils/ThemeSelector.svelte
📚 Learning: 2024-10-15T22:41:47.429Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1464
File: src/routes/component-data/Datepicker.json:0-0
Timestamp: 2024-10-15T22:41:47.429Z
Learning: The component should be named 'Datepicker' (with lowercase 'p') throughout the codebase to maintain consistency.

Applied to files:

  • src/routes/admin-dashboard/utils/dashboard/Transactions.svelte
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/routes/admin-dashboard/utils/dashboard/Transactions.svelte
  • src/routes/blocks/utils/Footer.svelte
  • src/lib/forms/button-toggle/ButtonToggle.svelte
  • src/routes/layouts/ComponentsLayout.svelte
  • src/lib/dialog/Dialog.svelte
  • src/lib/footer/FooterLink.svelte
  • src/routes/theme-test/+page.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/lib/footer/FooterCopyright.svelte
  • src/routes/utils/ThemeSelector.svelte
  • src/lib/footer/FooterBrand.svelte
  • src/lib/dropdown/DropdownItem.svelte
  • src/lib/darkmode/DarkMode.svelte
📚 Learning: 2025-12-16T13:21:28.743Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:28.743Z
Learning: In flowbite-svelte, when using ThemeProvider with reactive themes, `getTheme("componentName")` calls must be placed inside `$derived()` expressions (not at module scope) to ensure components react to dynamic theme changes. This pattern is intentional for reactive theming support.

Applied to files:

  • src/routes/utils/themeStore.svelte.ts
📚 Learning: 2024-11-22T08:37:27.996Z
Learnt from: mrh1997
Repo: themesberg/flowbite-svelte PR: 1442
File: src/lib/utils/Popper.svelte:144-145
Timestamp: 2024-11-22T08:37:27.996Z
Learning: In `src/lib/utils/Popper.svelte`, inconsistencies in event handling (e.g., using both `mouseenter`/`mouseleave` and `pointerenter`/`pointerleave`) may be intentional to minimize modifications and reduce the risk of new problems.

Applied to files:

  • src/lib/forms/button-toggle/ButtonToggle.svelte
  • src/routes/layouts/ComponentsLayout.svelte
  • src/lib/dropdown/DropdownItem.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

Applied to files:

  • src/routes/theme-test/+page.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Use getComponentList tool to discover available Flowbite-Svelte components or help users explore component options

Applied to files:

  • src/routes/theme-test/+page.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/theme-test/+page.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use getComponentList tool to discover available Flowbite-Svelte components with their categories or to help users explore component options

Applied to files:

  • src/routes/theme-test/+page.svelte
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: Use searchDocs tool for full-text search across Flowbite-Svelte documentation when looking for specific information that might span multiple components or when users ask about features or patterns

Applied to files:

  • src/routes/theme-test/+page.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/theme-test/+page.svelte
🧬 Code graph analysis (2)
src/lib/carousel/theme.ts (1)
src/lib/theme/themeUtils.ts (1)
  • Classes (42-48)
src/lib/types.ts (6)
src/lib/utils/theme.ts (1)
  • CloseButtonVariants (5-5)
src/lib/badge/theme.ts (1)
  • BadgeVariants (5-5)
src/lib/banner/theme.ts (1)
  • BannerVariants (5-5)
src/lib/buttons/theme.ts (1)
  • GradientButtonVariants (5-5)
src/lib/carousel/theme.ts (3)
  • CarouselIndicatorsVariants (5-5)
  • ControlButtonVariants (6-6)
  • ThumbnailsVariants (7-7)
src/lib/footer/theme.ts (1)
  • FooterBrandVariants (17-17)
🔇 Additional comments (36)
src/routes/layouts/ComponentsLayout.svelte (1)

83-83: Positioning adjustment looks good.

The change from top-2 with mb-2 to top-0 without bottom margin tightens the SidebarButton's placement against the top edge. The responsive offset at md:top-4 is preserved, and the adjustment aligns with the broader UI refinements in this v2 update.

src/lib/darkmode/DarkMode.svelte (1)

42-49: LGTM! Light icon correctly uses dynamic sizing.

The light mode icon properly respects the size prop via class={sizes[size]} and the stroke attributes align with the design language shift to outlined icons.

src/lib/dialog/Dialog.svelte (1)

149-149: LGTM: Proper use of optional chaining with derived styling.

The optional chaining on styling?.close and styling?.form is defensive and correct, ensuring safe access to the styling properties. The class composition through theme functions (closeCls, formCls) properly integrates with the theme system.

Also applies to: 168-168

src/lib/forms/button-toggle/ButtonToggle.svelte (4)

7-7: LGTM: Import aligns with theme utility usage.

The getTheme import is correctly used on line 21 within a $derived() expression.


10-10: Verify breaking change is documented.

Removing iconClass, txtClass, and contentClass from the public API is a breaking change for existing consumers. Ensure this is:

  1. Documented in migration guides or release notes
  2. Communicated clearly to users upgrading to version 2

19-21: LGTM: Reactive theme and styling derivations.

Both derivations correctly use $derived() to ensure reactivity:

  • styling reacts to classes prop changes
  • theme properly reacts to theme provider changes per learnings

Based on learnings, this follows the established pattern for reactive theme-driven components.


66-74: LGTM: Safe optional chaining for styling fields.

The optional chaining (styling?.content, styling?.icon, styling?.text) correctly handles cases where the classes prop doesn't provide all styling fields, preventing potential runtime errors.

src/lib/darkmode/theme.ts (1)

4-4: Semantic color tokens are properly defined in the Flowbite theme configuration.

The semantic tokens (text-heading, text-body, bg-neutral-secondary-soft, ring-neutral-tertiary) used in the darkmode component are defined in static/themes/default.css via Tailwind CSS v4's @theme directive. They map correctly to CSS variables that are available in both light and dark modes. The test suite confirms the expected output matches.

src/lib/carousel/theme.ts (4)

5-7: LGTM!

The new variant types follow the established pattern from CarouselVariants and correctly combine VariantProps with Classes to enable both variant configuration and slot-level class overrides.


22-24: LGTM!

The new active and inactive slots provide extension points for consumers to customize indicator states via the classes prop, while the base indicator slot defines sensible defaults.


51-56: LGTM!

The structural change from a simple base string to a slots object is required for ThumbnailsVariants to work correctly with the Classes<T> type. The empty img slot provides a customization hook for thumbnail images.


11-11: No action needed – rounded-base is valid.

rounded-base is a semantic token provided by the Flowbite design system, which is imported in src/routes/layout.css via @import "flowbite/src/themes/default" and the @plugin "flowbite/plugin" directive. This token is defined and working correctly throughout the codebase, including in tests and multiple component themes.

src/routes/theme-test/+page.svelte (4)

1-47: Well-structured test page setup.

The imports and reactive state declarations are appropriate for a theme testing page. The reactive variables for form bindings follow Svelte 5 conventions correctly.


49-111: Typography and Buttons sections look good.

The component demonstrations cover a comprehensive set of button color variants including both filled and outline styles. The responsive grid layout is well implemented.


175-210: Form elements section demonstrates proper two-way binding.

The form elements section correctly uses bind:value and bind:checked for the various input types. The usage of {#each} for the Select options is idiomatic.


371-400: Good color palette visualization for theme testing.

The color palette section effectively demonstrates the primary color scale across light and dark modes, which is essential for theme verification.

src/routes/layouts/FlowbiteSvelteLayout.svelte (3)

10-10: ThemeSelector import added correctly.

The import is properly placed with other utility imports.


61-65: NavUl updated to use new classes prop pattern.

The multiline format improves readability, and the classes prop with nested ul key aligns with the v2 class-based theming API mentioned in the PR summary.


81-83: DarkMode and ThemeSelector placement looks appropriate.

The focus ring styling improves keyboard navigation visibility. ThemeSelector is positioned alongside other toolbar controls.

src/routes/utils/ThemeSelector.svelte (2)

8-9: Correct use of $derived for reactive theme state.

Using $derived() for currentTheme and selectedTheme ensures the component reacts to dynamic theme changes, which aligns with the established pattern for ThemeProvider reactivity. Based on learnings.


18-20: Remove the redundant onMount initialization.

The layout already calls loadTheme(getCurrentTheme()) on mount (line 12 of +layout.svelte), and this component's onMount calls the same function with the same value (the current theme from derived state). Theme updates are handled by handleThemeChange() for user interactions, making the onMount block unnecessary and causing duplicate theme initialization on every page load.

src/routes/utils/themeStore.svelte.ts (3)

51-61: Good defensive coding for localStorage access.

The getInitialTheme function properly handles both SSR (non-browser) and localStorage exceptions, with a sensible fallback to "default".


63-67: Correct usage of Svelte 5 runes for reactive state.

Using $state for currentTheme and $derived for selectedTheme is the correct pattern for reactive global state in Svelte 5.


136-145: Getter functions provide clean API for state access.

The exported getter functions (getCurrentTheme, getSelectedTheme) provide a clear API for consumers to access reactive state values.

src/lib/types.ts (4)

36-36: LGTM - Consistent variant imports.

The new variant imports follow the established pattern and support the modernized component prop interfaces.

Also applies to: 39-39, 42-42


202-211: LGTM - Accordion API modernization confirmed.

The dual API approach (legacy activeClass/inactiveClass + new classes object) aligns with the breaking change strategy for v2 discussed in previous review rounds.


287-290: Well-structured deprecation notices.

The JSDoc @deprecated annotations provide clear migration guidance for btnClassclass and spanClassclasses.span.


686-693: LGTM - FooterBrandProps modernized.

The interface cleanly adopts the variant-based pattern, removing per-element class props in favor of the unified classes approach.

src/lib/dropdown/DropdownItem.svelte (2)

8-12: LGTM - Proper reactive theme usage.

The getTheme("dropdownItem") call is correctly wrapped in $derived() for reactive theme updates, following the established pattern from learnings.


19-22: Clean class composition with safe optional chaining.

The finalClass and li class derivations properly combine theme and styling values with optional chaining, providing robust fallback behavior.

src/lib/footer/FooterCopyright.svelte (2)

8-12: LGTM - Consistent reactive theme pattern.

Props destructuring and derived values follow the established modernization pattern with proper reactive theme access.


19-29: Clean conditional rendering with unified styling.

The href conditional properly applies theme and styling to the appropriate elements (link vs bySpan) with safe optional chaining.

src/lib/footer/FooterLink.svelte (2)

7-13: LGTM - Proper component structure.

Props and derived values follow the modernized pattern correctly. The distinction between className (for <li>) and classes.link (for <a>) is clear.


16-20: Clean template with proper class distribution.

The className applies to the list item wrapper, while styling?.link applies to the anchor element, providing granular control over both elements.

src/lib/footer/FooterBrand.svelte (2)

7-12: LGTM - Consistent modernization pattern.

Props and derived theme values follow the established pattern with proper reactivity.


15-29: Well-structured conditional rendering.

The href conditional properly applies className to the base anchor wrapper, while styling?.img and styling?.span provide granular control over nested elements. Both rendering paths maintain consistency.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/lib/forms/button-toggle/ButtonToggle.svelte (1)

85-87: Remove deprecated props from documentation.

The documentation comments still list @prop iconClass, @prop txtClass, and @prop contentClass, but these props have been removed from the component interface in favor of the unified classes prop. Please update the documentation to reflect the current API.

🔎 Proposed fix
 @prop color
 @prop class: className
-@prop iconClass
-@prop txtClass
-@prop contentClass
 @prop classes
 @prop ...restProps
src/lib/forms/checkbox/theme.ts (1)

106-109: Mismatch between theme defaultVariants and component default.

The theme's defaultVariants.color is set to "primary", but Checkbox.svelte (line 10) defaults to "brand". This inconsistency could cause confusion or unexpected behavior when the component is used without an explicit color prop but relies on theme defaults elsewhere.

🔎 Proposed fix - align with component default
   defaultVariants: {
-    color: "primary",
+    color: "brand",
     disabled: false
   }
🧹 Nitpick comments (4)
src/lib/forms/button-toggle/ButtonToggle.svelte (1)

12-12: Simplify unnecessary $derived usage.

In Svelte 5, props are already reactive, so wrapping classes in $derived() without any transformation is redundant. You can simplify this to a direct assignment or use classes directly in the template.

🔎 Proposed simplification
-  const styling = $derived(classes);
+  const styling = classes;

Or use classes directly in lines 59, 64, 67 instead of going through styling.

src/lib/forms/checkbox/Checkbox.svelte (1)

26-26: Consider removing redundant $derived wrapper.

classes is already a reactive prop in Svelte 5, so wrapping it in $derived() doesn't add any reactivity benefit. This could be simplified to a direct reference.

🔎 Proposed simplification
-  const styling = $derived(classes);
+  const styling = classes;

Alternatively, if styling is only used to access styling?.label, you could inline the usage directly as classes?.label in lines 57 and 67.

convertThemes.js (1)

21-32: Consider adding error handling for file operations.

File I/O operations could fail due to permissions or disk space issues. Wrapping the file operations in try-catch blocks would make failures clearer.

🔎 Optional enhancement
 files.forEach((file) => {
   const inputPath = join(themesDir, file);
   const outputPath = join(themesDir, file.replace(".css", "-runtime.css"));
 
   console.log(`Converting ${file}...`);
 
-  const content = readFileSync(inputPath, "utf-8");
-  const converted = convertThemeFile(content);
-
-  writeFileSync(outputPath, converted);
-  console.log(`✓ Created ${file.replace(".css", "-runtime.css")}`);
+  try {
+    const content = readFileSync(inputPath, "utf-8");
+    const converted = convertThemeFile(content);
+    writeFileSync(outputPath, converted);
+    console.log(`✓ Created ${file.replace(".css", "-runtime.css")}`);
+  } catch (error) {
+    console.error(`✗ Failed to convert ${file}:`, error.message);
+  }
 });
src/routes/utils/themeStore.svelte.ts (1)

1-2: Combine duplicate imports from the same module.

Both imports are from $app/environment and can be combined into a single statement.

🔎 Proposed fix
-import { browser } from "$app/environment";
-import { dev } from "$app/environment";
+import { browser, dev } from "$app/environment";
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1aec1de and ceddcdf.

📒 Files selected for processing (33)
  • QUICK_START.md
  • THEME_SELECTOR_FIX.md
  • convertThemes.js
  • src/lib/darkmode/DarkMode.svelte
  • src/lib/forms/button-toggle/ButtonToggle.svelte
  • src/lib/forms/checkbox/Checkbox.svelte
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/dropzone/Dropzone.svelte
  • src/lib/forms/fileupload/Fileupload.svelte
  • src/lib/forms/fileupload/theme.ts
  • src/lib/forms/helper/theme.ts
  • src/lib/forms/input-addon/InputAddon.svelte
  • src/lib/forms/input-addon/index.ts
  • src/lib/forms/input-addon/theme.ts
  • src/lib/theme/themes.ts
  • src/lib/types.ts
  • src/routes/+layout.svelte
  • src/routes/blocks/utils/Footer.svelte
  • src/routes/color-test/+page.svelte
  • src/routes/docs-examples/components/popover/Password.svelte
  • src/routes/docs-examples/forms/checkbox/Alternative.svelte
  • src/routes/docs-examples/forms/checkbox/Bordered.svelte
  • src/routes/docs-examples/forms/checkbox/Default.svelte
  • src/routes/docs-examples/forms/checkbox/Disabled.svelte
  • src/routes/docs-examples/forms/checkbox/Horizontal.svelte
  • src/routes/docs-examples/forms/checkbox/Inline2.svelte
  • src/routes/docs-examples/forms/checkbox/ListGroup.svelte
  • src/routes/docs-examples/forms/checkbox/ListGroup2.svelte
  • src/routes/docs-examples/forms/input-field/Default.svelte
  • src/routes/docs-examples/utilities/label/Default.svelte
  • src/routes/docs/examples/testsnap.svelte
  • src/routes/utils/ThemeSelector.svelte
  • src/routes/utils/themeStore.svelte.ts
💤 Files with no reviewable changes (2)
  • src/routes/docs-examples/forms/checkbox/Disabled.svelte
  • src/routes/docs-examples/forms/checkbox/Default.svelte
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/routes/utils/ThemeSelector.svelte
  • src/lib/darkmode/DarkMode.svelte
  • src/routes/+layout.svelte
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/routes/docs-examples/forms/checkbox/Horizontal.svelte
  • src/lib/forms/input-addon/index.ts
  • src/lib/forms/input-addon/theme.ts
  • src/routes/docs-examples/forms/checkbox/ListGroup.svelte
  • src/routes/docs-examples/forms/checkbox/Inline2.svelte
  • src/lib/theme/themes.ts
  • src/routes/docs-examples/forms/checkbox/Bordered.svelte
  • src/routes/docs/examples/testsnap.svelte
  • src/routes/docs-examples/components/popover/Password.svelte
  • src/routes/utils/themeStore.svelte.ts
  • src/routes/docs-examples/forms/checkbox/ListGroup2.svelte
  • src/lib/forms/dropzone/Dropzone.svelte
  • src/lib/forms/fileupload/theme.ts
  • src/routes/color-test/+page.svelte
  • convertThemes.js
  • src/lib/forms/button-toggle/ButtonToggle.svelte
  • src/lib/forms/helper/theme.ts
  • src/routes/docs-examples/utilities/label/Default.svelte
  • src/routes/docs-examples/forms/input-field/Default.svelte
  • src/lib/forms/fileupload/Fileupload.svelte
  • src/routes/docs-examples/forms/checkbox/Alternative.svelte
  • src/routes/blocks/utils/Footer.svelte
  • src/lib/forms/checkbox/Checkbox.svelte
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/input-addon/InputAddon.svelte
  • src/lib/types.ts
🧠 Learnings (10)
📓 Common learnings
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:28.743Z
Learning: In flowbite-svelte, when using ThemeProvider with reactive themes, `getTheme("componentName")` calls must be placed inside `$derived()` expressions (not at module scope) to ensure components react to dynamic theme changes. This pattern is intentional for reactive theming support.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles, ensure both the container (with focus-within) and the inner input element (with direct focus) have dynamic styling based on the validation state. The input element needs its own focus styles that change to red when inputInvalid=true.
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/routes/docs-examples/forms/checkbox/Horizontal.svelte
  • src/routes/docs-examples/forms/checkbox/ListGroup.svelte
  • src/routes/docs-examples/forms/checkbox/Inline2.svelte
  • src/routes/docs-examples/forms/checkbox/Bordered.svelte
  • src/routes/docs/examples/testsnap.svelte
  • src/routes/docs-examples/components/popover/Password.svelte
  • src/routes/docs-examples/forms/checkbox/ListGroup2.svelte
  • src/lib/forms/dropzone/Dropzone.svelte
  • src/routes/color-test/+page.svelte
  • src/lib/forms/button-toggle/ButtonToggle.svelte
  • src/routes/docs-examples/utilities/label/Default.svelte
  • src/routes/docs-examples/forms/input-field/Default.svelte
  • src/lib/forms/fileupload/Fileupload.svelte
  • src/routes/docs-examples/forms/checkbox/Alternative.svelte
  • src/routes/blocks/utils/Footer.svelte
  • src/lib/forms/checkbox/Checkbox.svelte
  • src/lib/forms/input-addon/InputAddon.svelte
📚 Learning: 2025-03-20T11:11:53.953Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.953Z
Learning: In the Flowbite Svelte library's MultiInput component, the 'inputInvalid' property should be exported and passed to the Wrapper component to properly style the component's ring with red color when validation fails, similar to how the Input component handles validation states.

Applied to files:

  • src/lib/forms/input-addon/index.ts
  • src/lib/types.ts
📚 Learning: 2024-11-22T08:37:27.996Z
Learnt from: mrh1997
Repo: themesberg/flowbite-svelte PR: 1442
File: src/lib/utils/Popper.svelte:144-145
Timestamp: 2024-11-22T08:37:27.996Z
Learning: In `src/lib/utils/Popper.svelte`, inconsistencies in event handling (e.g., using both `mouseenter`/`mouseleave` and `pointerenter`/`pointerleave`) may be intentional to minimize modifications and reduce the risk of new problems.

Applied to files:

  • src/routes/docs-examples/components/popover/Password.svelte
  • src/lib/forms/button-toggle/ButtonToggle.svelte
📚 Learning: 2025-12-16T13:21:28.743Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:28.743Z
Learning: In flowbite-svelte, when using ThemeProvider with reactive themes, `getTheme("componentName")` calls must be placed inside `$derived()` expressions (not at module scope) to ensure components react to dynamic theme changes. This pattern is intentional for reactive theming support.

Applied to files:

  • src/routes/utils/themeStore.svelte.ts
📚 Learning: 2025-08-31T12:56:05.074Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1745
File: src/lib/types.ts:677-686
Timestamp: 2025-08-31T12:56:05.074Z
Learning: HTMLInputAttributes includes a `group` property that can be used for grouping form controls like checkboxes and radio buttons, so interfaces extending HTMLInputAttributes don't need to explicitly declare `group` unless they want to override its type.

Applied to files:

  • src/routes/docs-examples/forms/checkbox/ListGroup2.svelte
  • src/lib/forms/checkbox/Checkbox.svelte
  • src/lib/types.ts
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.

Applied to files:

  • src/lib/forms/fileupload/theme.ts
  • src/routes/docs-examples/forms/input-field/Default.svelte
  • src/lib/forms/input-addon/InputAddon.svelte
📚 Learning: 2025-08-31T14:31:57.582Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1745
File: src/lib/forms/checkbox/CheckboxButton.svelte:16-17
Timestamp: 2025-08-31T14:31:57.582Z
Learning: In Svelte 5, the `on:event` syntax for event forwarding is obsolete. Event handlers are passed as callback props (e.g., `onchange`, `oninput`) through `{...restProps}` instead of using `on:change`, `on:input` etc.

Applied to files:

  • src/routes/docs-examples/forms/input-field/Default.svelte
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/lib/forms/checkbox/theme.ts
📚 Learning: 2025-03-20T11:11:53.952Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.952Z
Learning: In the Flowbite Svelte library, when implementing components with validation states, the 'inputInvalid' property should be explicitly defined and passed to the Wrapper component. When inputInvalid=true, the color should be set to "red" to ensure the ring/border styling is applied correctly.

Applied to files:

  • src/lib/types.ts
🧬 Code graph analysis (2)
src/lib/forms/input-addon/theme.ts (3)
src/lib/forms/input-addon/index.ts (1)
  • inputAddon (2-2)
src/lib/theme/themes.ts (1)
  • inputAddon (52-52)
src/lib/theme/themeUtils.ts (1)
  • Classes (42-48)
src/lib/types.ts (7)
src/lib/utils/theme.ts (1)
  • CloseButtonVariants (5-5)
src/lib/badge/theme.ts (1)
  • BadgeVariants (5-5)
src/lib/banner/theme.ts (1)
  • BannerVariants (5-5)
src/lib/buttons/theme.ts (1)
  • GradientButtonVariants (5-5)
src/lib/carousel/theme.ts (3)
  • CarouselIndicatorsVariants (5-5)
  • ControlButtonVariants (6-6)
  • ThumbnailsVariants (7-7)
src/lib/footer/theme.ts (1)
  • FooterBrandVariants (17-17)
src/lib/forms/checkbox/theme.ts (1)
  • CheckboxVariants (112-112)
🪛 LanguageTool
THEME_SELECTOR_FIX.md

[style] ~116-~116: Consider using polite language here.
Context: ...eme selector should now work perfectly! Let me know if you need help with the conversion or...

(INSERT_PLEASE)

QUICK_START.md

[style] ~19-~19: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...reate playful-runtime.css - Mono: Need to create mono-runtime.css ## Quick Tes...

(REP_NEED_TO_VB)

🔇 Additional comments (40)
src/lib/forms/helper/theme.ts (2)

7-7: LGTM: Improved typography for better readability.

The change from text-xs to text-sm improves readability while maintaining the same color scheme. Removing the explicit font-normal is acceptable as it relies on the default font-weight.


9-31: Verify: Are legacy color tokens intentional here?

According to the PR summary, this migration aims to move from legacy color tokens (primary, secondary, etc.) to semantic tokens (brand, danger, success, warning, dark, neutral). Other theme files in this PR (alert, badge, buttons) have undergone this migration, but the helper component's color variants still use the legacy token names.

Is this intentional (helper text should maintain legacy tokens), or should these variants also be migrated to semantic tokens?

src/routes/blocks/utils/Footer.svelte (1)

50-50: LGTM: Correct margin application.

The change to use class="mb-4" correctly applies spacing to the <li> element rather than the <a> element, which is the appropriate semantic location for list item spacing. This aligns with the broader footer module updates to standardize class handling.

src/lib/forms/input-addon/InputAddon.svelte (1)

15-32: Correct reactive theming implementation.

The getTheme("inputAddon") call is properly wrapped in $derived() (line 15), ensuring the component reacts to dynamic theme changes from ThemeProvider. This follows the established pattern per the repository's learnings.

The Tailwind Variants integration is correctly implemented:

  • Variant selection based on size, background, and grouped context
  • Theme overrides properly merged via clsx(theme, className)
src/lib/forms/input-addon/index.ts (1)

1-2: LGTM!

The export structure correctly exposes both the component (InputAddon) and its theme configuration (inputAddon), consistent with other form component modules in the library.

src/lib/theme/themes.ts (1)

16-17: Expanded exports align with new components.

The theme exports are correctly updated to include:

  • New device mockups (defaultMockup, laptop, smartwatch)
  • Drawer head component (drawerhead)
  • Input addon theme (inputAddon)

The inputAddon export path (../forms/input-addon) correctly resolves via the barrel export in index.ts.

Also applies to: 52-52

src/lib/forms/input-addon/theme.ts (1)

1-34: Well-structured Tailwind Variants configuration.

The theme configuration follows the established patterns in the codebase with proper slot definitions, variant options, and default values. The type definition correctly combines VariantProps and Classes for full type safety. The not-first: pseudo-class is a validated pattern used consistently across multiple components in the project.

src/lib/forms/button-toggle/ButtonToggle.svelte (1)

31-31: No changes required. The default color token "primary" is valid in v2 and intentionally set as the default in the theme configuration. The referenced migration to semantic tokens does not apply to buttonToggle color variants.

src/routes/docs-examples/components/popover/Password.svelte (1)

24-24: Consistent with theme refactor pattern.

The migration of spacing classes from the div slot to the label slot aligns with the broader consolidation of Checkbox styling. The visual spacing behavior should remain equivalent.

src/lib/types.ts (2)

199-212: Well-structured API evolution with backward compatibility.

The addition of the classes object with granular slots (button, contentWrapper, content, active, inactive) alongside the existing activeClass/inactiveClass props provides improved customization while maintaining backward compatibility. The use of Partial and ClassValue ensures type safety.

As confirmed in previous discussions, the migration path for this breaking change will be documented in the version 2 announcement.


344-355: Context type properly aligned with props.

The AccordionContextType correctly mirrors the prop structure changes, ensuring consistent theming across the accordion component tree.

src/routes/docs-examples/utilities/label/Default.svelte (1)

6-6: Styling migration applied correctly.

The shift of spacing classes to the label slot is consistent with the repository-wide theme refactor.

src/routes/docs-examples/forms/checkbox/Alternative.svelte (1)

23-23: Label-based styling applied consistently.

The migration maintains the RTL-aware spacing while aligning with the new theme structure.

src/routes/docs-examples/forms/checkbox/ListGroup2.svelte (1)

14-14: Padding correctly applied to label element.

Moving padding to the label slot improves the clickable area for list group items while maintaining visual consistency.

src/routes/docs/examples/testsnap.svelte (1)

47-47: Theme refactor applied to snapshot example.

The styling migration maintains RTL support and proper spacing while aligning with the new theme structure. The snapshot functionality remains unaffected.

src/routes/docs-examples/forms/checkbox/Horizontal.svelte (1)

7-10: Consistent label-based padding across horizontal list.

All four checkbox instances correctly apply padding to the label slot, providing better click targets within the bordered horizontal layout.

src/routes/docs-examples/forms/input-field/Default.svelte (1)

44-46: Label-based styling applied to form example.

The migration to the label slot maintains RTL support and spacing. The gap-1 class will control spacing between the checkbox input and label text if the label is displayed as flex.

src/routes/docs-examples/forms/checkbox/ListGroup.svelte (1)

7-10: LGTM!

The migration from div-based to label-based styling is correctly applied. Using classes={{ label: "p-3" }} aligns with the updated Checkbox component API where the label slot now handles layout styling.

src/routes/docs-examples/forms/checkbox/Inline2.svelte (1)

5-8: LGTM!

The inline checkbox examples correctly demonstrate the updated classes={{ label: "me-2" }} pattern for spacing. The combination of inline prop with label-based margin classes aligns with the new theming approach.

src/routes/docs-examples/forms/checkbox/Bordered.svelte (1)

6-9: LGTM!

The bordered checkbox examples correctly apply width and padding via the label slot. The classes={{ label: "w-full p-4" }} pattern ensures the clickable label area fills the bordered container.

src/lib/forms/checkbox/Checkbox.svelte (2)

28-30: Correct reactive theme pattern.

The getTheme("checkbox") call is properly placed inside $derived(), ensuring the component reacts to dynamic theme changes. This aligns with the established pattern for ThemeProvider-based reactive theming. Based on learnings, this is the correct approach.


55-72: LGTM - Label-based styling migration is complete.

The template correctly applies labelStyle() to the Label component's class prop, replacing the previous div-based approach. Both the choices iteration branch (line 57) and the single checkbox branch (line 67) consistently use the new pattern.

src/lib/forms/checkbox/theme.ts (1)

6-7: Slot rename from div to label aligns with component changes.

The slots structure correctly renames div to label, matching the updated Checkbox.svelte implementation that now applies styling to the Label component.

src/lib/forms/fileupload/Fileupload.svelte (8)

6-6: LGTM: Theme utility import.

The import is correctly used with $derived() on line 13 for reactive theming.


9-9: LGTM: Consolidated class props.

The removal of individual class props (wrapperClass, clearableClass, clearableSvgClass) in favor of a unified classes object simplifies the component API and aligns with the broader refactoring in this PR.


11-11: LGTM: Reactive styling derivation.

The use of $derived(classes) ensures the styling updates reactively when the classes prop changes.


13-13: LGTM: Correct reactive theme pattern.

The $derived(getTheme("fileupload")) pattern ensures the component reacts to dynamic theme changes when using ThemeProvider. Based on learnings, this is the recommended approach for reactive theming in Flowbite-Svelte components.


17-27: LGTM: Clear functionality with defensive programming.

The clearAll function correctly:

  1. Clears the input element value (line 19)
  2. Dispatches a change event to trigger handleChange (lines 21-22)
  3. Defensively sets files = undefined (line 24) as a safeguard

While line 24 is technically redundant (since the dispatched event should trigger handleChange which sets files to undefined), this defensive approach ensures correctness even if the event handling doesn't work as expected.


30-33: LGTM: Explicit file change handling.

The explicit handleChange function provides better control over file updates compared to two-way binding. The ?? undefined fallback correctly handles the case when no files are selected.


38-38: LGTM: Clear button visibility logic.

The derived value correctly determines when to show the clear button based on the clearable prop and file presence.


41-45: LGTM: Template updates with theme integration.

The template correctly:

  • Applies theme-based classes to wrapper and input elements
  • Uses onchange={handleChange} for explicit file handling
  • Conditionally renders the clear button with appropriate props
  • Maintains proper class composition using clsx for theme and custom classes
QUICK_START.md (1)

1-110: Excellent documentation!

This quick start guide is well-structured and provides clear, actionable steps for theme setup and troubleshooting. The inclusion of the Google Sans Code font caveat (lines 56-64) is particularly helpful.

THEME_SELECTOR_FIX.md (1)

1-116: Clear and comprehensive documentation.

This document effectively explains the problem, solution, and implementation steps. The TypeScript example (lines 50-89) shows all themes using -runtime.css paths, which represents the desired end state after conversion.

src/routes/utils/themeStore.svelte.ts (3)

63-67: Correct use of Svelte 5 runes for reactive theming.

The state management pattern using $state for currentTheme and $derived for selectedTheme correctly implements reactive theming, ensuring the selected theme updates when currentTheme changes.

Based on learnings, this pattern aligns with the flowbite-svelte reactive theming approach.


69-129: Well-implemented theme loading with proper cleanup and error handling.

The function correctly:

  • Validates theme existence before loading
  • Removes all existing theme-related links to prevent conflicts
  • Handles font and CSS load failures gracefully
  • Forces style recalculation using offsetHeight (lines 104, 109)
  • Persists theme choice with localStorage error handling
  • Updates reactive state

The style recalculation technique (lines 106-110) using transition manipulation is a valid approach to ensure CSS variables are applied immediately.


46-46: Google Sans Code is publicly available on Google Fonts.

According to web sources, Google Sans Code is an open-source monospace font from Google (OFL 1.1 license) available on Google Fonts with variable font support (wght 300–800). The font URL in line 46 is correct and will load successfully. While QUICK_START.md contains a note suggesting it's proprietary, this information is outdated; the font is now public and no change is needed.

Likely an incorrect or invalid review comment.

src/lib/forms/dropzone/Dropzone.svelte (4)

12-12: LGTM: Correct reactive theme pattern.

The use of $derived(getTheme("dropzone")) correctly ensures the component reacts to dynamic theme changes. Based on learnings, this is the proper pattern for reactive theming with ThemeProvider.


39-46: LGTM: File picker changes handled correctly.

The handleChange implementation properly updates the files bindable prop when users select files through the file picker.


52-52: Note: Removed two-way file binding.

The removal of bind:files in favor of manual change handling is part of the broader file handling pattern change. This means updates to the files prop won't reflect in the input element. Ensure this aligns with your form submission strategy (see earlier comment about dropped files).


19-25: The current implementation is correct for the component's design. The Dropzone component is explicitly designed to expose files via the files binding prop, not through the hidden input element. The input element is hidden and serves as the UI control (for click-to-select), while the files binding is the primary interface for both drag-drop and file selection.

Form submissions should use the files binding, not the input element's files property. This is evident from:

  • The input element having class="hidden"
  • The documentation example only using bind:files, never accessing the input element
  • No form submission patterns or tests in the codebase

The comment "The input will be updated on next user interaction" is misleading wording, but it reflects the intentional design: the hidden input element is not meant to be programmatically synchronized with dropped files. The files binding is the sole public interface.

Likely an incorrect or invalid review comment.

Comment on lines 11 to 19
brand: {
base: "border border-default-medium bg-neutral-secondary-medium focus:ring-brand-soft"
},
alternative: {
base: "border border-default-medium bg-neutral-secondary-medium focus:ring-alternative-soft"
},
gray: {
base: "border border-default-medium bg-neutral-secondary-medium focus:ring-gray-soft"
},
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 23, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's find Tailwind config files
find . -name "tailwind.config.*" -o -name "tailwind.config.js" -o -name "tailwind.config.ts" | head -20

Repository: themesberg/flowbite-svelte

Length of output: 52


🏁 Script executed:

#!/bin/bash
# Search for the semantic token definitions mentioned in the review
rg -n "border-default-medium|neutral-secondary-medium|brand-soft|alternative-soft|gray-soft" --type=js --type=ts --type=css --type=json

Repository: themesberg/flowbite-svelte

Length of output: 10391


🏁 Script executed:

#!/bin/bash
# Search for alternative-soft and gray-soft definitions
rg -n "alternative-soft|gray-soft" --type=css --type=js --type=ts

Repository: themesberg/flowbite-svelte

Length of output: 334


🏁 Script executed:

#!/bin/bash
# Search for default-medium or border-default definitions  
rg -n "default-medium|border-default" --type=css --type=js --type=ts

Repository: themesberg/flowbite-svelte

Length of output: 4927


🏁 Script executed:

#!/bin/bash
# Find and check Tailwind config files
find . -type f -name "tailwind.config.*" -o -name "*tailwind*.config.*" | head -20

Repository: themesberg/flowbite-svelte

Length of output: 52


🏁 Script executed:

#!/bin/bash
# Broader search for alternative and gray variants
rg -n "alternative.*soft|gray.*soft" --type=css --type=ts --type=js

Repository: themesberg/flowbite-svelte

Length of output: 429


🏁 Script executed:

#!/bin/bash
# Check if these colors are defined under different naming patterns
rg -n "alternative-medium|alternative-darker|gray-medium|gray-darker|alternative-soft|gray-soft" --type=css

Repository: themesberg/flowbite-svelte

Length of output: 52


Add missing semantic color tokens alternative-soft and gray-soft to theme configuration.

The tokens brand-soft, default-medium, and neutral-secondary-medium are properly defined in static/themes/*.css, but the new variants reference focus:ring-alternative-soft and focus:ring-gray-soft which do not exist. These must be added to all theme files alongside existing color definitions.

🤖 Prompt for AI Agents
In src/lib/forms/checkbox/theme.ts around lines 11 to 19, the theme references
focus:ring-alternative-soft and focus:ring-gray-soft which are missing from the
static theme CSS; add semantic color token definitions named
--color-alternative-soft and --color-gray-soft (or follow the existing token
naming pattern used for brand-soft/default-medium/neutral-secondary-medium) to
every file in static/themes/*.css (both light and dark variants if present),
using consistent values and contrast levels consistent with brand-soft, then
rebuild/verify CSS to ensure focus:ring utility maps to the new tokens.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed.

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if alternative-soft and gray-soft tokens are now defined in theme CSS files
echo "=== Searching for alternative-soft token definitions ==="
rg -n "alternative-soft" static/themes/ --type=css 2>/dev/null || echo "No matches found for alternative-soft"

echo ""
echo "=== Searching for gray-soft token definitions ==="
rg -n "gray-soft" static/themes/ --type=css 2>/dev/null || echo "No matches found for gray-soft"

echo ""
echo "=== Listing theme CSS files for reference ==="
fd -e css . static/themes/ 2>/dev/null || find static/themes/ -name "*.css" 2>/dev/null

Length of output: 449


@shinokada, I've verified the fix but the semantic color tokens alternative-soft and gray-soft are still missing from the theme CSS files. The search found no matches for either token in the static/themes/ directory.

The checkbox theme in src/lib/forms/checkbox/theme.ts (lines 11-18) references:

  • focus:ring-brand-soft ✅ (exists)
  • focus:ring-alternative-soft ❌ (missing)
  • focus:ring-gray-soft ❌ (missing)

To complete the fix, you'll need to add CSS custom property definitions for these tokens to all theme files (default.css, default-runtime.css, enterprise.css, enterprise-runtime.css, minimal.css, mono.css, playful.css). For example:

@theme {
  --color-alternative-soft: <value>;
  --color-gray-soft: <value>;
}

Or if using :root:

:root {
  --color-alternative-soft: <value>;
  --color-gray-soft: <value>;
}

Could you please add these missing token definitions? They should follow the same pattern and contrast levels as the existing brand-soft token.


🧬 Code Graph Analysis Results

[src/lib/theme/themes.ts] (lines 46-46)
checkbox

[src/lib/theme/themes.ts] (lines 46-46)
checkboxButton

[src/lib/forms/checkbox/index.ts] (lines 3-3)
checkbox

[src/lib/forms/checkbox/index.ts] (lines 3-3)
checkboxButton

[src/lib/theme/themeUtils.ts] (lines 42-48)
export type Classes<T extends { slots: Record<string, unknown> }> = {
/**

  • Mapping of slot names to class values.
  • Each slot is optional and may be partially specified.
    */
    classes?: Partial<{ [K in keyof Slots]: ClassValue }>;
    };

🧠 Learnings used
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

tests(floating-label): unit tests
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/forms/floating-label/theme.ts (1)

5-5: Typo in type name: "Varatiants" should be "Variants".

This typo appears in the exported type name and propagates to the documentation in TROUBLESHOOTING.md.

🔎 Proposed fix
-export type FloatingLabelInputVaratiants = VariantProps<typeof floatingLabelInput> & Classes<typeof floatingLabelInput>;
+export type FloatingLabelInputVariants = VariantProps<typeof floatingLabelInput> & Classes<typeof floatingLabelInput>;

Note: This is a breaking change for any external code referencing this type. Consider whether to fix now or defer based on v2 migration strategy.

♻️ Duplicate comments (1)
src/lib/types.ts (1)

199-212: The classes object pattern for AccordionProps is well-structured.

The consolidated classes object alongside the legacy activeClass/inactiveClass props provides a clean API for customization. Per the previous discussion, breaking changes will be documented in the v2 announcement.

🧹 Nitpick comments (4)
src/routes/docs-examples/forms/floating-label/WithIcon.svelte (1)

6-13: Minor inconsistencies in the example.

  1. The id="exampleWrapper" is present here but was removed from Disabled.svelte in this same PR. Consider removing it for consistency.
  2. The classes={{ label: "inline-flex " }} has a trailing space that could be trimmed.
🔎 Proposed fix
-<div id="exampleWrapper" class="grid w-full items-end gap-6 md:grid-cols-3">
-  <FloatingLabelInput variant="filled" id="floating_filled" name="floating_filled" type="text" classes={{ label: "inline-flex " }}>
+<div class="grid w-full items-end gap-6 md:grid-cols-3">
+  <FloatingLabelInput variant="filled" id="floating_filled" name="floating_filled" type="text" classes={{ label: "inline-flex" }}>
     <EnvelopeOutline class="me-1.5 h-4 w-4" />Floating filled
   </FloatingLabelInput>
-  <FloatingLabelInput variant="outlined" id="floating_outlined" name="floating_outlined" type="text" classes={{ label: "inline-flex " }}>
+  <FloatingLabelInput variant="outlined" id="floating_outlined" name="floating_outlined" type="text" classes={{ label: "inline-flex" }}>
     <EnvelopeOutline class="me-1.5 h-4 w-4" />Floating outlined
   </FloatingLabelInput>
-  <FloatingLabelInput id="floating_standard" name="floating_standard" type="text" classes={{ label: "inline-flex " }}><EnvelopeOutline class="me-1.5 h-4 w-4" />Floating standard</FloatingLabelInput>
+  <FloatingLabelInput id="floating_standard" name="floating_standard" type="text" classes={{ label: "inline-flex" }}><EnvelopeOutline class="me-1.5 h-4 w-4" />Floating standard</FloatingLabelInput>
 </div>
src/routes/builder/floating-label/+page.svelte (2)

63-68: Consider consolidating duplicate helper class logic.

The getHelperClass function duplicates the inline ternary logic on lines 44-45 in the code generator. Consider using getHelperClass in both places for consistency.

🔎 Proposed fix for the code generator
       let helperCode = "";
       if (helperSlot) {
-        const helperClass = helperValidation === "success" ? "text-fg-success-strong" : helperValidation === "error" ? "text-fg-danger-strong" : "";
+        const helperClass = getHelperClass(helperValidation);
         helperCode = `

Note: This requires moving the getHelperClass function definition before the generatedCode derived block or extracting it to a module-level function.


100-111: Simplify disabled prop expression.

The disabled={helperSlot ? false : true} can be simplified.

🔎 Proposed fix
       <Radio
         class="my-1 {helperSlot ? '' : 'cursor-not-allowed opacity-30'}"
         classes={{ label: "w-24" }}
-        disabled={helperSlot ? false : true}
+        disabled={!helperSlot}
         name="helper_validation"
         bind:group={helperValidation}
         value={validationOption}
TROUBLESHOOTING.md (1)

25-28: Consider softening the Svelte extension cache clearing advice.

Deleting ~/.vscode/extensions/svelte.svelte-vscode-*/ removes the entire extension, not just a cache. This forces a reinstall and loses any user customizations. A less destructive alternative would be to suggest restarting VS Code or reinstalling the extension via the Extensions panel.

🔎 Proposed alternative
 4. **Clear Svelte language server cache**
-   ```bash
-   rm -rf ~/.vscode/extensions/svelte.svelte-vscode-*/
-   ```
+   - Uninstall and reinstall the Svelte for VS Code extension via the Extensions panel
+   - Or restart VS Code with extensions disabled, then re-enable
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ceddcdf and 8ec967b.

📒 Files selected for processing (17)
  • TROUBLESHOOTING.md
  • convertThemes.js
  • src/lib/forms/button-toggle/ButtonToggle.svelte
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/fileupload/theme.ts
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/lib/forms/floating-label/theme.ts
  • src/lib/forms/helper/Helper.svelte
  • src/lib/forms/helper/theme.ts
  • src/lib/types.ts
  • src/routes/builder/floating-label/+page.svelte
  • src/routes/color-test/+page.svelte
  • src/routes/docs-examples/forms/floating-label/Disabled.svelte
  • src/routes/docs-examples/forms/floating-label/Validation.svelte
  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
  • src/routes/docs/forms/floating-label.md
  • src/routes/utils/themeStore.svelte.ts
✅ Files skipped from review due to trivial changes (2)
  • src/lib/forms/helper/Helper.svelte
  • src/routes/docs/forms/floating-label.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/routes/color-test/+page.svelte
  • src/lib/forms/fileupload/theme.ts
  • convertThemes.js
  • src/routes/utils/themeStore.svelte.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
  • src/lib/forms/button-toggle/ButtonToggle.svelte
  • src/routes/docs-examples/forms/floating-label/Disabled.svelte
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/helper/theme.ts
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/routes/builder/floating-label/+page.svelte
  • src/lib/forms/floating-label/theme.ts
  • src/routes/docs-examples/forms/floating-label/Validation.svelte
  • src/lib/types.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:28.743Z
Learning: In flowbite-svelte, when using ThemeProvider with reactive themes, `getTheme("componentName")` calls must be placed inside `$derived()` expressions (not at module scope) to ensure components react to dynamic theme changes. This pattern is intentional for reactive theming support.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
  • src/routes/builder/floating-label/+page.svelte
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles, ensure both the container (with focus-within) and the inner input element (with direct focus) have dynamic styling based on the validation state. The input element needs its own focus styles that change to red when inputInvalid=true.

Applied to files:

  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
  • src/routes/docs-examples/forms/floating-label/Disabled.svelte
  • TROUBLESHOOTING.md
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/routes/builder/floating-label/+page.svelte
  • src/lib/forms/floating-label/theme.ts
  • src/routes/docs-examples/forms/floating-label/Validation.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

Applied to files:

  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
📚 Learning: 2025-03-20T11:11:53.953Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.953Z
Learning: In the Flowbite Svelte library's MultiInput component, the 'inputInvalid' property should be exported and passed to the Wrapper component to properly style the component's ring with red color when validation fails, similar to how the Input component handles validation states.

Applied to files:

  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
  • src/routes/docs-examples/forms/floating-label/Disabled.svelte
  • TROUBLESHOOTING.md
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/routes/builder/floating-label/+page.svelte
  • src/lib/forms/floating-label/theme.ts
  • src/routes/docs-examples/forms/floating-label/Validation.svelte
  • src/lib/types.ts
📚 Learning: 2025-03-20T11:11:53.952Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.952Z
Learning: In the Flowbite Svelte library, when implementing components with validation states, the 'inputInvalid' property should be explicitly defined and passed to the Wrapper component. When inputInvalid=true, the color should be set to "red" to ensure the ring/border styling is applied correctly.

Applied to files:

  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
  • src/routes/docs-examples/forms/floating-label/Disabled.svelte
  • TROUBLESHOOTING.md
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/routes/builder/floating-label/+page.svelte
  • src/lib/forms/floating-label/theme.ts
  • src/routes/docs-examples/forms/floating-label/Validation.svelte
  • src/lib/types.ts
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.

Applied to files:

  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
  • src/routes/docs-examples/forms/floating-label/Disabled.svelte
  • TROUBLESHOOTING.md
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/routes/builder/floating-label/+page.svelte
  • src/lib/forms/floating-label/theme.ts
  • src/routes/docs-examples/forms/floating-label/Validation.svelte
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
  • src/routes/docs-examples/forms/floating-label/Disabled.svelte
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/lib/forms/floating-label/theme.ts
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
  • src/routes/docs-examples/forms/floating-label/Disabled.svelte
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.

Applied to files:

  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
  • TROUBLESHOOTING.md
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/routes/builder/floating-label/+page.svelte
  • src/lib/forms/floating-label/theme.ts
  • src/routes/docs-examples/forms/floating-label/Validation.svelte
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
  • src/lib/forms/button-toggle/ButtonToggle.svelte
  • src/routes/docs-examples/forms/floating-label/Disabled.svelte
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/routes/builder/floating-label/+page.svelte
  • src/routes/docs-examples/forms/floating-label/Validation.svelte
📚 Learning: 2024-11-22T08:37:27.996Z
Learnt from: mrh1997
Repo: themesberg/flowbite-svelte PR: 1442
File: src/lib/utils/Popper.svelte:144-145
Timestamp: 2024-11-22T08:37:27.996Z
Learning: In `src/lib/utils/Popper.svelte`, inconsistencies in event handling (e.g., using both `mouseenter`/`mouseleave` and `pointerenter`/`pointerleave`) may be intentional to minimize modifications and reduce the risk of new problems.

Applied to files:

  • src/lib/forms/button-toggle/ButtonToggle.svelte
📚 Learning: 2025-08-31T12:56:05.074Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1745
File: src/lib/types.ts:677-686
Timestamp: 2025-08-31T12:56:05.074Z
Learning: HTMLInputAttributes includes a `group` property that can be used for grouping form controls like checkboxes and radio buttons, so interfaces extending HTMLInputAttributes don't need to explicitly declare `group` unless they want to override its type.

Applied to files:

  • src/lib/types.ts
🔇 Additional comments (26)
src/lib/forms/button-toggle/ButtonToggle.svelte (3)

14-14: LGTM!

Correctly wraps getTheme("buttonToggle") inside $derived() to ensure the component reacts to dynamic theme changes.

Based on learnings, this is the correct pattern for reactive theming support in flowbite-svelte.


59-70: LGTM!

Optional chaining for styling?.content, styling?.icon, and styling?.text safely handles cases where the classes prop is not provided or specific style properties are undefined.


31-31: No action required. ButtonToggle's default color of "primary" is intentional and documented. Different component types (Button defaults to "brand", ButtonToggle to "primary", GradientButton to "blue") maintain their own design defaults, which is a normal pattern in component libraries.

Likely an incorrect or invalid review comment.

src/routes/docs-examples/forms/floating-label/Disabled.svelte (1)

5-9: LGTM!

The removal of the unused id="exampleWrapper" is a clean simplification. The example correctly demonstrates all three FloatingLabelInput variants (filled, outlined, standard) with the disabled prop.

src/routes/docs-examples/forms/floating-label/Validation.svelte (1)

8-52: LGTM!

The migration from color prop to validation prop is correctly demonstrated. The Helper components now properly use class-based styling with semantic tokens (text-fg-success-strong, text-fg-danger-strong).

Minor note: "Oh, snapp!" appears to be a typo (should be "Oh, snap!") at lines 35, 42, and 49, though this may be pre-existing.

src/lib/forms/floating-label/FloatingLabelInput.svelte (2)

32-36: LGTM! Correct reactive theming pattern.

The getTheme("floatingLabelInput") call is correctly placed inside a $derived() expression, ensuring the component reacts to dynamic theme changes. This follows the established pattern in this repository. Based on learnings, this is the correct approach for ThemeProvider integration.


167-188: LGTM! Clean prop binding and class composition.

The disabled prop is correctly passed to the native input element, and the class composition using styling?.X provides proper null-safety for optional class overrides.

src/lib/forms/checkbox/theme.ts (3)

92-98: Inline variant structure is now correct.

The previous review flagged a malformed inline variant structure where false was incorrectly nested inside true. This has been properly restructured with true and false as direct properties of inline.


100-106: LGTM! Disabled variant correctly uses label slot.

The disabled.true variant now correctly targets the label slot instead of the non-existent div slot, aligning with the slot definitions.


11-19: All semantic color tokens used in the checkbox theme are properly defined in static/themes/themes.css. The focus:ring-brand-soft, focus:ring-neutral-tertiary, and focus:ring-neutral-tertiary-soft tokens are all confirmed to exist with appropriate CSS variable mappings.

src/lib/forms/floating-label/theme.ts (2)

39-66: LGTM! Well-structured validation-based theming.

The new variant axes (disabled, validation, withIcon) provide a clean semantic API. The validation states correctly apply distinct styling for success and error cases with appropriate semantic color tokens. Based on learnings, this approach aligns with the library's pattern for validation-based focus styling.


120-141: LGTM! Compound variants handle filled validation states.

The compound variants correctly apply variant-specific backgrounds (bg-success-soft, bg-danger-soft) for the filled input style when validation is active. The disabled state override at the end ensures consistent disabled styling regardless of other variant combinations.

src/lib/types.ts (12)

36-42: Import additions and typo fix look good.

The GradientButtonVariantesGradientButtonVariants typo correction and the new variant imports (CarouselIndicatorsVariants, ControlButtonVariants, ThumbnailsVariants, FooterBrandVariants, etc.) align with the interface changes throughout the file.


224-235: AlertProps additions are well-typed.

The new closeColor, listContent, and borderAccent properties extend Alert's styling capabilities while using proper type references (CloseButtonVariants["color"]).


250-261: BadgeProps type refinement is correct.

Using Omit<BadgeVariants, "href"> to avoid type conflict with the locally-defined href?: HTMLAnchorAttributes["href"] is the right approach. The closeBtnColor addition follows the established pattern.


264-272: BannerProps update aligns with the component styling consolidation.

The closeBtnColor addition is consistent with other dismissable components (Alert, Badge).


338-342: GradientButtonProps extension is cleaner.

Extending GradientButtonVariants directly is preferable to having a separate btnClass prop, as it properly integrates the variant system.


344-355: AccordionContextType aligns with the new classes pattern.

The context type mirrors AccordionProps.classes structure, ensuring type consistency for classes passed through context. This supports the reactive theming pattern documented in the learnings.


458-463: CardProps additions improve accessibility and interactivity.

Adding imgAlt for image accessibility and hoverable for interaction states are good improvements.


480-507: Carousel component props consistently extend their variants.

IndicatorsProps, ControlButtonProps, and ThumbnailsProps now properly extend their respective variant types, aligning with the theme system refactoring.


686-693: FooterBrandProps properly extends its variant type.

The extension of FooterBrandVariants and explicit class?: ClassValue follows the established pattern.


726-735: CheckboxProps color typing is explicit and type-safe.

Using CheckboxVariants["color"] ensures the color prop stays synchronized with the variant definition.


768-786: FloatingLabelInputProps explicit typing is correct.

The explicit type references for validation, disabled, and withIcon ensure consistency with the variant system.

Note: There's a pre-existing typo in FloatingLabelInputVaratiants (should be Variants), but that's outside the scope of this PR's changes.


282-292: > Likely an incorrect or invalid review comment.

src/lib/forms/helper/theme.ts (2)

11-11: No action needed. The text-body utility class is properly defined through Tailwind's theming system in src/routes/layout.css and static/themes/themes.css via the @theme block (--color-body: var(--color-gray-600)) and the Flowbite plugin, which automatically generates the corresponding utility class. This is a standard pattern in the codebase and will function correctly.

Likely an incorrect or invalid review comment.


7-7: Verify impact of removing font-normal from helper text base styling.

The helper component renders as a <p> element without an explicit font-normal declaration, meaning it will inherit font weight from parent elements. While this works in typical form usage where parents have normal font weight, it could cause visual inconsistencies if a parent component applies bold or heavier font weights. Confirm that all use cases of the helper component render with the expected typography weight, particularly when nested inside form field wrappers or containers with non-default font weights.

Comment on lines +37 to +44
### FloatingLabelInputProps (in `src/lib/types.ts`)
**Removed:**
- `color?: FloatingLabelInputVaratiants["color"]`

**Added:**
- `validation?: FloatingLabelInputVaratiants["validation"]` - New semantic validation states (none, success, error)
- `disabled?: FloatingLabelInputVaratiants["disabled"]` - Explicit disabled state
- `withIcon?: FloatingLabelInputVaratiants["withIcon"]` - Icon support flag
Copy link
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

🏁 Script executed:

#!/bin/bash
# Search for the typo "Varatiants" across the codebase
rg -n "Varatiants" --type=ts --type=md

Repository: themesberg/flowbite-svelte

Length of output: 1257


Fix typo in type name: "Varatiants" should be "Variants"

The type FloatingLabelInputVaratiants is misspelled throughout the codebase. The typo appears in the type definition at src/lib/forms/floating-label/theme.ts:5, and is referenced in src/lib/types.ts and TROUBLESHOOTING.md. Rename to FloatingLabelInputVariants across all files.

🤖 Prompt for AI Agents
In TROUBLESHOOTING.md around lines 37 to 44 (and in the codebase), the type name
FloatingLabelInputVaratiants is misspelled; rename it to
FloatingLabelInputVariants: update the type definition in
src/lib/forms/floating-label/theme.ts (line ~5) to export
FloatingLabelInputVariants, update all references/imports in src/lib/types.ts
and any other files (including TROUBLESHOOTING.md) to use the corrected
identifier, ensure IDE/tsserver fixes imports, run TypeScript compile/tests to
confirm no remaining references to the old misspelled name, and update any
related docs or comments.

@shinokada shinokada merged commit f206ee0 into themesberg:version-2 Dec 24, 2025
1 check failed
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/routes/builder/floating-label/+page.svelte (1)

19-20: Ensure type consistency for validation states.

floatingValidation uses FloatingLabelInputProps["validation"] while helperValidation uses a hardcoded "none" | "success" | "error" type. Both are populated from the same validations array (line 18), which could lead to type mismatches if the component's validation type includes additional values.

Consider aligning the types:

🔎 Proposed type alignment
 let floatingValidation = $state<FloatingLabelInputProps["validation"]>("none");
-let helperValidation = $state<"none" | "success" | "error">("none");
+let helperValidation = $state<FloatingLabelInputProps["validation"]>("none");
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ec967b and 2ab7487.

📒 Files selected for processing (2)
  • src/routes/builder/floating-label/+page.svelte
  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/routes/docs-examples/forms/floating-label/WithIcon.svelte
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{svelte,ts,tsx,js,jsx}: Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Files:

  • src/routes/builder/floating-label/+page.svelte
🧠 Learnings (7)
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.

Applied to files:

  • src/routes/builder/floating-label/+page.svelte
📚 Learning: 2025-03-20T11:52:09.106Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components, both the regular focus styling (controlled by ringClasses) and focus-within styling need to be dynamically adjusted based on validation state. For proper validation styling, create separate objects for focus-within classes (like focusWithinClasses) that use the same color as ringClasses when inputInvalid=true.

Applied to files:

  • src/routes/builder/floating-label/+page.svelte
📚 Learning: 2025-03-20T11:11:53.952Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.952Z
Learning: In the Flowbite Svelte library, when implementing components with validation states, the 'inputInvalid' property should be explicitly defined and passed to the Wrapper component. When inputInvalid=true, the color should be set to "red" to ensure the ring/border styling is applied correctly.

Applied to files:

  • src/routes/builder/floating-label/+page.svelte
📚 Learning: 2025-03-20T11:11:53.953Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.953Z
Learning: In the Flowbite Svelte library's MultiInput component, the 'inputInvalid' property should be exported and passed to the Wrapper component to properly style the component's ring with red color when validation fails, similar to how the Input component handles validation states.

Applied to files:

  • src/routes/builder/floating-label/+page.svelte
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles, ensure both the container (with focus-within) and the inner input element (with direct focus) have dynamic styling based on the validation state. The input element needs its own focus styles that change to red when inputInvalid=true.

Applied to files:

  • src/routes/builder/floating-label/+page.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/builder/floating-label/+page.svelte
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

// bad: at module scope
const theme = getTheme("button");

// good: inside a derived store
import { derived } from 'svelte/store';

const themeDerived = derived(themeProviderStore, ($themeProvider) => getTheme("button"));

// use $themeDerived in template/component

Applied to files:

  • src/routes/builder/floating-label/+page.svelte
🔇 Additional comments (4)
src/routes/builder/floating-label/+page.svelte (4)

63-68: Well-structured helper class resolver.

The getHelperClass function properly encapsulates the validation-to-CSS mapping logic. Good separation of concerns.


79-82: Correct implementation of validation-based helper styling.

The Helper component properly uses getHelperClass(helperValidation) to apply dynamic styling based on validation state. This aligns well with the validation-based approach.


92-111: UI controls properly implement validation-based configuration.

The validation radio groups correctly use the theme-derived validation options and properly disable helper validation controls when the helper slot is inactive. The migration from color to validation semantics is well-executed in the UI layer.


18-18: No action required - direct theme imports are acceptable in builder pages.

The floatingLabelInput.variants.validation access at module scope is appropriate here. This is a direct import of a theme configuration object used to generate static radio button options, not a dynamic theme value accessed via getTheme(). Builder pages don't require theme reactivity support, so the pattern differs from reusable components which use $derived(getTheme(...)).


let helperCode = "";
if (helperSlot) {
const helperClass = helperValidation === "success" ? "text-fg-success-strong" : helperValidation === "error" ? "text-fg-danger-strong" : "";
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Eliminate duplicate helper class logic.

The inline helper class computation duplicates the getHelperClass function defined at lines 64-68. Use the dedicated function to maintain DRY principles.

🔎 Proposed refactor to use getHelperClass function
-      const helperClass = helperValidation === "success" ? "text-fg-success-strong" : helperValidation === "error" ? "text-fg-danger-strong" : "";
+      const helperClass = getHelperClass(helperValidation);
📝 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 helperClass = helperValidation === "success" ? "text-fg-success-strong" : helperValidation === "error" ? "text-fg-danger-strong" : "";
const helperClass = getHelperClass(helperValidation);
🤖 Prompt for AI Agents
In src/routes/builder/floating-label/+page.svelte around line 44, the inline
ternary that computes helperClass duplicates the existing getHelperClass
function (defined at lines 64-68); replace the inline expression with a call to
getHelperClass(helperValidation) so the component uses the single source of
truth for mapping validation -> class, removing the duplicated logic and keeping
DRY.

<CodeWrapper>
<div class="mb-4 md:h-20">
<FloatingLabelInput variant={inputStyle} {disabled} size={floatingSize} color={floatingColor} id="floating_filled" type="text">Floating {inputStyle}</FloatingLabelInput>
<FloatingLabelInput variant={inputStyle} {disabled} size={floatingSize} validation={floatingValidation} id="floating_filled" type="text">Floating {inputStyle}</FloatingLabelInput>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Flowbite-Svelte FloatingLabelInput component props validation variant API v2

💡 Result:

Short summary of the FloatingLabelInput API (Flowbite‑Svelte v2 docs)

  • Variant: prop "variant" — accepted values: "filled", "outlined", "standard" (controls filled / outlined / standard floating styles). [1][2]
  • Common props: id, name, type, disabled, class, aria-describedby (same as standard input attributes). [1]
  • Clearable: boolean "clearable" and callback "clearableOnClick" to handle clear-button clicks. [1]
  • Data / combobox: "data" prop can provide suggestion list for combobox behavior. [1]
  • Element ref: bind:elementRef to access the underlying input element. [1]
  • Validation / helper text: use the Helper component (or plain markup under the input) and Tailwind color classes (red/green) for error / success messages; validation styling is applied by adding appropriate classes to the helper text / surrounding markup. [1]
  • Usage examples and a live builder (for visualizing variant + helper + sizes + disabled) are on the docs site. [2][3]

References:

  1. Flowbite‑Svelte Floating Label docs (props, examples, clearable, elementRef, validation guidance). [1]
  2. Flowbite‑Svelte Floating‑label builder (shows variant options: filled/outlined/standard). [2]
  3. Flowbite (Tailwind) floating label reference (HTML examples of the three styles). [3]

If you want, I can extract the exact TypeScript prop types from the repo (FloatingLabelInput.svelte / index.d.ts) and paste them here.


🌐 Web query:

Flowbite-Svelte FloatingLabelInput size prop floatingValidation floatingSize component definition

💡 Result:

Short answer — Flowbite‑Svelte’s FloatingLabelInput supports a small/default size via a size prop (examples use size="small" or omit size for default). Common props shown in the docs include variant, clearable, id/name/type, data (for combobox), bind:elementRef, and helper slot. There are no documented props named floatingValidation or floatingSize in the official FloatingLabelInput docs or builder (those names are not part of the component API). See the Floating Label docs and builder for examples and the component prop list. [1][2]

Sources:
[1] Flowbite‑Svelte — Floating label docs (examples, size="small" and default).
[2] Flowbite‑Svelte — Floating‑label builder / component page.


Remove unsupported validation prop — use Helper component for validation styling instead.

The FloatingLabelInput component does not support a validation prop. The variant and size props are correct and supported, but validation styling must be applied via the Helper component with Tailwind color classes (e.g., text-red-600 for errors, text-green-600 for success), as documented in the official Flowbite-Svelte Floating Label API.

🤖 Prompt for AI Agents
In src/routes/builder/floating-label/+page.svelte around line 77, the
FloatingLabelInput is passed an unsupported validation prop; remove
validation={floatingValidation} from the component and instead render a Helper
component below the input that applies validation styling via Tailwind classes
(e.g., text-red-600 for error, text-green-600 for success) using the
floatingValidation value to choose the class and message so the visual
validation follows Flowbite‑Svelte's Floating Label API.

@shinokada shinokada deleted the v2-next branch December 24, 2025 09:15
This was referenced Dec 26, 2025
@coderabbitai coderabbitai bot mentioned this pull request Jan 4, 2026
15 tasks
@coderabbitai coderabbitai bot mentioned this pull request Jan 14, 2026
15 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet