diff --git a/apps/web/content/docs/components/drawer.mdx b/apps/web/content/docs/components/drawer.mdx new file mode 100644 index 000000000..d366405e7 --- /dev/null +++ b/apps/web/content/docs/components/drawer.mdx @@ -0,0 +1,114 @@ +--- +title: React Drawer (offcanvas) - Flowbite +description: The Drawer component can be used as a hidden off-canvas sidebar for navigation and to show other information based on multiple styles and placements +--- + +Use the Drawer component (or "off-canvas") to show a fixed element relative to the document page from any side for navigation, contact forms, informational purposes or other user actions. + +You can set multiple options such as the placement, activate body scrolling, show or hide the backdrop and even use the swipeable edge functionality to show a small part of the drawer when it is not shown completely. + +To start using the drawer component you need to import it from `flowbite-react`: + +```jsx +import { Drawer } from "flowbite-react"; +``` + +## Default drawer + + + +## Drawer navigation + +Use this example to show a navigational sidebar inside the drawer component. + + + +## Contact form + +Use this example to show a contact form inside the drawer component. + + + +## Form elements + +Use this example if you want to add form elements inside the drawer component including datepickers. + + + +## Placement + +Use the placement options to position the drawer component either on the top, right, bottom, or left side of the document page. This can be done using the `position="{top|right|bottom|left}"` attribute where the default value is "left". + +### Left drawer + +Use this example where you can position the drawer component on the left side of the page. + + + +### Right drawer + +Use this example to show the drawer component on the right side of the page. + + + +### Top drawer + +Use this example to show the drawer on the top side of the page. + + + +### Bottom drawer + +Use this example to show the drawer on the bottom side of the page. + + + +## Body scrolling + +By default, body scrolling is disabled when the drawer is visible, however, you can choose to enable it using the `bodyScrolling="{true|false}"` attribute. + +### Disabled (default) + +This is an example where the body scrolling behaviour is disabled when the drawer is visible. + + + +### Enabled + +Get started with this example in order to enable body scrolling even if the drawer component is visible by applying `overflow-y: auto` to your ``. + + + +## Backdrop + +The backdrop element can be used to dim out the background elements when the drawer is visible and also automatically hide the component when clicking outside of it. + +Use the `backdrop="{true|false}"` attribute where you can disable or enable the backdrop element. + +### Enabled (default) + +Use this example to enable the backdrop element by default. + + + +### Disabled + +Use the `backdrop="false"` attribute to disable the backdrop element when the drawer is shown. + + + +## Swipeable edge + +The drawer edge functionality allows you to show a small part of the drawer when it is not shown completely by applying the `edge="{true|false}"` attribute, specifying the edge you'd like to set with, e.g., `theme={{ edge: "bottom-16" }}`, and adding `onClick={() => setIsOpen(!isOpen)}` to ``. + + + +## Theme + +To learn more about how to customize the appearance of components, please see the [Theme docs](/docs/customize/theme). + + + +## References + +- [Flowbite Drawer](https://flowbite.com/docs/components/drawer/) diff --git a/apps/web/data/docs-sidebar.ts b/apps/web/data/docs-sidebar.ts index 60c49560b..ea2cb399b 100644 --- a/apps/web/data/docs-sidebar.ts +++ b/apps/web/data/docs-sidebar.ts @@ -64,6 +64,7 @@ export const DOCS_SIDEBAR: DocsSidebarSection[] = [ { title: "Card", href: "/docs/components/card" }, { title: "Carousel", href: "/docs/components/carousel" }, { title: "Datepicker", href: "/docs/components/datepicker", isNew: true }, + { title: "Drawer", href: "/docs/components/drawer", isNew: true }, { title: "Dropdown", href: "/docs/components/dropdown" }, { title: "Footer", href: "/docs/components/footer" }, { title: "Forms", href: "/docs/components/forms" }, diff --git a/apps/web/examples/drawer/drawer.backdrop.tsx b/apps/web/examples/drawer/drawer.backdrop.tsx new file mode 100644 index 000000000..fc0b7b760 --- /dev/null +++ b/apps/web/examples/drawer/drawer.backdrop.tsx @@ -0,0 +1,292 @@ +"use client"; + +import { + Button, + Drawer, + DrawerHeader, + DrawerItems, + Sidebar, + SidebarItem, + SidebarItemGroup, + SidebarItems, + TextInput, + theme, +} from "flowbite-react"; +import { useState } from "react"; +import { + HiChartPie, + HiClipboard, + HiCollection, + HiInformationCircle, + HiLogin, + HiPencil, + HiSearch, + HiShoppingBag, + HiUsers, +} from "react-icons/hi"; +import { twMerge } from "tailwind-merge"; +import type { CodeData } from "~/components/code-demo"; + +const code = ` +"use client"; + +import { + Button, + Drawer, + Sidebar, + TextInput, +} from "flowbite-react"; +import { useState } from "react"; +import { + HiChartPie, + HiClipboard, + HiCollection, + HiInformationCircle, + HiLogin, + HiPencil, + HiSearch, + HiShoppingBag, + HiUsers, +} from "react-icons/hi"; + +function Component() { + const [isOpen, setIsOpen] = useState(true); + + const handleClose = () => setIsOpen(false); + + return ( + <> +
+ +
+ + <>} /> + + +
+
+
+ + + + + + Dashboard + + + Products + + + Users list + + + Sign in + + + Sign up + + + + + Docs + + + Components + + + Help + + + +
+
+
+
+
+ + ); +} +`; +const codeRSC = ` +import { + Button, + Drawer, + DrawerHeader, + DrawerItems, + Sidebar, + SidebarItem, + SidebarItemGroup, + SidebarItems, + TextInput, +} from "flowbite-react"; +import { useState } from "react"; +import { + HiChartPie, + HiClipboard, + HiCollection, + HiInformationCircle, + HiLogin, + HiPencil, + HiSearch, + HiShoppingBag, + HiUsers, +} from "react-icons/hi"; + +function Component() { + const [isOpen, setIsOpen] = useState(true); + + const handleClose = () => setIsOpen(false); + + return ( + <> +
+ +
+ + <>} /> + + +
+
+
+ + + + + + Dashboard + + + Products + + + Users list + + + Sign in + + + Sign up + + + + + Docs + + + Components + + + Help + + + +
+
+
+
+
+ + ); +} +`; + +function Component() { + const [isOpen, setIsOpen] = useState(true); + + const handleClose = () => setIsOpen(false); + + return ( +
+
+ +
+ + <>} /> + + +
+
+
+ + + + + + Dashboard + + + Products + + + Users list + + + Sign in + + + Sign up + + + + + Docs + + + Components + + + Help + + + +
+
+
+
+
+
+ ); +} + +export const backdrop: CodeData = { + type: "single", + code: [ + { + fileName: "client", + language: "tsx", + code, + }, + { + fileName: "server", + language: "tsx", + code: codeRSC, + }, + ], + githubSlug: "drawer/drawer.backdrop.tsx", + component: , +}; diff --git a/apps/web/examples/drawer/drawer.bodyScrolling.tsx b/apps/web/examples/drawer/drawer.bodyScrolling.tsx new file mode 100644 index 000000000..b387fa0ae --- /dev/null +++ b/apps/web/examples/drawer/drawer.bodyScrolling.tsx @@ -0,0 +1,354 @@ +"use client"; + +import { + Button, + Drawer, + DrawerHeader, + DrawerItems, + Sidebar, + SidebarItem, + SidebarItemGroup, + SidebarItems, + TextInput, + theme, +} from "flowbite-react"; +import { useState } from "react"; +import { + HiChartPie, + HiClipboard, + HiCollection, + HiInformationCircle, + HiLogin, + HiPencil, + HiSearch, + HiShoppingBag, + HiUsers, +} from "react-icons/hi"; +import { twMerge } from "tailwind-merge"; +import type { CodeData } from "~/components/code-demo"; + +const code = ` +"use client"; + +import { + Button, + Drawer, + Sidebar, + TextInput, +} from "flowbite-react"; +import { useState } from "react"; +import { + HiChartPie, + HiClipboard, + HiCollection, + HiInformationCircle, + HiLogin, + HiPencil, + HiSearch, + HiShoppingBag, + HiUsers, +} from "react-icons/hi"; + +function Component() { + const [isOpen, setIsOpen] = useState(true); + + const handleClose = () => setIsOpen(false); + + return ( +
+
+ +
Testing scroll
+
+ + <>} /> + + +
+
+
+ + + + + + Dashboard + + + Products + + + Users list + + + Sign in + + + Sign up + + + + + Docs + + + Components + + + Help + + + +
+
+
+
+
+
+ ); +} +`; +const codeRSC = ` +import { + Button, + Drawer, + DrawerHeader, + DrawerItems, + Sidebar, + SidebarItem, + SidebarItemGroup, + SidebarItems, + TextInput, +} from "flowbite-react"; +import { useState } from "react"; +import { + HiChartPie, + HiClipboard, + HiCollection, + HiInformationCircle, + HiLogin, + HiPencil, + HiSearch, + HiShoppingBag, + HiUsers, +} from "react-icons/hi"; + +function Component() { + const [isOpen, setIsOpen] = useState(true); + + const handleClose = () => setIsOpen(false); + + return ( +
+
+ +
Testing scroll
+
+ + <>} /> + + +
+
+
+ + + + + + Dashboard + + + Products + + + Users list + + + Sign in + + + Sign up + + + + + Docs + + + Components + + + Help + + + +
+
+
+
+
+
+ ); +} +`; + +function Component() { + const [isOpen, setIsOpen] = useState(true); + + const handleClose = () => setIsOpen(false); + + return ( +
+
+ +
+ + <>} /> + + +
+
+
+ + + + + + Dashboard + + + Products + + + Users list + + + Sign in + + + Sign up + + + + + Docs + + + Components + + + Help + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+ Loading... +
+
+
+ +
+ Loading... +
+
+
+
+
+
+
+
+
+ Loading... +
+
+
+
+
+
+ Loading... +
+
+
+
+
+
+
+
+
+
+
+
+ Loading... +
+
+
+
+ Loading... +
+
+
+ ); +} + +export const bodyScrolling: CodeData = { + type: "single", + code: [ + { + fileName: "client", + language: "tsx", + code, + }, + { + fileName: "server", + language: "tsx", + code: codeRSC, + }, + ], + githubSlug: "drawer/drawer.bodyScrolling.tsx", + component: , +}; diff --git a/apps/web/examples/drawer/drawer.bottom.tsx b/apps/web/examples/drawer/drawer.bottom.tsx new file mode 100644 index 000000000..9a4af82a0 --- /dev/null +++ b/apps/web/examples/drawer/drawer.bottom.tsx @@ -0,0 +1,213 @@ +"use client"; + +import { Button, Drawer, DrawerHeader, DrawerItems, theme } from "flowbite-react"; +import { useState } from "react"; +import { twMerge } from "tailwind-merge"; +import type { CodeData } from "~/components/code-demo"; + +const code = ` +"use client"; + +import { Button, Drawer } from "flowbite-react"; +import { useState } from "react"; + +function Component() { + const [isOpen, setIsOpen] = useState(true); + + const handleClose = () => setIsOpen(false); + + return ( + <> +
+ +
+ + + +

+ Supercharge your hiring by taking advantage of our  + + limited-time sale + +  for Flowbite Docs + Job Board. Unlimited access to over 190K top-ranked candidates and the #1 design + job board. +

+ +
+
+ + ); +} +`; +const codeRSC = ` +import { Button, Drawer, DrawerHeader, DrawerItems } from "flowbite-react"; +import { useState } from "react"; + +function Component() { + const [isOpen, setIsOpen] = useState(true); + + const handleClose = () => setIsOpen(false); + + return ( + <> +
+ +
+ + + +

+ Supercharge your hiring by taking advantage of our  + + limited-time sale + +  for Flowbite Docs + Job Board. Unlimited access to over 190K top-ranked candidates and the #1 design + job board. +

+ +
+
+ + ); +} +`; + +function Component() { + const [isOpen, setIsOpen] = useState(true); + + const handleClose = () => setIsOpen(false); + + return ( +
+
+ +
+ + + +

+ Supercharge your hiring by taking advantage of our  + + limited-time sale + +  for Flowbite Docs + Job Board. Unlimited access to over 190K top-ranked candidates and the #1 design + job board. +

+ +
+
+
+ ); +} + +export const bottom: CodeData = { + type: "single", + code: [ + { + fileName: "client", + language: "tsx", + code, + }, + { + fileName: "server", + language: "tsx", + code: codeRSC, + }, + ], + githubSlug: "drawer/drawer.bottom.tsx", + component: , +}; diff --git a/apps/web/examples/drawer/drawer.contactForm.tsx b/apps/web/examples/drawer/drawer.contactForm.tsx new file mode 100644 index 000000000..c243ab416 --- /dev/null +++ b/apps/web/examples/drawer/drawer.contactForm.tsx @@ -0,0 +1,223 @@ +"use client"; + +import { Button, Drawer, DrawerHeader, DrawerItems, Label, Textarea, TextInput, theme } from "flowbite-react"; +import { useState } from "react"; +import { HiEnvelope } from "react-icons/hi2"; +import { twMerge } from "tailwind-merge"; +import type { CodeData } from "~/components/code-demo"; + +const code = ` +"use client"; + +import { Button, Drawer, Label, Textarea, TextInput } from "flowbite-react"; +import { useState } from "react"; +import { HiEnvelope } from "react-icons/hi2"; + +function Component() { + const [isOpen, setIsOpen] = useState(true); + + const handleClose = () => setIsOpen(false); + + return ( + <> +
+ +
+ + + +
+
+ + +
+
+ + +
+
+ +