Skip to content

version 2 part-6#1902

Merged
shinokada merged 34 commits intothemesberg:version-2from
shinokada:version-2
Jan 3, 2026
Merged

version 2 part-6#1902
shinokada merged 34 commits intothemesberg:version-2from
shinokada:version-2

Conversation

@shinokada
Copy link
Copy Markdown
Collaborator

@shinokada shinokada commented Dec 31, 2025

  • fix: data-scope, data-part, theme.ts slot name update for device-mockup and drawer

🔗 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

  • Breaking Changes

    • Several theme slot and prop names were renamed — update any custom theme/class mappings or component prop keys.
  • Improvements

    • Many components now include consistent data-scope/data-part attributes and clearer part names for more reliable CSS selection, styling and testing.
    • DOM parts reorganized to more semantic names improving styling consistency and testability.
  • New

    • PaginationNav: added visiblePages prop to control how many page links are shown.

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

@vercel
Copy link
Copy Markdown

vercel bot commented Dec 31, 2025

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

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 31, 2025

📝 Walkthrough

Walkthrough

Design-system-wide refactor: semantic renames of theme slot keys and derived tokens, addition of data-scope/data-part attributes across many components, updates to public props/types/exports, and numerous new/updated tests and migration docs.

Changes

Cohort / File(s) Summary
Device mockups
src/lib/device-mockups/*, src/lib/device-mockups/theme.ts
Renamed many slots/returned keys (e.g., slotscreen, topnotch, leftMidleftMiddle, leftBotleftBottom); updated destructuring and templates to use new keys.
Global theme, types & exports
src/lib/theme-provider/themes.ts, src/lib/types.ts, src/lib/index.ts, vite.config.ts
Reworked exported theme symbols and types (e.g., navbarUlnavUl, navbarLinavLi), added/adjusted exports (video, themeSelector), and updated Variant/Classes-based typings.
Sidebar / Navbar / Navigation
src/lib/sidebar/*, src/lib/navbar/*, src/routes/layouts/*, src/routes/docs-examples/**
Renamed slots/keys (e.g., divcontent, spanlabel, btntrigger), updated classes prop shapes and example usages, added data-scope/data-part attributes.
Forms & inputs
src/lib/forms/**, src/lib/forms/**/theme.ts
Systematic renames of parts (e.g., closecloseButton, combocomboList, lefticonWrapper, divcontainer/wrapper, baseinput for checkbox), added data-part/scope attributes and updated themes/types.
Dropdown / Popover / Popper / Drawer / Modal
src/lib/dropdown/*, src/lib/popover/*, src/lib/utils/Popper.svelte, src/lib/drawer/*, src/lib/modal/*, src/lib/drawer/theme.ts
Renamed slots (e.g., liitem, h3heading), added scoping/part attributes, Popper/Drawer/Modal attribute wiring changed; Drawerhead now uses closeButton/closeIcon.
Layout, primitives & patterns
src/lib/typography/*, src/lib/table/*, src/lib/tabs/*, src/lib/stepper/*, src/lib/timeline/*, src/lib/skeleton/*, src/lib/progress/*, src/lib/rating/*, src/lib/table/theme.ts
Replaced generic slot names with semantic ones (e.g., divwrapper/container, lineskeletonLine, pvalue, progressLineprogress), added data-part/scope attributes, updated theme mappings.
Extend / integrations
src/lib/extend/*, src/lib/extend/*/theme.ts, src/routes/docs-examples/extend/*
Renamed many slots (e.g., tagitem, spanlabel, emptyemptyState, containerbase), added data-part/scope hooks, consolidated or removed some exports (e.g., removed dividerHitArea).
Video & theme-selector
src/lib/video/*, src/lib/theme-selector/*
Added video theme and multi-part Video component (slots: base, source, track); ThemeSelector gains typed props and is rewired to theme slots and classes.
Tests, scripts & docs
src/tests/**, convert-imports.mjs, find-imports.mjs, find-all-imports.mjs, v2-migration-guide.md, design-system-guide.md, SLOT_NAMING_REVIEW.md, COMPLETE_REVIEW_SUMMARY.md
Large set of new/updated tests (Range, Search, Select, Textarea, Timepicker, Toggle, MultiSelect, etc.), import-fix scripts, and migration/design-system documentation added.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Poem

🐰 I hopped through slots and parts tonight,

I renamed keys by soft moonlight.
data-parts pinned, tests aligned,
Themes tidied, types redefined —
A carrot-cheer for refactor delight! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description only contains a brief fix statement and the uncompleted template. Most required sections (PR Type, Status, Checklist items) are not filled out, and no substantive details about the changes, testing, or impacts are provided. Complete the PR description by filling in all required sections: select PR Type, confirm PR Status as ready, check all applicable checklist items, and add a detailed description of what was changed and why.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% 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-6' is vague and does not clearly communicate the main changes in the PR, which involve data-scope, data-part attributes, and theme slot renaming across device-mockup and drawer components. Revise the title to be more descriptive, such as 'Add data-scope/data-part attributes and rename theme slots for device-mockup and drawer components' to clearly reflect the PR's primary changes.
✨ Finishing touches
  • 📝 Generate docstrings

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
Copy Markdown
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

📜 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 48d751a and d1b7df7.

📒 Files selected for processing (12)
  • src/lib/device-mockups/Android.svelte
  • src/lib/device-mockups/DefaultMockup.svelte
  • src/lib/device-mockups/Desktop.svelte
  • src/lib/device-mockups/Ios.svelte
  • src/lib/device-mockups/Laptop.svelte
  • src/lib/device-mockups/Smartwatch.svelte
  • src/lib/device-mockups/Tablet.svelte
  • src/lib/device-mockups/theme.ts
  • src/lib/drawer/Drawer.svelte
  • src/lib/drawer/Drawerhead.svelte
  • src/lib/drawer/theme.ts
  • src/tests/device-mockups/ios-with-classes.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/drawer/theme.ts
  • src/tests/device-mockups/ios-with-classes.test.svelte
  • src/lib/drawer/Drawer.svelte
  • src/lib/device-mockups/Smartwatch.svelte
  • src/lib/device-mockups/Desktop.svelte
  • src/lib/drawer/Drawerhead.svelte
  • src/lib/device-mockups/theme.ts
  • src/lib/device-mockups/Ios.svelte
  • src/lib/device-mockups/Laptop.svelte
  • src/lib/device-mockups/DefaultMockup.svelte
  • src/lib/device-mockups/Android.svelte
  • src/lib/device-mockups/Tablet.svelte
🧠 Learnings (2)
📚 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/device-mockups/ios-with-classes.test.svelte
  • src/lib/drawer/Drawer.svelte
  • src/lib/device-mockups/Smartwatch.svelte
  • src/lib/device-mockups/Desktop.svelte
  • src/lib/drawer/Drawerhead.svelte
  • src/lib/device-mockups/Ios.svelte
  • src/lib/device-mockups/Laptop.svelte
  • src/lib/device-mockups/DefaultMockup.svelte
  • src/lib/device-mockups/Android.svelte
  • src/lib/device-mockups/Tablet.svelte
📚 Learning: 2024-11-22T08:37:27.996Z
Learnt from: mrh1997
Repo: themesberg/flowbite-svelte PR: 1442
File: src/lib/utils/Popper.svelte:144-145
Timestamp: 2024-11-22T08:37:27.996Z
Learning: In `src/lib/utils/Popper.svelte`, inconsistencies in event handling (e.g., using both `mouseenter`/`mouseleave` and `pointerenter`/`pointerleave`) may be intentional to minimize modifications and reduce the risk of new problems.

Applied to files:

  • src/lib/drawer/Drawerhead.svelte
🔇 Additional comments (12)
src/tests/device-mockups/ios-with-classes.test.svelte (1)

5-5: Test correctly updated to reflect new API keys.

The test properly uses the renamed keys (screen, notch) matching the changes in the iOS component and theme. This confirms the rename is coordinated across implementation and tests.

src/lib/drawer/Drawer.svelte (1)

117-130: Good: Added consistent data attributes for theming.

Adding data-scope="drawer" and data-part="base" to both Dialog instances ensures consistent component identification and enables better theming/styling capabilities. The formatting change improves readability without altering functionality.

src/lib/device-mockups/Tablet.svelte (1)

12-24: Component correctly updated to use renamed theme keys.

The Tablet component properly destructures and uses the renamed keys (screen, leftMiddle, leftBottom) matching the theme.ts changes. The data-part attributes are correctly updated to kebab-case equivalents.

src/lib/device-mockups/Laptop.svelte (1)

13-27: Component correctly updated to use renamed theme keys.

The Laptop component properly destructures and uses the renamed keys (screen, bottom, bottomCenter) matching the theme.ts changes. All data-part attributes and class bindings are consistently updated.

src/lib/device-mockups/Ios.svelte (1)

12-24: Component correctly updated to use renamed theme keys.

The iOS component properly destructures and uses the renamed keys (screen, notch, leftBottom) matching the theme.ts changes. The data-part attributes are correctly updated, and the addition of data-part="base" on the outer container improves consistency.

src/lib/device-mockups/DefaultMockup.svelte (1)

11-24: Component correctly updated to use renamed theme keys.

The DefaultMockup component properly destructures and uses the renamed keys (screen, leftTop, leftMiddle, leftBottom) matching the theme.ts changes. All data-part attributes and class bindings are consistently updated.

src/lib/device-mockups/theme.ts (1)

10-14: Breaking change: Public API slot keys renamed across all device mockups—but internal migration is complete.

The slot key renames (e.g., leftMidleftMiddle, leftBotleftBottom, top → removed/changed per device) are real breaking changes affecting consumers. However, all component implementations have been properly updated to use the new keys, so there are no incomplete internal usages.

Update test documentation to reflect the new slot names. The test file comments (lines 115, 146, 179, 211 in device-mockups.test.ts) and the test README.md (lines 88-101) still reference old slot names like top, leftMid, and leftBot. These need to be corrected to match the actual implementation:

  • Android: screen, notch, leftTop, leftMiddle, leftBottom, right (not top, leftMid, leftBot)
  • iOS: screen, notch, leftTop, leftBottom, right (not top, leftBot)
  • DefaultMockup/Tablet: Similar updates needed

Recommended actions:

  1. Update test documentation and comments to reflect the actual new slot names
  2. Add migration notes to the PR description documenting all key renames for each device type
  3. Consider a major version bump for this breaking change
src/lib/drawer/Drawerhead.svelte (2)

7-7: Good aliasing to avoid name collision.

Aliasing the closeIcon prop to closeIconSnippet cleanly avoids collision with the theme's closeIcon styling key while preserving the public API.


12-27: Approve refactoring; theme exports verified.

The rename from button/svg to closeButton/closeIcon is applied consistently in destructuring, data-part attributes, and class bindings. The src/lib/drawer/theme.ts exports a drawerhead() function with the required closeButton and closeIcon keys, confirming the refactoring is complete and correct.

src/lib/device-mockups/Smartwatch.svelte (1)

11-25: Refactoring approved; theme definitions match component usage.

The slot name standardization is correctly implemented. All six keys (topBase, base, rightTop, rightBottom, bottomBase, screen) are properly exported from the smartwatch() function in theme.ts and correctly destructured and applied throughout the template with matching data-part attributes.

src/lib/device-mockups/Desktop.svelte (1)

12-23: Approve standardization; theme alignment confirmed.

The rename from inner/bot/botUnder to screen/bottom/bottomBase is consistently applied across destructuring, data-part attributes, and styling references. The desktop() theme function properly exports all required keys (base, screen, bottom, bottomBase) matching the component's destructuring and usage.

src/lib/device-mockups/Android.svelte (1)

12-25: Refactoring verified and properly aligned across files.

The standardization—slotscreen, topnotch, leftMidleftMiddle, leftBotleftBottom—is correctly applied. Theme exports in theme.ts (lines 7-17) match the destructured properties in the component: base, screen, notch, leftTop, leftMiddle, leftBottom, right. The AndroidVariants type correctly derives from the updated android() function. No stale references to old property names exist.

Comment on lines +72 to +74
closeButton:
"ms-auto inline-flex h-8 w-8 items-center justify-center rounded-base bg-transparent text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-white",
svg: "h-4 w-4"
closeIcon: "h-4 w-4"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check Drawerhead component for proper key usage

echo "=== Checking Drawerhead.svelte for new key usage ==="
rg -n --type=svelte -C5 'closeButton|closeIcon' src/lib/drawer/Drawerhead.svelte

echo "=== Checking for old key references (should be empty) ==="
rg -n --type=svelte -C3 'styling\?\.button|theme\?\.button|styling\?\.svg|theme\?\.svg' src/lib/drawer/Drawerhead.svelte

Repository: themesberg/flowbite-svelte

Length of output: 259


🏁 Script executed:

#!/bin/bash
# Check if Drawerhead.svelte exists and search for key usage

echo "=== Checking if Drawerhead.svelte exists ==="
if [ -f "src/lib/drawer/Drawerhead.svelte" ]; then
  echo "File found. Displaying content:"
  cat -n src/lib/drawer/Drawerhead.svelte
else
  echo "File not found at src/lib/drawer/Drawerhead.svelte"
  echo "Looking for Drawerhead files:"
  find . -name "*Drawerhead*" -type f
fi

Repository: themesberg/flowbite-svelte

Length of output: 1976


🏁 Script executed:

#!/bin/bash
# Check for migration guides or deprecation warnings

echo "=== Checking for CHANGELOG or migration documentation ==="
find . -iname "CHANGELOG*" -o -iname "MIGRATION*" -o -iname "BREAKING*" | head -20

echo "=== Checking DrawerheadProps type definition ==="
rg -n "DrawerheadProps" src/lib/types.ts -A 20 | head -40

echo "=== Checking for any deprecation comments in drawer files ==="
rg -n "deprecat|breaking|migration|old.*key|button.*closeButton|svg.*closeIcon" src/lib/drawer/

Repository: themesberg/flowbite-svelte

Length of output: 1268


🏁 Script executed:

#!/bin/bash
# Search CHANGELOG for drawer-related breaking changes

echo "=== Searching CHANGELOG for drawer changes ==="
rg -n -i "drawer|closeButton|closeIcon|breaking.*change" CHANGELOG.md | head -30

Repository: themesberg/flowbite-svelte

Length of output: 3810


🏁 Script executed:

#!/bin/bash
# Read the beginning of CHANGELOG to see recent changes

echo "=== First 50 lines of CHANGELOG.md ==="
head -50 CHANGELOG.md

echo ""
echo "=== Search for Drawerhead in CHANGELOG ==="
rg -n "Drawerhead|slot.*key|classes.*drawer" CHANGELOG.md

Repository: themesberg/flowbite-svelte

Length of output: 1510


Breaking change: Drawerhead slot keys renamed, but no migration path documented.

Drawerhead.svelte has been properly updated to use the new keys (closeButton and closeIcon). However, this breaking change affects any consumers using the classes prop with the old key names (button and svg). While the implementation is correct, there is no deprecation warning, migration guide, or CHANGELOG entry documenting this change, leaving users without guidance on updating their code.

Recommend adding:

  • A deprecation warning in the component or a comment noting the breaking change
  • An entry in CHANGELOG.md documenting the slot key rename and migration steps
  • Optionally, a temporary fallback or warning when old key names are detected
🤖 Prompt for AI Agents
In src/lib/drawer/theme.ts around lines 72 to 74, the theme keys for the drawer
head were renamed to closeButton and closeIcon which breaks consumers using the
old button and svg keys; add a migration path: update Drawerhead.svelte (or the
consuming component) to detect legacy classes prop keys (button, svg), map them
to the new keys internally so old props still work, and emit a single-console
deprecation warning when legacy keys are present; add a brief entry to
CHANGELOG.md documenting the rename and the suggested migration (replace
button→closeButton, svg→closeIcon); optionally add an inline comment in theme.ts
noting the breaking change and planned removal timeline.

Copy link
Copy Markdown
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

📜 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 d1b7df7 and 6e0be5d.

📒 Files selected for processing (19)
  • src/lib/dropdown/Dropdown.svelte
  • src/lib/dropdown/DropdownDivider.svelte
  • src/lib/dropdown/DropdownGroup.svelte
  • src/lib/dropdown/DropdownHeader.svelte
  • src/lib/dropdown/DropdownItem.svelte
  • src/lib/dropdown/theme.ts
  • src/lib/footer/Footer.svelte
  • src/lib/footer/FooterBrand.svelte
  • src/lib/footer/FooterCopyright.svelte
  • src/lib/footer/FooterIcon.svelte
  • src/lib/footer/FooterLink.svelte
  • src/lib/footer/FooterLinkGroup.svelte
  • src/lib/footer/theme.ts
  • src/lib/gallery/Gallery.svelte
  • src/lib/indicator/Indicator.svelte
  • src/lib/kbd/Kbd.svelte
  • src/lib/list-group/Listgroup.svelte
  • src/lib/list-group/ListgroupItem.svelte
  • v2-migration.md
✅ Files skipped from review due to trivial changes (2)
  • v2-migration.md
  • src/lib/gallery/Gallery.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/kbd/Kbd.svelte
  • src/lib/footer/FooterLink.svelte
  • src/lib/dropdown/DropdownItem.svelte
  • src/lib/list-group/ListgroupItem.svelte
  • src/lib/list-group/Listgroup.svelte
  • src/lib/footer/Footer.svelte
  • src/lib/footer/FooterIcon.svelte
  • src/lib/dropdown/Dropdown.svelte
  • src/lib/dropdown/DropdownGroup.svelte
  • src/lib/dropdown/theme.ts
  • src/lib/indicator/Indicator.svelte
  • src/lib/dropdown/DropdownHeader.svelte
  • src/lib/footer/FooterLinkGroup.svelte
  • src/lib/dropdown/DropdownDivider.svelte
  • src/lib/footer/FooterCopyright.svelte
  • src/lib/footer/FooterBrand.svelte
  • src/lib/footer/theme.ts
🧠 Learnings (5)
📚 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/kbd/Kbd.svelte
  • src/lib/footer/FooterLink.svelte
  • src/lib/dropdown/DropdownItem.svelte
  • src/lib/list-group/ListgroupItem.svelte
  • src/lib/list-group/Listgroup.svelte
  • src/lib/footer/Footer.svelte
  • src/lib/footer/FooterIcon.svelte
  • src/lib/dropdown/Dropdown.svelte
  • src/lib/dropdown/DropdownGroup.svelte
  • src/lib/indicator/Indicator.svelte
  • src/lib/dropdown/DropdownHeader.svelte
  • src/lib/footer/FooterLinkGroup.svelte
  • src/lib/dropdown/DropdownDivider.svelte
  • src/lib/footer/FooterCopyright.svelte
  • src/lib/footer/FooterBrand.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/footer/FooterLink.svelte
  • src/lib/footer/FooterIcon.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/dropdown/DropdownItem.svelte
  • src/lib/dropdown/Dropdown.svelte
  • src/lib/indicator/Indicator.svelte
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1465
File: src/lib/forms/Timepicker.svelte:105-116
Timestamp: 2024-10-18T09:38:03.879Z
Learning: In `Timepicker.svelte`, the `Dropdown` opens as intended and is used exclusively with the 'dropdown' and 'timerange-dropdown' Timepicker types.

Applied to files:

  • src/lib/dropdown/Dropdown.svelte
  • src/lib/dropdown/DropdownDivider.svelte
📚 Learning: 2025-12-28T05:16:44.735Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-12-28T05:16:44.735Z
Learning: In flowbite-svelte with Svelte 5, props are not reactive by default. To make prop values reactive (so they update when the prop changes), they must be wrapped with `$derived()`. For example, `const styling = $derived(classes)` is necessary—not redundant—to ensure `styling` reacts to changes in the `classes` prop.

Applied to files:

  • src/lib/dropdown/DropdownDivider.svelte
🔇 Additional comments (19)
src/lib/indicator/Indicator.svelte (1)

26-26: LGTM! Non-breaking data attribute addition.

The addition of data-scope="indicator" and data-part="base" provides better component identification for styling and testing without affecting functionality. The naming is semantic and consistent with the PR's broader pattern of adding scoping attributes.

src/lib/kbd/Kbd.svelte (1)

14-14: LGTM! Clean addition of metadata attributes.

The data-scope and data-part attributes are correctly positioned before {...restProps}, allowing potential overrides if needed. The values are semantically appropriate for the component, and the change aligns with the PR's objective of adding standardized metadata across components.

src/lib/list-group/ListgroupItem.svelte (2)

1-20: LGTM: Theme reactivity correctly implemented.

The theme derivation at line 12 follows best practices by using $derived(getTheme("listGroupItem")), ensuring the component reacts to dynamic theme changes. This aligns with the Flowbite-Svelte pattern for reactive theming.


34-42: LGTM: Consistent data attributes added.

The addition of data-scope="listgroup-item" and data-part="base" attributes across all three render branches (li, button, and a elements) is consistent and aligns with the PR's objective of standardizing component scoping attributes across the codebase. These non-breaking metadata attributes enable consistent element identification.

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

41-41: LGTM! Data attributes added for scoping.

The addition of data-scope and data-part attributes provides consistent component identification without altering functionality.

src/lib/footer/FooterLink.svelte (1)

16-17: LGTM! Data attributes added for scoping.

The addition of data-scope and data-part attributes provides consistent component identification across the footer module without altering functionality.

src/lib/dropdown/DropdownDivider.svelte (1)

10-13: LGTM! Consistent refactor with data attributes.

The extraction of base to a $derived expression (line 10) improves consistency with other components in the PR, and the data attributes (line 13) provide proper scoping without changing functionality.

src/lib/dropdown/Dropdown.svelte (1)

28-28: LGTM! Data attributes added for scoping.

The addition of data-scope and data-part attributes provides consistent component identification without altering functionality.

src/lib/footer/FooterLinkGroup.svelte (1)

12-12: LGTM! Data attributes added for scoping.

The addition of data-scope and data-part attributes provides consistent component identification without altering functionality.

src/lib/footer/FooterIcon.svelte (1)

13-13: LGTM! Data attributes added for scoping.

The addition of data-scope and data-part attributes provides consistent component identification without altering functionality. Appropriately applied only when href is present.

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

22-23: All consumers of footerBrand slots have been correctly updated.

The slot keys have been renamed from span and img to label and image in FooterBrand.svelte. No instances of the old slot names were found in the codebase, and the FooterBrand component correctly uses the new slot names internally.


33-33: All consumers of footerCopyright slots have been properly updated to use the new key.

The slot key has been successfully renamed from bySpan to label. FooterCopyright.svelte correctly destructures and applies the new label slot (line 16 and 26), and no references to the old key exist in the codebase. The public API via FooterCopyrightVariants properly exposes this slot.

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

20-22: All consumers of the dropdownItem slot have been properly updated to use the new item key.

The slot migration from li to item is complete. DropdownItem.svelte (line 18) correctly imports {base, active, item} from the dropdownItem theme and applies the styling on line 19 using theme?.item. No remaining references to the old li slot were found in the codebase, and the DropdownItemVariants type is correctly exposed through the updated dropdownItem definition.

src/lib/footer/Footer.svelte (1)

14-14: LGTM! Data attributes added correctly.

The addition of data-scope="footer" and data-part="base" provides scoping hooks without affecting functionality.

src/lib/dropdown/DropdownHeader.svelte (1)

10-13: LGTM! Improved class derivation.

The refactor to compute the base class once via $derived instead of inline is cleaner and more efficient. The data attributes provide proper scoping.

src/lib/footer/FooterBrand.svelte (1)

12-28: LGTM! Consistent slot name refactor.

The renaming from span/img to label/image improves semantic clarity, and all references are updated consistently. Data attributes are correctly applied to both the linked and non-linked variants.

src/lib/dropdown/DropdownGroup.svelte (1)

10-13: LGTM! Consistent pattern applied.

The derived base class and data attributes follow the same clean pattern established in other dropdown components.

src/lib/footer/FooterCopyright.svelte (1)

16-29: LGTM! Slot rename applied consistently.

The renaming from bySpan to label improves clarity, and all references are updated correctly. Data attributes are properly scoped for each element.

src/lib/dropdown/DropdownItem.svelte (1)

22-22: Verify empty data-part attribute.

The data-part="" attribute is empty on the <li> wrapper element. This might be intentional to indicate a structural wrapper without a specific part name, but please confirm this is the desired behavior rather than an oversight.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
src/lib/navbar/theme.ts (1)

76-109: Critical bug: Compound variants reference non-existent slot name.

The compound variants on lines 83, 91, 99, and 107 reference a slot named ul, but the slots definition on line 35 renamed this to list. This will cause the compound variant classes to never be applied, breaking responsive styling for the navigation list.

🔎 Proposed fix
     {
       breakpoint: "sm",
       hidden: false,
       class: {
         base: "sm:static sm:z-auto",
-        ul: "sm:border-none sm:rounded-none sm:bg-inherit dark:sm:bg-inherit sm:shadow-none"
+        list: "sm:border-none sm:rounded-none sm:bg-inherit dark:sm:bg-inherit sm:shadow-none"
       }
     },
     {
       breakpoint: "md",
       hidden: false,
       class: {
         base: "md:static md:z-auto",
-        ul: "md:border-none md:rounded-none md:bg-inherit dark:md:bg-inherit md:shadow-none"
+        list: "md:border-none md:rounded-none md:bg-inherit dark:md:bg-inherit md:shadow-none"
       }
     },
     {
       breakpoint: "lg",
       hidden: false,
       class: {
         base: "lg:static lg:z-auto",
-        ul: "lg:border-none lg:rounded-none lg:bg-inherit dark:lg:bg-inherit lg:shadow-none"
+        list: "lg:border-none lg:rounded-none lg:bg-inherit dark:lg:bg-inherit lg:shadow-none"
       }
     },
     {
       breakpoint: "xl",
       hidden: false,
       class: {
         base: "xl:static xl:z-auto",
-        ul: "xl:border-none xl:rounded-none xl:bg-inherit dark:xl:bg-inherit xl:shadow-none"
+        list: "xl:border-none xl:rounded-none xl:bg-inherit dark:xl:bg-inherit xl:shadow-none"
       }
     }
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e0be5d and 8fc4e46.

📒 Files selected for processing (19)
  • src/lib/dropdown/DropdownItem.svelte
  • src/lib/footer/FooterCopyright.svelte
  • src/lib/list-group/Listgroup.svelte
  • src/lib/mega-menu/MegaMenu.svelte
  • src/lib/mega-menu/theme.ts
  • src/lib/navbar/Menu.svelte
  • src/lib/navbar/NavBrand.svelte
  • src/lib/navbar/NavContainer.svelte
  • src/lib/navbar/NavLi.svelte
  • src/lib/navbar/NavUl.svelte
  • src/lib/navbar/Navbar.svelte
  • src/lib/navbar/index.ts
  • src/lib/navbar/theme.ts
  • src/lib/theme-provider/themes.ts
  • src/lib/types.ts
  • src/routes/docs-examples/components/mega-menu/Cta.svelte
  • src/routes/docs-examples/components/mega-menu/Image.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/tests/mega-menu/full-mega-menu.test.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/dropdown/DropdownItem.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/list-group/Listgroup.svelte
  • src/lib/footer/FooterCopyright.svelte
  • src/lib/navbar/NavBrand.svelte
  • src/lib/theme-provider/themes.ts
  • src/lib/mega-menu/theme.ts
  • src/lib/navbar/NavContainer.svelte
  • src/routes/docs-examples/components/mega-menu/Cta.svelte
  • src/lib/navbar/Menu.svelte
  • src/lib/navbar/NavLi.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/tests/mega-menu/full-mega-menu.test.svelte
  • src/routes/docs-examples/components/mega-menu/Image.svelte
  • src/lib/navbar/NavUl.svelte
  • src/lib/navbar/Navbar.svelte
  • src/lib/navbar/index.ts
  • src/lib/types.ts
  • src/lib/navbar/theme.ts
  • src/lib/mega-menu/MegaMenu.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/lib/list-group/Listgroup.svelte
  • src/lib/footer/FooterCopyright.svelte
  • src/lib/navbar/NavBrand.svelte
  • src/lib/navbar/NavContainer.svelte
  • src/routes/docs-examples/components/mega-menu/Cta.svelte
  • src/lib/navbar/Menu.svelte
  • src/lib/navbar/NavLi.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/tests/mega-menu/full-mega-menu.test.svelte
  • src/routes/docs-examples/components/mega-menu/Image.svelte
  • src/lib/navbar/NavUl.svelte
  • src/lib/navbar/Navbar.svelte
  • src/lib/mega-menu/MegaMenu.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/Menu.svelte
  • src/lib/mega-menu/MegaMenu.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/layouts/FlowbiteSvelteLayout.svelte
📚 Learning: 2025-12-28T05:16:44.735Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-12-28T05:16:44.735Z
Learning: In flowbite-svelte with Svelte 5, props are not reactive by default. To make prop values reactive (so they update when the prop changes), they must be wrapped with `$derived()`. For example, `const styling = $derived(classes)` is necessary—not redundant—to ensure `styling` reacts to changes in the `classes` prop.

Applied to files:

  • src/routes/layouts/FlowbiteSvelteLayout.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: 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/layouts/FlowbiteSvelteLayout.svelte
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1465
File: src/lib/forms/Timepicker.svelte:105-116
Timestamp: 2024-10-18T09:38:03.879Z
Learning: In `Timepicker.svelte`, the `Dropdown` opens as intended and is used exclusively with the 'dropdown' and 'timerange-dropdown' Timepicker types.

Applied to files:

  • src/lib/types.ts
🧬 Code graph analysis (1)
src/lib/navbar/theme.ts (2)
src/lib/navbar/index.ts (4)
  • navUl (8-8)
  • navbarHamburger (8-8)
  • navbar (8-8)
  • navLi (8-8)
src/lib/theme-provider/themes.ts (4)
  • navUl (26-26)
  • navbarHamburger (26-26)
  • navbar (26-26)
  • navLi (26-26)
🔇 Additional comments (22)
src/lib/list-group/Listgroup.svelte (1)

41-41: LGTM! Consistent with project-wide attribute standardization.

The addition of data-scope="list-group" and data-part="base" follows the established pattern across the codebase for component identification and theming. The kebab-case naming in data attributes (vs. camelCase in JS/TS) is standard practice and aligns with other components in this PR.

src/lib/footer/FooterCopyright.svelte (4)

19-19: LGTM! Data attributes correctly applied.

The addition of data-scope="footer-copyright" and data-part="base" attributes aligns with the PR objectives and provides proper element identification for styling and testing hooks.


22-27: LGTM! Consistent refactoring and data attributes.

The changes correctly:

  • Update the class binding from bySpan to label (line 26)
  • Add data-part="link" to the anchor tag (line 22)
  • Add data-part="label" to the span tag (line 26)
  • Reference theme?.label and styling?.label consistently with the destructured property

12-12: LGTM! Correct reactive theme usage.

The getTheme("footerCopyright") call is correctly wrapped in $derived(), ensuring the component reactively responds to dynamic theme changes from ThemeProvider.

Based on learnings, this is the correct pattern for theme-derived values in Flowbite-Svelte components.


16-16: Refactoring is correctly implemented.

The footerCopyright() function in theme.ts has been properly updated with the label slot replacing the previous bySpan, and no remaining references to bySpan exist in the codebase. The destructuring on line 16 is correct.

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

116-157: LGTM: New navLi theme definition.

The new navLi theme with slots and responsive variants is well-structured and follows the same pattern as navUl.


8-8: No breaking API change to document—the original exports were navUl/navLi, not navbarUl/navbarLi.

The references to navbarUl in Frame.svelte are local theme configuration keys defined within that component's <script module>, not exports from src/lib/navbar/theme.ts. The actual exports from theme.ts are navUl and navLi with corresponding types NavbarUlVariants and NavLiVariants, which have not been renamed. There is no evidence of a breaking API change.

Likely an incorrect or invalid review comment.

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

12-14: LGTM: Snippet rename aligns with MegaMenu API.

The snippet name change from extra to addon is consistent with the MegaMenu component's prop rename.

src/routes/docs-examples/components/mega-menu/Image.svelte (1)

37-46: LGTM: Consistent snippet rename.

The addon snippet name correctly reflects the updated MegaMenu API.

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

30-30: LGTM: Data attributes for component identification.

The addition of data-scope and data-part attributes is consistent with the PR's pattern of adding scoping identifiers to components.

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

12-12: LGTM: Scoping attributes added.

The data attributes follow the established pattern for component identification.

src/routes/docs-examples/components/mega-menu/Cta.svelte (1)

36-44: LGTM: Snippet rename matches API update.

The addon snippet usage is correct and consistent with the MegaMenu component changes.

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

12-12: LGTM: Data attributes added for scoping.

The addition is consistent with the PR's pattern of adding component identification attributes.

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

8-8: LGTM: Export names align with theme refactor.

The export renames (navbarUlnavUl) and the addition of navLi are consistent with the changes in theme.ts. Note that this is a breaking change for external consumers.

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

62-62: LGTM! Consistent with theme API changes.

The classes prop key update from ul to list correctly reflects the NavUl theme slot rename.

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

14-47: LGTM! Theme structure update implemented correctly.

The navbar component now includes a content wrapper layer, aligning with the updated theme API. Theme reactivity uses $derived appropriately, and data attributes follow the established pattern.

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

8-26: LGTM! Theme slot refactor implemented correctly.

The component now uses addon instead of extra (breaking API change noted in PR description), and slot keys have been updated to content, list, and footer. All changes are internally consistent with the theme updates.

src/lib/mega-menu/theme.ts (1)

10-27: LGTM! Theme slot and variant renames are consistent.

The slot keys (content, list, footer) and variant key (hasAddon) align perfectly with the component changes in MegaMenu.svelte.

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

8-59: LGTM! Theme API updates implemented correctly.

Import and theme lookup updated from navbarUl to navUl, and slot key renamed from ul to list. Theme reactivity uses $derived appropriately.

Based on learnings: Theme calls properly wrapped in $derived() for reactivity.

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

5-50: LGTM! NavLi refactor implemented correctly.

Import updated to navLi, classes prop added, and theme structure changed to use base and item slots. Data attributes added consistently, and theme reactivity uses $derived appropriately.

Based on learnings: Props like classes are properly made reactive using $derived().

src/lib/types.ts (1)

43-1121: LGTM! Type definitions updated to support component changes.

All type updates are consistent with component refactors:

  • Import additions support variant-based typing (DropdownItemVariants, NavLiVariants)
  • MegaMenuProps addon prop rename aligns with MegaMenu.svelte
  • NavLiProps correctly extends NavLiVariants and includes new class props
  • AccordionProps clarifying comment improves documentation
src/lib/theme-provider/themes.ts (1)

26-26: No action required. Verification found no imports using the old navbarLi or navbarUl names anywhere in the codebase. All references throughout the project already use the new names navLi and navUl, confirming the breaking change has been properly applied with no dangling references.

… popover, progress, rating, sidebar, skeleton directories
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
src/lib/pagination/Pagination.svelte (1)

35-61: Remove restProps spreading from the next button's li element for consistency.

The {...restProps} spreading has been removed from the previous button's <li> (line 35) and page items' <li> (line 46), but it's still present on line 53 for the next button's <li>. This creates inconsistent behavior where only the next button's list item receives additional props.

🔎 Proposed fix
    {/each}
    {#if typeof next === "function"}
-     <li {...restProps}>
+     <li>
        <PaginationItem {size} onclick={() => next()} class={table ? "rounded-none rounded-r" : "rounded-e-base rounded-none"}>
          {#if nextContent}
            {@render nextContent()}
🧹 Nitpick comments (3)
src/lib/skeleton/TestimonialPlaceholder.svelte (1)

9-11: Minor inconsistency: Consider wrapping in $derived() for consistency.

The testimonialPlaceholder() call on line 11 is not wrapped in $derived(), unlike similar calls in ListPlaceholder and TextPlaceholder. While this works because testimonialPlaceholder() takes no reactive props, wrapping it in $derived() would maintain consistency across skeleton components.

🔎 Suggested change for consistency
-  const { base, primaryLine, secondaryLine, avatarIcon, authorInfo } = testimonialPlaceholder();
+  const { base, primaryLine, secondaryLine, avatarIcon, authorInfo } = $derived(testimonialPlaceholder());
src/lib/skeleton/CardPlaceholder.svelte (1)

35-45: Consider adding data-part attributes to footer child elements for consistency.

The skeleton lines and SVG inside the footer (lines 36, 43, 44) don't have data-part attributes, while similar skeleton-line elements outside the footer (lines 31-34) do have them. This minor inconsistency may affect testing or styling hooks that target skeleton lines by data-part.

🔎 Suggested change for consistency
   <div data-part="footer" class={footer({ class: clsx(theme?.footer, classes?.footer) })}>
-    <svg class={skeletonLine({ class: clsx("h-14 w-14", theme?.skeletonLine, classes?.skeletonLine) })} aria-hidden="true" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
+    <svg data-part="skeleton-line" class={skeletonLine({ class: clsx("h-14 w-14", theme?.skeletonLine, classes?.skeletonLine) })} aria-hidden="true" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
       <path
         fill-rule="evenodd"
         d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-6-3a2 2 0 11-4 0 2 2 0 014 0zm-2 4a5 5 0 00-4.546 2.916A5.986 5.986 0 0010 16a5.986 5.986 0 004.546-2.084A5 5 0 0010 11z"
         clip-rule="evenodd"
       ></path>
     </svg>
-    <div class={skeletonLine({ class: clsx("mb-2 h-2.5 w-32", theme?.skeletonLine, classes?.skeletonLine) })}></div>
-    <div class={skeletonLine({ class: clsx("mb-2 h-2 w-32", theme?.skeletonLine, classes?.skeletonLine) })}></div>
+    <div data-part="skeleton-line" class={skeletonLine({ class: clsx("mb-2 h-2.5 w-32", theme?.skeletonLine, classes?.skeletonLine) })}></div>
+    <div data-part="skeleton-line" class={skeletonLine({ class: clsx("mb-2 h-2 w-32", theme?.skeletonLine, classes?.skeletonLine) })}></div>
   </div>
src/routes/docs-examples/components/sidebar/Single.svelte (1)

7-7: Consider renaming for consistency.

The variable spanClass is used with the label key on Line 47. For consistency with other example files (Branding.svelte, CloseButton.svelte), consider renaming this to labelClass.

🔎 Proposed rename for consistency
-  const spanClass = "flex-1 ms-3 whitespace-nowrap";
+  const labelClass = "flex-1 ms-3 whitespace-nowrap";

And update Line 47:

-      <SidebarItem label="Sidebar" classes={{ label: spanClass }} href="/components/sidebar">
+      <SidebarItem label="Sidebar" classes={{ label: labelClass }} href="/components/sidebar">
📜 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 8fc4e46 and fa73495.

📒 Files selected for processing (54)
  • src/lib/navbar/theme.ts
  • src/lib/pagination/Pagination.svelte
  • src/lib/pagination/PaginationButton.svelte
  • src/lib/pagination/PaginationNav.svelte
  • src/lib/pagination/theme.ts
  • src/lib/popover/Popover.svelte
  • src/lib/popover/theme.ts
  • src/lib/progress/Progressbar.svelte
  • src/lib/progress/Progressradial.svelte
  • src/lib/progress/theme.ts
  • src/lib/rating/AdvancedRating.svelte
  • src/lib/rating/Rating.svelte
  • src/lib/rating/Review.svelte
  • src/lib/rating/ScoreRating.svelte
  • src/lib/rating/theme.ts
  • 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/SidebarItem.svelte
  • src/lib/sidebar/theme.ts
  • src/lib/skeleton/CardPlaceholder.svelte
  • src/lib/skeleton/ImagePlaceholder.svelte
  • src/lib/skeleton/ListPlaceholder.svelte
  • src/lib/skeleton/Skeleton.svelte
  • src/lib/skeleton/TestimonialPlaceholder.svelte
  • src/lib/skeleton/TextPlaceholder.svelte
  • src/lib/skeleton/VideoPlaceholder.svelte
  • src/lib/skeleton/WidgetPlaceholder.svelte
  • src/lib/skeleton/theme.ts
  • src/lib/types.ts
  • src/routes/admin-dashboard/(sidebar)/Sidebar.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/MultiLevel2.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/progressradial/Animation.svelte
  • src/routes/docs-examples/extend/progressradial/Colors.svelte
  • src/routes/docs-examples/extend/split-pane/+page.svelte
  • src/routes/layouts/ComponentsLayout.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/types.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • src/lib/skeleton/VideoPlaceholder.svelte
  • src/routes/docs-examples/extend/progressradial/Animation.svelte
  • src/routes/docs-examples/components/sidebar/AlwaysOpen.svelte
  • src/routes/docs-examples/components/sidebar/Separator.svelte
  • src/lib/pagination/PaginationButton.svelte
  • src/lib/sidebar/SidebarBrand.svelte
  • src/lib/skeleton/CardPlaceholder.svelte
  • src/lib/rating/ScoreRating.svelte
  • src/routes/docs-examples/components/sidebar/Transition.svelte
  • src/routes/docs-examples/components/sidebar/MultiLevel2.svelte
  • src/lib/rating/AdvancedRating.svelte
  • src/lib/navbar/theme.ts
  • src/lib/progress/theme.ts
  • src/lib/pagination/Pagination.svelte
  • src/routes/docs-examples/components/sidebar/LinksAndActive2.svelte
  • src/lib/sidebar/SidebarButton.svelte
  • src/routes/docs-examples/components/sidebar/Static.svelte
  • src/lib/skeleton/TestimonialPlaceholder.svelte
  • src/lib/skeleton/Skeleton.svelte
  • src/routes/docs-examples/extend/split-pane/+page.svelte
  • src/lib/progress/Progressradial.svelte
  • src/lib/rating/theme.ts
  • src/routes/docs-examples/components/sidebar/CloseButton.svelte
  • src/routes/docs-examples/extend/progressradial/Colors.svelte
  • src/lib/skeleton/theme.ts
  • src/routes/layouts/ComponentsLayout.svelte
  • src/lib/sidebar/SidebarCta.svelte
  • src/lib/skeleton/ListPlaceholder.svelte
  • src/routes/docs-examples/components/sidebar/LinksAndActive.svelte
  • src/lib/popover/theme.ts
  • src/lib/skeleton/WidgetPlaceholder.svelte
  • src/lib/skeleton/ImagePlaceholder.svelte
  • src/routes/docs-examples/components/sidebar/ObjectEx.svelte
  • src/routes/docs-examples/components/sidebar/Default.svelte
  • src/lib/sidebar/Sidebar.svelte
  • src/routes/admin-dashboard/(sidebar)/Sidebar.svelte
  • src/routes/docs-examples/components/sidebar/BrandingUsingChildren.svelte
  • src/lib/rating/Review.svelte
  • src/routes/docs-examples/components/sidebar/Branding.svelte
  • src/lib/sidebar/SidebarItem.svelte
  • src/lib/popover/Popover.svelte
  • src/lib/pagination/PaginationNav.svelte
  • src/lib/skeleton/TextPlaceholder.svelte
  • src/lib/progress/Progressbar.svelte
  • src/lib/rating/Rating.svelte
  • src/routes/docs-examples/components/sidebar/MultiLevel.svelte
  • src/routes/docs-examples/components/sidebar/Cta.svelte
  • src/routes/docs-examples/components/drawer/Navigation.svelte
  • src/routes/docs-examples/components/sidebar/Single.svelte
  • src/lib/sidebar/SidebarDropdownWrapper.svelte
  • src/lib/sidebar/theme.ts
  • src/lib/pagination/theme.ts
  • src/routes/docs-examples/components/sidebar/AllOpen.svelte
🧠 Learnings (10)
📚 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/skeleton/VideoPlaceholder.svelte
  • src/routes/docs-examples/extend/progressradial/Animation.svelte
  • src/routes/docs-examples/components/sidebar/AlwaysOpen.svelte
  • src/routes/docs-examples/components/sidebar/Separator.svelte
  • src/lib/pagination/PaginationButton.svelte
  • src/lib/sidebar/SidebarBrand.svelte
  • src/lib/skeleton/CardPlaceholder.svelte
  • src/lib/rating/ScoreRating.svelte
  • src/routes/docs-examples/components/sidebar/Transition.svelte
  • src/routes/docs-examples/components/sidebar/MultiLevel2.svelte
  • src/lib/rating/AdvancedRating.svelte
  • src/lib/pagination/Pagination.svelte
  • src/routes/docs-examples/components/sidebar/LinksAndActive2.svelte
  • src/lib/sidebar/SidebarButton.svelte
  • src/routes/docs-examples/components/sidebar/Static.svelte
  • src/lib/skeleton/TestimonialPlaceholder.svelte
  • src/lib/skeleton/Skeleton.svelte
  • src/routes/docs-examples/extend/split-pane/+page.svelte
  • src/lib/progress/Progressradial.svelte
  • src/routes/docs-examples/components/sidebar/CloseButton.svelte
  • src/routes/docs-examples/extend/progressradial/Colors.svelte
  • src/routes/layouts/ComponentsLayout.svelte
  • src/lib/sidebar/SidebarCta.svelte
  • src/lib/skeleton/ListPlaceholder.svelte
  • src/routes/docs-examples/components/sidebar/LinksAndActive.svelte
  • src/lib/skeleton/WidgetPlaceholder.svelte
  • src/lib/skeleton/ImagePlaceholder.svelte
  • src/routes/docs-examples/components/sidebar/ObjectEx.svelte
  • src/routes/docs-examples/components/sidebar/Default.svelte
  • src/lib/sidebar/Sidebar.svelte
  • src/routes/admin-dashboard/(sidebar)/Sidebar.svelte
  • src/routes/docs-examples/components/sidebar/BrandingUsingChildren.svelte
  • src/lib/rating/Review.svelte
  • src/routes/docs-examples/components/sidebar/Branding.svelte
  • src/lib/sidebar/SidebarItem.svelte
  • src/lib/popover/Popover.svelte
  • src/lib/pagination/PaginationNav.svelte
  • src/lib/skeleton/TextPlaceholder.svelte
  • src/lib/progress/Progressbar.svelte
  • src/lib/rating/Rating.svelte
  • src/routes/docs-examples/components/sidebar/MultiLevel.svelte
  • src/routes/docs-examples/components/sidebar/Cta.svelte
  • src/routes/docs-examples/components/drawer/Navigation.svelte
  • src/routes/docs-examples/components/sidebar/Single.svelte
  • src/lib/sidebar/SidebarDropdownWrapper.svelte
  • src/routes/docs-examples/components/sidebar/AllOpen.svelte
📚 Learning: 2025-12-28T05:16:44.735Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-12-28T05:16:44.735Z
Learning: In flowbite-svelte with Svelte 5, props are not reactive by default. To make prop values reactive (so they update when the prop changes), they must be wrapped with `$derived()`. For example, `const styling = $derived(classes)` is necessary—not redundant—to ensure `styling` reacts to changes in the `classes` prop.

Applied to files:

  • src/routes/docs-examples/extend/progressradial/Animation.svelte
  • src/routes/docs-examples/components/sidebar/MultiLevel2.svelte
  • src/routes/docs-examples/extend/progressradial/Colors.svelte
  • src/routes/docs-examples/components/sidebar/Single.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/pagination/PaginationButton.svelte
  • src/routes/docs-examples/components/sidebar/Transition.svelte
  • src/routes/docs-examples/components/sidebar/MultiLevel2.svelte
  • src/lib/sidebar/Sidebar.svelte
  • src/lib/popover/Popover.svelte
  • src/routes/docs-examples/components/sidebar/MultiLevel.svelte
  • src/routes/docs-examples/components/sidebar/Single.svelte
  • src/lib/sidebar/SidebarDropdownWrapper.svelte
  • src/routes/docs-examples/components/sidebar/AllOpen.svelte
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1465
File: src/lib/forms/Timepicker.svelte:105-116
Timestamp: 2024-10-18T09:38:03.879Z
Learning: In `Timepicker.svelte`, the `Dropdown` opens as intended and is used exclusively with the 'dropdown' and 'timerange-dropdown' Timepicker types.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/routes/docs-examples/extend/progressradial/Colors.svelte
🧬 Code graph analysis (3)
src/lib/rating/theme.ts (1)
src/lib/rating/index.ts (3)
  • rating (10-10)
  • review (10-10)
  • scoreRating (10-10)
src/lib/skeleton/theme.ts (1)
src/lib/skeleton/index.ts (1)
  • textPlaceholder (9-9)
src/lib/sidebar/theme.ts (1)
src/lib/sidebar/index.ts (3)
  • sidebarCta (10-10)
  • sidebarDropdownWrapper (10-10)
  • sidebarItem (10-10)
🔇 Additional comments (90)
src/lib/popover/Popover.svelte (2)

25-26: LGTM: Destructuring updated to match theme slot rename.

The destructuring correctly uses heading instead of h3, aligning with the theme.ts slot key rename. This change is consistent with the broader refactoring effort.


28-38: LGTM: Data attributes and class bindings correctly updated.

The additions of data-scope="popover" and data-part attributes enhance component identification. All class bindings correctly reference the renamed heading token (previously h3), maintaining styling consistency while improving semantic clarity.

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

12-99: LGTM: Theme slot key consistently renamed across all variants.

The slot key rename from h3 to heading is applied consistently across:

  • The base slot definition (line 12)
  • All 21 color variants (lines 18-98)

This semantic naming improves API clarity and aligns with the broader theme refactoring effort. While this is a breaking change for users with custom themes, it's appropriate for a v2 release.

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

14-199: LGTM! Systematic slot renaming improves semantic clarity.

The theme refactoring comprehensively renames slots across all skeleton components for better semantic meaning (e.g., lineskeletonLine, areaimagePlaceholder, wrapperbase). All size and rounded variants are correctly updated to reference the new slot names.

Note: This is a breaking change for consumers using custom theme overrides or the classes prop with the old slot names.

src/lib/skeleton/VideoPlaceholder.svelte (1)

14-14: LGTM! Data attributes added correctly.

The data-scope="video-placeholder" and data-part="base" attributes enable part-based theming hooks, consistent with the broader skeleton component refactoring.

src/lib/skeleton/WidgetPlaceholder.svelte (2)

11-11: LGTM! Slot destructuring updated to match theme.ts.

The destructuring correctly uses the renamed slots from widgetPlaceholder theme: chartContainer, chartBar, and labelLine (previously wrapper, vLine, hLine).


14-27: LGTM! Data attributes and slot usage are consistent.

All elements correctly:

  • Use the new slot names (chartContainer, chartBar, labelLine)
  • Include data-part attributes matching the semantic part names
  • Properly merge theme and custom classes via clsx

The refactoring maintains functionality while improving theming hooks.

src/lib/skeleton/ImagePlaceholder.svelte (2)

11-22: LGTM! Slot destructuring correctly updated.

The destructuring uses the renamed slots from imagePlaceholder theme and aliases imagePlaceholder to imageArea for clarity. All slot names (imagePlaceholder, imageIcon, skeletonLine) match the theme.ts definitions.


25-89: LGTM! Data attributes and slot usage are consistent.

All elements correctly:

  • Use data-scope="image-placeholder" on the root container
  • Apply appropriate data-part attributes (base, image-placeholder, image-icon, content, skeleton-line)
  • Reference the new slot names (imageArea, imageIcon, content, skeletonLine)
  • Properly merge theme and custom classes

The refactoring maintains functionality while adding semantic theming hooks.

src/lib/skeleton/Skeleton.svelte (2)

11-11: LGTM! Slot destructuring updated correctly.

The destructuring uses the renamed slots: base and skeletonLine (previously wrapper and line), matching the theme.ts definitions at lines 123-124.


14-43: LGTM! Data attributes and slot usage are consistent.

All skeleton line elements correctly:

  • Use data-scope="skeleton" on the root container
  • Apply data-part="skeleton-line" to each line element
  • Reference the skeletonLine slot with proper theme/class merging
  • Maintain the base container styling

The refactoring adds semantic theming hooks while preserving functionality.

src/lib/skeleton/ListPlaceholder.svelte (2)

9-13: LGTM! Theme reactivity and slot naming are correctly implemented.

The getTheme() call is properly wrapped in $derived() per the established pattern for reactive themes. The renamed slots (listItem, itemContent, primaryLine, secondaryLine, valueLine) align with the semantic naming convention being applied across skeleton components.


16-49: Data attributes and class bindings are consistent.

The data-scope="list-placeholder" and data-part attributes are correctly applied throughout the component, enabling fine-grained styling and testing hooks. The class binding pattern slotFn({ class: clsx(theme?.slot, classes?.slot) }) is consistently applied.

src/lib/skeleton/TestimonialPlaceholder.svelte (1)

14-59: Data attributes and semantic slot names are well-structured.

The data-scope="testimonial-placeholder" and data-part attributes are consistently applied. The renamed slots (primaryLine, secondaryLine, avatarIcon, authorInfo) follow the semantic naming convention. The SVG element correctly includes aria-hidden="true" for accessibility.

src/lib/skeleton/TextPlaceholder.svelte (2)

9-15: LGTM! Theme reactivity correctly implemented.

The getTheme() and textPlaceholder() calls are both properly wrapped in $derived(), ensuring the component reacts to dynamic theme changes. The renamed slots (lineGroup, primaryLine, secondaryLine) align with the semantic naming convention.


18-78: Data attributes and class bindings are consistent throughout.

The data-scope="text-placeholder" and data-part attributes are correctly applied to all elements. The repetitive line-group structure appropriately represents the skeleton text placeholder visual pattern. Class bindings consistently follow the slotFn({ class: clsx(...) }) pattern.

src/lib/skeleton/CardPlaceholder.svelte (2)

9-11: LGTM! Theme reactivity correctly implemented.

The getTheme() and cardPlaceholder() calls are both properly wrapped in $derived(). The renamed slots (imagePlaceholder, imageIcon, skeletonLine, footer) align with the semantic naming convention being applied across skeleton components.


14-34: Data attributes and class bindings are well-structured.

The data-scope="card-placeholder" and data-part attributes are correctly applied to the main structural elements. The SVG includes proper aria-hidden="true" for accessibility.

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

48-59: LGTM!

The addition of data-scope="pagination-button" attributes provides consistent scoping for styling and testing without altering functionality. The theme reactivity pattern using $derived (line 10) correctly follows the established Flowbite-Svelte convention.

src/lib/pagination/Pagination.svelte (2)

9-9: LGTM!

Renaming class to className improves code clarity and aligns with common React/JSX conventions.


32-33: LGTM!

The addition of data-scope="pagination" and data-part="base" attributes establishes a consistent scoping pattern for styling and testing hooks.

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

16-16: LGTM!

The addition of the visiblePages prop (default 5) provides a useful configuration option for controlling the number of visible page numbers in pagination navigation.


67-108: LGTM!

The refactoring to use slot-based theming from paginationNav and the addition of data-part attributes for scoping are well-implemented. The data-part attributes on PaginationButton components (lines 82, 100) will correctly propagate to the underlying DOM elements via restProps. Theme reactivity using $derived (line 32) follows the established pattern.

src/routes/docs-examples/extend/progressradial/Animation.svelte (1)

7-7: LGTM! Slot name updated correctly.

The outside slot has been renamed to labelWrapper for better semantic clarity. This aligns with the broader refactoring effort across the progress components.

src/routes/docs-examples/extend/progressradial/Colors.svelte (1)

5-24: LGTM! Consistent slot name updates across all color variants.

All instances have been updated from outside to labelWrapper in the classes prop. The first example (line 5) now omits the color prop to demonstrate the default appearance, while all other examples retain their specific color values. The refactoring is consistent and maintains the same visual output.

src/lib/progress/Progressradial.svelte (2)

36-41: LGTM! Slot names refactored for better semantic clarity.

The destructured slot names have been updated:

  • outsidelabelWrapper
  • spanlabelText
  • progressClspercentage

These names are more descriptive and align with their actual usage in the component.


57-91: Excellent addition of data-scope and data-part attributes.

The component now includes proper semantic attributes for all major elements:

  • data-scope="progressradial" on the root container
  • data-part attributes on: label-wrapper, label-text, percentage, base, background, foreground, and label

These attributes enable better CSS targeting, easier testing, and improved debugging. The structure is well-organized and consistent.

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

12-15: LGTM! Progressbar slots renamed for better semantics.

The slot names have been improved:

  • insidebar (more specific to the progress bar element)
  • outsidelabelWrapper (clearer wrapper purpose)
  • spanlabelText (descriptive element name)
  • progressClspercentage (explicit about content)

21-97: All color variants updated consistently.

All 18 color variants have been properly updated with the new bar slot name. The refactoring is thorough and maintains the same color mappings for each variant.


130-132: LGTM! Progressradial slots renamed consistently.

The slot naming aligns with progressbar updates:

  • outsidelabelWrapper
  • spanlabelText
  • progressClspercentage

This creates a consistent API across both progress components.

src/lib/progress/Progressbar.svelte (2)

35-44: LGTM! Destructuring updated with new slot names.

The slot names have been updated to match the theme changes:

  • insidebar
  • outsidelabelWrapper
  • spanlabelText
  • progressClspercentage

The naming is now consistent with Progressradial and more semantically clear.


52-65: Excellent implementation of data-scope and data-part attributes.

The component structure is now properly annotated:

  • data-scope="progressbar" identifies the component
  • data-part attributes on: label-wrapper, label-text, percentage, base, label, and bar

This creates a clear, targetable structure for styling and testing. The implementation is consistent with the Progressradial component.

src/lib/rating/Rating.svelte (1)

14-26: LGTM! Theme integration is consistent.

The slot name change from p to value and the addition of data-scope/data-part attributes align perfectly with the theme refactoring. The semantic naming makes the code more maintainable.

src/lib/rating/ScoreRating.svelte (1)

12-59: LGTM! Clean theme integration.

The semantic slot names (badge, title, separator, subtitle, reviewLink) are much clearer than the previous generic names. The data-scope and data-part attributes provide excellent CSS targeting capabilities while maintaining backward compatibility with the props structure.

src/lib/rating/AdvancedRating.svelte (1)

13-28: LGTM! Good defensive coding practice.

The semantic slot names improve readability significantly. Nice work avoiding the naming collision on Line 22 by renaming loop variables to ratingLabel and ratingValue instead of shadowing the label function from the destructured theme slots.

src/lib/rating/Review.svelte (1)

13-55: LGTM! Comprehensive and consistent refactoring.

The semantic slot names (userInfo, userDetails, addressWrapper, avatar, metadata, metadataItem) greatly improve code clarity compared to the previous generic names (div, div2, div3, img, ul, li). The data-scope and data-part attributes provide excellent styling hooks while preserving all conditional rendering logic.

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

10-48: Excellent semantic naming improvements!

The refactoring from generic slot names to semantic names (value, label, barTrack, barFill, percentage, userInfo, userDetails, addressWrapper, avatar, metadata, metadataItem, badge, title, separator, subtitle, reviewLink, bar) significantly improves developer experience and code maintainability.

Type definitions in src/lib/rating/theme.ts are properly defined and exported (lines 5-8), and all four variant types (RatingVariants, AdvancedRatingVariants, ReviewVariants, ScoreRatingVariants) correctly match the new semantic slot names. All components (AdvancedRating.svelte, Rating.svelte, Review.svelte, ScoreRating.svelte) are using the new semantic slot names as expected.

Note: The old names (desc1, desc2, desc3) found in types.ts are part of the headerLabel data props interface, not theme slot names—they pass user input to the component, while the theme slots handle styling.

src/routes/layouts/ComponentsLayout.svelte (3)

70-77: LGTM! Variable renames align with the new theme slot naming conventions.

The local style variables are correctly renamed to match the updated theme slot keys (labelClass, triggerClass, contentClass), providing clearer semantic meaning for their purposes.


90-90: LGTM! Sidebar classes prop updated consistently.

The classes prop correctly uses the new slot keys (content, nonactive, active) matching the updated theme API.


100-141: LGTM! SidebarDropdownWrapper and SidebarItem prop updates are consistent.

All instances correctly use the new class key names:

  • trigger and list for SidebarDropdownWrapper
  • label for SidebarItem

The changes are applied uniformly across all component usages in this file.

src/routes/docs-examples/components/drawer/Navigation.svelte (2)

5-5: LGTM! Variable rename aligns with theme slot naming.

Renaming spanClass to labelClass improves semantic clarity and matches the updated sidebar theme API.


30-38: LGTM! SidebarItem classes prop correctly updated.

Both Kanban and Inbox items now use { label: labelClass } instead of the previous { span: spanClass }, consistent with the theme slot rename.

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

8-11: LGTM! Type definitions updated for the renamed theme constants.

The NavbarUlVariants type correctly references the renamed navUl, and the new NavLiVariants type supports the restructured navLi constant with its slots-based design.


32-114: LGTM! navUl slot rename from ul to list is comprehensive.

The slot rename is consistently applied across:

  • Base slots definition
  • All breakpoint variants (sm, md, lg, xl)
  • Hidden variants
  • All compound variants

The semantic name list better describes the slot's purpose.


116-157: Downstream consumer NavLi.svelte is properly updated for the navLi slots structure change.

The navLi constant's restructuring from a single string to a slots object with base and item keys has been correctly implemented in NavLi.svelte. The component properly destructures the slots (const { base, item } = $derived(navLi())) and uses both slot functions with their respective variant parameters. No other components directly consume navLi, so the risk surface is limited to this single consumer which is already updated.

src/routes/docs-examples/components/sidebar/ObjectEx.svelte (2)

7-7: LGTM! Variable rename follows the new naming convention.


55-55: LGTM! SidebarItem classes prop correctly uses the label key.

src/routes/docs-examples/components/sidebar/BrandingUsingChildren.svelte (2)

7-7: LGTM! Variable rename is consistent with the theme API update.


40-48: LGTM! Both SidebarItem instances correctly use the new label class key.

src/routes/docs-examples/components/sidebar/Transition.svelte (3)

13-13: LGTM! Variable rename aligns with the theme slot naming update.


41-41: LGTM! SidebarDropdownWrapper correctly uses the new trigger class key.

The rename from btn to trigger provides better semantic clarity for the dropdown toggle element.


49-57: LGTM! SidebarItem instances correctly use the new label class key.

src/routes/docs-examples/components/sidebar/MultiLevel.svelte (3)

7-7: LGTM! Variable rename follows the established naming convention.


43-43: LGTM! SidebarDropdownWrapper uses the updated trigger class key.


51-59: LGTM! SidebarItem instances correctly use the label class key.

src/routes/docs-examples/components/sidebar/LinksAndActive2.svelte (1)

7-7: LGTM! API usage correctly updated.

The rename from spanClass to labelClass and the corresponding update to use classes={{ label: labelClass }} correctly aligns with the broader migration where SidebarItem's styling key changed from span to label.

Also applies to: 37-37, 45-45

src/routes/docs-examples/components/sidebar/AlwaysOpen.svelte (1)

7-7: LGTM! API usage correctly updated.

The changes correctly update the example to use the new label key instead of span for SidebarItem styling customization.

Also applies to: 35-35, 43-43

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

7-7: LGTM! Consistent with API migration.

The example correctly demonstrates the updated SidebarItem API using the label styling key.

Also applies to: 35-35, 43-43

src/routes/docs-examples/components/sidebar/LinksAndActive.svelte (1)

14-14: LGTM! API usage correctly migrated.

The changes properly update the example to reflect the new SidebarItem theming API where label replaces span as the styling key.

Also applies to: 37-37, 45-45

src/routes/docs-examples/components/sidebar/Cta.svelte (1)

7-7: LGTM! Example correctly updated.

The changes align with the API migration, updating SidebarItem to use the label styling key consistently with the other sidebar examples.

Also applies to: 35-35, 43-43

src/routes/docs-examples/components/sidebar/MultiLevel2.svelte (1)

41-41: LGTM: Public API key updated to match component refactoring.

The change from btn to trigger correctly reflects the updated SidebarDropdownWrapper API and provides more semantic naming for the clickable trigger element.

src/lib/sidebar/SidebarBrand.svelte (1)

13-19: LGTM: Semantic improvements with data attributes.

The refactoring provides several benefits:

  • More descriptive names (logo/brandName vs img/span)
  • Data attributes (data-scope/data-part) enable precise CSS targeting
  • All theme and styling bindings are consistently updated
src/routes/docs-examples/components/sidebar/AllOpen.svelte (1)

7-7: LGTM: Consistent API updates throughout the example.

All changes correctly reflect the updated component APIs:

  • Constant renamed to labelClass (more semantic)
  • SidebarDropdownWrapper: btntrigger (3 instances)
  • SidebarItem: spanlabel (1 instance)

The updates are applied consistently across all component usages in this example.

Also applies to: 36-36, 42-42, 48-48, 55-55

src/lib/sidebar/SidebarButton.svelte (1)

12-17: LGTM: Consistent refactoring with improved semantics.

The changes follow the same pattern as other sidebar components:

  • Renamed svgicon for more generic/semantic naming
  • Added data-scope/data-part attributes for precise styling
  • All theme and styling bindings properly updated
src/routes/docs-examples/extend/split-pane/+page.svelte (2)

32-32: LGTM: SidebarItem API correctly updated in split-pane example.

The changes properly update the SidebarItem usage to the new API:

  • Constant renamed to labelClass for semantic clarity
  • Both instances (Kanban and Inbox items) use classes={{ label: labelClass }}

The updates are isolated to sidebar-related code and don't impact the split-pane functionality.

Also applies to: 266-266, 274-274


266-274: No action needed — API migration is complete.

The breaking changes mentioned (SidebarDropdownWrapper: classes.btnclasses.trigger; SidebarItem: classes.spanclasses.label) have been fully implemented. The code under review correctly uses the new API with classes={{ label: labelClass }}, and codebase-wide verification confirms no remaining instances of the old API exist.

src/lib/sidebar/SidebarItem.svelte (2)

22-27: LGTM: Data attributes and class bindings updated consistently.

The addition of data-scope and data-part attributes provides semantic hooks for styling and testing. The class binding on line 27 correctly references theme?.label (updated from the old theme?.span).


19-19: LGTM: Slot key renamed from span to label with proper type updates.

The destructuring correctly aliases label to labelCls at line 19, and the theme definition confirms all slots have been updated (base, link, label). The SidebarItemProps types reflect this change through the Classes<typeof sidebarItem> inheritance, where sidebarItem now defines label instead of span.

Internal usage is consistent: line 27 correctly uses styling?.label. This is a breaking change for consumers using classes.span with SidebarItem, but the refactoring is complete and properly implemented.

src/lib/sidebar/Sidebar.svelte (2)

100-103: LGTM: Data attributes and class bindings updated consistently across both branches.

The data-scope="sidebar" and data-part attributes are added consistently across both the conditional (lines 113-118) and else (lines 124-135) branches. The backdrop elements (lines 100, 102) correctly include data-part="backdrop". All class bindings use the new content(...) token consistently.

Also applies to: 113-118, 124-135


59-59: Confirm slot key rename from div to content.

The destructuring on line 59 correctly uses content. The TypeScript type SidebarProps['classes'] has been automatically updated via the Classes<typeof sidebar> type, which derives keys from the sidebar's slots—now only supporting content instead of div. No remaining consumer code using the old classes.div pattern was found in the Sidebar context.

src/routes/docs-examples/components/sidebar/Separator.svelte (1)

7-7: LGTM: Example updated to use the new label class key.

The variable rename (spanClasslabelClass) and the updated classes prop bindings correctly reflect the new public API of SidebarItem.

Also applies to: 35-35, 43-43

src/lib/sidebar/SidebarCta.svelte (2)

16-18: LGTM: Data attributes and class bindings updated consistently.

The data-scope and data-part attributes provide clear semantic hooks. Class bindings correctly reference theme?.labelWrapper and theme?.badge.


13-13: LGTM: Slot keys renamed to more semantic names.

The destructuring updates from { base, div, span } to { base, labelWrapper, badge } use clearer, more descriptive names. The TypeScript type SidebarCtaProps['classes'] is correctly updated through the automatic derivation from the theme slots, and no remaining references to old keys were found.

src/routes/docs-examples/components/sidebar/Static.svelte (1)

7-7: LGTM: Example updated to use the new label class key.

The variable rename (spanClasslabelClass) and the updated classes prop bindings correctly reflect the new public API of SidebarItem.

Also applies to: 37-37, 45-45

src/routes/admin-dashboard/(sidebar)/Sidebar.svelte (2)

129-129: LGTM! Semantic key renaming improves API clarity.

The update from div to content for the Sidebar's main wrapper styling is consistent with the broader theme key renaming in this PR. This semantic naming makes the API more intuitive.


147-168: LGTM! Consistent application of label key for SidebarItem styling.

All SidebarItem instances correctly updated to use label instead of span for class mappings. The changes are applied consistently across nested items, top-level items, and the final group items.

src/routes/docs-examples/components/sidebar/Branding.svelte (3)

7-7: LGTM! Variable renamed to match new API.

Renaming spanClass to labelClass aligns with the updated label key in the SidebarItem API.


36-36: LGTM! Semantic key for SidebarBrand logo.

The update from img to logo improves API clarity for the SidebarBrand component.


42-50: LGTM! Consistent usage of label key.

Both SidebarItem instances correctly use the label key with the renamed labelClass variable.

src/routes/docs-examples/components/sidebar/CloseButton.svelte (2)

7-7: LGTM! Variable renamed to match new API.

Consistent with other files, spanClass renamed to labelClass to align with the updated SidebarItem API.


36-44: LGTM! Correct usage of label key.

Both SidebarItem instances properly use the label key with the renamed variable.

src/routes/docs-examples/components/sidebar/Single.svelte (2)

35-54: LGTM! Correct usage of trigger key.

All three SidebarDropdownWrapper instances correctly updated to use trigger instead of btn for class mappings, aligning with the new API.


47-47: LGTM! Correct usage of label key.

The SidebarItem correctly uses the label key (though see suggestion on Line 7 regarding variable naming consistency).

src/lib/sidebar/SidebarDropdownWrapper.svelte (4)

15-16: LGTM! Reactive theme integration follows best practices.

The use of $derived(getTheme("sidebarDropdownWrapper")) ensures the component reacts to dynamic theme changes, following the documented learning for ThemeProvider usage in Flowbite-Svelte.


16-16: LGTM! Semantic key renaming improves API clarity.

The destructuring updates from generic keys (btn, span, svg, ul) to semantic keys (trigger, label, icon, list) make the API more intuitive and self-documenting.


49-76: LGTM! data-scope and data-part attributes properly added.

The addition of data-scope="sidebar-dropdown-wrapper" and corresponding data-part attributes (base, trigger, label, icon, menu) provides excellent hooks for testing and custom styling. All class bindings correctly updated to use the new semantic keys.


16-72: All consumers updated to new API — Verified that all SidebarDropdownWrapper usages have been migrated. No instances of old class keys (btn, span, svg, ul) remain in any sidebar components. All examples in src/routes/docs-examples/components/sidebar/ and integration files consistently use the new semantic keys (trigger, label, icon, list).

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

56-86: All slot renames have been properly implemented in the sidebar components.

Verification confirms:

  • SidebarButton.svelte: Uses icon slot
  • SidebarBrand.svelte: Uses logo and brandName slots
  • SidebarCta.svelte: Uses labelWrapper and badge slots

No old slot names remain in the components.


88-117: Slot name renames verified and correctly implemented.

The components are fully updated with the new slot names:

  • sidebarDropdownWrapper: trigger, label, icon, list
  • sidebarItem: link, label

Both SidebarDropdownWrapper.svelte and SidebarItem.svelte correctly destructure and use the new slot names with no references to old names.


12-54: The sidebar slot rename from div to content is correctly implemented.

The theme configuration and all downstream components (Sidebar.svelte, SidebarButton.svelte, SidebarBrand.svelte, SidebarCta.svelte, SidebarDropdownWrapper.svelte, SidebarItem.svelte) have been consistently updated to use the new slot names. The semantic improvement enhances API clarity.

…ble, tabs, timeline, toast, toolbar directories
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (2)
src/lib/stepper/VerticalStepper.svelte (1)

80-88: Add missing data-part attribute for consistency.

Line 82's content <div> is missing the data-part="content" attribute that was added to line 74 in the clickable path. Both code paths should have consistent data attributes for uniform styling hooks and testing selectors.

🔎 Proposed fix
-        <div class={card({ status, class: clsx(theme?.card, classes?.card) })} aria-current={status === "current" ? "step" : undefined} data-part="card">
-          <div class={content({ class: clsx(theme?.content, classes?.content) })}>
+        <div class={card({ status, class: clsx(theme?.card, classes?.card) })} aria-current={status === "current" ? "step" : undefined} data-part="card">
+          <div class={content({ class: clsx(theme?.content, classes?.content) })} data-part="content">
             <span class="sr-only">{step.label}</span>
src/lib/skeleton/TestimonialPlaceholder.svelte (1)

1-62: Add testimonialPlaceholder entry to v2-migration-guide.md.

Migration documentation exists at v2-migration-guide.md, but it omits the testimonialPlaceholder breaking changes. Add an entry to the component migration table to document the slot name changes:

Component Current Slot Recommended Slot
TestimonialPlaceholder lineA primaryLine
TestimonialPlaceholder lineB secondaryLine
TestimonialPlaceholder svg avatarIcon
TestimonialPlaceholder content authorInfo
🧹 Nitpick comments (4)
design-system.md (2)

60-65: Clarify the naming convention for renamed props to avoid confusion.

The guidance to rename conflicting props is valuable, but using an underscore prefix (_title) is misleading—this convention typically signals an unused variable in JavaScript, when here the variable is actively used, just renamed to avoid collision with a component prop.

Consider either:

  1. Documenting why underscore is appropriate here (if it's a convention in this codebase)
  2. Using a more descriptive prefix that clarifies the source (e.g., themeTitlePart, variantTitle, or titlePart)
  3. Simplifying the example to focus on destructuring pattern without committing to a specific naming style

Additionally, the example wraps timelineItem() in $derived(), which conflates destructuring patterns with Svelte 5 reactivity concerns. If reactivity is relevant here, it should be explained; if not, simplify to plain destructuring.


56-134: Placement of naming-conflict guidance disrupts document flow.

The new guidance at lines 60–65 interrupts the transition from "Slot Naming" to the "5 most common data-part categories" section. Consider relocating it to:

  • A dedicated subsection within "Slot Naming" (e.g., "Handling naming conflicts"), or
  • At the end of "Anatomical Selectors" section where data-part semantics are introduced

This keeps related naming topics together and improves readability.

v2-migration-guide.md (1)

1-16: Add context and guidance for developers.

The migration guide lacks essential information to help developers successfully migrate:

  • Version scope: Which versions does this apply to? (v1 → v2, v2.x → v2.y?)
  • Timeline: When are these changes enforced? Are old names deprecated or removed?
  • Backwards compatibility: Do old slot names still work, or is this a breaking change?
  • Code examples: Show before/after usage patterns
  • Organization: Group by component category for easier navigation

Consider structuring the guide with an introduction section covering these points, followed by per-component migration sections.

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

66-81: Update component documentation to reflect prop changes.

The documentation comment still lists @prop ...restProps (line 80), but if restProps are no longer spread on any element, this documentation is misleading and should be updated or removed.

📜 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 fa73495 and f443cc3.

📒 Files selected for processing (44)
  • design-system.md
  • src/lib/dialog/Dialog.svelte
  • src/lib/drawer/Drawer.svelte
  • src/lib/extend/command-palette/CommandPalette.svelte
  • src/lib/forms/dropzone/Dropzone.svelte
  • src/lib/forms/dropzone/theme.ts
  • src/lib/modal/Modal.svelte
  • src/lib/pagination/Pagination.svelte
  • src/lib/pagination/theme.ts
  • src/lib/popover/Popover.svelte
  • src/lib/skeleton/CardPlaceholder.svelte
  • src/lib/skeleton/TestimonialPlaceholder.svelte
  • src/lib/spinner/Spinner.svelte
  • src/lib/stepper/BreadcrumbStepper.svelte
  • src/lib/stepper/DetailedStepper.svelte
  • src/lib/stepper/ProgressStepper.svelte
  • src/lib/stepper/Stepper.svelte
  • src/lib/stepper/TimelineStepper.svelte
  • src/lib/stepper/VerticalStepper.svelte
  • src/lib/table/Table.svelte
  • src/lib/table/TableSearch.svelte
  • src/lib/table/theme.ts
  • src/lib/tabs/TabItem.svelte
  • src/lib/tabs/Tabs.svelte
  • src/lib/timeline/Activity.svelte
  • src/lib/timeline/ActivityItem.svelte
  • src/lib/timeline/Group.svelte
  • src/lib/timeline/GroupItem.svelte
  • src/lib/timeline/Timeline.svelte
  • src/lib/timeline/TimelineItem.svelte
  • src/lib/timeline/theme.ts
  • src/lib/toast/Toast.svelte
  • src/lib/toast/ToastContainer.svelte
  • src/lib/toolbar/Toolbar.svelte
  • src/lib/toolbar/ToolbarButton.svelte
  • src/lib/toolbar/ToolbarGroup.svelte
  • src/lib/tooltip/Tooltip.svelte
  • src/lib/types.ts
  • src/lib/utils/Arrow.svelte
  • src/lib/utils/Popper.svelte
  • src/routes/docs-examples/components/sidebar/Single.svelte
  • src/routes/docs/forms/file-input.md
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • v2-migration-guide.md
✅ Files skipped from review due to trivial changes (1)
  • src/lib/stepper/DetailedStepper.svelte
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/lib/skeleton/CardPlaceholder.svelte
  • src/lib/popover/Popover.svelte
  • src/routes/docs-examples/components/sidebar/Single.svelte
  • src/lib/drawer/Drawer.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/tabs/TabItem.svelte
  • src/lib/tooltip/Tooltip.svelte
  • src/lib/stepper/ProgressStepper.svelte
  • src/lib/utils/Popper.svelte
  • src/lib/stepper/Stepper.svelte
  • src/lib/stepper/BreadcrumbStepper.svelte
  • src/lib/toast/ToastContainer.svelte
  • src/lib/timeline/Group.svelte
  • src/lib/toolbar/ToolbarGroup.svelte
  • src/lib/dialog/Dialog.svelte
  • src/lib/modal/Modal.svelte
  • src/lib/stepper/VerticalStepper.svelte
  • src/lib/spinner/Spinner.svelte
  • src/lib/toolbar/ToolbarButton.svelte
  • src/lib/stepper/TimelineStepper.svelte
  • src/lib/skeleton/TestimonialPlaceholder.svelte
  • src/lib/table/TableSearch.svelte
  • src/lib/table/theme.ts
  • src/lib/timeline/Timeline.svelte
  • src/lib/toast/Toast.svelte
  • src/lib/extend/command-palette/CommandPalette.svelte
  • src/lib/toolbar/Toolbar.svelte
  • src/lib/utils/Arrow.svelte
  • src/lib/timeline/GroupItem.svelte
  • src/lib/timeline/ActivityItem.svelte
  • src/lib/table/Table.svelte
  • src/lib/tabs/Tabs.svelte
  • src/lib/timeline/Activity.svelte
  • src/lib/pagination/theme.ts
  • src/lib/pagination/Pagination.svelte
  • src/lib/timeline/theme.ts
  • src/lib/forms/dropzone/Dropzone.svelte
  • src/lib/forms/dropzone/theme.ts
  • src/lib/types.ts
  • src/lib/timeline/TimelineItem.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:28.743Z
Learning: In flowbite-svelte, when using ThemeProvider with reactive themes, `getTheme("componentName")` calls must be placed inside `$derived()` expressions (not at module scope) to ensure components react to dynamic theme changes. This pattern is intentional for reactive theming support.
Learnt from: 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
📚 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/tabs/TabItem.svelte
  • src/lib/tooltip/Tooltip.svelte
  • src/lib/stepper/ProgressStepper.svelte
  • src/lib/utils/Popper.svelte
  • src/lib/stepper/Stepper.svelte
  • src/lib/stepper/BreadcrumbStepper.svelte
  • src/lib/toast/ToastContainer.svelte
  • src/lib/timeline/Group.svelte
  • src/lib/toolbar/ToolbarGroup.svelte
  • src/lib/dialog/Dialog.svelte
  • src/lib/modal/Modal.svelte
  • src/lib/stepper/VerticalStepper.svelte
  • src/lib/spinner/Spinner.svelte
  • src/lib/toolbar/ToolbarButton.svelte
  • src/lib/stepper/TimelineStepper.svelte
  • src/lib/skeleton/TestimonialPlaceholder.svelte
  • src/lib/table/TableSearch.svelte
  • src/lib/timeline/Timeline.svelte
  • src/lib/toast/Toast.svelte
  • src/lib/extend/command-palette/CommandPalette.svelte
  • src/lib/toolbar/Toolbar.svelte
  • src/lib/utils/Arrow.svelte
  • src/lib/timeline/GroupItem.svelte
  • src/lib/timeline/ActivityItem.svelte
  • src/lib/table/Table.svelte
  • src/lib/tabs/Tabs.svelte
  • src/lib/timeline/Activity.svelte
  • src/lib/pagination/Pagination.svelte
  • src/lib/forms/dropzone/Dropzone.svelte
  • src/lib/timeline/TimelineItem.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.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/tooltip/Tooltip.svelte
  • src/lib/utils/Popper.svelte
  • src/lib/utils/Arrow.svelte
📚 Learning: 2025-08-31T12:56:05.074Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1745
File: src/lib/types.ts:677-686
Timestamp: 2025-08-31T12:56:05.074Z
Learning: HTMLInputAttributes includes a `group` property that can be used for grouping form controls like checkboxes and radio buttons, so interfaces extending HTMLInputAttributes don't need to explicitly declare `group` unless they want to override its type.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/routes/docs/forms/file-input.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} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components

Applied to files:

  • src/routes/docs/forms/file-input.md
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
📚 Learning: 2025-12-28T05:16:44.735Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-12-28T05:16:44.735Z
Learning: In flowbite-svelte with Svelte 5, props are not reactive by default. To make prop values reactive (so they update when the prop changes), they must be wrapped with `$derived()`. For example, `const styling = $derived(classes)` is necessary—not redundant—to ensure `styling` reacts to changes in the `classes` prop.

Applied to files:

  • design-system.md
  • src/lib/forms/dropzone/Dropzone.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.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/table/theme.ts
  • src/lib/timeline/theme.ts
📚 Learning: 2025-08-31T14:31:57.582Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1745
File: src/lib/forms/checkbox/CheckboxButton.svelte:16-17
Timestamp: 2025-08-31T14:31:57.582Z
Learning: In Svelte 5, the `on:event` syntax for event forwarding is obsolete. Event handlers are passed as callback props (e.g., `onchange`, `oninput`) through `{...restProps}` instead of using `on:change`, `on:input` etc.

Applied to files:

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

Applied to files:

  • src/lib/types.ts
🧬 Code graph analysis (3)
src/lib/timeline/theme.ts (1)
src/lib/timeline/index.ts (1)
  • groupItem (7-7)
src/lib/forms/dropzone/theme.ts (1)
src/lib/forms/dropzone/index.ts (1)
  • dropzone (1-1)
src/lib/types.ts (3)
src/lib/dropdown/theme.ts (1)
  • DropdownItemVariants (16-16)
src/lib/forms/dropzone/theme.ts (1)
  • DropzoneVariants (4-4)
src/lib/navbar/theme.ts (1)
  • NavLiVariants (11-11)
🔇 Additional comments (67)
design-system.md (1)

1-134: Verify whether naming-conflict guidance is duplicated elsewhere in the file.

The AI-generated summary notes that the naming-conflict guidance "appears in two places within the same document," but only one instance (lines 60–65) is visible in the provided code. Confirm whether the duplication occurs outside the provided range or represents an unintended copy-paste that should be consolidated.

src/lib/tooltip/Tooltip.svelte (1)

31-32: LGTM! Data attributes added correctly.

The addition of data-scope="tooltip" and data-part="content" attributes aligns with the PR objectives to standardize scoping and part identification across components. These are non-breaking, additive changes that improve testability and provide better styling hooks without affecting component behavior.

v2-migration-guide.md (1)

5-16: Verify comprehensive slot name documentation.

The table is well-formatted and reasons are clear, but confirm that:

  1. All slot name changes across the codebase are represented here
  2. No additional components (e.g., device-mockup, drawer, dropdown) have slot renames that should be documented
  3. The renamed keys align exactly with changes in component source files and theme definitions
src/lib/toast/ToastContainer.svelte (1)

21-21: LGTM! Data attributes added for semantic scoping.

The addition of data-scope="toast-container" and data-part="base" is a clean, additive change that provides semantic scoping for styling and testing without affecting the component's functionality or API.

src/lib/stepper/ProgressStepper.svelte (1)

79-79: LGTM! Clean instrumentation additions.

The data-scope and data-part attributes are well-named, consistently applied, and will improve testability without affecting component functionality. The semantic naming (base, line, progress-line, item, circle) clearly identifies each DOM part, and the consistent application of data-part="circle" to both clickable and non-clickable variants maintains uniformity.

Also applies to: 81-81, 84-84, 93-93, 101-101, 115-115

src/lib/tabs/TabItem.svelte (1)

47-47: LGTM! Data attributes added for component scoping.

The addition of data-scope="tab-item" and data-part attributes aligns with the PR's objective to introduce consistent scoping and part identification across components. The attributes are correctly placed on the root <li> (base) and nested <button> elements, with no impact on functionality or public API.

Also applies to: 59-59

src/lib/stepper/Stepper.svelte (3)

67-67: LGTM! Semantic data attributes added correctly.

The addition of data-scope="stepper" and data-part="base" to the root element provides clear scoping and improves testability without affecting component behavior.


76-76: LGTM! Step items properly annotated.

Adding data-part="item" to each step wrapper provides granular identification for testing and styling purposes.


88-88: LGTM! Content elements consistently annotated.

Both the clickable (<button>) and non-clickable (<span>) variants correctly receive data-part="content", maintaining semantic consistency across the conditional rendering branches.

Also applies to: 99-99

src/lib/toast/Toast.svelte (2)

61-61: LGTM! Data attributes added for component scoping.

The data-scope="toast" and data-part="base" attributes provide clear identification for this root element, consistent with the broader refactoring across the codebase to enable better CSS targeting and testing selectors.


63-68: LGTM! Consistent part identification for sub-elements.

The data-part attributes on the icon and content wrappers complete the component's part identification strategy, enabling granular CSS targeting for theming and testing purposes.

src/lib/stepper/TimelineStepper.svelte (3)

61-61: LGTM! Root element properly scoped.

The addition of data-scope="timeline-stepper" and data-part="base" to the root <ol> element follows the component scoping pattern established in this PR, enabling better styling hooks and test selectors without affecting behavior.


64-64: LGTM! List items properly identified.

Adding data-part="item" to each <li> element provides a clear selector for styling individual step items without changing component logic.


74-74: LGTM! Circle indicators properly identified across both variants.

Both clickable (button) and non-clickable (span) circle indicators correctly receive data-part="circle", enabling consistent styling for the step indicator regardless of the clickable state. The semantic equivalence is appropriate since they represent the same UI element in different interaction modes.

Also applies to: 79-79

src/lib/stepper/VerticalStepper.svelte (2)

62-62: LGTM! Root element data attributes are correct.

The data-scope="vertical-stepper" and data-part="base" attributes appropriately identify the component scope and root element for styling and testing purposes.


66-79: LGTM! Clickable path data attributes are correctly structured.

The data-part="card" on the button and data-part="content" on the inner div provide appropriate hooks for styling and testing the clickable stepper variant.

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

19-19: LGTM! Metadata attributes enhance component identification.

The addition of data-scope="toolbar-group" and data-part="base" attributes provides useful DOM metadata for testing, automation, and styling without affecting functionality or the public API.

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

42-43: LGTM! Consistent metadata pattern across base and content parts.

The data-scope="toolbar" and data-part attributes correctly identify the component scope and its structural parts (base and content), aligning with the theme structure and enabling better DOM targeting.

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

22-22: LGTM! Semantic part names distinguish button vs. link variants.

The data-scope="toolbar-button" consistently identifies the component across both rendering branches, while data-part="button" and data-part="link" appropriately distinguish the element type based on whether href is provided.

Also applies to: 27-27

src/lib/stepper/BreadcrumbStepper.svelte (3)

50-50: LGTM! Data attributes added correctly to the base element.

The data-scope="breadcrumb-stepper" and data-part="base" attributes are correctly added to the root <ol> element, aligning with the theme structure where base is destructured from breadcrumbStepper() at line 19.


59-59: LGTM! Item data attribute correctly applied.

The data-part="item" attribute correctly identifies each step list item and aligns with the item theme key destructured at line 19.


68-68: LGTM! Indicator data attributes consistently applied across both branches.

The data-part="indicator" attribute is correctly added to both the clickable (line 68) and non-clickable (line 90) indicator spans, ensuring consistency regardless of the clickable prop. This aligns with the indicator theme key destructured at line 19.

Also applies to: 90-90

src/lib/dialog/Dialog.svelte (1)

190-190: LGTM! Consistent data-part attribute addition.

The data-part="form" attribute appropriately identifies the form element within the dialog scope, aligning with the PR's objective to add structured metadata for better DOM targeting.

src/lib/extend/command-palette/CommandPalette.svelte (1)

119-129: LGTM! Appropriate data-scope attribute addition.

Adding data-scope="dialog" to the Dialog component provides proper scoping metadata consistent with the PR's objectives and mirrors the pattern used in Modal.svelte.

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

56-58: Excellent explanatory comment!

The comment clearly documents the architectural decision to inherit the dialog scope rather than create a new modal scope, which aids future maintainers in understanding the composition pattern.


62-63: LGTM! Comprehensive data-part attribute tagging.

All Modal sections (base, header, title, close, body, footer) are properly tagged with data-part attributes under the inherited dialog scope. This provides structured metadata for styling and testing hooks while maintaining a clean component hierarchy.

Also applies to: 73-73, 75-75, 77-77, 84-84, 88-88

src/lib/tabs/Tabs.svelte (1)

78-85: LGTM! Data attributes enhance testability and scoping.

The addition of data-scope="tabs" and data-part attributes to the base, divider, and content elements follows the PR's systematic approach to improve component scoping without altering functionality.

src/lib/pagination/Pagination.svelte (2)

9-9: Verify removal of restProps spread is intentional.

The restProps are destructured but never spread in the template. Previously (based on common patterns), these would typically be spread on the <nav> element to allow users to pass additional HTML attributes like id, data-*, or custom aria-* attributes.

If this removal is intentional, please confirm. Otherwise, consider restoring:

🔎 Proposed fix to restore restProps spreading
-<nav data-scope="pagination" aria-label={ariaLabel}>
+<nav {...restProps} data-scope="pagination" aria-label={ariaLabel}>

32-33: LGTM! Data attributes added for better scoping.

The addition of data-scope="pagination" and data-part="base" aligns with the PR's systematic approach to enhance component testability and styling hooks.

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

9-87: LGTM! Theme structure is now consistent and correct.

The refactored pagination theming with separate pagination and paginationNav exports provides better separation of concerns. The defaultVariants now correctly reference only variants that exist in their respective variants definitions, resolving the previously flagged issue.

src/routes/docs/forms/file-input.md (1)

13-18: LGTM! Migration guide aids user transition.

The addition of the Migration Guide section with a clear mapping table from v1 to v2 slot names (closecloseIcon, svgcloseIcon) provides valuable documentation for users upgrading their code. This aligns well with the PR's systematic slot renaming across components.

Also applies to: 82-87

src/lib/table/Table.svelte (1)

16-40: LGTM! Slot rename and data attributes align with theme updates.

The renaming from div to wrapper provides more semantic clarity, and the addition of data-scope="table" and data-part attributes follows the PR's consistent pattern of enhancing component scoping. The changes correctly align with the corresponding theme.ts updates.

src/lib/table/TableSearch.svelte (3)

25-29: LGTM! Correct reactive theme usage.

The getTheme call is properly placed inside $derived() for reactive theme support, and the destructured slot names (iconContainer, icon) correctly match the renamed theme slots.


47-62: Excellent data attribute structure.

The addition of data-scope="table-search" and granular data-part attributes provides clear component scoping and part identification, which will improve testability and enable advanced styling capabilities.


29-29: Slot migration from svgDiv/svg to iconContainer/icon is complete.

Verification confirms no references to the old slot names remain across the codebase, including theme customizations, other Svelte components, and documentation.

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

11-45: Semantic slot naming improvement.

The renaming from div to wrapper better conveys the element's purpose. The shadow variant correctly references the updated slot name.


392-401: LGTM! More semantic slot naming.

The renaming from svgDiv/svg to iconContainer/icon improves clarity and makes the theme more maintainable. The slot structure remains functionally equivalent.


404-437: Consistent color variant updates.

All 8 color variants correctly updated to reference the renamed icon slot. The update is uniform and complete across all variants.

src/lib/skeleton/TestimonialPlaceholder.svelte (5)

9-11: LGTM! Reactive theming and semantic renaming.

The use of $derived(getTheme("testimonialPlaceholder")) correctly follows the reactive theming pattern for Flowbite-Svelte components. The semantic renaming from lineA/lineB/svg/content to primaryLine/secondaryLine/avatarIcon/authorInfo significantly improves code readability.

Based on learnings, the reactive theme pattern ensures components respond to dynamic theme changes.


14-58: Excellent addition of data attributes for component scoping.

The addition of data-scope="testimonial-placeholder" and data-part attributes follows a consistent pattern:

  • Root element has both scope and part identifiers
  • Child elements have semantic part identifiers matching their purpose
  • Multiple elements appropriately share the same part name (e.g., two secondary-line elements, two primary-line elements)

This enhances testability, debugging, and scoped styling capabilities.


33-46: LGTM! Explicit SVG structure improves clarity.

The SVG element is now explicitly defined with the avatarIcon styling function, replacing the previous binding shorthand. All necessary attributes are present, including aria-hidden="true" for proper accessibility.


17-57: No action needed—theme.ts is correctly updated.

The testimonialPlaceholder() function in src/lib/skeleton/theme.ts (lines 148-156) properly defines all required slots: primaryLine, secondaryLine, avatarIcon, and authorInfo. The component correctly references these properties throughout. No orphaned property names from the old implementation remain.


7-7: The TypeScript type definition is correctly updated. The TestimonialPlaceholderVariants type uses the Classes generic, which automatically generates a classes property with all slots from the testimonialPlaceholder theme (base, primaryLine, secondaryLine, avatarIcon, authorInfo). No old slot names are present in the type system.

src/lib/spinner/Spinner.svelte (1)

14-14: LGTM! Consistent data-scope attribute additions.

The data-scope="spinner" attribute is correctly added to all five spinner variants (default, dots, bars, pulse, orbit), providing consistent scoping hooks for testing and styling.

Also applies to: 25-25, 40-40, 55-55, 70-70

src/lib/utils/Arrow.svelte (1)

6-6: LGTM! Enables attribute forwarding.

The addition of restProps destructuring and forwarding allows consumers to pass arbitrary attributes (e.g., data-*, aria-*) to the arrow element, improving flexibility without breaking existing functionality.

Also applies to: 46-46

src/lib/utils/Popper.svelte (1)

274-274: LGTM! Well-structured data-part attributes.

The addition of data-part attributes (positioner, base, arrow) provides clear structural hooks for testing and styling without affecting functionality.

Also applies to: 280-280, 296-296

src/lib/timeline/Activity.svelte (1)

12-12: LGTM! Consistent data attributes for timeline activity.

The data-scope="activity" and data-part="base" attributes align with the broader PR pattern of adding structural identifiers across components.

src/lib/timeline/Timeline.svelte (1)

16-16: LGTM! Consistent data attributes for timeline.

The data-scope="timeline" and data-part="base" attributes follow the same pattern applied across the PR for improved component scoping and testability.

src/lib/timeline/Group.svelte (1)

13-21: LGTM! Semantic slot names improve clarity.

The refactor from generic names (div, ol) to semantic names (card, list) makes the component structure more intuitive. Data attributes for scope and parts enhance testability and CSS targeting.

src/lib/timeline/TimelineItem.svelte (2)

15-15: Good defensive coding with the _title alias.

Renaming the destructured title slot to _title prevents collision with the title prop (line 8), making the code more maintainable.


46-90: LGTM! Comprehensive data-part coverage.

Data attributes are consistently applied across all conditional branches (vertical, horizontal, activity, default layouts), improving component introspection and testability.

src/lib/timeline/ActivityItem.svelte (1)

13-34: LGTM! Clear semantic hierarchy.

The refactor establishes an intuitive structure: itemindicator (with img) + cardheader (with time and title) + optional text. Data-part attributes consistently map to the new slot names.

src/lib/timeline/GroupItem.svelte (1)

13-52: LGTM! Consistent data-part application.

The semantic slot names (link, content, badge, icon) clearly describe their purpose. Both conditional icon blocks (private/public) correctly include data-part="icon" for consistent targeting.

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

17-45: LGTM! Semantic slot names across all timeline components.

The slot renames create a consistent, semantic vocabulary:

  • activityItem: item, indicator, card, header (instead of li, span, outer, inner)
  • group: card, list (instead of div, ol)
  • groupItem: link, content, badge, icon (instead of a, div, span, svg)

This improves code readability and makes the component structure self-documenting.


111-287: Add Timeline component to v2-migration-guide.md.

A v2-migration-guide.md exists, but it does not document the Timeline component's breaking changes (slot name updates from div and svg to indicator and icon). Since the compoundVariants have been updated with these new slot names, users customizing Timeline via the classes prop will encounter breakage without guidance. Update the migration guide to include Timeline alongside the other documented components and their slot mapping.

src/lib/forms/dropzone/theme.ts (2)

1-4: LGTM! Type definitions follow established patterns.

The addition of VariantProps and Classes imports, along with the new DropzoneVariants export type, properly follows the same pattern used in other components like NavLiVariants and DropdownItemVariants as shown in the relevant code snippets.


6-12: Breaking API change: single base string → slots object.

The theme now uses a slots-based structure (base, content, input) instead of a single base string. This is a breaking change where consumers using dropzone() will now receive an object with callable functions for each slot rather than a single class string.

This aligns with the PR's refactoring objectives and is properly consumed in Dropzone.svelte (line 49: const { base, content, input } = $derived(dropzone());).

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

62-62: LGTM! Prop rename aligns with NavUl API update.

The change from classes={{ ul: ... }} to classes={{ list: ... }} correctly reflects the updated NavUl component API where the internal element key was renamed from ul to list, as mentioned in the AI summary for this file.

src/lib/forms/dropzone/Dropzone.svelte (3)

10-14: LGTM! Reactive declarations follow Svelte 5 patterns.

The addition of the classes prop and the use of $derived() for both styling (line 12) and theme (line 13) correctly ensures reactivity in Svelte 5. Based on learnings, props are not reactive by default in Svelte 5, so wrapping them with $derived() is necessary—not redundant—to ensure components react to prop changes.


49-49: LGTM! Slot destructuring properly integrates with theme.

The destructuring of { base, content, input } from dropzone() correctly integrates with the new slots-based theme structure defined in theme.ts (lines 7-11) and uses $derived() for reactivity.


52-58: LGTM! Template correctly implements data-part attributes and slot-based theming.

The template restructuring introduces:

  • data-part attributes on each element (base, content, input) for granular theming hooks
  • Proper integration of slot-based styling with class merging using clsx
  • Maintains all existing functionality (drag handlers, change handler, file binding)

This correctly implements the PR's objectives for data-part attributes and slot-based theming while preserving component behavior.

src/lib/types.ts (6)

43-43: LGTM! Variant imports enable proper type composition.

The addition of DropdownItemVariants (line 43), NavLiVariants (line 50), and DropzoneVariants (line 80) imports correctly supports the type composition pattern used later in the file where Props interfaces extend their respective Variants types.

Also applies to: 50-50, 80-80


218-225: LGTM! Enhanced AccordionProps.classes for granular theming.

The expansion of AccordionProps.classes to include button, contentWrapper, and content fields provides more granular theming control for AccordionItem. The comment clarifies this is for AccordionItem usage, and all fields remain optional (non-breaking).


668-677: LGTM! Props interfaces properly extend Variants types.

  • DropdownItemProps (lines 668-677): Now extends DropdownItemVariants, simplifying the interface by removing the nested classes structure (likely now handled internally by variants)
  • DropzoneProps (line 753): Extends DropzoneVariants to properly inherit the new slots-based classes structure

Both changes align with the variant system migration pattern across the component library.

Also applies to: 753-753


1118-1122: LGTM! NavLiProps properly composes with NavLiVariants.

The updated NavLiProps type correctly composes AnchorButtonAttributes with NavLiVariants while preserving activeClass and nonActiveClass for custom styling. This aligns with the broader variant system migration and matches the usage in FlowbiteSvelteLayout.svelte.


1980-1980: LGTM! Type improvements for better class composition.

  • PopperProps.arrowClass (line 1980): Changed from string to ClassValue, enabling more flexible class composition (arrays, objects, etc.)
  • ArrowProps (lines 1996-2000): Now extends HTMLAttributes<HTMLDivElement>, which includes the class field and provides better type safety

Both changes improve the API by supporting more flexible class composition patterns, though they're technically breaking if consumers relied on string-only behavior.

Also applies to: 1996-2000


1058-1058: MegaMenuProps field rename extraaddon is properly implemented.

All consuming code has been consistently updated. The MegaMenu component correctly destructures and uses the addon prop (line 8 of MegaMenu.svelte), applies it in theme configuration (line 12), and conditionally renders it (line 26). No remaining usages of the old extra field name were found.

…ropzone, fileupload, floating-label, helper, and input-field directories
Copy link
Copy Markdown
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/lib/forms/phoneinput/theme.ts (1)

8-9: LGTM! Semantic slot naming improves clarity.

The slot renames from generic HTML element names (div, svg, span) to semantic component-part names (iconWrapper, icon, floatingIconWrapper) make the theme structure more self-documenting and maintainable.

This is a breaking change for consumers customizing the phoneInput theme. The type definitions correctly reflect the renamed slots through the Classes<typeof phoneInput> utility type in PhoneInputVariants, so TypeScript will catch incompatible customizations at compile time. All old slot references have been removed from the codebase.

📜 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 0fa9a13 and 12166ea.

📒 Files selected for processing (13)
  • src/lib/forms/label/Label.svelte
  • src/lib/forms/phoneinput/PhoneInput.svelte
  • src/lib/forms/phoneinput/theme.ts
  • src/lib/forms/radio/Radio.svelte
  • src/lib/forms/search/Search.svelte
  • src/lib/forms/search/theme.ts
  • src/lib/forms/select/MultiSelect.svelte
  • src/lib/forms/select/Select.svelte
  • src/lib/forms/textarea/Textarea.svelte
  • src/lib/forms/textarea/theme.ts
  • src/lib/forms/timepicker/Timepicker.svelte
  • src/lib/forms/toggle/Toggle.svelte
  • src/lib/forms/toggle/theme.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/forms/toggle/Toggle.svelte
  • src/lib/forms/select/Select.svelte
  • src/lib/forms/label/Label.svelte
  • src/lib/forms/select/MultiSelect.svelte
  • src/lib/forms/search/Search.svelte
  • src/lib/forms/radio/Radio.svelte
  • src/lib/forms/toggle/theme.ts
  • src/lib/forms/phoneinput/PhoneInput.svelte
  • src/lib/forms/phoneinput/theme.ts
  • src/lib/forms/textarea/Textarea.svelte
  • src/lib/forms/search/theme.ts
  • src/lib/forms/textarea/theme.ts
  • src/lib/forms/timepicker/Timepicker.svelte
🧠 Learnings (7)
📚 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/forms/toggle/Toggle.svelte
  • src/lib/forms/select/Select.svelte
  • src/lib/forms/label/Label.svelte
  • src/lib/forms/select/MultiSelect.svelte
  • src/lib/forms/search/Search.svelte
  • src/lib/forms/radio/Radio.svelte
  • src/lib/forms/phoneinput/PhoneInput.svelte
  • src/lib/forms/textarea/Textarea.svelte
  • src/lib/forms/timepicker/Timepicker.svelte
📚 Learning: 2024-11-22T08:37:27.996Z
Learnt from: mrh1997
Repo: themesberg/flowbite-svelte PR: 1442
File: src/lib/utils/Popper.svelte:144-145
Timestamp: 2024-11-22T08:37:27.996Z
Learning: In `src/lib/utils/Popper.svelte`, inconsistencies in event handling (e.g., using both `mouseenter`/`mouseleave` and `pointerenter`/`pointerleave`) may be intentional to minimize modifications and reduce the risk of new problems.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/lib/forms/phoneinput/theme.ts
📚 Learning: 2024-10-15T22:41:47.429Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1464
File: src/routes/component-data/Datepicker.json:0-0
Timestamp: 2024-10-15T22:41:47.429Z
Learning: The component should be named 'Datepicker' (with lowercase 'p') throughout the codebase to maintain consistency.

Applied to files:

  • src/lib/forms/timepicker/Timepicker.svelte
🔇 Additional comments (25)
src/lib/forms/label/Label.svelte (2)

9-9: LGTM: Correct reactive theme usage.

The theme is properly derived using $derived(getTheme("label")), ensuring the component reacts to dynamic theme changes from ThemeProvider.


15-15: LGTM: Consistent data attribute implementation.

The addition of data-scope="label" and data-part="base" aligns with the PR's goal of standardizing DOM scoping hooks across components. The attributes are correctly placed only when the label element is rendered.

src/lib/forms/select/Select.svelte (2)

64-65: LGTM! Clean metadata additions for testing/tooling.

The data-scope and data-part attributes provide clear hooks for testing and component introspection without altering behavior. The naming is semantic and consistent.


81-81: LGTM! Consistent data-part attribute on CloseButton.

The data-part="close" attribute aligns with the pattern established for other elements in this component.

src/lib/forms/select/MultiSelect.svelte (4)

219-220: LGTM! Proper scoping for the multi-select component.

The data-scope and data-part attributes on the container provide the foundation for testing and identifying this component's parts.


231-233: LGTM! Clear semantic identification of placeholder and selection display.

The data-part attributes on both the placeholder and select spans enable precise targeting of these distinct UI elements.


248-251: LGTM! Consistent metadata on interactive elements.

Both the CloseButton and SVG chevron icon have appropriate data-part attributes for testing and tooling.


257-262: LGTM! Comprehensive dropdown part identification.

The data-part attributes on both the dropdown container and individual items provide complete coverage for testing dropdown interactions.

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

23-23: Correct theme derivation pattern.

The use of $derived(getTheme("radio")) correctly follows the best practice for reactive theme updates, ensuring the component reacts to dynamic theme changes via ThemeProvider.

Based on learnings, this is the proper pattern (as opposed to calling getTheme() at module scope).


28-29: LGTM: Data attributes added for testability.

The addition of data-scope="radio" and data-part attributes aligns with the PR objectives to improve component scoping, selection hooks, and testability across the codebase. The attributes are correctly formatted and don't affect component behavior or accessibility.

src/lib/forms/textarea/Textarea.svelte (2)

33-33: Destructuring correctly updated to match theme slot rename.

The destructuring properly reflects the theme slot rename from div to container, maintaining consistency with the updated theme definition.


56-84: Well-structured data-part attributes enhance component scoping.

The systematic addition of data-scope="textarea" and granular data-part attributes provides clear semantic structure for styling and testing. All data-part values correctly correspond to their theme slot names:

  • container, wrapper, header, inner, addon, base, footer, close

The distinction between data-part="wrapper" (outer structure) and data-part="base" (actual textarea element) is particularly well thought out.

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

8-8: No action needed. The textarea theme slot is already correctly named container and the Textarea component properly uses this slot. No remaining references to an old div slot exist in the codebase, and no external updates are required.

Likely an incorrect or invalid review comment.

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

22-22: Variant update correctly matches renamed slot.

The phoneType.floating variant correctly updates svgicon to match the top-level slot rename.

src/lib/forms/phoneinput/PhoneInput.svelte (3)

25-25: Destructuring correctly updated to match renamed theme slots.

The destructured slot names align perfectly with the renamed slots in theme.ts (iconWrapper, icon, floatingIconWrapper).


29-29: Data attributes added for improved component styling and testing.

The consistent addition of data-scope="phone-input" and data-part attributes enables:

  • More specific CSS selectors without coupling to utility classes
  • Easier automated testing with stable selectors
  • Better styling encapsulation

The data-part naming follows a consistent kebab-case convention that maps to the camelCase slot names (iconWrapper → icon-wrapper, floatingIconWrapper → floating-icon-wrapper).

Also applies to: 37-37, 39-39, 43-43, 46-46, 48-48, 52-53


39-39: No type updates needed—PhoneInputProps classes property is correctly typed.

The PhoneInputProps type extends PhoneInputVariants, which includes Classes<typeof phoneInput>. The Classes utility automatically generates a classes? property with all slot names from the theme (iconWrapper, icon, input, floatingIconWrapper, floatingInput, label), matching the template references. No old property names (div, svg, span) appear in the codebase.

src/lib/forms/search/Search.svelte (3)

27-27: LGTM! Destructuring correctly updated to match theme changes.

The destructuring has been properly updated to use the new semantic slot names (iconWrapper, rightContent) that match the theme.ts changes.


44-44: LGTM! Close icon styling correctly updated.

The closeButtonProps classes now correctly reference closeIcon instead of the old svg slot name, aligning with the theme refactoring.


51-51: LGTM! Data-part attributes properly synchronized.

The data-part attributes have been correctly updated:

  • data-part="icon-wrapper" matches the iconWrapper slot
  • data-part="right-content" matches the rightContent slot

The naming convention (kebab-case for data-part, camelCase for code) is consistent and appropriate.

Also applies to: 58-58

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

10-10: Slot name refactoring is complete and properly implemented.

The search theme slots have been successfully renamed to more semantic names:

  • lefticonWrapper
  • contentrightContent
  • svgcloseIcon

Verification confirms the Search.svelte component correctly uses the new slot names, and no code in the codebase references the old names. All examples use the modern classes prop pattern for styling customization.

src/lib/forms/toggle/Toggle.svelte (2)

14-14: LGTM! Slot destructuring updated correctly.

The destructuring now uses track instead of span, matching the theme slot rename. This is more semantically appropriate for a toggle component.


17-22: LGTM! Template updates are consistent and well-structured.

The additions are correct:

  • data-scope and data-part attributes improve testability and styling hooks
  • The track styling function correctly replaces span throughout
  • Class composition logic is preserved
src/lib/forms/timepicker/Timepicker.svelte (2)

355-355: LGTM! Toggle classes prop correctly updated.

The classes prop now uses track instead of span, matching the theme slot rename in theme.ts. This ensures the custom styling "me-0 rounded-base" is applied to the correct element.


188-188: LGTM! Data attributes improve component introspection.

The data-scope and data-part attributes are consistently applied throughout the component. These provide useful hooks for testing and targeted styling without affecting functionality.

Also applies to: 203-203, 207-207, 243-243, 255-255, 269-269, 273-273, 279-279, 311-314, 353-354, 358-359, 397-397

export const toggle = tv({
slots: {
span: "me-3 shrink-0 bg-gray-200 rounded-full peer-focus:ring-4 peer-checked:after:translate-x-full peer-checked:rtl:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:bg-white after:border-gray-300 after:border after:rounded-full after:transition-all dark:bg-gray-600 dark:border-gray-500 relative ",
track: "me-3 shrink-0 bg-gray-200 rounded-full peer-focus:ring-4 peer-checked:after:translate-x-full peer-checked:rtl:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:bg-white after:border-gray-300 after:border after:rounded-full after:transition-all dark:bg-gray-600 dark:border-gray-500 relative ",
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Jan 1, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the toggle theme file structure
fd -t f toggle -x ls -la {} \;

Repository: themesberg/flowbite-svelte

Length of output: 2104


🏁 Script executed:

# Check the specific file mentioned in the review
cat -n src/lib/forms/toggle/theme.ts | head -100

Repository: themesberg/flowbite-svelte

Length of output: 4812


🏁 Script executed:

# Search for any remaining usages of 'span' in toggle theme customizations
rg -n -C3 --type=ts --type=svelte 'toggle.*span|span.*toggle' -g '!**/theme.ts' | head -50

