Skip to content

Drawer as Dialog#1715

Merged
shinokada merged 4 commits intothemesberg:mainfrom
jjagielka:drawer
Aug 13, 2025
Merged

Drawer as Dialog#1715
shinokada merged 4 commits intothemesberg:mainfrom
jjagielka:drawer

Conversation

@jjagielka
Copy link
Copy Markdown
Contributor

@jjagielka jjagielka commented Aug 12, 2025

📑 Description

Helper component created: Dialog. It's now base for:

  • Modal quite straight forward
  • Drawer - breaking change

The biggest change for Drawer is that now it's controlled by bind:open not by bind:hidden. This to be in sync with underlying Dialog.

As Drawer is now dialog we don't need to manage backdrop, but rather modal / non-modal case.
Position fixed and absolute now don't have sense (unless non-modal case).
Body scrolling - I don't understand that case, so probably to be removed.

Lots of side effects as Drawer was used in many other files / examples.

Status

  • Not Completed
  • Completed

✅ Checks

  • My pull request adheres to the code style of this project
  • My code requires changes to the documentation
  • I have updated the documentation and api-check directory as required
  • I have checked the page with https://validator.unl.edu/
  • All the tests have passed
  • My pull request is based on the latest commit (not the npm version).

ℹ Additional Information

Summary by CodeRabbit

  • New Features

    • Added a public Dialog component: configurable modal/non‑modal dialogs with bind:open, outside‑click control, focus trap, form support, transitions and styling hooks.
  • Refactor

    • Drawer and Modal now render via Dialog; visibility uses open; transitioned prop names standardized (transitionParams); outsideclose/modal semantics replace older outside/backdrop flags; styling/themes unified.
  • Documentation

    • Examples, docs and builder pages updated to the open-based API, new props and usage patterns.

@vercel
Copy link
Copy Markdown

vercel bot commented Aug 12, 2025

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

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Aug 12, 2025

Walkthrough

Adds a new Dialog component and theme, centralizes dialog-related props/types, refactors Modal and Drawer to delegate rendering/behavior to Dialog, updates drawer/modal themes to extend dialog, and migrates examples/docs from bind:hidden/backdrop/activateClickOutside → bind:open/modal/outsideclose and transitionParams.

Changes

Cohort / File(s) Summary
Dialog component & exports
src/lib/dialog/Dialog.svelte, src/lib/dialog/index.ts, src/lib/dialog/theme.ts, src/lib/index.ts
New Dialog.svelte (TypeScript) implementing native integration (form/modal modes), lifecycle callbacks (onaction/oncancel/onsubmit/ontoggle), focus trap, dismissal, transitions, and styling via dialog() theme; re-exports added and surfaced in library index.
Drawer refactor & theme
src/lib/drawer/Drawer.svelte, src/lib/drawer/theme.ts
Drawer now renders via Dialog (bind:open); public API changed from hidden/backdrop/activateClickOutside/transitionType → open/outsideclose/transition; theme extends dialog and simplifies slots, placement, and backdrop handling.
Modal refactor & theme
src/lib/modal/Modal.svelte, src/lib/modal/theme.ts
Modal delegates rendering/lifecycle to Dialog (bind:open), removes native dialog handlers and legacy props, adopts transitionParams; modal theme extends dialog and updates slots/placements.
Types centralization
src/lib/types.ts
Adds DialogProps and DialogVariants; refactors DrawerProps and ModalProps to extend/reuse dialog typings and reflect the new prop surface (transitionParams, modal, outsideclose, etc.).
Examples & docs — Drawer migration
src/routes/api-check/components/drawer/examples/*, src/routes/examples/drawer/*.svelte, src/routes/blocks/**, src/routes/docs/**, src/routes/builder/drawer/+page.svelte
Examples/docs updated: rename hiddenX → openX, bind:hidden → bind:open, replace backdrop/activateClickOutside with modal/outsideclose or CSS backdrop classes, remove some CloseButton/header wrappers, and update generated code snippets.
Specific page & example updates
src/routes/admin-dashboard/(sidebar)/crud/products/+page.svelte, src/routes/builder/modal/+page.svelte, src/routes/api-check/forms/timepicker.svelte, various drawer example pages
Replace hidden → open bindings; update modal usage from paramstransitionParams; align triggers and handlers to new open semantics and new Drawer props (outsideclose/modal).

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant Drawer
  participant Dialog
  participant HTMLDialog

  User->>Drawer: set open = true
  Drawer->>Dialog: render(bind:open, transition, transitionParams, outsideclose, modal)
  Dialog->>HTMLDialog: show() / showModal()
  User-->>Dialog: interact (click outside / Esc / CloseButton / submit)
  Dialog->>Dialog: evaluate autoclose/outsideclose/permanent/onaction/onsubmit/oncancel
  Dialog->>HTMLDialog: close()
  Dialog-->>Drawer: bind updates open = false
Loading
sequenceDiagram
  actor User
  participant Modal
  participant Dialog
  participant HTMLDialog

  User->>Modal: set open = true
  Modal->>Dialog: render(bind:open, transitionParams)
  Dialog->>HTMLDialog: showModal()
  User-->>Dialog: submit / cancel / toggle
  Dialog->>Dialog: call onsubmit / oncancel / onaction and manage returnValue
  Dialog->>HTMLDialog: close()
  Dialog-->>Modal: bind updates open = false
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Dismissable #1700 — Dismissable context/utilities used by the new Dialog and affecting dismissal integration.
  • Modal #1668 — Modal lifecycle and dialog behavior changes overlapping with delegation into Dialog.
  • Dialog #1665 — Dialog/init and submit/cancel lifecycle refactors similar to the new Dialog control flow.

Poem

I nibble code where dialogs bloom,
A tiny gate that shows a room.
Drawers open, close with grace,
Focus found in snug little space.
Hoppy props — now springtime’s pace. 🥕✨

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 31

🔭 Outside diff range comments (7)
src/routes/blocks/application/crud-create-drawers.md (1)

50-52: Fix label association and brand field typo

  • “Bland” appears to be a typo for “Brand.”
  • The Description label’s for doesn’t match the textarea id, breaking label association.

Apply this diff:

-      <div class="mb-6">
-        <Label for="bland" class="mb-2 block">Bland</Label>
-        <Input id="bland" name="bland" required placeholder="Product brand" />
-      </div>
+      <div class="mb-6">
+        <Label for="brand" class="mb-2 block">Brand</Label>
+        <Input id="brand" name="brand" required placeholder="Product brand" />
+      </div>
@@
-      <div class="mb-6">
-        <Label for="brand" class="mb-2">Description</Label>
-        <Textarea id="message" placeholder="Enter event description here" rows={4} name="message" />
-      </div>
+      <div class="mb-6">
+        <Label for="message" class="mb-2">Description</Label>
+        <Textarea id="message" placeholder="Enter event description here" rows={4} name="message" />
+      </div>

Also applies to: 64-66

src/routes/builder/modal/+page.svelte (2)

63-80: Update the generator to emit transitionParams instead of params

The generated snippet is out of date with the new API.

-        props.push(`params={{${paramsString}}}`);
+        props.push(`transitionParams={{${paramsString}}}`);

82-85: Update generated markup to use bind:open and drop legacy {closeModal}

Keep using modalStatus as the bound variable to minimize changes elsewhere.

-      return `<Modal title="Terms of Service" {modalStatus} {closeModal}${propsString}>
+      return `<Modal title="Terms of Service"${propsString} bind:open={modalStatus}>
   Modal content
 </Modal>`;
src/routes/builder/drawer/+page.svelte (1)

84-118: Builder code generator still emits legacy Drawer API and contains invalid markup.

The generated snippet still uses legacy props and structure (activateClickOutside, transitionType, params, drawerStatus/closeDrawer, drawer.toggle) and has a malformed class attribute on Drawerhead. This will produce incorrect and broken code for users copying from the builder.

Update to emit the new API: open/bind:open, outsideclose, transition, transitionParams, and correct handlers.

Apply this diff to fix the generator:

-      if (!outsideclickStatus) props.push(" activateClickOutside={false}");
+      if (!outsideclickStatus) props.push(" outsideclose={false}");
@@
-      if (currentTransition !== transitions[0]) {
-        props.push(` transitionType={${currentTransition.transition.name}}`);
+      if (currentTransition !== transitions[0]) {
+        props.push(` transition={${currentTransition.transition.name}}`);
@@
-        props.push(` params={{${paramsString}}}`);
+        props.push(` transitionParams={{${paramsString}}}`);
@@
-      return `<Button onclick={drawer.toggle}>Drawer</Button>
-<Drawer drawerStatus={drawerStatus} closeDrawer={closeDrawer}${propsString}>
-  <Drawerhead onclick={closeDrawer} class="mb-4>
+      return `<Button onclick={() => (open = true)}>Drawer</Button>
+<Drawer bind:open${propsString}>
+  <Drawerhead onclick={() => (open = false)} class="mb-4">
     <h5 id="drawer-label" class="inline-flex items-center text-xl font-semibold text-gray-500 dark:text-gray-400">
         <InfoCircleSolid class="me-2.5 h-5 w-5" />${selectedTransition} drawer
       </h5>
   </Drawerhead>
     My Drawer
 </Drawer>`;
src/lib/modal/Modal.svelte (1)

46-80: Update the in-file props documentation block to match the new API.

The block still lists removed props (onaction, oncancel, onsubmit, ontoggle, form, modal, autoclose, focustrap, params). Replace with the current public API (e.g., open, permanent, dismissable, outsideclose, size, placement, classes, transition, transitionParams, fullscreen, etc.).

I can draft a revised doc block if you want the exact text.

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

21-28: Avoid binding window size for transition computation.

Binding innerWidth/innerHeight and translating by viewport dimensions causes unnecessary reactivity and excessive off-screen motion. The simpler fixed-distance defaults above are adequate and perform better.

Also applies to: 30-30


43-55: Update the inline props doc to reflect the new API.

The comment still lists deprecated props (hidden, activateClickOutside, position, backdrop, transitionType). Replace with: open, width, placement, class, classes, transition, transitionParams, outsideclose (passed through), modal (if supported via Dialog), bodyScrolling (only if implemented), ...restProps.

I can propose an updated block if desired.

🧹 Nitpick comments (23)
src/routes/blocks/application/crud-update-drawers.md (1)

35-36: Add aria-labelledby for accessible dialog naming

Tie the Drawer to the title element to provide an accessible name for assistive tech.

Apply this diff:

-  <Drawer bind:open id="sidebar4">
+  <Drawer bind:open id="sidebar4" aria-labelledby="drawer-label">
src/routes/blocks/application/crud-read-drawers.md (2)

32-36: Add aria-labelledby to improve dialog accessibility

Associate the dialog with its visible title.

Apply this diff:

-  <Drawer bind:open id="sidebar1">
+  <Drawer bind:open id="sidebar1" aria-labelledby="drawer-label">

32-36: Consider restoring a visible close affordance

Relying solely on outside-click/Escape may reduce discoverability. Adding a CloseButton improves UX, especially on touch devices.

Apply this diff to include a close control without heavy layout changes:

-  <Drawer bind:open id="sidebar1">
+  <Drawer bind:open id="sidebar1" aria-labelledby="drawer-label">
@@
-    <div>
-      <h4 id="drawer-label" class="mb-1.5 text-xl leading-none font-semibold text-gray-900 dark:text-white">Apple iMac 25"</h4>
-      <p class="mb-5 text-xl font-bold text-gray-900 dark:text-white">$2999</p>
-    </div>
+    <div class="mb-2 flex items-start justify-between">
+      <div>
+        <h4 id="drawer-label" class="mb-1.5 text-xl leading-none font-semibold text-gray-900 dark:text-white">Apple iMac 25"</h4>
+        <p class="text-xl font-bold text-gray-900 dark:text-white">$2999</p>
+      </div>
+      <CloseButton class="ml-2" onclick={() => (open = false)} aria-label="Close product details drawer" />
+    </div>

If the intent is to rely on outside-close globally, verify that outsideclose defaults to true for Drawer. If not, consider explicitly setting it in examples.

src/routes/blocks/application/crud-create-drawers.md (1)

42-44: Add aria-labelledby for accessible dialog naming

Connect the Drawer to its title for screen readers.

Apply this diff:

-  <Drawer bind:open id="sidebar4">
+  <Drawer bind:open id="sidebar4" aria-labelledby="drawer-label">
src/lib/index.ts (1)

85-86: Remove duplicate exports to avoid confusion

video and utils are exported earlier (Lines 50–51 and 49). Duplicate exports are harmless at build but add noise.

Apply this diff:

-export * from "./video";
-export * from "./utils";
src/routes/api-check/components/drawer/examples/Default.svelte (1)

9-9: Prefer Svelte’s on:click for event binding

Use the idiomatic on:click to attach handlers; this avoids relying on prop forwarding and is consistent with Svelte’s event system.

Apply this diff:

-  <Button onclick={() => (open1 = true)}>Show drawer</Button>
+  <Button on:click={() => (open1 = true)}>Show drawer</Button>
src/routes/api-check/components/drawer/examples/Right.svelte (1)

15-15: Prefer Svelte’s on:click for event binding

Use on:click to attach handlers instead of onclick for idiomatic Svelte and to avoid relying on prop forwarding.

Apply this diff:

-  <Button onclick={() => (open6 = true)}>Show drawer</Button>
+  <Button on:click={() => (open6 = true)}>Show drawer</Button>
src/routes/api-check/components/drawer/examples/Left.svelte (1)

9-9: Prefer Svelte’s on:click for event binding

Use on:click to attach handlers instead of onclick for idiomatic Svelte and to avoid relying on prop forwarding.

Apply this diff:

-  <Button onclick={() => (open5 = true)}>Show drawer</Button>
+  <Button on:click={() => (open5 = true)}>Show drawer</Button>
src/routes/api-check/components/drawer/examples/Bottom.svelte (1)

7-11: Minor: verify easing choice for UX consistency.

You added easing: sineIn. Many UIs prefer sineOut or sineInOut for more natural settle-in/out motion. Not critical; just ensure this matches the rest of the Drawer examples for a consistent feel.

src/routes/api-check/forms/timepicker.svelte (1)

211-215: Close-on-save behavior wired to state; consider Svelte preventDefault modifier.

e.preventDefault() then setting open1 = false works. For brevity and clarity, you could use the Svelte modifier on the form and simplify the handler to avoid dealing with the event.

For example:

  • Change form: on:submit|preventDefault={saveAll}
  • Then define function saveAll(): void { /* save... */ open1 = false; }
