Skip to content

Version 2 part-2#1890

Merged
shinokada merged 15 commits intothemesberg:version-2from
shinokada:version-2
Dec 27, 2025
Merged

Version 2 part-2#1890
shinokada merged 15 commits intothemesberg:version-2from
shinokada:version-2

Conversation

@shinokada
Copy link
Collaborator

@shinokada shinokada commented Dec 24, 2025

🔗 Related issue (optional)

Closes #


📑 Description


🔍 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

    • Accessibility: menu controls now expose aria-expanded for assistive tech
  • Bug Fixes & Improvements

    • Refined styling, spacing and corner radii across gallery, modal, pagination, navbar and sidebar
    • Gallery gap normalization and improved responsive spacing/visibility
    • Pagination: configurable visible pages and improved navigation behavior
  • Documentation

    • Updated CSS/theme guidance, Quick Start and examples
  • Chores

    • Dev dependency updates and new unit-test script; expanded component test coverage

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

@vercel
Copy link

vercel bot commented Dec 24, 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 24, 2025

📝 Walkthrough

Walkthrough

Consolidates per-slot class props into a unified classes prop across many components, refactors theme definitions to slot-based APIs, removes deprecated class props and deprecation plumbing, adds extensive Vitest/Svelte tests, adds several route prerender toggles, small dependency bumps, and deletes the server hooks redirect file. (45 words)

Changes