Repository: themesberg/flowbite-svelte

Length of output: 100


🏁 Script executed:

# Also search for theme customizations that might reference the span slot
rg -n 'span\s*[:\|]' src/lib/forms/toggle/ --type=ts --type=svelte

Repository: themesberg/flowbite-svelte

Length of output: 100


🏁 Script executed:

# Search broader for any toggle theme references in the codebase
rg -n 'toggle.*theme|theme.*toggle' --type=ts --type=svelte --type=html -g '!**/node_modules' | grep -i span

Repository: themesberg/flowbite-svelte

Length of output: 100


🏁 Script executed:

# Search for 'span' in toggle-related files without type restrictions
rg -n 'span' src/lib/forms/toggle/ --no-heading

Repository: themesberg/flowbite-svelte

Length of output: 202


🏁 Script executed:

# Check the Toggle.svelte component to see how it uses the theme
cat -n src/lib/forms/toggle/Toggle.svelte

Repository: themesberg/flowbite-svelte

Length of output: 1825


🏁 Script executed:

# Search for any references to toggle theme with 'span' in the entire codebase
rg -n "toggle.*span|span.*toggle" --ignore-case | head -30

Repository: themesberg/flowbite-svelte

Length of output: 1428


🏁 Script executed:

# Search for theme customizations in documentation and examples
find . -type f \( -name "*.md" -o -name "*.svelte" \) -path "*toggle*" -exec grep -l "span" {} \;

Repository: themesberg/flowbite-svelte

Length of output: 243


🏁 Script executed:

# Check for any 'classes' or 'theme' object assignments that might use the old 'span' key
rg -n '"span"\s*:|span\s*:' src/lib/forms/toggle/ src/routes/ -A 2 -B 2

Repository: themesberg/flowbite-svelte

Length of output: 39861


🏁 Script executed:

# Let's examine the specific files that still use the old 'span' key
cat -n src/routes/docs-examples/forms/toggle/Sizes.svelte

Repository: themesberg/flowbite-svelte

Length of output: 518


🏁 Script executed:

# Check the markdown documentation file
cat -n src/routes/llm/forms/toggle.md | sed -n '50,60p'

Repository: themesberg/flowbite-svelte

Length of output: 426


🏁 Script executed:

# Verify there are no other toggle component files using the old span key
rg -n 'Toggle.*classes|classes.*Toggle' src/lib/forms/toggle/ src/routes/docs-examples/forms/toggle/ src/routes/docs/forms/toggle.md --no-heading

Repository: themesberg/flowbite-svelte

Length of output: 410


Breaking change not fully migrated to documentation and examples.

The theme file correctly uses the track slot key, and the Toggle component correctly references it. However, the public examples and documentation still reference the old span key:

  • src/routes/docs-examples/forms/toggle/Sizes.svelte line 9
  • src/routes/llm/forms/toggle.md line 55

Both files contain classes={{ span: customSize }} which should be updated to classes={{ track: customSize }}. Users following the official examples will encounter broken code unless these are corrected.

🤖 Prompt for AI Agents
In src/routes/docs-examples/forms/toggle/Sizes.svelte line ~9 and
src/routes/llm/forms/toggle.md line ~55, the examples still use the old classes
key "span" which no longer exists; update both occurrences from classes={{ span:
customSize }} to classes={{ track: customSize }} so they match the theme's
"track" slot and the Toggle component API; ensure there are no other references
to "span" in these docs/examples.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

fixed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the Sizes.svelte example now uses 'track' instead of 'span'
echo "=== Checking Sizes.svelte ==="
cat src/routes/docs-examples/forms/toggle/Sizes.svelte

echo -e "\n=== Checking toggle.md documentation ==="
cat src/routes/llm/forms/toggle.md | grep -A 2 -B 2 "customSize" || echo "Pattern not found or file doesn't exist"

echo -e "\n=== Searching for any remaining 'span' references in toggle examples/docs ==="
rg -n "classes.*span|span.*:" src/routes/docs-examples/forms/toggle/ src/routes/llm/forms/toggle.md 2>/dev/null || echo "No matches found"

Length of output: 1001


@shinokada Thank you for fixing src/routes/docs-examples/forms/toggle/Sizes.svelte! ✓

However, there's still one file that needs updating:

src/routes/llm/forms/toggle.md (line 55) still has:

<Toggle size={undefined} classes={{ span: customSize }}>Custom toggle</Toggle>

This should be updated to:

<Toggle size={undefined} classes={{ track: customSize }}>Custom toggle</Toggle>

Could you please update this file as well? Once both files are fixed, the migration will be complete.


🧬 Code Graph Analysis Results

[src/lib/forms/toggle/index.ts] (lines 2-2)

toggle

…te, descriptionlist, heading, hr, img directories
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (1)
src/lib/typography/a/A.svelte (1)

24-27: Critical: buttonProps spreads a function instead of filtered props.

Lines 24-27 define buttonProps as a derived function: $derived(() => {...}). This makes buttonProps equal the function itself, not its return value. On line 32, {...buttonProps} spreads the function object, not the filtered props.

When asButton is true, anchor-specific props (href, target, rel, download) will not be filtered out correctly, breaking the button rendering path.

🔎 Proposed fix
-let buttonProps = $derived(() => {
-  const { href, target, rel, download, ...filtered } = restProps;
-  return filtered;
-});
+let buttonProps = $derived((() => {
+  const { href, target, rel, download, ...filtered } = restProps;
+  return filtered;
+})());

This immediately invokes the function so buttonProps becomes the filtered object rather than a function.

Also applies to: 32-32

📜 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 12166ea and 579d40d.

📒 Files selected for processing (7)
  • src/lib/typography/a/A.svelte
  • src/lib/typography/blockquote/Blockquote.svelte
  • src/lib/typography/descriptionlist/DescriptionList.svelte
  • src/lib/typography/heading/Heading.svelte
  • src/lib/typography/hr/Hr.svelte
  • src/lib/typography/hr/theme.ts
  • src/lib/typography/img/Img.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/typography/blockquote/Blockquote.svelte
  • src/lib/typography/descriptionlist/DescriptionList.svelte
  • src/lib/typography/a/A.svelte
  • src/lib/typography/heading/Heading.svelte
  • src/lib/typography/hr/theme.ts
  • src/lib/typography/img/Img.svelte
  • src/lib/typography/hr/Hr.svelte
🧠 Learnings (3)
📚 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/typography/blockquote/Blockquote.svelte
  • src/lib/typography/descriptionlist/DescriptionList.svelte
  • src/lib/typography/a/A.svelte
  • src/lib/typography/heading/Heading.svelte
  • src/lib/typography/img/Img.svelte
  • src/lib/typography/hr/Hr.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/typography/a/A.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/typography/a/A.svelte
🔇 Additional comments (11)
src/lib/typography/blockquote/Blockquote.svelte (1)

23-23: LGTM! Clean addition of data-scope attribute.

The addition of data-scope="blockquote" is straightforward and aligns with the PR's objective to add consistent data-scope attributes across components.

Also worth noting: The theme handling on line 9 correctly uses $derived(getTheme("blockquote")) to ensure reactivity with dynamic theme changes, which follows the established best practice. Based on learnings, this pattern ensures components react properly when themes change via ThemeProvider.

src/lib/typography/img/Img.svelte (3)

11-11: LGTM! Correct reactive theme usage.

The theme retrieval correctly uses $derived() to ensure the component reacts to dynamic theme changes, following best practices for ThemeProvider integration.

Based on learnings, this pattern ensures proper reactivity when themes change at runtime.


23-23: LGTM! Proper data attribute structure.

The data-scope and data-part attributes on figure and figcaption elements are correctly structured. The figcaption appropriately inherits scope from its parent figure element.

Also applies to: 29-29


27-27: Verify attribute order: data-scope can be overridden by restProps.

The data-scope="img" attribute is placed before the {...restProps} spread, which means users can override it by passing a data-scope prop. Verify whether this override behavior is intentional.

If data-scope is critical for styling or component functionality and should not be overridden, consider moving it after {...restProps}:

🔎 Proposed fix if override should be prevented
-        <img data-scope="img" {...restProps} class={imgClass} />
+        <img {...restProps} data-scope="img" class={imgClass} />

And similarly for line 36:

-    <img data-scope="img" {...restProps} class={imgClass} />
+    <img {...restProps} data-scope="img" class={imgClass} />

Also applies to: 36-36

src/lib/typography/hr/theme.ts (2)

14-18: Potential loss of base styling when withChildren is true.

When withChildren is true, the base slot is set to just "w-full", which replaces the default base styling entirely. This means the <hr> element loses h-px my-8 border-0 bg-gray-200 dark:bg-gray-700.

If the intent is to add w-full while preserving the original styles, you should extend rather than replace:

🔎 Suggested fix if styles should be preserved
  variants: {
    withChildren: {
      true: {
-        base: "w-full"
+        base: "h-px my-8 border-0 bg-gray-200 dark:bg-gray-700 w-full"
      }
    }
  },

Alternatively, if this is intentional (e.g., the <hr> should only provide width when wrapped), please confirm.


7-23: LGTM on the slot renaming and structure.

The slot renaming from div/bg to wrapper/base/content aligns with the PR's objective to standardize slot naming across components. The addition of defaultVariants is a good practice for explicit defaults.

src/lib/typography/hr/Hr.svelte (2)

9-16: Proper use of $derived for reactive theme access.

The getTheme("hr") call is correctly placed inside a $derived() expression, ensuring the component reacts to dynamic theme changes. Based on learnings, this is the recommended pattern.


19-25: Data attributes properly added for accessibility/styling hooks.

The data-scope="hr" and data-part="wrapper"/data-part="content" attributes are correctly added per the PR objectives. This aligns with the broader refactor pattern across components.

src/lib/typography/a/A.svelte (1)

32-32: LGTM! Consistent data-scope attribute additions.

The data-scope="anchor" attribute additions to both rendering paths (button and anchor elements) align with the PR's objective to add consistent data attributes for improved DOM targeting and testing across components.

Also applies to: 37-37

src/lib/typography/descriptionlist/DescriptionList.svelte (1)

9-9: LGTM: Reactive theme derivation implemented correctly.

The use of $derived(getTheme("descriptionList")) ensures the component reacts to dynamic theme changes from ThemeProvider.

Based on learnings, this pattern is the recommended approach for theme reactivity in Flowbite-Svelte components.

src/lib/typography/heading/Heading.svelte (1)

9-9: LGTM: Correct reactive theme pattern.

The theme derivation correctly uses $derived(getTheme("heading")), ensuring the component reacts to dynamic theme changes per the established pattern in this repository.

Copy link
Copy Markdown
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/forms/timepicker/Timepicker.svelte (3)

294-317: Inconsistent data-part attributes on paired range elements.

The second range input wrapper (line 294), range button (line 308), and icon SVG (line 312) are missing data-part attributes that were added to their counterparts at lines 263, 277-283, and 287 respectively. This inconsistency will make it difficult to target all similar elements for testing or styling.

🔎 Proposed fix to add missing data-part attributes
-      <div class={styles.rangeInputWrapper({ class: clsx(theme?.rangeInputWrapper) })}>
+      <div data-part="range-input-wrapper" class={styles.rangeInputWrapper({ class: clsx(theme?.rangeInputWrapper) })}>
         <Input
           id={endId}
           color={inputColor}
           type="time"
           {min}
           {max}
           {required}
           {disabled}
           class={styles.input({ class: clsx(styles.rangeInput(), theme?.rangeInput, inputClass) })}
           bind:value={endValue}
           oninput={(e) => handleTimeChange(e, true)}
           onchange={(e) => handleTimeChange(e, true)}
         />
-        <button type="button" class={styles.rangeButton({ class: clsx(theme?.rangeButton) })} onclick={() => document.getElementById(endId)?.click()} aria-label="Open end time picker">
+        <button data-part="range-button" type="button" class={styles.rangeButton({ class: clsx(theme?.rangeButton) })} onclick={() => document.getElementById(endId)?.click()} aria-label="Open end time picker">
           {#if Icon}
             <Icon class={iconClass} />
           {:else}
-            <svg class={styles.icon({ class: clsx(theme?.icon) })} aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
+            <svg data-part="icon" class={styles.icon({ class: clsx(theme?.icon) })} aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
               <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6v4l3.276 3.276M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
             </svg>
           {/if}
         </button>
       </div>

344-359: Missing data-part on second dropdown-time-col.

The second dropdown-time-col div (line 344) is missing the data-part="dropdown-time-col" attribute that was added to its sibling at line 328.

🔎 Proposed fix
-            <div class={styles.dropdownTimeCol({ class: clsx(theme?.dropdownTimeCol) })}>
+            <div data-part="dropdown-time-col" class={styles.dropdownTimeCol({ class: clsx(theme?.dropdownTimeCol) })}>
               <Label for={endId}>End time:</Label>

389-404: Missing data-part on second toggle-time-col.

The second toggle-time-col div (line 389) is missing the data-part="toggle-time-col" attribute that was added to its sibling at line 373.

🔎 Proposed fix
-            <div class={styles.toggleTimeCol({ class: clsx(theme?.toggleTimeCol) })}>
+            <div data-part="toggle-time-col" class={styles.toggleTimeCol({ class: clsx(theme?.toggleTimeCol) })}>
               <Label for={endId}>End time:</Label>
♻️ Duplicate comments (1)
src/lib/typography/hr/Hr.svelte (1)

21-21: Note: Past review issue appears resolved.

The past review comment indicated that styling?.wrapper was missing from this line, but it's now present in the code. The wrapper correctly merges theme?.wrapper and styling?.wrapper.

🧹 Nitpick comments (1)
src/lib/forms/checkbox/Checkbox.svelte (1)

77-78: LGTM! Data attributes correctly applied.

The same data-scope and data-part pattern is consistently used in the no-choices branch.

For consistency, consider formatting the input element across multiple lines (as done in the choices loop at lines 58-68), but this is purely stylistic.

🔎 Optional formatting consistency
-  <Label show={!!children} {...labelProps} class={labelStyle({ class: clsx(theme?.label, styling?.label) })} data-scope="checkbox" data-part="label">
-    <input type="checkbox" {value} bind:checked {disabled} {...restProps} class={base({ class: clsx(theme?.base, className) })} data-scope="checkbox" data-part="base" />
+  <Label show={!!children} {...labelProps} class={labelStyle({ class: clsx(theme?.label, styling?.label) })} data-scope="checkbox" data-part="label">
+    <input
+      type="checkbox"
+      {value}
+      bind:checked
+      {disabled}
+      {...restProps}
+      class={base({ class: clsx(theme?.base, className) })}
+      data-scope="checkbox"
+      data-part="base"
+    />
    {#if children}
      {@render children({ value, checked, disabled })}
    {/if}
  </Label>
📜 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 579d40d and ff8807b.

📒 Files selected for processing (15)
  • src/lib/forms/checkbox/Checkbox.svelte
  • src/lib/forms/timepicker/Timepicker.svelte
  • src/lib/forms/toggle/theme.ts
  • src/lib/typography/hr/Hr.svelte
  • src/lib/typography/hr/theme.ts
  • src/lib/typography/layout/Layout.svelte
  • src/lib/typography/list/List.svelte
  • src/lib/typography/mark/Mark.svelte
  • src/lib/typography/paragraph/P.svelte
  • src/lib/typography/secondary/Secondary.svelte
  • src/lib/typography/span/Span.svelte
  • src/routes/docs-examples/forms/phone-input/Classes.svelte
  • src/routes/docs-examples/forms/textarea/Chatroom.svelte
  • src/routes/docs-examples/forms/toggle/Sizes.svelte
  • src/routes/docs-examples/typography/hr/Text.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/typography/hr/theme.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/typography/paragraph/P.svelte
  • src/lib/typography/secondary/Secondary.svelte
  • src/lib/typography/span/Span.svelte
  • src/lib/forms/toggle/theme.ts
  • src/lib/typography/list/List.svelte
  • src/lib/typography/hr/Hr.svelte
  • src/lib/forms/timepicker/Timepicker.svelte
  • src/lib/typography/mark/Mark.svelte
  • src/routes/docs-examples/forms/textarea/Chatroom.svelte
  • src/lib/forms/checkbox/Checkbox.svelte
  • src/routes/docs-examples/forms/toggle/Sizes.svelte
  • src/routes/docs-examples/forms/phone-input/Classes.svelte
  • src/routes/docs-examples/typography/hr/Text.svelte
  • src/lib/typography/layout/Layout.svelte
🧠 Learnings (12)
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

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

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

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

// use $themeDerived in template/component

Applied to files:

  • src/lib/typography/paragraph/P.svelte
  • src/lib/typography/secondary/Secondary.svelte
  • src/lib/typography/span/Span.svelte
  • src/lib/typography/list/List.svelte
  • src/lib/typography/hr/Hr.svelte
  • src/lib/forms/timepicker/Timepicker.svelte
  • src/lib/typography/mark/Mark.svelte
  • src/routes/docs-examples/forms/textarea/Chatroom.svelte
  • src/lib/forms/checkbox/Checkbox.svelte
  • src/routes/docs-examples/forms/toggle/Sizes.svelte
  • src/routes/docs-examples/forms/phone-input/Classes.svelte
  • src/routes/docs-examples/typography/hr/Text.svelte
  • src/lib/typography/layout/Layout.svelte
📚 Learning: 2025-03-20T12:47:33.307Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles with focus-within, create a dedicated focusWithinClasses object with appropriate colors for each state (base, primary, green, red). Using just 'focus-within:ring-1' without color specification won't correctly apply color-specific styling when the input receives focus directly.

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/lib/typography/hr/Hr.svelte
  • src/routes/docs-examples/forms/phone-input/Classes.svelte
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1465
File: src/lib/forms/Timepicker.svelte:105-116
Timestamp: 2024-10-18T09:38:03.879Z
Learning: In `Timepicker.svelte`, the `Dropdown` opens as intended and is used exclusively with the 'dropdown' and 'timerange-dropdown' Timepicker types.

Applied to files:

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

Applied to files:

  • src/lib/forms/timepicker/Timepicker.svelte
📚 Learning: 2024-10-15T22:41:47.429Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1464
File: src/routes/component-data/Datepicker.json:0-0
Timestamp: 2024-10-15T22:41:47.429Z
Learning: The component should be named 'Datepicker' (with lowercase 'p') throughout the codebase to maintain consistency.

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/routes/docs-examples/forms/phone-input/Classes.svelte
📚 Learning: 2025-12-28T05:16:44.735Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-12-28T05:16:44.735Z
Learning: In flowbite-svelte with Svelte 5, props are not reactive by default. To make prop values reactive (so they update when the prop changes), they must be wrapped with `$derived()`. For example, `const styling = $derived(classes)` is necessary—not redundant—to ensure `styling` reacts to changes in the `classes` prop.

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/routes/docs-examples/forms/phone-input/Classes.svelte
🔇 Additional comments (20)
src/lib/typography/layout/Layout.svelte (1)

14-14: LGTM!

The addition of data-scope="layout" aligns with the PR's objective to standardize DOM metadata across components. This attribute enables better targeting for styling and testing without introducing breaking changes.

src/routes/docs-examples/forms/phone-input/Classes.svelte (1)

5-5: LGTM! Example correctly updated to match the API refactoring.

The change from div to iconWrapper in the classes prop correctly reflects the theme slot rename in src/lib/forms/phoneinput/theme.ts. The example now demonstrates the new public API properly.

src/lib/typography/secondary/Secondary.svelte (2)

9-9: LGTM! Correct reactive theme pattern.

The theme retrieval correctly uses $derived(getTheme("secondary")), ensuring the component reacts to dynamic theme changes. This follows the recommended pattern for ThemeProvider integration.

Based on learnings, getTheme calls should be inside $derived() expressions (not at module scope) for reactive theme support.


12-12: LGTM! Data-scope attribute added correctly.

The data-scope="secondary" attribute properly identifies this component's scope, aligning with the PR's objective to standardize data-scope/data-part attributes across components. This is a non-breaking change that adds helpful metadata for theming and testing.

src/lib/typography/paragraph/P.svelte (2)

27-27: Verify attribute placement to prevent unintended override.

The data-scope="paragraph" attribute is placed before {...restProps}, which means a user could accidentally override it by passing a custom data-scope in props. Since data-scope attributes are typically used for semantic identification and testing (as indicated by the PR objectives), they usually should not be overrideable.

Consider placing data-scope after {...restProps} to ensure it cannot be overridden:

-<p data-scope="paragraph" {...restProps} class={classP}>
+<p {...restProps} data-scope="paragraph" class={classP}>

If allowing override is intentional for flexibility, please confirm this design decision.


22-22: Correct reactive theme pattern!

The use of $derived(getTheme("paragraph")) correctly follows the pattern for reactive theme changes with ThemeProvider. This ensures the component responds to dynamic theme updates.

Based on learnings, this is the recommended approach.

src/lib/forms/checkbox/Checkbox.svelte (1)

57-74: LGTM! Data attributes correctly added for scoping.

The data-scope="checkbox" and data-part="label"/"base" attributes are consistently applied to enable targeted styling and testing without affecting functionality.

src/lib/forms/timepicker/Timepicker.svelte (4)

188-188: LGTM!

The data-scope="timepicker" and data-part="button-group" attributes are correctly placed on the root container for non-inline button types, enabling targeted testing and styling.


203-211: LGTM!

The data-part attributes on the icon wrapper and default SVG icon are correctly applied, allowing precise targeting for tests and styles.


243-253: LGTM!

The data-part="button-icon" attribute is correctly added to the dropdown chevron icon with cleaner multi-line formatting.


411-417: LGTM!

The data-scope="timepicker" and data-part="inline-grid" attributes are correctly placed on the root container for the inline-buttons type, maintaining consistency with the other rendering branch.

src/lib/typography/mark/Mark.svelte (1)

12-12: LGTM! Data-scope attribute correctly added.

The addition of data-scope="mark" appropriately identifies this component's scope in the DOM and aligns with the PR's objective to add consistent data attributes across components. The change is non-breaking and purely additive.

src/routes/docs-examples/forms/toggle/Sizes.svelte (1)

9-9: Correctly updated to use the new track slot key.

This example now properly uses classes={{ track: customSize }}, which aligns with the theme refactor in src/lib/forms/toggle/theme.ts. This resolves the issue flagged in a previous review where this line was using the old span key.

src/routes/docs-examples/forms/textarea/Chatroom.svelte (1)

17-17: LGTM! Example updated to match theme migration.

The slot key update from div to container correctly aligns with the Textarea component's theme migration. The more semantic naming improves clarity while maintaining the same styling behavior.

If you'd like, I can verify that all other Textarea examples across the docs have been similarly updated:

🔍 Verification script
#!/bin/bash
# Description: Search for any remaining Textarea usages with the old 'div' slot pattern in examples

# Search for Textarea components with classes prop containing 'div:' key
rg -n --type=svelte -C2 'classes=\{\{[^}]*\bdiv:' src/routes/docs-examples/
src/routes/docs-examples/typography/hr/Text.svelte (1)

10-10: LGTM - demonstrates the new structured classes API.

The example correctly shows how to customize the Hr component's content part using the new classes prop structure, applying dark mode text styling.

src/lib/typography/list/List.svelte (1)

31-31: LGTM - consistent scoping attribute.

The data-scope="list" attribute addition aligns with the PR's systematic introduction of scoping attributes across components for improved testability.

src/lib/typography/span/Span.svelte (1)

27-27: LGTM - consistent scoping attribute.

The data-scope="span" attribute addition follows the same pattern as other typography components in this PR.

src/lib/typography/hr/Hr.svelte (3)

12-12: LGTM - flexible background color handling.

The derived bg value allows users to override the default background via classes.bg while providing sensible defaults with dark mode support.


17-17: LGTM - wrapper slot renaming.

The destructuring change from div to wrapper aligns with the broader theme.ts refactoring mentioned in the AI summary and provides more semantic naming.


28-28: Verify data-scope value on standalone hr element.

The standalone <hr> uses data-scope="base" but should likely use data-scope="hr" to identify it as the Hr component's root element. In the children branch (line 21), the wrapper uses data-scope="hr". For consistency, the standalone variant should also use "hr" as its scope identifier.

This can be verified using the same script as the previous comment, checking whether standalone root elements use the component name or a different value for data-scope.

@shinokada
Copy link
Copy Markdown
Collaborator Author

@coderabbitai Please ignore files under src/routes/llm directory. When I publish a new version, they will be automatically update.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 1, 2026

Tip

For best results, initiate chat on the files or code changes.

@shinokada: Understood! I'll ignore files under the src/routes/llm directory in future reviews since they are automatically updated when you publish new versions.


✏️ Learnings added
Learnt from: shinokada
URL: https://github.com/themesberg/flowbite-svelte/pull/1902

Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Copy link
Copy Markdown
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

📜 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 ff8807b and 05c84ff.

📒 Files selected for processing (15)
  • src/lib/forms/timepicker/Timepicker.svelte
  • src/lib/typography/a/A.svelte
  • src/lib/typography/blockquote/Blockquote.svelte
  • src/lib/typography/descriptionlist/DescriptionList.svelte
  • src/lib/typography/heading/Heading.svelte
  • src/lib/typography/hr/Hr.svelte
  • src/lib/typography/img/Img.svelte
  • src/lib/typography/img/theme.ts
  • src/lib/typography/layout/Layout.svelte
  • src/lib/typography/list/Li.svelte
  • src/lib/typography/list/List.svelte
  • src/lib/typography/mark/Mark.svelte
  • src/lib/typography/paragraph/P.svelte
  • src/lib/typography/secondary/Secondary.svelte
  • src/lib/typography/span/Span.svelte
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/lib/typography/layout/Layout.svelte
  • src/lib/typography/heading/Heading.svelte
  • src/lib/typography/descriptionlist/DescriptionList.svelte
  • src/lib/typography/mark/Mark.svelte
  • src/lib/typography/a/A.svelte
  • src/lib/typography/paragraph/P.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/typography/list/List.svelte
  • src/lib/typography/blockquote/Blockquote.svelte
  • src/lib/typography/span/Span.svelte
  • src/lib/forms/timepicker/Timepicker.svelte
  • src/lib/typography/secondary/Secondary.svelte
  • src/lib/typography/list/Li.svelte
  • src/lib/typography/img/Img.svelte
  • src/lib/typography/img/theme.ts
  • src/lib/typography/hr/Hr.svelte
🧠 Learnings (3)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
📚 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/typography/list/List.svelte
  • src/lib/typography/blockquote/Blockquote.svelte
  • src/lib/typography/span/Span.svelte
  • src/lib/forms/timepicker/Timepicker.svelte
  • src/lib/typography/secondary/Secondary.svelte
  • src/lib/typography/list/Li.svelte
  • src/lib/typography/img/Img.svelte
  • src/lib/typography/hr/Hr.svelte
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1465
File: src/lib/forms/Timepicker.svelte:105-116
Timestamp: 2024-10-18T09:38:03.879Z
Learning: In `Timepicker.svelte`, the `Dropdown` opens as intended and is used exclusively with the 'dropdown' and 'timerange-dropdown' Timepicker types.

Applied to files:

  • src/lib/forms/timepicker/Timepicker.svelte
🔇 Additional comments (12)
src/lib/typography/span/Span.svelte (1)

27-27: LGTM! Data attributes added for component metadata standardization.

The addition of data-scope="span" and data-part="base" attributes aligns with the PR's objective to standardize DOM metadata across components. These attributes provide semantic hooks for testing and styling without affecting functionality.

src/lib/typography/secondary/Secondary.svelte (1)

12-12: LGTM! Data attributes added correctly.

The addition of data-scope="secondary" and data-part="base" attributes aligns with the PR objective to standardize component scoping and improve testability across the codebase. The implementation is clean and has no impact on existing functionality.

src/lib/typography/list/List.svelte (1)

31-31: LGTM! Data attributes added correctly.

The addition of data-scope="list" and data-part="base" follows the PR-wide pattern of adding semantic metadata attributes across components. This enables more precise DOM targeting and styling without affecting component functionality.

src/lib/typography/blockquote/Blockquote.svelte (1)

23-23: LGTM! Data attributes align with PR objectives.

The addition of data-scope="blockquote" and data-part="base" follows the consistent pattern being applied across components in this PR. The implementation is clean, non-breaking, and provides useful semantic markers for styling and testing.

Additionally, the reactive theme handling at line 9 correctly uses $derived(getTheme("blockquote")), which ensures the component reacts to dynamic theme changes as per best practices.

src/lib/typography/list/Li.svelte (1)

13-13: LGTM! Data attributes added consistently.

The addition of data-scope="li" and data-part="base" aligns with the PR objective to systematically add data attributes across components. The scope value matches the component name, and "base" is an appropriate part name for the root element.

src/lib/forms/timepicker/Timepicker.svelte (1)

188-411: LGTM! Consistent addition of data-scope and data-part attributes.

The changes systematically add semantic attributes throughout the component for targeted testing and styling:

  • data-scope="timepicker" on top-level containers (ButtonGroup, inline-grid)
  • data-part="*" on individual elements (icon-wrapper, button-icon, range-button, dropdown-content, etc.)

The implementation is clean, follows consistent kebab-case naming, and doesn't modify any logic. The theme usage at line 43 correctly uses $derived() for reactivity.

src/lib/typography/img/theme.ts (1)

9-44: LGTM! Well-structured theme refactoring.

The slot renaming from figure to image/base improves semantic clarity. The apparent duplication of classes across image and base slots in size and align variants is intentional and correct—since the component can render the image standalone or within a <figure>, both slots need styling to cover all rendering paths.

src/lib/typography/img/Img.svelte (3)

11-11: Correct reactive theme usage.

The getTheme("img") call is properly wrapped in $derived(), ensuring the component reacts to dynamic theme changes. This follows the established pattern for ThemeProvider integration.

Based on learnings, this placement ensures proper reactivity.


13-18: LGTM! Proper theme slot integration.

The destructuring correctly maps to the updated theme structure (base, image, caption), and the imgClass derivation properly uses the new image slot with appropriate styling composition.


23-36: Well-structured data attributes for component scoping.

The addition of data-scope="img" and data-part attributes (base, image, caption) provides clear semantic hooks for styling and testing. The class applications are correctly mapped to their respective theme slots across all rendering paths.

src/lib/typography/hr/Hr.svelte (2)

12-12: LGTM: Derived values properly structured.

The new bg derived value provides a configurable background with a sensible default, and the destructuring of { base, wrapper, content } correctly aligns with the updated theme shape.

Also applies to: 17-17


21-21: LGTM: Wrapper and content styling correctly implemented.

The wrapper now properly includes styling?.wrapper (confirmed fix from previous review), and the content element correctly merges both theme?.content and styling?.content. Both elements follow the expected pattern for theme customization.

Also applies to: 23-23

Copy link
Copy Markdown
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 (4)
convert-imports.mjs (2)

118-128: Remove redundant check for helpers.ts.

The check at lines 119-122 can never be true because convertImports already returns unchanged content for helpers.ts at line 66. When content equals converted, the condition at line 114 prevents entry into this block entirely.

🔎 Suggested simplification
       if (content !== converted) {
         const fileName = path.basename(filePath);
         const relativePath = path.relative(process.cwd(), filePath);
 
-        // Check if it's a transformation utility file that should be skipped
-        if (fileName === "helpers.ts" && filePath.includes("src/routes/utils/helpers.ts")) {
-          console.log(`⊘ Skipped (transformation utility): ${relativePath}`);
-          skippedFiles.push(relativePath);
-          skippedCount++;
-        } else {
-          fs.writeFileSync(filePath, converted, "utf-8");
-          console.log(`✓ Converted: ${relativePath}`);
-          convertedFiles.push(relativePath);
-          convertedCount++;
-        }
+        fs.writeFileSync(filePath, converted, "utf-8");
+        console.log(`✓ Converted: ${relativePath}`);
+        convertedFiles.push(relativePath);
+        convertedCount++;
       } else {
         unchangedCount++;
       }

69-72: Consider using the existing shouldExcludeFile function for consistency.

The check at line 70 uses .includes("include-files.js") for path matching, while line 62 uses a more specific check. Consider leveraging the existing shouldExcludeFile function (lines 19-22) for consistency.

🔎 Proposed refactor
 function convertImports(content, filePath) {
   const fileName = path.basename(filePath);
 
+  // Skip excluded files entirely
+  if (shouldExcludeFile(filePath)) {
+    return content;
+  }
+
   // Special handling for helpers.ts - only convert the actual imports, not the string replacements
   if (fileName === "helpers.ts" && filePath.includes("src/routes/utils/helpers.ts")) {
     // Don't convert lines that are part of the replaceLibImport function
     // These lines contain strings like: .replace(/from ["']\$lib["']/g, "from 'flowbite-svelte'")
     // We want to preserve those
     return content;
   }
 
-  // Don't convert if the file contains transformation logic in include-files.js
-  if (filePath.includes("include-files.js")) {
-    return content;
-  }
-
   let converted = content.replace(/from\s+["']flowbite-svelte["']/g, 'from "$lib"');
find-imports.mjs (1)

53-64: Consider adding conversion command suggestion for consistency.

The find-all-imports.mjs script suggests running node convert-imports.mjs when imports are found (line 65 in that file). Consider adding the same helpful suggestion here for consistency.

🔎 Proposed addition
 if (results.length === 0) {
   console.log('✅ No "flowbite-svelte" imports found!');
 } else {
   console.log(`❌ Found ${results.length} file(s) with "flowbite-svelte" imports:\n`);
   results.forEach(({ file, matches }) => {
     console.log(`📄 ${file}`);
     matches.forEach(({ lineNum, line }) => {
       console.log(`   Line ${lineNum}: ${line}`);
     });
     console.log("");
   });
+
+  console.log("\n💡 To fix these, run: node convert-imports.mjs");
 }
questions.md (1)

6-12: Consider adding language specifications to code blocks.

The markdown code blocks at lines 6-12 and 28-35 are missing language specifications, which would enable syntax highlighting. While this is an internal documentation file, adding language specs improves readability.

🔎 Proposed fix
-```
+```markdown
 ...
   resolve: {
```

And for the second block:

```diff
-```
+```ts
  ...
   resolve: {
📜 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 05c84ff and 4415ed8.

📒 Files selected for processing (12)
  • convert-imports.mjs
  • design-system.md
  • find-all-imports.mjs
  • find-imports.mjs
  • questions.md
  • src/lib/forms/checkbox/Checkbox.svelte
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/dropzone/Dropzone.svelte
  • src/lib/forms/fileupload/Fileupload.svelte
  • src/lib/forms/fileupload/theme.ts
  • src/lib/forms/floating-label/FloatingLabelInput.svelte
  • src/lib/forms/input-field/Input.svelte
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/forms/fileupload/theme.ts
  • src/lib/forms/floating-label/FloatingLabelInput.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/forms/checkbox/Checkbox.svelte
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/dropzone/Dropzone.svelte
  • src/lib/forms/input-field/Input.svelte
  • src/lib/forms/fileupload/Fileupload.svelte
🧠 Learnings (20)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
📚 Learning: 2025-08-31T12:56:05.074Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1745
File: src/lib/types.ts:677-686
Timestamp: 2025-08-31T12:56:05.074Z
Learning: HTMLInputAttributes includes a `group` property that can be used for grouping form controls like checkboxes and radio buttons, so interfaces extending HTMLInputAttributes don't need to explicitly declare `group` unless they want to override its type.

Applied to files:

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

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

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

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

// use $themeDerived in template/component

Applied to files:

  • src/lib/forms/checkbox/Checkbox.svelte
  • src/lib/forms/dropzone/Dropzone.svelte
  • src/lib/forms/input-field/Input.svelte
  • src/lib/forms/fileupload/Fileupload.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:

  • find-all-imports.mjs
  • convert-imports.mjs
  • find-imports.mjs
  • questions.md
  • design-system.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} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation

Applied to files:

  • find-all-imports.mjs
  • convert-imports.mjs
  • find-imports.mjs
  • questions.md
  • design-system.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:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/lib/forms/checkbox/theme.ts
📚 Learning: 2025-11-25T07:26:39.377Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: 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:

  • find-imports.mjs
  • questions.md
📚 Learning: 2026-01-01T13:12:34.868Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/lib/forms/input-field/Input.svelte
📚 Learning: 2025-12-28T05:16:44.735Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-12-28T05:16:44.735Z
Learning: In flowbite-svelte with Svelte 5, props are not reactive by default. To make prop values reactive (so they update when the prop changes), they must be wrapped with `$derived()`. For example, `const styling = $derived(classes)` is necessary—not redundant—to ensure `styling` reacts to changes in the `classes` prop.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • design-system.md
🧬 Code graph analysis (2)
find-all-imports.mjs (2)
convert-imports.mjs (9)
  • __filename (7-7)
  • __dirname (8-8)
  • EXCLUDE_DIRS (14-14)
  • files (32-32)
  • filePath (35-35)
  • stat (36-36)
  • content (111-111)
  • relativePath (20-20)
  • relativePath (116-116)
find-imports.mjs (11)
  • __filename (7-7)
  • __dirname (8-8)
  • EXCLUDE_DIRS (11-11)
  • results (51-51)
  • files (16-16)
  • filePath (19-19)
  • stat (20-20)
  • content (28-28)
  • relativePath (30-30)
  • lines (31-31)
  • matchingLines (32-32)
convert-imports.mjs (2)
find-all-imports.mjs (8)
  • __filename (7-7)
  • __dirname (8-8)
  • EXCLUDE_DIRS (11-11)
  • filePath (19-19)
  • relativePath (30-30)
  • files (16-16)
  • stat (20-20)
  • content (28-28)
find-imports.mjs (8)
  • __filename (7-7)
  • __dirname (8-8)
  • EXCLUDE_DIRS (11-11)
  • filePath (19-19)
  • relativePath (30-30)
  • files (16-16)
  • stat (20-20)
  • content (28-28)
🪛 LanguageTool
questions.md

[style] ~51-~51: Consider using a different verb for a more formal wording.
Context: ...? Do you have any suggestions? Can you fix this problem?

(FIX_RESOLVE)

🪛 markdownlint-cli2 (0.18.1)
questions.md

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

(MD040, fenced-code-language)


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

(MD040, fenced-code-language)

🔇 Additional comments (20)
src/lib/forms/dropzone/Dropzone.svelte (1)

49-52: LGTM! Data attributes added for testing/styling.

The addition of data-scope="dropzone" and data-part attributes aligns with the PR's objective to standardize component markup for testing and styling selectors. The part names ("base", "input") are consistent with the theme structure.

convert-imports.mjs (1)

1-163: LGTM! Well-structured import conversion utility.

The script provides a clear workflow for converting flowbite-svelte imports to $lib with appropriate exclusions and helpful console output. The special handling for transformation utility files ensures the conversion logic itself remains intact.

find-all-imports.mjs (1)

1-66: LGTM! Comprehensive import search utility.

The script effectively searches the entire project for flowbite-svelte imports with clear console output and proper exclusions. The distinction between this script (entire project) and find-imports.mjs (src only) is well-communicated.

questions.md (1)

37-50: Helpful documentation of development workflow issue.

This documentation clearly describes the build-time dependency problem and proposes a reasonable solution using $lib imports with string transformation in ExampleWrapper.svelte. The new utility scripts in this PR (convert-imports.mjs, find-imports.mjs, find-all-imports.mjs) appear to be part of implementing this workflow improvement.

src/lib/forms/checkbox/Checkbox.svelte (3)

30-30: LGTM! Semantic improvement in theme slot naming.

The rename from base to input improves clarity by explicitly indicating that the styling applies to the checkbox input element. This aligns with the PR's theme slot name updates.


57-67: LGTM! Consistent data attributes and styling updates.

The addition of data-scope="checkbox" and data-part attributes improves component testability and CSS targeting. The class binding correctly uses the renamed input() styling function, maintaining consistency with the theme changes.


76-77: LGTM! Consistent implementation across both branches.

The data attributes and styling updates in the no-choices branch mirror those in the choices branch, ensuring consistent behavior and testability regardless of how the component is used.

design-system.md (3)

13-14: Clear constraint on data-scope usage.

The constraint limiting each component to a single data-scope attribute (with exceptions for conditional rendering) is clear and helps maintain a clean component boundary model.


29-39: Helpful guidance on naming conflicts.

The new section provides practical guidance for handling naming conflicts between data-part names and component props. The example correctly uses $derived() for Svelte 5 reactivity, and the suggested prefixes (themeTitlePart, variantTitle, titlePart) are descriptive and consistent with JavaScript conventions.


78-99: Updated slot naming tables align with component implementations.

The additions of list, item, and close-button entries, along with improved formatting, accurately reflect the slot naming patterns used across the codebase. The close-button entry specifically aligns with the usage in Fileupload.svelte.

src/lib/forms/fileupload/Fileupload.svelte (3)

41-48: Updated closeButton and closeIcon references align with theme refactor.

The changes from close to closeButton and svg to closeIcon follow a more semantic naming convention, making the component API clearer and more descriptive.


51-56: Data attributes correctly applied per design system conventions.

The data-scope="fileupload" and data-part attributes follow the documented pattern in design-system.md:

  • data-scope="fileupload" on the root element establishes the component boundary
  • data-part="wrapper" on the base container
  • data-part="input" on the input element
  • data-part="close-button" on the CloseButton component

These provide stable selectors for styling and testing without relying on utility classes.


15-15: Destructuring updated to match renamed theme slots.

The destructuring now uses { input, base, closeButton } matching the theme slot renaming pattern described in the PR objectives. All slot names are correctly defined in src/lib/forms/fileupload/theme.ts.

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

6-112: Slot rename from base to input is complete and properly implemented.

The checkbox theme consistently uses input and label slots across all variants (lines 5-112). The Checkbox.svelte component correctly destructures and applies these slots. No remaining references to the old base slot were found in the checkbox theme or its consumers. The change is safe; Checkbox.svelte uses slot styling as a theme implementation detail rather than exposing slot names to consumers.

src/lib/forms/input-field/Input.svelte (6)

235-239: Approve the closeButton and closeIcon updates.

The renamed references to closeButton and closeIcon align with the theme slot renaming. The usage pattern correctly applies the theme function closeButton() and merges theme/styling overrides for both slots.


252-254: LGTM: leftAddon implementation is consistent.

The renamed leftAddon slot is used consistently across the function call, theme override, and styling override. The data-part="left-addon" attribute correctly uses kebab-case.


258-260: LGTM: rightAddon implementation is consistent.

The renamed rightAddon slot is used consistently across the function call, theme override, and styling override. The data-part="right-addon" attribute correctly uses kebab-case.


264-277: LGTM: comboList and option implementations are consistent.

The renamed slots are used consistently:

  • comboList (renamed from combo) with data-part="combo-list"
  • option (renamed from comboItem) with data-part="option"

All function calls, theme overrides, and styling overrides match the new slot names, and data-part attributes correctly use kebab-case.


296-296: LGTM: data-part attribute added to input element.

The data-part="input" attribute correctly identifies the input element, consistent with the data-part attributes added to other elements.


299-299: LGTM: data-part attribute added to CloseButton.

The data-part="close-button" attribute correctly identifies the close button element using kebab-case, consistent with other data-part attributes.

let _size = $derived(size || (group?.size ? clampSize(group.size) : undefined) || "md");
const _color = $derived(color === "default" && background ? "tinted" : color);
const { base, input: inputCls, left: leftCls, right: rightCls, close, combo, comboItem } = $derived(input({ size: _size, color: _color, grouped: isGroup }));
const { base, input: inputCls, leftAddon, rightAddon, closeButton, comboList, option } = $derived(input({ size: _size, color: _color, grouped: isGroup }));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find and examine the theme.ts file for the input component
fd -t f 'theme\.ts' --search-path src/lib/forms/input-field/

Repository: themesberg/flowbite-svelte

Length of output: 104


🏁 Script executed:

#!/bin/bash
# Search for the input theme function definition
rg -A 30 'export const input\s*=' src/lib/forms/input-field/

Repository: themesberg/flowbite-svelte

Length of output: 2744


🏁 Script executed:

#!/bin/bash
# Check the current directory structure to locate theme.ts
ls -la src/lib/forms/input-field/

Repository: themesberg/flowbite-svelte

Length of output: 364


🏁 Script executed:

#!/bin/bash
# Check the Input.svelte file around lines 239-250 and 59
sed -n '55,65p' src/lib/forms/input-field/Input.svelte

Repository: themesberg/flowbite-svelte

Length of output: 643


🏁 Script executed:

#!/bin/bash
# Check lines around 235-245 to see how closeIcon is used
sed -n '235,245p' src/lib/forms/input-field/Input.svelte

Repository: themesberg/flowbite-svelte

Length of output: 501


🏁 Script executed:

#!/bin/bash
# Check lines around 245-255 to see how wrapper is used
sed -n '245,255p' src/lib/forms/input-field/Input.svelte

Repository: themesberg/flowbite-svelte

Length of output: 485


🏁 Script executed:

#!/bin/bash
# Search for all references to wrapper and closeIcon in Input.svelte
rg -n 'wrapper|closeIcon' src/lib/forms/input-field/Input.svelte

Repository: themesberg/flowbite-svelte

Length of output: 277


Include wrapper and closeIcon in the theme destructuring or remove them from theme.ts.

Line 59 doesn't destructure wrapper and closeIcon even though theme.ts defines them as slots. Currently, these slots are defined in the theme function with empty values but aren't destructured. Line 250 uses styling?.wrapper while destructuring base, and line 239 accesses theme?.closeIcon directly from the component prop. Either destructure these slots and use them explicitly, or remove them from the theme.ts slots definition if they're not needed.

🤖 Prompt for AI Agents
In src/lib/forms/input-field/Input.svelte around line 59 (and usages at ~239 and
~250), the theme destructuring omits wrapper and closeIcon even though theme.ts
defines them as slots; either add wrapper and closeIcon to the destructuring on
line 59 so you use the explicit variables where styling?.wrapper and
theme?.closeIcon are referenced, or remove those two slot entries from theme.ts;
update the references at ~239 and ~250 to use the newly destructured wrapper and
closeIcon variables (or remove the references if you removed the slots) so there
are no undeclared property accesses.

Copy link
Copy Markdown
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/routes/docs-examples/extend/clipboard-manager/+page.svelte (1)

39-205: Critical: rounded-base is not a valid Tailwind CSS v4 utility class.

Throughout this file, rounded-lg has been replaced with rounded-base, but this class does not exist in Tailwind CSS v4. According to the Tailwind v4 documentation, the valid border radius utilities are: rounded, rounded-sm, rounded-md, rounded-lg, rounded-xl, rounded-2xl, rounded-3xl, and rounded-full.

This will cause all affected elements to lose their border radius styling, resulting in visual regression.

🔎 Suggested fix

Revert to rounded-lg or choose another valid Tailwind utility:

-    <div class="space-y-3 rounded-base p-6 shadow">
+    <div class="space-y-3 rounded-lg p-6 shadow">

Apply this fix to all occurrences on lines 39, 48, 64, 77, 92, 107, 117, 149, 174, 183, 195, 205, 232, 235, and 259.

♻️ Duplicate comments (1)
src/lib/forms/input-field/Input.svelte (1)

59-59: Destructure closeIcon for consistency with other slots.

The destructuring omits closeIcon even though it's defined in theme.ts. All other slots follow the pattern of destructuring the function and calling it with merged classes, but line 239 directly accesses theme?.closeIcon instead. This inconsistency means the base closeIcon slot from theme.ts is never applied.

🔎 Recommended fix
-const { base, input: inputCls, leftAddon, rightAddon, closeButton, comboList, option } = $derived(input({ size: _size, color: _color, grouped: isGroup }));
+const { base, input: inputCls, leftAddon, rightAddon, closeButton, comboList, option, closeIcon } = $derived(input({ size: _size, color: _color, grouped: isGroup }));

Then update line 239 to call the function:

-  classes: closeButtonProps?.classes ?? { svg: clsx(theme?.closeIcon, styling?.closeIcon) },
+  classes: closeButtonProps?.classes ?? { svg: closeIcon({ class: clsx(theme?.closeIcon, styling?.closeIcon) }) },
🧹 Nitpick comments (1)
find-imports.mjs (1)

27-41: Consider enhancing pattern matching and error handling.

The current implementation has two areas for improvement:

  1. Pattern matching (Line 29): The search only matches static imports with from "flowbite-svelte" or from 'flowbite-svelte'. It won't detect re-exports like export { Button } from 'flowbite-svelte', which could be relevant for a comprehensive migration audit.

  2. Error handling (Line 28): fs.readFileSync can throw on permission errors or I/O issues. Adding try-catch would make the script more robust and prevent it from crashing on problematic files.

🔎 Proposed enhancements
     } else if (file.endsWith(".svelte") || file.endsWith(".ts") || file.endsWith(".js") || file.endsWith(".md")) {
-      const content = fs.readFileSync(filePath, "utf-8");
-      if (content.includes('from "flowbite-svelte"') || content.includes("from 'flowbite-svelte'")) {
+      try {
+        const content = fs.readFileSync(filePath, "utf-8");
+        // Match both imports and re-exports
+        const pattern = /(from|export\s+.*\s+from)\s+['"]flowbite-svelte['"]/;
+        if (pattern.test(content)) {
           const relativePath = path.relative(__dirname, filePath);
           const lines = content.split("\n");
           const matchingLines = [];
 
           lines.forEach((line, index) => {
-            if (line.includes('from "flowbite-svelte"') || line.includes("from 'flowbite-svelte'")) {
+            if (pattern.test(line)) {
               matchingLines.push({ lineNum: index + 1, line: line.trim() });
             }
           });
 
           results.push({ file: relativePath, matches: matchingLines });
+        }
+      } catch (err) {
+        console.error(`⚠️  Error reading ${filePath}: ${err.message}`);
       }
     }
📜 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 4415ed8 and 15b52d9.

📒 Files selected for processing (24)
  • COMPLETE_REVIEW_SUMMARY.md
  • SLOT_NAMING_REVIEW.md
  • convert-imports.mjs
  • find-imports.mjs
  • package.json
  • src/lib/extend/button-toggle/ButtonToggle.svelte
  • src/lib/extend/button-toggle/ButtonToggleGroup.svelte
  • src/lib/extend/button-toggle/theme.ts
  • src/lib/extend/clipboard-manager/ClipboardManager.svelte
  • src/lib/extend/clipboard-manager/theme.ts
  • src/lib/extend/command-palette/CommandPalette.svelte
  • src/lib/extend/command-palette/theme.ts
  • src/lib/forms/checkbox/theme.ts
  • src/lib/forms/fileupload/theme.ts
  • src/lib/forms/input-field/Input.svelte
  • src/lib/forms/input-field/theme.ts
  • src/lib/forms/timepicker/Timepicker.svelte
  • src/lib/typography/img/Img.svelte
  • src/lib/typography/img/theme.ts
  • src/routes/builder/checkbox/+page.svelte
  • src/routes/docs-examples/extend/clipboard-manager/+page.svelte
  • src/routes/docs-examples/extend/clipboard-manager/examples/Interactive.svelte
  • src/routes/docs-examples/forms/checkbox/Colors.svelte
  • src/routes/layout.css
✅ Files skipped from review due to trivial changes (1)
  • src/routes/docs-examples/extend/clipboard-manager/examples/Interactive.svelte
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/lib/forms/timepicker/Timepicker.svelte
  • src/lib/extend/command-palette/CommandPalette.svelte
  • src/lib/forms/fileupload/theme.ts
  • src/lib/forms/checkbox/theme.ts
  • convert-imports.mjs
🧰 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/extend/button-toggle/ButtonToggleGroup.svelte
  • src/lib/extend/command-palette/theme.ts
  • src/routes/docs-examples/forms/checkbox/Colors.svelte
  • src/routes/docs-examples/extend/clipboard-manager/+page.svelte
  • src/lib/typography/img/theme.ts
  • src/lib/typography/img/Img.svelte
  • src/lib/extend/clipboard-manager/ClipboardManager.svelte
  • src/lib/forms/input-field/Input.svelte
  • src/routes/builder/checkbox/+page.svelte
  • src/lib/extend/clipboard-manager/theme.ts
  • src/lib/extend/button-toggle/theme.ts
  • src/lib/extend/button-toggle/ButtonToggle.svelte
  • src/lib/forms/input-field/theme.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
📚 Learning: 2025-08-31T12:56:05.074Z
Learnt from: jjagielka
Repo: themesberg/flowbite-svelte PR: 1745
File: src/lib/types.ts:677-686
Timestamp: 2025-08-31T12:56:05.074Z
Learning: HTMLInputAttributes includes a `group` property that can be used for grouping form controls like checkboxes and radio buttons, so interfaces extending HTMLInputAttributes don't need to explicitly declare `group` unless they want to override its type.

Applied to files:

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

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

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

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

// use $themeDerived in template/component

Applied to files:

  • src/lib/extend/button-toggle/ButtonToggleGroup.svelte
  • src/routes/docs-examples/forms/checkbox/Colors.svelte
  • src/routes/docs-examples/extend/clipboard-manager/+page.svelte
  • src/lib/typography/img/Img.svelte
  • src/lib/extend/clipboard-manager/ClipboardManager.svelte
  • src/lib/forms/input-field/Input.svelte
  • src/routes/builder/checkbox/+page.svelte
  • src/lib/extend/button-toggle/ButtonToggle.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components

Applied to files:

  • src/routes/docs-examples/extend/clipboard-manager/+page.svelte
  • find-imports.mjs
📚 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/extend/clipboard-manager/ClipboardManager.svelte
  • src/lib/forms/input-field/Input.svelte
📚 Learning: 2025-03-20T11:11:53.953Z
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:11:53.953Z
Learning: In the Flowbite Svelte library's MultiInput component, the 'inputInvalid' property should be exported and passed to the Wrapper component to properly style the component's ring with red color when validation fails, similar to how the Input component handles validation states.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • find-imports.mjs
📚 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:

  • find-imports.mjs
📚 Learning: 2026-01-01T13:12:34.868Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.

Applied to files:

  • find-imports.mjs
🔇 Additional comments (23)
src/lib/typography/img/theme.ts (1)

7-47: LGTM!

The slot rename from base to image is applied consistently across all variant definitions (size, effect, align). This semantic naming improves clarity and aligns with the broader PR objective of standardizing slot names across components.

src/lib/typography/img/Img.svelte (2)

11-18: LGTM!

The getTheme("img") is correctly placed inside $derived() ensuring reactivity to theme changes. The destructuring with caption aliased to figureCaption appropriately avoids the naming conflict with the component's caption prop. Based on learnings, this follows the recommended pattern for reactive theme usage.


21-32: LGTM!

The data-scope="img" and data-part attributes are correctly applied to the figure structure:

  • <figure> gets data-scope="img" and data-part="figure"
  • Nested <img> gets data-part="image" (scope inherited from parent)
  • <figcaption> gets data-part="caption"

This provides proper hooks for testing and theming.

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

6-9: No changes needed—semantic color props are fully supported.

The migration from explicit color names to semantic tokens ("success", "warning", "danger") is correct. The Checkbox component's theme explicitly defines these color variants with appropriate styling (lines 20-28 of the theme configuration). The "Brand" checkbox without a color prop correctly demonstrates the default behavior.

package.json (2)

177-182: LGTM! Development export improves developer experience.

Adding the development condition for the main export allows Vite to resolve source TypeScript files directly during development, enabling instant HMR without rebuilding. The condition order is correct, and the fallback to dist/index.js is preserved for production.


183-188: LGTM! Source paths verified.

The types export follows the same pattern as the main export, providing development-time access to source files. Both src/lib/index.ts and src/lib/types.ts exist at the specified locations. The dist outputs (dist/types.d.ts and dist/types.js) will be generated during the build process.

src/routes/layout.css (1)

11-21: The suggested custom properties do not exist in this file.

The review's recommended refactor references --color-gray-900, --color-gray-800, and --color-gray-50, but these custom properties are not defined in the @theme block of layout.css. The only color custom properties defined are --color-primary-*, --color-secondary-*, and --color-white. The hardcoded hex values appear necessary given the current set of available custom properties.

If consistency with custom properties is desired, consider adding gray color variables to the @theme block to replace the hardcoded values. Otherwise, the !important flags here may be necessary to override Flowbite plugin styles, depending on where .cw-base and .cw-inner are applied in the page.

Likely an incorrect or invalid review comment.

find-imports.mjs (2)

1-8: LGTM!

The ESM setup and __dirname workaround are correct and follow standard Node.js patterns for ES modules.


22-26: LGTM!

The directory exclusion logic correctly skips both hidden directories and the defined exclusion list during recursive traversal.

src/lib/forms/input-field/theme.ts (1)

11-16: LGTM! Semantic slot naming improves clarity.

The slot renames (leftleftAddon, rightrightAddon, closecloseButton, combocomboList, comboItemoption) enhance readability and better describe each part's purpose. The naming is consistent with the data-part attributes added throughout the component.

src/lib/forms/input-field/Input.svelte (2)

250-277: LGTM! Data attributes enhance component introspection.

The addition of data-scope="input" and consistent data-part attributes (base, left-addon, right-addon, combo-list, option) follows best practices for component part identification. The kebab-case convention for data attributes aligns well with HTML standards while the code uses camelCase for JavaScript properties.


296-299: LGTM! Input and close button data attributes complete the pattern.

The data-part="input" and data-part="close-button" attributes maintain consistency with the data attribute pattern applied to other component parts.

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

16-16: LGTM: Default color updated to "brand".

The default checkbox color change from "primary" to "brand" aligns with the design token updates across the codebase.

src/lib/extend/button-toggle/ButtonToggle.svelte (1)

43-68: LGTM: Slot rename and data attributes correctly implemented.

The changes correctly implement the theme refactor:

  • Destructuring updated to use label instead of text (line 43, 68), matching the theme.ts changes.
  • Semantic data-scope and data-part attributes added consistently (lines 52, 60, 65, 68) for improved testability and styling hooks.
  • Theme reactivity properly handled via $derived expression (line 14).

All changes align with the broader slot naming and data attribute standardization across the codebase.

src/lib/extend/button-toggle/ButtonToggleGroup.svelte (1)

112-112: LGTM: Data attribute added for semantic scoping.

The data-scope="button-toggle-group" attribute addition aligns with the standardized data attribute pattern across the codebase, providing a consistent hook for styling and testing without changing behavior.

src/lib/extend/button-toggle/theme.ts (1)

23-29: Slot rename from text to label has been properly updated.

The theme.ts file correctly defines the label slot (lines 23, 29), and ButtonToggle.svelte properly destructures and applies it throughout the component, including in theme styling (theme?.label) and slot rendering. No remaining references to the old text slot name found.

src/lib/extend/command-palette/theme.ts (1)

13-13: All references to the renamed slot have been properly updated.

The slot rename from empty to emptyState is complete. The CommandPalette component correctly uses emptyState at line 177 in CommandPalette.svelte (with styles.emptyState(), theme?.emptyState, and classes?.emptyState), and no legacy references to the old empty slot remain in the codebase.

src/routes/docs-examples/extend/clipboard-manager/+page.svelte (1)

3-3: LGTM! Syntax highlighting stylesheet added.

Adding the GitHub Dark theme for highlight.js is appropriate for code snippet styling in the documentation.

SLOT_NAMING_REVIEW.md (1)

1-174: LGTM! Excellent documentation of slot naming changes.

This documentation clearly explains the rationale behind the slot naming updates and provides concrete examples of the changes. The alignment with design system principles is well-articulated.

src/lib/extend/clipboard-manager/ClipboardManager.svelte (1)

283-496: LGTM! Comprehensive data-scope and data-part attribute implementation.

The addition of data-scope and data-part attributes throughout the component follows best practices for semantic markup and provides stable selectors for styling and testing. The slot name updates (emptyTextemptyMessage, emptySubtextemptyDescription, addToClipboardaddButton, clearAllclearButton) are consistently applied across all template references.

The implementation correctly:

  • Adds data-scope="clipboard-manager" to root elements
  • Uses kebab-case for all data-part values
  • Maintains consistency with the theme.ts slot definitions
  • Preserves existing functionality while improving semantic structure

Note: The visual styling depends on theme.ts, which currently uses rounded-base (an invalid Tailwind v4 class). See the review comment on theme.ts for details.

COMPLETE_REVIEW_SUMMARY.md (1)

1-295: LGTM! Comprehensive documentation of the design system refactor.

This documentation provides an excellent overview of all changes, including:

  • Detailed data attribute mappings for each component
  • Practical CSS selector examples
  • Clear explanation of benefits and design system alignment
  • Complete file listing and change quantification

This will serve as a valuable reference for the team and future contributors.

src/lib/extend/clipboard-manager/theme.ts (2)

27-28: LGTM! Semantic slot name improvements.

The slot renaming from emptyTextemptyMessage and emptySubtextemptyDescription improves clarity and aligns with design system conventions. These names better describe the purpose of each text element.


13-56: No changes needed. rounded-base is a valid utility class provided by Flowbite's Tailwind v4 plugin. The project imports @plugin "flowbite/plugin" and defines the --radius-base: 12px CSS custom property in the theme, making rounded-base available as a standard utility throughout the codebase. This usage is correct.

Likely an incorrect or invalid review comment.

Comment on lines +10 to +11
// Directories to exclude
const EXCLUDE_DIRS = ["node_modules", ".svelte-kit", "dist", "build", ".git", "llm", "utils"];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Update the console output to match the exclusion list.

The EXCLUDE_DIRS array includes .git and utils, but the console output at Line 49 doesn't mention them. This inconsistency could confuse users about which directories are actually excluded.

🔎 Proposed fix
-console.log("Excluding: llm, node_modules, .svelte-kit, dist, build\n");
+console.log("Excluding: " + EXCLUDE_DIRS.join(", ") + "\n");

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In find-imports.mjs around lines 10-11 (EXCLUDE_DIRS) and line 49 (console
output), the console message does not reflect the full exclusion list (missing
".git" and "utils"); update the console output to match EXCLUDE_DIRS exactly by
either printing EXCLUDE_DIRS.join(', ') or otherwise including ".git" and
"utils" in the logged string so the message always mirrors the actual array
contents and remains consistent.

{@render children?.({ class: imgClass, restProps })}
{:else}
<img {...restProps} class={imgClass} />
<img data-scope="img" {...restProps} class={imgClass} />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing data-part="image" on standalone <img>.

For consistency with line 27 where the <img> inside the figure has data-part="image", the standalone <img> should also include this attribute.

🔎 Proposed fix
-    <img data-scope="img" {...restProps} class={imgClass} />
+    <img data-scope="img" data-part="image" {...restProps} class={imgClass} />
📝 Committable suggestion

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

Suggested change
<img data-scope="img" {...restProps} class={imgClass} />
<img data-scope="img" data-part="image" {...restProps} class={imgClass} />
🤖 Prompt for AI Agents
In src/lib/typography/img/Img.svelte around line 36, the standalone <img>
element is missing the data-part="image" attribute which breaks consistency with
the figure-contained image; add data-part="image" to the img tag (preserving
existing {...restProps} and class={imgClass}) so both image usages expose the
same part attribute for styling/selection.

Copy link
Copy Markdown
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

📜 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 71dea4c and cbe3b5a.

📒 Files selected for processing (14)
  • src/lib/extend/clipboard-manager/ClipboardManager.svelte
  • src/lib/extend/scroll-spy/ScrollSpy.svelte
  • src/lib/extend/scroll-spy/theme.ts
  • src/lib/extend/split-pane/Divider.svelte
  • src/lib/extend/split-pane/Pane.svelte
  • src/lib/extend/split-pane/SplitPane.svelte
  • src/lib/extend/split-pane/index.ts
  • src/lib/extend/split-pane/theme.ts
  • src/lib/extend/step-indicator/StepIndicator.svelte
  • src/lib/extend/step-indicator/theme.ts
  • src/lib/theme-provider/themes.ts
  • src/routes/docs-examples/extend/clipboard-manager/+page.svelte
  • src/routes/layout.css
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
✅ Files skipped from review due to trivial changes (2)
  • src/lib/extend/split-pane/Divider.svelte
  • src/lib/extend/split-pane/Pane.svelte
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/lib/extend/clipboard-manager/ClipboardManager.svelte
  • src/routes/layout.css
  • src/routes/docs-examples/extend/clipboard-manager/+page.svelte
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • src/lib/extend/scroll-spy/theme.ts
  • src/lib/extend/split-pane/SplitPane.svelte
  • src/lib/extend/step-indicator/theme.ts
  • src/lib/theme-provider/themes.ts
  • src/lib/extend/split-pane/index.ts
  • src/lib/extend/scroll-spy/ScrollSpy.svelte
  • src/lib/extend/step-indicator/StepIndicator.svelte
  • src/lib/extend/split-pane/theme.ts
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
🧠 Learnings (5)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
📚 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/extend/split-pane/SplitPane.svelte
  • src/lib/extend/scroll-spy/ScrollSpy.svelte
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

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

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

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

// use $themeDerived in template/component

Applied to files:

  • src/lib/extend/split-pane/SplitPane.svelte
  • src/lib/extend/scroll-spy/ScrollSpy.svelte
  • src/lib/extend/step-indicator/StepIndicator.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
📚 Learning: 2025-12-28T05:16:44.735Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-12-28T05:16:44.735Z
Learning: In flowbite-svelte with Svelte 5, props are not reactive by default. To make prop values reactive (so they update when the prop changes), they must be wrapped with `$derived()`. For example, `const styling = $derived(classes)` is necessary—not redundant—to ensure `styling` reacts to changes in the `classes` prop.

Applied to files:

  • src/routes/layouts/FlowbiteSvelteLayout.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: 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
🔇 Additional comments (14)
src/routes/layouts/FlowbiteSvelteLayout.svelte (2)

45-45: LGTM! Correct adoption of the new content slot key.

The migration from root padding classes to classes={{ content: "py-0" }} aligns with the navbar theming refactor where the content slot is now exposed for inner content styling.


59-63: LGTM! Correct migration from ul to list slot key.

The slot key rename from ul to list aligns with the NavUl theme refactor. The styling classes are preserved correctly.

src/lib/extend/scroll-spy/ScrollSpy.svelte (2)

41-41: LGTM! Theme slot usage correctly updated.

The destructuring and usage of item properly reflects the slot key rename in theme.ts. The implementation maintains type safety through the scrollspy() variant call.

Also applies to: 56-56


235-243: LGTM! Data attributes improve component introspection.

The addition of data-scope and data-part attributes provides useful hooks for testing, debugging, and telemetry without affecting functionality. The naming is consistent with the slot keys and follows the pattern established across the broader PR refactor.

src/lib/extend/scroll-spy/theme.ts (1)

13-13: Breaking change implementation verified: slot rename from li to item is complete.

The slot key rename has been properly applied across all integration points. The theme definition uses the new item key, the ScrollSpy.svelte component correctly destructures and references item, and the type system automatically exposes the updated slot through the Classes<T> utility type. No remnants of the old li slot key exist in the codebase.

src/lib/extend/split-pane/SplitPane.svelte (1)

380-380: LGTM: Data attributes added for improved testing and styling hooks.

The addition of data-scope="split-pane" and data-part="base" follows the consistent pattern being applied across components in this PR. The theme usage at line 43 correctly uses $derived(getTheme("splitpane")) to support reactive theme changes.

src/lib/extend/split-pane/index.ts (1)

4-4: LGTM: Export removal aligns with theme refactor.

This change is consistent with the removal of dividerHitArea from themes.ts (line 83) and the refactoring of the divider theme to use a slot-based structure with slots.base and slots.hitArea.

Note: This breaking change is already covered by the verification script in the themes.ts review.

src/lib/extend/split-pane/theme.ts (1)

24-53: LGTM: Divider theme refactored to slot-based structure.

The divider theme has been refactored from a flat structure to a slot-based structure with slots.base and slots.hitArea. This consolidates the previously separate dividerHitArea export into the main divider theme, improving consistency.

Key changes:

  • divider now returns an object with base() and hitArea() methods
  • Variants are now per-slot (e.g., direction.horizontal.base and direction.horizontal.hitArea)
  • The separate dividerHitArea export has been removed

This is a breaking change for consumers accessing divider styling, but aligns with the broader theme architecture improvements in this PR.

Note: The verification script in the themes.ts review will confirm that Divider.svelte and other consumers have been updated to use the new structure.

src/lib/theme-provider/themes.ts (1)

83-83: Verify dividerHitArea removal doesn't break consumers.

The dividerHitArea export has been removed from the split-pane theme. Ensure that all usages have been migrated to the new divider slot-based structure with slots.hitArea.

src/lib/extend/step-indicator/theme.ts (1)

19-19: No action required. The slot renaming from incomplete to incompleteStep has been properly implemented. All internal consumers in StepIndicator.svelte reference the new slot name correctly (destructuring at line 25, usage at lines 100 and 124). The getStepStateClasses helper correctly maintains data-[state=incomplete] for the HTML data attribute, which is distinct from the slot name. No references to the old slot name remain in the codebase.

src/lib/extend/step-indicator/StepIndicator.svelte (4)

23-23: LGTM! Theme setup follows best practices.

The theme is correctly wrapped in $derived(), ensuring that the component reacts to dynamic theme changes from ThemeProvider.

Based on learnings, this is the correct pattern for reactive theme support in Flowbite-Svelte.


59-64: LGTM! Data attributes follow the established pattern.

The addition of data-scope="step-indicator" on the root element and data-part attributes on sub-elements follows the pattern applied across the codebase. These metadata attributes facilitate testing and tooling without affecting functionality.


71-124: LGTM! Step rendering consistently implements data attributes.

The changes correctly:

  • Use incompleteStep consistently throughout both clickable and non-clickable branches
  • Add data-part attributes to all major UI parts (wrapper, step, glow, incomplete-step)
  • Include data-state attributes that accurately reflect step state (current, completed, incomplete)
  • Preserve existing accessibility attributes (aria-current, aria-label)

The metadata additions are well-structured and don't affect component behavior.


25-25: The type definitions are correctly updated through the tailwind-variants slot definition.

The incompleteStep slot is properly defined in theme.ts (line 19), and StepIndicatorTheme automatically includes it since it's derived from keyof typeof stepIndicator.slots. There is no StepIndicatorProps type in this codebase—the relevant types are StepIndicatorTheme and StepIndicatorVariants, both of which are correctly updated.

The data-[state=incomplete] value on line 110 of theme.ts is intentional and correct; it represents a state value for conditional styling, distinct from the slot name incompleteStep.

Copy link
Copy Markdown
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 (2)
src/lib/navbar/Navbar.svelte (1)

42-42: Consider removing redundant clsx() call.

The clsx(className) call is redundant since className is already a string from the destructured props. You can simplify this to base({ class: className }).

🔎 Proposed simplification
-<nav data-scope="navbar" data-part="base" class={base({ class: clsx(className) })} bind:this={navbarElement}>
+<nav data-scope="navbar" data-part="base" class={base({ class: className })} bind:this={navbarElement}>
src/routes/layouts/FlowbiteSvelteLayout.svelte (1)

62-62: Add space after colon for consistent formatting.

Minor formatting inconsistency: the item property is missing a space after the colon. While this works, consistent spacing improves readability.

🔎 Proposed formatting fix
-      classes={{ list: "flex flex-col lg:flex-row lg:my-0 text-sm font-medium text-gray-900 dark:text-gray-300 gap-1 p-3", item:"ps-0 pe-0 lg:ps-2 lg:pe-2" }}
+      classes={{ list: "flex flex-col lg:flex-row lg:my-0 text-sm font-medium text-gray-900 dark:text-gray-300 gap-1 p-3", item: "ps-0 pe-0 lg:ps-2 lg:pe-2" }}
📜 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 cbe3b5a and f2e3da3.

📒 Files selected for processing (8)
  • questions.md
  • src/lib/accordion/Accordion.svelte
  • src/lib/navbar/NavLi.svelte
  • src/lib/navbar/NavUl.svelte
  • src/lib/navbar/Navbar.svelte
  • src/lib/types.ts
  • src/routes/admin-dashboard/(sidebar)/Frame.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
🚧 Files skipped from review as they are similar to previous changes (4)
  • questions.md
  • src/lib/types.ts
  • src/lib/navbar/NavLi.svelte
  • src/lib/navbar/NavUl.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/accordion/Accordion.svelte
  • src/routes/admin-dashboard/(sidebar)/Frame.svelte
  • src/lib/navbar/Navbar.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
🧠 Learnings (4)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
📚 Learning: 2025-12-28T05:16:44.735Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-12-28T05:16:44.735Z
Learning: In flowbite-svelte with Svelte 5, props are not reactive by default. To make prop values reactive (so they update when the prop changes), they must be wrapped with `$derived()`. For example, `const styling = $derived(classes)` is necessary—not redundant—to ensure `styling` reacts to changes in the `classes` prop.

Applied to files:

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

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

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

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

// use $themeDerived in template/component

Applied to files:

  • src/lib/accordion/Accordion.svelte
  • src/routes/admin-dashboard/(sidebar)/Frame.svelte
  • src/lib/navbar/Navbar.svelte
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
📚 Learning: 2025-11-25T07:26:46.504Z
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: 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
🔇 Additional comments (12)
src/routes/admin-dashboard/(sidebar)/Frame.svelte (1)

17-17: The key rename from navbarUl to navUl is complete and consistent across all three color dictionaries (lines 17, 85, 106).

No stale references to the old navbarUl key remain in the codebase. The FrameColor type, which is derived from bgColors keys, automatically reflects this change and will correctly exclude navbarUl while including navUl.

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

43-47: New content wrapper aligns with theme refactoring.

The introduction of a data-part="content" wrapper div correctly separates the base navigation element from the content region. This structural change aligns with the broader PR objectives to standardize theme slots and data attributes across components.


14-14: No changes needed — navbar() correctly returns the content property.

The navbar theme function in src/lib/navbar/theme.ts defines slots for base, content, and container (lines 14-18), which matches the destructuring on line 14 of Navbar.svelte. The implementation is correct.

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

45-45: Correct usage of the new content classes prop.

The classes={{ content: "py-0" }} prop correctly targets the new content wrapper introduced in the Navbar component refactoring. This aligns with the updated public API.


64-69: Good consolidation of NavLi styling.

Moving the per-item styling from individual NavLi elements to the parent NavUl's item key (Line 62) is a cleaner pattern that reduces duplication and improves maintainability.

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

8-8: LGTM!

The untrack import is correctly added and properly used on line 35 to capture the initial value of the multiple prop.


10-10: Breaking change: Verify migration documentation.

The removal of activeClass and inactiveClass props is a breaking change for existing users. Ensure migration documentation is updated to guide users on how to style accordion items with the new classes prop structure.


12-12: LGTM!

Theme derivation correctly uses $derived() to ensure reactivity when themes change dynamically.


15-31: LGTM!

The reactive context implementation using getters correctly ensures child components can access the latest prop values. This follows Svelte 5 patterns for reactive context sharing.


37-37: LGTM!

The base class derivation correctly combines the theme classes with the user-provided className and will reactively update when any dependency changes.


40-42: LGTM!

The addition of data-scope="accordion" and data-part="base" attributes aligns with the PR objectives and provides structured data attributes for styling and testing purposes.


33-35: The multiple prop selection mode is intentionally static and set at initialization.

The untrack(() => multiple) captures the initial value to determine whether the selection context enforces single or multiple selection mode. This design prevents runtime mode switching, which is intentional—the accordion's selection behavior is set once during initialization and does not respond to prop changes afterward. Tests confirm this behavior is working as designed.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/lib/extend/tags/Tags.svelte (1)

181-219: Consider renaming dropdown item's data-part for clarity.

Lines 174 and 199 both use data-part="item", which could be ambiguous:

  • Line 174: Tag item (styled with the item theme slot)
  • Line 199: Dropdown list item (structural wrapper, not styled with item slot)

The dropdown list item is purely structural and contains a button with data-part="option" that receives the actual styling via the option theme slot. Consider using a more distinctive name like data-part="suggestion-item" or data-part="dropdown-item" for line 199 to avoid confusion in testing and styling contexts.

🔎 Proposed change for clarity
-            <li data-part="item">
+            <li data-part="suggestion-item">
📜 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 f2e3da3 and 92938d6.

📒 Files selected for processing (7)
  • src/lib/extend/tags/Tags.svelte
  • src/lib/extend/tags/theme.ts
  • src/lib/extend/tour/Tour.svelte
  • src/lib/extend/tour/theme.ts
  • src/lib/navbar/NavLi.svelte
  • src/lib/types.ts
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/routes/layouts/FlowbiteSvelteLayout.svelte
  • src/lib/navbar/NavLi.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/extend/tour/theme.ts
  • src/lib/types.ts
  • src/lib/extend/tour/Tour.svelte
  • src/lib/extend/tags/theme.ts
  • src/lib/extend/tags/Tags.svelte
🧠 Learnings (4)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1465
File: src/lib/forms/Timepicker.svelte:105-116
Timestamp: 2024-10-18T09:38:03.879Z
Learning: In `Timepicker.svelte`, the `Dropdown` opens as intended and is used exclusively with the 'dropdown' and 'timerange-dropdown' Timepicker types.

Applied to files:

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

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

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

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

// use $themeDerived in template/component

Applied to files:

  • src/lib/extend/tour/Tour.svelte
  • src/lib/extend/tags/Tags.svelte
🧬 Code graph analysis (1)
src/lib/types.ts (3)
src/lib/dropdown/theme.ts (1)
  • DropdownItemVariants (16-16)
src/lib/forms/dropzone/theme.ts (1)
  • DropzoneVariants (4-4)
src/lib/navbar/theme.ts (1)
  • NavLiVariants (11-11)
🔇 Additional comments (11)
src/lib/extend/tags/theme.ts (1)

8-20: Theme slot refactoring looks good.

The renaming of slots from generic names (tagitem, spanlabel) to semantic names improves clarity, and the addition of inputWrapper and option slots enables finer-grained theming control. This aligns with the broader pattern across the codebase.

Note: This is a breaking change for users who have customized the tags theme using the old slot names, but this appears intentional for the v2 refactoring.

src/lib/extend/tags/Tags.svelte (3)

31-31: Slot renaming and new slots integrated correctly.

The destructuring properly uses the renamed slots (item: itemCls, label: labelCls) and incorporates the new inputWrapper and option slots. The component correctly derives these from the theme.


150-163: Data-part attributes added consistently for helper messages.

The addition of data-part attributes to info, warning, and error messages provides proper testing hooks and follows the pattern established across the component.


165-179: Data attributes properly structured for tag items.

The data-scope="tags" on the base container and data-part attributes on child elements (item, label, close-button) provide clear structural hooks for testing and styling. The use of renamed itemCls and labelCls is consistent with the theme updates.

src/lib/extend/tour/Tour.svelte (2)

26-26: Correct usage of reactive theme with $derived().

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

Based on learnings, this follows the established pattern for reactive theme support in Flowbite-Svelte components.


212-271: Well-structured implementation of data-scope and data-part attributes.

The addition of data-scope="tour" at the root wrapper and consistent data-part attributes throughout the component template enables targeted styling and testing without affecting functionality. The semantic naming (overlay, highlight, tooltip, arrow, content, title, description, progress-container, progress-dot, actions, button, navigation) clearly identifies each UI region.

All accessibility attributes, event handlers, and theme bindings are properly maintained.

src/lib/types.ts (5)

43-43: LGTM! Variant imports align with theme refactoring.

The new variant imports (DropdownItemVariants, NavLiVariants, DropzoneVariants) follow a consistent pattern of extracting variant types from their respective theme files and are properly used in their corresponding Props interfaces.

Also applies to: 50-50, 80-80


217-223: Documentation improvement enhances clarity.

The added comment clarifies that these classes are for AccordionItem, improving developer understanding of the props relationship.


666-666: Good refactoring: using variant composition.

Both DropdownItemProps and DropzoneProps now properly extend their respective variant types, replacing internal class blocks with composed variants. This improves maintainability and type consistency.

Also applies to: 751-751


1081-1081: Navbar component implementations correctly consume the expanded styling API.

The type definitions and component implementations are properly aligned:

  • NavUl.svelte destructures the classes prop and sets navState.activeClass, navState.nonActiveClass, and navState.itemClass via an effect, correctly using all five granular styling points
  • NavLi.svelte destructures activeClass and nonActiveClass props, falling back to context values from navState, and correctly combines all styling sources (local props, context, theme, and styling?.item)
  • The pattern allows NavUl to establish defaults while NavLi can override them, providing flexible composition

No action required.


1986-1986: Arrow component correctly handles refactored props.

The implementation fully supports the changes:

  1. PopperProps.arrowClass typed as ClassValue - Arrow receives it as the class prop (line 294 of Popper.svelte)
  2. ArrowProps extending HTMLAttributes<HTMLDivElement> - Arrow.svelte correctly destructures class: className and applies it to the div element (lines 6, 46)

Both changes are backward compatible and properly implemented.

export interface MegaMenuProps extends MegaMenuVariants, Omit<PopperProps, "children"> {
children: Snippet<[{ item: LinkType; index: number }]>;
extra?: Snippet;
addon?: Snippet;
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Jan 2, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the actual code at line 1056 in src/lib/types.ts
sed -n '1040,1075p' src/lib/types.ts

Repository: themesberg/flowbite-svelte

Length of output: 1005


🏁 Script executed:

# Search for any remaining usages of 'extra' in MegaMenu context
rg -n 'extra' --type=ts --type=tsx --type=svelte -g '*mega*' -g '*Mega*'

Repository: themesberg/flowbite-svelte

Length of output: 97


🏁 Script executed:

# Also check for 'extra' in prop definitions or type definitions
rg -n "extra\s*[?:=]" --type=ts --type=tsx --type=svelte

Repository: themesberg/flowbite-svelte

Length of output: 97


🏁 Script executed:

# Look for the old 'extra' prop in component implementations
rg -n "extra\s*[,}]" --type=ts --type=tsx --type=svelte

Repository: themesberg/flowbite-svelte

Length of output: 97


🏁 Script executed:

# Search in svelte files specifically for props or export statements with 'extra'
rg -n "export.*extra|let.*extra" --type=svelte

Repository: themesberg/flowbite-svelte

Length of output: 100


🏁 Script executed:

# Search for 'extra' without file type restrictions
rg -n 'extra' --max-count=20

Repository: themesberg/flowbite-svelte

Length of output: 29146


🏁 Script executed:

# Find MegaMenu component files
fd -e svelte -e ts -e js 'mega' -i

Repository: themesberg/flowbite-svelte

Length of output: 285


🏁 Script executed:

# Look for changelog or breaking changes documentation
fd -e md '(CHANGELOG|BREAKING|CHANGES|RELEASE)' -i

Repository: themesberg/flowbite-svelte

Length of output: 82


🏁 Script executed:

# Search in the actual MegaMenu component for prop definitions
fd mega -i | head -20

Repository: themesberg/flowbite-svelte

Length of output: 574


🏁 Script executed:

# Read the MegaMenu component
cat -n src/lib/mega-menu/MegaMenu.svelte | head -100

Repository: themesberg/flowbite-svelte

Length of output: 1965


🏁 Script executed:

# Check the component-data JSON file
cat -n src/routes/component-data/MegaMenu.json

Repository: themesberg/flowbite-svelte

Length of output: 529


🏁 Script executed:

# Check documentation references to extra/addon
grep -n "addon\|extra" src/routes/docs/components/mega-menu.md | head -20

Repository: themesberg/flowbite-svelte

Length of output: 52


🏁 Script executed:

# Check the test file
cat -n src/tests/mega-menu/mega-menu.test.ts | head -100

Repository: themesberg/flowbite-svelte

Length of output: 3589


🏁 Script executed:

# Check CHANGELOG for breaking changes
cat -n CHANGELOG.md | head -50

Repository: themesberg/flowbite-svelte

Length of output: 1559


🏁 Script executed:

# Check the full-mega-menu test component to see which prop name it uses
cat -n src/tests/mega-menu/full-mega-menu.test.svelte

Repository: themesberg/flowbite-svelte

Length of output: 614


🏁 Script executed:

# Double-check documentation files for extra vs addon references
grep -A2 -B2 "extra\|addon" src/routes/docs/components/mega-menu.md | head -30

Repository: themesberg/flowbite-svelte

Length of output: 52


🏁 Script executed:

# Check LLM docs component file
grep -A2 -B2 "extra\|addon" src/routes/llm/components/mega-menu.md | head -30

Repository: themesberg/flowbite-svelte

Length of output: 812


Breaking change: extra field renamed to addon — but documentation is out of sync.

The rename in MegaMenuProps is confirmed as a breaking change. The component code and tests correctly use addon, but documentation remains inconsistent:

  • src/routes/component-data/MegaMenu.json still lists "extra" instead of "addon"
  • src/routes/docs/components/mega-menu.md and src/routes/llm/components/mega-menu.md reference {#snippet extra()} in examples
  • No breaking change note in CHANGELOG.md

Update the documentation metadata and examples to reflect addon, and add a breaking change entry to the changelog to notify users upgrading to this version.

🤖 Prompt for AI Agents
In src/lib/types.ts around line 1056 the MegaMenuProps field was renamed from
extra to addon; update docs and changelog to match: edit
src/routes/component-data/MegaMenu.json to replace the "extra" key with "addon"
(and keep same snippet value), update src/routes/docs/components/mega-menu.md
and src/routes/llm/components/mega-menu.md to change any `{#snippet extra()}`
usages to `{#snippet addon()}` in examples, and add a brief breaking-change
entry to CHANGELOG.md noting the rename from extra → addon and migration
guidance for users.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Since this will be major change, ignore this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@shinokada, understood! I'll ignore this breaking change. Since you're aware it's a major change, I won't pursue documentation updates or changelog entries for the extraaddon rename in MegaMenuProps. You can handle it as part of your overall major version release strategy.


🧠 Learnings used
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
questions.md (1)

11-44: Support needed: Update NavLi type definition to include item in classes.

The error message on line 27 correctly identifies the root issue: the type definition for NavLi's classes parameter does not include an item property, but the code attempts to pass one (line 36).

To resolve this:

  1. Update NavLi.svelte's classes type to accept an item property (in addition to the existing active and nonActive).
  2. Apply the item class to the rendered <li> or relevant container element in NavLi.svelte.
  3. Ensure the type exports from src/lib/navbar/theme.ts and src/lib/navbar/index.ts reflect this change.

The learnings indicate that you're using context patterns successfully elsewhere; the same pattern should work here once the type definition is updated to match the intent shown in line 36.

Would you like me to:

  1. Generate the required changes to NavLi.svelte to accept and apply the item class?
  2. Update the corresponding type definitions in theme.ts?
  3. Verify that the context flow from NavUl → NavLi is correctly wired?

I can also help verify the changes against the existing test files (e.g., src/tests/device-mockups/ios-with-classes.test.svelte) to ensure consistency with the broader design-system refactor.

📜 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 92938d6 and 5801a57.

📒 Files selected for processing (7)
  • design-system-guide.md
  • questions.md
  • src/lib/extend/kanban/KanbanBoard.svelte
  • src/lib/extend/kanban/KanbanCard.svelte
  • src/lib/extend/kanban/theme.ts
  • src/lib/extend/virtual-masonry/VirtualMasonry.svelte
  • src/lib/extend/virtual-masonry/theme.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/extend/virtual-masonry/VirtualMasonry.svelte
  • src/lib/extend/kanban/KanbanBoard.svelte
  • src/lib/extend/virtual-masonry/theme.ts
  • src/lib/extend/kanban/KanbanCard.svelte
  • src/lib/extend/kanban/theme.ts
🧠 Learnings (11)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:28.743Z
Learning: In flowbite-svelte, when using ThemeProvider with reactive themes, `getTheme("componentName")` calls must be placed inside `$derived()` expressions (not at module scope) to ensure components react to dynamic theme changes. This pattern is intentional for reactive theming support.
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T12:47:33.307Z
Learning: In the Flowbite Svelte library's composite form components like MultiInput, when implementing focus styles, ensure both the container (with focus-within) and the inner input element (with direct focus) have dynamic styling based on the validation state. The input element needs its own focus styles that change to red when inputInvalid=true.
📚 Learning: 2025-12-16T13:21:19.575Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:19.575Z
Learning: When using ThemeProvider with reactive themes in Flowbite-Svelte, ensure that getTheme("componentName") calls are placed inside a $derived() expression (not at module scope) so components react to dynamic theme changes. This applies broadly to Svelte components in this repo that rely on theme-derived values. For example:

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

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

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

// use $themeDerived in template/component

Applied to files:

  • src/lib/extend/virtual-masonry/VirtualMasonry.svelte
  • src/lib/extend/kanban/KanbanBoard.svelte
  • src/lib/extend/kanban/KanbanCard.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:

  • questions.md
  • design-system-guide.md
📚 Learning: 2026-01-01T13:12:34.868Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.

Applied to files:

  • questions.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} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation

Applied to files:

  • questions.md
  • design-system-guide.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:

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

Applied to files:

  • questions.md
📚 Learning: 2025-12-28T05:16:44.735Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-12-28T05:16:44.735Z
Learning: In flowbite-svelte with Svelte 5, props are not reactive by default. To make prop values reactive (so they update when the prop changes), they must be wrapped with `$derived()`. For example, `const styling = $derived(classes)` is necessary—not redundant—to ensure `styling` reacts to changes in the `classes` prop.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • design-system-guide.md
🔇 Additional comments (18)
design-system-guide.md (3)

78-87: The list and item entries are actively used across multiple components and appropriately documented.

Verification confirms these additions are used throughout the codebase: KanbanBoard, Tags, ScrollSpy, CommandPalette, ClipboardManager, timeline components, Stepper variants, Navbar, Dropdown, and MultiSelect all include data-part="list" or data-part="item". The documentation additions align correctly with actual component implementation.


92-99: close-button entry is correctly documented.

The close-button data-part is implemented consistently across the codebase. The CloseButton component accepts it as a prop via restProps, and multiple components (Input, Fileupload, FloatingLabelInput, Tags, and Drawer) have been updated to pass data-part="close-button" consistently. The documentation entry accurately reflects the implementation.


13-13: The single data-scope guideline is already being correctly enforced in practice.

Examination of the component implementations shows the guideline is being consistently applied. Spinner.svelte, ClipboardManager.svelte, and ToolbarButton.svelte all properly use multiple data-scope attributes only within conditional rendering blocks (if-else statements), exactly as specified in the design system documentation. No validation script is needed—the guideline is already being followed.

Likely an incorrect or invalid review comment.

src/lib/extend/virtual-masonry/VirtualMasonry.svelte (4)

22-23: LGTM! Proper use of $derived() for reactive theming.

The getTheme() call is correctly placed inside $derived(), ensuring the component reacts to dynamic theme changes. This follows the established pattern for ThemeProvider integration.


30-30: LGTM! Clear destructuring with semantic renaming.

The item:itemPart rename improves clarity by distinguishing the theme slot function from the data items. The reactive destructuring properly tracks theme changes.


149-153: LGTM! Class bindings properly updated for new slot structure.

The class bindings correctly reference the renamed slots (base, spacer, content) and properly merge theme classes with custom styling. The pattern is consistent throughout.


159-159: LGTM! Proper usage of itemPart slot function.

The class binding correctly uses the renamed itemPart function while referencing theme?.item, which matches the actual theme slot name. Implementation is consistent with the component's theming pattern.

src/lib/extend/virtual-masonry/theme.ts (1)

6-6: VirtualMasonry slot rename is a breaking API change; verify external consumer impact.

This public API component (exported from lib/index.ts) changes the container slot to base. Any external consumers using classes?.container to override styles will break. No internal codebase usages of the old slot name were found, but external packages depending on this API will require updates.

src/lib/extend/kanban/KanbanCard.svelte (3)

7-12: LGTM! Proper reactive prop handling and conflict avoidance.

The use of class:className aliasing, $derived(classes) for reactivity, and destructuring with renamed values (base: basePart, etc.) correctly follows Svelte 5 patterns and avoids naming conflicts with props.


25-27: LGTM! Consistent data attribute implementation.

The data-scope="kanban-card" and data-part="base" attributes correctly identify the component and its root element, and basePart properly combines the theme, className, and isDragging variant.


29-46: LGTM! Consistent part-based styling throughout.

All elements (title, description, tags, tag) correctly use their respective part functions with data-part attributes that match the theme slot names, and consistently apply the clsx(theme?.X, styling?.X) pattern.

src/lib/extend/kanban/KanbanBoard.svelte (4)

18-26: LGTM! Proper reactive patterns for props and theme.

The use of $derived(classes) and $derived(getTheme("kanbanBoard")) correctly follows Svelte 5 reactivity patterns, ensuring the component reacts to prop and theme changes.


78-89: LGTM! Correct data attributes and variant handling.

The root element properly uses data-scope="kanban-board" and data-part="base", and the column element correctly applies the isDragOver variant with consistent class merging.


98-98: LGTM! Consistent button part implementation.

The button element correctly uses data-part="button" matching the theme slot, with proper class merging via clsx(theme?.button, styling?.button).


94-94: No action needed. The removal of the classes prop from KanbanCard is correct. The board's classes object contains styling only for board-level elements (column, title, list, button), not card-level elements. Card styling is properly handled through cardProps, which can include a classes property if custom card styling is needed. The API change is intentional and maintains proper separation of concerns.

src/lib/extend/kanban/theme.ts (3)

7-28: LGTM! Consistent kanbanBoard theme refactor.

The slot renames (container→base, columnTitle→title, cardList→list, addButton→button) and variant adjustments (isDragging now targets base) correctly align with the component's data-part attributes and usage patterns in KanbanBoard.svelte.


30-45: LGTM! Consistent kanbanCard theme refactor.

The slot renames (card→base, cardTitle→title, cardDescription→description, cardTags→tags, cardTag→tag) and variant adjustment (isDragging now targets base) correctly align with the component's data-part attributes and usage patterns in KanbanCard.svelte.


1-45: Excellent refactor alignment across the kanban component suite.

The theme slot renames are consistent across both kanbanBoard and kanbanCard, using semantic generic names (base, title, list, button, description, tags, tag) that align with the data-part attributes in the components. The variant configurations correctly target the renamed slots, and the public API types properly reflect these changes.

Comment on lines +29 to +39
### Handling naming conflicts

When a data-part name matches a component prop, rename it while destructuring.
This prevents naming conflicts and makes it clear which value comes from the variant system.

```ts
let { title } = $props;
const { title: titlePart } = $derived(timelineItem());
```

Use a descriptive prefix that clarifies the source. (e.g., themeTitlePart, variantTitle, or titlePart)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, find and examine the design-system-guide.md file
fd design-system-guide.md -t f

Repository: themesberg/flowbite-svelte

Length of output: 92


🏁 Script executed:

# Search for components using $derived with destructuring/renaming patterns
rg '\$derived\s*\(' src/lib --type svelte -A 3 | head -50

Repository: themesberg/flowbite-svelte

Length of output: 100


🏁 Script executed:

# Also search for data-part usage to understand the pattern better
rg 'data-part' src/lib --type svelte -B 2 -A 2 | head -40

Repository: themesberg/flowbite-svelte

Length of output: 100


🏁 Script executed:

# Read the design-system-guide.md file to verify the snippet
cat -n design-system-guide.md | sed -n '20,50p'

Repository: themesberg/flowbite-svelte

Length of output: 1246


🏁 Script executed:

# Search for $derived patterns in .svelte files without type flag
rg '\$derived\s*\(' --glob='*.svelte' -A 3 | head -60

Repository: themesberg/flowbite-svelte

Length of output: 3915


🏁 Script executed:

# Search for data-part patterns in components
rg 'data-part' --glob='*.svelte' -B 1 -A 2 | head -50

Repository: themesberg/flowbite-svelte

Length of output: 4059


🏁 Script executed:

# Search for timelineItem function that's used in the guide example
rg 'timelineItem' --glob='*.svelte' --glob='*.ts' --glob='*.js'

Repository: themesberg/flowbite-svelte

Length of output: 876


🏁 Script executed:

# Search for Timeline component and similar patterns with props and data-part
rg -A 10 'data-part.*title' --glob='*.svelte' | head -40

Repository: themesberg/flowbite-svelte

Length of output: 3215


🏁 Script executed:

# Look for component files that might have title prop and data-part
fd -e svelte | xargs grep -l 'title.*prop' | xargs grep -l 'data-part' | head -10

Repository: themesberg/flowbite-svelte

Length of output: 411


🏁 Script executed:

# Examine the full TimelineItem.svelte file
cat -n src/lib/timeline/TimelineItem.svelte

Repository: themesberg/flowbite-svelte

Length of output: 4566


🏁 Script executed:

# Search for the suggested naming patterns in the codebase
rg 'titlePart|variantTitle|themeTitlePart' --glob='*.svelte' --glob='*.ts'

Repository: themesberg/flowbite-svelte

Length of output: 359


🏁 Script executed:

# Search more broadly for prop destructuring patterns to see actual usage
rg '\$props[^;]*title' --glob='*.svelte' -A 3 | head -50

Repository: themesberg/flowbite-svelte

Length of output: 52


Fix inconsistent prefix naming for data-part destructuring across components.

The pattern documented at lines 29-39 is correct and used in real components (e.g., TimelineItem.svelte destructures title: _title). However, component implementations don't consistently follow the suggested prefix conventions. TimelineItem.svelte uses _title (underscore prefix), while KanbanCard.svelte uses titlePart (the suggested pattern). Standardize on one of the documented naming approaches (themeTitlePart, variantTitle, or titlePart) across all components that handle data-part/prop conflicts.

🤖 Prompt for AI Agents
design-system-guide.md lines 29-39: the docs show a pattern for renaming
data-part destructures but implementations are inconsistent (some use _title,
others use titlePart); pick a single canonical prefix (e.g., titlePart), update
all components to use that prefix when destructuring data-part values (e.g.,
change TimelineItem.svelte from _title to titlePart), and update the guide text
to explicitly name the chosen convention so all future components follow the
same naming.

Copy link
Copy Markdown
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 (3)
src/lib/extend/tags/Tags.svelte (1)

197-197: Consider using a theme function for the suggestions list.

The <ul> element uses hardcoded Tailwind classes while all other elements in this component use theme functions (e.g., inputWrapper(), option()). If this is intentional to keep dropdown positioning simple, consider adding a brief comment. Otherwise, adding a list slot to the theme would maintain consistency.

src/lib/extend/virtual-masonry/VirtualMasonry.svelte (1)

22-22: Optional: Consider removing the redundant styling derivation.

The styling variable is just an alias for classes without any transformation. You could use classes directly throughout the component (e.g., classes?.spacer, classes?.content, classes?.item) to simplify the code.

🔎 Proposed simplification

Remove line 22 and update references:

-  const styling = $derived(classes);

Then update the usage sites:

-  <div data-part="spacer" class={spacer({ class: clsx(theme?.spacer, styling?.spacer) })} ...>
+  <div data-part="spacer" class={spacer({ class: clsx(theme?.spacer, classes?.spacer) })} ...>
-    <div data-part="content" class={content({ class: clsx(theme?.content, styling?.content) })}>
+    <div data-part="content" class={content({ class: clsx(theme?.content, classes?.content) })}>
-          class={itemPart({ class: clsx(theme?.item, styling?.item) })}
+          class={itemPart({ class: clsx(theme?.item, classes?.item) })}
src/lib/video/Video.svelte (1)

19-22: Simplify: Remove unnecessary $derived() wrapper.

Line 19 wraps the classes prop in $derived() without any transformation. In Svelte 5, props are already reactive signals, so this creates unnecessary overhead.

Line 20 correctly uses $derived() for getTheme() to enable reactive theme updates (per ThemeProvider best practices).

🔎 Suggested simplification
-  const styling = $derived(classes);
   const theme = $derived(getTheme("video"));
-
   const { base, source, track } = video();

Then update the references:

-  <source data-part="source" class={source({ class: clsx(theme?.source, styling?.source) })} {src} {type} />
+  <source data-part="source" class={source({ class: clsx(theme?.source, classes?.source) })} {src} {type} />
-    class={track({ class: clsx(theme?.track, styling?.track) })}
+    class={track({ class: clsx(theme?.track, classes?.track) })}

Based on learnings about ThemeProvider requiring $derived() for getTheme() calls.

📜 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 5801a57 and 3d7eed6.

📒 Files selected for processing (12)
  • src/lib/extend/tags/Tags.svelte
  • src/lib/extend/tour/theme.ts
  • src/lib/extend/virtual-list/VirtualList.svelte
  • src/lib/extend/virtual-list/index.ts
  • src/lib/extend/virtual-list/theme.ts
  • src/lib/extend/virtual-masonry/VirtualMasonry.svelte
  • src/lib/index.ts
  • src/lib/theme-provider/themes.ts
  • src/lib/types.ts
  • src/lib/utils/Arrow.svelte
  • src/lib/video/Video.svelte
  • src/lib/video/theme.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/utils/Arrow.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/extend/virtual-list/theme.ts
  • src/lib/extend/tour/theme.ts
  • src/lib/video/theme.ts
  • src/lib/index.ts
  • src/lib/types.ts
  • src/lib/extend/virtual-masonry/VirtualMasonry.svelte
  • src/lib/video/Video.svelte
  • src/lib/extend/tags/Tags.svelte
  • src/lib/extend/virtual-list/VirtualList.svelte
  • src/lib/theme-provider/themes.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
📚 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/extend/tour/theme.ts
📚 Learning: 2026-01-01T13:12:34.868Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.

Applied to files:

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

Applied to files:

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

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

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

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

// use $themeDerived in template/component

Applied to files:

  • src/lib/extend/virtual-masonry/VirtualMasonry.svelte
  • src/lib/video/Video.svelte
  • src/lib/extend/tags/Tags.svelte
  • src/lib/extend/virtual-list/VirtualList.svelte
📚 Learning: 2025-12-28T05:16:44.735Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-12-28T05:16:44.735Z
Learning: In flowbite-svelte with Svelte 5, props are not reactive by default. To make prop values reactive (so they update when the prop changes), they must be wrapped with `$derived()`. For example, `const styling = $derived(classes)` is necessary—not redundant—to ensure `styling` reacts to changes in the `classes` prop.

Applied to files:

  • src/lib/extend/virtual-list/VirtualList.svelte
🧬 Code graph analysis (1)
src/lib/types.ts (4)
src/lib/dropdown/theme.ts (1)
  • DropdownItemVariants (16-16)
src/lib/forms/dropzone/theme.ts (1)
  • DropzoneVariants (4-4)
src/lib/navbar/theme.ts (1)
  • NavLiVariants (11-11)
src/lib/video/theme.ts (1)
  • VideoVariants (4-4)
🔇 Additional comments (25)
src/lib/extend/tour/theme.ts (1)

11-11: LGTM! Border-radius consistency properly addressed.

The tooltip, content, and actions slots now use consistent border radius values (rounded-base and rounded-b-base), ensuring a cohesive visual appearance. This properly resolves the mismatch noted in the previous review.

Also applies to: 13-13, 19-19

src/lib/extend/tags/Tags.svelte (3)

31-31: Theme slot destructuring looks correct.

The aliasing of item: itemCls and label: labelCls properly avoids conflicts with reserved identifiers while maintaining alignment with the renamed theme slots (tagitem, spanlabel) described in the PR.


165-179: Data-scope and data-part attributes correctly applied.

The container and tag item structure now expose granular hooks (data-scope="tags", data-part="base", data-part="item", data-part="label", data-part="close-button") for styling and testing, aligning with the broader PR pattern.


181-219: Input wrapper and dropdown structure properly themed.

The input area and autocomplete dropdown now consistently apply data-part attributes (input-wrapper, input, list, suggestion-item, option) and use the new inputWrapper and option theme slots correctly.

src/lib/extend/virtual-masonry/VirtualMasonry.svelte (5)

23-23: Correct reactive theme pattern.

The getTheme() call is properly wrapped in $derived(), which ensures the component reacts to dynamic theme changes. This follows best practices for Flowbite-Svelte theme integration.

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


30-30: Clean theme destructuring with proper reactivity.

The destructuring pattern correctly extracts theme parts from the virtualMasonry() function and uses $derived() to ensure reactivity when the contained prop changes.


143-144: Data attributes correctly applied.

The data-scope and data-part attributes are now properly set. The typo from the previous review ("virtual-mansonry") has been fixed to "virtual-masonry", which matches the component name and maintains consistency.


149-149: Consistent theme integration pattern.

The class bindings correctly merge theme classes with custom classes using the theme part functions. The pattern is consistent across base, spacer, and content elements.

Also applies to: 152-153


159-160: Item element correctly styled with data attributes.

The item element properly uses data-part="item" and applies the itemPart theme function with merged classes, maintaining consistency with the rest of the component.

src/lib/index.ts (1)

99-99: LGTM! Export path corrected to use proper kebab-case naming.

The updated export path correctly references the kebab-case directory name and explicitly includes index.js, which aligns with standard module naming conventions.

src/lib/extend/virtual-list/VirtualList.svelte (3)

21-21: LGTM! Correct use of $derived() for prop reactivity.

The styling constant properly wraps the classes prop with $derived() to ensure reactivity in Svelte 5, as per the established pattern in this codebase.

Based on learnings: In Svelte 5, props must be wrapped with $derived() to be reactive.


33-33: LGTM! Destructuring updated to match the new theme slot names.

The destructuring correctly references the renamed slots (base, spacer, content) and aliases item to itemPart to avoid naming conflicts with the loop variable.


111-123: LGTM! Data attributes consistently applied across all parts.

The data-scope="virtual-list" and data-part attributes have been correctly added to all DOM elements (base, spacer, content, item), which aligns with the broader design system refactor mentioned in the PR objectives.

src/lib/theme-provider/themes.ts (3)

26-26: Changes already verified and addressed.

The navbarLi/navbarUl to navLi/navUl rename has been confirmed as fixed in previous review iterations.


87-87: LGTM! Import path updated to match the corrected directory structure.

The virtualList import path has been correctly updated from the old virtuallist to the new kebab-case virtual-list, maintaining consistency across the codebase.


83-83: The dividerHitArea export removal is complete with no code references.

No code in the codebase references dividerHitArea, confirming it has been safely removed from the split-pane theme exports. The current export includes only splitpane, pane, and divider.

src/lib/extend/virtual-list/theme.ts (1)

9-9: The slot refactoring from container to base has been properly implemented. The theme file correctly defines the base slot, and the VirtualList component properly destructures and applies it. No remaining references to the old container slot exist in the virtualList implementation.

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

6-12: LGTM! Clean theme structure for multi-part video component.

The three-slot structure (base, source, track) aligns with the component's DOM hierarchy. The base slot provides sensible default styling with w-full, while empty strings for source and track allow full customization through the classes prop without imposing defaults.

src/lib/types.ts (5)

43-43: LGTM! Consistent Variants import pattern.

The new Variants type imports follow the established naming convention and are properly organized by component area, supporting the props refactoring throughout this file.

Also applies to: 50-50, 77-77, 81-81, 120-120


217-224: LGTM! Well-structured classes prop for parent-to-child styling.

The nested classes property allows the Accordion parent to pass granular styling to AccordionItem children. Using Partial makes all sub-keys optional, providing a flexible API without forcing consumers to specify every class.


667-667: LGTM! Consistent application of Variants composition pattern.

The props for DropdownItem, Dropzone, and Video now extend their corresponding Variants types, providing type-safe access to variant options and classes. This aligns with the broader theme-driven architecture refactoring across the PR.

Also applies to: 752-752, 1968-1968


1082-1082: LGTM! Cohesive navbar type updates support flexible styling.

The changes to NavbarState, NavUlProps, and NavLiProps work together harmoniously:

  • NavbarState.itemClass provides global item styling
  • NavUlProps.classes offers granular control with base/list/active/nonActive/item keys
  • NavLiProps extends NavLiVariants and adds active/nonActive class props

This layered approach enables both global and per-component styling customization.

Also applies to: 1116-1122, 1125-1129


1987-1987: LGTM! Type updates improve flexibility and align with modern patterns.

  • PopperProps.arrowClass changing from string to ClassValue enables more flexible styling (arrays, objects, conditional classes via clsx)
  • ArrowProps extending HTMLAttributes<HTMLDivElement> provides all standard div attributes (including class) while removing the need for a separate class field

Both changes align with modern Tailwind CSS and Svelte patterns.

Also applies to: 2003-2003

src/lib/video/Video.svelte (2)

7-17: LGTM! Clean props destructuring with Svelte 5 runes.

The prop destructuring follows Svelte 5 conventions:

  • class: className avoids reserved word collision while maintaining familiar API
  • New classes prop enables multi-part theming for source/track elements
  • Rest props captured for flexibility

25-44: LGTM! Clean multi-part theming with data attributes.

The markup correctly implements the multi-part theming pattern:

  • Consistent data-scope="video" and element-specific data-part attributes
  • Theme classes properly merged with custom classes via clsx()
  • base uses className, while source/track use their respective classes sub-keys
  • Fallback text provides good browser compatibility messaging

Copy link
Copy Markdown
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/lib/video/Video.svelte (1)

9-9: Redundant derived assignment.

styling is simply assigned from classes which is already a reactive prop. Consider using classes directly in the template to reduce unnecessary indirection.

🔎 Proposed simplification
-  const styling = $derived(classes);
-  const theme = $derived(getTheme("video"));
+  const theme = $derived(getTheme("video"));

Then use classes?.source, classes?.track, etc. directly in the template.

📜 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 3d7eed6 and cc1eee5.

📒 Files selected for processing (8)
  • src/lib/extend/kanban/KanbanCard.svelte
  • src/lib/extend/tags/Tags.svelte
  • src/lib/theme-provider/themes.ts
  • src/lib/theme-selector/ThemeSelector.svelte
  • src/lib/types.ts
  • src/lib/utils/Arrow.svelte
  • src/lib/video/Video.svelte
  • src/lib/video/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/utils/Arrow.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/video/index.ts
  • src/lib/extend/kanban/KanbanCard.svelte
  • src/lib/theme-selector/ThemeSelector.svelte
  • src/lib/extend/tags/Tags.svelte
  • src/lib/types.ts
  • src/lib/video/Video.svelte
  • src/lib/theme-provider/themes.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
📚 Learning: 2025-12-28T05:16:44.735Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-12-28T05:16:44.735Z
Learning: In flowbite-svelte with Svelte 5, props are not reactive by default. To make prop values reactive (so they update when the prop changes), they must be wrapped with `$derived()`. For example, `const styling = $derived(classes)` is necessary—not redundant—to ensure `styling` reacts to changes in the `classes` prop.

Applied to files:

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

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

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

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

// use $themeDerived in template/component

Applied to files:

  • src/lib/extend/kanban/KanbanCard.svelte
  • src/lib/theme-selector/ThemeSelector.svelte
  • src/lib/extend/tags/Tags.svelte
  • src/lib/video/Video.svelte
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
Repo: themesberg/flowbite-svelte PR: 1465
File: src/lib/forms/Timepicker.svelte:105-116
Timestamp: 2024-10-18T09:38:03.879Z
Learning: In `Timepicker.svelte`, the `Dropdown` opens as intended and is used exclusively with the 'dropdown' and 'timerange-dropdown' Timepicker types.

Applied to files:

  • src/lib/theme-selector/ThemeSelector.svelte
  • src/lib/extend/tags/Tags.svelte
  • src/lib/types.ts
📚 Learning: 2026-01-01T13:12:34.868Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.

Applied to files:

  • src/lib/types.ts
  • src/lib/theme-provider/themes.ts
🧬 Code graph analysis (1)
src/lib/types.ts (4)
src/lib/dropdown/theme.ts (1)
  • DropdownItemVariants (16-16)
src/lib/forms/dropzone/theme.ts (1)
  • DropzoneVariants (4-4)
src/lib/navbar/theme.ts (1)
  • NavLiVariants (11-11)
src/lib/video/theme.ts (1)
  • VideoVariants (4-4)
🔇 Additional comments (21)
src/lib/extend/kanban/KanbanCard.svelte (3)

9-10: Excellent reactivity pattern!

Both styling and theme are correctly wrapped in $derived(), ensuring they react to prop changes and dynamic theme updates. This aligns perfectly with Svelte 5 best practices and the ThemeProvider pattern.

Based on learnings, props are not reactive by default in Svelte 5, and getTheme() calls should be inside $derived() for dynamic theme changes.


7-7: Well-structured props and part functions.

The destructuring approach is clean: aliasing class to className avoids conflicts, and destructuring kanbanCard() into named parts with descriptive aliases improves readability. The inline comment helpfully explains the rationale.

Also applies to: 11-12


25-27: Consistent implementation of data attributes and part bindings.

The standardized data-scope and data-part attributes align with the PR objectives, and the uniform pattern of using part functions with merged theme/styling classes is clean and maintainable. Optional chaining correctly handles undefined theme or styling values.

Also applies to: 29-29, 34-34, 40-42

src/lib/extend/tags/Tags.svelte (4)

29-29: Correct reactive theme pattern.

The use of $derived(getTheme("tags")) properly ensures the component reactively responds to theme changes from the ThemeProvider. This follows the established pattern for dynamic theme updates.


31-31: Well-structured theme destructuring with semantic naming.

The renaming from tag/span to item/label improves clarity and aligns with semantic component design. The addition of inputWrapper and option keys provides better granular styling control. All destructured keys are consistently used throughout the template.


150-163: Excellent addition of data-part attributes for message states.

The systematic addition of data-part attributes (info, warning, error) on feedback messages enhances component testability and provides clear styling hooks. The semantic categorization aligns well with the message types.


165-220: Comprehensive and well-structured data attribute implementation.

The systematic addition of data-scope="tags" and data-part attributes throughout the component structure provides excellent hooks for testing, styling, and component identification. The semantic naming (item, label, input-wrapper, option) and consistent pattern improve maintainability. All new theme keys are properly integrated with the existing class merging logic.

src/lib/video/Video.svelte (1)

10-12: Theme integration follows reactive pattern correctly.

The getTheme("video") call is properly wrapped in $derived(), ensuring the component reacts to dynamic theme changes. Based on learnings, this is the correct pattern for Flowbite-Svelte components.

src/lib/types.ts (6)

668-677: Type extension looks correct.

DropdownItemProps now properly extends DropdownItemVariants to incorporate variant-based styling, aligning with the multi-part theming approach used across the codebase.


753-759: Type composition is appropriate.

DropzoneProps correctly extends both DropzoneVariants for theming and HTMLInputAttributes for native input behavior.


1117-1130: NavUl and NavLi prop types align with multi-part theming.

The classes structure in NavUlProps with base, list, active, nonActive, and item slots provides granular styling control. NavLiProps correctly composes AnchorButtonAttributes with NavLiVariants.


1969-1975: VideoProps correctly extends VideoVariants.

This aligns with the multi-part theming integration in Video.svelte and the theme definition in src/lib/video/theme.ts.


2004-2008: ArrowProps simplification is appropriate.

Extending HTMLAttributes<HTMLDivElement> directly includes the class property via the standard HTML attributes, making an explicit class field unnecessary.


2218-2220: ThemeSelectorProps type definition is well-formed.

The interface correctly extends both ThemeSelectorVariants for theming and HTMLAttributes<HTMLDivElement> for standard div attributes.

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

1-2: Theme export augments the module API appropriately.

Exporting the video theme alongside the Video component enables consumers to access theming utilities directly, consistent with the pattern used across other component modules.

src/lib/theme-selector/ThemeSelector.svelte (2)

14-17: Theme integration follows the correct reactive pattern.

The getTheme("themeSelector") call is properly wrapped in $derived(), ensuring reactivity to dynamic theme changes. The themeSelector() factory call for extracting slot functions is appropriately placed outside the reactive block since it's a static factory. Based on learnings, this is the expected pattern.


38-66: Well-structured multi-part theming with data attributes.

The component correctly applies data-scope="theme-selector" and data-part attributes throughout, enabling CSS targeting and inspection. The class composition using clsx properly merges theme defaults with user overrides. The color swatch position logic (first, middle, last) is cleanly implemented.

src/lib/theme-provider/themes.ts (4)

1-2: ThemeSelector theme export added appropriately.

Adding themeSelector as a new export enables centralized access to the theme-selector theming through the theme-provider module, consistent with the pattern used for other components.


46-46: Video theme export is correctly wired.

Re-enabling the video export aligns with the multi-part theming integration in Video.svelte and the new theme definition in src/lib/video/theme.ts.


86-86: Split-pane exports simplified.

The removal of dividerHitArea from the exports reflects the corresponding cleanup in src/lib/extend/split-pane/index.ts, keeping the public API in sync.


90-90: VirtualList path normalized.

The import path change from virtuallist to virtual-list follows consistent kebab-case naming conventions for directory structures.


<video {...restProps} class={clsx(theme, classname)}>
<source {src} {type} />
<video {...restProps} data-scope="video" data-part="base" class={base({ class: clsx(theme?.base, className) })}>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing styling?.base in base class composition.

The source and track parts include styling?.source and styling?.track respectively, but the base part only uses className and omits styling?.base. This inconsistency means users cannot override base styles via the classes prop.

🔎 Proposed fix
-<video {...restProps} data-scope="video" data-part="base" class={base({ class: clsx(theme?.base, className) })}>
+<video {...restProps} data-scope="video" data-part="base" class={base({ class: clsx(theme?.base, styling?.base, className) })}>
📝 Committable suggestion

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

Suggested change
<video {...restProps} data-scope="video" data-part="base" class={base({ class: clsx(theme?.base, className) })}>
<video {...restProps} data-scope="video" data-part="base" class={base({ class: clsx(theme?.base, styling?.base, className) })}>
🤖 Prompt for AI Agents
In src/lib/video/Video.svelte around line 15, the base part's class composition
omits styling?.base so consumers cannot override base styles via the classes
prop; update the base class composition to include styling?.base (e.g., merge
theme?.base, styling?.base, and className via clsx) when calling base({ class:
... }) so styling.classes.base is applied alongside theme and user className.

Copy link
Copy Markdown
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/tests/forms/search/search.test.ts (1)

1-334: LGTM! Comprehensive test coverage for Search component.

The test suite thoroughly validates:

  • Basic rendering and DOM structure
  • Data attributes (data-part, data-scope) introduced in the PR refactor
  • Value binding and user interactions
  • Clearable behavior with callbacks
  • Size variants and custom props
  • Content slot functionality

The tests follow Testing Library best practices with appropriate queries and user-event interactions.

Optional: Consider more resilient clear button queries.

Multiple tests (lines 125, 146, 156, 160, 232, 250) rely on the hardcoded aria-label "Clear search value". If this text changes in the Search component, these tests will break.

🔎 Suggested alternatives for more resilient queries

Consider one of these approaches:

  1. Add data-testid to the clear button (recommended):
 const closeButton = screen.getByLabelText("Clear search value");
+// Or use:
+const closeButton = screen.getByTestId("search-clear-button");
  1. Query by role with name pattern:
-const closeButton = screen.getByLabelText("Clear search value");
+const closeButton = screen.getByRole("button", { name: /clear/i });

This makes tests more resilient to label text changes while maintaining accessibility verification.

📜 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 cc1eee5 and 62a5e50.

📒 Files selected for processing (15)
  • src/tests/forms/range/range-attributes.test.svelte
  • src/tests/forms/range/range-basic.test.svelte
  • src/tests/forms/range/range-colors.test.svelte
  • src/tests/forms/range/range-custom-props.test.svelte
  • src/tests/forms/range/range-sizes.test.svelte
  • src/tests/forms/range/range-value-binding.test.svelte
  • src/tests/forms/range/range.test.ts
  • src/tests/forms/search/search-basic.test.svelte
  • src/tests/forms/search/search-callback.test.svelte
  • src/tests/forms/search/search-clearable.test.svelte
  • src/tests/forms/search/search-custom-props.test.svelte
  • src/tests/forms/search/search-sizes.test.svelte
  • src/tests/forms/search/search-value-binding.test.svelte
  • src/tests/forms/search/search-with-content.test.svelte
  • src/tests/forms/search/search.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/forms/range/range-colors.test.svelte
  • src/tests/forms/search/search-basic.test.svelte
  • src/tests/forms/range/range-basic.test.svelte
  • src/tests/forms/search/search-with-content.test.svelte
  • src/tests/forms/search/search.test.ts
  • src/tests/forms/range/range-custom-props.test.svelte
  • src/tests/forms/search/search-value-binding.test.svelte
  • src/tests/forms/search/search-custom-props.test.svelte
  • src/tests/forms/range/range-attributes.test.svelte
  • src/tests/forms/range/range-sizes.test.svelte
  • src/tests/forms/range/range.test.ts
  • src/tests/forms/range/range-value-binding.test.svelte
  • src/tests/forms/search/search-clearable.test.svelte
  • src/tests/forms/search/search-callback.test.svelte
  • src/tests/forms/search/search-sizes.test.svelte
🧠 Learnings (7)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
📚 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/forms/range/range-colors.test.svelte
  • src/tests/forms/search/search-basic.test.svelte
  • src/tests/forms/range/range-basic.test.svelte
  • src/tests/forms/search/search-with-content.test.svelte
  • src/tests/forms/range/range-custom-props.test.svelte
  • src/tests/forms/search/search-value-binding.test.svelte
  • src/tests/forms/search/search-custom-props.test.svelte
  • src/tests/forms/range/range-attributes.test.svelte
  • src/tests/forms/range/range-sizes.test.svelte
  • src/tests/forms/range/range-value-binding.test.svelte
  • src/tests/forms/search/search-clearable.test.svelte
  • src/tests/forms/search/search-callback.test.svelte
  • src/tests/forms/search/search-sizes.test.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/tests/forms/search/search-basic.test.svelte
  • src/tests/forms/search/search-with-content.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/tests/forms/search/search-with-content.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/forms/search/search-with-content.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/forms/search/search-with-content.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: 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/tests/forms/search/search-with-content.test.svelte
🔇 Additional comments (14)
src/tests/forms/range/range-basic.test.svelte (1)

1-5: LGTM! Clean basic test fixture.

The test fixture correctly imports and renders a basic Range component with an appropriate data-testid attribute for test queries. This follows the established pattern for test fixtures in this suite.

src/tests/forms/range/range-sizes.test.svelte (1)

1-7: LGTM! Comprehensive size variant coverage.

The test fixture correctly covers all size variants (sm, md, lg) with clear, descriptive data-testid attributes for each variant. This enables thorough testing of size-related styling and behavior.

src/tests/forms/range/range-custom-props.test.svelte (1)

1-7: LGTM! Good coverage of custom properties.

The test fixture appropriately covers common customization scenarios including custom classes, IDs, disabled state, and name attributes. Each variant is properly identified with data-testid attributes for effective test queries.

src/tests/forms/range/range-value-binding.test.svelte (1)

1-10: LGTM! Proper two-way binding test setup.

The test fixture correctly demonstrates two-way binding using Svelte 5's $state rune. The display element allows verification that value updates propagate correctly in both directions. The min/max props provide a complete range configuration for testing.

src/tests/forms/range/range-colors.test.svelte (1)

1-9: LGTM! Complete color variant coverage.

The test fixture provides comprehensive coverage of color variants with clear, descriptive data-testid attributes. This enables thorough testing of color-related styling across all supported color options.

src/tests/forms/range/range-attributes.test.svelte (1)

1-8: LGTM! Well-structured test fixture.

The test file provides clear coverage of Range attribute variations (min/max, step, negative values, and decimal steps) with descriptive test IDs. The attribute combinations are appropriate for validating the Range component's flexibility.

src/tests/forms/range/range.test.ts (1)

16-229: Excellent test coverage.

The test suite is comprehensive and well-organized, covering basic rendering, value binding, variants (colors/sizes), attributes, custom props, and user interactions. The inclusion of data-scope and data-part attribute tests aligns with the PR objectives. The reactivity handling using setTimeout is an acceptable pattern for Svelte component testing.

src/tests/forms/search/search-clearable.test.svelte (1)

1-9: LGTM! Clean test for clearable functionality.

The test correctly uses Svelte 5 $state runes for reactive values and demonstrates two-way binding with the clearable prop. Testing both populated and empty initial values provides good coverage.

src/tests/forms/search/search-custom-props.test.svelte (1)

1-8: LGTM! Comprehensive prop testing.

The test effectively covers various customization props including placeholder, class, id, classes (for nested input styling), and name. The structure is clean and each test case has appropriate data-testid attributes for test targeting.

src/tests/forms/search/search-basic.test.svelte (1)

1-5: LGTM! Clean baseline test.

This minimal test case provides a good foundation for verifying basic Search component rendering with default props.

src/tests/forms/search/search-sizes.test.svelte (1)

5-7: I need the review comment content within <review_comment> tags to proceed with the verification and rewriting process. Please provide the review comment you'd like me to verify and rewrite.

src/tests/forms/search/search-with-content.test.svelte (1)

5-9: [Rewritten review comment]
[Classification tag]

src/tests/forms/search/search-value-binding.test.svelte (1)

1-10: LGTM! Clean value binding test implementation.

The test component correctly uses Svelte 5's $state rune for reactive binding and provides clear testability through data-testid attributes. The fallback display ("empty") enables straightforward assertion of the initial empty state.

src/tests/forms/search/search-callback.test.svelte (1)

1-20: LGTM! Effective callback testing pattern.

The test component properly demonstrates callback verification with:

  • Initial non-empty value to ensure the clear button renders
  • Boolean flag to track callback invocation
  • Clear status display for assertion

This pattern effectively isolates and validates the clearableOnClick callback behavior.

Copy link
Copy Markdown
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

♻️ Duplicate comments (1)
src/tests/forms/range/range.test.ts (1)

1-10: Import fix confirmed - excellent work!

The userEvent import now correctly uses default import syntax, which aligns with @testing-library/user-event v14.x export pattern. All imports are properly structured.

🧹 Nitpick comments (5)
src/tests/forms/range/range.test.ts (1)

54-86: Consider consolidating similar value binding tests.

The tests at lines 54-69, 71-85, and 213-228 follow nearly identical patterns: programmatically setting a value, dispatching an input event, and verifying both the range value and display update. While testing with multiple values provides thorough coverage, these could potentially be consolidated into a parameterized test or a single test that checks multiple values in sequence to reduce duplication.

Also applies to: 213-228

src/tests/forms/select/multiselect.test.ts (3)

66-66: Replace class-based selectors with data attributes for consistency.

The selector [class*="badge"] is fragile because it depends on class naming conventions. Consider using [data-part="badge"] instead to match the consistent data attribute pattern used throughout this test file for dropdown, item, select, and close elements.

🔎 Proposed refactor to use data-part attributes

For example, at line 66:

-      const selectedBadges = container.querySelectorAll('[data-part="select"] [class*="badge"]');
+      const selectedBadges = container.querySelectorAll('[data-part="badge"]');

Apply similar changes to lines 88, 142, 158, 161, 169, 335, and 374.

Note: This refactor assumes the MultiSelect component renders badges with data-part="badge". If not, please verify and update the component accordingly to maintain consistency with other data-part attributes.

Also applies to: 88-89, 142-142, 158-158, 161-161, 169-169, 335-335, 374-374


63-63: Add null checks before non-null assertions for better test diagnostics.

Using the non-null assertion operator (!) without prior existence checks can lead to unhelpful TypeError messages when elements aren't found. Consider asserting element existence explicitly before interactions.

🔎 Proposed refactor pattern

Instead of:

 const appleItem = getDropdownItem(container, "Apple");
-await user.click(appleItem!);
+expect(appleItem).toBeInTheDocument();
+await user.click(appleItem);

This provides clearer error messages when elements are missing and removes the need for type assertions.

Apply this pattern to lines 63, 84-85, 104, 112, 166, 221, 241, 353, and 369.

Also applies to: 84-85, 104-104, 112-112, 166-166, 221-221, 241-241, 353-353, 369-369


190-191: Consider using waitFor with explicit timeout for negative assertions.

The hardcoded setTimeout delays work but could be made more explicit. For negative assertions (verifying something doesn't happen), consider using waitFor with a custom timeout or add comments explaining the wait.

🔎 Alternative pattern
-// Wait a bit to ensure dropdown doesn't appear
-await new Promise(resolve => setTimeout(resolve, 200));
-expect(isDropdownVisible(container)).toBe(false);
+await waitFor(() => {
+  expect(isDropdownVisible(container)).toBe(false);
+}, { timeout: 200 });

This makes the wait intent more explicit and integrates with the testing library's wait utilities.

Also applies to: 224-227

src/tests/forms/textarea/textarea.test.ts (1)

236-257: Tests don't validate component prop passthrough.

These tests set rows and maxLength directly on the DOM element, then assert the values. This tests native DOM behavior, not whether the Textarea component properly forwards these props to the underlying <textarea>.

To properly test attribute passthrough, the test fixtures should render the component with these props:

<!-- In a test fixture like textarea-attributes.test.svelte -->
<Textarea rows={5} maxlength={10} placeholder="Test" />

Then the test should verify the props appear on the rendered element:

test("supports rows attribute", () => {
  const { container } = render(TextareaAttributesTest);
  const textarea = getTextareaElement(container);
  expect(textarea.rows).toBe(5);
});

test("supports maxlength attribute", () => {
  const { container } = render(TextareaAttributesTest);
  const textarea = getTextareaElement(container);
  expect(textarea.maxLength).toBe(10);
});
📜 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 62a5e50 and 9381c7f.

📒 Files selected for processing (36)
  • .gitignore
  • src/lib/extend/tags/Tags.svelte
  • src/lib/extend/tags/theme.ts
  • src/tests/clipboard-manager/clipboard-manager.test.ts
  • src/tests/clipboard/clipboard.test.ts
  • src/tests/forms/button-toggle/button-toggle.test.ts
  • src/tests/forms/checkbox/checkbox.test.ts
  • src/tests/forms/dropzone/dropzone.test.ts
  • src/tests/forms/fileupload/fileupload.test.ts
  • src/tests/forms/floating-label/floating-label.test.ts
  • src/tests/forms/input-field/input.test.ts
  • src/tests/forms/phoneinput/phoneinput.test.ts
  • src/tests/forms/radio/radio-button.test.ts
  • src/tests/forms/range/range.test.ts
  • src/tests/forms/search/search.test.ts
  • src/tests/forms/select/multiselect-basic.test.svelte
  • src/tests/forms/select/multiselect-disabled-options.test.svelte
  • src/tests/forms/select/multiselect-disabled.test.svelte
  • src/tests/forms/select/multiselect-preselected.test.svelte
  • src/tests/forms/select/multiselect.test.ts
  • src/tests/forms/select/select-basic.test.svelte
  • src/tests/forms/select/select-children.test.svelte
  • src/tests/forms/select/select-clearable.test.svelte
  • src/tests/forms/select/select-disabled-options.test.svelte
  • src/tests/forms/select/select-disabled.test.svelte
  • src/tests/forms/select/select.test.ts
  • src/tests/forms/textarea/textarea-addon.test.svelte
  • src/tests/forms/textarea/textarea-basic.test.svelte
  • src/tests/forms/textarea/textarea-clearable.test.svelte
  • src/tests/forms/textarea/textarea-disabled.test.svelte
  • src/tests/forms/textarea/textarea-header-footer.test.svelte
  • src/tests/forms/textarea/textarea.test.ts
  • src/tests/list-group/listgroup.test.ts
  • src/tests/mega-menu/mega-menu.test.ts
  • src/tests/modal/modal.test.ts
  • src/tests/navbar/navbar.test.ts
✅ Files skipped from review due to trivial changes (2)
  • src/tests/forms/fileupload/fileupload.test.ts
  • src/tests/forms/textarea/textarea-basic.test.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/tests/forms/search/search.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/forms/textarea/textarea-addon.test.svelte
  • src/tests/forms/checkbox/checkbox.test.ts
  • src/tests/clipboard-manager/clipboard-manager.test.ts
  • src/tests/forms/textarea/textarea-clearable.test.svelte
  • src/tests/forms/select/multiselect-preselected.test.svelte
  • src/tests/forms/select/multiselect-basic.test.svelte
  • src/tests/navbar/navbar.test.ts
  • src/tests/forms/input-field/input.test.ts
  • src/tests/forms/select/multiselect-disabled-options.test.svelte
  • src/tests/forms/dropzone/dropzone.test.ts
  • src/tests/mega-menu/mega-menu.test.ts
  • src/tests/forms/select/select-basic.test.svelte
  • src/tests/forms/phoneinput/phoneinput.test.ts
  • src/tests/clipboard/clipboard.test.ts
  • src/tests/forms/floating-label/floating-label.test.ts
  • src/tests/forms/select/multiselect.test.ts
  • src/tests/forms/textarea/textarea.test.ts
  • src/tests/forms/select/select-children.test.svelte
  • src/tests/modal/modal.test.ts
  • src/tests/forms/radio/radio-button.test.ts
  • src/tests/forms/textarea/textarea-header-footer.test.svelte
  • src/tests/list-group/listgroup.test.ts
  • src/tests/forms/select/select-clearable.test.svelte
  • src/tests/forms/select/select.test.ts
  • src/tests/forms/select/multiselect-disabled.test.svelte
  • src/lib/extend/tags/theme.ts
  • src/tests/forms/button-toggle/button-toggle.test.ts
  • src/tests/forms/select/select-disabled.test.svelte
  • src/tests/forms/select/select-disabled-options.test.svelte
  • src/tests/forms/range/range.test.ts
  • src/lib/extend/tags/Tags.svelte
  • src/tests/forms/textarea/textarea-disabled.test.svelte
🧠 Learnings (4)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Use the Flowbite-Svelte MCP server to discover components by name or category before implementing UI components
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : After calling findComponent, use getComponentDoc tool to fetch complete documentation including usage examples, props, and best practices for Flowbite-Svelte components
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 1882
File: src/lib/bottom-navigation/BottomNavHeaderItem.svelte:9-9
Timestamp: 2025-12-16T13:21:28.743Z
Learning: In flowbite-svelte, when using ThemeProvider with reactive themes, `getTheme("componentName")` calls must be placed inside `$derived()` expressions (not at module scope) to ensure components react to dynamic theme changes. This pattern is intentional for reactive theming support.
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T07:26:46.504Z
Learning: Applies to **/*.{svelte,ts,tsx,js,jsx} : Always use findComponent tool FIRST to locate the correct Flowbite-Svelte component before fetching documentation
Learnt from: superstes
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2025-03-20T11:52:09.106Z
Learning: In the Flowbite Svelte library's form components like MultiInput, when handling focus states for validation, avoid hardcoding focus-within classes like 'focus-within:border-primary-500'. Instead, create a dynamic mapping object (e.g., focusWithinClasses) that changes the focus ring color based on the current color state, especially when inputInvalid=true.
Learnt from: CR
Repo: themesberg/flowbite-svelte PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T07:26:39.377Z
Learning: 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
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
📚 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/forms/textarea/textarea-addon.test.svelte
  • src/tests/forms/textarea/textarea-clearable.test.svelte
  • src/tests/forms/select/multiselect-preselected.test.svelte
  • src/tests/forms/select/multiselect-basic.test.svelte
  • src/tests/forms/select/multiselect-disabled-options.test.svelte
  • src/tests/forms/select/select-basic.test.svelte
  • src/tests/forms/select/select-children.test.svelte
  • src/tests/forms/textarea/textarea-header-footer.test.svelte
  • src/tests/forms/select/select-clearable.test.svelte
  • src/tests/forms/select/multiselect-disabled.test.svelte
  • src/tests/forms/select/select-disabled.test.svelte
  • src/tests/forms/select/select-disabled-options.test.svelte
  • src/lib/extend/tags/Tags.svelte
  • src/tests/forms/textarea/textarea-disabled.test.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/forms/button-toggle/button-toggle.test.ts
📚 Learning: 2026-01-01T13:12:34.868Z
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.

Applied to files:

  • src/tests/forms/range/range.test.ts
🔇 Additional comments (44)
.gitignore (1)

20-20: LGTM!

The addition of questions.md to .gitignore is a straightforward housekeeping change to prevent the file from being tracked in version control.

src/tests/forms/phoneinput/phoneinput.test.ts (1)

3-3: Correct import syntax fix.

The change from named import to default import is correct for @testing-library/user-event v14.6.1, which exports userEvent as the default export. The userEvent.setup() usage throughout the file is consistent with the v14 API.

src/tests/forms/radio/radio-button.test.ts (1)

3-3: LGTM! Critical import syntax fix.

The change from a named import to a default import is correct. The @testing-library/user-event library exports userEvent as a default export, so the previous syntax would have caused runtime failures.

src/tests/forms/textarea/textarea-disabled.test.svelte (1)

1-7: LGTM! Clean disabled state test.

The test correctly demonstrates the disabled Textarea functionality using Svelte 5's $state rune for reactive binding. The implementation is concise and follows the project's test patterns.

src/tests/forms/textarea/textarea-header-footer.test.svelte (1)

1-14: LGTM! Proper header/footer snippet usage.

The test correctly demonstrates Textarea's header and footer snippet slots using Svelte 5 syntax. The implementation properly uses $state for reactive binding and follows the component's updated slot naming conventions mentioned in the PR context.

src/tests/forms/textarea/textarea-addon.test.svelte (1)

1-11: LGTM! Clean addon snippet test.

The test correctly demonstrates the Textarea component's addon slot functionality using Svelte 5's snippet syntax. The implementation is straightforward and follows the established test patterns.

src/tests/forms/textarea/textarea-clearable.test.svelte (1)

1-7: LGTM! Clean clearable feature test.

The test correctly demonstrates the Textarea component's clearable functionality with proper reactive binding using Svelte 5's $state rune. The implementation is concise and follows the project's testing conventions.

src/tests/forms/range/range.test.ts (1)

16-229: Comprehensive and well-organized test suite!

The test coverage is thorough and systematic, covering all essential aspects:

  • Basic rendering and element structure
  • Data attributes (data-scope and data-part) validation, aligning with PR objectives
  • Value binding and reactivity
  • Color and size variants
  • HTML attributes including edge cases (negative ranges, decimal steps)
  • Custom props and accessibility
  • User interactions

The tests are well-structured with clear describe blocks and descriptive test names.

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

3-3: LGTM: Import syntax corrected.

The change from a named import to a default import aligns with @testing-library/user-event's API, which exports userEvent as the default export. This pattern is consistently applied across all test files in this PR (floating-label, list-group, button-toggle, clipboard-manager, and mega-menu tests).

src/tests/forms/checkbox/checkbox.test.ts (1)

3-3: Import syntax corrected.

This matches the proper default import pattern for @testing-library/user-event. The usage throughout the test suite remains consistent.

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

2-2: Import syntax corrected.

The default import is the correct pattern for @testing-library/user-event. The change maintains consistency with the other test files in this PR.

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

3-3: Import syntax corrected.

Proper default import pattern applied consistently with the repository-wide standardization.

src/tests/forms/input-field/input.test.ts (1)

3-3: Import syntax corrected.

This completes the consistent application of the proper default import pattern across all test files.

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

3-3: Import syntax correctly uses the default import pattern required for @testing-library/user-event v14.6.1.

The default import import userEvent from '@testing-library/user-event' is the correct and required syntax for this version.

src/tests/forms/dropzone/dropzone.test.ts (1)

3-3: Import syntax correction is accurate.

The change to a default import is the recommended pattern for @testing-library/user-event v14, and the usage on line 25 (userEvent.setup()) aligns with this approach.

src/tests/forms/select/multiselect-disabled.test.svelte (1)

1-13: LGTM! Well-structured test for disabled MultiSelect.

The test correctly demonstrates the disabled state of the MultiSelect component with proper Svelte 5 syntax, TypeScript typing, and component binding. This expands test coverage for the disabled scenario.

src/tests/forms/select/select-children.test.svelte (1)

1-13: LGTM! Correct usage of children snippet pattern.

The test properly demonstrates rendering Select options via the children snippet, using correct Svelte 5 syntax and proper state binding. This verifies the component's support for explicit child option elements.

src/tests/forms/select/multiselect-preselected.test.svelte (1)

1-13: LGTM! Effective test for preselected values.

The test correctly demonstrates the MultiSelect component with preselected values, using proper Svelte 5 syntax and TypeScript typing. The preselected values (apple, orange) align with the available items, ensuring the test verifies the preselection behavior accurately.

src/tests/forms/select/select-clearable.test.svelte (1)

1-13: LGTM! Clean test for clearable Select.

The test properly demonstrates the clearable functionality of the Select component with correct Svelte 5 syntax, TypeScript typing, and component binding. This verifies that users can clear their selection, which is an important UX feature.

src/tests/forms/select/multiselect-basic.test.svelte (1)

1-13: LGTM! Solid basic test case.

The test correctly demonstrates the fundamental usage of the MultiSelect component with proper Svelte 5 syntax, TypeScript typing, and component binding. This serves as a baseline test for the component's core functionality.

src/tests/forms/select/select-basic.test.svelte (1)

1-13: LGTM! Clean test fixture for basic Select functionality.

The test fixture is well-structured with correct Svelte 5 syntax, appropriate data structure, and proper two-way binding.

src/tests/forms/select/select-disabled-options.test.svelte (1)

1-13: LGTM! Proper test fixture for disabled options scenario.

The test correctly demonstrates a Select with one disabled option, following the same clean pattern as the basic test fixture.

src/tests/forms/select/select-disabled.test.svelte (1)

1-13: LGTM! Appropriate test fixture for disabled Select.

The test fixture correctly adds the disabled prop to verify the Select component's disabled state behavior.

src/tests/forms/select/multiselect-disabled-options.test.svelte (1)

1-13: LGTM! Well-typed test fixture for MultiSelect with disabled options.

The test fixture correctly uses $state<string[]>([]) for multi-select binding and demonstrates disabled option behavior.

src/tests/forms/select/select.test.ts (5)

1-17: Excellent test setup and helper function.

The imports, cleanup configuration, and getSelectElement helper using data-part="select" align well with the PR's data-attribute strategy for improved testability.


19-62: Comprehensive coverage of basic Select functionality.

The test suite thoroughly validates placeholder rendering, option rendering, and selection behavior with clear assertions and proper async handling.


64-123: Thorough testing of clearable Select behavior.

The test suite excellently covers all clearable scenarios: button visibility, clearing behavior, event triggering, and proper cleanup. The verification that the clear button hides after clearing is particularly valuable.


125-142: Proper validation of disabled state.

The tests correctly verify that disabled selects prevent value changes, which is essential for form control security.


144-185: Good coverage of disabled options and children slot.

Both test suites properly verify that disabled options cannot be selected while non-disabled options remain functional, and that the children slot pattern works correctly for option rendering.

src/tests/forms/select/multiselect.test.ts (2)

1-12: LGTM!

The imports and test setup follow standard Vitest and Testing Library patterns. The cleanup in afterEach ensures test isolation.


14-28: LGTM!

The helper functions provide clean abstractions for dropdown interactions and use data-part attributes consistently, which aligns with the PR's systematic addition of data attributes for improved DOM targeting.

src/tests/forms/textarea/textarea.test.ts (7)

21-71: LGTM!

The basic tests cover essential functionality: rendering, placeholder, text input, multiline handling, and clearing. The use of userEvent for realistic user interactions is appropriate.


73-133: LGTM!

Comprehensive coverage of the clearable textarea behavior, including edge cases like button visibility toggling and reappearance after re-typing. Good use of waitFor for async DOM assertions.


135-158: LGTM!

Solid coverage of disabled state behavior: render state, input rejection, and focus prevention.


160-201: LGTM!

Good coverage of header/footer functionality, including DOM ordering validation using compareDocumentPosition. The position tests ensure structural correctness.


203-226: LGTM!

Good coverage of the addon feature, including verifying the addon is correctly nested within the inner wrapper.


259-302: LGTM!

Good coverage of native event firing (input, change, focus, blur). The pattern of attaching handlers directly to the DOM element and verifying they're called is appropriate for testing event propagation.


15-19: The data-part selectors are correct; remove the concern about selector validity.

The component legitimately uses both textarea[data-part="wrapper"] (when not wrapped) and textarea[data-part="base"] (when wrapped with header/footer/addon). The test helper's fallback pattern is the right approach.

However, adding a null check for clearer error messages is still good practice:

Optional null check improvement
 const getTextareaElement = (container: HTMLElement): HTMLTextAreaElement => {
   const wrapped = container.querySelector('textarea[data-part="base"]');
   const unwrapped = container.querySelector('textarea[data-part="wrapper"]');
-  return (wrapped || unwrapped) as HTMLTextAreaElement;
+  const textarea = wrapped || unwrapped;
+  if (!textarea) {
+    throw new Error('Textarea element not found. Expected textarea[data-part="base"] or textarea[data-part="wrapper"]');
+  }
+  return textarea as HTMLTextAreaElement;
 };
src/lib/extend/tags/theme.ts (2)

18-20: LGTM! Well-designed slots for dropdown functionality.

The new slots (inputWrapper, option, list) appropriately expand the theming surface to support the autocomplete dropdown. The styling choices are sound:

  • inputWrapper uses relative positioning for proper dropdown anchoring
  • option includes hover feedback for better UX
  • list has proper z-index stacking and overflow handling for long suggestion lists

10-11: LGTM! Semantic slot name improvements properly integrated.

The renaming of tagitem and spanlabel improves clarity and aligns with design system conventions. The Tailwind classes are preserved correctly, and the Tags.svelte component is already using the new slot names consistently throughout the codebase with no orphaned references to the old names.

src/lib/extend/tags/Tags.svelte (4)

29-31: LGTM! Correct reactive theme handling.

The theme is correctly wrapped in $derived(getTheme("tags")) to support dynamic theme changes, which aligns with the established pattern for ThemeProvider usage in this repository. The destructuring with aliases (item: itemCls, label: labelCls) is a good practice that prevents naming conflicts while maintaining clarity.

Based on learnings, this reactive pattern ensures components respond to theme updates at runtime.


150-167: LGTM! Consistent data attribute implementation.

The addition of data-scope="tags" and semantic data-part attributes (info, warning, error, base) provides well-structured DOM hooks for styling, testing, and debugging. This aligns with the PR's systematic refactor to add data attributes across components.


174-179: LGTM! Proper integration of renamed theme slots.

The tag item structure correctly uses the renamed theme slots (itemCls and labelCls) while adding semantic data-part attributes. Note that the close button uses data-part="close-button" (semantic) while applying the close theme slot (technical) - this separation is appropriate for distinguishing DOM semantics from styling concerns.


181-219: LGTM! Complete integration of new theme slots.

The input wrapper and dropdown structure correctly implements all the new theme slots (inputWrapper, option, list) with matching data-part attributes. The inline position: absolute style on line 197 is appropriate since the positioning coordinates are dynamically calculated by floating-ui and applied via the updateDropdownPosition function.

Copy link
Copy Markdown
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 (4)
src/tests/forms/select/select-children.test.svelte (1)

7-11: Component usage looks correct.

The Select component is properly configured with a value binding, placeholder, and option children. This effectively tests the children slot functionality of the Select component.

For improved accessibility, consider adding a label even in test files:

<label for="country-select">Country</label>
<Select id="country-select" bind:value placeholder="Choose a country">
  <option value="us">United States</option>
  <option value="ca">Canada</option>
  <option value="mx">Mexico</option>
</Select>
src/tests/forms/timepicker/timepicker.test.ts (1)

224-258: Replace hardcoded setTimeout delays with proper async waiting.

The callback tests use setTimeout with hardcoded 100ms delays (lines 235, 250), which is an anti-pattern that can lead to flaky tests. The delays may be insufficient on slower machines or unnecessarily long on faster ones.

🔎 Recommended approach using waitFor
 describe("Timepicker - Callback Functionality", () => {
-  test("calls onselect callback on time change", async () => {
+  test("calls onselect callback on time change", async () => {
     render(TimepickerCallback);
     const wrapper = screen.getByTestId("callback-wrapper");
     const input = wrapper.querySelector('input[type="time"]') as HTMLInputElement;
 
     // For time inputs, directly set the value and fire the input event
     input.value = "15:30";
     await fireEvent.input(input);
 
-    // Wait for callback to be processed
-    await new Promise((resolve) => setTimeout(resolve, 100));
-
-    const result = screen.queryByTestId("callback-result");
+    const result = await screen.findByTestId("callback-result");
     expect(result).toBeInTheDocument();
   });
 
   test("provides correct data structure in callback", async () => {
     render(TimepickerCallback);
     const wrapper = screen.getByTestId("callback-wrapper");
     const input = wrapper.querySelector('input[type="time"]') as HTMLInputElement;
 
     // For time inputs, directly set the value and fire the input event
     input.value = "11:45";
     await fireEvent.input(input);
 
-    await new Promise((resolve) => setTimeout(resolve, 100));
-
-    const result = screen.queryByTestId("callback-result");
+    const result = await screen.findByTestId("callback-result");
     if (result) {
       const data = JSON.parse(result.textContent || "{}");
       expect(data).toHaveProperty("time");
     }
   });
 });

Using screen.findByTestId automatically waits for the element to appear (with a default timeout of 1000ms) and fails fast if it doesn't, making tests more reliable and faster.

src/tests/forms/textarea/textarea.test.ts (2)

16-20: Consider clarifying variable names.

The variable naming is counterintuitive: wrapped holds the element with data-part="base", while unwrapped holds data-part="wrapper". This reversal could confuse maintainers.

🔎 Suggested refactor for clearer naming
 const getTextareaElement = (container: HTMLElement): HTMLTextAreaElement => {
-  const wrapped = container.querySelector('textarea[data-part="base"]');
-  const unwrapped = container.querySelector('textarea[data-part="wrapper"]');
-  return (wrapped || unwrapped) as HTMLTextAreaElement;
+  const base = container.querySelector('textarea[data-part="base"]');
+  const wrapper = container.querySelector('textarea[data-part="wrapper"]');
+  return (base || wrapper) as HTMLTextAreaElement;
 };

230-235: Consider strengthening or removing this test.

The test titled "passes through native textarea attributes" only verifies that the element is a TEXTAREA. It doesn't actually verify that attributes are passed through. The subsequent tests (lines 237-247) provide meaningful attribute validation for rows and maxlength.

💡 Suggestion

Either enhance this test to verify actual attribute passthrough (e.g., check that arbitrary attributes like data-testid or aria-label are passed through), or remove it as redundant given the specific attribute tests that follow.

📜 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 9381c7f and 504cb11.

📒 Files selected for processing (44)
  • src/lib/extend/tags/Tags.svelte
  • src/routes/docs-examples/extend/kanban-board/LocalStorage.svelte
  • src/routes/docs-examples/extend/kanban-board/UsingModal.svelte
  • src/tests/clipboard-manager/clipboard-manager.test.ts
  • src/tests/clipboard/clipboard.test.ts
  • src/tests/forms/button-toggle/button-toggle.test.ts
  • src/tests/forms/checkbox/checkbox.test.ts
  • src/tests/forms/dropzone/dropzone.test.ts
  • src/tests/forms/fileupload/fileupload.test.ts
  • src/tests/forms/floating-label/floating-label.test.ts
  • src/tests/forms/input-field/input.test.ts
  • src/tests/forms/phoneinput/phoneinput.test.ts
  • src/tests/forms/radio/radio-button.test.ts
  • src/tests/forms/range/range-colors.test.svelte
  • src/tests/forms/range/range.test.ts
  • src/tests/forms/search/search-callback.test.svelte
  • src/tests/forms/search/search-with-content.test.svelte
  • src/tests/forms/search/search.test.ts
  • src/tests/forms/select/multiselect.test.ts
  • src/tests/forms/select/select-children.test.svelte
  • src/tests/forms/select/select.test.ts
  • src/tests/forms/textarea/textarea-attributes.test.svelte
  • src/tests/forms/textarea/textarea.test.ts
  • src/tests/forms/timepicker/timepicker-callback.test.svelte
  • src/tests/forms/timepicker/timepicker-default.test.svelte
  • src/tests/forms/timepicker/timepicker-disabled.test.svelte
  • src/tests/forms/timepicker/timepicker-dropdown.test.svelte
  • src/tests/forms/timepicker/timepicker-inline.test.svelte
  • src/tests/forms/timepicker/timepicker-minmax.test.svelte
  • src/tests/forms/timepicker/timepicker-range.test.svelte
  • src/tests/forms/timepicker/timepicker-select.test.svelte
  • src/tests/forms/timepicker/timepicker.test.ts
  • src/tests/forms/toggle/toggle-basic.test.svelte
  • src/tests/forms/toggle/toggle-colors.test.svelte
  • src/tests/forms/toggle/toggle-disabled.test.svelte
  • src/tests/forms/toggle/toggle-offlabel.test.svelte
  • src/tests/forms/toggle/toggle-prechecked.test.svelte
  • src/tests/forms/toggle/toggle-sizes.test.svelte
  • src/tests/forms/toggle/toggle-value.test.svelte
  • src/tests/forms/toggle/toggle.test.ts
  • src/tests/list-group/listgroup.test.ts
  • src/tests/mega-menu/mega-menu.test.ts
  • src/tests/modal/modal.test.ts
  • src/tests/navbar/navbar.test.ts
✅ Files skipped from review due to trivial changes (1)
  • src/tests/forms/timepicker/timepicker-minmax.test.svelte
🚧 Files skipped from review as they are similar to previous changes (15)
  • src/tests/clipboard-manager/clipboard-manager.test.ts
  • src/tests/forms/radio/radio-button.test.ts
  • src/tests/forms/select/multiselect.test.ts
  • src/tests/forms/range/range.test.ts
  • src/tests/modal/modal.test.ts
  • src/tests/forms/search/search-with-content.test.svelte
  • src/tests/forms/search/search-callback.test.svelte
  • src/tests/forms/floating-label/floating-label.test.ts
  • src/tests/mega-menu/mega-menu.test.ts
  • src/tests/forms/select/select.test.ts
  • src/tests/navbar/navbar.test.ts
  • src/tests/forms/dropzone/dropzone.test.ts
  • src/tests/forms/fileupload/fileupload.test.ts
  • src/tests/forms/search/search.test.ts
  • src/tests/forms/range/range-colors.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/forms/toggle/toggle-prechecked.test.svelte
  • src/tests/forms/timepicker/timepicker-range.test.svelte
  • src/tests/forms/select/select-children.test.svelte
  • src/tests/forms/checkbox/checkbox.test.ts
  • src/tests/forms/timepicker/timepicker-default.test.svelte
  • src/tests/forms/button-toggle/button-toggle.test.ts
  • src/tests/forms/phoneinput/phoneinput.test.ts
  • src/tests/forms/textarea/textarea-attributes.test.svelte
  • src/routes/docs-examples/extend/kanban-board/LocalStorage.svelte
  • src/tests/forms/timepicker/timepicker-callback.test.svelte
  • src/tests/clipboard/clipboard.test.ts
  • src/tests/forms/timepicker/timepicker.test.ts
  • src/tests/forms/toggle/toggle-disabled.test.svelte
  • src/tests/forms/toggle/toggle-value.test.svelte
  • src/tests/forms/toggle/toggle-offlabel.test.svelte
  • src/tests/forms/toggle/toggle.test.ts
  • src/tests/forms/timepicker/timepicker-select.test.svelte
  • src/tests/forms/toggle/toggle-basic.test.svelte
  • src/tests/forms/toggle/toggle-sizes.test.svelte
  • src/tests/forms/toggle/toggle-colors.test.svelte
  • src/routes/docs-examples/extend/kanban-board/UsingModal.svelte
  • src/tests/forms/textarea/textarea.test.ts
  • src/tests/forms/timepicker/timepicker-disabled.test.svelte
  • src/tests/list-group/listgroup.test.ts
  • src/tests/forms/timepicker/timepicker-inline.test.svelte
  • src/lib/extend/tags/Tags.svelte
  • src/tests/forms/input-field/input.test.ts
  • src/tests/forms/timepicker/timepicker-dropdown.test.svelte
🧠 Learnings (4)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
📚 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/forms/toggle/toggle-prechecked.test.svelte
  • src/tests/forms/timepicker/timepicker-range.test.svelte
  • src/tests/forms/select/select-children.test.svelte
  • src/tests/forms/timepicker/timepicker-default.test.svelte
  • src/tests/forms/textarea/textarea-attributes.test.svelte
  • src/routes/docs-examples/extend/kanban-board/LocalStorage.svelte
  • src/tests/forms/timepicker/timepicker-callback.test.svelte
  • src/tests/forms/toggle/toggle-disabled.test.svelte
  • src/tests/forms/toggle/toggle-value.test.svelte
  • src/tests/forms/toggle/toggle-offlabel.test.svelte
  • src/tests/forms/timepicker/timepicker-select.test.svelte
  • src/tests/forms/toggle/toggle-basic.test.svelte
  • src/tests/forms/toggle/toggle-sizes.test.svelte
  • src/tests/forms/toggle/toggle-colors.test.svelte
  • src/routes/docs-examples/extend/kanban-board/UsingModal.svelte
  • src/tests/forms/timepicker/timepicker-disabled.test.svelte
  • src/tests/forms/timepicker/timepicker-inline.test.svelte
  • src/lib/extend/tags/Tags.svelte
  • src/tests/forms/timepicker/timepicker-dropdown.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/forms/timepicker/timepicker-range.test.svelte
  • src/tests/forms/timepicker/timepicker-default.test.svelte
  • src/tests/forms/timepicker/timepicker-callback.test.svelte
  • src/tests/forms/timepicker/timepicker.test.ts
  • src/tests/forms/timepicker/timepicker-select.test.svelte
  • src/tests/forms/timepicker/timepicker-disabled.test.svelte
  • src/tests/forms/timepicker/timepicker-inline.test.svelte
  • src/lib/extend/tags/Tags.svelte
  • src/tests/forms/timepicker/timepicker-dropdown.test.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/forms/button-toggle/button-toggle.test.ts
🔇 Additional comments (32)
src/tests/clipboard/clipboard.test.ts (1)

2-2: LGTM! Correct import style for user-event v14.x.

The change to a default import aligns with the standard API for @testing-library/user-event v14.6.1 and matches the usage pattern throughout the file.

src/tests/forms/input-field/input.test.ts (1)

3-3: LGTM! Standardized import aligns with user-event v14.x.

The default import is the correct style for @testing-library/user-event v14.6.1 and maintains consistency with the broader test suite updates in this PR.

src/tests/forms/select/select-children.test.svelte (1)

1-5: LGTM!

The script block correctly imports the Select component and uses Svelte 5's $state() rune for reactive state management. The initialization of value as an empty string is appropriate for testing the placeholder behavior.

src/tests/forms/phoneinput/phoneinput.test.ts (1)

3-3: Import pattern aligns with @testing-library/user-event best practices.

The default import is correct for @testing-library/user-event v14.6.1. All test usages with userEvent.setup() are compatible with this pattern.

src/tests/forms/timepicker/timepicker-default.test.svelte (1)

1-9: LGTM!

The test fixture is well-structured and correctly demonstrates basic Timepicker usage with state binding.

src/tests/forms/timepicker/timepicker-select.test.svelte (1)

1-14: LGTM!

The test fixture correctly demonstrates Timepicker in select mode with properly typed options.

src/tests/forms/timepicker/timepicker-range.test.svelte (1)

1-10: LGTM!

The test fixture correctly demonstrates Timepicker in range mode with separate bindings for start and end values.

src/tests/forms/timepicker/timepicker-disabled.test.svelte (1)

1-9: LGTM!

The test fixture correctly demonstrates Timepicker in a disabled state.

src/tests/forms/timepicker/timepicker-dropdown.test.svelte (1)

1-15: LGTM!

The test fixture correctly demonstrates Timepicker in dropdown mode with custom options and an option label.

src/tests/forms/timepicker/timepicker-inline.test.svelte (1)

1-11: LGTM!

The test component is well-structured and follows Svelte 5 patterns correctly. The use of $state for reactive values and proper data-testid attributes aligns with the testing approach in this PR.

src/tests/forms/timepicker/timepicker-callback.test.svelte (1)

1-21: LGTM!

The callback test component demonstrates good TypeScript practices with the type extraction pattern on line 5. The state management and callback handling are clean and appropriate for testing the onselect callback behavior.

src/tests/forms/timepicker/timepicker.test.ts (1)

1-222: LGTM!

The test suite provides comprehensive coverage across all Timepicker variants with clear test cases and proper assertions. The test structure is well-organized and follows testing best practices.

src/tests/forms/checkbox/checkbox.test.ts (2)

14-143: Comprehensive test coverage.

The test suites provide thorough coverage of checkbox functionality including single checkboxes, groups, choices arrays, and button variants. The tests properly use async/await patterns and verify both rendering and interaction behavior.


3-3: The import style is correct for the installed @testing-library/user-event version.

The default import of userEvent on line 3 is appropriate for @testing-library/user-event v14.6.1 (as specified in package.json). This version uses a default export, whereas v13 and earlier used named exports.

src/tests/forms/toggle/toggle-basic.test.svelte (1)

1-9: LGTM! Clean basic toggle test.

The test properly demonstrates basic Toggle functionality with correct Svelte 5 state management and two-way binding.

src/tests/forms/toggle/toggle-disabled.test.svelte (1)

1-9: LGTM! Disabled state test implemented correctly.

The test correctly demonstrates the disabled Toggle state with appropriate state management and prop usage.

src/tests/forms/toggle/toggle-colors.test.svelte (1)

1-19: LGTM! Color variants tested comprehensively.

The test properly demonstrates Toggle color variants with independent state management for each instance, enabling proper testing of the primary, red, and green color options.

src/tests/forms/toggle/toggle-value.test.svelte (1)

1-9: LGTM! Value prop test implemented correctly.

The test appropriately demonstrates Toggle usage with the value prop, which is essential for form integration scenarios.

src/tests/forms/toggle/toggle-prechecked.test.svelte (1)

1-9: LGTM! Pre-checked state test implemented correctly.

The test properly demonstrates Toggle with initial checked state, an important scenario for forms with default selections.

src/tests/forms/toggle/toggle-offlabel.test.svelte (1)

1-14: LGTM! Clean test implementation for off-label functionality.

The test correctly demonstrates the offLabel snippet usage with proper Svelte 5 syntax and includes appropriate test IDs for verification.

src/tests/forms/toggle/toggle-sizes.test.svelte (1)

1-19: LGTM! Well-structured size variant testing.

The test properly separates state for each size variant and uses clear test identifiers for independent verification.

src/tests/forms/toggle/toggle.test.ts (1)

1-260: LGTM! Comprehensive and well-structured test suite.

The test suite provides excellent coverage of Toggle component functionality:

  • Basic rendering and interaction
  • All size variants with independent behavior
  • Disabled state handling
  • Color variants
  • Off-label snippet support
  • Value attribute persistence
  • Pre-checked state management

The tests properly use data-scope and data-part attributes for querying elements, aligning with the broader PR changes. The consistent patterns and clear test descriptions make this suite maintainable and reliable.

src/tests/forms/button-toggle/button-toggle.test.ts (1)

3-3: The default import syntax is correct for @testing-library/user-event v14.6.1 and aligns with the recommended usage pattern for this version.

src/tests/forms/textarea/textarea-attributes.test.svelte (1)

1-5: LGTM! Clean test fixture.

This test fixture correctly renders a Textarea with native HTML attributes (rows, maxlength, placeholder) for attribute passthrough testing. The implementation is straightforward and appropriate for its purpose.

src/tests/forms/textarea/textarea.test.ts (3)

1-14: LGTM! Clean test setup.

The imports are appropriate, and the afterEach cleanup hook ensures proper test isolation by cleaning up the DOM after each test. This follows testing best practices.


22-227: Excellent test coverage for core functionality.

The test suite provides comprehensive coverage across all major Textarea variants (Basic, Clearable, Disabled, Header/Footer, Addon). The use of compareDocumentPosition for verifying header/footer ordering (lines 185-201) is particularly effective for validating DOM structure.


250-293: LGTM! Comprehensive event testing.

The event tests properly verify that native textarea events (input, change, focus, blur) are triggered as expected. The use of vi.fn() for event handler mocking is appropriate for verifying event propagation.

src/routes/docs-examples/extend/kanban-board/LocalStorage.svelte (1)

72-79: Consistent API migration applied.

The KanbanBoard props match the same migration pattern as UsingModal.svelte, correctly adopting the button key and cardProps object structure. The consistency across both example files ensures clear documentation of the new API.

src/routes/docs-examples/extend/kanban-board/UsingModal.svelte (1)

91-98: API migration is correct and complete.

The KanbanBoard props have been correctly updated: the classes.button key styles the add button, and the new cardProps object spreads per-card styling properties into KanbanCard. Both class and title fields within cardProps are valid properties that apply to the card component's styling slots.

Verification confirmed no remaining references to old prop names (such as card:, cardTitle:, or addButton:) elsewhere in the codebase, and both example files (UsingModal.svelte and LocalStorage.svelte) use the consistent new API structure.

src/lib/extend/tags/Tags.svelte (3)

166-167: Excellent systematic addition of data-scope and data-part attributes.

All major DOM elements now have semantic data-part attributes that align with the theme keys:

  • Root container: data-scope="tags" + data-part="base"
  • Tag items: data-part="item", data-part="label", data-part="close-button"
  • Input area: data-part="input-wrapper", data-part="input"
  • Dropdown: data-part="list", data-part="suggestion-item", data-part="option"

This provides clear styling hooks for theme customization and follows a consistent naming pattern.

Also applies to: 174-175, 178-178, 181-181, 183-183, 197-197, 199-199, 201-201


150-150: Helper messages properly annotated with data-part attributes.

Info, warning, and error messages now have semantic data-part attributes that match their theme keys (info, warning, error), improving both styling control and semantic clarity.

Also applies to: 155-155, 157-157, 162-162


29-31: Theme destructuring is correctly implemented.

The component uses $derived(getTheme("tags")) for reactive theming and destructures all required builder functions from tags() in theme.ts. Verification confirms theme.ts exports all expected keys: base, item, label, close, input, info, warning, error, inputWrapper, option, and list. The dual pattern of merging theme object properties with builder functions via clsx() is consistently applied throughout the component.

import { cleanup, render, screen } from "@testing-library/svelte";
import { expect, test, afterEach, describe } from "vitest";
import { userEvent } from "@testing-library/user-event";
import userEvent from "@testing-library/user-event";
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Jan 3, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's read the test file to see the current state
head -20 src/tests/list-group/listgroup.test.ts

Repository: themesberg/flowbite-svelte

Length of output: 894


🏁 Script executed:

#!/bin/bash
# Check the package.json for @testing-library/user-event version
grep -A 2 -B 2 "@testing-library/user-event" package.json

Repository: themesberg/flowbite-svelte

Length of output: 262


🏁 Script executed:

#!/bin/bash
# Search for all userEvent imports across test files to check consistency
rg "import.*userEvent.*from.*@testing-library/user-event" src/tests/ --type ts

Repository: themesberg/flowbite-svelte

Length of output: 5330


Correct import pattern for @testing-library/user-event v14, but refactor incomplete.

The switch to default import on line 3 is correct for v14.6.1's default export pattern. However, the project-wide refactor is incomplete—three test files still use the incorrect named import:

  • src/tests/forms/textarea/textarea.test.ts
  • src/tests/forms/select/multiselect.test.ts
  • src/tests/forms/select/select.test.ts

These files must be updated to use the default import pattern to maintain consistency.

🤖 Prompt for AI Agents
In src/tests/list-group/listgroup.test.ts around line 3, the import was changed
to use a default import for @testing-library/user-event (import userEvent from
"@testing-library/user-event"), which is correct for v14, but the refactor is
incomplete: update the other test files listed
(src/tests/forms/textarea/textarea.test.ts,
src/tests/forms/select/multiselect.test.ts,
src/tests/forms/select/select.test.ts) to use the same default import pattern
(replace any named imports like { userEvent } with the default import userEvent)
so all tests consistently use import userEvent from
"@testing-library/user-event"; ensure any usages remain the same after changing
the import.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

fixed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
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 (3)
src/tests/forms/timepicker/timepicker.test.ts (3)

126-147: Min/Max tests validate basic constraint application.

The tests verify that min/max attributes are correctly applied and accept valid values. For more comprehensive coverage, consider adding tests for boundary cases (values exactly at min/max) and invalid values (outside the range), though this can be deferred if prioritizing other work.


184-198: Inline button test works correctly, with minor redundancy.

The button selection test is properly structured. The if (button) check on line 193 is defensive but redundant since expect(button).toBeInTheDocument() on line 192 would fail if button is null. This is a minor nitpick and doesn't affect test correctness.


239-253: Callback tests properly validate data structure, with minor redundancy.

The tests correctly verify that callbacks are invoked with the proper data structure. The if (result) check on line 249 is defensive but redundant since screen.findByTestId on line 248 would throw if the element doesn't exist. This doesn't affect correctness but could be simplified.

📜 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 504cb11 and 5610ccf.

📒 Files selected for processing (4)
  • src/tests/forms/select/multiselect.test.ts
  • src/tests/forms/select/select.test.ts
  • src/tests/forms/textarea/textarea.test.ts
  • src/tests/forms/timepicker/timepicker.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/tests/forms/select/multiselect.test.ts
  • src/tests/forms/select/select.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/forms/textarea/textarea.test.ts
  • src/tests/forms/timepicker/timepicker.test.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: shinokada
Repo: themesberg/flowbite-svelte PR: 0
File: :0-0
Timestamp: 2026-01-01T13:12:34.868Z
Learning: Files under the `src/routes/llm` directory should be ignored during reviews in the themesberg/flowbite-svelte repository, as they are automatically updated when new versions are published.
📚 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/forms/timepicker/timepicker.test.ts
🔇 Additional comments (11)
src/tests/forms/timepicker/timepicker.test.ts (6)

1-16: LGTM! Test setup is properly configured.

The imports and cleanup are correctly structured. The pattern of importing separate test component files for each variant provides good test isolation.


53-74: LGTM! Select type tests properly use userEvent.

The tests correctly use userEvent.selectOptions() for dropdown interaction, which provides realistic user simulation.


76-124: LGTM! Range tests thoroughly validate independent start/end time inputs.

The tests correctly verify that start and end inputs update independently, and check for proper rendering of range-specific UI elements (separator, buttons).


149-167: Dropdown tests validate UI element rendering.

The tests verify that the dropdown UI elements render correctly. Based on learnings, the Dropdown functionality works as intended. If dropdown interaction behavior (opening/closing, selecting times from dropdown) is tested elsewhere or can be deferred, this coverage is acceptable.


201-222: LGTM! Disabled state tests verify interaction prevention.

The tests correctly validate that disabled inputs prevent user interaction and maintain their initial value.


34-44: The direct value setting pattern for time inputs is documented and appropriate.

The code already explains this design choice with inline comments at each instance. Since fireEvent.input() is consistently fired after value manipulation, event handlers are properly triggered. This approach is appropriate for HTML time inputs, which have special browser handling that makes direct value setting + event firing more reliable than other methods.

src/tests/forms/textarea/textarea.test.ts (5)

1-14: LGTM!

The imports and test setup are correct. The cleanup after each test ensures proper test isolation.


22-241: Excellent test coverage and structure.

The test suites comprehensively cover the Textarea component's functionality across multiple variants and scenarios. The tests are well-organized, follow best practices with async/await, and include sophisticated DOM position validation. The coverage includes:

  • Basic input and multiline handling
  • Clearable functionality with conditional rendering
  • Disabled state behavior
  • Header/footer structural elements and positioning
  • Addon integration
  • HTML attributes (rows, maxlength)

243-286: LGTM!

The event tests correctly verify that native DOM events (input, change, focus, blur) are properly triggered during user interactions. The use of vi.fn() for mocking event handlers and the direct addEventListener approach are appropriate for testing native events.


169-173: The test is correct. The [data-part="footer"] attribute is a valid and properly defined part of the Textarea component. It is rendered at line 75 of Textarea.svelte and defined in the theme.ts slots with styling and conditional variants (hasFooter). The test appropriately verifies that the footer element is present in the DOM when rendered.


16-20: No action needed—the selector logic is correct.

The Textarea component intentionally uses two rendering modes:

  • Unwrapped mode (no header/footer/addon): textarea[data-part="wrapper"] is the textarea element itself, serving as the main container
  • Wrapped mode (with header/footer/addon): textarea[data-part="base"] is the textarea element nested inside a wrapper div

The helper function correctly queries both selectors and returns whichever exists, making it compatible with both component variants. The data-part naming is semantically appropriate for each mode.

@shinokada shinokada merged commit ccdbb21 into themesberg:version-2 Jan 3, 2026
1 check failed
This was referenced Jan 3, 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