src/routes/api-check/components/drawer/examples/DisablingOutside.svelte (1)

5-5: Inline constant outsideclose to reduce noise

Since it’s never changed, you can inline it at the usage site.

-let outsideclose = false;
 
-<Drawer {outsideclose} bind:open={open10} id="sidebar10" aria-labelledby="drawer-label">
+<Drawer outsideclose={false} bind:open={open10} id="sidebar10" aria-labelledby="drawer-label">

Also applies to: 12-12

src/routes/api-check/components/drawer/examples/Disabled.svelte (1)

6-6: Rename state for clarity

Consider a clearer name that reflects non-modal usage. This is an example file, but readability helps.

-  let openBackdropFalse = $state(false);
+  let openNonModal = $state(false);

And update usages:

-  <Button on:click={() => (openBackdropFalse = true)}>Show drawer</Button>
+  <Button on:click={() => (openNonModal = true)}>Show drawer</Button>
-<Drawer modal={false} bind:open={openBackdropFalse} aria-labelledby="drawer-label">
+<Drawer modal={false} bind:open={openNonModal} aria-labelledby="drawer-label">

Also applies to: 10-10, 13-13

src/routes/api-check/components/drawer/examples/Navigation.svelte (1)

4-4: Optional: rename open2 to something meaningful

Minor readability tweak in the example.

-  let open2 = $state(false);
+  let openNavigation = $state(false);
-  <Button on:click={() => (open2 = true)}>Show navigation</Button>
+  <Button on:click={() => (openNavigation = true)}>Show navigation</Button>
-<Drawer bind:open={open2} aria-labelledby="drawer-nav-label" class="w-64 bg-gray-50 p-0 dark:bg-gray-800">
+<Drawer bind:open={openNavigation} aria-labelledby="drawer-nav-label" class="w-64 bg-gray-50 p-0 dark:bg-gray-800">

Also applies to: 9-9, 11-11

src/routes/api-check/components/drawer/examples/OnlyOutside.svelte (1)

5-5: Optional: shorten the state variable name

Improves readability without changing behavior.

-  let openDisablingOnlyOutsideClick = $state(false);
+  let openOutsideDisabled = $state(false);
-  <Button on:click={() => (openDisablingOnlyOutsideClick = true)}>Show drawer</Button>
+  <Button on:click={() => (openOutsideDisabled = true)}>Show drawer</Button>
-<Drawer outsideclose={false} bind:open={openDisablingOnlyOutsideClick} aria-labelledby="drawer-label">
+<Drawer outsideclose={false} bind:open={openOutsideDisabled} aria-labelledby="drawer-label">

Also applies to: 9-9, 12-12

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

12-20: Remove commented variant scaffolding or implement it

The commented variants.position and defaultVariants blocks add noise and can mislead future readers. Either implement them or remove the commented code to keep the theme lean.

Apply this cleanup:

-    variants: {
-        // position: {
-        //     fixed: { base: "fixed" },
-        //     absolute: { base: "absolute" }
-        // },
-    },
-    defaultVariants: {
-        // position: "fixed"
-    }
+    variants: {
+    },
+    defaultVariants: {
+    }
src/routes/api-check/components/drawer/examples/Scrolling.svelte (1)

16-17: Ensure header CloseButton actually closes the Drawer

With Dialog handling dismissal, this header CloseButton may not close unless it’s wired into the dismissable context or bound to state. If the context isn’t in use here, explicitly toggle openHidden to false for clarity.

Apply this change:

-    <CloseButton class="mb-4 dark:text-white" />
+    <CloseButton class="mb-4 dark:text-white" onclick={() => (openHidden = false)} />

Alternatively, remove it and rely on Dialog’s built-in dismiss button (dismissable={true}).

src/lib/types.ts (1)

915-916: Typo/minor formatting in type literal for onselect payload

There’s no space before the index signature; not harmful but reduces readability.

-  onselect?: (data: { time: string; endTime: string;[key: string]: string }) => void;
+  onselect?: (data: { time: string; endTime: string; [key: string]: string }) => void;
src/lib/modal/theme.ts (1)

11-13: Slot overrides are minimal and consistent with dialog base

The simplified base and form work with the extended dialog theme. Note that bg-white dark:bg-gray-800 exists both here and in the dialog base; duplication is harmless but could be trimmed later.

If desired, you can rely on dialog’s bg colors and remove them here:

-    base: "w-full rounded-lg divide-y text-gray-500 dark:text-gray-400 border-gray-300 dark:border-gray-700 divide-gray-300 dark:divide-gray-700 bg-white dark:bg-gray-800 pointer-events-auto",
+    base: "w-full rounded-lg divide-y text-gray-500 dark:text-gray-400 border-gray-300 dark:border-gray-700 divide-gray-300 dark:divide-gray-700 pointer-events-auto",
src/lib/dialog/Dialog.svelte (1)

94-99: CloseButton renders with type="submit" even when no form is present

When form === false, type="submit" has no effect. Dismissal currently relies on the dismissable context via createDismissableContext(close_handler), which is okay, but the type attribute is misleading. Consider setting type="button" when not in form mode.

-    <CloseButton type="submit" formnovalidate class={closeCls({ class: clsx(classes?.close) })} />
+    <CloseButton
+      type={form ? "submit" : "button"}
+      formnovalidate
+      class={closeCls({ class: clsx(classes?.close) })}
+    />
src/lib/modal/Modal.svelte (1)

29-29: Use type="button" for the header CloseButton to avoid accidental form submissions.

This avoids submitting a nested form if present in modal content.

Apply this diff:

-          <CloseButton type="submit" formnovalidate class={clsx(styling.close)} />
+          <CloseButton type="button" class={clsx(styling.close)} />
src/routes/docs/components/drawer.md (3)

389-389: Grammar: “its” not “it’s”.

[Suggest fix] “Use the drawer’s backdrop:xxx class to manage its look.”

Apply this diff:

-Use the drawer's `backdrop:xxx` class to manage it's look.
+Use the drawer's `backdrop:xxx` class to manage its look.

392-392: Grammar and clarity in Non-modal note.

Correct typos and phrasing.

Apply this diff:

-Drawer by default is `modal` (see `dialog`). You can set prop `modal={false}` to open `Drawer` in non-modal mode, that means with no backdrop. Note howerver, that you will need managed the `Drawer` position, z-index and `Esc` button manually.
+Drawer is `modal` by default (see `Dialog`). Set `modal={false}` to open the `Drawer` in non-modal mode (no backdrop). Note, however, that you will need to manage the Drawer’s position, z-index, and Esc key handling manually.

20-24: Minor: imported items in examples not used.

CloseButton and sineIn are imported but not used in several blocks. Consider removing them from the examples to reduce noise.

Also applies to: 33-37

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8117d65 and 5c102ad.