Cohort / File(s) Summary
Package & Tooling
package.json, vite.config.ts
Added test:unit:run script; bumped several devDependencies; added Vitest env propagation and process.env.VITEST define.
Large test surface
src/tests/** (many files, e.g. src/tests/sidebar/*, src/tests/navbar/*, src/tests/modal/*, src/tests/gallery/*, src/tests/pagination/*, src/tests/popover/*, src/tests/list-group/*, src/tests/indicator/*, src/tests/progress/*, src/tests/kbd/*)
Adds 100+ new test fixtures and suites (Vitest + @testing-library/svelte) covering many components and interactions.
API: unified classes prop
src/lib/*/*.svelte (notably sidebar/*, list-group/*, rating/*, pagination/PaginationNav.svelte, gallery/Gallery.svelte, mega-menu/MegaMenu.svelte, modal/Modal.svelte, popover/Popover.svelte, ...)
Replaced many per-slot class props (e.g., spanClass, imgClass, itemClass, iconClass, prevClass, ulClass, closeBtnClass, etc.) with a single classes prop; internal styling now derived from classes with optional chaining.
Theming & types
src/lib/*/theme.ts, src/lib/theme/themes.ts, src/lib/types.ts
Converted theme definitions to slot-based APIs, added Classes<T> integration and new variant types (e.g., NavbarVariants, SidebarItemVariants), exported sidebarItem.
Sidebar refactor & call sites
src/lib/sidebar/*.svelte, src/lib/sidebar/theme.ts, src/lib/sidebar/index.ts, src/routes/**/Sidebar*.svelte, src/routes/docs-examples/components/sidebar/*
Added sidebarItem theme, changed SidebarItem API to accept classes object, removed many deprecated per-prop classes, added controlled/uncontrolled DropdownWrapper behavior, and updated call sites to classes={{ span, link }}.
Navbar & Menu updates
src/lib/navbar/*.svelte, src/lib/navbar/Menu.svelte, src/lib/navbar/theme.ts, src/lib/navbar/index.ts
Removed legacy class props, introduced classes/breakpoint reactivity, exported Menu, removed ariaLabel prop from Menu SVG (now aria-hidden="true").
Toolbar accessibility
src/lib/toolbar/ToolbarButton.svelte, src/lib/toolbar/theme.ts
Added aria-expanded prop forwarding on ToolbarButton; adjusted md size radius token.
Modal & theme slot
src/lib/modal/Modal.svelte, src/lib/modal/theme.ts
Removed per-section class props and deprecation plumbing; derive styling from classes; added close slot to modal theme.
Popover & other component cleanups
src/lib/popover/Popover.svelte, src/lib/gallery/Gallery.svelte, src/lib/gallery/theme.ts, src/lib/accordion/theme.ts, src/lib/navbar/NavLi.svelte, src/lib/menu/Menu.svelte, src/lib/rating/*
Simplified styling derivation to classes, removed warnThemeDeprecation/untrack usage, renamed several svgClass→class/className props, minor class token tweaks (rounded sizes), Menu SVG now aria-hidden.
Routes: prerender & data loading
src/routes/+page.server.ts, src/routes/blocks/+layout.ts, src/routes/builder/+layout.ts, src/routes/icons/+layout.ts, src/routes/illustrations/+layout.ts
Added prerender = false to several layouts/routes; switched some fetches to direct helpers; added dashboard to load payload and strengthened error fallback structures.
Removed files / docs
src/hooks.server.js, THEME_SELECTOR_FIX.md, TROUBLESHOOTING.md
Deleted precomputed redirect server hook and two documentation files.
Pages & docs updates
src/routes/docs/pages/introduction.md, src/routes/theme-test/*, src/routes/layouts/FlowbiteSvelteLayout.svelte, src/routes/layout.css
Updated introduction docs and layout CSS guidance, added theme-test demo pages, adjusted layout spacing and font fallbacks.
Misc. route/component tweaks
assorted src/routes/** and src/lib/** files
Minor UI/spacing tweaks, small behavior refinements (e.g., NavHamburger aria-expanded wiring, modal/footer slot usage, Gallery gap normalization on init).

Sequence Diagram(s)

(omitted — changes are broad API/theme refactors and many test additions; no single new multi-component sequential flow introduced that warrants a focused sequence diagram)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • fix: update for version 2 #1887: Widespread classes prop consolidation and theme/type updates — strongly overlaps the same API migration pattern.
  • Classes2 #1683: Introduces VariantProps & Classes type pattern and large-scale classes-prop migration — directly related to theme/type changes.
  • Dismissable #1700: Changes around dismissable/context and CloseButton behavior — intersects with modal/dropdown and floating-label clear handling in this diff.

Poem

🐰 I hopped through props and slots so wide,

pulled many classes into one cozy hide.
Tests like carrots sprouted everywhere,
aria sings when menus open in the air.
I nibbled deprecations — tidy and spry.

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is entirely a blank template with no actual content, missing description, PR type selection, and checklist confirmation. Complete all required sections: describe the changes, select PR type, confirm checklist items, and explain breaking changes if applicable.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Version 2 part-2' is vague and generic, providing no meaningful information about what changes are included in the changeset. Use a descriptive title that summarizes the main changes, such as 'Refactor component props to use consolidated classes objects' or 'Update theme system and add comprehensive test suites'.
✨ 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.

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

Caution

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

⚠️ Outside diff range comments (3)
src/lib/navbar/Navbar.svelte (1)

54-60: Documentation is missing the classes prop.

The @prop documentation block doesn't list the new classes prop that was added to the component's public API.

🔎 Proposed fix
 @prop children
 @prop fluid
 @prop class: className
+@prop classes
 @prop closeOnClickOutside = true
 @prop breakpoint = "md"
 @prop ...restProps
src/lib/list-group/ListgroupItem.svelte (1)

59-61: Stale documentation: iconClass prop no longer exists.

The documentation block still references @prop iconClass = "me-2.5 h-15 w-15" but this prop was removed and replaced by the classes prop pattern.

🔎 Proposed fix
 @prop Icon
 @prop class: className
-@prop iconClass = "me-2.5 h-15 w-15"
+@prop classes
 @prop ...restProps
src/lib/list-group/Listgroup.svelte (1)

73-81: Documentation is missing the classes prop.

The @prop documentation block doesn't list the new classes prop that replaces the removed itemClass and iconClass props.

🔎 Proposed fix
 @prop horizontal
 @prop rounded
 @prop border
 @prop class: className
+@prop classes
 @prop ...restProps
🧹 Nitpick comments (9)
src/routes/utils/ThemeSelector.svelte (1)

23-26: Consider adding aria-expanded for complete accessibility.

The aria-haspopup="true" is good, but dropdown trigger buttons should also include aria-expanded to indicate the open/closed state to screen readers. The Dropdown component may handle this internally, but verify this is the case.

Otherwise, the padding and icon sizing changes look appropriate.

src/routes/theme-test/leading/+page.svelte (1)

5-18: Consider organizing textVariables by category.

The array mixes different utility types: font-size (text-2xs), spacing (spacing-8xl), line-height (leading-*), and letter-spacing (tracking-*). Consider splitting into separate arrays for clearer organization and testing, or rename to typographyVariables.

src/routes/theme-test/components/+page.svelte (1)

69-69: Link navigates away from test page.

The example link href="/" will navigate users away from the theme test page. Consider using href="#" or href="javascript:void(0)" with onclick|preventDefault to keep users on the test page, or add a note that this is an intentional navigation example.

🔎 Proposed fix
-        <a href="/" class="text-primary-600 hover:text-primary-700 dark:text-primary-500">Link example</a>
+        <a href="#link-example" class="text-primary-600 hover:text-primary-700 dark:text-primary-500">Link example</a>
src/lib/gallery/Gallery.svelte (1)

13-15: CSS gap normalization workaround.

The init function handles a browser edge case where gap: normal doesn't inherit properly. Consider adding a brief inline comment explaining why this is needed for future maintainers.

src/tests/forms/floating-label/floating-label.test.ts (1)

284-284: Consider replacing remaining setTimeout delays with waitFor.

The Suggestions/Autocomplete tests still use setTimeout(..., 100) delays. For consistency and reduced flakiness, consider migrating these to waitFor as well, similar to the Clearable tests above.

Example pattern
-    // Wait for suggestions to appear
-    await new Promise((resolve) => setTimeout(resolve, 100));
-
-    expect(screen.getByText("Apple")).toBeInTheDocument();
+    // Wait for suggestions to appear
+    await waitFor(() => {
+      expect(screen.getByText("Apple")).toBeInTheDocument();
+    });

Also applies to: 299-299, 315-315, 335-335, 357-357, 364-364

src/lib/modal/Modal.svelte (1)

50-54: Minor: CloseButton missing theme fallback.

The CloseButton on line 54 uses only styling?.close, while other sections (header, body, footer) include both theme and styling: clsx(theme?.header, styling?.header). Consider adding theme?.close for consistency.

Suggested fix
-          <CloseButton type="submit" formnovalidate class={clsx(styling?.close)} />
+          <CloseButton type="submit" formnovalidate class={clsx(theme?.close, styling?.close)} />
src/routes/+page.server.ts (1)

13-24: Consider parallelizing npm and discord fetches.

The npm and discord fetches on lines 23-24 run sequentially after the Promise.all. They could be included in the parallel batch for faster page load during prerendering.

Suggested optimization
+    const today = new Date().toISOString().slice(0, 10);
+    
     // Fetch data directly instead of through API endpoint for prerendering
-    const [posts, blocks, builders, dashboard, github, contributors] = await Promise.all([
+    const [posts, blocks, builders, dashboard, github, contributors, npm, discord] = await Promise.all([
       fetchMarkdownPosts(),
       fetchBlocksMarkdownPosts(),
       fetchBuilders(),
       fetchDashboardPosts(),
       fetch(githubAPI).then(json),
-      fetch(githubAPI + "/contributors?per_page=21").then(json)
+      fetch(githubAPI + "/contributors?per_page=21").then(json),
+      fetch(`https://api.npmjs.org/downloads/point/2020-01-01:${today}/flowbite-svelte`).then(json),
+      fetch("https://discord.com/api/v9/invites/4eeurUVvTy?with_counts=true&with_expiration=true").then(json)
     ]);
-    
-    const today = new Date().toISOString().slice(0, 10);
-    const npm = await fetch(`https://api.npmjs.org/downloads/point/2020-01-01:${today}/flowbite-svelte`).then(json);
-    const discord = await fetch("https://discord.com/api/v9/invites/4eeurUVvTy?with_counts=true&with_expiration=true").then(json);
src/lib/forms/floating-label/FloatingLabelInput.svelte (1)

41-53: Unused event parameter.

The event?: MouseEvent parameter is declared but never used in the function body. If it's intended for future use or for signature compatibility with event handlers, consider prefixing with underscore (_event) to indicate intentional non-use.

Suggested fix
-  const clearAll = (event?: MouseEvent) => {
+  const clearAll = (_event?: MouseEvent) => {
src/lib/navbar/NavUl.svelte (1)

56-68: Consider consolidating duplicate template structure.

The <div> and <ul> structure is duplicated between the !hidden and else branches, differing only in the transition directive. Consider using a single template with conditional transition application to reduce duplication.

📜 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 344adc3 and 1f91b45.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (30)
  • TEST_SUMMARY.md
  • package.json
  • src/lib/accordion/theme.ts
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/lib/gallery/Gallery.svelte
  • src/lib/gallery/theme.ts
  • src/lib/list-group/Listgroup.svelte
  • src/lib/list-group/ListgroupItem.svelte
  • src/lib/list-group/theme.ts
  • src/lib/mega-menu/MegaMenu.svelte
  • src/lib/modal/Modal.svelte
  • src/lib/navbar/NavHamburger.svelte
  • src/lib/navbar/NavUl.svelte
  • src/lib/navbar/Navbar.svelte
  • src/lib/navbar/theme.ts
  • src/lib/types.ts
  • src/routes/+page.server.ts
  • src/routes/api/posts/+server.js
  • src/routes/blocks/+layout.ts
  • src/routes/builder/+layout.ts
  • src/routes/docs/pages/introduction.md
  • src/routes/icons/+layout.ts
  • src/routes/illustrations/+layout.ts
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/routes/theme-test/color/+page.svelte
  • src/routes/theme-test/components/+page.svelte
  • src/routes/theme-test/leading/+page.svelte
  • src/routes/utils/ThemeSelector.svelte
  • src/routes/utils/ToolbarLink.svelte
  • src/tests/forms/floating-label/floating-label.test.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/illustrations/+layout.ts
  • src/routes/icons/+layout.ts
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/tests/forms/floating-label/floating-label.test.ts
  • src/routes/builder/+layout.ts
  • src/routes/api/posts/+server.js
  • src/routes/theme-test/components/+page.svelte
  • src/routes/blocks/+layout.ts
  • src/routes/utils/ToolbarLink.svelte
  • src/lib/navbar/theme.ts
  • src/lib/accordion/theme.ts
  • src/routes/utils/ThemeSelector.svelte
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/lib/gallery/Gallery.svelte
  • src/lib/modal/Modal.svelte
  • src/lib/navbar/NavUl.svelte
  • src/lib/gallery/theme.ts
  • src/lib/mega-menu/MegaMenu.svelte
  • src/lib/list-group/theme.ts
  • src/lib/navbar/Navbar.svelte
  • src/lib/navbar/NavHamburger.svelte
  • src/routes/theme-test/color/+page.svelte
  • src/lib/list-group/ListgroupItem.svelte
  • src/lib/types.ts
  • src/lib/list-group/Listgroup.svelte
  • src/routes/theme-test/leading/+page.svelte
  • src/routes/+page.server.ts
🧠 Learnings (10)
📚 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/layouts/FlowbiteSvelteLayout.svelte
  • package.json
📚 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/layouts/FlowbiteSvelteLayout.svelte
  • src/routes/theme-test/components/+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/layouts/FlowbiteSvelteLayout.svelte
  • src/routes/theme-test/components/+page.svelte
  • src/routes/utils/ToolbarLink.svelte
  • src/routes/utils/ThemeSelector.svelte
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/lib/gallery/Gallery.svelte
  • src/lib/modal/Modal.svelte
  • src/lib/navbar/NavUl.svelte
  • src/lib/mega-menu/MegaMenu.svelte
  • src/lib/navbar/Navbar.svelte
  • src/lib/navbar/NavHamburger.svelte
  • src/routes/theme-test/color/+page.svelte
  • src/lib/list-group/ListgroupItem.svelte
  • src/lib/list-group/Listgroup.svelte
  • src/routes/theme-test/leading/+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: Use getComponentList tool to discover available Flowbite-Svelte components or help users explore component options

Applied to files:

  • src/routes/theme-test/components/+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/components/+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/components/+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/components/+page.svelte
  • package.json
📚 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/pages/introduction.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/utils/ThemeSelector.svelte
  • src/lib/navbar/NavUl.svelte
  • src/lib/mega-menu/MegaMenu.svelte
  • src/lib/navbar/NavHamburger.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:

  • package.json
🧬 Code graph analysis (8)
src/routes/illustrations/+layout.ts (5)
src/routes/+page.server.ts (1)
  • prerender (4-4)
src/routes/api/posts/+server.js (2)
  • prerender (6-6)
  • prerender (6-6)
src/routes/blocks/+layout.ts (1)
  • prerender (3-3)
src/routes/builder/+layout.ts (1)
  • prerender (3-3)
src/routes/icons/+layout.ts (1)
  • prerender (3-3)
src/routes/icons/+layout.ts (5)
src/routes/+page.server.ts (1)
  • prerender (4-4)
src/routes/api/posts/+server.js (2)
  • prerender (6-6)
  • prerender (6-6)
src/routes/blocks/+layout.ts (1)
  • prerender (3-3)
src/routes/builder/+layout.ts (1)
  • prerender (3-3)
src/routes/illustrations/+layout.ts (1)
  • prerender (3-3)
src/routes/builder/+layout.ts (5)
src/routes/+page.server.ts (1)
  • prerender (4-4)
src/routes/api/posts/+server.js (2)
  • prerender (6-6)
  • prerender (6-6)
src/routes/blocks/+layout.ts (1)
  • prerender (3-3)
src/routes/icons/+layout.ts (1)
  • prerender (3-3)
src/routes/illustrations/+layout.ts (1)
  • prerender (3-3)
src/routes/api/posts/+server.js (5)
src/routes/+page.server.ts (1)
  • prerender (4-4)
src/routes/blocks/+layout.ts (1)
  • prerender (3-3)
src/routes/builder/+layout.ts (1)
  • prerender (3-3)
src/routes/icons/+layout.ts (1)
  • prerender (3-3)
src/routes/illustrations/+layout.ts (1)
  • prerender (3-3)
src/routes/blocks/+layout.ts (5)
src/routes/+page.server.ts (1)
  • prerender (4-4)
src/routes/api/posts/+server.js (2)
  • prerender (6-6)
  • prerender (6-6)
src/routes/builder/+layout.ts (1)
  • prerender (3-3)
src/routes/icons/+layout.ts (1)
  • prerender (3-3)
src/routes/illustrations/+layout.ts (1)
  • prerender (3-3)
src/lib/navbar/theme.ts (2)
src/lib/navbar/index.ts (1)
  • navbar (7-7)
src/lib/theme/themeUtils.ts (1)
  • Classes (42-48)
src/lib/list-group/theme.ts (1)
src/lib/theme/themeUtils.ts (1)
  • Classes (42-48)
src/lib/types.ts (1)
src/lib/navbar/theme.ts (1)
  • NavbarVariants (10-10)
🔇 Additional comments (40)
src/lib/accordion/theme.ts (1)

49-49: LGTM! Correct styling cleanup for non-flush accordion buttons.

The hover states are properly applied for non-flush accordion items. The removal of any redundant rounding utility (as noted in the summary) is correct since the base button style on line 35 already handles first-item rounding with group-first:rounded-t-base.

src/routes/theme-test/color/+page.svelte (2)

4-95: Well-structured data-driven approach.

Good use of TypeScript's as const assertions and Record types for type-safe color mappings. The separation of colorClasses and bgColorClasses makes the intent clear and the template code cleaner.


98-123: LGTM!

The data-driven rendering with nested iteration over colors and border sizes is clean and maintainable. The ThemeSelector integration follows the same pattern as other theme-test pages.

src/routes/theme-test/components/+page.svelte (3)

1-47: Comprehensive component showcase setup.

Good organization of imports and state variables. The form bindings provide interactive testing of theme styles across various input types.


371-400: Good theme color palette visualization.

The color palette section effectively demonstrates primary color shades with appropriate light/dark mode variants. This provides a useful reference for theme verification.


230-233: Avatar image paths are valid and images exist.

All three referenced images (/images/blog/image-1.jpg, /images/blog/image-3.jpg, /images/blog/image-4.jpg) are present in the static directory with valid file sizes. No action required.

src/routes/docs/pages/introduction.md (4)

86-98: Comprehensive font and theme guidance provided clearly.

The addition of Inter font import alongside commented alternatives for different themes (Minimal, Enterprise, Playful) creates helpful scaffolding for developers choosing different design directions. The duplication across both CSS file locations (app.css and +layout.css) ensures consistency in guidance.

Also applies to: 180-192


111-149: Clear, actionable color customization scaffolding with proper dual-location documentation.

The commented color override blocks follow Flowbite's color variable naming conventions and provide clear guidance on overriding brand, foreground, and border colors. The duplication across both CSS file locations with appropriate @source paths (../ for app.css, ../../ for +layout.css) demonstrates correct relative path handling for different project structures.

Also applies to: 205-243


154-169: Dark mode overrides properly structured with clear instructions.

The commented @layer base blocks for dark mode color customization follow the same conventions as light mode and provide complete guidance for both light and dark theme customization. The documentation correctly notes that @source directives are needed for Tailwind CSS v4 to scan the Flowbite libraries.

Also applies to: 248-263


100-109: Both the Tailwind v4 @plugin syntax and the flowbite-typography package name are correct. The @plugin directive properly accepts both npm package names (like flowbite-typography, which is published on npm at v1.0.5) and local paths (like flowbite/plugin within the flowbite package). The @custom-variant syntax is also valid for Tailwind v4. No changes needed.

src/routes/api/posts/+server.js (1)

5-6: LGTM!

Disabling prerendering is appropriate for this API endpoint since import.meta.glob requires runtime evaluation. The inline comment clearly explains the reasoning.

src/routes/builder/+layout.ts (1)

2-3: LGTM!

Disabling prerendering is appropriate for this layout. The change is consistent with the broader pattern applied across multiple layouts in this PR.

src/routes/blocks/+layout.ts (1)

2-3: LGTM!

The prerender flag is consistently applied across multiple layouts in this PR, maintaining a uniform approach to rendering strategy.

src/routes/utils/ToolbarLink.svelte (1)

5-8: LGTM!

The explicit destructuring and forwarding of the class prop (aliased as className) ensures proper class handling while maintaining clean prop forwarding to the child component.

src/routes/icons/+layout.ts (1)

2-3: LGTM!

Consistent with the prerendering strategy applied across other layouts in this PR.

src/routes/illustrations/+layout.ts (1)

2-3: LGTM!

The prerender flag is appropriately applied, consistent with other layout files in this PR.

package.json (1)

41-42: Dependency versions verified.

All five updated package versions exist on the npm registry and are maintained by their official teams:

  • @docsearch/css@4.4.0 ✓
  • @docsearch/js@4.4.0 ✓
  • @testing-library/svelte@5.3.0 ✓
  • svelte@5.46.1 ✓
  • typescript-eslint@8.50.1 ✓

No known security vulnerabilities were identified for these versions.

src/routes/layouts/FlowbiteSvelteLayout.svelte (2)

64-64: LGTM - Responsive gap adjustments.

The classes prop pattern aligns with the broader PR refactor toward centralized styling. The gap changes (gap-1 lg:gap-4) provide tighter spacing at smaller breakpoints.


75-78: LGTM - Breakpoint visibility adjustments.

Shifting GitHub/Discord links and NPM badge visibility from xl to 2xl breakpoints accommodates the layout at intermediate widths. The margin adjustment from ms-6 to ms-2 on Line 86 is consistent with the tighter layout.

Also applies to: 85-86

src/lib/gallery/Gallery.svelte (2)

5-9: LGTM - Simplified styling API.

Clean migration from individual imgClass prop to unified classes prop pattern. The getTheme call is correctly placed inside $derived() on line 11, ensuring reactivity to theme changes. Based on learnings about ThemeProvider usage.


22-22: LGTM - Optional chaining for styling access.

Correct use of styling?.image to handle cases where classes prop is not provided.

src/tests/forms/floating-label/floating-label.test.ts (1)

229-242: Good use of waitFor for async assertions.

Using waitFor is more robust than fixed timeouts for Svelte's reactive DOM updates. This correctly waits for the clear button to appear after value changes.

Also applies to: 252-270

src/lib/modal/Modal.svelte (1)

29-29: LGTM - Simplified styling derivation.

Clean migration to the unified classes prop pattern, consistent with the broader PR refactor.

src/routes/+page.server.ts (1)

30-39: Good error fallback structure.

The empty data structure prevents undefined errors in consuming components. The shape matches the success response, ensuring consistent typing.

src/lib/forms/floating-label/FloatingLabelInput.svelte (2)

38-39: LGTM - Derived visibility flag.

The showClearButton derived value properly encapsulates the visibility logic, ensuring the button only appears when clearable is enabled and value is non-empty.


183-185: LGTM - Clear button visibility.

Using the derived showClearButton flag keeps the template clean and the visibility logic centralized.

src/lib/navbar/NavHamburger.svelte (2)

8-13: LGTM - Simplified styling API.

Clean migration from individual menuClass prop to unified classes prop, consistent with the broader refactor. The getTheme is correctly placed inside $derived().


18-18: LGTM - Breakpoint-aware initialization.

The navbarHamburger now uses navBreakpoint ?? "md" for breakpoint-aware styling, and correctly applies optional chaining for styling?.menu.

Also applies to: 27-27

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

10-10: LGTM - New NavbarVariants type.

The NavbarVariants type properly combines VariantProps and Classes for type-safe variant and classes prop usage.


12-17: Slot-based navbar structure correctly implemented.

Both slots are properly consumed in Navbar.svelte: the base slot applies to the outer nav wrapper (line 42), and the container slot applies to the NavContainer child component (line 43). The empty container: "" placeholder allows for future theme customization through merging with theme?.container. This implementation aligns with the slot-based styling pattern used across other components.

TEST_SUMMARY.md (1)

1-51: Helpful documentation for test fixes.

This summary document clearly explains the test issues and their solutions. Good practice to document the pattern used (waitFor for Svelte reactivity) for future reference.

src/lib/mega-menu/MegaMenu.svelte (2)

10-12: Good use of $derived for reactive theme access.

The getTheme("megamenu") is correctly placed inside a $derived() expression, ensuring the component reacts to dynamic theme changes. This aligns with the established pattern in this codebase. Based on learnings.


22-24: The {:else} block references items[0] which will be undefined when the array is empty, but the children snippet expects { item: LinkType; index: number } where LinkType requires a name property.

Either remove the else block if items must always be non-empty, or provide a guard to handle the empty case (e.g., render nothing or a fallback).

src/lib/navbar/Navbar.svelte (1)

11-14: Clean implementation of the unified styling pattern.

The reactive derivation of styling from classes and theme from getTheme() is correctly implemented using $derived(). The slot-based destructuring from navbar() is well-structured.

src/lib/list-group/theme.ts (2)

7-38: Well-structured slot-based theme definition.

The migration from a flat base string to a slots-based structure (base, item, icon) provides better granularity for styling customization. The variant definitions properly return slot-specific objects.


43-43: No action needed. The h-15 and w-15 classes are intentional custom spacing utilities provided by the Flowbite plugin system, not errors. They appear consistently throughout the library as documented component defaults and are part of Flowbite's design specification.

Likely an incorrect or invalid review comment.

src/lib/navbar/NavUl.svelte (1)

14-18: Clean migration to unified classes prop pattern.

The refactor from individual ulClass, activeClass, nonActiveClass props to a single classes object is well-implemented. The reactive derivation of styling and theme follows the established pattern.

src/lib/list-group/Listgroup.svelte (1)

47-59: Correct propagation of styling to child components.

The ListgroupItem components correctly receive both class (for item styling) and classes={{ icon: listIconCls }} (for nested icon styling). This maintains the cascading nature of the unified styling approach.

src/lib/types.ts (2)

48-48: Type import correctly expanded for NavbarVariants.

The import now includes NavbarVariants which supports the new slot-based styling surface for the Navbar component.


1117-1122: NavbarProps correctly extended with NavbarVariants.

The type definition now properly extends NavbarVariants, enabling type-safe usage of the new classes prop pattern for the Navbar component.

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/pagination/PaginationNav.svelte (1)

20-21: Remove unused props from the component API.

According to the AI summary, prevClass, nextClass, spanClass, and tableDivClass were removed as part of the unified classes prop pattern. However, these props are still present in the destructuring but are never used in the component. The template uses styling?.prev, styling?.next, styling?.span, and styling?.tableDiv instead (derived from the classes prop).

Leaving unused props in the signature creates confusion about the component's actual API surface.

🔎 Proposed fix to remove unused props
  let {
    currentPage = 1,
    totalPages = 1,
    visiblePages = 5, // New prop to control visible pages
    onPageChange,
    prevContent,
    nextContent,
-    prevClass,
-    nextClass,
    layout = "pagination",
    nextLabel = "Next",
    previousLabel = "Previous",
    ariaLabel = "Page navigation",
    size = "default",
    class: className,
    classes,
-    spanClass,
-    tableDivClass,
    ...restProps
  }: PaginationNavProps = $props();

Also applies to: 29-30

🧹 Nitpick comments (15)
src/routes/theme-test/text-variables/+page.svelte (2)

11-18: Inconsistent array formatting.

The leadingVariables array has inconsistent indentation—the first item appears on the same line as the array declaration while subsequent items are on separate lines.

🔎 Proposed formatting fix
-  const leadingVariables = ["leading-9",
+  const leadingVariables = [
+    "leading-9",
     "leading-8",
     "leading-7",
     "leading-6",
     "leading-5",
     "leading-4",
     "leading-none",
-    "leading-heading-none"]
+    "leading-heading-none"
+  ];

34-48: Structural organization issues in token sections.

The fgBrand tokens (lines 39-41) are rendered within the "Font size" section but appear unrelated to font sizing. Additionally, the shikiFgBrand tokens (lines 45-47) are rendered in a section without a descriptive header.

🔎 Proposed structural improvements
   <div class="flex flex-wrap gap-4 p-8">
     <h2 class="w-full text-2xl font-semibold text-gray-900 dark:text-white">Font size</h2>
     {#each fontSizeVariables as token}
       <p class={`mb-2 ${token} bg-gray-200`}>{token} - The quick brown fox jumps over the lazy dog.</p>
     {/each}
+  </div>
+
+  <div class="flex flex-wrap gap-4 p-8">
+    <h2 class="w-full text-2xl font-semibold text-gray-900 dark:text-white">Foreground Brand Colors</h2>
     {#each fgBrand as token}
       <p class={`mb-2 ${token}`}>{token}</p>
     {/each}
   </div>

   <div class="flex flex-wrap gap-4 p-8">
+    <h2 class="w-full text-2xl font-semibold text-gray-900 dark:text-white">Shiki Foreground Brand Colors</h2>
     {#each shikiFgBrand as token}
       <p class={`mb-2 ${token}`}>{token}</p>
     {/each}
   </div>
src/tests/kbd/kbd.test.ts (1)

36-40: Prefer testing-library queries over direct DOM access.

The test uses document.querySelectorAll("kbd") which bypasses testing-library's query abstraction. Consider using screen.getAllByRole() or leveraging the queries from the first test to maintain consistency with testing-library best practices and improve test maintainability.

🔎 Proposed refactor using testing-library queries
-  test("all kbd elements have correct tag", () => {
-    render(MultipleKbd);
-    const kbds = document.querySelectorAll("kbd");
-    expect(kbds.length).toBeGreaterThanOrEqual(3);
-  });
+  test("all kbd elements have correct tag", () => {
+    render(MultipleKbd);
+    const ctrlKbd = screen.getByText("Ctrl");
+    const shiftKbd = screen.getByText("Shift");
+    const sKbd = screen.getByText("S");
+    expect(ctrlKbd.tagName).toBe("KBD");
+    expect(shiftKbd.tagName).toBe("KBD");
+    expect(sKbd.tagName).toBe("KBD");
+  });
src/redirects.js (1)

19-25: Consider optimizing lookup performance with a Map.

The current linear search has O(n) complexity. For a documentation site with dozens to hundreds of files, this is acceptable. However, if the file count grows significantly, you could optimize to O(1) lookup:

🔎 Optional optimization using Map
+// Build a Map for O(1) lookups
+const redirectMap = new Map(
+  allFiles.map(([key, value]) => [
+    value, // filename as key
+    { key, value } // store both for easy access
+  ])
+);
+
 export function getRedirectPath(dir, file) {
-  for (const [key, value] of allFiles) {
-    if (value !== file) continue;
-    if (dir === "" || dir === key) return `/docs/${key}/${value}`;
-  }
-  return null;
+  const match = redirectMap.get(file);
+  if (!match) return null;
+  
+  const { key, value } = match;
+  if (dir === "" || dir === key) {
+    return `/docs/${key}/${value}`;
+  }
+  return null;
 }

Note: This optimization is only beneficial if the number of documentation files becomes substantial (500+). The current implementation is perfectly adequate for typical use cases.

src/lib/pagination/PaginationNav.svelte (1)

118-138: Document the structure of the classes prop.

The JSDoc comments should document what properties the classes object supports to help developers understand the unified styling API. Based on the implementation, classes can include:

  • classes.tableDiv - styles for table layout container
  • classes.span - styles for page count spans
  • classes.prev - styles for previous button
  • classes.next - styles for next button
  • classes.active - styles for active page button (passed to children via context)
📝 Suggested documentation addition

Add this after line 136:

 @prop class: className
 @prop classes
+@prop classes.tableDiv - Custom classes for table layout container
+@prop classes.span - Custom classes for page count spans  
+@prop classes.prev - Custom classes for previous button
+@prop classes.next - Custom classes for next button
+@prop classes.active - Custom classes for active page button
 @prop ...restProps
vite.config.ts (1)

16-36: Stderr override is a pragmatic workaround but consider documenting the root cause.

The stderr interception correctly handles both callback signatures of write(). However, this pattern suppresses errors globally at the process level, which could hide legitimate issues during development.

Consider adding a brief comment explaining why these specific errors occur (SvelteKit cleanup during Vitest) and whether there's an upstream fix tracking this issue.

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

7-11: Add data-testid attributes for test assertions.

Consider adding data-testid attributes to the Button and Modal components for easier querying in test assertions. Other test files in the PR (e.g., menu-icon.test.svelte, color-indicator.test.svelte) follow this pattern, and consistency improves test maintainability.

🔎 Suggested enhancement with data-testid attributes
-<Button onclick={() => open = true}>Open Modal</Button>
+<Button data-testid="open-modal-button" onclick={() => open = true}>Open Modal</Button>

-<Modal bind:open>
+<Modal data-testid="basic-modal" bind:open>
   <div>Modal Content</div>
 </Modal>
src/tests/list-group/horizontal-listgroup.test.svelte (1)

7-7: Consider adding data-testid for test assertions.

Adding a data-testid attribute would make this component easier to query in automated tests and maintain consistency with other test files in the suite.

🔎 Suggested enhancement
-<Listgroup {items} horizontal />
+<Listgroup data-testid="horizontal-listgroup" {items} horizontal />
src/tests/list-group/border-listgroup.test.svelte (1)

7-7: Consider adding data-testid for test assertions.

Adding a data-testid attribute would improve test queryability and maintain consistency with other test files that include test identifiers.

🔎 Suggested enhancement
-<Listgroup {items} border />
+<Listgroup data-testid="border-listgroup" {items} border />
src/tests/modal/title-modal.test.svelte (1)

7-11: Add data-testid attributes for test assertions.

Consider adding data-testid attributes to improve test queryability and maintain consistency with other test files in the suite that follow this pattern.

🔎 Suggested enhancement with data-testid attributes
-<Button onclick={() => open = true}>Open Modal</Button>
+<Button data-testid="open-title-modal-button" onclick={() => open = true}>Open Modal</Button>

-<Modal bind:open title="Modal Title">
+<Modal data-testid="title-modal" bind:open title="Modal Title">
   <div>Modal Content with Title</div>
 </Modal>
src/tests/list-group/basic-listgroup.test.svelte (1)

1-7: LGTM! Consider adding data-testid for consistency.

The test correctly imports and renders the Listgroup component with a simple items array. The implementation is clean and follows Svelte 5 patterns.

For consistency with other test files in this PR (e.g., border-indicator.test.svelte, custom-breakpoint.test.svelte), consider adding a data-testid attribute to make test targeting more explicit:

Optional enhancement
-<Listgroup {items} />
+<Listgroup {items} data-testid="basic-listgroup" />
src/tests/list-group/disabled-listgroup.test.svelte (1)

5-9: Consider adding a data-testid wrapper for consistency.

Other list-group test files (e.g., active-listgroup.test.svelte) wrap their content with a data-testid attribute for easier DOM querying in tests. Consider adding one here for consistency:

+<div data-testid="disabled-listgroup">
 <Listgroup active>
   <ListgroupItem active>Normal Item</ListgroupItem>
   <ListgroupItem active disabled>Disabled Item</ListgroupItem>
   <ListgroupItem active>Another Item</ListgroupItem>
 </Listgroup>
+</div>
src/tests/modal/dismissable-modal.test.svelte (1)

9-11: Consider using boolean attribute shorthand.

In Svelte, boolean props can be written without an explicit ={true} when the value is true.

-<Modal bind:open dismissable={true}>
+<Modal bind:open dismissable>
   <div>Dismissable Modal</div>
 </Modal>
src/tests/navbar/navbar.test.ts (2)

3-3: Inconsistent userEvent import pattern.

Line 3 imports userEvent as a default export, while other test files in this PR use named import destructuring: import { userEvent } from "@testing-library/user-event" (e.g., listgroup.test.ts line 3, mega-menu.test.ts line 3).

🔎 Suggested fix for consistency
-import userEvent from "@testing-library/user-event";
+import { userEvent } from "@testing-library/user-event";

78-95: Avoid testing implementation details with fragile selectors.

The selector container.querySelector("[class*='hidden']") (Lines 84, 216, 342) relies on implementation details (Tailwind's hidden class) rather than testing user-visible behavior. This makes tests brittle and coupled to styling implementation.

Consider these alternatives:

  • Use aria-hidden or aria-expanded attributes for better semantic testing
  • Use toBeVisible() / not.toBeVisible() matchers
  • Add test IDs to the menu container for reliable selection

Example:

// Instead of checking for 'hidden' class
const menuContainer = container.querySelector("[class*='hidden']");

// Use visibility matcher
const menu = screen.queryByRole("list");
expect(menu).not.toBeVisible(); // or expect(menu).toBeNull()
📜 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 1f91b45 and ec385e1.

📒 Files selected for processing (64)
  • src/hooks.server.js
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/lib/list-group/Listgroup.svelte
  • src/lib/list-group/ListgroupItem.svelte
  • src/lib/list-group/theme.ts
  • src/lib/navbar/Navbar.svelte
  • src/lib/pagination/PaginationNav.svelte
  • src/redirects.js
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/routes/theme-test/components/+page.svelte
  • src/routes/theme-test/text-variables/+page.svelte
  • src/routes/utils/ThemeSelector.svelte
  • src/tests/forms/floating-label/floating-label-clearable-empty.test.svelte
  • src/tests/forms/floating-label/floating-label.test.ts
  • src/tests/gallery/basic-gallery.test.svelte
  • src/tests/gallery/custom-class-gallery.test.svelte
  • src/tests/gallery/custom-figure-gallery.test.svelte
  • src/tests/gallery/empty-gallery.test.svelte
  • src/tests/gallery/gallery.test.ts
  • src/tests/indicator/basic-indicator.test.svelte
  • src/tests/indicator/border-indicator.test.svelte
  • src/tests/indicator/color-indicator.test.svelte
  • src/tests/indicator/corner-style-indicator.test.svelte
  • src/tests/indicator/indicator.test.ts
  • src/tests/indicator/placement-indicator.test.svelte
  • src/tests/indicator/size-indicator.test.svelte
  • src/tests/kbd/basic-kbd.test.svelte
  • src/tests/kbd/custom-class-kbd.test.svelte
  • src/tests/kbd/kbd.test.ts
  • src/tests/kbd/multiple-kbd.test.svelte
  • src/tests/list-group/active-listgroup.test.svelte
  • src/tests/list-group/basic-listgroup.test.svelte
  • src/tests/list-group/border-listgroup.test.svelte
  • src/tests/list-group/custom-listgroup.test.svelte
  • src/tests/list-group/disabled-listgroup.test.svelte
  • src/tests/list-group/horizontal-listgroup.test.svelte
  • src/tests/list-group/link-listgroup.test.svelte
  • src/tests/list-group/listgroup.test.ts
  • src/tests/list-group/rounded-listgroup.test.svelte
  • src/tests/mega-menu/basic-mega-menu.test.svelte
  • src/tests/mega-menu/custom-mega-menu.test.svelte
  • src/tests/mega-menu/full-mega-menu.test.svelte
  • src/tests/mega-menu/mega-menu.test.ts
  • src/tests/modal/basic-modal.test.svelte
  • src/tests/modal/dismissable-modal.test.svelte
  • src/tests/modal/footer-modal.test.svelte
  • src/tests/modal/fullscreen-modal.test.svelte
  • src/tests/modal/modal.test.ts
  • src/tests/modal/permanent-modal.test.svelte
  • src/tests/modal/size-modal.test.svelte
  • src/tests/modal/title-modal.test.svelte
  • src/tests/navbar/active-link.test.svelte
  • src/tests/navbar/basic-navbar.test.svelte
  • src/tests/navbar/custom-active-classes.test.svelte
  • src/tests/navbar/custom-breakpoint.test.svelte
  • src/tests/navbar/custom-classes.test.svelte
  • src/tests/navbar/fluid-navbar.test.svelte
  • src/tests/navbar/menu-icon.test.svelte
  • src/tests/navbar/nav-brand.test.svelte
  • src/tests/navbar/navbar.test.ts
  • src/tests/navbar/navli-button.test.svelte
  • src/tests/navbar/navli-click.test.svelte
  • src/tests/navbar/no-close-on-click.test.svelte
  • vite.config.ts
✅ Files skipped from review due to trivial changes (1)
  • src/tests/navbar/no-close-on-click.test.svelte
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/tests/forms/floating-label/floating-label.test.ts
  • src/lib/list-group/ListgroupItem.svelte
  • src/lib/list-group/Listgroup.svelte
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/routes/theme-test/components/+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/tests/navbar/menu-icon.test.svelte
  • src/routes/utils/ThemeSelector.svelte
  • src/tests/modal/footer-modal.test.svelte
  • src/routes/theme-test/text-variables/+page.svelte
  • src/tests/list-group/disabled-listgroup.test.svelte
  • src/tests/indicator/placement-indicator.test.svelte
  • src/tests/navbar/custom-breakpoint.test.svelte
  • src/tests/list-group/rounded-listgroup.test.svelte
  • src/tests/indicator/color-indicator.test.svelte
  • src/tests/modal/basic-modal.test.svelte
  • src/tests/modal/dismissable-modal.test.svelte
  • src/tests/navbar/navbar.test.ts
  • src/redirects.js
  • src/tests/list-group/link-listgroup.test.svelte
  • src/tests/list-group/active-listgroup.test.svelte
  • src/tests/modal/permanent-modal.test.svelte
  • src/tests/navbar/active-link.test.svelte
  • src/tests/mega-menu/mega-menu.test.ts
  • src/tests/list-group/custom-listgroup.test.svelte
  • src/tests/forms/floating-label/floating-label-clearable-empty.test.svelte
  • vite.config.ts
  • src/tests/indicator/indicator.test.ts
  • src/tests/indicator/border-indicator.test.svelte
  • src/tests/kbd/multiple-kbd.test.svelte
  • src/tests/kbd/basic-kbd.test.svelte
  • src/tests/navbar/custom-classes.test.svelte
  • src/tests/gallery/custom-figure-gallery.test.svelte
  • src/tests/mega-menu/basic-mega-menu.test.svelte
  • src/tests/indicator/corner-style-indicator.test.svelte
  • src/tests/navbar/custom-active-classes.test.svelte
  • src/tests/modal/modal.test.ts
  • src/tests/mega-menu/custom-mega-menu.test.svelte
  • src/lib/pagination/PaginationNav.svelte
  • src/tests/list-group/listgroup.test.ts
  • src/tests/indicator/size-indicator.test.svelte
  • src/tests/list-group/border-listgroup.test.svelte
  • src/tests/kbd/kbd.test.ts
  • src/lib/navbar/Navbar.svelte
  • src/tests/gallery/basic-gallery.test.svelte
  • src/lib/list-group/theme.ts
  • src/tests/navbar/fluid-navbar.test.svelte
  • src/tests/gallery/gallery.test.ts
  • src/tests/navbar/basic-navbar.test.svelte
  • src/tests/navbar/nav-brand.test.svelte
  • src/tests/list-group/basic-listgroup.test.svelte
  • src/tests/navbar/navli-button.test.svelte
  • src/tests/modal/fullscreen-modal.test.svelte
  • src/tests/modal/title-modal.test.svelte
  • src/tests/gallery/custom-class-gallery.test.svelte
  • src/tests/navbar/navli-click.test.svelte
  • src/tests/modal/size-modal.test.svelte
  • src/tests/list-group/horizontal-listgroup.test.svelte
  • src/hooks.server.js
  • src/tests/gallery/empty-gallery.test.svelte
  • src/tests/mega-menu/full-mega-menu.test.svelte
  • src/tests/indicator/basic-indicator.test.svelte
  • src/tests/kbd/custom-class-kbd.test.svelte
🧠 Learnings (6)
📚 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/navbar/menu-icon.test.svelte
  • src/routes/utils/ThemeSelector.svelte
  • src/tests/modal/footer-modal.test.svelte
  • src/routes/theme-test/text-variables/+page.svelte
  • src/tests/list-group/disabled-listgroup.test.svelte
  • src/tests/indicator/placement-indicator.test.svelte
  • src/tests/navbar/custom-breakpoint.test.svelte
  • src/tests/list-group/rounded-listgroup.test.svelte
  • src/tests/indicator/color-indicator.test.svelte
  • src/tests/modal/basic-modal.test.svelte
  • src/tests/modal/dismissable-modal.test.svelte
  • src/tests/list-group/link-listgroup.test.svelte
  • src/tests/list-group/active-listgroup.test.svelte
  • src/tests/modal/permanent-modal.test.svelte
  • src/tests/navbar/active-link.test.svelte
  • src/tests/list-group/custom-listgroup.test.svelte
  • src/tests/forms/floating-label/floating-label-clearable-empty.test.svelte
  • src/tests/indicator/border-indicator.test.svelte
  • src/tests/kbd/multiple-kbd.test.svelte
  • src/tests/kbd/basic-kbd.test.svelte
  • src/tests/navbar/custom-classes.test.svelte
  • src/tests/gallery/custom-figure-gallery.test.svelte
  • src/tests/mega-menu/basic-mega-menu.test.svelte
  • src/tests/indicator/corner-style-indicator.test.svelte
  • src/tests/navbar/custom-active-classes.test.svelte
  • src/tests/mega-menu/custom-mega-menu.test.svelte
  • src/lib/pagination/PaginationNav.svelte
  • src/tests/indicator/size-indicator.test.svelte
  • src/tests/list-group/border-listgroup.test.svelte
  • src/lib/navbar/Navbar.svelte
  • src/tests/gallery/basic-gallery.test.svelte
  • src/tests/navbar/fluid-navbar.test.svelte
  • src/tests/navbar/basic-navbar.test.svelte
  • src/tests/navbar/nav-brand.test.svelte
  • src/tests/list-group/basic-listgroup.test.svelte
  • src/tests/navbar/navli-button.test.svelte
  • src/tests/modal/fullscreen-modal.test.svelte
  • src/tests/modal/title-modal.test.svelte
  • src/tests/gallery/custom-class-gallery.test.svelte
  • src/tests/navbar/navli-click.test.svelte
  • src/tests/modal/size-modal.test.svelte
  • src/tests/list-group/horizontal-listgroup.test.svelte
  • src/tests/gallery/empty-gallery.test.svelte
  • src/tests/mega-menu/full-mega-menu.test.svelte
  • src/tests/indicator/basic-indicator.test.svelte
  • src/tests/kbd/custom-class-kbd.test.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/utils/ThemeSelector.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/utils/ThemeSelector.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/navbar/navbar.test.ts
  • src/redirects.js
  • src/hooks.server.js
📚 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/redirects.js
  • src/hooks.server.js
📚 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:

  • vite.config.ts
  • src/tests/navbar/fluid-navbar.test.svelte
  • src/tests/navbar/basic-navbar.test.svelte
  • src/hooks.server.js
🧬 Code graph analysis (3)
src/redirects.js (1)
src/hooks.server.js (2)
  • dir (19-19)
  • file (18-18)
src/lib/list-group/theme.ts (2)
src/lib/list-group/index.ts (1)
  • listGroup (3-3)
src/lib/theme/themeUtils.ts (1)
  • Classes (42-48)
src/hooks.server.js (1)
src/redirects.js (1)
  • getRedirectPath (19-25)
🔇 Additional comments (59)
src/tests/forms/floating-label/floating-label-clearable-empty.test.svelte (2)

1-5: LGTM! Script block is correctly structured.

The import and reactive state initialization using Svelte 5's $state() rune are correct. The empty string initial value appropriately tests the "clearable-empty" scenario.


7-7: Verify the test structure and add assertions if needed.

This file is named .test.svelte but contains no test assertions, DOM queries, or validation logic. The AI summary indicates that "tests were updated to... synchronize DOM state with Svelte reactivity, following patterns similar to the FileUpload clearable tests (waitFor usage to observe DOM updates and button visibility after state changes)," but none of that logic appears in this file.

Based on the expected behavior (clear button should NOT be visible when value is empty), consider adding:

  • Test assertions to verify the clear button is not present initially
  • Logic to update the value and verify the clear button appears
  • DOM queries and waitFor patterns as described in the PR context

Is this file intended as a minimal visual test fixture, or should it include functional test logic?

💡 Example test structure with assertions
 <script lang="ts">
   import { FloatingLabelInput } from "$lib";
+  import { waitFor } from "@testing-library/svelte";

   let value = $state("");
+
+  // Test: Clear button should not be visible when value is empty
+  $effect(() => {
+    waitFor(() => {
+      const clearButton = document.querySelector('[data-testid="clear-button"]');
+      if (!clearButton) {
+        console.log("✓ Clear button correctly hidden when value is empty");
+      }
+    });
+  });
+
+  // Test: Clear button should appear when value is set
+  setTimeout(() => {
+    value = "test input";
+    waitFor(() => {
+      const clearButton = document.querySelector('[data-testid="clear-button"]');
+      if (clearButton) {
+        console.log("✓ Clear button correctly shown when value is present");
+      }
+    });
+  }, 100);
 </script>

 <FloatingLabelInput bind:value clearable={true} id="test-clearable-empty" name="test-clearable-empty" type="text">Clearable Input</FloatingLabelInput>

Note: Adjust the test implementation to match your testing framework and conventions.

src/routes/utils/ThemeSelector.svelte (1)

21-28: Button interaction pattern uses one-way control.

The Button's onclick handler only sets isOpen = true (line 24), but never toggles it to false. This means clicking the button when the dropdown is already open won't close it. The Dropdown component with bind:isOpen (line 28) likely handles closing via its internal logic (e.g., clicking outside, ESC key, or selecting an item).

While this is a valid pattern if the Dropdown component properly manages its own closure, it may create an inconsistent user experience. Users typically expect a trigger button to toggle the dropdown state (open ↔ closed).

Please verify that:

  1. The Flowbite Dropdown component properly closes when clicking outside, pressing ESC, or selecting an item
  2. This one-way pattern aligns with your intended UX—if users expect the button to toggle the dropdown, consider changing to:
🔎 Alternative toggle pattern
-<Button onclick={() => (isOpen = true)} color="gray" class="gap-2 rounded-xl border-0 px-1.5 py-1.5 shadow-none focus:ring-gray-100 dark:focus:ring-gray-700" aria-haspopup="true" aria-expanded={isOpen} aria-label="Select Theme">
+<Button onclick={() => (isOpen = !isOpen)} color="gray" class="gap-2 rounded-xl border-0 px-1.5 py-1.5 shadow-none focus:ring-gray-100 dark:focus:ring-gray-700" aria-haspopup="true" aria-expanded={isOpen} aria-label="Select Theme">

Based on learnings, the use of $derived() for theme values (lines 8-9) correctly ensures reactivity to theme changes.

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

1-5: LGTM! Clean test fixture.

The test component correctly imports and renders the Kbd component with a simple text label, providing a clean fixture for basic rendering tests.

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

1-7: LGTM! Tests multiple Kbd component rendering.

The test fixture correctly demonstrates rendering multiple Kbd components in sequence with separator text, providing good coverage for a common keyboard shortcut display pattern.

src/tests/kbd/kbd.test.ts (3)

1-10: LGTM! Proper test setup.

The imports and cleanup configuration are correctly structured using @testing-library/svelte and Vitest best practices.


12-26: LGTM! Basic rendering and styling tests are correct.

The tests properly verify that the Kbd component renders as a <kbd> HTML element and applies the expected default styling classes.


43-55: LGTM! Custom class tests verify proper class merging.

The tests correctly verify that custom classes can be applied while preserving the base component styling. This ensures the component properly merges user-provided classes with default styles.

src/tests/kbd/custom-class-kbd.test.svelte (1)

5-5: Verify class prop usage aligns with new API pattern.

The test uses the class prop for custom styling. However, the PR summary mentions "introducing a unified classes prop pattern" as part of standardizing component styling APIs. Ensure this test reflects the correct API—if Kbd now uses a classes prop instead of class, the test should be updated accordingly.

Run the following script to check the Kbd component's prop definitions:

#!/bin/bash
# Description: Verify Kbd component's styling prop API (class vs classes)

# Search for Kbd component prop definitions
ast-grep --pattern $'export let class$$$' src/lib/**/Kbd.svelte src/lib/**/kbd*.svelte
ast-grep --pattern $'export let classes$$$' src/lib/**/Kbd.svelte src/lib/**/kbd*.svelte

# Also check for interface definitions
rg -nP --type=svelte --type=ts 'interface.*Kbd.*Props' -A 10
src/hooks.server.js (1)

13-14: LGTM: Test mode detection is correct.

The dual check for both VITEST and NODE_ENV appropriately covers different testing scenarios.

src/redirects.js (1)

5-17: LGTM: File path processing logic is correct.

The chained transformations correctly extract category/filename pairs from the markdown file paths for redirect matching.

src/lib/pagination/PaginationNav.svelte (5)

1-7: LGTM! Imports are appropriate.

All necessary utilities and types are properly imported.


34-36: LGTM! Theme derivation follows best practices.

The getTheme() call is correctly placed inside $derived() rather than at module scope, ensuring components react to dynamic theme changes. The styling derivation is clean and straightforward.

Based on learnings, this is the correct pattern for reactive theming.


57-63: Clarify the lastPage calculation difference between layouts.

Line 59 uses different logic for table vs pagination layouts:

  • pagination: currentPage + halfVisiblePages (symmetric window)
  • table: currentPage + halfVisiblePages * 2 (more pages on the right)

The rationale for this asymmetry in table layout is not documented. If this is intentional behavior, please add a comment explaining why table layout requires showing more pages to the right of the current page.


77-116: LGTM! Template properly merges theme and custom classes.

The template consistently merges theme and styling (from the classes prop) using clsx() with safe optional chaining throughout. The defensive check for pageNumbers.length > 0 on line 97 is appropriate, and the navigation helpers properly clamp to valid page boundaries.


38-55: activeClasses from context is properly consumed by PaginationButton.

The context correctly exposes activeClasses from the unified classes prop, and PaginationButton properly consumes it with safe null-checking (ctx?.activeClasses) before applying it via clsx() at line 23 of PaginationButton.svelte.

vite.config.ts (2)

74-78: LGTM!

Explicit environment variables for both client and server test projects ensure consistent test detection across different execution contexts.

Also applies to: 87-90


93-103: LGTM!

The onConsoleLog hook complements the stderr filter, ensuring these SvelteKit-specific messages are suppressed in console output as well.

src/lib/list-group/theme.ts (3)

1-5: LGTM!

The type definitions correctly combine VariantProps with Classes to enable both variant props and slot-based class overrides. This aligns with the unified classes prop pattern described in the PR.


7-38: LGTM!

The slot-based structure with base, item, and icon slots provides a clean API for styling different parts of the list group. The compound variant correctly applies divider colors when border: true.


45-80: LGTM!

The variant definitions for state, active, and horizontal behaviors are well-structured. The compound variants correctly combine active and state conditions for hover/focus styling.

src/tests/list-group/link-listgroup.test.svelte (1)

1-11: LGTM!

Clean test fixture that exercises the link-enabled Listgroup rendering path with object items containing name and href properties. This complements the existing test coverage for string-based items.

src/tests/navbar/nav-brand.test.svelte (1)

1-12: LGTM!

Well-structured test fixture demonstrating NavBrand composition within Navbar using the Svelte 5 snippet pattern. The data-testid attribute enables reliable DOM querying in the test suite.

src/tests/list-group/rounded-listgroup.test.svelte (1)

1-7: LGTM!

Concise test fixture for the rounded variant of Listgroup. This aligns with the slot-based variant refactoring in theme.ts where rounded: true applies rounded-lg to the base slot.

src/tests/gallery/empty-gallery.test.svelte (1)

1-7: LGTM!

This test verifies Gallery accepts custom slot content when no images prop is provided. The test correctly exercises the fallback rendering path.

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

1-5: LGTM!

Simple and effective baseline test for the Indicator component's default rendering. The data-testid attribute enables verification in the corresponding test suite.

src/tests/indicator/size-indicator.test.svelte (1)

1-8: LGTM!

Thorough test fixture covering all four size variants (sm, md, lg, xl) of the Indicator component. Each variant has a distinct data-testid for targeted assertions.

src/tests/indicator/color-indicator.test.svelte (1)

1-8: LGTM! Well-structured color variant test.

The test covers the key color variants (brand, success, danger, warning) with proper data-testid attributes for assertions. The structure is clean and aligns with the existing indicator test suite patterns.

src/tests/navbar/menu-icon.test.svelte (1)

1-9: LGTM! Comprehensive menu icon variant test.

The test effectively covers different Menu variations (outline, solid) and custom color styling, with proper data-testid attributes for test assertions. Well-structured test following best practices.

src/tests/indicator/corner-style-indicator.test.svelte (1)

1-6: LGTM! Clear corner style variant test.

The test covers circular and rounded corner styles with appropriate data-testid attributes for assertions. The structure is clean and consistent with the indicator test suite.

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

4-8: These tests use Vitest with @testing-library/svelte to perform unit testing of the Gallery component. The tests only verify that the component renders <img> elements with correct src and alt attributes—they do not load or display actual images. The hardcoded paths are intentional and do not need to correspond to existing image files for the unit tests to pass.

Likely an incorrect or invalid review comment.

src/tests/list-group/custom-listgroup.test.svelte (1)

1-16: Excellent test implementation!

This test effectively demonstrates custom Listgroup rendering using Svelte 5 snippets. The code:

  • Correctly uses the children snippet for custom item rendering
  • Properly destructures the item parameter from the snippet
  • Includes data-testid attributes for reliable test targeting
  • Applies custom styling via the class prop

The implementation aligns well with the new classes-based styling API introduced in this PR.

src/tests/modal/footer-modal.test.svelte (1)

1-14: LGTM! Clean modal footer test.

The test correctly implements:

  • Svelte 5's $state rune for reactive state management
  • Two-way binding with bind:open for modal visibility
  • The footer snippet for custom footer content
  • Button onclick handler to open the modal

The implementation follows best practices and aligns with the modal component's API.

src/tests/indicator/border-indicator.test.svelte (1)

1-6: LGTM! Well-structured border variant test.

The test cleanly covers both border states (true/false) with distinct data-testid attributes for reliable test targeting. The implementation is straightforward and follows the established testing patterns in the indicator test suite.

src/tests/modal/permanent-modal.test.svelte (1)

1-11: LGTM! Effective permanent modal test.

The test correctly exercises the permanent (non-dismissable) modal scenario:

  • Uses Svelte 5's $state for reactive state
  • Applies dismissable={false} to prevent modal dismissal
  • Two-way binding with bind:open manages visibility
  • Button interaction pattern is clear and testable

This test complements the broader modal test suite by covering the permanent modal use case.

src/tests/modal/fullscreen-modal.test.svelte (1)

1-11: LGTM! Clean fullscreen modal test.

The test properly verifies the fullscreen modal variant:

  • Correctly uses Svelte 5's $state rune
  • Applies size="fullscreen" to test the size variant
  • Two-way binding with bind:open for state management
  • Button trigger pattern is clear and consistent

The implementation follows the established modal testing patterns in this PR.

src/tests/indicator/placement-indicator.test.svelte (1)

1-8: LGTM! Comprehensive placement test.

The test effectively covers all four corner placements for the Indicator component:

  • Each placement variant has a descriptive data-testid
  • Consistent naming pattern ({placement}-indicator)
  • Complete coverage of placement options

This aligns well with the indicator test suite structure and provides thorough coverage of the placement API.

src/tests/navbar/custom-breakpoint.test.svelte (1)

1-12: Excellent navbar breakpoint test!

The test effectively demonstrates responsive navbar behavior with a custom breakpoint:

  • Correctly uses the children snippet with destructured { hidden, toggle } parameters
  • Properly wires toggle to NavHamburger's onclick handler
  • Passes hidden state to NavUl for responsive visibility
  • Applies breakpoint="lg" to test custom breakpoint behavior
  • Includes data-testid for reliable test targeting

The implementation follows Svelte 5 patterns correctly and aligns with the new navbar API structure introduced in this PR.

src/tests/gallery/custom-class-gallery.test.svelte (1)

1-12: LGTM!

The test correctly exercises the new classes prop API for the Gallery component, testing both the container class and nested classes.image customization. This aligns well with the API changes that replaced imgClass with the unified classes prop pattern.

src/tests/gallery/custom-figure-gallery.test.svelte (1)

1-18: LGTM!

The test correctly demonstrates the custom figure snippet pattern for the Gallery component. The snippet-based approach allows flexible rendering of gallery items with custom captions, and the data-testid="custom-caption" enables proper test assertions.

src/tests/navbar/fluid-navbar.test.svelte (1)

1-13: LGTM!

The test correctly exercises the fluid Navbar variant using the snippet-based children pattern. The hidden and toggle props are properly destructured and wired to control the responsive menu behavior.

src/tests/navbar/custom-classes.test.svelte (1)

1-13: LGTM!

Excellent test coverage for custom class application across all Navbar subcomponents. Each component receives a distinct custom class name (custom-navbar-class, custom-brand-class, etc.), which makes test assertions straightforward and verifies that the class prop propagates correctly through the component hierarchy.

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

1-17: LGTM!

This test provides a solid baseline for the standard Navbar composition pattern, demonstrating the canonical usage with NavBrand, NavHamburger, and multiple NavLi items within a NavUl. The snippet-based children pattern with hidden/toggle is correctly implemented.

src/tests/list-group/active-listgroup.test.svelte (1)

1-11: LGTM!

The test correctly exercises the active state styling for Listgroup and its items. The data-testid="active-listgroup" wrapper enables easy DOM querying in the corresponding test file.

src/tests/mega-menu/basic-mega-menu.test.svelte (1)

1-16: LGTM!

The test correctly demonstrates basic MegaMenu usage with a Button trigger and item rendering via snippets. The triggeredBy selector properly matches the button ID, and the snippet structure aligns with the MegaMenu API.

src/tests/modal/size-modal.test.svelte (1)

1-17: LGTM!

The test correctly demonstrates Modal size variations using Svelte 5 runes. The state management with $state and two-way binding with bind:open properly control modal visibility.

src/tests/navbar/navli-button.test.svelte (1)

1-13: LGTM!

The test correctly demonstrates Navbar composition with NavHamburger toggle functionality. The snippet pattern properly exposes hidden and toggle states, and the NavLi items correctly differentiate between button (no href) and link (with href) behaviors.

src/tests/mega-menu/custom-mega-menu.test.svelte (1)

1-17: LGTM!

The test effectively demonstrates MegaMenu with custom content rendering. The snippet correctly uses both item and index parameters, and the dynamic test IDs enable precise element targeting in tests.

src/tests/navbar/navli-click.test.svelte (1)

1-27: LGTM!

The test correctly demonstrates click handling in Navbar components. The dual state management (module-level testState and component-level $state) enables both external verification and internal reactivity, which is appropriate for testing scenarios.

src/tests/navbar/active-link.test.svelte (1)

1-16: LGTM!

The test correctly demonstrates active link state management in Navbar. The activeUrl binding on NavUl enables dynamic active state tracking, and the initial value of "/about" sets up the test scenario appropriately.

src/tests/navbar/custom-active-classes.test.svelte (1)

1-15: LGTM!

The test correctly demonstrates NavLi's activeClass and nonActiveClass props, which allow per-item class customization that overrides the context-provided classes from NavUl. The test setup with activeUrl="/about" properly validates custom styling for non-active items.

src/tests/mega-menu/full-mega-menu.test.svelte (1)

1-17: LGTM!

The test correctly demonstrates full-width MegaMenu usage with the full prop. The dual snippet pattern (children for item rendering, extra for additional content) properly showcases the MegaMenu's flexibility for full-width layouts.

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

1-92: Well-structured test suite with comprehensive coverage.

The test organization is excellent, covering basic rendering, custom figures, empty states, and custom classes. The use of afterEach cleanup and descriptive test names follows best practices.

src/tests/list-group/listgroup.test.ts (1)

1-126: Comprehensive test coverage for ListGroup variants.

The test suite effectively covers basic rendering, active state, horizontal/rounded/border variants, links, disabled state, and custom classes. Good use of describe blocks for organization.

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

1-147: Excellent test coverage for Indicator component.

This test suite demonstrates best practices with comprehensive coverage of all Indicator variants (colors, sizes, borders, placements, corner styles). The use of test IDs for element selection is appropriate and the test organization is clear.

src/lib/navbar/Navbar.svelte (2)

9-14: Correct reactive theme pattern with $derived.

The implementation properly wraps getTheme("navbar") inside a $derived() expression (Line 12), ensuring the component reacts to dynamic theme changes from ThemeProvider. This aligns with the established pattern for reactive themes in Flowbite-Svelte.

Based on learnings, this is the correct approach for theme reactivity.


42-43: No action required. The base and navContainerClass functions are properly derived from the navbar() theme function using tailwind-variants slots configuration, and they correctly handle class merging with clsx. The implementation matches expected patterns.

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

1-202: Comprehensive and well-structured Modal test suite.

The tests provide excellent coverage of modal variants with proper use of waitFor for asynchronous assertions. The accessibility-focused approach using getByLabelText("Close") (Line 46, etc.) ensures the close button is properly labeled.

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

20-362: Comprehensive navbar test coverage with minor improvement opportunities.

The test suite provides excellent coverage of Navbar functionality including basic rendering, props, toggle behavior, custom classes, and all sub-components. The organization with nested describe blocks is clear and maintainable.

Comment on lines 5 to 10
const fontSizeVariables = [
"text-2xs",
];
const spacingVariables = [
"spacing-8xl",
];
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 25, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Incomplete token arrays detected.

Both fontSizeVariables and spacingVariables contain only a single item each, while other token arrays are more comprehensive. This suggests incomplete implementation.

If this is work in progress, would you like me to help generate a more complete list of Tailwind font-size and spacing utility classes for testing purposes?

🤖 Prompt for AI Agents
In src/routes/theme-test/text-variables/+page.svelte around lines 5–10, the
fontSizeVariables and spacingVariables arrays currently contain only a single
item each, indicating incomplete token sets; replace them with comprehensive
lists of Tailwind utility tokens used in the project (e.g., include the full
range of text-* sizes you support such as 2xs, xs, sm, base, lg, xl, 2xl,
3xl…9xl or your configured scale) and a full spacing scale (spacing-0,
spacing-0.5/1/2/3…, or spacing-1 through spacing-96/128 depending on your
Tailwind config) so tests cover realistic variants; ensure the lists match your
Tailwind config and remove or comment any values not present in your design
system.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In future it may increase. So please ignore for now.

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 for now since you plan to expand these arrays in the future. Thanks for the context.


🧠 Learnings used
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.

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/tests/footer/footer-brand-no-name.test.svelte (1)

5-5: Duplicate verification already requested.

This file makes the same logo URL update as the other test fixtures. Verification of the URL accessibility has already been requested in the review of basic-footer-brand.test.svelte.

src/tests/footer/footer-brand-no-link.test.svelte (1)

5-5: Duplicate verification already requested.

This file makes the same logo URL update as the other test fixtures. Verification of the URL accessibility has already been requested in the review of basic-footer-brand.test.svelte.

🧹 Nitpick comments (3)
src/lib/list-group/theme.ts (1)

72-79: Consider removing or implementing the commented-out compound variants.

These commented focus styling rules for horizontal navigation appear to be incomplete work. If they're planned for future implementation, consider adding a TODO comment explaining the intent; otherwise, remove the dead code to reduce noise.

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

83-95: Hidden state detection relies on CSS class substring matching.

The selector [class*='hidden'] may produce false positives if other classes contain "hidden" as a substring, or false negatives if the hiding mechanism changes. Consider using a more semantic approach like checking aria-expanded on the hamburger button or testing element visibility directly.

🔎 Suggested alternative
-      // Menu should be hidden initially
-      const menuContainer = container.querySelector("[class*='hidden']");
-      expect(menuContainer).toBeTruthy();
+      // Menu should be hidden initially - check hamburger aria-expanded
+      expect(hamburger).toHaveAttribute("aria-expanded", "false");

Or if aria-expanded isn't available, use visibility testing:

const ul = container.querySelector("ul");
expect(ul).not.toBeVisible();
src/lib/pagination/PaginationNav.svelte (1)

132-137: Inconsistent documentation format for nested classes props.

The classes.* props use a different format (@prop classes.tableDiv - description) compared to other props. For consistency with the existing documentation style, consider aligning these or documenting them as part of @prop classes with a type reference.

📜 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 ec385e1 and d7250d5.

📒 Files selected for processing (46)
  • src/hooks.server.js
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/lib/list-group/ListgroupItem.svelte
  • src/lib/list-group/theme.ts
  • src/lib/modal/Modal.svelte
  • src/lib/modal/theme.ts
  • src/lib/navbar/index.ts
  • src/lib/pagination/PaginationNav.svelte
  • src/lib/types.ts
  • src/routes/+page.server.ts
  • src/routes/admin-dashboard/(sidebar)/Navbar.svelte
  • src/routes/theme-test/text-variables/+page.svelte
  • src/routes/utils/ThemeSelector.svelte
  • src/tests/footer/basic-footer-brand.test.svelte
  • src/tests/footer/footer-brand-no-link.test.svelte
  • src/tests/footer/footer-brand-no-name.test.svelte
  • src/tests/footer/footer-brand.test.ts
  • src/tests/forms/floating-label/floating-label.test.ts
  • src/tests/gallery/basic-gallery.test.svelte
  • src/tests/gallery/custom-class-gallery.test.svelte
  • src/tests/gallery/custom-figure-gallery.test.svelte
  • src/tests/gallery/gallery.test.ts
  • src/tests/kbd/kbd.test.ts
  • src/tests/list-group/basic-listgroup.test.svelte
  • src/tests/list-group/border-listgroup.test.svelte
  • src/tests/list-group/custom-listgroup.test.svelte
  • src/tests/list-group/disabled-listgroup.test.svelte
  • src/tests/list-group/horizontal-listgroup.test.svelte
  • src/tests/list-group/listgroup.test.ts
  • src/tests/mega-menu/basic-mega-menu.test.svelte
  • src/tests/mega-menu/full-mega-menu.test.svelte
  • src/tests/mega-menu/mega-menu.test.ts
  • src/tests/modal/basic-modal.test.svelte
  • src/tests/modal/dismissable-modal.test.svelte
  • src/tests/modal/footer-modal.test.svelte
  • src/tests/modal/fullscreen-modal.test.svelte
  • src/tests/modal/modal.test.ts
  • src/tests/modal/permanent-modal.test.svelte
  • src/tests/modal/size-modal.test.svelte
  • src/tests/modal/title-modal.test.svelte
  • src/tests/navbar/active-link.test.svelte
  • src/tests/navbar/custom-active-classes.test.svelte
  • src/tests/navbar/nav-brand.test.svelte
  • src/tests/navbar/navbar.test.ts
  • src/tests/navbar/navli-click.test.svelte
  • vite.config.ts
💤 Files with no reviewable changes (1)
  • src/hooks.server.js
🚧 Files skipped from review as they are similar to previous changes (26)
  • src/tests/gallery/custom-figure-gallery.test.svelte
  • src/tests/navbar/nav-brand.test.svelte
  • src/tests/kbd/kbd.test.ts
  • src/tests/modal/dismissable-modal.test.svelte
  • src/tests/modal/basic-modal.test.svelte
  • src/tests/modal/title-modal.test.svelte
  • src/tests/navbar/custom-active-classes.test.svelte
  • src/tests/gallery/gallery.test.ts
  • src/routes/utils/ThemeSelector.svelte
  • src/tests/forms/floating-label/floating-label.test.ts
  • src/tests/mega-menu/mega-menu.test.ts
  • src/tests/modal/modal.test.ts
  • src/tests/list-group/horizontal-listgroup.test.svelte
  • src/tests/mega-menu/full-mega-menu.test.svelte
  • src/tests/list-group/custom-listgroup.test.svelte
  • src/routes/theme-test/text-variables/+page.svelte
  • src/tests/modal/size-modal.test.svelte
  • src/tests/list-group/disabled-listgroup.test.svelte
  • src/tests/gallery/custom-class-gallery.test.svelte
  • src/tests/modal/footer-modal.test.svelte
  • src/lib/list-group/ListgroupItem.svelte
  • src/tests/modal/permanent-modal.test.svelte
  • src/tests/gallery/basic-gallery.test.svelte
  • src/tests/list-group/border-listgroup.test.svelte
  • src/tests/navbar/navli-click.test.svelte
  • vite.config.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/lib/navbar/index.ts
  • src/tests/list-group/basic-listgroup.test.svelte
  • src/routes/admin-dashboard/(sidebar)/Navbar.svelte
  • src/tests/footer/footer-brand-no-link.test.svelte
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/tests/footer/footer-brand-no-name.test.svelte
  • src/tests/navbar/active-link.test.svelte
  • src/tests/footer/basic-footer-brand.test.svelte
  • src/tests/list-group/listgroup.test.ts
  • src/tests/footer/footer-brand.test.ts
  • src/tests/navbar/navbar.test.ts
  • src/lib/list-group/theme.ts
  • src/routes/+page.server.ts
  • src/lib/pagination/PaginationNav.svelte
  • src/lib/modal/theme.ts
  • src/lib/types.ts
  • src/tests/modal/fullscreen-modal.test.svelte
  • src/lib/modal/Modal.svelte
  • src/tests/mega-menu/basic-mega-menu.test.svelte
🧠 Learnings (4)
📓 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-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-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/tests/list-group/basic-listgroup.test.svelte
  • src/routes/admin-dashboard/(sidebar)/Navbar.svelte
  • src/tests/footer/footer-brand-no-link.test.svelte
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/tests/footer/footer-brand-no-name.test.svelte
  • src/tests/navbar/active-link.test.svelte
  • src/tests/footer/basic-footer-brand.test.svelte
  • src/lib/pagination/PaginationNav.svelte
  • src/tests/modal/fullscreen-modal.test.svelte
  • src/lib/modal/Modal.svelte
  • src/tests/mega-menu/basic-mega-menu.test.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/footer/footer-brand-no-name.test.svelte
  • src/tests/footer/basic-footer-brand.test.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/navbar/navbar.test.ts
🧬 Code graph analysis (3)
src/lib/list-group/theme.ts (2)
src/lib/list-group/index.ts (2)
  • listGroup (3-3)
  • listGroupItem (3-3)
src/lib/theme/themeUtils.ts (1)
  • Classes (42-48)
src/routes/+page.server.ts (1)
src/routes/utils/index.ts (4)
  • fetchMarkdownPosts (71-122)
  • fetchBlocksMarkdownPosts (150-166)
  • fetchBuilders (124-136)
  • fetchDashboardPosts (168-207)
src/lib/types.ts (1)
src/lib/navbar/theme.ts (1)
  • NavbarVariants (10-10)
🔇 Additional comments (23)
src/tests/mega-menu/basic-mega-menu.test.svelte (2)

1-5: LGTM! Test setup is clean and correct.

The imports and test data structure are appropriate. The items array matches the expected structure used in the snippet below.


7-12: LGTM! MegaMenu integration is correctly structured.

The Button trigger and MegaMenu component are properly connected via the triggeredBy selector. The Svelte 5 snippet syntax is correct, and the destructured item parameter properly accesses the name property.

This appears to be a minimal render fixture (appropriate for a .test.svelte file) that's likely consumed by the test suite in mega-menu.test.ts.

src/tests/footer/footer-brand.test.ts (1)

29-29: LGTM! Test assertions updated to match fixture changes.

The test expectations have been correctly updated to verify the new logo URL. These changes are properly synchronized with the updates made to the test fixture files (basic-footer-brand.test.svelte, footer-brand-no-link.test.svelte, and footer-brand-no-name.test.svelte).

Also applies to: 49-49

src/tests/footer/basic-footer-brand.test.svelte (1)

5-5: Logo URL correctly updated to flowbite-svelte.com across test fixtures.

The src prop has been updated consistently in all FooterBrand test files. The href attribute remains as https://flowbite.com, which is intentional and properly tested. The image URL is accessible and the component usage is correct.

src/lib/forms/floating-label/FloatingLabelInput.svelte (3)

38-39: LGTM! Good readability improvement.

Extracting the clear button visibility logic into a named derived state improves code clarity.


41-53: LGTM! Signature updated for API consistency.

The optional MouseEvent parameter aligns the function signature with the dismissable context system, even though it's currently unused within the function body.


183-185: CloseButton API accepts ariaLabel prop correctly. The component destructures and uses this prop on lines 21 and 36, with proper fallback to the name prop. The usage in FloatingLabelInput.svelte is compatible.

src/routes/+page.server.ts (2)

1-7: LGTM! Clean refactoring for prerendering.

The changes properly shift from API endpoint consumption to direct data fetching, which is appropriate for prerendered pages. The json helper reduces boilerplate, and moving the prerender export after imports follows standard conventions.


30-39: Good defensive coding with structured error fallback.

Returning a fully-formed empty data structure prevents downstream undefined errors when components consume the load data. This is a solid improvement over potentially returning undefined values.

src/lib/navbar/index.ts (1)

7-7: LGTM! Public API extension for Menu component.

The addition of the Menu export is consistent with the module's structure and aligns with the test coverage added elsewhere in this PR.

src/tests/list-group/basic-listgroup.test.svelte (1)

1-7: LGTM! Clean test setup.

The basic ListGroup test follows established patterns and provides a simple fixture for the comprehensive test suite. The use of data-testid enables reliable test targeting.

src/routes/admin-dashboard/(sidebar)/Navbar.svelte (1)

97-97: LGTM! Consistent with NavUl API refactoring.

The removal of activeClass aligns with the broader refactoring that consolidates per-slot class props into a unified classes prop approach. The activeUrl binding remains correctly in place for active state management.

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

15-16: LGTM! Extends modal theming surface for close button customization.

The new close slot allows consumers to customize close button styling via the theme system. The empty string default is appropriate and follows the established pattern for optional slot customization.

src/tests/modal/fullscreen-modal.test.svelte (1)

1-11: LGTM! Clean fullscreen modal test.

The test properly exercises the modal with size="xl" for fullscreen-like behavior. The use of $state for the open binding is correct for Svelte 5 runes syntax.

src/tests/navbar/active-link.test.svelte (1)

1-16: LGTM! Well-structured active link test.

The test properly exercises active link state using the refactored Navbar API. The snippet-based children pattern and activeUrl binding are correctly implemented, and data-testid attributes enable reliable assertions.

src/tests/list-group/listgroup.test.ts (1)

1-127: LGTM! Comprehensive test coverage with addressed null check.

The test suite provides excellent coverage of ListGroup functionality across all variants. The previous concern about the null check for .closest("a") has been properly addressed on Line 96 with expect(link1).not.toBeNull(), ensuring graceful test failures.

src/lib/list-group/theme.ts (1)

1-12: Well-structured slot-based theme definitions.

The refactored listGroup and listGroupItem themes correctly implement the slot-based pattern with base, item, and icon slots. The type exports properly combine VariantProps and Classes for type-safe usage.

src/lib/modal/Modal.svelte (2)

29-31: Correctly implements reactive theme access pattern.

The getTheme("modal") call is properly placed inside a $derived() expression, ensuring the component reacts to dynamic theme changes from ThemeProvider. This aligns with the established pattern for Flowbite-Svelte components. Based on learnings.


50-66: Clean styling application with proper null-safety.

The template correctly applies theme and custom styling using optional chaining (styling?.header, styling?.close, etc.), preventing runtime errors when classes prop is not provided.

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

1-18: Comprehensive test coverage for Navbar components.

Excellent coverage spanning basic rendering, props, toggle behavior, custom classes, accessibility, and responsive behavior across Navbar, NavBrand, NavUl, NavLi, NavHamburger, and NavContainer components. The structure with nested describe blocks improves readability and organization.

src/lib/pagination/PaginationNav.svelte (1)

30-32: Correctly implements reactive theme access pattern.

The getTheme("paginationNav") is properly placed inside a $derived() expression for reactive theme updates. Based on learnings.

src/lib/types.ts (2)

48-48: Type imports align with navbar theme definitions.

The addition of NavbarVariants, NavbarUlVariants, and NavbarHamburgerVariants imports correctly corresponds to the new variant types exported from src/lib/navbar/theme.ts.


1117-1122: NavbarProps correctly extends NavbarVariants.

The interface properly incorporates the variant-based props from the navbar theme, consistent with the slot-based styling pattern adopted across the codebase in this PR.

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: 13

Caution

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

⚠️ Outside diff range comments (9)
src/lib/popover/Popover.svelte (1)

41-58: Update component documentation.

The documentation comment at line 50 still references the removed defaultClass prop. This should be removed to match the current API.

🔎 Proposed fix
 ## Props
 @prop title: titleSlot
 @prop color = "default"
 @prop trigger = "hover"
-@prop defaultClass
 @prop arrow = true
 @prop children
 @prop placement = "top"
 @prop class: className
 @prop classes
 @prop isOpen = $bindable(false)
 @prop ...restProps
src/lib/rating/CustomIcon.svelte (1)

54-54: Update stale documentation comment.

The documentation comment still references the old prop name svgClass, but the prop has been renamed to className (Line 15).

🔎 Proposed fix
-@prop svgClass
+@prop class
src/lib/rating/Heart.svelte (1)

58-58: Documentation is out of sync with code.

The doc comment still references @prop svgClass, but the prop has been renamed to class. Update to reflect the actual prop name.

🔎 Proposed fix
-@prop svgClass
+@prop class: className
src/lib/rating/AdvancedRating.svelte (1)

41-48: Documentation references removed props.

The doc comments list divClass, spanClass, div2Class, div3Class, and span2Class as props, but these have been replaced by the unified classes prop. Remove the obsolete prop references.

🔎 Proposed fix
 @prop rating
 @prop globalText
 @prop ratings
-@prop divClass
-@prop spanClass
-@prop div2Class
-@prop div3Class
-@prop span2Class
 @prop class: className
 @prop classes
 @prop unit
src/lib/navbar/Menu.svelte (1)

34-46: Update documentation comment to reflect prop removal.

Line 43 documents @prop ariaLabel = "bars 3", but this prop was removed from the component (line 5). Remove this line from the documentation comment.

🔎 Proposed fix
 ## Props
 @prop size = "24"
 @prop color = "currentColor"
 @prop variation = "outline"
-@prop ariaLabel = "bars 3"
 @prop class: className
 @prop ...restProps
src/lib/sidebar/SidebarDropdownWrapper.svelte (1)

31-38: Documentation props don't match actual component props.

The doc comment block lists imgClass and spanClass (lines 33-34) as props, but these were removed from the component. The actual props are classes (line 88), not the individual class props.

🔎 Proposed fix
 ## Props
 @prop children
 @prop arrowup
 @prop arrowdown
 @prop icon
 @prop isOpen = $bindable()
 @prop label
 @prop transition = slide
 @prop params
 @prop class: className
 @prop classes
 @prop onclick
-@prop imgClass
-@prop spanClass
 @prop ...restProps
src/lib/sidebar/SidebarBrand.svelte (1)

31-37: Documentation props don't match actual component props.

The doc comment block lists imgClass and spanClass (lines 33-34) as props, but these were removed from the component in favor of the unified classes prop.

🔎 Proposed fix
 ## Props
 @prop children
 @prop site
-@prop imgClass
-@prop spanClass
 @prop class: className
 @prop classes
 @prop ...restProps
src/lib/rating/Review.svelte (2)

42-53: Inconsistent class application for list items.

Lines 42 and 49 use clsx(styling?.li) directly, while line 35 correctly uses li({ class: clsx(theme?.li, styling?.li) }). This inconsistency means item2 and item3 won't receive the base styles from the li() function or the theme's li value.

🔎 Proposed fix
         {#if review.item2}
-          <li class={clsx(styling?.li)}>
+          <li class={li({ class: clsx(theme?.li, styling?.li) })}>
             {#if item2}
               {@render item2()}
             {/if}
           </li>
         {/if}
         {#if review.item3}
-          <li class={clsx(styling?.li)}>
+          <li class={li({ class: clsx(theme?.li, styling?.li) })}>
             {#if item3}
               {@render item3()}
             {/if}
           </li>
         {/if}

82-102: Documentation props don't match actual component props.

The doc comment block lists deprecated per-element class props (articleClass, divClass, div2Class, div3Class, imgClass, ulClass, liClass) that were removed from the component in favor of the unified classes prop.

🔎 Proposed fix
 ## Props
 @prop children
 @prop address
 @prop item1
 @prop item2
 @prop item3
 @prop review
 @prop classes
-@prop articleClass
-@prop divClass
-@prop div2Class
-@prop div3Class
-@prop imgClass
-@prop ulClass
-@prop liClass
 -->
♻️ Duplicate comments (1)
src/lib/list-group/theme.ts (1)

40-73: LGTM! listGroupItem refactor follows the same excellent pattern.

The slot-based structure is consistently applied:

  • Slots: base and icon (lines 41-44)
  • Line 43: Uses standard Tailwind classes w-4 h-4 me-1.5 (past review concern about h-15/w-15 has been addressed ✅)
  • Line 49: Appropriate opacity-50 added to disabled state for better UX
  • Compound variants properly structured (lines 60-72)
🧹 Nitpick comments (21)
src/tests/dropdown/dropdown-with-links.test.svelte (1)

14-17: Consider the interaction between href and preventDefault().

Each DropdownItem has both an href attribute (suggesting navigation) and an onclick handler that prevents navigation. This creates a semantic contradiction where the links appear interactive but don't navigate.

If this test is verifying:

  • Visual rendering or accessibility: The current approach is acceptable.
  • Navigation behavior: Consider removing preventDefault() or using a different testing strategy.
  • Click handling: Consider testing without href or documenting why both are needed.
src/routes/utils/index.ts (1)

99-127: Consider extracting duplicated resolution logic.

The resolution logic for pages (lines 99-112) and mcp (lines 114-127) is nearly identical—both sort, map with try/catch, and filter nulls. This could be consolidated into a helper function to reduce duplication.

🔎 Proposed refactor to reduce duplication
+const resolveOrderedMarkdownFiles = async (
+  files: Record<string, () => Promise<{ metadata: Metadata }>>,
+  order: string[]
+): Promise<MarkdownEntry[]> => {
+  const results = await Promise.all(
+    Object.entries(files)
+      .sort(sortByList(order))
+      .map(async ([path, resolver]) => {
+        try {
+          const { metadata } = await resolver();
+          return { meta: metadata, path: toSlug(path) };
+        } catch (error) {
+          console.error(`Failed to resolve markdown file: ${path}`, error);
+          return null;
+        }
+      })
+  );
+  return results.filter((entry): entry is MarkdownEntry => entry !== null);
+};

// Then in fetchMarkdownPosts:
-    const pagesResults = await Promise.all(
-      Object.entries(globs.pages)
-        .sort(sortByList(pageOrder))
-        .map(async ([path, resolver]) => {
-          try {
-            const { metadata } = await resolver();
-            return { meta: metadata, path: toSlug(path) };
-          } catch (error) {
-            console.error(`Failed to resolve page markdown file: ${path}`, error);
-            return null;
-          }
-        })
-    );
-    const pages = pagesResults.filter((entry): entry is MarkdownEntry => entry !== null);
+    const pages = await resolveOrderedMarkdownFiles(globs.pages, pageOrder);

-    const mcpResults = await Promise.all(
-      Object.entries(globs.mcp)
-        .sort(sortByList(mcpOrder))
-        .map(async ([path, resolver]) => {
-          try {
-            const { metadata } = await resolver();
-            return { meta: metadata, path: toSlug(path) };
-          } catch (error) {
-            console.error(`Failed to resolve MCP markdown file: ${path}`, error);
-            return null;
-          }
-        })
-    );
-    const mcp = mcpResults.filter((entry): entry is MarkdownEntry => entry !== null);
+    const mcp = await resolveOrderedMarkdownFiles(globs.mcp, mcpOrder);
src/routes/blocks/utils/Sectioncompo.svelte (1)

47-59: Repeated as Post[] casts could be avoided.

The double cast to Post[] (lines 47 and 50) suggests the derived state typing could be improved by typing sectionPosts as Post[] directly.

🔎 Proposed refactor
-  const sectionPosts = $derived(section !== undefined ? data.blocks[section] : Object.values(data.blocks).flat());
+  const sectionPosts = $derived<Post[]>((section !== undefined ? data.blocks[section] : Object.values(data.blocks).flat()) as Post[]);
   // $inspect('sectionPosts',sectionPosts)

   const searchTermLower = $derived(searchTerm.toLowerCase());
   let blockSelected = $state("");
   let blockCategories = [
     { value: "application", name: "Application UI" },
     { value: "marketing", name: "Marketing UI" },
     { value: "publisher", name: "Publisher UI" }
   ];
-  const filteredSectionPosts = $derived(blockSelected ? (sectionPosts as Post[]).filter((post) => post.meta?.dir === blockSelected) : sectionPosts);
+  const filteredSectionPosts = $derived(blockSelected ? sectionPosts.filter((post) => post.meta?.dir === blockSelected) : sectionPosts);

   const components = $derived(
-    (filteredSectionPosts as Post[]).filter((post) => {
+    filteredSectionPosts.filter((post) => {
src/routes/blocks/+layout.ts (1)

6-11: Consider replacing any[] with proper types.

Using any[] for builders and dashboard loses type safety. If these have known structures, consider defining proper interfaces or importing existing types.

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

88-108: Consider more comprehensive interaction tests.

The current interaction tests only verify that buttons remain in the document after being clicked. They don't validate actual pagination behavior such as page changes, state updates, or disabled states. While these tests serve as basic smoke tests, consider adding assertions that verify the expected side effects of user interactions.

Example enhancement
test("previous button updates page state", async () => {
  const user = userEvent.setup();
  render(BasicPaginationTest);
  
  // Navigate to page 2 first
  const nextButton = screen.getByText("Next");
  await user.click(nextButton);
  
  // Then go back
  const prevButton = screen.getByText("Previous");
  await user.click(prevButton);
  
  // Verify we're back on page 1
  const activeLink = screen.getByRole("link", { current: "page" });
  expect(activeLink).toHaveTextContent("1");
});
src/tests/pagination/pagination-nav.test.ts (1)

123-132: Redundant boundary condition test.

This test is largely redundant with the "disables Previous button on first page" test at lines 82-87. Both verify that the Previous button is disabled on page 1 and check the current page value. The test name suggests it attempts to click the disabled button, but the implementation only checks the disabled state without attempting interaction.

Consider removing or enhancing

Either remove this test as redundant, or enhance it to test additional boundary conditions such as:

  • Verifying Next button is disabled on the last page
  • Attempting to navigate beyond the last page
  • Verifying behavior with totalPages=1 (both buttons disabled)
-  describe("Boundary Conditions", () => {
-    test("stays on first page when clicking Previous on page 1", async () => {
-      render(BasicPaginationNavTest);
-
-      const prevButton = screen.getByText("Previous");
-      expect(prevButton).toBeDisabled();
-
-      expect(screen.getByTestId("current-page")).toHaveTextContent("1");
-    });
-  });
+  describe("Boundary Conditions", () => {
+    test("disables Next button on last page", async () => {
+      const user = userEvent.setup();
+      render(BasicPaginationNavTest);
+      
+      // Navigate to last page
+      // ... implementation
+      
+      const nextButton = screen.getByText("Next");
+      expect(nextButton).toBeDisabled();
+    });
+  });
src/tests/progress/progressbar.test.ts (4)

23-28: Weak assertion: test doesn't verify the width value.

The test "applies correct progress width" only checks if a width style exists, but doesn't validate that the width matches the expected progress value. Consider verifying the actual width percentage.

🔎 Proposed enhancement
 test("applies correct progress width", () => {
   const { container } = render(BasicProgressbarTest);
   const progressFill = container.querySelector('div[style*="width"]');
 
   expect(progressFill).toBeInTheDocument();
+  // Verify actual width value matches the progress prop
+  const style = progressFill?.getAttribute('style');
+  expect(style).toMatch(/width:\s*\d+%/);
 });

39-44: Weak assertion: test doesn't verify label content.

The test "renders with label inside" only checks for a bg- element, not the actual label text or positioning. Consider verifying the label content is present inside the progress bar.


53-58: Redundant test case.

This test duplicates the assertion from the "renders with label outside" test (lines 46-51) which already verifies the "60%" text is present.


62-67: Weak assertion: test doesn't verify custom color is applied.

The test only checks that an element with a bg- class exists, not that the specific custom color from ColoredProgressbarTest is applied. Consider verifying the specific color class (e.g., bg-blue-600).

src/tests/progress/progressradial.test.ts (1)

70-75: Weak assertion: test doesn't verify custom color is applied.

The test only checks that an SVG element exists, not that the custom color from ColoredProgressradialTest is applied. Consider verifying the stroke or fill color on the circle elements.

test-both.sh (1)

1-12: Clarify the purpose of this test script.

This script runs two specific test groups with hardcoded filters. Consider:

  1. Is this intended as a development/debugging tool or part of CI/CD?
  2. If it's for development, adding a comment explaining when to use it would be helpful
  3. If it's for CI, consider making it more robust with error handling
🔎 Optional improvements for robustness
 #!/bin/bash
+set -e  # Exit on error
 
 echo "====================================="
 echo "Testing Simple Aria Components"
 echo "====================================="
 npm run test:unit -- simple-aria --reporter=verbose --run
+EXIT_CODE=$?
 
 echo ""
 echo "====================================="
 echo "Testing Navbar Close on Link Click"
 echo "====================================="
 npm run test:unit -- navbar --run -t "closes mobile menu on link click"
+EXIT_CODE=$((EXIT_CODE + $?))
+
+exit $EXIT_CODE
src/tests/sidebar/sidebar-item.test.ts (1)

83-90: Strengthen the interaction test with meaningful assertions.

The clickability test only verifies that the element remains in the document after clicking, which doesn't validate any actual behavior. Consider adding assertions for expected outcomes such as navigation, state changes, or event handler calls.

Example: Enhanced interaction test
-  describe("Interaction", () => {
-    test("sidebar item link is clickable", async () => {
-      const user = userEvent.setup();
-      render(BasicSidebarTest);
-      const dashboardLink = screen.getByRole("link", { name: /dashboard/i });
-
-      await user.click(dashboardLink);
-      expect(dashboardLink).toBeInTheDocument();
-    });
-  });
+  describe("Interaction", () => {
+    test("sidebar item link is clickable and navigates", async () => {
+      const user = userEvent.setup();
+      const { component } = render(BasicSidebarTest);
+      const dashboardLink = screen.getByRole("link", { name: /dashboard/i });
+
+      // Verify href is correct before click
+      expect(dashboardLink).toHaveAttribute("href", "/dashboard");
+      
+      // For actual navigation testing, you might need to mock navigation
+      await user.click(dashboardLink);
+      
+      // Add meaningful assertion here based on expected behavior
+      expect(dashboardLink).toBeInTheDocument();
+    });
+  });
src/tests/sidebar/sidebar-button.test.ts (1)

40-47: Consider enhancing the interaction test with meaningful assertions.

Similar to the SidebarItem test, this interaction test only verifies that the button remains in the document after clicking, without validating the expected behavior. Consider verifying state changes, such as sidebar visibility toggling or event handler invocation.

Example: Enhanced interaction test
   describe("Interaction", () => {
-    test("button is clickable", async () => {
+    test("button is clickable and triggers sidebar toggle", async () => {
       const user = userEvent.setup();
-      render(BasicSidebarButtonTest);
+      const { component } = render(BasicSidebarButtonTest);
       const button = screen.getByRole("button");
 
+      // You might want to add a prop or spy to verify the onclick handler
+      // or check for expected state changes in the sidebar
       await user.click(button);
       expect(button).toBeInTheDocument();
+      
+      // Example: verify sidebar state changed
+      // expect(component.sidebarIsOpen).toBe(true);
     });
   });
src/tests/popover/popover.test.ts (2)

85-92: Consider strengthening the placement test.

The current test only verifies the trigger button's presence but doesn't validate the actual bottom placement of the popover. Consider adding assertions that check for placement-specific classes or data attributes if available.

💡 Suggested enhancement
   test("applies bottom placement", () => {
     render(ColoredPopoverTest);
     const button = screen.getByRole("button", { name: "Click me" });
     
     expect(button).toBeInTheDocument();
+    // Add assertion to verify popover placement
+    // For example: const popover = screen.getByRole('tooltip');
+    // expect(popover).toHaveAttribute('data-placement', 'bottom');
   });

94-104: Consider enhancing the interaction test.

The test clicks the button but only verifies the button remains present. Consider adding assertions that verify the popover's visibility state changes after the click interaction.

💡 Suggested enhancement
   test("trigger button is clickable", async () => {
     const user = userEvent.setup();
     render(BasicPopoverTest);
     
     const button = screen.getByRole("button", { name: "Hover me" });
     await user.click(button);
     
     expect(button).toBeInTheDocument();
+    // Verify popover state change after click
+    // For example: const popover = screen.getByRole('tooltip');
+    // expect(popover).toBeVisible();
   });
src/lib/rating/Rating.svelte (1)

8-10: Consider deprecating or removing unused pClass prop.

The pClass prop is still declared on Line 8 but no longer used in the styling derivation (Line 10 now uses classes directly without the ?? { p: pClass } fallback). The optional chaining on Line 26 (styling?.p) suggests the prop may be undefined.

If pClass is being kept for backward compatibility, consider adding a deprecation warning. Otherwise, it could be removed from the prop interface.

Also applies to: 26-26

src/lib/navbar/Navbar.svelte (2)

11-11: Consider simplifying the styling derivation.

The styling variable is just re-assigning classes without transformation. Since classes is already reactive as a prop, this derivation may be unnecessary unless there's a specific reason for it.

-  const styling = $derived(classes);

Then use classes?.container directly in the template.


18-23: Minor redundancy in breakpoint context initialization.

setNavbarBreakpointContext(breakpoint) is called at line 18 during component initialization, and the $effect at lines 21-22 will also run on mount, calling it again. Consider removing the initial call at line 18 since the $effect handles both initial setup and subsequent updates.

  setNavbarStateContext(navState);
-  setNavbarBreakpointContext(breakpoint);

-  // Update context when breakpoint prop changes
  $effect(() => {
    setNavbarBreakpointContext(breakpoint);
  });
src/tests/navbar/navbar.test.ts (2)

1-4: Unused import: tick from svelte.

The tick function is imported but only used in commented-out test code (line 226). Consider removing it until the tests are re-enabled.

🔎 Proposed fix
 import { cleanup, render, screen, waitFor } from "@testing-library/svelte";
 import { expect, test, afterEach, describe } from "vitest";
-import { tick } from 'svelte';
 import { userEvent } from "@testing-library/user-event";

78-103: Consider adding a TODO comment explaining why toggle tests are disabled.

Multiple toggle behavior tests are commented out across the file (lines 78-103, 208-233, 340-361). Adding a brief explanation would help future maintainers understand when/if these should be re-enabled.

📜 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 d7250d5 and bbd7e8c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (126)
  • THEME_SELECTOR_FIX.md
  • TROUBLESHOOTING.md
  • package.json
  • src/lib/list-group/ListgroupItem.svelte
  • src/lib/list-group/theme.ts
  • src/lib/modal/Modal.svelte
  • src/lib/navbar/Menu.svelte
  • src/lib/navbar/NavHamburger.svelte
  • src/lib/navbar/NavLi.svelte
  • src/lib/navbar/NavUl.svelte
  • src/lib/navbar/Navbar.svelte
  • src/lib/pagination/PaginationNav.svelte
  • src/lib/popover/Popover.svelte
  • src/lib/rating/AdvancedRating.svelte
  • src/lib/rating/CustomIcon.svelte
  • src/lib/rating/Heart.svelte
  • src/lib/rating/Rating.svelte
  • src/lib/rating/Review.svelte
  • src/lib/rating/ScoreRating.svelte
  • src/lib/rating/Star.svelte
  • src/lib/rating/Thumbup.svelte
  • src/lib/sidebar/Sidebar.svelte
  • src/lib/sidebar/SidebarBrand.svelte
  • src/lib/sidebar/SidebarButton.svelte
  • src/lib/sidebar/SidebarCta.svelte
  • src/lib/sidebar/SidebarDropdownWrapper.svelte
  • src/lib/sidebar/SidebarGroup.svelte
  • src/lib/sidebar/SidebarItem.svelte
  • src/lib/sidebar/index.ts
  • src/lib/sidebar/theme.ts
  • src/lib/theme/themes.ts
  • src/lib/toolbar/theme.ts
  • src/lib/types.ts
  • src/routes/admin-dashboard/(sidebar)/Sidebar.svelte
  • src/routes/blocks/+layout.ts
  • src/routes/blocks/utils/Sectioncompo.svelte
  • src/routes/docs-examples/components/drawer/Navigation.svelte
  • src/routes/docs-examples/components/sidebar/AllOpen.svelte
  • src/routes/docs-examples/components/sidebar/AlwaysOpen.svelte
  • src/routes/docs-examples/components/sidebar/Branding.svelte
  • src/routes/docs-examples/components/sidebar/BrandingUsingChildren.svelte
  • src/routes/docs-examples/components/sidebar/CloseButton.svelte
  • src/routes/docs-examples/components/sidebar/Cta.svelte
  • src/routes/docs-examples/components/sidebar/Default.svelte
  • src/routes/docs-examples/components/sidebar/LinksAndActive.svelte
  • src/routes/docs-examples/components/sidebar/LinksAndActive2.svelte
  • src/routes/docs-examples/components/sidebar/MultiLevel.svelte
  • src/routes/docs-examples/components/sidebar/ObjectEx.svelte
  • src/routes/docs-examples/components/sidebar/Separator.svelte
  • src/routes/docs-examples/components/sidebar/Single.svelte
  • src/routes/docs-examples/components/sidebar/Static.svelte
  • src/routes/docs-examples/components/sidebar/Transition.svelte
  • src/routes/docs-examples/extend/split-pane/+page.svelte
  • src/routes/layouts/ComponentsLayout.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/routes/utils/index.ts
  • src/tests/dropdown/dropdown-with-links.test.svelte
  • src/tests/gallery/basic-gallery.test.svelte
  • src/tests/gallery/custom-class-gallery.test.svelte
  • src/tests/gallery/custom-figure-gallery.test.svelte
  • src/tests/gallery/gallery.test.ts
  • src/tests/kbd/kbd.test.ts
  • src/tests/modal/title-modal.test.svelte
  • src/tests/navbar/active-link.test.svelte
  • src/tests/navbar/basic-navbar.test.svelte
  • src/tests/navbar/custom-active-classes.test.svelte
  • src/tests/navbar/custom-breakpoint.test.svelte
  • src/tests/navbar/custom-classes.test.svelte
  • src/tests/navbar/fluid-navbar.test.svelte
  • src/tests/navbar/nav-brand.test.svelte
  • src/tests/navbar/navbar.test.ts
  • src/tests/navbar/navli-button.test.svelte
  • src/tests/navbar/navli-click.test.svelte
  • src/tests/navbar/no-close-on-click.test.svelte
  • src/tests/pagination/active-pagination-button.test.svelte
  • src/tests/pagination/basic-pagination-button.test.svelte
  • src/tests/pagination/basic-pagination-nav.test.svelte
  • src/tests/pagination/basic-pagination.test.svelte
  • src/tests/pagination/custom-content-pagination.test.svelte
  • src/tests/pagination/custom-pagination-nav.test.svelte
  • src/tests/pagination/disabled-pagination-button.test.svelte
  • src/tests/pagination/link-pagination-button.test.svelte
  • src/tests/pagination/pagination-button.test.ts
  • src/tests/pagination/pagination-nav.test.ts
  • src/tests/pagination/pagination.test.ts
  • src/tests/pagination/table-pagination-nav.test.svelte
  • src/tests/pagination/table-pagination.test.svelte
  • src/tests/popover/basic-popover.test.svelte
  • src/tests/popover/colored-popover.test.svelte
  • src/tests/popover/hover-popover.test.svelte
  • src/tests/popover/no-arrow-popover.test.svelte
  • src/tests/popover/no-title-popover.test.svelte
  • src/tests/popover/popover.test.ts
  • src/tests/progress/animated-progressbar.test.svelte
  • src/tests/progress/animated-progressradial.test.svelte
  • src/tests/progress/basic-progressbar.test.svelte
  • src/tests/progress/basic-progressradial.test.svelte
  • src/tests/progress/colored-progressbar.test.svelte
  • src/tests/progress/colored-progressradial.test.svelte
  • src/tests/progress/custom-size-progressradial.test.svelte
  • src/tests/progress/label-inside-progressbar.test.svelte
  • src/tests/progress/label-inside-progressradial.test.svelte
  • src/tests/progress/label-outside-progressbar.test.svelte
  • src/tests/progress/label-outside-progressradial.test.svelte
  • src/tests/progress/progressbar.test.ts
  • src/tests/progress/progressradial.test.ts
  • src/tests/sidebar/active-sidebar-item.test.svelte
  • src/tests/sidebar/backdrop-sidebar.test.svelte
  • src/tests/sidebar/basic-sidebar-brand.test.svelte
  • src/tests/sidebar/basic-sidebar-button.test.svelte
  • src/tests/sidebar/basic-sidebar-cta.test.svelte
  • src/tests/sidebar/basic-sidebar.test.svelte
  • src/tests/sidebar/border-sidebar-group.test.svelte
  • src/tests/sidebar/custom-sidebar-brand.test.svelte
  • src/tests/sidebar/dropdown-sidebar.test.svelte
  • src/tests/sidebar/positioned-sidebar.test.svelte
  • src/tests/sidebar/sidebar-brand.test.ts
  • src/tests/sidebar/sidebar-button.test.ts
  • src/tests/sidebar/sidebar-cta.test.ts
  • src/tests/sidebar/sidebar-dropdown-wrapper.test.ts
  • src/tests/sidebar/sidebar-group.test.ts
  • src/tests/sidebar/sidebar-item.test.ts
  • src/tests/sidebar/sidebar-wrapper.test.svelte
  • src/tests/sidebar/sidebar.test.ts
  • test-both.sh
  • vite.config.ts
💤 Files with no reviewable changes (2)
  • TROUBLESHOOTING.md
  • THEME_SELECTOR_FIX.md
✅ Files skipped from review due to trivial changes (1)
  • src/tests/progress/basic-progressradial.test.svelte
🚧 Files skipped from review as they are similar to previous changes (14)
  • src/tests/navbar/no-close-on-click.test.svelte
  • src/tests/navbar/nav-brand.test.svelte
  • src/tests/kbd/kbd.test.ts
  • src/tests/gallery/custom-figure-gallery.test.svelte
  • src/tests/gallery/basic-gallery.test.svelte
  • package.json
  • src/lib/list-group/ListgroupItem.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/tests/navbar/custom-active-classes.test.svelte
  • vite.config.ts
  • src/tests/navbar/fluid-navbar.test.svelte
  • src/tests/modal/title-modal.test.svelte
  • src/tests/navbar/custom-classes.test.svelte
  • src/tests/navbar/active-link.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/tests/progress/label-inside-progressradial.test.svelte
  • src/tests/popover/hover-popover.test.svelte
  • src/tests/sidebar/basic-sidebar-cta.test.svelte
  • src/tests/sidebar/sidebar-wrapper.test.svelte
  • src/lib/sidebar/theme.ts
  • src/lib/sidebar/SidebarButton.svelte
  • src/tests/popover/basic-popover.test.svelte
  • src/tests/progress/label-outside-progressradial.test.svelte
  • src/tests/progress/animated-progressradial.test.svelte
  • src/tests/sidebar/sidebar-brand.test.ts
  • src/tests/sidebar/sidebar-cta.test.ts
  • src/tests/sidebar/sidebar-button.test.ts
  • src/tests/pagination/basic-pagination-button.test.svelte
  • src/tests/pagination/pagination.test.ts
  • src/tests/sidebar/active-sidebar-item.test.svelte
  • src/lib/navbar/NavHamburger.svelte
  • src/tests/dropdown/dropdown-with-links.test.svelte
  • src/tests/progress/label-outside-progressbar.test.svelte
  • src/lib/rating/ScoreRating.svelte
  • src/routes/docs-examples/components/sidebar/Default.svelte
  • src/tests/pagination/custom-content-pagination.test.svelte
  • src/tests/gallery/gallery.test.ts
  • src/routes/docs-examples/components/sidebar/Single.svelte
  • src/tests/progress/colored-progressbar.test.svelte
  • src/tests/progress/animated-progressbar.test.svelte
  • src/tests/pagination/pagination-button.test.ts
  • src/tests/sidebar/backdrop-sidebar.test.svelte
  • src/tests/progress/progressradial.test.ts
  • src/lib/sidebar/index.ts
  • src/routes/docs-examples/components/sidebar/LinksAndActive2.svelte
  • src/tests/pagination/disabled-pagination-button.test.svelte
  • src/routes/docs-examples/components/sidebar/AllOpen.svelte
  • src/tests/navbar/custom-breakpoint.test.svelte
  • src/lib/modal/Modal.svelte
  • src/tests/progress/label-inside-progressbar.test.svelte
  • src/routes/docs-examples/components/sidebar/Cta.svelte
  • src/tests/sidebar/sidebar.test.ts
  • src/routes/docs-examples/components/drawer/Navigation.svelte
  • src/lib/theme/themes.ts
  • src/tests/navbar/navli-button.test.svelte
  • src/tests/pagination/pagination-nav.test.ts
  • src/routes/utils/index.ts
  • src/routes/docs-examples/components/sidebar/AlwaysOpen.svelte
  • src/lib/rating/Thumbup.svelte
  • src/routes/docs-examples/components/sidebar/BrandingUsingChildren.svelte
  • src/tests/popover/colored-popover.test.svelte
  • src/tests/pagination/basic-pagination.test.svelte
  • src/tests/pagination/table-pagination.test.svelte
  • src/lib/toolbar/theme.ts
  • src/tests/sidebar/basic-sidebar-button.test.svelte
  • src/tests/gallery/custom-class-gallery.test.svelte
  • src/tests/pagination/custom-pagination-nav.test.svelte
  • src/lib/sidebar/SidebarCta.svelte
  • src/lib/sidebar/SidebarDropdownWrapper.svelte
  • src/tests/sidebar/custom-sidebar-brand.test.svelte
  • src/tests/pagination/active-pagination-button.test.svelte
  • src/tests/progress/basic-progressbar.test.svelte
  • src/routes/docs-examples/components/sidebar/CloseButton.svelte
  • src/tests/popover/no-arrow-popover.test.svelte
  • src/routes/docs-examples/components/sidebar/ObjectEx.svelte
  • src/lib/list-group/theme.ts
  • src/routes/blocks/+layout.ts
  • src/tests/progress/colored-progressradial.test.svelte
  • src/lib/popover/Popover.svelte
  • src/routes/docs-examples/components/sidebar/Branding.svelte
  • src/routes/docs-examples/components/sidebar/LinksAndActive.svelte
  • src/tests/pagination/link-pagination-button.test.svelte
  • src/lib/pagination/PaginationNav.svelte
  • src/tests/sidebar/basic-sidebar.test.svelte
  • src/tests/navbar/navbar.test.ts
  • src/lib/navbar/NavLi.svelte
  • src/tests/popover/popover.test.ts
  • src/tests/sidebar/sidebar-dropdown-wrapper.test.ts
  • src/tests/pagination/basic-pagination-nav.test.svelte
  • src/lib/sidebar/SidebarBrand.svelte
  • src/tests/progress/custom-size-progressradial.test.svelte
  • src/tests/sidebar/positioned-sidebar.test.svelte
  • src/tests/sidebar/sidebar-item.test.ts
  • src/tests/navbar/navli-click.test.svelte
  • src/tests/sidebar/sidebar-group.test.ts
  • src/routes/blocks/utils/Sectioncompo.svelte
  • src/tests/navbar/basic-navbar.test.svelte
  • src/routes/admin-dashboard/(sidebar)/Sidebar.svelte
  • src/tests/sidebar/border-sidebar-group.test.svelte
  • src/lib/sidebar/SidebarItem.svelte
  • src/lib/sidebar/Sidebar.svelte
  • src/lib/rating/CustomIcon.svelte
  • src/tests/sidebar/basic-sidebar-brand.test.svelte
  • src/tests/pagination/table-pagination-nav.test.svelte
  • src/routes/docs-examples/extend/split-pane/+page.svelte
  • src/lib/rating/AdvancedRating.svelte
  • src/lib/navbar/Menu.svelte
  • src/lib/navbar/NavUl.svelte
  • src/lib/sidebar/SidebarGroup.svelte
  • src/lib/rating/Rating.svelte
  • src/lib/rating/Heart.svelte
  • src/routes/docs-examples/components/sidebar/MultiLevel.svelte
  • src/lib/navbar/Navbar.svelte
  • src/routes/layouts/ComponentsLayout.svelte
  • src/tests/popover/no-title-popover.test.svelte
  • src/routes/docs-examples/components/sidebar/Static.svelte
  • src/tests/sidebar/dropdown-sidebar.test.svelte
  • src/lib/rating/Review.svelte
  • src/routes/docs-examples/components/sidebar/Transition.svelte
  • src/routes/docs-examples/components/sidebar/Separator.svelte
  • src/lib/rating/Star.svelte
  • src/lib/types.ts
  • src/tests/progress/progressbar.test.ts
🧠 Learnings (14)
📚 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/progress/label-inside-progressradial.test.svelte
  • src/tests/popover/hover-popover.test.svelte
  • src/tests/sidebar/basic-sidebar-cta.test.svelte
  • src/tests/sidebar/sidebar-wrapper.test.svelte
  • src/lib/sidebar/SidebarButton.svelte
  • src/tests/popover/basic-popover.test.svelte
  • src/tests/progress/label-outside-progressradial.test.svelte
  • src/tests/progress/animated-progressradial.test.svelte
  • src/tests/pagination/basic-pagination-button.test.svelte
  • src/tests/sidebar/active-sidebar-item.test.svelte
  • src/lib/navbar/NavHamburger.svelte
  • src/tests/dropdown/dropdown-with-links.test.svelte
  • src/tests/progress/label-outside-progressbar.test.svelte
  • src/lib/rating/ScoreRating.svelte
  • src/routes/docs-examples/components/sidebar/Default.svelte
  • src/tests/pagination/custom-content-pagination.test.svelte
  • src/routes/docs-examples/components/sidebar/Single.svelte
  • src/tests/progress/colored-progressbar.test.svelte
  • src/tests/progress/animated-progressbar.test.svelte
  • src/tests/sidebar/backdrop-sidebar.test.svelte
  • src/routes/docs-examples/components/sidebar/LinksAndActive2.svelte
  • src/tests/pagination/disabled-pagination-button.test.svelte
  • src/routes/docs-examples/components/sidebar/AllOpen.svelte
  • src/tests/navbar/custom-breakpoint.test.svelte
  • src/lib/modal/Modal.svelte
  • src/tests/progress/label-inside-progressbar.test.svelte
  • src/routes/docs-examples/components/sidebar/Cta.svelte
  • src/routes/docs-examples/components/drawer/Navigation.svelte
  • src/tests/navbar/navli-button.test.svelte
  • src/routes/docs-examples/components/sidebar/AlwaysOpen.svelte
  • src/lib/rating/Thumbup.svelte
  • src/routes/docs-examples/components/sidebar/BrandingUsingChildren.svelte
  • src/tests/popover/colored-popover.test.svelte
  • src/tests/pagination/basic-pagination.test.svelte
  • src/tests/pagination/table-pagination.test.svelte
  • src/tests/sidebar/basic-sidebar-button.test.svelte
  • src/tests/gallery/custom-class-gallery.test.svelte
  • src/tests/pagination/custom-pagination-nav.test.svelte
  • src/lib/sidebar/SidebarCta.svelte
  • src/lib/sidebar/SidebarDropdownWrapper.svelte
  • src/tests/sidebar/custom-sidebar-brand.test.svelte
  • src/tests/pagination/active-pagination-button.test.svelte
  • src/tests/progress/basic-progressbar.test.svelte
  • src/routes/docs-examples/components/sidebar/CloseButton.svelte
  • src/tests/popover/no-arrow-popover.test.svelte
  • src/routes/docs-examples/components/sidebar/ObjectEx.svelte
  • src/tests/progress/colored-progressradial.test.svelte
  • src/lib/popover/Popover.svelte
  • src/routes/docs-examples/components/sidebar/Branding.svelte
  • src/routes/docs-examples/components/sidebar/LinksAndActive.svelte
  • src/tests/pagination/link-pagination-button.test.svelte
  • src/lib/pagination/PaginationNav.svelte
  • src/tests/sidebar/basic-sidebar.test.svelte
  • src/lib/navbar/NavLi.svelte
  • src/tests/pagination/basic-pagination-nav.test.svelte
  • src/lib/sidebar/SidebarBrand.svelte
  • src/tests/progress/custom-size-progressradial.test.svelte
  • src/tests/sidebar/positioned-sidebar.test.svelte
  • src/tests/navbar/navli-click.test.svelte
  • src/routes/blocks/utils/Sectioncompo.svelte
  • src/tests/navbar/basic-navbar.test.svelte
  • src/routes/admin-dashboard/(sidebar)/Sidebar.svelte
  • src/tests/sidebar/border-sidebar-group.test.svelte
  • src/lib/sidebar/SidebarItem.svelte
  • src/lib/sidebar/Sidebar.svelte
  • src/lib/rating/CustomIcon.svelte
  • src/tests/sidebar/basic-sidebar-brand.test.svelte
  • src/tests/pagination/table-pagination-nav.test.svelte
  • src/routes/docs-examples/extend/split-pane/+page.svelte
  • src/lib/rating/AdvancedRating.svelte
  • src/lib/navbar/Menu.svelte
  • src/lib/navbar/NavUl.svelte
  • src/lib/sidebar/SidebarGroup.svelte
  • src/lib/rating/Rating.svelte
  • src/lib/rating/Heart.svelte
  • src/routes/docs-examples/components/sidebar/MultiLevel.svelte
  • src/lib/navbar/Navbar.svelte
  • src/routes/layouts/ComponentsLayout.svelte
  • src/tests/popover/no-title-popover.test.svelte
  • src/routes/docs-examples/components/sidebar/Static.svelte
  • src/tests/sidebar/dropdown-sidebar.test.svelte
  • src/lib/rating/Review.svelte
  • src/routes/docs-examples/components/sidebar/Transition.svelte
  • src/routes/docs-examples/components/sidebar/Separator.svelte
  • src/lib/rating/Star.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/tests/popover/hover-popover.test.svelte
  • src/tests/popover/basic-popover.test.svelte
  • src/tests/dropdown/dropdown-with-links.test.svelte
  • src/tests/popover/colored-popover.test.svelte
  • src/lib/sidebar/SidebarDropdownWrapper.svelte
  • src/tests/popover/no-arrow-popover.test.svelte
  • src/lib/popover/Popover.svelte
  • src/lib/pagination/PaginationNav.svelte
  • src/tests/navbar/navbar.test.ts
  • src/tests/popover/popover.test.ts
  • src/lib/sidebar/Sidebar.svelte
  • src/lib/navbar/Menu.svelte
  • src/lib/navbar/NavUl.svelte
  • src/tests/popover/no-title-popover.test.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/tests/popover/basic-popover.test.svelte
  • src/tests/dropdown/dropdown-with-links.test.svelte
  • src/lib/sidebar/SidebarDropdownWrapper.svelte
  • src/tests/sidebar/dropdown-sidebar.test.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/sidebar/sidebar-brand.test.ts
  • src/tests/sidebar/sidebar.test.ts
  • src/tests/navbar/navbar.test.ts
  • src/routes/blocks/utils/Sectioncompo.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/toolbar/theme.ts
  • src/lib/list-group/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/list-group/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/list-group/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/list-group/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/tests/navbar/navbar.test.ts
  • src/lib/navbar/Menu.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/blocks/utils/Sectioncompo.svelte
  • src/tests/navbar/basic-navbar.test.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/blocks/utils/Sectioncompo.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/blocks/utils/Sectioncompo.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/blocks/utils/Sectioncompo.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/blocks/utils/Sectioncompo.svelte
🧬 Code graph analysis (6)
src/lib/sidebar/theme.ts (2)
src/lib/sidebar/index.ts (1)
  • sidebarItem (10-10)
src/lib/theme/themeUtils.ts (1)
  • Classes (42-48)
src/routes/utils/index.ts (2)
src/routes/blocks/utils/mdsvex.d.ts (3)
  • metadata (9-9)
  • metadata (17-17)
  • metadata (25-25)
src/routes/utils/mdsvex.d.ts (3)
  • metadata (9-9)
  • metadata (17-17)
  • metadata (25-25)
src/lib/list-group/theme.ts (2)
src/lib/list-group/index.ts (2)
  • listGroup (3-3)
  • listGroupItem (3-3)
src/lib/theme/themeUtils.ts (1)
  • Classes (42-48)
src/routes/blocks/+layout.ts (2)
src/routes/utils/index.ts (1)
  • MarkdownEntry (22-25)
src/routes/builder/+layout.ts (2)
  • prerender (3-3)
  • load (5-13)
src/tests/navbar/navbar.test.ts (1)
src/lib/navbar/index.ts (1)
  • navbar (8-8)
src/lib/types.ts (3)
src/lib/list-group/theme.ts (1)
  • ListgroupItemVariants (5-5)
src/lib/navbar/theme.ts (2)
  • NavbarBreakpoint (5-5)
  • NavbarVariants (10-10)
src/lib/sidebar/theme.ts (1)
  • SidebarItemVariants (10-10)

@shinokada
Copy link
Collaborator Author

Fixed all 🧹 Nitpick comments (21).

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

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)

1075-1086: Apply discriminated union pattern to ElementProps for type safety consistency.

The ElementProps intersection type allows all attribute combinations simultaneously, but ListgroupItem conditionally renders three different elements (<li>, <button>, or <a>) based on the href prop (lines 32-55 of ListgroupItem.svelte). This permits passing semantically invalid combinations like { href: "...", type: "button" } without type errors.

The codebase already establishes a discriminated union pattern with AnchorButtonAttributes used across multiple components (CloseButton, Button, NavLi, etc.). Apply the same pattern to ElementProps to match three possible elements:

type ElementProps =
  | ({ href: string } & HTMLAnchorAttributes)
  | ({ href?: undefined } & HTMLButtonAttributes)
  | ({ href?: undefined } & HTMLLiAttributes);

While the component handles invalid combinations at runtime, stricter types would catch errors at development time and align with existing codebase conventions.

🧹 Nitpick comments (11)
src/routes/blocks/+layout.ts (1)

37-63: Solid error handling and data fetching implementation.

The load function correctly:

  • Checks response.ok before parsing JSON (addressing the prior review)
  • Merges parent data for hierarchical composition
  • Returns empty fallback structures on failure for graceful degradation

One minor consideration: the error message in Line 55 says "Error in load function for /" but this is the /blocks layout. Consider updating for clarity.

🔎 Optional: Fix error message path
   } catch (error) {
-    console.error(`Error in load function for /: ${error}`);
+    console.error(`Error in load function for /blocks: ${error}`);
     return {
src/routes/utils/index.ts (1)

99-117: Consider extracting resolveOrderedMarkdownFiles to module scope.

This helper function duplicates most of resolveMarkdownFiles with added sorting. Hoisting it to module scope (alongside resolveMarkdownFiles) would:

  1. Enable reuse by other functions
  2. Reduce nesting complexity
  3. Make testing easier
🔎 Proposed refactor
+const resolveOrderedMarkdownFiles = async (
+  files: Record<string, () => Promise<{ metadata: Metadata }>>,
+  order: string[]
+): Promise<MarkdownEntry[]> => {
+  const results = await Promise.all(
+    Object.entries(files)
+      .sort(sortByList(order))
+      .map(async ([path, resolver]) => {
+        try {
+          const { metadata } = await resolver();
+          return { meta: metadata, path: toSlug(path) };
+        } catch (error) {
+          console.error(`Failed to resolve markdown file: ${path}`, error);
+          return null;
+        }
+      })
+  );
+  return results.filter((entry): entry is MarkdownEntry => entry !== null);
+};
+
 export const fetchMarkdownPosts = async () => {
   try {
     const globs = {
       // ... globs definition
     };

     const pageOrder = ["introduction", "quickstart", "colors", "customization", "typescript", "compiler-speed", "how-to-contribute", "license"];
     const mcpOrder = ["overview", "local-setup", "remote-setup", "prompts"];

-    const resolveOrderedMarkdownFiles = async (
-      files: Record<string, () => Promise<{ metadata: Metadata }>>,
-      order: string[]
-    ): Promise<MarkdownEntry[]> => {
-      // ... function body
-    };

     const pages = await resolveOrderedMarkdownFiles(globs.pages, pageOrder);
     const mcp = await resolveOrderedMarkdownFiles(globs.mcp, mcpOrder);
src/routes/blocks/utils/Sectioncompo.svelte (1)

3-3: Remove commented-out import.

Dead code should be removed to keep the codebase clean.

🔎 Proposed fix
-  // import type { PageData } from "../../$types";
src/tests/sidebar/sidebar.test.ts (4)

102-109: Strengthen the clickability assertion.

The test clicks the button but only verifies it's still in the document. Consider asserting on the expected behavior (e.g., sidebar visibility toggle, state change, event emission) to make the test meaningful.

💡 Example enhancement

If the button toggles sidebar visibility:

  test("sidebar button is clickable", async () => {
    const user = userEvent.setup();
    render(BasicSidebarButtonTest);
    const button = screen.getByRole("button");
+   const sidebar = screen.getByRole("complementary");

    await user.click(button);
-   expect(button).toBeInTheDocument();
+   // Verify sidebar visibility changed or event was dispatched
+   expect(sidebar).toHaveClass("hidden"); // or whatever the expected state is
  });

150-157: Strengthen the dropdown clickability assertion.

Similar to the button test, this only verifies the button remains in the document after clicking. Consider asserting on dropdown state changes (e.g., items visibility toggle, aria-expanded attribute) to verify actual functionality.


168-174: Consider testing behavior over implementation.

Line 173 asserts on a specific CSS class bg-gray-200. While functional, this couples the test to styling implementation. If only visual state matters, consider testing aria-current alone or use a data attribute for state verification.


183-190: Strengthen the link clickability assertion.

The test clicks a link but only verifies it's still in the document. For navigation links, consider using a mock router or verifying expected side effects to ensure the click handler functions correctly.

src/tests/navbar/navbar.test.ts (4)

3-3: Consider removing commented import if not needed soon.

This commented import of tick relates to the disabled tests below. If these tests won't be re-enabled in the near term, remove the commented import to keep the file clean.


78-104: Track disabled tests with issues to ensure they're re-enabled.

Multiple test blocks are commented out due to Svelte 5 state/DOM sync issues. While understandable during migration, these represent important functionality (hamburger toggle, mobile menu closing) that should be verified once the issues are resolved.

Would you like me to open tracking issues for these disabled tests so they're not forgotten once the Svelte 5 synchronization issues are resolved?

Also applies to: 209-235, 342-364


156-157: Complete assertions for active state styling.

These tests check element existence but don't verify the actual active/inactive styling behavior mentioned in the comments. Add assertions to check for expected CSS classes or attributes that indicate active state.

Example approach
 test("handles active URL", () => {
   render(ActiveLinkTest);
   const aboutLink = screen.getByTestId("about-link");
   
   expect(aboutLink).toBeInTheDocument();
-  // Active link should have active styling
+  expect(aboutLink).toHaveClass("text-blue-700"); // or whatever the active class is
 });

Also applies to: 244-245, 254-255


323-331: Test doesn't verify actual keyboard accessibility.

The test "navigation links are keyboard accessible" only checks that links have href attributes, which doesn't verify keyboard accessibility. Consider either:

  1. Renaming to "navigation links have valid hrefs"
  2. Adding actual keyboard accessibility checks (focus behavior, tab navigation)
Example for actual keyboard testing
 test("navigation links are keyboard accessible", () => {
   render(BasicNavbarTest);
   const links = screen.getAllByRole("link");
   
   links.forEach((link) => {
     expect(link).toBeInTheDocument();
     expect(link).toHaveAttribute("href");
+    // Verify link can receive focus (not tabindex="-1")
+    expect(link).not.toHaveAttribute("tabindex", "-1");
   });
 });
📜 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 bbd7e8c and f2a18e6.

📒 Files selected for processing (24)
  • src/lib/navbar/Navbar.svelte
  • src/lib/rating/Rating.svelte
  • src/lib/rating/Star.svelte
  • src/lib/rating/Thumbup.svelte
  • src/lib/sidebar/Sidebar.svelte
  • src/lib/types.ts
  • src/routes/blocks/+layout.ts
  • src/routes/blocks/utils/Sectioncompo.svelte
  • src/routes/utils/index.ts
  • src/tests/navbar/navbar.test.ts
  • src/tests/pagination/basic-pagination.test.svelte
  • src/tests/pagination/custom-content-pagination.test.svelte
  • src/tests/pagination/pagination-nav.test.ts
  • src/tests/pagination/pagination.test.ts
  • src/tests/pagination/table-pagination.test.svelte
  • src/tests/popover/basic-popover.test.svelte
  • src/tests/popover/popover.test.ts
  • src/tests/progress/high-progressbar.test.svelte
  • src/tests/progress/low-progressbar.test.svelte
  • src/tests/progress/progressbar.test.ts
  • src/tests/progress/progressradial.test.ts
  • src/tests/sidebar/sidebar-button.test.ts
  • src/tests/sidebar/sidebar-item.test.ts
  • src/tests/sidebar/sidebar.test.ts
🚧 Files skipped from review as they are similar to previous changes (14)
  • src/tests/pagination/pagination.test.ts
  • src/tests/pagination/table-pagination.test.svelte
  • src/tests/sidebar/sidebar-button.test.ts
  • src/tests/popover/popover.test.ts
  • src/tests/progress/progressbar.test.ts
  • src/lib/rating/Thumbup.svelte
  • src/lib/sidebar/Sidebar.svelte
  • src/lib/rating/Rating.svelte
  • src/lib/navbar/Navbar.svelte
  • src/tests/pagination/custom-content-pagination.test.svelte
  • src/tests/pagination/basic-pagination.test.svelte
  • src/lib/rating/Star.svelte
  • src/tests/popover/basic-popover.test.svelte
  • src/tests/pagination/pagination-nav.test.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/navbar/navbar.test.ts
  • src/tests/sidebar/sidebar-item.test.ts
  • src/lib/types.ts
  • src/tests/progress/high-progressbar.test.svelte
  • src/tests/progress/progressradial.test.ts
  • src/tests/progress/low-progressbar.test.svelte
  • src/tests/sidebar/sidebar.test.ts
  • src/routes/utils/index.ts
  • src/routes/blocks/+layout.ts
  • src/routes/blocks/utils/Sectioncompo.svelte
🧠 Learnings (9)
📚 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/tests/navbar/navbar.test.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/tests/navbar/navbar.test.ts
📚 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/progress/high-progressbar.test.svelte
  • src/tests/progress/low-progressbar.test.svelte
  • src/routes/blocks/utils/Sectioncompo.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/sidebar/sidebar.test.ts
  • src/routes/blocks/utils/Sectioncompo.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/blocks/utils/Sectioncompo.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/blocks/utils/Sectioncompo.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/blocks/utils/Sectioncompo.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/blocks/utils/Sectioncompo.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/blocks/utils/Sectioncompo.svelte
🧬 Code graph analysis (4)
src/tests/navbar/navbar.test.ts (1)
src/lib/navbar/index.ts (1)
  • navbar (8-8)
src/lib/types.ts (3)
src/lib/list-group/theme.ts (1)
  • ListgroupItemVariants (5-5)
src/lib/navbar/theme.ts (2)
  • NavbarBreakpoint (5-5)
  • NavbarVariants (10-10)
src/lib/sidebar/theme.ts (1)
  • SidebarItemVariants (10-10)
src/routes/utils/index.ts (2)
src/routes/blocks/utils/mdsvex.d.ts (3)
  • metadata (9-9)
  • metadata (17-17)
  • metadata (25-25)
src/routes/utils/mdsvex.d.ts (3)
  • metadata (9-9)
  • metadata (17-17)
  • metadata (25-25)
src/routes/blocks/+layout.ts (1)
src/routes/utils/index.ts (1)
  • MarkdownEntry (22-25)
🔇 Additional comments (22)
src/routes/blocks/+layout.ts (1)

4-33: Well-structured type definitions with appropriate extensibility.

The type definitions are clean and allow for additional properties via index signatures. This provides flexibility for API evolution.

src/routes/utils/index.ts (4)

41-49: Improved type safety in sortByList.

The explicit tuple typing [string, unknown] is correct and clarifies the expected input format for the sort comparator. The edge case handling for items not in the order list is appropriate (pushing unknown items to the end).


51-69: Robust per-file error handling in resolveMarkdownFiles.

Good defensive approach: catching errors per file, logging them, and returning null for failed files rather than failing the entire batch. The type guard filter entry !== null correctly narrows the type.


137-153: Comprehensive fallback structure on error.

The catch block returns a complete empty structure matching all expected keys. This ensures consumers always receive a consistent shape, preventing downstream undefined access errors.


182-203: Consistent error handling pattern in fetchBlocksMarkdownPosts.

Mirrors the pattern established in fetchMarkdownPosts with try/catch and empty fallback. This consistency is good for maintainability.

src/routes/blocks/utils/Sectioncompo.svelte (4)

11-24: Well-defined type extensions.

The Post interface properly extends MarkdownEntry and augments the meta property with additional optional fields. The SectionData interface correctly types the blocks structure.


37-37: Type assertion on flattened array.

The as Post[] cast is reasonable here since MarkdownEntry[] items should conform to Post based on the data source. However, if the actual data doesn't include the expected meta properties, runtime issues could occur.

Consider adding runtime validation if data integrity is a concern, or ensure the upstream data source always provides the expected shape.


47-47: Good defensive access with optional chaining.

Using post.meta?.dir prevents potential runtime errors if meta is unexpectedly undefined.


80-86: Key generation issue addressed.

The key expression (component.meta.dir || "") + component.path correctly handles undefined dir values, ensuring unique and stable keys. This addresses the previous review feedback.

src/tests/progress/progressradial.test.ts (1)

156-186: Excellent implementation of stroke-dashoffset verification.

These tests now properly verify the actual progress values by calculating the expected stroke-dashoffset and comparing it to the rendered value using toBeCloseTo. This directly addresses the previous review feedback.

src/tests/progress/high-progressbar.test.svelte (1)

1-5: LGTM!

This test fixture correctly renders a Progressbar component with high progress (95%) for testing near-complete state scenarios.

src/tests/progress/low-progressbar.test.svelte (1)

1-5: LGTM!

This test fixture correctly renders a Progressbar component with low progress (10%) for testing early-stage progress scenarios.

src/tests/sidebar/sidebar.test.ts (6)

1-19: LGTM!

Test setup and imports are well-organized. The cleanup hook ensures proper test isolation.


21-49: LGTM!

Basic functionality tests provide solid coverage of rendering, link attributes, and ARIA structure.


51-75: LGTM!

SidebarBrand tests effectively verify brand rendering with both site objects and custom content.


193-215: LGTM!

SidebarGroup tests provide good coverage. The previously flagged duplicate render issue has been successfully resolved.


217-246: LGTM!

SidebarWrapper and variant tests effectively verify wrapper functionality and positioning variants.


248-271: LGTM!

Accessibility tests provide comprehensive coverage of ARIA roles and attributes. The test suite ensures proper semantic HTML and screen reader support.

src/tests/sidebar/sidebar-item.test.ts (1)

1-96: LGTM! Comprehensive test coverage for SidebarItem component.

The test suite is well-organized with clear sections covering basic functionality, active state behavior, styling, and user interaction. The test assertions appropriately validate:

  • Rendering and DOM structure
  • Accessibility attributes (aria-current)
  • CSS class application for active/inactive states
  • User interaction capabilities

The use of describe blocks for logical grouping and the cleanup pattern follow testing best practices.

src/lib/types.ts (3)

1110-1115: LGTM! Consistent use of ClassValue for class props.

The change from string to ClassValue for activeClass and nonActiveClass properties provides better flexibility, allowing arrays, objects, or conditional class names. This aligns with the PR's goal of consolidating styling APIs.


1337-1348: Good: Consistent ClassValue usage.

The class property in RatingIconProps now uses ClassValue for consistency with other component props throughout the codebase.


48-51: These changes are compatible with existing component usages.

The NavbarProps and SidebarItemProps extensions with variant types are additive changes that don't break existing code. All usages across the codebase (test files, docs, examples, and layouts) remain compatible because:

  1. Both components already destructure and accept the classes prop, which contains the variant type information
  2. Existing component usages pass standard props (like fluid, closeOnClickOutside for Navbar; label, href, active for SidebarItem) that remain unchanged
  3. The variant types are merged via extends, allowing new variant-based styling without affecting current implementations

No migration guide or breaking change documentation is needed—this is a transparent API consolidation for internal styling management.

@shinokada
Copy link
Collaborator Author

Your suggestion in ⚠️ Outside diff range comments (1), src/lib/types.ts (1) is not applied since it breaks src/lib/list-group/ListgroupItem.svelte.

Otherwise most of the Nitpick comments (11) are fixed.

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

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/pages/introduction.md (1)

254-275: Missing font-family declarations in the second CSS example.

The first CSS example (src/app.css) includes font-family declarations for body and other text elements within @layer base (lines 154-160), but the second example for src/routes/+layout.css omits these declarations. This inconsistency could cause developers to experience different styling depending on which file location they use.

Ensure both CSS examples have identical @layer base structures, including the font-family declarations.

🔎 Proposed addition to match the first CSS example
 @layer base {
+  body {
+    font-family: var(--font-sans), sans-serif;
+  }
+  
+  p, span, div {
+    font-family: var(--font-body, var(--font-sans)), sans-serif;
+  }
+
   /* Uncomment following lines to override brand colors in dark mode */
src/routes/utils/Paging.svelte (1)

61-61: Fix CSS syntax error.

There's an extra dark: token in the class string that makes it invalid Tailwind CSS syntax.

🔎 Proposed fix
-        <PaginationItem {href} class="hover:text-primary-700 dark: dark:hover:text-primary-700 flex items-center gap-2.5">
+        <PaginationItem {href} class="hover:text-primary-700 dark:hover:text-primary-700 flex items-center gap-2.5">
🧹 Nitpick comments (4)
src/routes/docs/pages/introduction.md (1)

112-147: Consider condensing large commented customization blocks for improved readability.

The color customization examples (115+ lines of commented code per block) significantly expand the documentation examples. While showing customization options is valuable, these could be presented more concisely, such as by using a collapsible section or extracting them into a separate customization guide to keep the main examples focused and scannable.

Also applies to: 213-248

src/lib/navbar/NavLi.svelte (1)

26-32: Simplify tagName comparison (optional).

The tagName property in the DOM is always uppercase, so the || tagName === "a" check is redundant. This is a minor nit but could be simplified.

🔎 Suggested simplification
  function handleClick(event: MouseEvent) {
    const tagName = (event.currentTarget as HTMLElement).tagName;
    // Close the mobile menu when a link is clicked
    const state = navState;
-   if (state && (tagName === "A" || tagName === "a") && !state.hidden) {
+   if (state && tagName === "A" && !state.hidden) {
      state.hidden = true;
    }
src/lib/toolbar/ToolbarButton.svelte (1)

38-45: Update docblock to include new prop.

The @prop list in the component documentation is missing the newly added aria-expanded prop.

🔎 Suggested documentation update
 @prop children
 @prop color
 @prop name
 @prop "aria-label": ariaLabel
+@prop "aria-expanded": ariaExpanded
 @prop size
 @prop class: className
 @prop ...restProps
QUICK_START.md (1)

45-60: Add language specifier to fenced code block.

The code block starting at line 45 is missing a language specifier. Adding one improves syntax highlighting and accessibility.

🔎 Suggested fix
-```
+```text
 flowbite-svelte-local-development/
 ├── TEST_IMPROVEMENTS_SUMMARY.md       ← What changed in tests
📜 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 f2a18e6 and 3e6c79d.

📒 Files selected for processing (28)
  • FIX_SUMMARY_aria_expanded.md
  • PROPOSED_FIX_NavHamburger.md
  • QUICK_START.md
  • TEST_IMPROVEMENTS_SUMMARY.md
  • package.json
  • src/lib/list-group/ListgroupItem.svelte
  • src/lib/navbar/NavHamburger.svelte
  • src/lib/navbar/NavLi.svelte
  • src/lib/navbar/NavUl.svelte
  • src/lib/navbar/Navbar.svelte
  • src/lib/sidebar/theme.ts
  • src/lib/toolbar/ToolbarButton.svelte
  • src/routes/blocks/+layout.ts
  • src/routes/blocks/utils/Sectioncompo.svelte
  • src/routes/docs/pages/introduction.md
  • src/routes/layout.css
  • src/routes/utils/Paging.svelte
  • src/tests/navbar/basic-navbar.test.svelte
  • src/tests/navbar/navbar.test.ts
  • src/tests/navbar/navli-click.test.svelte
  • src/tests/pagination/pagination-nav.test.ts
  • src/tests/pagination/pagination.test.ts
  • src/tests/popover/popover.test.ts
  • src/tests/progress/progressbar.test.ts
  • src/tests/progress/progressradial.test.ts
  • src/tests/sidebar/sidebar-item.test.ts
  • src/tests/sidebar/sidebar.test.ts
  • vite.config.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/tests/navbar/navli-click.test.svelte
  • src/tests/pagination/pagination.test.ts
  • src/tests/progress/progressradial.test.ts
  • src/lib/navbar/NavHamburger.svelte
  • src/lib/list-group/ListgroupItem.svelte
  • src/tests/pagination/pagination-nav.test.ts
  • src/tests/progress/progressbar.test.ts
  • src/tests/popover/popover.test.ts
  • src/tests/navbar/basic-navbar.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/sidebar/theme.ts
  • src/lib/navbar/NavLi.svelte
  • src/lib/toolbar/ToolbarButton.svelte
  • src/lib/navbar/Navbar.svelte
  • src/lib/navbar/NavUl.svelte
  • src/routes/blocks/+layout.ts
  • src/tests/sidebar/sidebar.test.ts
  • src/routes/blocks/utils/Sectioncompo.svelte
  • src/tests/navbar/navbar.test.ts
  • vite.config.ts
  • src/tests/sidebar/sidebar-item.test.ts
  • src/routes/utils/Paging.svelte
🧠 Learnings (9)
📚 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/navbar/NavLi.svelte
  • src/lib/navbar/NavUl.svelte
  • src/tests/navbar/navbar.test.ts
📚 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/navbar/NavLi.svelte
  • src/lib/toolbar/ToolbarButton.svelte
  • src/lib/navbar/Navbar.svelte
  • src/lib/navbar/NavUl.svelte
  • src/routes/blocks/utils/Sectioncompo.svelte
  • src/routes/utils/Paging.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/toolbar/ToolbarButton.svelte
  • FIX_SUMMARY_aria_expanded.md
  • src/tests/navbar/navbar.test.ts
  • PROPOSED_FIX_NavHamburger.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/tests/sidebar/sidebar.test.ts
  • src/routes/blocks/utils/Sectioncompo.svelte
  • 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} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

Applied to files:

  • src/routes/blocks/utils/Sectioncompo.svelte
  • 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:

  • src/routes/blocks/utils/Sectioncompo.svelte
  • package.json
📚 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/blocks/utils/Sectioncompo.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/blocks/utils/Sectioncompo.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/blocks/utils/Sectioncompo.svelte
🧬 Code graph analysis (2)
src/tests/sidebar/sidebar.test.ts (1)
src/lib/sidebar/theme.ts (1)
  • sidebar (12-54)
src/tests/navbar/navbar.test.ts (1)
src/lib/navbar/index.ts (1)
  • navbar (8-8)
🪛 LanguageTool
QUICK_START.md

[style] ~114-~114: Some style guides suggest that commas should set off the year in a month-day-year date.
Context: ...tional) --- Created: December 27, 2025 Status: ✅ Test improvements compl...

(MISSING_COMMA_AFTER_YEAR)

TEST_IMPROVEMENTS_SUMMARY.md

[style] ~41-~41: Try using a synonym here to strengthen your wording.
Context: ...acking for Disabled Tests** Before: Comments about Svelte 5 issues without tracking ...

(COMMENT_REMARK)

FIX_SUMMARY_aria_expanded.md

[style] ~165-~165: Consider using a different verb for a more formal wording.
Context: ...'t Create Them Since the problem is now fixed, you might not need to create the GitHu...

(FIX_RESOLVE)


[style] ~172-~172: ‘with reference to’ might be wordy. Consider a shorter alternative.
Context: ...ixed (this PR) - Close them immediately with reference to the fix ### Option 3: Skip Entirely Ju...

(EN_WORDINESS_PREMIUM_WITH_REFERENCE_TO)


[style] ~217-~217: Using many exclamation marks might seem excessive (in this case: 7 exclamation marks for a text that’s 3786 characters long)
Context: ...ub-issues directory** - no longer needed! 5. Update documentation - note that...

(EN_EXCESSIVE_EXCLAMATION)

🪛 markdownlint-cli2 (0.18.1)
QUICK_START.md

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

(MD040, fenced-code-language)

🔇 Additional comments (20)
src/routes/blocks/+layout.ts (3)

1-33: Well-structured type definitions.

The type definitions clearly document the expected API response shape and provide good TypeScript contracts for the data flow. The BuilderEntry and DashboardEntry interfaces with [key: string]: unknown allow for future extensibility while maintaining required fields.


37-53: Excellent implementation of parent data merging with proper error handling.

The load function correctly:

  • Integrates parent layout data for composition
  • Checks response.ok before parsing JSON (addressing the previous review comment)
  • Merges parent data with API response for a complete data payload

The response status check ensures robust error handling when the API returns non-2xx responses.


54-63: Graceful error handling with sensible defaults.

The catch block provides a good fallback by returning empty data structures while preserving parent data. The error logging includes the path context, which aids debugging.

src/routes/blocks/utils/Sectioncompo.svelte (3)

8-23: Clear and well-defined type interfaces.

The Post interface properly extends MarkdownEntry with additional metadata fields, and the SectionData interface provides a clean contract that aligns with the data structure from +layout.ts.


36-36: Correct data access pattern with safe optional chaining.

The derived values correctly access data.blocks (matching the updated layout structure) and use optional chaining (post.meta?.dir) to safely handle potentially undefined metadata.

Also applies to: 46-46


79-84: Key generation correctly handles undefined values.

The key generation using (component.meta.dir || "") prevents "undefined" string concatenation when dir is missing, ensuring stable and unique keys for the each blocks. This addresses the previous review concern effectively.

src/routes/layout.css (1)

145-154: The CSS variables --font-sans and --font-body are defined in the imported Flowbite theme files (static/themes/default.css and related theme files). Since layout.css imports "flowbite/src/themes/default" on line 17, both variables are available at runtime with proper font stacks defined. The fallback chain var(--font-body, var(--font-sans)), sans-serif is correct and will work as intended. The code does not rely on undefined variables.

Likely an incorrect or invalid review comment.

src/routes/utils/Paging.svelte (1)

26-28: Fix CSS syntax error on line 61.

The Tailwind class string has a malformed prefix: "dark: dark:hover:text-primary-700" contains an extra dark: that should be removed, leaving just "dark:hover:text-primary-700".

The merge of data.posts and data.blocks on lines 26-28 is correct—the keys are from mutually exclusive namespaces (forms, components, etc. vs. application, quickstart, etc.), so there are no collisions and the type assertion is valid.

Likely an incorrect or invalid review comment.

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

98-117: LGTM! Clean slot-based variant structure for SidebarItem.

The new sidebarItem configuration follows the established pattern with proper slots (base, link, span), active variants, and sensible defaults. The styling is consistent with the existing sidebar.active/sidebar.nonactive definitions.


56-70: No issue found: rounded-base is a valid design token.

rounded-base is a legitimate Flowbite-Svelte design token used consistently throughout the codebase across 20+ component theme files and verified in multiple test assertions. No action required.

src/lib/navbar/NavLi.svelte (1)

9-11: LGTM! Proper reactive context derivation.

Using $derived(getNavbarBreakpointContext()) ensures the breakpoint value updates reactively, aligning with the pattern for theme-derived values in this codebase. Based on learnings, this is the correct approach for dynamic context updates.

src/tests/sidebar/sidebar-item.test.ts (1)

82-95: LGTM! Good interaction test pattern.

The interaction test properly sets up user-event, verifies the href before click, and confirms the element remains in the document after interaction. This is a solid pattern for testing link behavior in a test environment.

package.json (2)

27-27: LGTM! Useful addition for CI workflows.

The test:unit:run script provides a non-watch mode for running tests, which is essential for CI/CD pipelines where vitest run exits after completion rather than watching for changes.


42-43: Minor dependency updates look appropriate.

These are all patch/minor version bumps (@docsearch/* 4.3.2→4.4.0, @testing-library/svelte 5.2.10→5.3.1, svelte 5.46.0→5.46.1, typescript-eslint 8.50.0→8.50.1). Low risk for breaking changes.

Also applies to: 58-58, 91-91, 100-100

src/lib/toolbar/ToolbarButton.svelte (1)

7-7: Good accessibility enhancement for toggle functionality.

Adding aria-expanded support enables proper ARIA state communication for expandable controls. This aligns with the NavHamburger changes that wire aria-expanded to menu state.

Note: aria-expanded on anchor elements (line 27) is less common but valid when the link controls an expandable region.

Also applies to: 22-22, 27-27

QUICK_START.md (1)

1-42: Clear and actionable documentation.

The restructured Quick Start guide provides clear paths for different automation preferences (fully automated, semi-automated, manual) with well-organized steps. The directory structure and key changes sections provide good context.

vite.config.ts (1)

49-65: LGTM! Consistent test environment configuration.

Adding explicit env blocks with VITEST and NODE_ENV to both client and server test configurations ensures environment detection works consistently across all test contexts.

src/lib/navbar/Navbar.svelte (3)

9-14: LGTM! Well-structured slot-based styling implementation.

The refactor from navContainerClass to a unified classes prop aligns with the broader component API consolidation. The getTheme("navbar") is correctly wrapped in $derived() ensuring reactive theme updates. Based on learnings, this is the correct approach for ThemeProvider compatibility.


19-22: Appropriate use of $effect for context updates.

The $effect block properly updates the navbar breakpoint context when the breakpoint prop changes, enabling child components like NavLi to reactively access the current breakpoint value.


42-48: Clean rendering with composed styling.

The template correctly applies base and container styles through their respective slot functions, merging theme defaults with custom class overrides via clsx. This maintains backward compatibility while enabling the new theming system.

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 (1)
src/routes/docs/pages/introduction.md (1)

138-194: Add clarity on brand color customization examples.

The @theme block and @layer base sections provide comprehensive examples for overriding brand colors. Consider adding a brief comment explaining that these are example values that users should customize to match their brand identity, and that the dark mode overrides (lines 179-192) should be uncommented only when dark mode brand colors differ from light mode.

This would help users understand which parts are boilerplate to copy-paste and which parts require customization.

📜 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 3e6c79d and efdbafa.

📒 Files selected for processing (5)
  • src/lib/navbar/NavLi.svelte
  • src/lib/toolbar/ToolbarButton.svelte
  • src/routes/docs/pages/introduction.md
  • src/routes/utils/Paging.svelte
  • vite.config.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • vite.config.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/utils/Paging.svelte
  • src/lib/navbar/NavLi.svelte
  • src/lib/toolbar/ToolbarButton.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/routes/docs/pages/introduction.md
📚 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/utils/Paging.svelte
  • src/lib/navbar/NavLi.svelte
  • src/lib/toolbar/ToolbarButton.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/navbar/NavLi.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/toolbar/ToolbarButton.svelte
🔇 Additional comments (8)
src/routes/utils/Paging.svelte (2)

28-31: Data consolidation looks good.

The change from data.posts.posts to the unified all_posts object is consistent with the merge above. The filtering and mapping logic correctly handles the combined data structure.


61-61: Good fix removing the redundant "dark:" prefix.

This correction resolves the malformed class string. The dark mode hover style now applies correctly.

src/routes/docs/pages/introduction.md (2)

86-98: Clarify theme and font alignment.

The commented theme imports at lines 87-104 show font imports for different themes, but the alignment appears inconsistent:

  • Line 87-89: "MINIMAL THEME" with "Open Sans" font
  • Line 91-93: "ENTERPRISE THEME" with "Shantell Sans" font
  • Line 95-97: "PLAYFUL THEME" with "Google Sans Code" font

The pairing of "PLAYFUL THEME" with "Google Sans Code" (a monospace/code font) seems unusual. Verify that these theme-to-font mappings align with the actual v2 theme designs and clarify the intention if "Google Sans Code" is intentional for PLAYFUL.


99-107: [No changes needed. The import paths and syntax in the documentation are correct per official Tailwind v4 and Flowbite documentation.]

src/lib/navbar/NavLi.svelte (2)

9-11: Good use of reactive derivation for context values.

Using $derived ensures the breakpoint updates reactively when the context changes, which aligns with Svelte 5 best practices and is consistent with the broader navbar refactoring. The fallback to "md" on line 20 appropriately handles undefined cases.


26-32: Improved specificity for mobile menu closing logic.

The tagName check correctly gates the menu closing behavior to only apply when clicking anchor tags, leaving button interactions (e.g., dropdowns) unaffected. The implementation properly uses event.currentTarget and guards against undefined state.

Minor note: The local state variable on line 29 is redundant and could be inlined, but this doesn't affect functionality.

src/lib/toolbar/ToolbarButton.svelte (2)

7-7: LGTM: Prop addition follows established patterns.

The aria-expanded prop is correctly destructured following the same pattern as aria-label. The kebab-case to camelCase conversion is appropriate for Svelte prop handling.


22-22: aria-expanded attribute is correctly implemented and Svelte 5 properly handles undefined values.

Verification confirms the implementation is sound. Svelte 5 correctly omits aria-expanded={undefined} from the DOM, and tests verify that the attribute properly renders as "true" or "false" strings when a value is provided. NavHamburger intentionally passes undefined when no state is available, which Svelte 5 handles by not rendering the attribute—exactly the correct ARIA-compliant behavior.

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

🧹 Nitpick comments (7)
src/routes/docs/pages/introduction.md (7)

83-112: Clarify Tailwind CSS version requirement.

The CSS configuration uses Tailwind v4 directives (@import, @plugin, @source, @custom-variant, @theme) which differ significantly from v3. The documentation should explicitly state this requires Tailwind CSS v4 to avoid configuration errors for users upgrading from v3.

Consider adding a note above the code block:

> **Note:** This configuration requires **Tailwind CSS v4**. If you're using Tailwind v3, refer to the v3 configuration guide.

122-178: Document the purpose and usage of CSS variables.

The CSS variables section defines color mappings but lacks explanation of:

  1. Which component properties these variables target
  2. The semantic meaning of each variant (softer, soft, medium, strong)
  3. Why some variables appear to have similar mappings (e.g., --color-brand-subtle mapped twice with different values)
  4. How components reference these variables in their styles

Adding inline comments or a explanatory paragraph before this section would help users understand how to customize colors effectively.


86-97: Clarify theme font selection behavior.

The commented font imports for alternative themes (MINIMAL, ENTERPRISE, PLAYFUL) could be misunderstood as allowing multiple font imports simultaneously. Add a clarifying comment to indicate that users should uncomment only one theme font at a time to avoid CSS conflicts.

Consider adding a comment:

@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap");

/* Theme font options - uncomment ONLY ONE */
/* MINIMAL THEME
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap');
*/

74-189: Add migration guidance and breaking-change notice.

The Configuration section reorganizes CSS file recommendations (from src/app.css to src/routes/+layout.css) and introduces new CSS variable-based theming, which may represent breaking changes from previous documentation or versions. Consider adding:

  1. A "Breaking Changes" or "Version 2 Migration" section if this differs from Version 1 guidance
  2. Explicit minimum version requirements for Tailwind CSS (v4), Flowbite, and flowbite-svelte
  3. Migration steps for users updating from older configurations

86-97: Clarify theme font selection behavior.

The commented font imports for alternative themes (MINIMAL, ENTERPRISE, PLAYFUL) could mislead users into enabling multiple fonts simultaneously. Add guidance that only one theme font should be active at a time.

Add a clarifying comment above the alternatives:

@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap");

/* Theme font options - uncomment ONLY ONE */
/* MINIMAL THEME
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap');
*/

122-178: Document CSS variable purpose and component usage.

The CSS variables section defines color mappings but lacks explanation of:

  1. Which component properties these variables target
  2. Semantic meaning of each variant (softer, soft, medium, strong)
  3. Why some variables appear duplicated (e.g., --color-brand-subtle on lines 158 and 174)
  4. How components reference these variables

Adding inline comments or an explanatory paragraph would help users understand how to customize colors effectively.


74-189: Add migration guidance and explicit dependency version requirements.

This Configuration section reorganizes CSS file recommendations and introduces new CSS variable-based theming, which may represent breaking changes. The documentation should include:

  1. Explicit minimum versions for Tailwind CSS (v4), Flowbite, and flowbite-svelte
  2. A "Migration" or "Breaking Changes" section if this differs from Version 1 guidance
  3. Steps for users updating from older configurations
📜 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 efdbafa and 3bf049d.

📒 Files selected for processing (2)
  • src/routes/docs/pages/introduction.md
  • src/routes/utils/Paging.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/routes/utils/Paging.svelte
🧰 Additional context used
🧠 Learnings (1)
📚 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/pages/introduction.md
🔇 Additional comments (3)
src/routes/docs/pages/introduction.md (3)

180-182: Clear and helpful path documentation.

The note accurately explains the relative path behavior for different CSS file locations and provides concrete examples. This helps prevent a common source of misconfiguration.


83-112: Clarify Tailwind CSS v4 requirement.

The CSS configuration uses Tailwind v4 directives (@import, @plugin, @source, @custom-variant, @theme) which differ significantly from v3. The documentation should explicitly state this requires Tailwind CSS v4 to prevent configuration errors for users upgrading.

Consider adding a banner or note immediately before the code block:

> **Note:** This configuration requires **Tailwind CSS v4**. For Tailwind v3 setups, adjust the syntax accordingly.

180-182: Path documentation is clear and accurate.

The note correctly explains the relative path behavior for different CSS file locations and provides concrete examples, helping prevent a common source of misconfiguration.

@shinokada shinokada merged commit 17829d9 into themesberg:version-2 Dec 27, 2025
1 check failed
This was referenced Dec 28, 2025
This was referenced Jan 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant