Conversation
|
@shinokada is attempting to deploy a commit to the Bergside Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughWalkthroughDesign-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
Sequence Diagram(s)(omitted) Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings, 1 inconclusive)
✨ Finishing touches
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
src/lib/device-mockups/Android.sveltesrc/lib/device-mockups/DefaultMockup.sveltesrc/lib/device-mockups/Desktop.sveltesrc/lib/device-mockups/Ios.sveltesrc/lib/device-mockups/Laptop.sveltesrc/lib/device-mockups/Smartwatch.sveltesrc/lib/device-mockups/Tablet.sveltesrc/lib/device-mockups/theme.tssrc/lib/drawer/Drawer.sveltesrc/lib/drawer/Drawerhead.sveltesrc/lib/drawer/theme.tssrc/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.tssrc/tests/device-mockups/ios-with-classes.test.sveltesrc/lib/drawer/Drawer.sveltesrc/lib/device-mockups/Smartwatch.sveltesrc/lib/device-mockups/Desktop.sveltesrc/lib/drawer/Drawerhead.sveltesrc/lib/device-mockups/theme.tssrc/lib/device-mockups/Ios.sveltesrc/lib/device-mockups/Laptop.sveltesrc/lib/device-mockups/DefaultMockup.sveltesrc/lib/device-mockups/Android.sveltesrc/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.sveltesrc/lib/drawer/Drawer.sveltesrc/lib/device-mockups/Smartwatch.sveltesrc/lib/device-mockups/Desktop.sveltesrc/lib/drawer/Drawerhead.sveltesrc/lib/device-mockups/Ios.sveltesrc/lib/device-mockups/Laptop.sveltesrc/lib/device-mockups/DefaultMockup.sveltesrc/lib/device-mockups/Android.sveltesrc/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"anddata-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. Thedata-partattributes 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. Alldata-partattributes 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. Thedata-partattributes are correctly updated, and the addition ofdata-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. Alldata-partattributes 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.,
leftMid→leftMiddle,leftBot→leftBottom,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, andleftBot. These need to be corrected to match the actual implementation:
- Android:
screen,notch,leftTop,leftMiddle,leftBottom,right(nottop,leftMid,leftBot)- iOS:
screen,notch,leftTop,leftBottom,right(nottop,leftBot)- DefaultMockup/Tablet: Similar updates needed
Recommended actions:
- Update test documentation and comments to reflect the actual new slot names
- Add migration notes to the PR description documenting all key renames for each device type
- 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
closeIconprop tocloseIconSnippetcleanly avoids collision with the theme'scloseIconstyling key while preserving the public API.
12-27: Approve refactoring; theme exports verified.The rename from
button/svgtocloseButton/closeIconis applied consistently in destructuring, data-part attributes, and class bindings. Thesrc/lib/drawer/theme.tsexports adrawerhead()function with the requiredcloseButtonandcloseIconkeys, 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 thesmartwatch()function intheme.tsand correctly destructured and applied throughout the template with matchingdata-partattributes.src/lib/device-mockups/Desktop.svelte (1)
12-23: Approve standardization; theme alignment confirmed.The rename from
inner/bot/botUndertoscreen/bottom/bottomBaseis consistently applied across destructuring, data-part attributes, and styling references. Thedesktop()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—
slot→screen,top→notch,leftMid→leftMiddle,leftBot→leftBottom—is correctly applied. Theme exports intheme.ts(lines 7-17) match the destructured properties in the component:base,screen,notch,leftTop,leftMiddle,leftBottom,right. TheAndroidVariantstype correctly derives from the updatedandroid()function. No stale references to old property names exist.
| 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" |
There was a problem hiding this comment.
🧩 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.svelteRepository: 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
fiRepository: 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 -30Repository: 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.mdRepository: 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.
…ooter, gallery, kbd, list-group directories
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (19)
src/lib/dropdown/Dropdown.sveltesrc/lib/dropdown/DropdownDivider.sveltesrc/lib/dropdown/DropdownGroup.sveltesrc/lib/dropdown/DropdownHeader.sveltesrc/lib/dropdown/DropdownItem.sveltesrc/lib/dropdown/theme.tssrc/lib/footer/Footer.sveltesrc/lib/footer/FooterBrand.sveltesrc/lib/footer/FooterCopyright.sveltesrc/lib/footer/FooterIcon.sveltesrc/lib/footer/FooterLink.sveltesrc/lib/footer/FooterLinkGroup.sveltesrc/lib/footer/theme.tssrc/lib/gallery/Gallery.sveltesrc/lib/indicator/Indicator.sveltesrc/lib/kbd/Kbd.sveltesrc/lib/list-group/Listgroup.sveltesrc/lib/list-group/ListgroupItem.sveltev2-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.sveltesrc/lib/footer/FooterLink.sveltesrc/lib/dropdown/DropdownItem.sveltesrc/lib/list-group/ListgroupItem.sveltesrc/lib/list-group/Listgroup.sveltesrc/lib/footer/Footer.sveltesrc/lib/footer/FooterIcon.sveltesrc/lib/dropdown/Dropdown.sveltesrc/lib/dropdown/DropdownGroup.sveltesrc/lib/dropdown/theme.tssrc/lib/indicator/Indicator.sveltesrc/lib/dropdown/DropdownHeader.sveltesrc/lib/footer/FooterLinkGroup.sveltesrc/lib/dropdown/DropdownDivider.sveltesrc/lib/footer/FooterCopyright.sveltesrc/lib/footer/FooterBrand.sveltesrc/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.sveltesrc/lib/footer/FooterLink.sveltesrc/lib/dropdown/DropdownItem.sveltesrc/lib/list-group/ListgroupItem.sveltesrc/lib/list-group/Listgroup.sveltesrc/lib/footer/Footer.sveltesrc/lib/footer/FooterIcon.sveltesrc/lib/dropdown/Dropdown.sveltesrc/lib/dropdown/DropdownGroup.sveltesrc/lib/indicator/Indicator.sveltesrc/lib/dropdown/DropdownHeader.sveltesrc/lib/footer/FooterLinkGroup.sveltesrc/lib/dropdown/DropdownDivider.sveltesrc/lib/footer/FooterCopyright.sveltesrc/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.sveltesrc/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.sveltesrc/lib/dropdown/Dropdown.sveltesrc/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.sveltesrc/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"anddata-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-scopeanddata-partattributes 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"anddata-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-scopeanddata-partattributes 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-scopeanddata-partattributes 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
baseto a$derivedexpression (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-scopeanddata-partattributes 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-scopeanddata-partattributes 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-scopeanddata-partattributes provides consistent component identification without altering functionality. Appropriately applied only whenhrefis 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
spanandimgtolabelandimagein 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
bySpantolabel. FooterCopyright.svelte correctly destructures and applies the newlabelslot (line 16 and 26), and no references to the old key exist in the codebase. The public API viaFooterCopyrightVariantsproperly exposes this slot.src/lib/dropdown/theme.ts (1)
20-22: All consumers of the dropdownItem slot have been properly updated to use the newitemkey.The slot migration from
litoitemis complete. DropdownItem.svelte (line 18) correctly imports{base, active, item}from the dropdownItem theme and applies the styling on line 19 usingtheme?.item. No remaining references to the oldlislot 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"anddata-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
$derivedinstead 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/imgtolabel/imageimproves 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
bySpantolabelimproves clarity, and all references are updated correctly. Data attributes are properly scoped for each element.src/lib/dropdown/DropdownItem.svelte (1)
22-22: Verify emptydata-partattribute.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.
There was a problem hiding this comment.
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 tolist. 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
📒 Files selected for processing (19)
src/lib/dropdown/DropdownItem.sveltesrc/lib/footer/FooterCopyright.sveltesrc/lib/list-group/Listgroup.sveltesrc/lib/mega-menu/MegaMenu.sveltesrc/lib/mega-menu/theme.tssrc/lib/navbar/Menu.sveltesrc/lib/navbar/NavBrand.sveltesrc/lib/navbar/NavContainer.sveltesrc/lib/navbar/NavLi.sveltesrc/lib/navbar/NavUl.sveltesrc/lib/navbar/Navbar.sveltesrc/lib/navbar/index.tssrc/lib/navbar/theme.tssrc/lib/theme-provider/themes.tssrc/lib/types.tssrc/routes/docs-examples/components/mega-menu/Cta.sveltesrc/routes/docs-examples/components/mega-menu/Image.sveltesrc/routes/layouts/FlowbiteSvelteLayout.sveltesrc/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.sveltesrc/lib/footer/FooterCopyright.sveltesrc/lib/navbar/NavBrand.sveltesrc/lib/theme-provider/themes.tssrc/lib/mega-menu/theme.tssrc/lib/navbar/NavContainer.sveltesrc/routes/docs-examples/components/mega-menu/Cta.sveltesrc/lib/navbar/Menu.sveltesrc/lib/navbar/NavLi.sveltesrc/routes/layouts/FlowbiteSvelteLayout.sveltesrc/tests/mega-menu/full-mega-menu.test.sveltesrc/routes/docs-examples/components/mega-menu/Image.sveltesrc/lib/navbar/NavUl.sveltesrc/lib/navbar/Navbar.sveltesrc/lib/navbar/index.tssrc/lib/types.tssrc/lib/navbar/theme.tssrc/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.sveltesrc/lib/footer/FooterCopyright.sveltesrc/lib/navbar/NavBrand.sveltesrc/lib/navbar/NavContainer.sveltesrc/routes/docs-examples/components/mega-menu/Cta.sveltesrc/lib/navbar/Menu.sveltesrc/lib/navbar/NavLi.sveltesrc/routes/layouts/FlowbiteSvelteLayout.sveltesrc/tests/mega-menu/full-mega-menu.test.sveltesrc/routes/docs-examples/components/mega-menu/Image.sveltesrc/lib/navbar/NavUl.sveltesrc/lib/navbar/Navbar.sveltesrc/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.sveltesrc/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"anddata-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"anddata-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
bySpantolabel(line 26)- Add
data-part="link"to the anchor tag (line 22)- Add
data-part="label"to the span tag (line 26)- Reference
theme?.labelandstyling?.labelconsistently 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 intheme.tshas been properly updated with thelabelslot replacing the previousbySpan, and no remaining references tobySpanexist 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
navLitheme with slots and responsive variants is well-structured and follows the same pattern asnavUl.
8-8: No breaking API change to document—the original exports werenavUl/navLi, notnavbarUl/navbarLi.The references to
navbarUlin Frame.svelte are local theme configuration keys defined within that component's<script module>, not exports fromsrc/lib/navbar/theme.ts. The actual exports from theme.ts arenavUlandnavLiwith corresponding typesNavbarUlVariantsandNavLiVariants, 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
extratoaddonis 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
addonsnippet 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-scopeanddata-partattributes 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
addonsnippet 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 (
navbarUl→navUl) and the addition ofnavLiare consistent with the changes intheme.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
ultolistcorrectly 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
contentwrapper layer, aligning with the updated theme API. Theme reactivity uses$derivedappropriately, 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
addoninstead ofextra(breaking API change noted in PR description), and slot keys have been updated tocontent,list, andfooter. 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
navbarUltonavUl, and slot key renamed fromultolist. Theme reactivity uses$derivedappropriately.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,classesprop added, and theme structure changed to usebaseanditemslots. Data attributes added consistently, and theme reactivity uses$derivedappropriately.Based on learnings: Props like
classesare 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
addonprop 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 oldnavbarLiornavbarUlnames anywhere in the codebase. All references throughout the project already use the new namesnavLiandnavUl, confirming the breaking change has been properly applied with no dangling references.
… popover, progress, rating, sidebar, skeleton directories
There was a problem hiding this comment.
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 inListPlaceholderandTextPlaceholder. While this works becausetestimonialPlaceholder()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 addingdata-partattributes to footer child elements for consistency.The skeleton lines and SVG inside the footer (lines 36, 43, 44) don't have
data-partattributes, 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 bydata-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
spanClassis used with thelabelkey on Line 47. For consistency with other example files (Branding.svelte, CloseButton.svelte), consider renaming this tolabelClass.🔎 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
📒 Files selected for processing (54)
src/lib/navbar/theme.tssrc/lib/pagination/Pagination.sveltesrc/lib/pagination/PaginationButton.sveltesrc/lib/pagination/PaginationNav.sveltesrc/lib/pagination/theme.tssrc/lib/popover/Popover.sveltesrc/lib/popover/theme.tssrc/lib/progress/Progressbar.sveltesrc/lib/progress/Progressradial.sveltesrc/lib/progress/theme.tssrc/lib/rating/AdvancedRating.sveltesrc/lib/rating/Rating.sveltesrc/lib/rating/Review.sveltesrc/lib/rating/ScoreRating.sveltesrc/lib/rating/theme.tssrc/lib/sidebar/Sidebar.sveltesrc/lib/sidebar/SidebarBrand.sveltesrc/lib/sidebar/SidebarButton.sveltesrc/lib/sidebar/SidebarCta.sveltesrc/lib/sidebar/SidebarDropdownWrapper.sveltesrc/lib/sidebar/SidebarItem.sveltesrc/lib/sidebar/theme.tssrc/lib/skeleton/CardPlaceholder.sveltesrc/lib/skeleton/ImagePlaceholder.sveltesrc/lib/skeleton/ListPlaceholder.sveltesrc/lib/skeleton/Skeleton.sveltesrc/lib/skeleton/TestimonialPlaceholder.sveltesrc/lib/skeleton/TextPlaceholder.sveltesrc/lib/skeleton/VideoPlaceholder.sveltesrc/lib/skeleton/WidgetPlaceholder.sveltesrc/lib/skeleton/theme.tssrc/lib/types.tssrc/routes/admin-dashboard/(sidebar)/Sidebar.sveltesrc/routes/docs-examples/components/drawer/Navigation.sveltesrc/routes/docs-examples/components/sidebar/AllOpen.sveltesrc/routes/docs-examples/components/sidebar/AlwaysOpen.sveltesrc/routes/docs-examples/components/sidebar/Branding.sveltesrc/routes/docs-examples/components/sidebar/BrandingUsingChildren.sveltesrc/routes/docs-examples/components/sidebar/CloseButton.sveltesrc/routes/docs-examples/components/sidebar/Cta.sveltesrc/routes/docs-examples/components/sidebar/Default.sveltesrc/routes/docs-examples/components/sidebar/LinksAndActive.sveltesrc/routes/docs-examples/components/sidebar/LinksAndActive2.sveltesrc/routes/docs-examples/components/sidebar/MultiLevel.sveltesrc/routes/docs-examples/components/sidebar/MultiLevel2.sveltesrc/routes/docs-examples/components/sidebar/ObjectEx.sveltesrc/routes/docs-examples/components/sidebar/Separator.sveltesrc/routes/docs-examples/components/sidebar/Single.sveltesrc/routes/docs-examples/components/sidebar/Static.sveltesrc/routes/docs-examples/components/sidebar/Transition.sveltesrc/routes/docs-examples/extend/progressradial/Animation.sveltesrc/routes/docs-examples/extend/progressradial/Colors.sveltesrc/routes/docs-examples/extend/split-pane/+page.sveltesrc/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.sveltesrc/routes/docs-examples/extend/progressradial/Animation.sveltesrc/routes/docs-examples/components/sidebar/AlwaysOpen.sveltesrc/routes/docs-examples/components/sidebar/Separator.sveltesrc/lib/pagination/PaginationButton.sveltesrc/lib/sidebar/SidebarBrand.sveltesrc/lib/skeleton/CardPlaceholder.sveltesrc/lib/rating/ScoreRating.sveltesrc/routes/docs-examples/components/sidebar/Transition.sveltesrc/routes/docs-examples/components/sidebar/MultiLevel2.sveltesrc/lib/rating/AdvancedRating.sveltesrc/lib/navbar/theme.tssrc/lib/progress/theme.tssrc/lib/pagination/Pagination.sveltesrc/routes/docs-examples/components/sidebar/LinksAndActive2.sveltesrc/lib/sidebar/SidebarButton.sveltesrc/routes/docs-examples/components/sidebar/Static.sveltesrc/lib/skeleton/TestimonialPlaceholder.sveltesrc/lib/skeleton/Skeleton.sveltesrc/routes/docs-examples/extend/split-pane/+page.sveltesrc/lib/progress/Progressradial.sveltesrc/lib/rating/theme.tssrc/routes/docs-examples/components/sidebar/CloseButton.sveltesrc/routes/docs-examples/extend/progressradial/Colors.sveltesrc/lib/skeleton/theme.tssrc/routes/layouts/ComponentsLayout.sveltesrc/lib/sidebar/SidebarCta.sveltesrc/lib/skeleton/ListPlaceholder.sveltesrc/routes/docs-examples/components/sidebar/LinksAndActive.sveltesrc/lib/popover/theme.tssrc/lib/skeleton/WidgetPlaceholder.sveltesrc/lib/skeleton/ImagePlaceholder.sveltesrc/routes/docs-examples/components/sidebar/ObjectEx.sveltesrc/routes/docs-examples/components/sidebar/Default.sveltesrc/lib/sidebar/Sidebar.sveltesrc/routes/admin-dashboard/(sidebar)/Sidebar.sveltesrc/routes/docs-examples/components/sidebar/BrandingUsingChildren.sveltesrc/lib/rating/Review.sveltesrc/routes/docs-examples/components/sidebar/Branding.sveltesrc/lib/sidebar/SidebarItem.sveltesrc/lib/popover/Popover.sveltesrc/lib/pagination/PaginationNav.sveltesrc/lib/skeleton/TextPlaceholder.sveltesrc/lib/progress/Progressbar.sveltesrc/lib/rating/Rating.sveltesrc/routes/docs-examples/components/sidebar/MultiLevel.sveltesrc/routes/docs-examples/components/sidebar/Cta.sveltesrc/routes/docs-examples/components/drawer/Navigation.sveltesrc/routes/docs-examples/components/sidebar/Single.sveltesrc/lib/sidebar/SidebarDropdownWrapper.sveltesrc/lib/sidebar/theme.tssrc/lib/pagination/theme.tssrc/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.sveltesrc/routes/docs-examples/extend/progressradial/Animation.sveltesrc/routes/docs-examples/components/sidebar/AlwaysOpen.sveltesrc/routes/docs-examples/components/sidebar/Separator.sveltesrc/lib/pagination/PaginationButton.sveltesrc/lib/sidebar/SidebarBrand.sveltesrc/lib/skeleton/CardPlaceholder.sveltesrc/lib/rating/ScoreRating.sveltesrc/routes/docs-examples/components/sidebar/Transition.sveltesrc/routes/docs-examples/components/sidebar/MultiLevel2.sveltesrc/lib/rating/AdvancedRating.sveltesrc/lib/pagination/Pagination.sveltesrc/routes/docs-examples/components/sidebar/LinksAndActive2.sveltesrc/lib/sidebar/SidebarButton.sveltesrc/routes/docs-examples/components/sidebar/Static.sveltesrc/lib/skeleton/TestimonialPlaceholder.sveltesrc/lib/skeleton/Skeleton.sveltesrc/routes/docs-examples/extend/split-pane/+page.sveltesrc/lib/progress/Progressradial.sveltesrc/routes/docs-examples/components/sidebar/CloseButton.sveltesrc/routes/docs-examples/extend/progressradial/Colors.sveltesrc/routes/layouts/ComponentsLayout.sveltesrc/lib/sidebar/SidebarCta.sveltesrc/lib/skeleton/ListPlaceholder.sveltesrc/routes/docs-examples/components/sidebar/LinksAndActive.sveltesrc/lib/skeleton/WidgetPlaceholder.sveltesrc/lib/skeleton/ImagePlaceholder.sveltesrc/routes/docs-examples/components/sidebar/ObjectEx.sveltesrc/routes/docs-examples/components/sidebar/Default.sveltesrc/lib/sidebar/Sidebar.sveltesrc/routes/admin-dashboard/(sidebar)/Sidebar.sveltesrc/routes/docs-examples/components/sidebar/BrandingUsingChildren.sveltesrc/lib/rating/Review.sveltesrc/routes/docs-examples/components/sidebar/Branding.sveltesrc/lib/sidebar/SidebarItem.sveltesrc/lib/popover/Popover.sveltesrc/lib/pagination/PaginationNav.sveltesrc/lib/skeleton/TextPlaceholder.sveltesrc/lib/progress/Progressbar.sveltesrc/lib/rating/Rating.sveltesrc/routes/docs-examples/components/sidebar/MultiLevel.sveltesrc/routes/docs-examples/components/sidebar/Cta.sveltesrc/routes/docs-examples/components/drawer/Navigation.sveltesrc/routes/docs-examples/components/sidebar/Single.sveltesrc/lib/sidebar/SidebarDropdownWrapper.sveltesrc/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.sveltesrc/routes/docs-examples/components/sidebar/MultiLevel2.sveltesrc/routes/docs-examples/extend/progressradial/Colors.sveltesrc/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.sveltesrc/routes/docs-examples/components/sidebar/Transition.sveltesrc/routes/docs-examples/components/sidebar/MultiLevel2.sveltesrc/lib/sidebar/Sidebar.sveltesrc/lib/popover/Popover.sveltesrc/routes/docs-examples/components/sidebar/MultiLevel.sveltesrc/routes/docs-examples/components/sidebar/Single.sveltesrc/lib/sidebar/SidebarDropdownWrapper.sveltesrc/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.tssrc/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
headinginstead ofh3, 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"anddata-partattributes enhance component identification. All class bindings correctly reference the renamedheadingtoken (previouslyh3), 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
h3toheadingis 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.,
line→skeletonLine,area→imagePlaceholder,wrapper→base). 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
classesprop with the old slot names.src/lib/skeleton/VideoPlaceholder.svelte (1)
14-14: LGTM! Data attributes added correctly.The
data-scope="video-placeholder"anddata-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
widgetPlaceholdertheme:chartContainer,chartBar, andlabelLine(previouslywrapper,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-partattributes matching the semantic part names- Properly merge theme and custom classes via
clsxThe 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
imagePlaceholdertheme and aliasesimagePlaceholdertoimageAreafor 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-partattributes (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:
baseandskeletonLine(previouslywrapperandline), 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
skeletonLineslot with proper theme/class merging- Maintain the
basecontainer stylingThe 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"anddata-partattributes are correctly applied throughout the component, enabling fine-grained styling and testing hooks. The class binding patternslotFn({ 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"anddata-partattributes are consistently applied. The renamed slots (primaryLine,secondaryLine,avatarIcon,authorInfo) follow the semantic naming convention. The SVG element correctly includesaria-hidden="true"for accessibility.src/lib/skeleton/TextPlaceholder.svelte (2)
9-15: LGTM! Theme reactivity correctly implemented.The
getTheme()andtextPlaceholder()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"anddata-partattributes are correctly applied to all elements. The repetitive line-group structure appropriately represents the skeleton text placeholder visual pattern. Class bindings consistently follow theslotFn({ class: clsx(...) })pattern.src/lib/skeleton/CardPlaceholder.svelte (2)
9-11: LGTM! Theme reactivity correctly implemented.The
getTheme()andcardPlaceholder()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"anddata-partattributes are correctly applied to the main structural elements. The SVG includes properaria-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
classtoclassNameimproves code clarity and aligns with common React/JSX conventions.
32-33: LGTM!The addition of
data-scope="pagination"anddata-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
visiblePagesprop (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
paginationNavand the addition ofdata-partattributes for scoping are well-implemented. Thedata-partattributes onPaginationButtoncomponents (lines 82, 100) will correctly propagate to the underlying DOM elements viarestProps. 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
outsideslot has been renamed tolabelWrapperfor 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
outsidetolabelWrapperin the classes prop. The first example (line 5) now omits thecolorprop 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:
outside→labelWrapperspan→labelTextprogressCls→percentageThese 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 containerdata-partattributes on: label-wrapper, label-text, percentage, base, background, foreground, and labelThese 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:
inside→bar(more specific to the progress bar element)outside→labelWrapper(clearer wrapper purpose)span→labelText(descriptive element name)progressCls→percentage(explicit about content)
21-97: All color variants updated consistently.All 18 color variants have been properly updated with the new
barslot 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:
outside→labelWrapperspan→labelTextprogressCls→percentageThis 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:
inside→baroutside→labelWrapperspan→labelTextprogressCls→percentageThe 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 componentdata-partattributes on: label-wrapper, label-text, percentage, base, label, and barThis 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
ptovalueand 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
ratingLabelandratingValueinstead of shadowing thelabelfunction 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.tsare 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
classesprop 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:
triggerandlistforSidebarDropdownWrapperlabelforSidebarItemThe 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
spanClasstolabelClassimproves 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
NavbarUlVariantstype correctly references the renamednavUl, and the newNavLiVariantstype supports the restructurednavLiconstant with its slots-based design.
32-114: LGTM!navUlslot rename fromultolistis 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
listbetter describes the slot's purpose.
116-157: Downstream consumer NavLi.svelte is properly updated for thenavLislots structure change.The
navLiconstant's restructuring from a single string to aslotsobject withbaseanditemkeys 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 consumenavLi, 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 thelabelkey.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 newlabelclass 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 newtriggerclass key.The rename from
btntotriggerprovides better semantic clarity for the dropdown toggle element.
49-57: LGTM! SidebarItem instances correctly use the newlabelclass 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 updatedtriggerclass key.
51-59: LGTM! SidebarItem instances correctly use thelabelclass key.src/routes/docs-examples/components/sidebar/LinksAndActive2.svelte (1)
7-7: LGTM! API usage correctly updated.The rename from
spanClasstolabelClassand the corresponding update to useclasses={{ label: labelClass }}correctly aligns with the broader migration where SidebarItem's styling key changed fromspantolabel.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
labelkey instead ofspanfor 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
labelstyling 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
labelreplacesspanas 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
labelstyling 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
btntotriggercorrectly 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/brandNamevsimg/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:
btn→trigger(3 instances)- SidebarItem:
span→label(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
svg→iconfor more generic/semantic naming- Added
data-scope/data-partattributes 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
labelClassfor 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.btn→classes.trigger; SidebarItem:classes.span→classes.label) have been fully implemented. The code under review correctly uses the new API withclasses={{ 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-scopeanddata-partattributes provides semantic hooks for styling and testing. The class binding on line 27 correctly referencestheme?.label(updated from the oldtheme?.span).
19-19: LGTM: Slot key renamed fromspantolabelwith proper type updates.The destructuring correctly aliases
labeltolabelClsat line 19, and the theme definition confirms all slots have been updated (base,link,label). TheSidebarItemPropstypes reflect this change through theClasses<typeof sidebarItem>inheritance, wheresidebarItemnow defineslabelinstead ofspan.Internal usage is consistent: line 27 correctly uses
styling?.label. This is a breaking change for consumers usingclasses.spanwith 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"anddata-partattributes are added consistently across both the conditional (lines 113-118) and else (lines 124-135) branches. The backdrop elements (lines 100, 102) correctly includedata-part="backdrop". All class bindings use the newcontent(...)token consistently.Also applies to: 113-118, 124-135
59-59: Confirm slot key rename fromdivtocontent.The destructuring on line 59 correctly uses
content. The TypeScript typeSidebarProps['classes']has been automatically updated via theClasses<typeof sidebar>type, which derives keys from the sidebar's slots—now only supportingcontentinstead ofdiv. No remaining consumer code using the oldclasses.divpattern was found in the Sidebar context.src/routes/docs-examples/components/sidebar/Separator.svelte (1)
7-7: LGTM: Example updated to use the newlabelclass key.The variable rename (
spanClass→labelClass) and the updatedclassesprop bindings correctly reflect the new public API ofSidebarItem.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-scopeanddata-partattributes provide clear semantic hooks. Class bindings correctly referencetheme?.labelWrapperandtheme?.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 typeSidebarCtaProps['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 newlabelclass key.The variable rename (
spanClass→labelClass) and the updatedclassesprop bindings correctly reflect the new public API ofSidebarItem.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
divtocontentfor 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
labelinstead ofspanfor 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
spanClasstolabelClassaligns with the updatedlabelkey in the SidebarItem API.
36-36: LGTM! Semantic key for SidebarBrand logo.The update from
imgtologoimproves API clarity for the SidebarBrand component.
42-50: LGTM! Consistent usage of label key.Both SidebarItem instances correctly use the
labelkey with the renamedlabelClassvariable.src/routes/docs-examples/components/sidebar/CloseButton.svelte (2)
7-7: LGTM! Variable renamed to match new API.Consistent with other files,
spanClassrenamed tolabelClassto align with the updated SidebarItem API.
36-44: LGTM! Correct usage of label key.Both SidebarItem instances properly use the
labelkey 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
triggerinstead ofbtnfor class mappings, aligning with the new API.
47-47: LGTM! Correct usage of label key.The SidebarItem correctly uses the
labelkey (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 correspondingdata-partattributes (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: UsesiconslotSidebarBrand.svelte: UseslogoandbrandNameslotsSidebarCta.svelte: UseslabelWrapperandbadgeslotsNo 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,listsidebarItem:link,labelBoth 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 fromdivtocontentis 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
There was a problem hiding this comment.
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 thedata-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 lineAprimaryLineTestimonialPlaceholder lineBsecondaryLineTestimonialPlaceholder svgavatarIconTestimonialPlaceholder contentauthorInfo
🧹 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:
- Documenting why underscore is appropriate here (if it's a convention in this codebase)
- Using a more descriptive prefix that clarifies the source (e.g.,
themeTitlePart,variantTitle, ortitlePart)- 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 ifrestPropsare 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
📒 Files selected for processing (44)
design-system.mdsrc/lib/dialog/Dialog.sveltesrc/lib/drawer/Drawer.sveltesrc/lib/extend/command-palette/CommandPalette.sveltesrc/lib/forms/dropzone/Dropzone.sveltesrc/lib/forms/dropzone/theme.tssrc/lib/modal/Modal.sveltesrc/lib/pagination/Pagination.sveltesrc/lib/pagination/theme.tssrc/lib/popover/Popover.sveltesrc/lib/skeleton/CardPlaceholder.sveltesrc/lib/skeleton/TestimonialPlaceholder.sveltesrc/lib/spinner/Spinner.sveltesrc/lib/stepper/BreadcrumbStepper.sveltesrc/lib/stepper/DetailedStepper.sveltesrc/lib/stepper/ProgressStepper.sveltesrc/lib/stepper/Stepper.sveltesrc/lib/stepper/TimelineStepper.sveltesrc/lib/stepper/VerticalStepper.sveltesrc/lib/table/Table.sveltesrc/lib/table/TableSearch.sveltesrc/lib/table/theme.tssrc/lib/tabs/TabItem.sveltesrc/lib/tabs/Tabs.sveltesrc/lib/timeline/Activity.sveltesrc/lib/timeline/ActivityItem.sveltesrc/lib/timeline/Group.sveltesrc/lib/timeline/GroupItem.sveltesrc/lib/timeline/Timeline.sveltesrc/lib/timeline/TimelineItem.sveltesrc/lib/timeline/theme.tssrc/lib/toast/Toast.sveltesrc/lib/toast/ToastContainer.sveltesrc/lib/toolbar/Toolbar.sveltesrc/lib/toolbar/ToolbarButton.sveltesrc/lib/toolbar/ToolbarGroup.sveltesrc/lib/tooltip/Tooltip.sveltesrc/lib/types.tssrc/lib/utils/Arrow.sveltesrc/lib/utils/Popper.sveltesrc/routes/docs-examples/components/sidebar/Single.sveltesrc/routes/docs/forms/file-input.mdsrc/routes/layouts/FlowbiteSvelteLayout.sveltev2-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.sveltesrc/lib/tooltip/Tooltip.sveltesrc/lib/stepper/ProgressStepper.sveltesrc/lib/utils/Popper.sveltesrc/lib/stepper/Stepper.sveltesrc/lib/stepper/BreadcrumbStepper.sveltesrc/lib/toast/ToastContainer.sveltesrc/lib/timeline/Group.sveltesrc/lib/toolbar/ToolbarGroup.sveltesrc/lib/dialog/Dialog.sveltesrc/lib/modal/Modal.sveltesrc/lib/stepper/VerticalStepper.sveltesrc/lib/spinner/Spinner.sveltesrc/lib/toolbar/ToolbarButton.sveltesrc/lib/stepper/TimelineStepper.sveltesrc/lib/skeleton/TestimonialPlaceholder.sveltesrc/lib/table/TableSearch.sveltesrc/lib/table/theme.tssrc/lib/timeline/Timeline.sveltesrc/lib/toast/Toast.sveltesrc/lib/extend/command-palette/CommandPalette.sveltesrc/lib/toolbar/Toolbar.sveltesrc/lib/utils/Arrow.sveltesrc/lib/timeline/GroupItem.sveltesrc/lib/timeline/ActivityItem.sveltesrc/lib/table/Table.sveltesrc/lib/tabs/Tabs.sveltesrc/lib/timeline/Activity.sveltesrc/lib/pagination/theme.tssrc/lib/pagination/Pagination.sveltesrc/lib/timeline/theme.tssrc/lib/forms/dropzone/Dropzone.sveltesrc/lib/forms/dropzone/theme.tssrc/lib/types.tssrc/lib/timeline/TimelineItem.sveltesrc/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.sveltesrc/lib/tooltip/Tooltip.sveltesrc/lib/stepper/ProgressStepper.sveltesrc/lib/utils/Popper.sveltesrc/lib/stepper/Stepper.sveltesrc/lib/stepper/BreadcrumbStepper.sveltesrc/lib/toast/ToastContainer.sveltesrc/lib/timeline/Group.sveltesrc/lib/toolbar/ToolbarGroup.sveltesrc/lib/dialog/Dialog.sveltesrc/lib/modal/Modal.sveltesrc/lib/stepper/VerticalStepper.sveltesrc/lib/spinner/Spinner.sveltesrc/lib/toolbar/ToolbarButton.sveltesrc/lib/stepper/TimelineStepper.sveltesrc/lib/skeleton/TestimonialPlaceholder.sveltesrc/lib/table/TableSearch.sveltesrc/lib/timeline/Timeline.sveltesrc/lib/toast/Toast.sveltesrc/lib/extend/command-palette/CommandPalette.sveltesrc/lib/toolbar/Toolbar.sveltesrc/lib/utils/Arrow.sveltesrc/lib/timeline/GroupItem.sveltesrc/lib/timeline/ActivityItem.sveltesrc/lib/table/Table.sveltesrc/lib/tabs/Tabs.sveltesrc/lib/timeline/Activity.sveltesrc/lib/pagination/Pagination.sveltesrc/lib/forms/dropzone/Dropzone.sveltesrc/lib/timeline/TimelineItem.sveltesrc/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.sveltesrc/lib/utils/Popper.sveltesrc/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.mdsrc/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.mdsrc/lib/forms/dropzone/Dropzone.sveltesrc/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.tssrc/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"anddata-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:
- All slot name changes across the codebase are represented here
- No additional components (e.g., device-mockup, drawer, dropdown) have slot renames that should be documented
- 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"anddata-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"anddata-partattributes 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"anddata-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 receivedata-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"anddata-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-partattributes 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"anddata-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"anddata-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 anddata-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"anddata-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"anddata-partattributes 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, whiledata-part="button"anddata-part="link"appropriately distinguish the element type based on whetherhrefis 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"anddata-part="base"attributes are correctly added to the root<ol>element, aligning with the theme structure wherebaseis destructured frombreadcrumbStepper()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 theitemtheme 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 theclickableprop. This aligns with theindicatortheme 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
dialogscope rather than create a newmodalscope, 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-partattributes under the inheriteddialogscope. 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"anddata-partattributes 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 ofrestPropsspread is intentional.The
restPropsare 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 likeid,data-*, or customaria-*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"anddata-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
paginationandpaginationNavexports provides better separation of concerns. ThedefaultVariantsnow correctly reference only variants that exist in their respectivevariantsdefinitions, 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 (
close→closeIcon,svg→closeIcon) 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
divtowrapperprovides more semantic clarity, and the addition ofdata-scope="table"anddata-partattributes 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
getThemecall 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 granulardata-partattributes provides clear component scoping and part identification, which will improve testability and enable advanced styling capabilities.
29-29: Slot migration fromsvgDiv/svgtoiconContainer/iconis 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
divtowrapperbetter 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/svgtoiconContainer/iconimproves 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
iconslot. 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 fromlineA/lineB/svg/contenttoprimaryLine/secondaryLine/avatarIcon/authorInfosignificantly 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"anddata-partattributes 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-lineelements, twoprimary-lineelements)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
avatarIconstyling function, replacing the previous binding shorthand. All necessary attributes are present, includingaria-hidden="true"for proper accessibility.
17-57: No action needed—theme.ts is correctly updated.The
testimonialPlaceholder()function insrc/lib/skeleton/theme.ts(lines 148-156) properly defines all required slots:primaryLine,secondaryLine,avatarIcon, andauthorInfo. 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. TheTestimonialPlaceholderVariantstype uses theClassesgeneric, which automatically generates aclassesproperty with all slots from thetestimonialPlaceholdertheme (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
restPropsdestructuring 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-partattributes (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"anddata-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"anddata-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_titlealias.Renaming the destructured
titleslot to_titleprevents collision with thetitleprop (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:
item→indicator(withimg) +card→header(withtimeandtitle) + optionaltext. 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 includedata-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 ofli,span,outer,inner)group:card,list(instead ofdiv,ol)groupItem:link,content,badge,icon(instead ofa,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
divandsvgtoindicatorandicon). Since the compoundVariants have been updated with these new slot names, users customizing Timeline via theclassesprop 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
VariantPropsandClassesimports, along with the newDropzoneVariantsexport type, properly follows the same pattern used in other components likeNavLiVariantsandDropdownItemVariantsas 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 singlebasestring. This is a breaking change where consumers usingdropzone()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: ... }}toclasses={{ list: ... }}correctly reflects the updated NavUl component API where the internal element key was renamed fromultolist, 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
classesprop and the use of$derived()for bothstyling(line 12) andtheme(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 }fromdropzone()correctly integrates with the new slots-based theme structure defined intheme.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-partattributes 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), andDropzoneVariants(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.classesto includebutton,contentWrapper, andcontentfields 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 nestedclassesstructure (likely now handled internally by variants)- DropzoneProps (line 753): Extends
DropzoneVariantsto properly inherit the new slots-based classes structureBoth 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
NavLiPropstype correctly composesAnchorButtonAttributeswithNavLiVariantswhile preservingactiveClassandnonActiveClassfor custom styling. This aligns with the broader variant system migration and matches the usage inFlowbiteSvelteLayout.svelte.
1980-1980: LGTM! Type improvements for better class composition.
- PopperProps.arrowClass (line 1980): Changed from
stringtoClassValue, enabling more flexible class composition (arrays, objects, etc.)- ArrowProps (lines 1996-2000): Now extends
HTMLAttributes<HTMLDivElement>, which includes theclassfield and provides better type safetyBoth 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 renameextra→addonis properly implemented.All consuming code has been consistently updated. The MegaMenu component correctly destructures and uses the
addonprop (line 8 of MegaMenu.svelte), applies it in theme configuration (line 12), and conditionally renders it (line 26). No remaining usages of the oldextrafield name were found.
…ropzone, fileupload, floating-label, helper, and input-field directories
…einput, radio, range, search directories
…tarea, timepicker, toggle directories
There was a problem hiding this comment.
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 inPhoneInputVariants, 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
📒 Files selected for processing (13)
src/lib/forms/label/Label.sveltesrc/lib/forms/phoneinput/PhoneInput.sveltesrc/lib/forms/phoneinput/theme.tssrc/lib/forms/radio/Radio.sveltesrc/lib/forms/search/Search.sveltesrc/lib/forms/search/theme.tssrc/lib/forms/select/MultiSelect.sveltesrc/lib/forms/select/Select.sveltesrc/lib/forms/textarea/Textarea.sveltesrc/lib/forms/textarea/theme.tssrc/lib/forms/timepicker/Timepicker.sveltesrc/lib/forms/toggle/Toggle.sveltesrc/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.sveltesrc/lib/forms/select/Select.sveltesrc/lib/forms/label/Label.sveltesrc/lib/forms/select/MultiSelect.sveltesrc/lib/forms/search/Search.sveltesrc/lib/forms/radio/Radio.sveltesrc/lib/forms/toggle/theme.tssrc/lib/forms/phoneinput/PhoneInput.sveltesrc/lib/forms/phoneinput/theme.tssrc/lib/forms/textarea/Textarea.sveltesrc/lib/forms/search/theme.tssrc/lib/forms/textarea/theme.tssrc/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.sveltesrc/lib/forms/select/Select.sveltesrc/lib/forms/label/Label.sveltesrc/lib/forms/select/MultiSelect.sveltesrc/lib/forms/search/Search.sveltesrc/lib/forms/radio/Radio.sveltesrc/lib/forms/phoneinput/PhoneInput.sveltesrc/lib/forms/textarea/Textarea.sveltesrc/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.sveltesrc/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.sveltesrc/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"anddata-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"anddata-partattributes 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
divtocontainer, 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 granulardata-partattributes 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,closeThe distinction between
data-part="wrapper"(outer structure) anddata-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 namedcontainerand the Textarea component properly uses this slot. No remaining references to an olddivslot 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
svg→iconto 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"anddata-partattributes 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
PhoneInputPropstype extendsPhoneInputVariants, which includesClasses<typeof phoneInput>. TheClassesutility automatically generates aclasses?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
closeIconinstead of the oldsvgslot 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 theiconWrapperslotdata-part="right-content"matches therightContentslotThe 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:
left→iconWrappercontent→rightContentsvg→closeIconVerification 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
classesprop pattern for styling customization.src/lib/forms/toggle/Toggle.svelte (2)
14-14: LGTM! Slot destructuring updated correctly.The destructuring now uses
trackinstead ofspan, 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-scopeanddata-partattributes improve testability and styling hooks- The
trackstyling function correctly replacesspanthroughout- Class composition logic is preserved
src/lib/forms/timepicker/Timepicker.svelte (2)
355-355: LGTM! Toggle classes prop correctly updated.The
classesprop now usestrackinstead ofspan, matching the theme slot rename intheme.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-scopeanddata-partattributes 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
src/lib/forms/toggle/theme.ts
Outdated
| 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 ", |
There was a problem hiding this comment.
🧩 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 -100Repository: 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 -50Repository: 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=svelteRepository: 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 spanRepository: 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-headingRepository: 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.svelteRepository: 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 -30Repository: 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 2Repository: 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.svelteRepository: 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-headingRepository: 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.svelteline 9src/routes/llm/forms/toggle.mdline 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.
There was a problem hiding this comment.
🧩 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
There was a problem hiding this comment.
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:buttonPropsspreads a function instead of filtered props.Lines 24-27 define
buttonPropsas a derived function:$derived(() => {...}). This makesbuttonPropsequal the function itself, not its return value. On line 32,{...buttonProps}spreads the function object, not the filtered props.When
asButtonis 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
buttonPropsbecomes the filtered object rather than a function.Also applies to: 32-32
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
src/lib/typography/a/A.sveltesrc/lib/typography/blockquote/Blockquote.sveltesrc/lib/typography/descriptionlist/DescriptionList.sveltesrc/lib/typography/heading/Heading.sveltesrc/lib/typography/hr/Hr.sveltesrc/lib/typography/hr/theme.tssrc/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.sveltesrc/lib/typography/descriptionlist/DescriptionList.sveltesrc/lib/typography/a/A.sveltesrc/lib/typography/heading/Heading.sveltesrc/lib/typography/hr/theme.tssrc/lib/typography/img/Img.sveltesrc/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.sveltesrc/lib/typography/descriptionlist/DescriptionList.sveltesrc/lib/typography/a/A.sveltesrc/lib/typography/heading/Heading.sveltesrc/lib/typography/img/Img.sveltesrc/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-scopecan be overridden byrestProps.The
data-scope="img"attribute is placed before the{...restProps}spread, which means users can override it by passing adata-scopeprop. Verify whether this override behavior is intentional.If
data-scopeis 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 whenwithChildrenis true.When
withChildrenistrue, thebaseslot is set to just"w-full", which replaces the defaultbasestyling entirely. This means the<hr>element losesh-px my-8 border-0 bg-gray-200 dark:bg-gray-700.If the intent is to add
w-fullwhile 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/bgtowrapper/base/contentaligns with the PR's objective to standardize slot naming across components. The addition ofdefaultVariantsis a good practice for explicit defaults.src/lib/typography/hr/Hr.svelte (2)
9-16: Proper use of$derivedfor 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"anddata-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.
There was a problem hiding this comment.
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-partattributes 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-coldiv (line 344) is missing thedata-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-coldiv (line 389) is missing thedata-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?.wrapperwas missing from this line, but it's now present in the code. The wrapper correctly mergestheme?.wrapperandstyling?.wrapper.
🧹 Nitpick comments (1)
src/lib/forms/checkbox/Checkbox.svelte (1)
77-78: LGTM! Data attributes correctly applied.The same
data-scopeanddata-partpattern 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
📒 Files selected for processing (15)
src/lib/forms/checkbox/Checkbox.sveltesrc/lib/forms/timepicker/Timepicker.sveltesrc/lib/forms/toggle/theme.tssrc/lib/typography/hr/Hr.sveltesrc/lib/typography/hr/theme.tssrc/lib/typography/layout/Layout.sveltesrc/lib/typography/list/List.sveltesrc/lib/typography/mark/Mark.sveltesrc/lib/typography/paragraph/P.sveltesrc/lib/typography/secondary/Secondary.sveltesrc/lib/typography/span/Span.sveltesrc/routes/docs-examples/forms/phone-input/Classes.sveltesrc/routes/docs-examples/forms/textarea/Chatroom.sveltesrc/routes/docs-examples/forms/toggle/Sizes.sveltesrc/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.sveltesrc/lib/typography/secondary/Secondary.sveltesrc/lib/typography/span/Span.sveltesrc/lib/forms/toggle/theme.tssrc/lib/typography/list/List.sveltesrc/lib/typography/hr/Hr.sveltesrc/lib/forms/timepicker/Timepicker.sveltesrc/lib/typography/mark/Mark.sveltesrc/routes/docs-examples/forms/textarea/Chatroom.sveltesrc/lib/forms/checkbox/Checkbox.sveltesrc/routes/docs-examples/forms/toggle/Sizes.sveltesrc/routes/docs-examples/forms/phone-input/Classes.sveltesrc/routes/docs-examples/typography/hr/Text.sveltesrc/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.sveltesrc/lib/typography/secondary/Secondary.sveltesrc/lib/typography/span/Span.sveltesrc/lib/typography/list/List.sveltesrc/lib/typography/hr/Hr.sveltesrc/lib/forms/timepicker/Timepicker.sveltesrc/lib/typography/mark/Mark.sveltesrc/routes/docs-examples/forms/textarea/Chatroom.sveltesrc/lib/forms/checkbox/Checkbox.sveltesrc/routes/docs-examples/forms/toggle/Sizes.sveltesrc/routes/docs-examples/forms/phone-input/Classes.sveltesrc/routes/docs-examples/typography/hr/Text.sveltesrc/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.tssrc/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.tssrc/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.sveltesrc/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
divtoiconWrapperin the classes prop correctly reflects the theme slot rename insrc/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 customdata-scopein 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-scopeafter{...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"anddata-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"anddata-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-partattributes 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"anddata-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 newtrackslot key.This example now properly uses
classes={{ track: customSize }}, which aligns with the theme refactor insrc/lib/forms/toggle/theme.ts. This resolves the issue flagged in a previous review where this line was using the oldspankey.src/routes/docs-examples/forms/textarea/Chatroom.svelte (1)
17-17: LGTM! Example updated to match theme migration.The slot key update from
divtocontainercorrectly 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
classesprop 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
bgvalue allows users to override the default background viaclasses.bgwhile providing sensible defaults with dark mode support.
17-17: LGTM - wrapper slot renaming.The destructuring change from
divtowrapperaligns 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>usesdata-scope="base"but should likely usedata-scope="hr"to identify it as the Hr component's root element. In the children branch (line 21), the wrapper usesdata-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.
|
@coderabbitai Please ignore files under |
|
Tip For best results, initiate chat on the files or code changes. @shinokada: Understood! I'll ignore files under the ✏️ Learnings added
|
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
src/lib/forms/timepicker/Timepicker.sveltesrc/lib/typography/a/A.sveltesrc/lib/typography/blockquote/Blockquote.sveltesrc/lib/typography/descriptionlist/DescriptionList.sveltesrc/lib/typography/heading/Heading.sveltesrc/lib/typography/hr/Hr.sveltesrc/lib/typography/img/Img.sveltesrc/lib/typography/img/theme.tssrc/lib/typography/layout/Layout.sveltesrc/lib/typography/list/Li.sveltesrc/lib/typography/list/List.sveltesrc/lib/typography/mark/Mark.sveltesrc/lib/typography/paragraph/P.sveltesrc/lib/typography/secondary/Secondary.sveltesrc/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.sveltesrc/lib/typography/blockquote/Blockquote.sveltesrc/lib/typography/span/Span.sveltesrc/lib/forms/timepicker/Timepicker.sveltesrc/lib/typography/secondary/Secondary.sveltesrc/lib/typography/list/Li.sveltesrc/lib/typography/img/Img.sveltesrc/lib/typography/img/theme.tssrc/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.sveltesrc/lib/typography/blockquote/Blockquote.sveltesrc/lib/typography/span/Span.sveltesrc/lib/forms/timepicker/Timepicker.sveltesrc/lib/typography/secondary/Secondary.sveltesrc/lib/typography/list/Li.sveltesrc/lib/typography/img/Img.sveltesrc/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"anddata-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"anddata-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"anddata-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"anddata-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"anddata-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
figuretoimage/baseimproves semantic clarity. The apparent duplication of classes acrossimageandbaseslots 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 theimgClassderivation properly uses the newimageslot with appropriate styling composition.
23-36: Well-structured data attributes for component scoping.The addition of
data-scope="img"anddata-partattributes (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
bgderived 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 boththeme?.contentandstyling?.content. Both elements follow the expected pattern for theme customization.Also applies to: 23-23
There was a problem hiding this comment.
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
convertImportsalready 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 existingshouldExcludeFilefunction (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.mjswhen 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
📒 Files selected for processing (12)
convert-imports.mjsdesign-system.mdfind-all-imports.mjsfind-imports.mjsquestions.mdsrc/lib/forms/checkbox/Checkbox.sveltesrc/lib/forms/checkbox/theme.tssrc/lib/forms/dropzone/Dropzone.sveltesrc/lib/forms/fileupload/Fileupload.sveltesrc/lib/forms/fileupload/theme.tssrc/lib/forms/floating-label/FloatingLabelInput.sveltesrc/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.sveltesrc/lib/forms/checkbox/theme.tssrc/lib/forms/dropzone/Dropzone.sveltesrc/lib/forms/input-field/Input.sveltesrc/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.sveltesrc/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.sveltesrc/lib/forms/dropzone/Dropzone.sveltesrc/lib/forms/input-field/Input.sveltesrc/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.mjsconvert-imports.mjsfind-imports.mjsquestions.mddesign-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.mjsconvert-imports.mjsfind-imports.mjsquestions.mddesign-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.mjsfind-imports.mjsquestions.mddesign-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.tssrc/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.tssrc/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.mjsquestions.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"anddata-partattributes 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
basetoinputimproves 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"anddata-partattributes improves component testability and CSS targeting. The class binding correctly uses the renamedinput()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-scopeattribute (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, andclose-buttonentries, along with improved formatting, accurately reflect the slot naming patterns used across the codebase. Theclose-buttonentry 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
closetocloseButtonandsvgtocloseIconfollow 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"anddata-partattributes follow the documented pattern in design-system.md:
data-scope="fileupload"on the root element establishes the component boundarydata-part="wrapper"on the base containerdata-part="input"on the input elementdata-part="close-button"on the CloseButton componentThese 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 insrc/lib/forms/fileupload/theme.ts.src/lib/forms/checkbox/theme.ts (1)
6-112: Slot rename frombasetoinputis complete and properly implemented.The checkbox theme consistently uses
inputandlabelslots across all variants (lines 5-112). The Checkbox.svelte component correctly destructures and applies these slots. No remaining references to the oldbaseslot 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
closeButtonandcloseIconalign with the theme slot renaming. The usage pattern correctly applies the theme functioncloseButton()and merges theme/styling overrides for both slots.
252-254: LGTM: leftAddon implementation is consistent.The renamed
leftAddonslot is used consistently across the function call, theme override, and styling override. Thedata-part="left-addon"attribute correctly uses kebab-case.
258-260: LGTM: rightAddon implementation is consistent.The renamed
rightAddonslot is used consistently across the function call, theme override, and styling override. Thedata-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 fromcombo) withdata-part="combo-list"option(renamed fromcomboItem) withdata-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 })); |
There was a problem hiding this comment.
🧩 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.svelteRepository: 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.svelteRepository: 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.svelteRepository: 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.svelteRepository: 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.
There was a problem hiding this comment.
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-baseis not a valid Tailwind CSS v4 utility class.Throughout this file,
rounded-lghas been replaced withrounded-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, androunded-full.This will cause all affected elements to lose their border radius styling, resulting in visual regression.
🔎 Suggested fix
Revert to
rounded-lgor 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: DestructurecloseIconfor consistency with other slots.The destructuring omits
closeIconeven 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 accessestheme?.closeIconinstead. This inconsistency means the basecloseIconslot 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:
Pattern matching (Line 29): The search only matches static imports with
from "flowbite-svelte"orfrom 'flowbite-svelte'. It won't detect re-exports likeexport { Button } from 'flowbite-svelte', which could be relevant for a comprehensive migration audit.Error handling (Line 28):
fs.readFileSynccan 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
📒 Files selected for processing (24)
COMPLETE_REVIEW_SUMMARY.mdSLOT_NAMING_REVIEW.mdconvert-imports.mjsfind-imports.mjspackage.jsonsrc/lib/extend/button-toggle/ButtonToggle.sveltesrc/lib/extend/button-toggle/ButtonToggleGroup.sveltesrc/lib/extend/button-toggle/theme.tssrc/lib/extend/clipboard-manager/ClipboardManager.sveltesrc/lib/extend/clipboard-manager/theme.tssrc/lib/extend/command-palette/CommandPalette.sveltesrc/lib/extend/command-palette/theme.tssrc/lib/forms/checkbox/theme.tssrc/lib/forms/fileupload/theme.tssrc/lib/forms/input-field/Input.sveltesrc/lib/forms/input-field/theme.tssrc/lib/forms/timepicker/Timepicker.sveltesrc/lib/typography/img/Img.sveltesrc/lib/typography/img/theme.tssrc/routes/builder/checkbox/+page.sveltesrc/routes/docs-examples/extend/clipboard-manager/+page.sveltesrc/routes/docs-examples/extend/clipboard-manager/examples/Interactive.sveltesrc/routes/docs-examples/forms/checkbox/Colors.sveltesrc/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.sveltesrc/lib/extend/command-palette/theme.tssrc/routes/docs-examples/forms/checkbox/Colors.sveltesrc/routes/docs-examples/extend/clipboard-manager/+page.sveltesrc/lib/typography/img/theme.tssrc/lib/typography/img/Img.sveltesrc/lib/extend/clipboard-manager/ClipboardManager.sveltesrc/lib/forms/input-field/Input.sveltesrc/routes/builder/checkbox/+page.sveltesrc/lib/extend/clipboard-manager/theme.tssrc/lib/extend/button-toggle/theme.tssrc/lib/extend/button-toggle/ButtonToggle.sveltesrc/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.sveltesrc/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.sveltesrc/routes/docs-examples/forms/checkbox/Colors.sveltesrc/routes/docs-examples/extend/clipboard-manager/+page.sveltesrc/lib/typography/img/Img.sveltesrc/lib/extend/clipboard-manager/ClipboardManager.sveltesrc/lib/forms/input-field/Input.sveltesrc/routes/builder/checkbox/+page.sveltesrc/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.sveltefind-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.sveltesrc/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
basetoimageis 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 withcaptionaliased tofigureCaptionappropriately avoids the naming conflict with the component'scaptionprop. Based on learnings, this follows the recommended pattern for reactive theme usage.
21-32: LGTM!The
data-scope="img"anddata-partattributes are correctly applied to the figure structure:
<figure>getsdata-scope="img"anddata-part="figure"- Nested
<img>getsdata-part="image"(scope inherited from parent)<figcaption>getsdata-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
developmentcondition 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 todist/index.jsis 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.tsandsrc/lib/types.tsexist at the specified locations. The dist outputs (dist/types.d.tsanddist/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@themeblock oflayout.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
@themeblock to replace the hardcoded values. Otherwise, the!importantflags here may be necessary to override Flowbite plugin styles, depending on where.cw-baseand.cw-innerare applied in the page.Likely an incorrect or invalid review comment.
find-imports.mjs (2)
1-8: LGTM!The ESM setup and
__dirnameworkaround 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 (
left→leftAddon,right→rightAddon,close→closeButton,combo→comboList,comboItem→option) 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 consistentdata-partattributes (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"anddata-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
labelinstead oftext(line 43, 68), matching the theme.ts changes.- Semantic
data-scopeanddata-partattributes added consistently (lines 52, 60, 65, 68) for improved testability and styling hooks.- Theme reactivity properly handled via
$derivedexpression (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 fromtexttolabelhas been properly updated.The theme.ts file correctly defines the
labelslot (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 oldtextslot 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
emptytoemptyStateis complete. The CommandPalette component correctly usesemptyStateat line 177 in CommandPalette.svelte (withstyles.emptyState(),theme?.emptyState, andclasses?.emptyState), and no legacy references to the oldemptyslot 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-scopeanddata-partattributes throughout the component follows best practices for semantic markup and provides stable selectors for styling and testing. The slot name updates (emptyText→emptyMessage,emptySubtext→emptyDescription,addToClipboard→addButton,clearAll→clearButton) 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 usesrounded-base(an invalid Tailwind v4 class). See the review comment ontheme.tsfor 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
emptyText→emptyMessageandemptySubtext→emptyDescriptionimproves clarity and aligns with design system conventions. These names better describe the purpose of each text element.
13-56: No changes needed.rounded-baseis a valid utility class provided by Flowbite's Tailwind v4 plugin. The project imports@plugin "flowbite/plugin"and defines the--radius-base: 12pxCSS custom property in the theme, makingrounded-baseavailable as a standard utility throughout the codebase. This usage is correct.Likely an incorrect or invalid review comment.
| // Directories to exclude | ||
| const EXCLUDE_DIRS = ["node_modules", ".svelte-kit", "dist", "build", ".git", "llm", "utils"]; |
There was a problem hiding this comment.
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} /> |
There was a problem hiding this comment.
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.
| <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.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
src/lib/extend/clipboard-manager/ClipboardManager.sveltesrc/lib/extend/scroll-spy/ScrollSpy.sveltesrc/lib/extend/scroll-spy/theme.tssrc/lib/extend/split-pane/Divider.sveltesrc/lib/extend/split-pane/Pane.sveltesrc/lib/extend/split-pane/SplitPane.sveltesrc/lib/extend/split-pane/index.tssrc/lib/extend/split-pane/theme.tssrc/lib/extend/step-indicator/StepIndicator.sveltesrc/lib/extend/step-indicator/theme.tssrc/lib/theme-provider/themes.tssrc/routes/docs-examples/extend/clipboard-manager/+page.sveltesrc/routes/layout.csssrc/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.tssrc/lib/extend/split-pane/SplitPane.sveltesrc/lib/extend/step-indicator/theme.tssrc/lib/theme-provider/themes.tssrc/lib/extend/split-pane/index.tssrc/lib/extend/scroll-spy/ScrollSpy.sveltesrc/lib/extend/step-indicator/StepIndicator.sveltesrc/lib/extend/split-pane/theme.tssrc/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.sveltesrc/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.sveltesrc/lib/extend/scroll-spy/ScrollSpy.sveltesrc/lib/extend/step-indicator/StepIndicator.sveltesrc/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 newcontentslot key.The migration from root padding classes to
classes={{ content: "py-0" }}aligns with the navbar theming refactor where thecontentslot is now exposed for inner content styling.
59-63: LGTM! Correct migration fromultolistslot key.The slot key rename from
ultolistaligns 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
itemproperly reflects the slot key rename intheme.ts. The implementation maintains type safety through thescrollspy()variant call.Also applies to: 56-56
235-243: LGTM! Data attributes improve component introspection.The addition of
data-scopeanddata-partattributes 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 fromlitoitemis complete.The slot key rename has been properly applied across all integration points. The theme definition uses the new
itemkey, the ScrollSpy.svelte component correctly destructures and referencesitem, and the type system automatically exposes the updated slot through theClasses<T>utility type. No remnants of the oldlislot 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"anddata-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
dividerHitAreafromthemes.ts(line 83) and the refactoring of the divider theme to use a slot-based structure withslots.baseandslots.hitArea.Note: This breaking change is already covered by the verification script in the
themes.tsreview.src/lib/extend/split-pane/theme.ts (1)
24-53: LGTM: Divider theme refactored to slot-based structure.The
dividertheme has been refactored from a flat structure to a slot-based structure withslots.baseandslots.hitArea. This consolidates the previously separatedividerHitAreaexport into the maindividertheme, improving consistency.Key changes:
dividernow returns an object withbase()andhitArea()methods- Variants are now per-slot (e.g.,
direction.horizontal.baseanddirection.horizontal.hitArea)- The separate
dividerHitAreaexport has been removedThis 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.tsreview will confirm thatDivider.svelteand other consumers have been updated to use the new structure.src/lib/theme-provider/themes.ts (1)
83-83: VerifydividerHitArearemoval doesn't break consumers.The
dividerHitAreaexport has been removed from the split-pane theme. Ensure that all usages have been migrated to the newdividerslot-based structure withslots.hitArea.src/lib/extend/step-indicator/theme.ts (1)
19-19: No action required. The slot renaming fromincompletetoincompleteStephas been properly implemented. All internal consumers inStepIndicator.sveltereference the new slot name correctly (destructuring at line 25, usage at lines 100 and 124). ThegetStepStateClasseshelper correctly maintainsdata-[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 anddata-partattributes 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
incompleteStepconsistently throughout both clickable and non-clickable branches- Add
data-partattributes to all major UI parts (wrapper, step, glow, incomplete-step)- Include
data-stateattributes 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
incompleteStepslot is properly defined in theme.ts (line 19), andStepIndicatorThemeautomatically includes it since it's derived fromkeyof typeof stepIndicator.slots. There is noStepIndicatorPropstype in this codebase—the relevant types areStepIndicatorThemeandStepIndicatorVariants, 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 nameincompleteStep.
There was a problem hiding this comment.
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 sinceclassNameis already a string from the destructured props. You can simplify this tobase({ 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
itemproperty 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
📒 Files selected for processing (8)
questions.mdsrc/lib/accordion/Accordion.sveltesrc/lib/navbar/NavLi.sveltesrc/lib/navbar/NavUl.sveltesrc/lib/navbar/Navbar.sveltesrc/lib/types.tssrc/routes/admin-dashboard/(sidebar)/Frame.sveltesrc/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.sveltesrc/routes/admin-dashboard/(sidebar)/Frame.sveltesrc/lib/navbar/Navbar.sveltesrc/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.sveltesrc/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.sveltesrc/routes/admin-dashboard/(sidebar)/Frame.sveltesrc/lib/navbar/Navbar.sveltesrc/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 fromnavbarUltonavUlis complete and consistent across all three color dictionaries (lines 17, 85, 106).No stale references to the old
navbarUlkey remain in the codebase. TheFrameColortype, which is derived frombgColorskeys, automatically reflects this change and will correctly excludenavbarUlwhile includingnavUl.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
navbartheme function insrc/lib/navbar/theme.tsdefines slots forbase,content, andcontainer(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
NavLielements to the parentNavUl'sitemkey (Line 62) is a cleaner pattern that reduces duplication and improves maintainability.src/lib/accordion/Accordion.svelte (7)
8-8: LGTM!The
untrackimport is correctly added and properly used on line 35 to capture the initial value of themultipleprop.
10-10: Breaking change: Verify migration documentation.The removal of
activeClassandinactiveClassprops is a breaking change for existing users. Ensure migration documentation is updated to guide users on how to style accordion items with the newclassesprop 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
classNameand will reactively update when any dependency changes.
40-42: LGTM!The addition of
data-scope="accordion"anddata-part="base"attributes aligns with the PR objectives and provides structured data attributes for styling and testing purposes.
33-35: Themultipleprop 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.
There was a problem hiding this comment.
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
itemtheme slot)- Line 199: Dropdown list item (structural wrapper, not styled with
itemslot)The dropdown list item is purely structural and contains a button with
data-part="option"that receives the actual styling via theoptiontheme slot. Consider using a more distinctive name likedata-part="suggestion-item"ordata-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
📒 Files selected for processing (7)
src/lib/extend/tags/Tags.sveltesrc/lib/extend/tags/theme.tssrc/lib/extend/tour/Tour.sveltesrc/lib/extend/tour/theme.tssrc/lib/navbar/NavLi.sveltesrc/lib/types.tssrc/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.tssrc/lib/types.tssrc/lib/extend/tour/Tour.sveltesrc/lib/extend/tags/theme.tssrc/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.tssrc/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.sveltesrc/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 (
tag→item,span→label) to semantic names improves clarity, and the addition ofinputWrapperandoptionslots 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 newinputWrapperandoptionslots. The component correctly derives these from the theme.
150-163: Data-part attributes added consistently for helper messages.The addition of
data-partattributes 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 anddata-partattributes on child elements (item, label, close-button) provide clear structural hooks for testing and styling. The use of renameditemClsandlabelClsis 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 consistentdata-partattributes 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
DropdownItemPropsandDropzonePropsnow 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.sveltedestructures theclassesprop and setsnavState.activeClass,navState.nonActiveClass, andnavState.itemClassvia an effect, correctly using all five granular styling pointsNavLi.sveltedestructuresactiveClassandnonActiveClassprops, falling back to context values fromnavState, and correctly combines all styling sources (local props, context, theme, andstyling?.item)- The pattern allows
NavUlto establish defaults whileNavLican override them, providing flexible compositionNo action required.
1986-1986: Arrow component correctly handles refactored props.The implementation fully supports the changes:
PopperProps.arrowClasstyped asClassValue- Arrow receives it as theclassprop (line 294 of Popper.svelte)ArrowPropsextendingHTMLAttributes<HTMLDivElement>- Arrow.svelte correctly destructuresclass: classNameand 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; |
There was a problem hiding this comment.
🧩 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.tsRepository: 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=svelteRepository: 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=svelteRepository: 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=svelteRepository: themesberg/flowbite-svelte
Length of output: 100
🏁 Script executed:
# Search for 'extra' without file type restrictions
rg -n 'extra' --max-count=20Repository: themesberg/flowbite-svelte
Length of output: 29146
🏁 Script executed:
# Find MegaMenu component files
fd -e svelte -e ts -e js 'mega' -iRepository: themesberg/flowbite-svelte
Length of output: 285
🏁 Script executed:
# Look for changelog or breaking changes documentation
fd -e md '(CHANGELOG|BREAKING|CHANGES|RELEASE)' -iRepository: themesberg/flowbite-svelte
Length of output: 82
🏁 Script executed:
# Search in the actual MegaMenu component for prop definitions
fd mega -i | head -20Repository: themesberg/flowbite-svelte
Length of output: 574
🏁 Script executed:
# Read the MegaMenu component
cat -n src/lib/mega-menu/MegaMenu.svelte | head -100Repository: themesberg/flowbite-svelte
Length of output: 1965
🏁 Script executed:
# Check the component-data JSON file
cat -n src/routes/component-data/MegaMenu.jsonRepository: 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 -20Repository: themesberg/flowbite-svelte
Length of output: 52
🏁 Script executed:
# Check the test file
cat -n src/tests/mega-menu/mega-menu.test.ts | head -100Repository: themesberg/flowbite-svelte
Length of output: 3589
🏁 Script executed:
# Check CHANGELOG for breaking changes
cat -n CHANGELOG.md | head -50Repository: 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.svelteRepository: 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 -30Repository: 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 -30Repository: 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.jsonstill lists"extra"instead of"addon"src/routes/docs/components/mega-menu.mdandsrc/routes/llm/components/mega-menu.mdreference{#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.
There was a problem hiding this comment.
Since this will be major change, ignore this.
There was a problem hiding this comment.
@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 extra → addon 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.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
questions.md (1)
11-44: Support needed: Update NavLi type definition to includeitemin classes.The error message on line 27 correctly identifies the root issue: the type definition for NavLi's
classesparameter does not include anitemproperty, but the code attempts to pass one (line 36).To resolve this:
- Update NavLi.svelte's classes type to accept an
itemproperty (in addition to the existingactiveandnonActive).- Apply the
itemclass to the rendered<li>or relevant container element in NavLi.svelte.- Ensure the type exports from
src/lib/navbar/theme.tsandsrc/lib/navbar/index.tsreflect 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:
- Generate the required changes to NavLi.svelte to accept and apply the
itemclass?- Update the corresponding type definitions in theme.ts?
- 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
📒 Files selected for processing (7)
design-system-guide.mdquestions.mdsrc/lib/extend/kanban/KanbanBoard.sveltesrc/lib/extend/kanban/KanbanCard.sveltesrc/lib/extend/kanban/theme.tssrc/lib/extend/virtual-masonry/VirtualMasonry.sveltesrc/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.sveltesrc/lib/extend/kanban/KanbanBoard.sveltesrc/lib/extend/virtual-masonry/theme.tssrc/lib/extend/kanban/KanbanCard.sveltesrc/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.sveltesrc/lib/extend/kanban/KanbanBoard.sveltesrc/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.mddesign-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.mddesign-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.mddesign-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.mdsrc/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: Thelistanditementries 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"ordata-part="item". The documentation additions align correctly with actual component implementation.
92-99: close-button entry is correctly documented.The
close-buttondata-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 passdata-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:itemPartrename 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 ofitemPartslot function.The class binding correctly uses the renamed
itemPartfunction while referencingtheme?.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 thecontainerslot tobase. Any external consumers usingclasses?.containerto 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:classNamealiasing,$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"anddata-part="base"attributes correctly identify the component and its root element, andbasePartproperly 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-partattributes that match the theme slot names, and consistently apply theclsx(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"anddata-part="base", and the column element correctly applies theisDragOvervariant 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 viaclsx(theme?.button, styling?.button).
94-94: No action needed. The removal of theclassesprop from KanbanCard is correct. The board'sclassesobject contains styling only for board-level elements (column, title, list, button), not card-level elements. Card styling is properly handled throughcardProps, which can include aclassesproperty 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
kanbanBoardandkanbanCard, 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.
| ### 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) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, find and examine the design-system-guide.md file
fd design-system-guide.md -t fRepository: 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 -50Repository: 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 -40Repository: 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 -60Repository: 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 -50Repository: 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 -40Repository: 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 -10Repository: themesberg/flowbite-svelte
Length of output: 411
🏁 Script executed:
# Examine the full TimelineItem.svelte file
cat -n src/lib/timeline/TimelineItem.svelteRepository: 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 -50Repository: 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.
There was a problem hiding this comment.
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 alistslot to the theme would maintain consistency.src/lib/extend/virtual-masonry/VirtualMasonry.svelte (1)
22-22: Optional: Consider removing the redundantstylingderivation.The
stylingvariable is just an alias forclasseswithout any transformation. You could useclassesdirectly 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
classesprop in$derived()without any transformation. In Svelte 5, props are already reactive signals, so this creates unnecessary overhead.Line 20 correctly uses
$derived()forgetTheme()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
📒 Files selected for processing (12)
src/lib/extend/tags/Tags.sveltesrc/lib/extend/tour/theme.tssrc/lib/extend/virtual-list/VirtualList.sveltesrc/lib/extend/virtual-list/index.tssrc/lib/extend/virtual-list/theme.tssrc/lib/extend/virtual-masonry/VirtualMasonry.sveltesrc/lib/index.tssrc/lib/theme-provider/themes.tssrc/lib/types.tssrc/lib/utils/Arrow.sveltesrc/lib/video/Video.sveltesrc/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.tssrc/lib/extend/tour/theme.tssrc/lib/video/theme.tssrc/lib/index.tssrc/lib/types.tssrc/lib/extend/virtual-masonry/VirtualMasonry.sveltesrc/lib/video/Video.sveltesrc/lib/extend/tags/Tags.sveltesrc/lib/extend/virtual-list/VirtualList.sveltesrc/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.tssrc/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.tssrc/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.sveltesrc/lib/video/Video.sveltesrc/lib/extend/tags/Tags.sveltesrc/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-baseandrounded-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: itemClsandlabel: labelClsproperly avoids conflicts with reserved identifiers while maintaining alignment with the renamed theme slots (tag→item,span→label) 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-partattributes (input-wrapper,input,list,suggestion-item,option) and use the newinputWrapperandoptiontheme 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 thecontainedprop changes.
143-144: Data attributes correctly applied.The
data-scopeanddata-partattributes 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 theitemParttheme 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
stylingconstant properly wraps theclassesprop 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 aliasesitemtoitemPartto avoid naming conflicts with the loop variable.
111-123: LGTM! Data attributes consistently applied across all parts.The
data-scope="virtual-list"anddata-partattributes 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/navbarUltonavLi/navUlrename 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
virtuallistto the new kebab-casevirtual-list, maintaining consistency across the codebase.
83-83: ThedividerHitAreaexport 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 onlysplitpane,pane, anddivider.src/lib/extend/virtual-list/theme.ts (1)
9-9: The slot refactoring fromcontainertobasehas been properly implemented. The theme file correctly defines thebaseslot, and the VirtualList component properly destructures and applies it. No remaining references to the oldcontainerslot 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
baseslot provides sensible default styling withw-full, while empty strings forsourceandtrackallow full customization through theclassesprop 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
classesproperty allows theAccordionparent to pass granular styling toAccordionItemchildren. UsingPartialmakes 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, andVideonow extend their correspondingVariantstypes, 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, andNavLiPropswork together harmoniously:
NavbarState.itemClassprovides global item stylingNavUlProps.classesoffers granular control with base/list/active/nonActive/item keysNavLiPropsextendsNavLiVariantsand adds active/nonActive class propsThis 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.arrowClasschanging fromstringtoClassValueenables more flexible styling (arrays, objects, conditional classes via clsx)ArrowPropsextendingHTMLAttributes<HTMLDivElement>provides all standard div attributes (includingclass) while removing the need for a separate class fieldBoth 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: classNameavoids reserved word collision while maintaining familiar API- New
classesprop 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-specificdata-partattributes- Theme classes properly merged with custom classes via
clsx()baseusesclassName, whilesource/trackuse their respectiveclassessub-keys- Fallback text provides good browser compatibility messaging
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/lib/video/Video.svelte (1)
9-9: Redundant derived assignment.
stylingis simply assigned fromclasseswhich is already a reactive prop. Consider usingclassesdirectly 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
📒 Files selected for processing (8)
src/lib/extend/kanban/KanbanCard.sveltesrc/lib/extend/tags/Tags.sveltesrc/lib/theme-provider/themes.tssrc/lib/theme-selector/ThemeSelector.sveltesrc/lib/types.tssrc/lib/utils/Arrow.sveltesrc/lib/video/Video.sveltesrc/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.tssrc/lib/extend/kanban/KanbanCard.sveltesrc/lib/theme-selector/ThemeSelector.sveltesrc/lib/extend/tags/Tags.sveltesrc/lib/types.tssrc/lib/video/Video.sveltesrc/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.sveltesrc/lib/theme-selector/ThemeSelector.sveltesrc/lib/extend/tags/Tags.sveltesrc/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.sveltesrc/lib/extend/tags/Tags.sveltesrc/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.tssrc/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
stylingandthemeare 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
classtoclassNameavoids conflicts, and destructuringkanbanCard()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-scopeanddata-partattributes 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/spantoitem/labelimproves clarity and aligns with semantic component design. The addition ofinputWrapperandoptionkeys 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-partattributes (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"anddata-partattributes 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.
DropdownItemPropsnow properly extendsDropdownItemVariantsto incorporate variant-based styling, aligning with the multi-part theming approach used across the codebase.
753-759: Type composition is appropriate.
DropzonePropscorrectly extends bothDropzoneVariantsfor theming andHTMLInputAttributesfor native input behavior.
1117-1130: NavUl and NavLi prop types align with multi-part theming.The
classesstructure inNavUlPropswithbase,list,active,nonActive, anditemslots provides granular styling control.NavLiPropscorrectly composesAnchorButtonAttributeswithNavLiVariants.
1969-1975: VideoProps correctly extends VideoVariants.This aligns with the multi-part theming integration in
Video.svelteand the theme definition insrc/lib/video/theme.ts.
2004-2008: ArrowProps simplification is appropriate.Extending
HTMLAttributes<HTMLDivElement>directly includes theclassproperty via the standard HTML attributes, making an explicitclassfield unnecessary.
2218-2220: ThemeSelectorProps type definition is well-formed.The interface correctly extends both
ThemeSelectorVariantsfor theming andHTMLAttributes<HTMLDivElement>for standard div attributes.src/lib/video/index.ts (1)
1-2: Theme export augments the module API appropriately.Exporting the
videotheme alongside theVideocomponent 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. ThethemeSelector()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"anddata-partattributes throughout, enabling CSS targeting and inspection. The class composition usingclsxproperly 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
themeSelectoras 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
videoexport aligns with the multi-part theming integration inVideo.svelteand the new theme definition insrc/lib/video/theme.ts.
86-86: Split-pane exports simplified.The removal of
dividerHitAreafrom the exports reflects the corresponding cleanup insrc/lib/extend/split-pane/index.ts, keeping the public API in sync.
90-90: VirtualList path normalized.The import path change from
virtuallisttovirtual-listfollows 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) })}> |
There was a problem hiding this comment.
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.
| <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.
There was a problem hiding this comment.
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:
- Add data-testid to the clear button (recommended):
const closeButton = screen.getByLabelText("Clear search value"); +// Or use: +const closeButton = screen.getByTestId("search-clear-button");
- 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
📒 Files selected for processing (15)
src/tests/forms/range/range-attributes.test.sveltesrc/tests/forms/range/range-basic.test.sveltesrc/tests/forms/range/range-colors.test.sveltesrc/tests/forms/range/range-custom-props.test.sveltesrc/tests/forms/range/range-sizes.test.sveltesrc/tests/forms/range/range-value-binding.test.sveltesrc/tests/forms/range/range.test.tssrc/tests/forms/search/search-basic.test.sveltesrc/tests/forms/search/search-callback.test.sveltesrc/tests/forms/search/search-clearable.test.sveltesrc/tests/forms/search/search-custom-props.test.sveltesrc/tests/forms/search/search-sizes.test.sveltesrc/tests/forms/search/search-value-binding.test.sveltesrc/tests/forms/search/search-with-content.test.sveltesrc/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.sveltesrc/tests/forms/search/search-basic.test.sveltesrc/tests/forms/range/range-basic.test.sveltesrc/tests/forms/search/search-with-content.test.sveltesrc/tests/forms/search/search.test.tssrc/tests/forms/range/range-custom-props.test.sveltesrc/tests/forms/search/search-value-binding.test.sveltesrc/tests/forms/search/search-custom-props.test.sveltesrc/tests/forms/range/range-attributes.test.sveltesrc/tests/forms/range/range-sizes.test.sveltesrc/tests/forms/range/range.test.tssrc/tests/forms/range/range-value-binding.test.sveltesrc/tests/forms/search/search-clearable.test.sveltesrc/tests/forms/search/search-callback.test.sveltesrc/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.sveltesrc/tests/forms/search/search-basic.test.sveltesrc/tests/forms/range/range-basic.test.sveltesrc/tests/forms/search/search-with-content.test.sveltesrc/tests/forms/range/range-custom-props.test.sveltesrc/tests/forms/search/search-value-binding.test.sveltesrc/tests/forms/search/search-custom-props.test.sveltesrc/tests/forms/range/range-attributes.test.sveltesrc/tests/forms/range/range-sizes.test.sveltesrc/tests/forms/range/range-value-binding.test.sveltesrc/tests/forms/search/search-clearable.test.sveltesrc/tests/forms/search/search-callback.test.sveltesrc/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.sveltesrc/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
$staterune. 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
setTimeoutis 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
$staterunes for reactive values and demonstrates two-way binding with theclearableprop. 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), andname. The structure is clean and each test case has appropriatedata-testidattributes 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
$staterune 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
clearableOnClickcallback behavior.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/tests/forms/range/range.test.ts (1)
1-10: Import fix confirmed - excellent work!The
userEventimport now correctly uses default import syntax, which aligns with@testing-library/user-eventv14.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 fordropdown,item,select, andcloseelements.🔎 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 unhelpfulTypeErrormessages 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 usingwaitForwith explicit timeout for negative assertions.The hardcoded
setTimeoutdelays work but could be made more explicit. For negative assertions (verifying something doesn't happen), consider usingwaitForwith 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
rowsandmaxLengthdirectly 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
📒 Files selected for processing (36)
.gitignoresrc/lib/extend/tags/Tags.sveltesrc/lib/extend/tags/theme.tssrc/tests/clipboard-manager/clipboard-manager.test.tssrc/tests/clipboard/clipboard.test.tssrc/tests/forms/button-toggle/button-toggle.test.tssrc/tests/forms/checkbox/checkbox.test.tssrc/tests/forms/dropzone/dropzone.test.tssrc/tests/forms/fileupload/fileupload.test.tssrc/tests/forms/floating-label/floating-label.test.tssrc/tests/forms/input-field/input.test.tssrc/tests/forms/phoneinput/phoneinput.test.tssrc/tests/forms/radio/radio-button.test.tssrc/tests/forms/range/range.test.tssrc/tests/forms/search/search.test.tssrc/tests/forms/select/multiselect-basic.test.sveltesrc/tests/forms/select/multiselect-disabled-options.test.sveltesrc/tests/forms/select/multiselect-disabled.test.sveltesrc/tests/forms/select/multiselect-preselected.test.sveltesrc/tests/forms/select/multiselect.test.tssrc/tests/forms/select/select-basic.test.sveltesrc/tests/forms/select/select-children.test.sveltesrc/tests/forms/select/select-clearable.test.sveltesrc/tests/forms/select/select-disabled-options.test.sveltesrc/tests/forms/select/select-disabled.test.sveltesrc/tests/forms/select/select.test.tssrc/tests/forms/textarea/textarea-addon.test.sveltesrc/tests/forms/textarea/textarea-basic.test.sveltesrc/tests/forms/textarea/textarea-clearable.test.sveltesrc/tests/forms/textarea/textarea-disabled.test.sveltesrc/tests/forms/textarea/textarea-header-footer.test.sveltesrc/tests/forms/textarea/textarea.test.tssrc/tests/list-group/listgroup.test.tssrc/tests/mega-menu/mega-menu.test.tssrc/tests/modal/modal.test.tssrc/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.sveltesrc/tests/forms/checkbox/checkbox.test.tssrc/tests/clipboard-manager/clipboard-manager.test.tssrc/tests/forms/textarea/textarea-clearable.test.sveltesrc/tests/forms/select/multiselect-preselected.test.sveltesrc/tests/forms/select/multiselect-basic.test.sveltesrc/tests/navbar/navbar.test.tssrc/tests/forms/input-field/input.test.tssrc/tests/forms/select/multiselect-disabled-options.test.sveltesrc/tests/forms/dropzone/dropzone.test.tssrc/tests/mega-menu/mega-menu.test.tssrc/tests/forms/select/select-basic.test.sveltesrc/tests/forms/phoneinput/phoneinput.test.tssrc/tests/clipboard/clipboard.test.tssrc/tests/forms/floating-label/floating-label.test.tssrc/tests/forms/select/multiselect.test.tssrc/tests/forms/textarea/textarea.test.tssrc/tests/forms/select/select-children.test.sveltesrc/tests/modal/modal.test.tssrc/tests/forms/radio/radio-button.test.tssrc/tests/forms/textarea/textarea-header-footer.test.sveltesrc/tests/list-group/listgroup.test.tssrc/tests/forms/select/select-clearable.test.sveltesrc/tests/forms/select/select.test.tssrc/tests/forms/select/multiselect-disabled.test.sveltesrc/lib/extend/tags/theme.tssrc/tests/forms/button-toggle/button-toggle.test.tssrc/tests/forms/select/select-disabled.test.sveltesrc/tests/forms/select/select-disabled-options.test.sveltesrc/tests/forms/range/range.test.tssrc/lib/extend/tags/Tags.sveltesrc/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.sveltesrc/tests/forms/textarea/textarea-clearable.test.sveltesrc/tests/forms/select/multiselect-preselected.test.sveltesrc/tests/forms/select/multiselect-basic.test.sveltesrc/tests/forms/select/multiselect-disabled-options.test.sveltesrc/tests/forms/select/select-basic.test.sveltesrc/tests/forms/select/select-children.test.sveltesrc/tests/forms/textarea/textarea-header-footer.test.sveltesrc/tests/forms/select/select-clearable.test.sveltesrc/tests/forms/select/multiselect-disabled.test.sveltesrc/tests/forms/select/select-disabled.test.sveltesrc/tests/forms/select/select-disabled-options.test.sveltesrc/lib/extend/tags/Tags.sveltesrc/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.mdto.gitignoreis 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-eventv14.6.1, which exportsuserEventas the default export. TheuserEvent.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-eventlibrary exportsuserEventas 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
$staterune 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
$statefor 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
$staterune. 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-scopeanddata-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
userEventas 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
disabledprop 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
getSelectElementhelper usingdata-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
afterEachensures test isolation.
14-28: LGTM!The helper functions provide clean abstractions for dropdown interactions and use
data-partattributes 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
userEventfor 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
waitForfor 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) andtextarea[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:
inputWrapperuses relative positioning for proper dropdown anchoringoptionincludes hover feedback for better UXlisthas proper z-index stacking and overflow handling for long suggestion lists
10-11: LGTM! Semantic slot name improvements properly integrated.The renaming of
tag→itemandspan→labelimproves clarity and aligns with design system conventions. The Tailwind classes are preserved correctly, and theTags.sveltecomponent 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 semanticdata-partattributes (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 (
itemClsandlabelCls) while adding semanticdata-partattributes. Note that the close button usesdata-part="close-button"(semantic) while applying theclosetheme 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 matchingdata-partattributes. The inlineposition: absolutestyle on line 197 is appropriate since the positioning coordinates are dynamically calculated by floating-ui and applied via theupdateDropdownPositionfunction.
There was a problem hiding this comment.
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
setTimeoutwith 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.findByTestIdautomatically 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:
wrappedholds the element withdata-part="base", whileunwrappedholdsdata-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
rowsandmaxlength.💡 Suggestion
Either enhance this test to verify actual attribute passthrough (e.g., check that arbitrary attributes like
data-testidoraria-labelare 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
📒 Files selected for processing (44)
src/lib/extend/tags/Tags.sveltesrc/routes/docs-examples/extend/kanban-board/LocalStorage.sveltesrc/routes/docs-examples/extend/kanban-board/UsingModal.sveltesrc/tests/clipboard-manager/clipboard-manager.test.tssrc/tests/clipboard/clipboard.test.tssrc/tests/forms/button-toggle/button-toggle.test.tssrc/tests/forms/checkbox/checkbox.test.tssrc/tests/forms/dropzone/dropzone.test.tssrc/tests/forms/fileupload/fileupload.test.tssrc/tests/forms/floating-label/floating-label.test.tssrc/tests/forms/input-field/input.test.tssrc/tests/forms/phoneinput/phoneinput.test.tssrc/tests/forms/radio/radio-button.test.tssrc/tests/forms/range/range-colors.test.sveltesrc/tests/forms/range/range.test.tssrc/tests/forms/search/search-callback.test.sveltesrc/tests/forms/search/search-with-content.test.sveltesrc/tests/forms/search/search.test.tssrc/tests/forms/select/multiselect.test.tssrc/tests/forms/select/select-children.test.sveltesrc/tests/forms/select/select.test.tssrc/tests/forms/textarea/textarea-attributes.test.sveltesrc/tests/forms/textarea/textarea.test.tssrc/tests/forms/timepicker/timepicker-callback.test.sveltesrc/tests/forms/timepicker/timepicker-default.test.sveltesrc/tests/forms/timepicker/timepicker-disabled.test.sveltesrc/tests/forms/timepicker/timepicker-dropdown.test.sveltesrc/tests/forms/timepicker/timepicker-inline.test.sveltesrc/tests/forms/timepicker/timepicker-minmax.test.sveltesrc/tests/forms/timepicker/timepicker-range.test.sveltesrc/tests/forms/timepicker/timepicker-select.test.sveltesrc/tests/forms/timepicker/timepicker.test.tssrc/tests/forms/toggle/toggle-basic.test.sveltesrc/tests/forms/toggle/toggle-colors.test.sveltesrc/tests/forms/toggle/toggle-disabled.test.sveltesrc/tests/forms/toggle/toggle-offlabel.test.sveltesrc/tests/forms/toggle/toggle-prechecked.test.sveltesrc/tests/forms/toggle/toggle-sizes.test.sveltesrc/tests/forms/toggle/toggle-value.test.sveltesrc/tests/forms/toggle/toggle.test.tssrc/tests/list-group/listgroup.test.tssrc/tests/mega-menu/mega-menu.test.tssrc/tests/modal/modal.test.tssrc/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.sveltesrc/tests/forms/timepicker/timepicker-range.test.sveltesrc/tests/forms/select/select-children.test.sveltesrc/tests/forms/checkbox/checkbox.test.tssrc/tests/forms/timepicker/timepicker-default.test.sveltesrc/tests/forms/button-toggle/button-toggle.test.tssrc/tests/forms/phoneinput/phoneinput.test.tssrc/tests/forms/textarea/textarea-attributes.test.sveltesrc/routes/docs-examples/extend/kanban-board/LocalStorage.sveltesrc/tests/forms/timepicker/timepicker-callback.test.sveltesrc/tests/clipboard/clipboard.test.tssrc/tests/forms/timepicker/timepicker.test.tssrc/tests/forms/toggle/toggle-disabled.test.sveltesrc/tests/forms/toggle/toggle-value.test.sveltesrc/tests/forms/toggle/toggle-offlabel.test.sveltesrc/tests/forms/toggle/toggle.test.tssrc/tests/forms/timepicker/timepicker-select.test.sveltesrc/tests/forms/toggle/toggle-basic.test.sveltesrc/tests/forms/toggle/toggle-sizes.test.sveltesrc/tests/forms/toggle/toggle-colors.test.sveltesrc/routes/docs-examples/extend/kanban-board/UsingModal.sveltesrc/tests/forms/textarea/textarea.test.tssrc/tests/forms/timepicker/timepicker-disabled.test.sveltesrc/tests/list-group/listgroup.test.tssrc/tests/forms/timepicker/timepicker-inline.test.sveltesrc/lib/extend/tags/Tags.sveltesrc/tests/forms/input-field/input.test.tssrc/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.sveltesrc/tests/forms/timepicker/timepicker-range.test.sveltesrc/tests/forms/select/select-children.test.sveltesrc/tests/forms/timepicker/timepicker-default.test.sveltesrc/tests/forms/textarea/textarea-attributes.test.sveltesrc/routes/docs-examples/extend/kanban-board/LocalStorage.sveltesrc/tests/forms/timepicker/timepicker-callback.test.sveltesrc/tests/forms/toggle/toggle-disabled.test.sveltesrc/tests/forms/toggle/toggle-value.test.sveltesrc/tests/forms/toggle/toggle-offlabel.test.sveltesrc/tests/forms/timepicker/timepicker-select.test.sveltesrc/tests/forms/toggle/toggle-basic.test.sveltesrc/tests/forms/toggle/toggle-sizes.test.sveltesrc/tests/forms/toggle/toggle-colors.test.sveltesrc/routes/docs-examples/extend/kanban-board/UsingModal.sveltesrc/tests/forms/timepicker/timepicker-disabled.test.sveltesrc/tests/forms/timepicker/timepicker-inline.test.sveltesrc/lib/extend/tags/Tags.sveltesrc/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.sveltesrc/tests/forms/timepicker/timepicker-default.test.sveltesrc/tests/forms/timepicker/timepicker-callback.test.sveltesrc/tests/forms/timepicker/timepicker.test.tssrc/tests/forms/timepicker/timepicker-select.test.sveltesrc/tests/forms/timepicker/timepicker-disabled.test.sveltesrc/tests/forms/timepicker/timepicker-inline.test.sveltesrc/lib/extend/tags/Tags.sveltesrc/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-eventv14.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-eventv14.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 ofvalueas 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
$statefor 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
onselectcallback 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
userEventon line 3 is appropriate for@testing-library/user-eventv14.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-scopeanddata-partattributes 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
compareDocumentPositionfor 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
buttonkey andcardPropsobject 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.buttonkey styles the add button, and the newcardPropsobject spreads per-card styling properties into KanbanCard. Bothclassandtitlefields withincardPropsare valid properties that apply to the card component's styling slots.Verification confirmed no remaining references to old prop names (such as
card:,cardTitle:, oraddButton:) 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-partattributes 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 fromtags()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 viaclsx()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"; |
There was a problem hiding this comment.
🧩 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.tsRepository: 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.jsonRepository: 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 tsRepository: 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.
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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 sinceexpect(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 sincescreen.findByTestIdon 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
📒 Files selected for processing (4)
src/tests/forms/select/multiselect.test.tssrc/tests/forms/select/select.test.tssrc/tests/forms/textarea/textarea.test.tssrc/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.tssrc/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 directaddEventListenerapproach 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 divThe 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.
🔗 Related issue (optional)
Closes #
📑 Description
🔍 PR Type
🚦 PR Status
✅ Checklist
pnpm lint && pnpm check && pnpm test:e2eand all tests passmainbranch (not the published npm version)🧪 Screenshots / Demos (optional)
ℹ️ Additional Information
Summary by CodeRabbit
Breaking Changes
Improvements
New
✏️ Tip: You can customize this high-level summary in your review settings.