📒 Files selected for processing (34)
  • src/lib/dialog/Dialog.svelte (1 hunks)
  • src/lib/dialog/index.ts (1 hunks)
  • src/lib/dialog/theme.ts (1 hunks)
  • src/lib/drawer/Drawer.svelte (2 hunks)
  • src/lib/drawer/theme.ts (1 hunks)
  • src/lib/index.ts (1 hunks)
  • src/lib/modal/Modal.svelte (3 hunks)
  • src/lib/modal/theme.ts (2 hunks)
  • src/lib/types.ts (9 hunks)
  • src/routes/admin-dashboard/(sidebar)/crud/products/+page.svelte (2 hunks)
  • src/routes/api-check/components/drawer/examples/Bottom.svelte (2 hunks)
  • src/routes/api-check/components/drawer/examples/Contact.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Default.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Disabled.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/DisablingOutside.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Enabled.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Form.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Left.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Navigation.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/OnlyOutside.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Position.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Right.svelte (2 hunks)
  • src/routes/api-check/components/drawer/examples/Scrolling.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Top.svelte (2 hunks)
  • src/routes/api-check/forms/timepicker.svelte (4 hunks)
  • src/routes/blocks/application/crud-create-drawers.md (2 hunks)
  • src/routes/blocks/application/crud-read-drawers.md (1 hunks)
  • src/routes/blocks/application/crud-update-drawers.md (1 hunks)
  • src/routes/blocks/application/faceted-search-drawers.md (1 hunks)
  • src/routes/builder/drawer/+page.svelte (3 hunks)
  • src/routes/builder/modal/+page.svelte (1 hunks)
  • src/routes/docs/components/drawer.md (15 hunks)
  • src/routes/docs/forms/timepicker.md (4 hunks)
  • src/routes/examples/drawer/classesCheck.svelte (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
PR: themesberg/flowbite-svelte#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/forms/timepicker.md
  • src/routes/api-check/forms/timepicker.svelte
🧬 Code Graph Analysis (3)
src/lib/modal/theme.ts (4)
src/lib/modal/index.ts (1)
  • modal (2-2)
src/lib/theme/themeUtils.ts (1)
  • Classes (14-16)
src/lib/dialog/index.ts (1)
  • dialog (2-2)
src/lib/dialog/theme.ts (1)
  • dialog (6-21)
src/lib/types.ts (6)
src/lib/drawer/theme.ts (1)
  • DrawerVariants (5-5)
src/lib/forms/helper/theme.ts (1)
  • HelperVariants (4-4)
src/lib/modal/theme.ts (1)
  • ModalVariants (6-6)
src/lib/dialog/theme.ts (1)
  • DialogVariants (4-4)
src/lib/toolbar/theme.ts (1)
  • ToolbarGroupVariants (6-6)
src/lib/skeleton/theme.ts (2)
  • TestimonialPlaceholderVariants (9-9)
  • WidgetPlaceholderVariants (12-12)
src/lib/drawer/theme.ts (3)
src/lib/theme/themeUtils.ts (1)
  • Classes (14-16)
src/lib/dialog/index.ts (1)
  • dialog (2-2)
src/lib/dialog/theme.ts (1)
  • dialog (6-21)
🪛 ESLint
src/lib/dialog/Dialog.svelte

[error] 74-74: Expected an assignment or function call and instead saw an expression.

(@typescript-eslint/no-unused-expressions)

🪛 LanguageTool
src/routes/docs/components/drawer.md

[grammar] ~392-~392: Ensure spelling is correct
Context: ...mode, that means with no backdrop. Note howerver, that you will need managed the `Drawer...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.17.2)
src/routes/docs/components/drawer.md

458-458: Trailing punctuation in heading
Punctuation: '.'

(MD026, no-trailing-punctuation)

🔇 Additional comments (44)
src/routes/blocks/application/crud-update-drawers.md (1)

24-24: Switch to bind:open is consistent and clear

Using an open boolean and bind:open aligns with the new Dialog-backed Drawer API and simplifies state handling.

Also applies to: 27-27, 33-36

src/routes/docs/forms/timepicker.md (1)

419-419: bind:open migration and control flow look good

The Drawer visibility is driven by open and properly toggled on open, cancel, and save. This matches the new Dialog model.

Also applies to: 494-496, 501-501, 552-553

src/routes/blocks/application/crud-read-drawers.md (1)

24-24: bind:open migration LGTM

Visibility is now controlled by open and usage in the trigger and Drawer matches the new API.

Also applies to: 29-29, 32-36

src/routes/blocks/application/crud-create-drawers.md (1)

24-24: bind:open migration looks correct

open state, trigger, and Drawer binding reflect the new API and behavior.

Also applies to: 34-35, 40-41, 42-44

src/lib/index.ts (1)

22-22: Publicly exporting Dialog is appropriate

Exposing ./dialog at the root aligns the API surface with Drawer/Modal’s new foundation.

src/routes/api-check/components/drawer/examples/Default.svelte (2)

5-5: State rename to open1 aligns with new Drawer API

Using $state(false) and open1 matches the new bind:open contract for Drawer.


12-12: Update remaining bind:hidden occurrences in documentation

A repo-wide search uncovered several bind:hidden usages in the static documentation that need to be updated to bind:open to stay in sync with the new Drawer API:

• static/llm/forms/timepicker.md:490
• static/llm/components/drawer.md:31, 64, 142, 188, 250, 292, 332, 369, 407, 441, 475, 510, 538, 573

Please update each example to use:

- <Drawer bind:hidden={…} …>
+ <Drawer bind:open={…} …>

and adjust any associated variable names if necessary.

Likely an incorrect or invalid review comment.

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

1-2: Public exports for Dialog look good

Named re-export of the Svelte component and theme is clear and tree-shakable.

src/routes/blocks/application/faceted-search-drawers.md (2)

18-18: State rename to open aligns with new Drawer API

The boolean open state reflects the new bind:open contract and is initialized correctly.


23-23: LGTM on trigger update

Switching the trigger to set open = true matches the new state semantics.

src/routes/api-check/components/drawer/examples/Right.svelte (1)

6-6: State rename to open6 aligns with new Drawer API

Using $state(false) and open6 matches the bind:open contract.

src/routes/api-check/components/drawer/examples/Left.svelte (1)

5-5: State rename to open5 aligns with new Drawer API

Using $state(false) and open5 matches the bind:open contract.

src/routes/admin-dashboard/(sidebar)/crud/products/+page.svelte (2)

11-11: Correct migration to open-based state.

Switching to let open: boolean = $state(false) aligns with the Dialog-based Drawer API and sets a clear closed-by-default state.


98-100: bind:open usage is correct; consider explicit modal intent.

The shorthand bind:open correctly binds to the local open variable, and passing it to DrawerComponent enables children to close the Drawer. If this Drawer is intended to be modal (backdrop, focus-trap), consider setting the explicit prop if the new API doesn’t default to modal in your theme, to avoid ambiguity in examples.

Do you want me to scan the new Drawer API to confirm the default modal behavior and update this instance to be explicit for docs consistency?

src/routes/api-check/components/drawer/examples/Bottom.svelte (3)

6-6: State migration to open looks good.

open8 defaults to false and is used consistently with bind:open.


15-15: Open handler is correct.

Directly setting open8 = true is clear and avoids ambiguous toggling.


18-18: bind:open and transitionParams wiring is correct.

placement="bottom" with transitionParams={transitionParamsBottom} and bind:open={open8} conforms to the new API and keeps the example focused.

src/routes/api-check/components/drawer/examples/Contact.svelte (2)

5-5: Good migration to open-based state.

open3 = $state(false) follows the new Drawer/Dialog model.


9-12: Event and binding changes look correct.

Opening with open3 = true and switching to bind:open={open3} reflect the new API without altering behavior.

src/routes/api-check/forms/timepicker.svelte (4)

148-148: State initialization for Drawer is correct.

open1 = $state(false) matches the new open-binding convention.


423-423: Open handler aligns with the new API.

Using open1 = true avoids toggle edge cases and keeps the example deterministic.


429-429: bind:open is correctly applied to Drawer.

Binding open1 ensures close buttons and outside interactions can update the parent state through the Dialog-based Drawer.


481-481: Cancel closes the Drawer as expected.

Explicitly closing with open1 = false is clear. UX-wise, this aligns with the Save handler’s close behavior.

src/routes/api-check/components/drawer/examples/Enabled.svelte (2)

5-5: State variable naming reflects the example intent.

openBackdropTrue reads clearly in the “Enabled” example context.


9-12: Open binding migrated correctly; consider making modal intent explicit.

Since this example likely demonstrates “backdrop enabled,” consider setting the explicit prop (e.g., modal={true}) if that is now the public surface, to avoid relying on defaults in documentation examples.

Would you like me to sweep the new Drawer API and examples to ensure all “backdrop-enabled” demos explicitly use modal={true} for clarity?

src/routes/examples/drawer/classesCheck.svelte (1)

4-9: Migration to bind:open is correct and consistent

State initialization and the trigger button correctly reflect the new open-based API.

src/routes/api-check/components/drawer/examples/Form.svelte (1)

5-11: Migration to bind:open looks good

State and binding updates are correct and match the new Dialog-based API.

src/routes/api-check/components/drawer/examples/Top.svelte (1)

6-6: Open-binding migration is correct

The state, trigger, and Drawer binding are updated correctly and align with the new API.

Also applies to: 15-15, 18-18

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

112-112: Prop rename to transitionParams is correct

This aligns the live example with the new Dialog-based API.

Note: The code generator below still emits params= and {modalStatus} {closeModal}. See next comments for fixes.

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

8-11: LGTM: theme extends dialog and simplifies base/styles

Extending the dialog theme and simplifying the base slot looks consistent with the new Dialog-based architecture.

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

6-11: Solid initial theme token for Dialog; slots and base classes look consistent

The base/form/close slots cover the essentials for dialog and interop with Modal/Drawer. The ::backdrop and open: variants align with native semantics. No issues here.

src/lib/types.ts (7)

90-91: Correct import path and type usage for DialogVariants

Importing DialogVariants from ./dialog/theme keeps types local and consistent across Modal/Drawer. Looks good.


556-558: Drawer inherits DialogProps cleanly; bodyScrolling isolated here is appropriate

Extending DialogProps ensures Drawer stays in sync with Dialog capabilities while preserving Drawer-specific props via bodyScrolling. Good separation.


1032-1040: Avoid classes duplication in Modal by omitting from DialogProps

Using Omit<DialogProps, "classes"> is the right move since ModalVariants already includes Classes<typeof dialog>. Prevents structural type conflicts and makes classes.close available through the extended dialog theme.


721-721: Style-only change is fine

Whitespace-only change; no impact.


1117-1117: Style-only change is fine

Whitespace-only change; no impact.


1426-1426: Style-only change is fine

Whitespace-only change; no impact.


1436-1436: Style-only change is fine

Whitespace-only change; no impact.

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

3-3: Extending modal from dialog centralizes shared concerns

extend: dialog is the right direction; it de-duplicates styling and keeps the close slot available via Classes<typeof dialog>. Good call.


24-32: Placement classes applied correctly, no overrides detected

We’ve confirmed that in src/lib/modal/Modal.svelte the placement prop feeds directly into modalStyle, and src/lib/modal/theme.ts only uses the fixed inset container plus the auto-margin utilities for each of the nine placements. No other positioning rules (absolute, inset-*, overriding margins) were found in the Modal files.

Modal.svelte lines 9 & 20: placement is passed into modalStyle
theme.ts lines 24–32: only fixed inset-0 plus mt|mb|mx|my margin classes

Please proceed with a visual smoke test of all nine placement options at various breakpoints to catch any cross-browser quirks.

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

137-141: Migration to bind:open is correct and consistent.

The button now opens via open = true and Drawer binds to open. Drawerhead closes via open = false. This aligns with the new Dialog-based API.


147-147: outsideclose status display looks good.

The label reflects the current outsideclose setting, which matches the new API semantics.


163-163: Good UX control for outsideclose.

Toggling outsideclose via this button is a clear demonstration of the new prop’s effect.

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

32-34: LGTM on Dialog integration and class theming.

Forwarding rest props to Dialog while resolving theme classes keeps Drawer lean and consistent with the new architecture.

Comment on lines 13 to 23
placement: {
left: { base: "inset-y-0 start-0" },
right: { base: "inset-y-0 end-0" },
top: { base: "inset-x-0 top-0" },
bottom: { base: "inset-x-0 bottom-0" }
left: { base: "me-auto h-full" },
right: { base: "ms-auto h-full" },
top: { base: "mb-auto w-full" },
bottom: { base: "mt-auto w-full" }
},
width: {
default: { base: "w-80" },
full: { base: "w-full" },
half: { base: "w-1/2" }
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Width vs. placement conflict for top/bottom drawers

For placement="top"/"bottom" you add w-full, but the width variant defaults to w-80. Depending on class order, w-80 can override w-full, producing incorrect widths for top/bottom drawers.

Consider enforcing w-full for top/bottom via compoundVariants so it reliably wins:

 export const drawer = tv({
   extend: dialog,
   slots: {
     base: "p-4 max-h-screen max-w-screen",
   },
   variants: {
-    placement: {
+    placement: {
       left: { base: "me-auto h-full" },
       right: { base: "ms-auto h-full" },
       top: { base: "mb-auto w-full" },
       bottom: { base: "mt-auto w-full" }
     },
     width: {
       default: { base: "w-80" },
       full: { base: "w-full" },
       half: { base: "w-1/2" }
     },
   },
+  compoundVariants: [
+    // Ensure top/bottom drawers are always full width regardless of width variant
+    { placement: ["top", "bottom"], class: { base: "!w-full" } },
+  ],
   defaultVariants: {
     placement: "left",
     width: "default"
   }
 });

Alternatively, reorder the variants so placement classes are appended after width, but compoundVariants is more robust.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
placement: {
left: { base: "inset-y-0 start-0" },
right: { base: "inset-y-0 end-0" },
top: { base: "inset-x-0 top-0" },
bottom: { base: "inset-x-0 bottom-0" }
left: { base: "me-auto h-full" },
right: { base: "ms-auto h-full" },
top: { base: "mb-auto w-full" },
bottom: { base: "mt-auto w-full" }
},
width: {
default: { base: "w-80" },
full: { base: "w-full" },
half: { base: "w-1/2" }
},
export const drawer = tv({
extend: dialog,
slots: {
base: "p-4 max-h-screen max-w-screen",
},
variants: {
placement: {
left: { base: "me-auto h-full" },
right: { base: "ms-auto h-full" },
top: { base: "mb-auto w-full" },
bottom: { base: "mt-auto w-full" }
},
width: {
default: { base: "w-80" },
full: { base: "w-full" },
half: { base: "w-1/2" }
},
},
compoundVariants: [
// Ensure top/bottom drawers are always full width regardless of width variant
{ placement: ["top", "bottom"], class: { base: "!w-full" } },
],
defaultVariants: {
placement: "left",
width: "default"
}
});
🤖 Prompt for AI Agents
In src/lib/drawer/theme.ts around lines 13 to 23, the placement variant sets
w-full for top/bottom but the width variant can later append w-80 and override
it; add compoundVariants that match placement: "top" and placement: "bottom"
(for any width variant, or explicitly for default/half/full) and set the
computed class to enforce w-full for those placements so the top/bottom drawers
always use full width; alternatively (if you prefer) reorder the variants so
placement classes are appended after width, but the recommended fix is to add
explicit compoundVariants forcing w-full for placement "top" and "bottom".

</div>

<Drawer bind:hidden class="w-96 bg-gray-50 p-6 dark:bg-gray-800" id="drawer-timepicker">
<Drawer bind:open class="w-96 bg-gray-50 p-6 dark:bg-gray-800" id="drawer-timepicker">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Wire CloseButton to actually close the Drawer and add accessible naming

CloseButton currently doesn’t modify open; wire it to close. Also set aria-labelledby to connect the dialog to its title.

Apply this diff:

-<Drawer bind:open class="w-96 bg-gray-50 p-6 dark:bg-gray-800" id="drawer-timepicker">
+<Drawer bind:open class="w-96 bg-gray-50 p-6 dark:bg-gray-800" id="drawer-timepicker" aria-labelledby="drawer-label">
@@
-    <CloseButton class="mb-4 dark:text-white" />
+    <CloseButton class="mb-4 dark:text-white" onclick={() => (open = false)} aria-label="Close time schedule drawer" />

To ensure consistent accessibility across docs, you can scan for Drawers missing aria-labelledby:

Also applies to: 503-507


🏁 Script executed:

#!/bin/bash
# List Drawer usages that bind `open` but lack an aria-labelledby attribute
rg -nP '<Drawer(?![^>]*aria-labelledby)[^>]*bind:open'

Length of output: 4047


Ensure Drawer components include accessible naming and a working close button

Wire each CloseButton to set its open binding to false and add aria-labelledby on the corresponding <Drawer>.

In src/routes/docs/forms/timepicker.md around line 501, apply:

-<Drawer bind:open class="w-96 bg-gray-50 p-6 dark:bg-gray-800" id="drawer-timepicker">
+<Drawer
+  bind:open
+  class="w-96 bg-gray-50 p-6 dark:bg-gray-800"
+  id="drawer-timepicker"
+  aria-labelledby="drawer-label"
+>
@@
-  <CloseButton class="mb-4 dark:text-white" />
+  <CloseButton
+    class="mb-4 dark:text-white"
+    on:click={() => (open = false)}
+    aria-label="Close time schedule drawer"
+  />

Other instances missing aria-labelledby and a working close handler:

  • src/routes/admin-dashboard/(sidebar)/crud/products/+page.svelte:98–99
  • src/routes/builder/drawer/+page.svelte:139
  • src/routes/api-check/forms/timepicker.svelte:429
  • src/routes/api-check/components/drawer/examples/Bottom.svelte:18
  • src/routes/api-check/components/drawer/examples/Contact.svelte:11
  • src/routes/api-check/components/drawer/examples/Navigation.svelte:11
  • src/routes/api-check/components/drawer/examples/Scrolling.svelte:11
  • src/routes/api-check/components/drawer/examples/Top.svelte:18
  • src/routes/api-check/components/drawer/examples/Right.svelte:18
  • src/routes/api-check/components/drawer/examples/OnlyOutside.svelte:12
  • src/routes/api-check/components/drawer/examples/Enabled.svelte:12
  • src/routes/api-check/components/drawer/examples/Form.svelte:11
  • src/routes/api-check/components/drawer/examples/Left.svelte:12
  • src/routes/api-check/components/drawer/examples/Position.svelte:12
  • src/routes/api-check/components/drawer/examples/Disabled.svelte:13
  • src/routes/api-check/components/drawer/examples/DisablingOutside.svelte:12
  • src/routes/docs/components/drawer.md:44, 75, 151, 195, 258, 298, 336, 371, 408, 440, 476
  • src/routes/blocks/application/crud-read-drawers.md:32
  • src/routes/blocks/application/faceted-search-drawers.md:25
  • src/routes/blocks/application/crud-update-drawers.md:35
  • src/routes/blocks/application/crud-create-drawers.md:42
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Drawer bind:open class="w-96 bg-gray-50 p-6 dark:bg-gray-800" id="drawer-timepicker">
<Drawer
bind:open
class="w-96 bg-gray-50 p-6 dark:bg-gray-800"
id="drawer-timepicker"
aria-labelledby="drawer-label"
>
<CloseButton
class="mb-4 dark:text-white"
on:click={() => (open = false)}
aria-label="Close time schedule drawer"
/>
<!-- …rest of drawer content… -->
🤖 Prompt for AI Agents
In src/routes/docs/forms/timepicker.md around line 501, the <Drawer
id="drawer-timepicker" ...> lacks an accessible label and the CloseButton isn't
wired to close it; add aria-labelledby="drawer-timepicker-title" on the Drawer,
add a heading or element inside the drawer with id="drawer-timepicker-title" to
serve as the label, and wire the CloseButton to set the drawer's open binding to
false (e.g., call the handler or set the bound variable to false) so clicking
CloseButton closes the drawer; apply the same pattern to the other listed
files/locations.


<div class="text-center">
<Button onclick={() => (hidden1 = false)}>Show drawer</Button>
<Button onclick={() => (open1 = true)}>Show drawer</Button>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix ARIA: aria-labelledby should reference the heading; aria-controls belongs on the trigger (not the dialog)

The dialog should be labelled by the header (id="drawer-label"). aria-controls is typically used on the control element (button), not on the dialog itself.

Apply this diff:

-  <Button onclick={() => (open1 = true)}>Show drawer</Button>
+  <Button aria-controls="sidebar1" onclick={() => (open1 = true)}>Show drawer</Button>
-<Drawer bind:open={open1} id="sidebar1" aria-controls="sidebar1" aria-labelledby="sidebar1" classes={{ backdrop: "bg-red-700 opacity-50" }}>
+<Drawer bind:open={open1} id="sidebar1" aria-labelledby="drawer-label" classes={{ backdrop: "bg-red-700 opacity-50" }}>

Also applies to: 11-11

🤖 Prompt for AI Agents
In src/routes/examples/drawer/classesCheck.svelte around lines 8 and 11, the
dialog currently uses aria-controls incorrectly and the heading isn't referenced
by aria-labelledby; update the markup so the dialog element has
aria-labelledby="drawer-label" (ensure the dialog has an id, e.g., id="drawer")
and the heading element has id="drawer-label", and move aria-controls to the
trigger Button (e.g., aria-controls="drawer") instead of placing it on the
dialog; remove any aria-controls on the dialog itself.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🔭 Outside diff range comments (1)
src/routes/examples/drawer/classesCheck.svelte (1)

16-16: Wire CloseButton to actually close the Drawer and add an accessible label

Currently it doesn't change open.

-    <CloseButton class="mb-4 dark:text-white" />
+    <CloseButton class="mb-4 dark:text-white" on:click={() => (open1 = false)} aria-label="Close drawer" />
♻️ Duplicate comments (4)
src/routes/examples/drawer/classesCheck.svelte (1)

8-8: Add aria-controls on the trigger (Button), not on the dialog

This links the trigger to the Drawer element and improves a11y.

-  <Button onclick={() => (open1 = true)}>Show drawer</Button>
+  <Button aria-controls="sidebar1" onclick={() => (open1 = true)}>Show drawer</Button>
src/lib/types.ts (1)

557-568: title prop is missing in DialogProps; it gets swallowed if destructured in Dialog.svelte

Either stop destructuring title in Dialog.svelte (preferred), or add it to DialogProps to forward to the underlying element.

Preferred fix (no API expansion): remove title from the destructuring list in Dialog.svelte so it passes through via {...restProps}.

Alternative (if you want to support it explicitly), apply:

 export interface DialogProps extends DialogVariants, HTMLDialogAttributes {
   onaction?: ({ action, data }: { action: string; data: FormData }) => any;
   form?: boolean;
   modal?: boolean;
   autoclose?: boolean;
   focustrap?: boolean;
   permanent?: boolean;
   dismissable?: boolean;
   outsideclose?: boolean;
   transition?: TransitionFunc;
   transitionParams?: ParamsType;
+  title?: string;
 }

To verify whether Dialog.svelte currently destructures title, search:

#!/bin/bash
rg -nA2 -i $'component|script|let\\s*{[^}]*title' src/lib/dialog/Dialog.svelte
src/routes/docs/components/drawer.md (2)

371-381: Remove non-existent Drawer prop “form”

Drawer doesn’t accept a form prop; the attribute is inert and misleading.

-<Drawer form placement="bottom" class="w-full" transitionParams={transitionParamsBottom} bind:open={open8}>
+<Drawer placement="bottom" class="w-full" transitionParams={transitionParamsBottom} bind:open={open8}>

455-497: Remove the “Body scrolling” section (outdated and includes an internal note)

This documents a prop that isn’t wired and includes an internal comment. Recommend removing the entire section until behavior is decided and implemented.

-## Body scrolling
-
-### This section is useless. We don't need it. Confirm.
-
-By default, body scrolling is disabled when the drawer is visible, however, you can choose to enable it using the `bodyScrolling={true|false}` prop.
-
-**Limitation:** When bodyScrolling={true}, clicking the backdrop to close the drawer is disabled. Use the Escape key or provide a close button inside the drawer content instead.
-
-```svelte example
-<script>
-  import { Drawer, CardPlaceholder, Button, CloseButton } from "flowbite-svelte";
-  import { InfoCircleSolid, ArrowRightOutline } from "flowbite-svelte-icons";
-  let drawerOpen = $state(false);
-</script>
-
-<div class="text-center">
-  <Button onclick={() => (drawerOpen = true)}>Show drawer</Button>
-  <CardPlaceholder size="2xl" class="mt-6"/>
-</div>
-
-<Drawer bind:open={drawerOpen} bodyScrolling={true}>
-  <h5 class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
-    <InfoCircleSolid class="me-2.5 h-5 w-5" />Info
-  </h5>
-  <p class="mb-6 text-sm text-gray-500 dark:text-gray-400">
-    Supercharge your hiring by taking advantage of our <a href="/" class="text-primary-600 dark:text-primary-500 underline hover:no-underline">limited-time sale</a>
-    for Flowbite Docs + Job Board. Unlimited access to over 190K top-ranked candidates and the #1 design job board. Lorem ipsum dolor sit, amet consectetur adipisicing elit. At vel quidem sed numquam repellendus. Nihil earum veritatis quas non quisquam nisi hic ad, quo ullam iusto aliquid architecto saepe asperiores. Lorem, ipsum dolor sit amet consectetur adipisicing elit. Amet ratione vero repudiandae ex? Possimus doloremque culpa excepturi, corporis natus hic perferendis dolorem dignissimos fugit nostrum ipsam sapiente voluptate eos ea! Lorem ipsum dolor sit, amet
-    consectetur adipisicing elit. At vel quidem sed numquam repellendus. Nihil earum veritatis quas non quisquam nisi hic ad, quo ullam iusto aliquid architecto saepe asperiores. Lorem, ipsum dolor sit amet consectetur adipisicing elit. Amet ratione vero repudiandae ex? Possimus doloremque culpa excepturi, corporis natus hic perferendis dolorem dignissimos fugit nostrum ipsam sapiente voluptate eos ea! Lorem ipsum dolor sit, amet consectetur adipisicing elit. At vel quidem sed numquam repellendus. Nihil earum veritatis quas non quisquam nisi hic ad, quo ullam iusto
-    aliquid architecto saepe asperiores. Lorem, ipsum dolor sit amet consectetur adipisicing elit. Amet ratione vero repudiandae ex? Possimus doloremque culpa excepturi, corporis natus hic perferendis dolorem dignissimos fugit nostrum ipsam sapiente voluptate eos ea!
-  </p>
-  <p class="mb-6 text-sm text-gray-500 dark:text-gray-400">
-    Supercharge your hiring by taking advantage of our <a href="/" class="text-primary-600 dark:text-primary-500 underline hover:no-underline">limited-time sale</a>
-    for Flowbite Docs + Job Board. Unlimited access to over 190K top-ranked candidates and the #1 design job board. Lorem ipsum dolor sit, amet consectetur adipisicing elit. At vel quidem sed numquam repellendus. Nihil earum veritatis quas non quisquam nisi hic ad, quo ullam iusto aliquid architecto saepe asperiores. Lorem, ipsum dolor sit amet consectetur adipisicing elit. Amet ratione vero repudiandae ex? Possimus doloremque culpa excepturi, corporis natus hic perferendis dolorem dignissimos fugit nostrum ipsam sapiente voluptate eos ea! Lorem ipsum dolor sit, amet consectetur adipisicing elit. At vel quidem sed numquam repellendus. Nihil earum veritatis quas non quisquam nisi hic ad, quo ullam iusto aliquid architecto saepe asperiores. Lorem, ipsum dolor sit amet consectetur adipisicing elit. Amet ratione vero repudiandae ex? Possimus doloremque culpa excepturi, corporis natus hic perferendis dolorem dignissimos fugit nostrum ipsam sapiente voluptate eos ea! Lorem ipsum dolor sit, amet consectetur adipisicing elit. At vel quidem sed numquam repellendus. Nihil earum veritatis quas non quisquam nisi hic ad, quo ullam iusto
-    aliquid architecto saepe asperiores. Lorem, ipsum dolor sit amet consectetur adipisicing elit. Amet ratione vero repudiandae ex? Possimus doloremque culpa excepturi, corporis natus hic perferendis dolorem dignissimos fugit nostrum ipsam sapiente voluptate eos ea!
-  </p>
-  <div class="grid grid-cols-2 gap-4">
-    <Button color="light" href="/">Learn more</Button>
-    <Button href="/" class="px-4">Get access <ArrowRightOutline class="ms-2 h-5 w-5" /></Button>
-  </div>
-</Drawer>
-```

Optionally, once behavior is decided and implemented, re-introduce a corrected section.

🧹 Nitpick comments (4)
src/routes/docs/components/drawer.md (2)

388-390: Grammar: “its” (possessive), not “it's”

Minor doc nit.

-Use the drawer's `backdrop:xxx` class to manage it's look.
+Use the drawer’s `backdrop:xxx` class to manage its look.

392-392: Clarify and fix typos in the Non-modal description

Corrects “howerver” and improves phrasing.

-Drawer by default is `modal` (see `dialog`). You can set prop `modal={false}` to open `Drawer` in non-modal mode, that means with no backdrop. Note howerver, that you will need managed the `Drawer` position, z-index and `Esc` button manually.
+Drawer is modal by default (see Dialog). You can set `modal={false}` to use a non-modal Drawer (no backdrop). However, you will need to manage the Drawer’s position, stacking context (z-index), and Escape key handling manually.
src/lib/drawer/Drawer.svelte (2)

36-56: Update the component JSDoc to reflect the new API

Comment still lists legacy props (hidden, backdrop, etc.). Update to the open-based API and Dialog-facing props.

-@prop hidden = $bindable()
-@prop activateClickOutside = true
-@prop position
+@prop open = $bindable(false)
 @prop width
-@prop backdrop = true
-@prop backdropClass
 @prop placement = "left"
 @prop class: className
 @prop classes
-@prop transitionParams
-@prop transitionType = fly
-@prop bodyScrolling = false
+@prop transition = fly
+@prop transitionParams
 @prop ...restProps

21-26: Optional: simplify transition offsets to consistent constants

Using innerWidth/innerHeight yields very large offsets on some screens. Consider symmetric constants for a smoother animation, matching the docs’ 320px examples.

-  let x = $derived(placement === "left" ? -320 : placement === "right" ? innerWidth + 320 : undefined);
-  let y = $derived(placement === "top" ? -100 : placement === "bottom" ? innerHeight + 100 : undefined);
+  let x = $derived(placement === "left" ? -320 : placement === "right" ? 320 : undefined);
+  let y = $derived(placement === "top" ? -320 : placement === "bottom" ? 320 : undefined);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c102ad and 6bfd4ec.

📒 Files selected for processing (6)
  • src/lib/dialog/Dialog.svelte (1 hunks)
  • src/lib/drawer/Drawer.svelte (2 hunks)
  • src/lib/types.ts (8 hunks)
  • src/routes/docs/components/drawer.md (15 hunks)
  • src/routes/docs/forms/timepicker.md (4 hunks)
  • src/routes/examples/drawer/classesCheck.svelte (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/dialog/Dialog.svelte
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-10-18T09:38:03.879Z
Learnt from: Chizaruu
PR: themesberg/flowbite-svelte#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/forms/timepicker.md
📚 Learning: 2024-11-12T10:36:34.807Z
Learnt from: LahTeuto
PR: themesberg/flowbite-svelte#1484
File: src/lib/navbar/NavLi.svelte:34-34
Timestamp: 2024-11-12T10:36:34.807Z
Learning: When enhancing ARIA roles in Svelte components, avoid setting `role="presentation"` on elements that should retain the `link` role, as it can diminish ARIA role coverage and negatively affect accessibility.

Applied to files:

  • src/routes/examples/drawer/classesCheck.svelte
🧬 Code Graph Analysis (1)
src/lib/types.ts (6)
src/lib/dialog/theme.ts (1)
  • DialogVariants (4-4)
src/lib/drawer/theme.ts (1)
  • DrawerVariants (5-5)
src/lib/forms/helper/theme.ts (1)
  • HelperVariants (4-4)
src/lib/modal/theme.ts (1)
  • ModalVariants (6-6)
src/lib/toolbar/theme.ts (1)
  • ToolbarGroupVariants (6-6)
src/lib/skeleton/theme.ts (2)
  • TestimonialPlaceholderVariants (9-9)
  • WidgetPlaceholderVariants (12-12)
🪛 LanguageTool
src/routes/docs/components/drawer.md

[grammar] ~392-~392: Ensure spelling is correct
Context: ...mode, that means with no backdrop. Note howerver, that you will need managed the `Drawer...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🔇 Additional comments (2)
src/routes/docs/forms/timepicker.md (1)

494-499: Visibility flow LGTM

Trigger opens the Drawer and Cancel button closes it using the new bind:open API. Clean and consistent.

Also applies to: 549-551

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

27-28: Honoring transitionParams: LGTM

The component now prefers consumer-supplied transitionParams and falls back to sensible defaults.


warnThemeDeprecation("Drawer", { backdropClass }, { backdropClass: "backdrop" });
const styling = $derived(classes ?? { backdrop: backdropClass });
let { children, open = $bindable(false), width, placement = "left", class: className, classes, transitionParams, transition = fly, bodyScrolling = false, ...restProps }: DrawerProps = $props();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Remove unused bodyScrolling prop (or implement it), and align docs

bodyScrolling is destructured but never used; this is confusing and the docs’ “Body scrolling” section is slated for removal. Either implement the behavior or remove the prop from Drawer and types.

Proposed removal in this component:

-let { children, open = $bindable(false), width, placement = "left", class: className, classes, transitionParams, transition = fly, bodyScrolling = false, ...restProps }: DrawerProps = $props();
+let { children, open = $bindable(false), width, placement = "left", class: className, classes, transitionParams, transition = fly, ...restProps }: DrawerProps = $props();

And in src/lib/types.ts (outside this range), remove the unused prop:

 export interface DrawerProps extends DrawerVariants, DialogProps {
-  bodyScrolling?: boolean;
 }

To verify there are no remaining references:


🏁 Script executed:

#!/bin/bash
rg -n "bodyScrolling"

Length of output: 1662


Remove unused bodyScrolling prop (or implement it) and sync docs/examples

The bodyScrolling prop is currently destructured in Drawer.svelte and annotated with @prop, but its value is never used. You should either implement the intended “disable body scroll when open” behavior or remove the prop entirely—including all type definitions, docs, component metadata, and examples—to avoid confusion.

If you opt for removal, please update the following:

src/lib/drawer/Drawer.svelte
– Remove bodyScrolling = false from the prop destructuring on line 10.
– Remove the @prop bodyScrolling = false annotation on line 54.

src/lib/types.ts
– Delete bodyScrolling?: boolean; from the DrawerProps interface.

src/routes/component-data/Drawer.json
– Remove the ["bodyScrolling", "false"] entry.

Documentation (src/routes/docs/components/drawer.md)
– Delete the entire “Body scrolling” section (lines ~460–470) and any <Drawer bodyScrolling={…}> examples.
– Remove the limitation note about backdrop clicks being disabled.

Static docs (static/llm/components/drawer.md)
– Mirror the removals made in the live docs.

Examples (src/routes/api-check/components/drawer/examples/Scrolling.svelte)
– Remove bodyScrolling={true} from the <Drawer> usage.

Once all references are cleaned up (or the feature is fully implemented), rerun:

rg -n bodyScrolling

to confirm no stray mentions remain.

🤖 Prompt for AI Agents
In src/lib/drawer/Drawer.svelte around line 10 the prop bodyScrolling is
destructured but unused; remove bodyScrolling = false from the prop list and
delete the @prop bodyScrolling = false annotation (line ~54); then remove
bodyScrolling?: boolean; from src/lib/types.ts, delete the
["bodyScrolling","false"] entry from src/routes/component-data/Drawer.json,
remove the “Body scrolling” section and any <Drawer bodyScrolling={…}> examples
from src/routes/docs/components/drawer.md and mirror those removals in
static/llm/components/drawer.md, and remove bodyScrolling={true} from
src/routes/api-check/components/drawer/examples/Scrolling.svelte; after edits
run rg -n bodyScrolling to ensure no remaining references.

Comment on lines +44 to +47
<Drawer bind:open>
<h5 class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
<InfoCircleSolid class="me-2.5 h-5 w-5" />Info
</h5>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Fix Svelte binding and add accessible naming in the default Drawer example

bind:open must bind to the variable. Also connect aria-labelledby to the heading.

-<Drawer bind:open>
-  <h5 class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
+<Drawer bind:open={open} aria-labelledby="drawer-label">
+  <h5 id="drawer-label" class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
     <InfoCircleSolid class="me-2.5 h-5 w-5" />Info
   </h5>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Drawer bind:open>
<h5 class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
<InfoCircleSolid class="me-2.5 h-5 w-5" />Info
</h5>
<Drawer bind:open={open} aria-labelledby="drawer-label">
<h5 id="drawer-label" class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
<InfoCircleSolid class="me-2.5 h-5 w-5" />Info
</h5>
🤖 Prompt for AI Agents
In src/routes/docs/components/drawer.md around lines 44 to 47, the Drawer
example uses bind:open without referencing a variable and the heading isn't
referenced for accessibility; change the binding to bind:open={open} (ensure an
`open` variable exists/initialized in the component) and add an id on the
heading (e.g., id="drawer-title") then add aria-labelledby="drawer-title" to the
Drawer component so the dialog is programmatically associated with its heading.

Comment on lines +245 to 262
```svelte example
<script>
import { Drawer, Button, CloseButton, Label, Textarea } from "flowbite-svelte";
import { Drawer, CardPlaceholder, Button, CloseButton, Label, Textarea } from "flowbite-svelte";
import { InfoCircleSolid, ArrowRightOutline } from "flowbite-svelte-icons";

let hidden5 = $state(true);
let open5 = $state(false);
</script>

<div class="text-center">
<Button onclick={() => (hidden5 = false)}>Show drawer</Button>
<Button onclick={() => (open5 = true)}>Show drawer</Button>
<CardPlaceholder size="2xl" class="mt-6"/>
</div>

<Drawer placement="left" bind:hidden={hidden5}>
<div class="flex items-center justify-between">
<h5 id="drawer-label" class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
<InfoCircleSolid class="me-2.5 h-5 w-5" />Info
</h5>
<CloseButton class="mb-4 dark:text-white" />
</div>
<Drawer placement="left" bind:open={open5}>
<h5 class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
<InfoCircleSolid class="me-2.5 h-5 w-5" />Info
</h5>
<p class="mb-6 text-sm text-gray-500 dark:text-gray-400">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Ensure Drawer examples are labelled by their headings

Several examples are missing aria-labelledby and matching heading ids. Apply the same pattern used in the default example across these snippets.

Example pattern:

-<Drawer placement="left" bind:open={open5}>
-  <h5 class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
+<Drawer placement="left" bind:open={open5} aria-labelledby="drawer-label-left">
+  <h5 id="drawer-label-left" class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">

You can list occurrences missing aria-labelledby with:

Also applies to: 298-301, 336-345, 371-374, 440-443, 409-411


🏁 Script executed:

#!/bin/bash
# Drawers without aria-labelledby in this file
rg -n '^\s*<Drawer(?![^>]*aria-labelledby)[^>]*>' src/routes/docs/components/drawer.md

Length of output: 344


🏁 Script executed:

#!/bin/bash
# List Drawer tags missing aria-labelledby in the docs file
rg -n '<Drawer' src/routes/docs/components/drawer.md | grep -v 'aria-labelledby'

Length of output: 794


Add aria-labelledby to all Drawer examples

Several <Drawer> instances in src/routes/docs/components/drawer.md are missing aria-labelledby attributes and corresponding heading ids. Please apply the same pattern used in the default example to each of the following locations:

• Line 44: <Drawer bind:open>
• Line 75: <Drawer bind:open={open2} class="…">
• Line 151: <Drawer bind:open={open3}>
• Line 195: <Drawer bind:open={open4}>
• Line 258: <Drawer placement="left" bind:open={open5}>
• Line 298: <Drawer placement="right" transitionParams={transitionParamsRight} bind:open={open6}>
• Line 336: <Drawer placement="top" class="w-full" transitionParams={transitionParamsTop} bind:open={open7}>
• Line 371: <Drawer form placement="bottom" class="w-full" transitionParams={transitionParamsBottom} bind:open={open8}>
• Line 408: <Drawer modal={false} bind:open={openNonModal} class="fixed z-50">
• Line 440: <Drawer outsideclose={false} bind:open={openDisablingOnlyOutsideClick}>
• Line 476: <Drawer bind:open={drawerOpen} bodyScrolling={true}>

Example pattern to follow:

-<Drawer placement="left" bind:open={open5}>
-  <h5 class="mb-4 inline-flex items-center …">
+<Drawer placement="left" bind:open={open5} aria-labelledby="drawer-label-left">
+  <h5 id="drawer-label-left" class="mb-4 inline-flex items-center …">

Ensure each Drawer’s heading has a unique id matching its aria-labelledby.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/routes/docs/components/drawer.md around the listed lines (44, 75, 151,
195, 258, 298, 336, 371, 408, 440, 476), several <Drawer> examples lack
aria-labelledby and matching heading ids; update each <Drawer> tag to include
aria-labelledby="unique-id-X" and set the corresponding heading element inside
that Drawer to id="unique-id-X" (use a distinct id per example, following the
pattern used in the default example) so every Drawer has an aria-labelledby
value that points to its heading id.

Comment on lines +501 to +505
<Drawer bind:open class="w-96 bg-gray-50 p-6 dark:bg-gray-800">
<Heading tag="h5" id="drawer-label" class="mb-8 inline-flex items-center text-base font-semibold text-gray-800 uppercase dark:text-white">
<ClockSolid class="h-6 w-6" />
Time schedule
</Heading>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add aria-labelledby on Drawer to provide an accessible name

The heading already has id="drawer-label"; wire the Drawer to it.

-<Drawer bind:open class="w-96 bg-gray-50 p-6 dark:bg-gray-800">
+<Drawer bind:open class="w-96 bg-gray-50 p-6 dark:bg-gray-800" aria-labelledby="drawer-label">
   <Heading tag="h5" id="drawer-label" class="mb-8 inline-flex items-center text-base font-semibold text-gray-800 uppercase dark:text-white">
     <ClockSolid class="h-6 w-6" />
     Time schedule
   </Heading>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Drawer bind:open class="w-96 bg-gray-50 p-6 dark:bg-gray-800">
<Heading tag="h5" id="drawer-label" class="mb-8 inline-flex items-center text-base font-semibold text-gray-800 uppercase dark:text-white">
<ClockSolid class="h-6 w-6" />
Time schedule
</Heading>
<Drawer bind:open class="w-96 bg-gray-50 p-6 dark:bg-gray-800" aria-labelledby="drawer-label">
<Heading
tag="h5"
id="drawer-label"
class="mb-8 inline-flex items-center text-base font-semibold text-gray-800 uppercase dark:text-white"
>
<ClockSolid class="h-6 w-6" />
Time schedule
</Heading>
</Drawer>
🤖 Prompt for AI Agents
In src/routes/docs/forms/timepicker.md around lines 501 to 505, the Drawer
element lacks an accessible name even though the Heading has id="drawer-label";
add aria-labelledby="drawer-label" to the Drawer component (e.g., <Drawer
bind:open aria-labelledby="drawer-label" ...>) so the Drawer is properly
associated with the heading for screen readers.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
src/lib/drawer/Drawer.svelte (1)

37-55: Update the component documentation to reflect current props

The component documentation still references outdated props like hidden, activateClickOutside, backdrop, and backdropClass. Update it to match the current API:

  • Remove references to deprecated props
  • Add open prop documentation
  • Update the type reference to the correct line number

Apply this diff:

-@prop hidden = $bindable()
-@prop activateClickOutside = true
-@prop position
+@prop open = $bindable(false)
 @prop width
-@prop backdrop = true
-@prop backdropClass
 @prop placement = "left"
 @prop class: className
 @prop classes
 @prop transitionParams
-@prop transitionType = fly
+@prop transition = fly
♻️ Duplicate comments (4)
src/lib/types.ts (1)

557-568: Title property is destructured in Dialog.svelte but not part of DialogProps

The title property is destructured from props in Dialog.svelte (line 38) but it's not defined in the DialogProps interface. This causes the title to be swallowed and not forwarded to the dialog element.

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

10-10: Remove unused bodyScrolling prop

The bodyScrolling prop is destructured but never used in the component. This creates confusion as it suggests functionality that doesn't exist.

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

44-47: Fix incomplete binding in default example

The bind:open directive is missing its binding variable. Based on the script declaration on line 36, this should bind to the open variable.


371-371: Remove non-existent form prop from Drawer

The form prop is not supported by Drawer. This attribute has no effect and should be removed.

🧹 Nitpick comments (2)
src/lib/types.ts (1)

734-734: Consider extracting the empty interface pattern to reduce boilerplate

Multiple interfaces (HelperProps, ToolbarGroupProps, TestimonialPlaceholderProps, WidgetPlaceholderProps) follow the same empty extension pattern. Consider extracting a type alias pattern to reduce redundancy.

Add a utility type alias:

type EmptyExtension<V, E> = V & E;

Then simplify:

-export interface HelperProps extends HelperVariants, Omit<HTMLAttributes<HTMLParagraphElement>, "color"> { }
+export type HelperProps = EmptyExtension<HelperVariants, Omit<HTMLAttributes<HTMLParagraphElement>, "color">>;

Also applies to: 1117-1117, 1426-1426, 1436-1436

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

392-392: Fix typo: "howerver" should be "however"

There's a spelling error in the documentation.

Apply this diff:

-Drawer by default is `modal` (see `dialog`). You can set prop `modal={false}` to open `Drawer` in non-modal mode, that means with no backdrop. Note howerver, that you will need managed the `Drawer` position, z-index and `Esc` button manually.
+Drawer by default is `modal` (see `dialog`). You can set prop `modal={false}` to open `Drawer` in non-modal mode, that means with no backdrop. Note however, that you will need to manage the `Drawer` position, z-index and `Esc` button manually.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6bfd4ec and 193501f.

📒 Files selected for processing (3)
  • src/lib/drawer/Drawer.svelte (2 hunks)
  • src/lib/types.ts (8 hunks)
  • src/routes/docs/components/drawer.md (14 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/lib/types.ts (6)
src/lib/dialog/theme.ts (1)
  • DialogVariants (4-4)
src/lib/drawer/theme.ts (1)
  • DrawerVariants (5-5)
src/lib/forms/helper/theme.ts (1)
  • HelperVariants (4-4)
src/lib/modal/theme.ts (1)
  • ModalVariants (6-6)
src/lib/toolbar/theme.ts (1)
  • ToolbarGroupVariants (6-6)
src/lib/skeleton/theme.ts (2)
  • TestimonialPlaceholderVariants (9-9)
  • WidgetPlaceholderVariants (12-12)
🪛 LanguageTool
src/routes/docs/components/drawer.md

[grammar] ~392-~392: Ensure spelling is correct
Context: ...mode, that means with no backdrop. Note howerver, that you will need managed the `Drawer...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Playwright and Lint
🔇 Additional comments (7)
src/lib/types.ts (2)

571-571: LGTM!

The DrawerProps interface correctly extends both DrawerVariants and DialogProps, properly implementing the centralized dialog behavior.


1045-1053: LGTM!

The ModalProps interface correctly extends ModalVariants and DialogProps (excluding "classes"), and appropriately adds modal-specific styling properties like header, footer, and class properties.

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

32-34: LGTM! Clean dialog delegation

The implementation correctly delegates all drawer behavior to the Dialog component, properly forwarding transition parameters and maintaining theme styling.

src/routes/docs/components/drawer.md (4)

155-155: Valid use of method="dialog" for dialog-based forms

The method="dialog" attribute is appropriate here as Drawer now uses a Dialog component internally, which supports native dialog form submission behavior.


388-388: LGTM! Clear documentation of backdrop styling

Good update to document the CSS-based backdrop management approach using backdrop:xxx classes.


390-421: LGTM! Well-documented non-modal drawer behavior

The non-modal section clearly explains the behavior and requirements when using modal={false}, including proper positioning with fixed classes and z-index management.


423-453: LGTM! Clear documentation of outsideclose prop

The section effectively documents the outsideclose prop behavior with a working example.

@shinokada
Copy link
Copy Markdown
Collaborator

Can you run pnpm check please?

@jjagielka
Copy link
Copy Markdown
Contributor Author

I did and it pass. Does it fail for you?

@shinokada
Copy link
Copy Markdown
Collaborator

pnpm check && pnpm test:e2e

flowbite-svelte@1.11.8 check /Users/shinichiokada/Flowbite/flowbite-svelte
svelte-kit sync && svelte-check --tsconfig ./tsconfig.json

Loading svelte-check in workspace: /Users/shinichiokada/Flowbite/flowbite-svelte
Getting Svelte diagnostics...

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Bottom.svelte:18:90
Error: Object literal may only specify known properties, and 'open' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Bottom.svelte:18:85
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Contact.svelte:11:14
Error: Object literal may only specify known properties, and 'open' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Contact.svelte:11:9
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Default.svelte:12:14
Error: Object literal may only specify known properties, and 'open' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Default.svelte:12:9
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Disabled.svelte:13:9
Error: Object literal may only specify known properties, and '"modal"' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Disabled.svelte:13:23
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/DisablingOutside.svelte:12:10
Error: Object literal may only specify known properties, and 'outsideclose' does not exist in type 'DrawerProps'. (js)

<Drawer {outsideclose} bind:open={open10} id="sidebar10">

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/DisablingOutside.svelte:12:24
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

<Drawer {outsideclose} bind:open={open10} id="sidebar10">

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Enabled.svelte:12:14
Error: Object literal may only specify known properties, and 'open' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Enabled.svelte:12:9
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Form.svelte:11:14
Error: Object literal may only specify known properties, and 'open' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Form.svelte:11:9
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Left.svelte:12:31
Error: Object literal may only specify known properties, and 'open' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Left.svelte:12:26
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Navigation.svelte:11:14
Error: Object literal may only specify known properties, and 'open' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Navigation.svelte:11:9
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/OnlyOutside.svelte:12:9
Error: Object literal may only specify known properties, and '"outsideclose"' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/OnlyOutside.svelte:12:30
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Position.svelte:12:49
Error: Object literal may only specify known properties, and 'open' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Position.svelte:12:44
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Right.svelte:18:73
Error: Object literal may only specify known properties, and 'open' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Right.svelte:18:68
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Scrolling.svelte:11:14
Error: Object literal may only specify known properties, and 'open' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Scrolling.svelte:11:9
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Top.svelte:18:84
Error: Object literal may only specify known properties, and 'open' does not exist in type 'DrawerProps'. (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/api-check/components/drawer/examples/Top.svelte:18:79
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (js)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/admin-dashboard/(sidebar)/crud/products/+page.svelte:98:32
Error: Object literal may only specify known properties, and 'open' does not exist in type 'DrawerProps'. (ts)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/admin-dashboard/(sidebar)/crud/products/+page.svelte:98:27
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { open = $bindable() } = $props()' (ts)

/Users/shinichiokada/Flowbite/flowbite-svelte/src/routes/testdir/drawer/+page.svelte:11:9
Error: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component.
To mark a property as bindable: 'let { hidden = $bindable() } = $props()' (js)

====================================
svelte-check found 31 errors and 0 warnings in 16 files
 ELIFECYCLE  Command failed with exit code 1.
➜ flowbite-svelte git:(jjagielka-drawer)

@jjagielka
Copy link
Copy Markdown
Contributor Author

You must have something wrong with you conf. All those errors claims property open does not exist on Drawer, but that is the change I have just done.
Try to pnpm build and re-run.

Or add an alias to your svelte.config.js:

  kit: {
    adapter: adapter(),
    alias: { "flowbite-svelte": "src/lib" },
  }

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 11

🔭 Outside diff range comments (3)
src/routes/api-check/components/drawer/examples/Form.svelte (3)

21-22: Fix label-control association (for/id mismatch breaks accessibility)

The Label’s for value doesn’t match the Textarea id, so assistive tech won’t announce the description correctly.

Apply this diff:

-      <Label for="description" class="mb-2">Description</Label>
-      <Textarea id="message" placeholder="Write event description..." rows={4} name="message" class="w-full" />
+      <Label for="description" class="mb-2">Description</Label>
+      <Textarea id="description" placeholder="Write event description..." rows={4} name="description" class="w-full" />

24-26: Add a label for the date input

Inputs should have an associated label for accessibility and better click target.

Apply this diff:

     <div class="mb-6">
+      <Label for="date" class="mb-2 block">Date</Label>
       <Input id="date" name="date" required type="date" />
     </div>

28-32: Prevent unintended form submit and improve email input semantics

  • The “Add” button likely shouldn’t submit the entire form; set it to type="button".
  • Use type="email" for the guest email field and provide an accessible label (sr-only is fine if you want a clean UI).

Apply this diff:

       <div class="relative">
-        <Input id="search" placeholder="Add guest email" class="p-3" />
-        <Button class="bg-primary-700 hover:bg-primary-800 focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800 absolute end-2 bottom-2 inline-flex items-center rounded-lg px-3 py-1 text-sm font-medium text-white focus:ring-4 focus:outline-hidden" type="submit">
+        <Label for="search" class="sr-only">Guest email</Label>
+        <Input id="search" type="email" name="guest" autocomplete="email" placeholder="Add guest email" class="p-3" />
+        <Button class="bg-primary-700 hover:bg-primary-800 focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800 absolute end-2 bottom-2 inline-flex items-center rounded-lg px-3 py-1 text-sm font-medium text-white focus:ring-4 focus:outline-hidden" type="button">
           <UserAddOutline class="me-1.5 h-3 w-3 text-white" />Add
         </Button>
       </div>
♻️ Duplicate comments (8)
src/routes/api-check/components/drawer/examples/Left.svelte (1)

12-15: Add aria-labelledby to provide an accessible name (and ensure a unique id)

Builds on the previous review: the Drawer still lacks aria-labelledby. Also, consider making the heading id unique to avoid collisions across multiple examples on the same page.

Apply this diff:

-<Drawer placement="left" bind:open={open5}>
-  <h5 id="drawer-label" class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
+<Drawer placement="left" bind:open={open5} aria-labelledby="drawer-left-label">
+  <h5 id="drawer-left-label" class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">

Optional: add aria-describedby referencing the paragraph below for a richer accessible description (assign an id to the paragraph and set aria-describedby on Drawer accordingly).

src/routes/api-check/components/drawer/examples/Form.svelte (1)

11-11: Add aria-labelledby to ensure the drawer has an accessible name

Link the dialog to the existing header id.

Apply this diff:

-<Drawer bind:open={open4}>
+<Drawer aria-labelledby="drawer-label" bind:open={open4}>
src/routes/api-check/components/drawer/examples/Top.svelte (1)

18-21: Add aria-labelledby to provide an accessible name for the dialog

The dialog currently lacks an accessible name. You already have id="drawer-label" on the header; reference it from the Drawer.

Apply this diff:

-<Drawer placement="top" class="w-full" transitionParams={transitionParamsTop} bind:open={open7}>
+<Drawer placement="top" class="w-full" transitionParams={transitionParamsTop} bind:open={open7} aria-labelledby="drawer-label">

Optional (nice to have): also add aria-describedby pointing to the descriptive paragraph to improve screen reader context.

For example:

<!-- Drawer -->
<Drawer ... aria-labelledby="drawer-label" aria-describedby="drawer-desc">

<!-- Description -->
<p id="drawer-desc" class="mb-6 max-w-lg text-sm text-gray-500 dark:text-gray-400">
  ...
</p>
src/routes/api-check/components/drawer/examples/Default.svelte (1)

12-12: Fix dialog labelling and remove incorrect aria-controls on the dialog

The dialog’s aria-labelledby should reference the heading id (drawer-label). aria-controls is not appropriate on the dialog element; it belongs on the trigger.

-<Drawer bind:open={open1} id="sidebar1" aria-controls="sidebar1" aria-labelledby="sidebar1">
+<Drawer bind:open={open1} id="sidebar1" aria-labelledby="drawer-label">
src/routes/api-check/components/drawer/examples/Navigation.svelte (2)

9-9: Use Svelte’s on:click; onclick won’t attach an event listener

Svelte won’t register the handler via a plain onclick attribute on a component. Use on:click to ensure the Drawer opens.

-  <Button onclick={() => (open2 = true)}>Show navigation</Button>
+  <Button on:click={() => (open2 = true)}>Show navigation</Button>

11-12: Add accessible labeling via aria-labelledby and a matching header id

Ensure assistive tech announces the dialog title.

-<Drawer bind:open={open2} class="w-64 bg-gray-50 p-0 dark:bg-gray-800">
-  <h5 class="px-4 text-base font-semibold text-gray-500 uppercase dark:text-gray-400">Menu</h5>
+<Drawer bind:open={open2} aria-labelledby="drawer-nav-label" class="w-64 bg-gray-50 p-0 dark:bg-gray-800">
+  <h5 id="drawer-nav-label" class="px-4 text-base font-semibold text-gray-500 uppercase dark:text-gray-400">Menu</h5>
src/routes/api-check/components/drawer/examples/Disabled.svelte (2)

10-10: Use Svelte’s on:click instead of onclick

onclick won’t attach a Svelte event listener.

Apply this diff:

-  <Button onclick={() => (openBackdropFalse = true)}>Show drawer</Button>
+  <Button on:click={() => (openBackdropFalse = true)}>Show drawer</Button>

13-13: Label the dialog via aria-labelledby

Tie the Drawer to the existing heading for better a11y.

Apply this diff:

-<Drawer modal={false} bind:open={openBackdropFalse} class="fixed inset-y-0 z-50">
+<Drawer modal={false} bind:open={openBackdropFalse} aria-labelledby="drawer-label" class="fixed inset-y-0 z-50">
🧹 Nitpick comments (4)
src/routes/api-check/components/drawer/examples/Bottom.svelte (1)

18-21: Connect the heading to the dialog with aria-labelledby for better a11y.

Since Drawer now uses dialog semantics, exposing aria-labelledby improves screen reader labeling.

-<Drawer placement="bottom" class="w-full" transitionParams={transitionParamsBottom} bind:open={open8}>
+<Drawer placement="bottom" class="w-full" transitionParams={transitionParamsBottom} bind:open={open8} aria-labelledby="drawer-label">
   <h5 id="drawer-label" class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
     <InfoCircleSolid class="me-2.5 h-5 w-5" />Info
   </h5>
src/routes/api-check/components/drawer/examples/Form.svelte (1)

11-11: Verify bind:open against the local Drawer build (svelte-check errors suggest alias issue)

The PR intentionally switched Drawer to bind:open. If svelte-check complains that open is non-bindable/unknown, your examples are likely resolving to the published package instead of the local src/lib. Add an alias and rebuild:

  • svelte.config.js:
    kit: { adapter: adapter(), alias: { "flowbite-svelte": "src/lib" } }

  • Then:
    pnpm build
    pnpm check

I can help generate a script to assert the alias is set if needed.

src/routes/api-check/components/drawer/examples/Disabled.svelte (2)

13-16: Add an explicit close affordance inside the drawer

Even with Esc support, a visible close affordance improves discoverability and accessibility.

Apply this diff to add a CloseButton next to the title:

-<Drawer modal={false} bind:open={openBackdropFalse} aria-labelledby="drawer-label" class="fixed inset-y-0 z-50">
-  <h5 id="drawer-label" class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
-    <InfoCircleSolid class="me-2.5 h-5 w-5" />Info
-  </h5>
+<Drawer modal={false} bind:open={openBackdropFalse} aria-labelledby="drawer-label" class="fixed inset-y-0 z-50">
+  <div class="mb-4 flex items-center justify-between">
+    <h5 id="drawer-label" class="inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400">
+      <InfoCircleSolid class="me-2.5 h-5 w-5" />Info
+    </h5>
+    <CloseButton aria-label="Close drawer" on:click={() => (openBackdropFalse = false)} />
+  </div>

2-2: Remove testing-library import from this runtime example (if unneeded)

Prevents pulling a test-only dependency into the example bundle.

Apply this diff:

-import { findAllByTestId } from "@testing-library/svelte";
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 193501f and 30cf7d1.

📒 Files selected for processing (14)
  • src/routes/api-check/components/drawer/examples/Bottom.svelte (2 hunks)
  • src/routes/api-check/components/drawer/examples/Contact.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Default.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Disabled.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/DisablingOutside.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Enabled.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Form.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Left.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Navigation.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/OnlyOutside.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Position.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Right.svelte (2 hunks)
  • src/routes/api-check/components/drawer/examples/Scrolling.svelte (1 hunks)
  • src/routes/api-check/components/drawer/examples/Top.svelte (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/routes/api-check/components/drawer/examples/Right.svelte
  • src/routes/api-check/components/drawer/examples/OnlyOutside.svelte
  • src/routes/api-check/components/drawer/examples/DisablingOutside.svelte
  • src/routes/api-check/components/drawer/examples/Contact.svelte
  • src/routes/api-check/components/drawer/examples/Position.svelte
  • src/routes/api-check/components/drawer/examples/Enabled.svelte
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-11-22T08:37:27.996Z
Learnt from: mrh1997
PR: themesberg/flowbite-svelte#1442
File: src/lib/utils/Popper.svelte:144-145
Timestamp: 2024-11-22T08:37:27.996Z
Learning: In `src/lib/utils/Popper.svelte`, inconsistencies in event handling (e.g., using both `mouseenter`/`mouseleave` and `pointerenter`/`pointerleave`) may be intentional to minimize modifications and reduce the risk of new problems.

Applied to files:

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

Applied to files:

  • src/routes/api-check/components/drawer/examples/Disabled.svelte
  • src/routes/api-check/components/drawer/examples/Default.svelte
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Playwright and Lint
🔇 Additional comments (8)
src/routes/api-check/components/drawer/examples/Left.svelte (1)

5-5: Migration to bind:open looks good

Initialization with $state(false) and using bind:open aligns with the new Dialog-based API.

src/routes/api-check/components/drawer/examples/Form.svelte (1)

5-5: LGTM: correct migration to bindable open state

Using a local state var for bind:open aligns with the new Dialog-based API.

src/routes/api-check/components/drawer/examples/Top.svelte (1)

6-6: State rename and default closed state align with new Dialog API

Using open7 with default false matches bind:open semantics. Looks good.

src/routes/api-check/components/drawer/examples/Default.svelte (1)

5-5: LGTM on migrating to bind:open state

The state rename to align with the new Dialog-based Drawer API looks correct.

src/routes/api-check/components/drawer/examples/Scrolling.svelte (1)

11-14: Good migration to bind:open and simplified header content

This aligns with the Dialog-based API and removes the deprecated bodyScrolling usage from this example. Looks good.

src/routes/api-check/components/drawer/examples/Navigation.svelte (1)

4-4: State migration looks correct

Defaulting to closed with let open2 = $state(false) matches the new open-based API.

src/routes/api-check/components/drawer/examples/Disabled.svelte (2)

13-13: Verify Drawer doesn’t already apply fixed/inset styles

Dialog/Drawer typically manages positioning and stacking. Adding class="fixed inset-y-0 z-50" at the usage site can double-create stacking contexts or conflict with internal styles.

Apply this diff if positioning is already handled internally:

-<Drawer modal={false} bind:open={openBackdropFalse} aria-labelledby="drawer-label" class="fixed inset-y-0 z-50">
+<Drawer modal={false} bind:open={openBackdropFalse} aria-labelledby="drawer-label">

6-6: LGTM: bindable state via $state aligns with Svelte 5 and bind:open

This pairs correctly with bind:open usage.

import { sineIn } from "svelte/easing";

let hidden8 = $state(true);
let open8 = $state(false);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Confirm Svelte 5 runes and local alias setup to avoid svelte-check “open is non-bindable” errors.

This example uses $state and bind:open (new Drawer API). If svelte-check still reports DrawerProps lacks open/non-bindable, your local tooling might resolve to the published package instead of src/lib or target an older Drawer. Verify alias and component props.


🏁 Script executed:

#!/bin/bash
# Verify Svelte version, alias config, and Drawer prop exposure.

set -e

echo "Svelte version (dev/prod deps):"
jq -r '.dependencies.svelte // empty' package.json 2>/dev/null || true
jq -r '.devDependencies.svelte // empty' package.json 2>/dev/null || true

echo -e "\nLook for alias mapping 'flowbite-svelte' -> 'src/lib' in svelte.config.*:"
fd -a 'svelte.config.*' | while read -r f; do
  echo -e "\n--- $f ---"
  sed -n '1,200p' "$f"
done
echo -e "\nAlias occurrences:"
rg -n 'alias\s*:\s*{[^}]*"flowbite-svelte"\s*:\s*"src/lib"' -A 3 || true

echo -e "\nFind Drawer.svelte implementations and check for 'open' prop:"
fd -a 'Drawer.svelte' | while read -r d; do
  echo -e "\n--- $d ---"
  rg -n 'export let (open|hidden)|bindable|bind:' "$d" -n || sed -n '1,80p' "$d"
done

echo -e "\nConfirm example uses bind:open in routes:"
rg -n 'bind:open=' src/routes || true

echo -e "\nTip: if alias is missing, set in svelte.config.js kit.alias:"
cat <<'ALIAS_EXAMPLE'

kit: {
  adapter: adapter(),
  alias: { "flowbite-svelte": "src/lib" },
}

ALIAS_EXAMPLE

Length of output: 11217


Enable Svelte 5 runes & map flowbite-svelte to src/lib in your config

Your project is on Svelte ^5.38.0, but:

  • runes: true is commented out under compilerOptions
  • there’s no kit.alias entry pointing flowbite-sveltesrc/lib

Without these, VS Code/svelte-check will fall back to the published package and flag open as non-bindable. Please update svelte.config.js:

 /** @type {import('@sveltejs/kit').Config} */
 const config = {
   extensions: [".svelte", ...mdsvexConfig.extensions],
   compilerOptions: {
-    // runes: true
+    runes: true
   },
   preprocess: [
     mdsvex(mdsvexConfig),
     vitePreprocess({ typeScript: true })
   ],
   vitePlugin: {
     inspector: { holdMode: true }
   },
   kit: {
     adapter: adapter(),
+    alias: {
+      "flowbite-svelte": "src/lib"
+    }
   }
 };

Once that’s in place, svelte-check will correctly resolve your local Drawer and recognize bind:open.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let open8 = $state(false);
/** @type {import('@sveltejs/kit').Config} */
const config = {
extensions: [".svelte", ...mdsvexConfig.extensions],
compilerOptions: {
runes: true
},
preprocess: [
mdsvex(mdsvexConfig),
vitePreprocess({ typeScript: true })
],
vitePlugin: {
inspector: { holdMode: true }
},
kit: {
adapter: adapter(),
alias: {
"flowbite-svelte": "src/lib"
}
}
};
export default config;
🤖 Prompt for AI Agents
In src/routes/api-check/components/drawer/examples/Bottom.svelte around line 6,
Svelte-check flags bind:open because the project Svelte config doesn't enable
runes and doesn't map flowbite-svelte to the local src/lib; open is created with
let open8 = $state(false) but the compiler isn't resolving your local Drawer.
Fix svelte.config.js: uncomment/enable compilerOptions.runes = true and add a
kit.alias (or top-level alias) mapping "flowbite-svelte" -> "src/lib" (or the
correct relative path to your local library), then restart the language server
so Svelte 5 runes and the alias allow bind:open to be recognized.


<div class="text-center">
<Button onclick={() => (hidden8 = false)}>Show drawer</Button>
<Button onclick={() => (open8 = true)}>Show drawer</Button>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use Svelte’s on:click instead of onclick (current handler won’t fire).

onclick on a Svelte component is forwarded as a prop/attribute and won’t attach a DOM listener. Use on:click to actually open the drawer.

-  <Button onclick={() => (open8 = true)}>Show drawer</Button>
+  <Button on:click={() => (open8 = true)}>Show drawer</Button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Button onclick={() => (open8 = true)}>Show drawer</Button>
<Button on:click={() => (open8 = true)}>Show drawer</Button>
🤖 Prompt for AI Agents
In src/routes/api-check/components/drawer/examples/Bottom.svelte around line 15,
the Button uses an onclick prop which is forwarded as an attribute and does not
attach a DOM listener, so the handler won't fire; change it to use Svelte's
event directive (on:click) and bind the same inline handler to set open8 = true
so the drawer actually opens when the button is clicked.

import { InfoCircleSolid, ArrowRightOutline } from "flowbite-svelte-icons";
import { sineIn } from "svelte/easing";
let hidden1 = $state(true);
let open1 = $state(false);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Ensure svelte-check resolves the new Drawer typings

The reported “open is non-bindable/unknown prop” errors typically occur when examples import Drawer from the published package instead of the local refactored source. Verify that the dev config aliases "flowbite-svelte" to "src/lib" so svelte-check uses the local Drawer with the new open prop.

Run this script to confirm the alias is present:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find svelte config files
files=$(fd -a 'svelte\.config\.(js|ts|cjs|mjs)$' || true)
if [ -z "$files" ]; then
  echo "No svelte.config.* found at repo root"
  exit 1
fi

echo "Checking for kit.alias {'flowbite-svelte': 'src/lib'} in:"
echo "$files"

# Look for the alias mapping to local source
if rg -n --pretty 'kit\s*:\s*{[^}]*alias\s*:\s*{[^}]*["'\''`]flowbite-svelte["'\''`]\s*:\s*["'\''`]src/lib["'\''`]' $files; then
  echo "Alias found. svelte-check should resolve local Drawer with open prop."
else
  echo "Alias not found. Add under kit.alias:"
  echo "  alias: { 'flowbite-svelte': 'src/lib' }"
  exit 1
fi

Length of output: 899


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== svelte.config.js (first 200 lines) ==="
sed -n '1,200p' svelte.config.js

echo
echo "=== Searching for 'flowbite-svelte' in svelte.config.js ==="
rg -n "flowbite-svelte" svelte.config.js || echo "No occurrences of 'flowbite-svelte' found"

Length of output: 1255


Add missing flowbite-svelte alias so svelte-check uses local Drawer

The dev config currently lacks an alias mapping for flowbite-svelte, so your examples are still resolving the published package instead of your local src/lib source. Please update svelte.config.js to include:

• File: svelte.config.js
• Location: inside the existing kit block

Suggested diff:

 kit: {
   adapter: adapter(),
+  // Ensure svelte-check resolves local source for Drawer and other components
+  alias: {
+    'flowbite-svelte': 'src/lib'
+  }
 }

This will route all imports of flowbite-svelte to your local refactored code and eliminate the “open is non-bindable/unknown prop” errors in your examples.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In svelte.config.js (inside the existing kit block), add a Vite resolve alias
mapping 'flowbite-svelte' to the local source (./src/lib) so imports resolve to
your local refactored code; update kit.vite.resolve.alias (or create it if
missing) to point 'flowbite-svelte' to the project src/lib path so svelte-check
and the examples use the local Drawer component instead of the published
package.


<div class="text-center">
<Button onclick={() => (hidden1 = false)}>Show drawer</Button>
<Button onclick={() => (open1 = true)}>Show drawer</Button>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use Svelte’s on:click (not onclick) and move control ARIA to the trigger

onclick won’t correctly attach a listener on the Svelte component. Use on:click. Also, move aria-controls to the trigger and add aria-haspopup="dialog" and a reflective aria-expanded for better accessibility.

-  <Button onclick={() => (open1 = true)}>Show drawer</Button>
+  <Button
+    on:click={() => (open1 = true)}
+    aria-controls="sidebar1"
+    aria-haspopup="dialog"
+    aria-expanded={open1}
+  >
+    Show drawer
+  </Button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Button onclick={() => (open1 = true)}>Show drawer</Button>
<Button
on:click={() => (open1 = true)}
aria-controls="sidebar1"
aria-haspopup="dialog"
aria-expanded={open1}
>
Show drawer
</Button>
🤖 Prompt for AI Agents
In src/routes/api-check/components/drawer/examples/Default.svelte around line 9,
the button uses the DOM prop "onclick" and the ARIA control is on the wrong
element; replace "onclick" with Svelte's "on:click" on the trigger, move the
aria-controls attribute to that trigger with its value set to the drawer's id,
add aria-haspopup="dialog" and add aria-expanded={open1} on the trigger so it
reflects the open state, and ensure the drawer element has the same id and
role="dialog" (or appropriate dialog semantics) so the attributes correctly
reference the controlled element.

</h5>
<CloseButton class="mb-4 dark:text-white" />
</div>
<Drawer modal={false} bind:open={openBackdropFalse} class="fixed inset-y-0 z-50">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Resolve svelte-check errors for bind:open (type/bindability)

Given the PR’s API shift, ensure Drawer’s open is bindable in the installed source used by these examples. If examples import from "flowbite-svelte" (package), but your local type/impl still has hidden and/or non-bindable open, svelte-check will fail.

Options:

  • Ensure Drawer exports a bindable open (Svelte 5) and that types reflect it.
  • Or point "flowbite-svelte" to "src/lib" during local dev (as suggested) so examples type-check against the PR’s updated code.

Run this script to verify that open is present and bindable in the local Drawer implementation and that examples resolve to it:

If you prefer the alias approach, add this to svelte.config.js:

// svelte.config.js (excerpt)
kit: {
  adapter: adapter(),
  alias: {
    'flowbite-svelte': 'src/lib'
  }
}

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) Locate Drawer implementation"
fd -a 'Drawer.svelte' | sed -n '1,120p'

echo
echo "2) Inspect Drawer for bindable 'open' (look for $state or @bindable)"
# Expect to see either: export let open = $state(false)  OR a JSDoc @bindable above 'export let open'
rg -n --sortr path $'export\\s+let\\s+open' -A 3
rg -n --sortr path $'\\$state\\(|@bindable' src | sed -n '1,200p'

echo
echo "3) Verify examples import resolves to local src/lib (if using alias)"
# Expect alias in svelte.config.js: alias: { "flowbite-svelte": "src/lib" }
rg -n $'alias\\s*:\\s*\\{[^}]*"flowbite-svelte"\\s*:\\s*"src/lib"' svelte.config.* jsconfig.* tsconfig.*

echo
echo "4) Grep DrawerProps typing to ensure 'open' exists and is bindable"
rg -n 'interface\\s+DrawerProps|type\\s+DrawerProps' -A 6 src
rg -n 'open\\s*:\\s*boolean' src

echo
echo "5) Re-run checks"
echo "pnpm build && pnpm check && pnpm test:e2e"

Length of output: 281


To properly verify bindable open support in your local Drawer implementation, let’s rerun a focused script that avoids unescaped $ in echoes and pinpoints the definitions and alias configuration:

This will confirm whether:

  • open is declared and bindable in your local Drawer.svelte.
  • Your TypeScript typings include open.
  • You’ve configured the flowbite-svelte alias to point at src/lib for local examples.

Once we have the output, we can determine if fixes or config updates are needed.


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "1) Locate Drawer.svelte"
drawer_file=$(fd -a Drawer.svelte | head -n 1)
echo "$drawer_file"

echo
echo "2) Search for 'export let open' in Drawer.svelte"
rg -n 'export\s+let\s+open' "$drawer_file" -A 3 || echo "  No 'export let open' found"

echo
echo "3) Search for \$state usage in Drawer.svelte"
rg -n '\$state\(' "$drawer_file" -A 3 || echo "  No \$state found"

echo
echo "4) Search for @bindable JSDoc in Drawer.svelte"
rg -n '@bindable' "$drawer_file" -A 3 || echo "  No @bindable found"

echo
echo "5) Inspect DrawerProps typings"
rg -n 'interface\s+DrawerProps' -A 6 src/lib/drawer || echo "  No DrawerProps interface"
rg -n 'type\s+DrawerProps' -A 6 src/lib/drawer || echo "  No DrawerProps type"

echo
echo "6) Verify 'open' in DrawerProps"
rg -n 'open\s*:' src/lib/drawer || echo "  No open property in types"

echo
echo "7) Check for flowbite-svelte → src/lib alias"
rg -n 'alias' svelte.config.js tsconfig.json jsconfig.json || echo "  No alias key found"
rg -n '"flowbite-svelte"\s*:\s*"src/lib"' svelte.config.js tsconfig.json jsconfig.json || echo "  No flowbite-svelte → src/lib alias"

Length of output: 2858


Enable bindable open on Drawer and configure local alias

Findings:

  • src/lib/drawer/Drawer.svelte does not export an open prop or use the Svelte 5 bindable API.
  • The DrawerProps type (imported from $lib) has no open field.
  • No flowbite-svelte → src/lib alias is set in svelte.config.js or TypeScript config, so examples import the published package instead of your local source.

Action items:

  • In src/lib/drawer/Drawer.svelte, add a bindable open prop. For Svelte 5:
    /** @bindable */
    export let open = $state(false);
    Or for Svelte 4:
    export let open = false;
  • Update your DrawerProps type to include:
    open?: boolean;
  • Add a local‐dev alias so examples point at your in-repo code. In svelte.config.js:
    kit: {
      adapter: adapter(),
      alias: {
        'flowbite-svelte': 'src/lib'
      }
    }

After applying these changes, re-run:

pnpm build && pnpm check && pnpm test:e2e

to confirm that bind:open errors are resolved.

🤖 Prompt for AI Agents
In src/routes/api-check/components/drawer/examples/Disabled.svelte around line
13, the example uses bind:open but the Drawer component and types don't expose a
bindable open prop and the example imports the published package instead of
local source; fix by adding a bindable open prop to src/lib/drawer/Drawer.svelte
(use the Svelte 5 @bindable export or export let open = false for Svelte 4),
update the DrawerProps type in your library to include open?: boolean, and add a
local dev alias in svelte.config.js mapping 'flowbite-svelte' to 'src/lib' so
examples import the in-repo component; after changes run pnpm build && pnpm
check && pnpm test:e2e to verify bind:open works.


<div class="text-center">
<Button onclick={() => (hidden5 = false)}>Show drawer</Button>
<Button onclick={() => (open5 = true)}>Show drawer</Button>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix Svelte event directive (use on:click, not onclick)

onclick won’t register as an event listener on a Svelte component. Use on:click so the button actually opens the drawer.

Apply this diff:

-  <Button onclick={() => (open5 = true)}>Show drawer</Button>
+  <Button on:click={() => (open5 = true)}>Show drawer</Button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Button onclick={() => (open5 = true)}>Show drawer</Button>
<Button on:click={() => (open5 = true)}>Show drawer</Button>
🤖 Prompt for AI Agents
In src/routes/api-check/components/drawer/examples/Left.svelte around line 9,
the Button uses the native attribute onclick which Svelte components do not
bind; replace onclick={() => (open5 = true)} with the Svelte event directive
on:click={() => (open5 = true)} so the click handler properly registers and
opens the drawer.

<h5 class="px-4 text-base font-semibold text-gray-500 uppercase dark:text-gray-400">Menu</h5>
<CloseButton class="dark:text-white" />
</div>
<Drawer bind:open={open2} class="w-64 bg-gray-50 p-0 dark:bg-gray-800">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify svelte-check setup resolves the local Drawer with bind:open

The usage of bind:open aligns with this PR, but the reported svelte-check errors suggest the examples might be resolving Drawer from the published package (which still expects bind:hidden) instead of src/lib. Confirm the alias is configured so imports from "flowbite-svelte" point to src/lib.

Run this script to verify the alias and the Drawer prop in the PR branch:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) Check svelte.config.* for alias mapping flowbite-svelte -> src/lib"
fd -a 'svelte.config.*' | while read -r cfg; do
  echo "---- $cfg ----"
  rg -n "alias|kit|flowbite-svelte" "$cfg" || true
done

echo
echo "2) Check Drawer implementation exposes an 'open' prop (and not 'hidden')"
fd -a Drawer.svelte | rg -n 'src/lib' | while read -r file; do
  echo "---- $file ----"
  rg -n "export let open|let open =|bindable|hidden" "$file" || true
done

echo
echo "3) Grep example usage of bind:open (should be present)"
rg -n "bind:open" src/routes || true

echo
echo "If alias is missing, add this to svelte.config.* under kit:"
cat <<'CFG'
kit: {
  // ...
  alias: {
    "flowbite-svelte": "src/lib"
  }
}
CFG

Length of output: 12520


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) Verify Drawer.svelte exports 'open' and not 'hidden'"
rg -n "export let open" src/lib/drawer/Drawer.svelte
rg -n "export let hidden" src/lib/drawer/Drawer.svelte || echo "No 'hidden' export found"

Length of output: 207


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Verifying Drawer.svelte exports in src/lib/drawer/Drawer.svelte..."

echo "1) Checking for 'export let open':"
rg -n "export let open" src/lib/drawer/Drawer.svelte || echo "  → No 'export let open' found"

echo
echo "2) Checking for 'export let hidden':"
rg -n "export let hidden" src/lib/drawer/Drawer.svelte || echo "  → No 'export let hidden' found"

Length of output: 614


#!/usr/bin/env bash
set -euo pipefail

echo "=== svelte.config.js (first 200 lines) ==="
sed -n '1,200p' svelte.config.js || true

echo
echo "=== Locating Drawer.svelte ==="
fd -t f Drawer.svelte || true

FILE=$(fd -t f Drawer.svelte | head -n1 || true)
if [[ -n "$FILE" ]]; then
  echo
  echo "=== Preview of $FILE (first 50 lines) ==="
  head -n50 "$FILE"
else
  echo "Drawer.svelte not found in src/lib/drawer or elsewhere."
fi

#!/usr/bin/env bash
set -euo pipefail

echo "=== Checking alias mapping in svelte.config.js ==="
rg -n "alias" svelte.config.js || echo "→ No alias section found"
rg -n "flowbite-svelte" svelte.config.js || echo "→ No flowbite-svelte reference found"

echo
echo "=== Locating all Drawer.svelte files ==="
DRAWER_FILES=$(fd -t f Drawer.svelte || true)
if [[ -z "$DRAWER_FILES" ]]; then
  echo "→ No Drawer.svelte files found"
  exit 0
fi

echo "$DRAWER_FILES"
for file in $DRAWER_FILES; do
  echo
  echo "---- $file ----"
  rg -n "export let open" "$file" || echo "  → 'export let open' not declared"
  rg -n "export let hidden" "$file" || echo "  → 'export let hidden' not declared"
done

Add SvelteKit alias so examples resolve local Drawer component

It looks like your svelte.config.js does not define an alias for flowbite-svelte, so svelte-check may be picking up the published package (which still expects a bind:hidden prop) instead of your local src/lib. Please add the following under the kit section in svelte.config.js:

 kit: {
   // …
+  alias: {
+    'flowbite-svelte': 'src/lib'
+  }
 }

This will ensure that imports from "flowbite-svelte" in your examples (including the Navigation.svelte snippet) resolve to your PR’s source code where Drawer properly exports open rather than hidden.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Drawer bind:open={open2} class="w-64 bg-gray-50 p-0 dark:bg-gray-800">
// In svelte.config.js, under the `kit` section, add the alias:
kit: {
// …
alias: {
'flowbite-svelte': 'src/lib'
}
}
🤖 Prompt for AI Agents
In src/routes/api-check/components/drawer/examples/Navigation.svelte around line
11, the example imports resolve to the published flowbite-svelte package (which
expects bind:hidden) instead of the local Drawer component; update
svelte.config.js by adding a kit.alias (mapping "flowbite-svelte" to your local
src/lib path) so SvelteKit and svelte-check resolve imports to the PR source
code where Drawer exports bind:open; save and restart the dev server / re-run
svelte-check to verify examples now use the local component.

import { Drawer, Button, CloseButton } from "flowbite-svelte";
import { InfoCircleSolid, ArrowRightOutline } from "flowbite-svelte-icons";
let drawerHidden = $state(true);
let openHidden = $state(false);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix event binding (use on:click) and align state name with new API

  • Svelte requires on:click (not onclick). The current handler won’t fire.
  • Rename openHidden to open for clarity and consistency with bind:open.
-  let openHidden = $state(false);
+  let open = $state(false);
-  <Button onclick={() => (openHidden = true)}>Show drawer</Button>
+  <Button on:click={() => (open = true)}>Show drawer</Button>
-<Drawer bind:open={openHidden}>
+<Drawer bind:open={open}>

Also applies to: 8-8, 11-11

🤖 Prompt for AI Agents
In src/routes/api-check/components/drawer/examples/Scrolling.svelte around lines
4, 8 and 11, rename the local state variable from openHidden to open (change the
let declaration using $state to let open = $state(false)) and update the click
handlers to use Svelte's on:click syntax instead of onclick on the relevant
elements; also update any bind:open usages to reference the new open variable so
binding and events work with the new API.

</h5>
<CloseButton class="mb-4 dark:text-white" />
</div>
<Drawer bind:open={openHidden}>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Optional: provide an accessible name for the dialog

Consider wiring the header to the dialog for screen readers. If Drawer/Dialog forwards ARIA attributes to the dialog element, add aria-labelledby referencing the heading id.

Example change (if supported by Drawer/Dialog):

-<Drawer bind:open={open}>
+<Drawer bind:open={open} aria-labelledby="drawer-label">

To verify support, run:


🏁 Script executed:

#!/bin/bash
# Check if Drawer/Dialog forwards aria-labelledby or exposes a specific prop (e.g., labelledby/ariaLabel)
rg -n --no-heading $'aria-labelledby|labelledby|ariaLabel' src/lib/dialog src/lib/drawer src/lib/types

Length of output: 157


🏁 Script executed:

#!/bin/bash
# 1. Locate the Drawer component file
DRAWER_FILE=$(fd -t f Drawer.svelte src | head -n1)
if [[ -z "$DRAWER_FILE" ]]; then
  echo "ERROR: Could not find Drawer.svelte in src/"
  exit 1
fi

echo "Found Drawer component at: $DRAWER_FILE"
echo

# 2. Check for rest‐props forwarding
echo "Checking for $$restProps forwarding:"
grep -R '{\$\$restProps}' -n "$DRAWER_FILE" || echo "  → No $$restProps forwarding found"

echo
# 3. Inspect top of the file for dialog or ARIA handling
echo "Inspecting first 200 lines of the component:"
sed -n '1,200p' "$DRAWER_FILE"

echo
# 4. Search for any aria- attributes in the component
echo "Searching for aria- attributes in the component:"
grep -R 'aria-' -n "$DRAWER_FILE" || echo "  → No aria- attributes referenced"

echo
# 5. Look for a <dialog> element or role="dialog"
echo "Searching for <dialog> tag or role=\"dialog\":"
grep -R -n "<dialog" "$DRAWER_FILE" && exit 0
grep -R -n 'role=.*dialog' "$DRAWER_FILE" || echo "  → No native <dialog> or role=\"dialog\" usage found"

Length of output: 2959


🏁 Script executed:

#!/bin/bash
# Locate Dialog component file
DIALOG_FILE=$(fd -t f Dialog.svelte src/lib/dialog | head -n1)
if [[ -z "$DIALOG_FILE" ]]; then
  echo "ERROR: Could not find Dialog.svelte in src/lib/dialog"
  exit 1
fi

echo "Found Dialog component at: $DIALOG_FILE"
echo

# 1. Check for restProps in props destructuring
echo "Looking for restProps in props destructuring:"
grep -n '...restProps' -n "$DIALOG_FILE" || echo "  → No restProps destructuring found"

echo
# 2. Search for restProps spread in markup
echo "Searching for {...restProps} in markup:"
grep -n '{\.\.\.restProps}' "$DIALOG_FILE" || echo "  → No restProps spread in markup found"

echo
# 3. Inspect the top 200 lines of the component for context
echo "Inspecting first 200 lines of Dialog.svelte:"
sed -n '1,200p' "$DIALOG_FILE"

Length of output: 6432


Add an accessible name to the drawer

The Drawer component forwards all extra props down to the underlying <dialog>, so you can expose your header to screen readers by wiring up aria-labelledby.

– Give your header element an id, e.g.

<h2 id="drawer-label">Scrolling Content</h2>

– Update the Drawer invocation:

- <Drawer bind:open={openHidden}>
+ <Drawer bind:open={openHidden} aria-labelledby="drawer-label">

Since Drawer spreads {...restProps} into Dialog.svelte, and Dialog.svelte in turn spreads {...restProps} onto its <dialog> element, this will correctly expose the label to assistive technologies.

🤖 Prompt for AI Agents
In src/routes/api-check/components/drawer/examples/Scrolling.svelte around line
11, the Drawer lacks an accessible name for screen readers; add an id to the
header (e.g. assign an id like "drawer-label" to the <h2> element) and pass
aria-labelledby="drawer-label" to the <Drawer> component so the prop is
forwarded to the underlying <dialog>, exposing the header as the dialog label
for assistive technologies.


<div class="text-center">
<Button onclick={() => (hidden7 = false)}>Show drawer</Button>
<Button onclick={() => (open7 = true)}>Show drawer</Button>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix event handler: use Svelte’s on:click instead of onclick

onclick won’t attach a Svelte event listener; the button won’t open the drawer.

Apply this diff:

-  <Button onclick={() => (open7 = true)}>Show drawer</Button>
+  <Button on:click={() => (open7 = true)}>Show drawer</Button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Button onclick={() => (open7 = true)}>Show drawer</Button>
<Button on:click={() => (open7 = true)}>Show drawer</Button>
🤖 Prompt for AI Agents
In src/routes/api-check/components/drawer/examples/Top.svelte around line 15,
the Button uses a plain DOM onclick attribute which Svelte won't bind; replace
onclick={() => (open7 = true)} with Svelte's on:click handler (on:click={() =>
open7 = true}) so the click opens the drawer; update that single line
accordingly.

@shinokada shinokada merged commit 8716564 into themesberg:main Aug 13, 2025
1 of 2 checks passed
@shinokada
Copy link
Copy Markdown
Collaborator

Double close button.

image

@shinokada
Copy link
Copy Markdown
Collaborator

https://flowbite-svelte.com/docs/components/drawer#non-modal

Using modal={false} disable outside click to close. Is it intentional?

@jjagielka
Copy link
Copy Markdown
Contributor Author

Non-modal means not backdrop and the ability to play with the rest of the elements of the page. The Esc button does not work either and the position must be set manually: fixed or absolute.

See: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/dialog

@jjagielka jjagielka deleted the drawer branch August 13, 2025 10:03
@coderabbitai coderabbitai bot mentioned this pull request Aug 14, 2025
8 tasks
@coderabbitai coderabbitai bot mentioned this pull request Aug 22, 2025
8 tasks
@coderabbitai coderabbitai bot mentioned this pull request Nov 25, 2025
15 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants