Skip to content

Commit e47944d

Browse files
authored
Merge branch 'main' into main
2 parents a38dc87 + 7ddef82 commit e47944d

File tree

272 files changed

+5792
-668
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

272 files changed

+5792
-668
lines changed

.changeset/shiny-wolves-report.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"flowbite-react": patch
3+
---
4+
5+
Mega Menu - export all entities

.vscode/settings.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
["createTheme\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
1212
],
1313
"tailwindCSS.experimental.configFile": {
14-
"apps/web/tailwind.config.js": "apps/web/**",
15-
"packages/ui/tailwind.config.js": "packages/ui/**"
14+
"apps/web/tailwind.config.cjs": "apps/web/**",
15+
"packages/ui/tailwind.config.cjs": "packages/ui/**"
1616
},
1717
"typescript.tsdk": "node_modules/typescript/lib"
1818
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
"use client";
2+
3+
import { useSearchParams } from "next/navigation";
4+
import type { PropsWithChildren } from "react";
5+
import { twMerge } from "tailwind-merge";
6+
7+
export default function ExamplePageLayout({ children }: PropsWithChildren) {
8+
const searchParams = useSearchParams();
9+
const noPadding = searchParams.get("noPadding");
10+
11+
return <main className={twMerge(noPadding === null && "p-5")}>{children}</main>;
12+
}

apps/web/app/examples/[name]/page.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { notFound } from "next/navigation";
2+
3+
interface Props {
4+
params: {
5+
name: string;
6+
};
7+
}
8+
9+
export default async function ExamplePage({ params }: Props) {
10+
try {
11+
const [key] = params.name.split(".");
12+
13+
const { Component } = await import(`~/examples/${key}/${params.name}`);
14+
15+
return Component ? <Component /> : notFound();
16+
} catch (e) {
17+
notFound();
18+
}
19+
}

apps/web/components/code-demo.tsx

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { Select, Tooltip, useThemeMode } from "flowbite-react";
44
import type { ComponentProps, PropsWithChildren } from "react";
5-
import { useEffect, useState } from "react";
5+
import { useEffect, useRef, useState } from "react";
66
import type { IconType } from "react-icons";
77
import { FaCopy } from "react-icons/fa";
88
import { HiMoon, HiSun } from "react-icons/hi";
@@ -12,10 +12,18 @@ import { TfiMobile } from "react-icons/tfi";
1212
import { twMerge } from "tailwind-merge";
1313
import { CodeHighlight, type Language } from "./code-highlight";
1414

15+
type IFrameData = number | IFrameOptions;
16+
17+
interface IFrameOptions {
18+
height: number;
19+
noPadding?: boolean;
20+
}
21+
1522
interface BaseCodeData<T extends "single" | "variant"> {
1623
type: T;
1724
githubSlug: string;
1825
component: React.ReactNode;
26+
iframe?: IFrameData;
1927
}
2028

2129
interface VariantCodeData<V extends Variant> extends BaseCodeData<"variant"> {
@@ -135,8 +143,8 @@ export function CodeDemo({ data }: CodeDemoProps) {
135143
</div>
136144
</div>
137145
</div>
138-
<CodePreview view={view} isRTL={isRTL} isDarkMode={isDarkMode}>
139-
{data.component}
146+
<CodePreview view={view} isRTL={isRTL} isDarkMode={isDarkMode} iframe={data.iframe}>
147+
{data.iframe ? <IFrame data={data} isRTL={isRTL} isDarkMode={isDarkMode} /> : data.component}
140148
</CodePreview>
141149
<div className="code-syntax-wrapper">
142150
<div
@@ -173,6 +181,40 @@ export function CodeDemo({ data }: CodeDemoProps) {
173181
);
174182
}
175183

184+
function IFrame({ data, isRTL, isDarkMode }: { data: CodeData; isRTL: boolean; isDarkMode: boolean | null }) {
185+
const ref = useRef<HTMLIFrameElement>(null);
186+
187+
useEffect(() => {
188+
const document = ref.current?.contentDocument;
189+
190+
if (!document) return;
191+
192+
document.documentElement.setAttribute("dir", isRTL ? "rtl" : "ltr");
193+
194+
if (isDarkMode) {
195+
document.documentElement.classList.add("dark");
196+
} else {
197+
document.documentElement.classList.remove("dark");
198+
}
199+
}, [isRTL, isDarkMode]);
200+
201+
function getSrc() {
202+
const base = "/examples";
203+
const target = data.githubSlug.split("/")[1].replace(".tsx", "");
204+
const noPadding = typeof data.iframe === "object" && data.iframe.noPadding ? `?noPadding` : "";
205+
206+
return `${base}/${target}${noPadding}`;
207+
}
208+
209+
function getHeight(): number {
210+
const payload = data.iframe!;
211+
212+
return typeof payload === "number" ? payload : payload.height;
213+
}
214+
215+
return <iframe ref={ref} src={getSrc()} height={getHeight()} className="w-full" />;
216+
}
217+
176218
function Tabs({ tabIndex, items, onSelect }: { tabIndex: number; items: CodeItem[]; onSelect(index: number): void }) {
177219
return (
178220
<ul className="flex flex-1 text-center text-sm font-medium text-gray-500 dark:text-gray-400">
@@ -198,20 +240,22 @@ function CodePreview({
198240
view,
199241
isRTL,
200242
isDarkMode,
243+
iframe,
201244
children,
202-
}: PropsWithChildren<{ view: View; isRTL: boolean; isDarkMode: boolean | null }>) {
245+
}: PropsWithChildren<{ view: View; isRTL: boolean; isDarkMode: boolean | null; iframe?: IFrameData }>) {
203246
return (
204247
<div
205248
{...(isRTL && { dir: "rtl" })}
206249
className={twMerge("code-preview-wrapper", isDarkMode !== null && (isDarkMode ? "dark" : "light"))}
207250
>
208-
<div className="code-preview flex border-x border-gray-200 bg-white bg-gradient-to-r p-0 dark:border-gray-600 dark:bg-gray-900">
251+
<div className="flex border-x border-gray-200 bg-white bg-gradient-to-r p-0 dark:border-gray-600 dark:bg-gray-900">
209252
<div className="code-responsive-wrapper w-full">
210253
<div
211254
className={twMerge(
212-
"mx-auto w-full bg-white bg-gradient-to-r p-5 dark:bg-gray-900",
255+
"mx-auto w-full bg-white bg-gradient-to-r dark:bg-gray-900",
213256
view === "tablet" && "max-w-lg",
214257
view === "mobile" && "max-w-sm",
258+
!iframe && "p-5",
215259
)}
216260
>
217261
{children}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
---
2+
title: React Drawer (offcanvas) - Flowbite
3+
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
4+
---
5+
6+
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.
7+
8+
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.
9+
10+
To start using the drawer component you need to import it from `flowbite-react`:
11+
12+
```jsx
13+
import { Drawer } from "flowbite-react";
14+
```
15+
16+
## Default drawer
17+
18+
<Example name="drawer.root" />
19+
20+
## Drawer navigation
21+
22+
Use this example to show a navigational sidebar inside the drawer component.
23+
24+
<Example name="drawer.navigation" />
25+
26+
## Contact form
27+
28+
Use this example to show a contact form inside the drawer component.
29+
30+
<Example name="drawer.contactForm" />
31+
32+
## Form elements
33+
34+
Use this example if you want to add form elements inside the drawer component including datepickers.
35+
36+
<Example name="drawer.formElements" />
37+
38+
## Placement
39+
40+
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".
41+
42+
### Left drawer
43+
44+
Use this example where you can position the drawer component on the left side of the page.
45+
46+
<Example name="drawer.left" />
47+
48+
### Right drawer
49+
50+
Use this example to show the drawer component on the right side of the page.
51+
52+
<Example name="drawer.right" />
53+
54+
### Top drawer
55+
56+
Use this example to show the drawer on the top side of the page.
57+
58+
<Example name="drawer.top" />
59+
60+
### Bottom drawer
61+
62+
Use this example to show the drawer on the bottom side of the page.
63+
64+
<Example name="drawer.bottom" />
65+
66+
## Body scrolling
67+
68+
By default, body scrolling is disabled when the drawer is visible, however, you can choose to enable it using the `bodyScrolling="{true|false}"` attribute.
69+
70+
### Disabled (default)
71+
72+
This is an example where the body scrolling behaviour is disabled when the drawer is visible.
73+
74+
<Example name="drawer.noBodyScrolling" />
75+
76+
### Enabled
77+
78+
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 `<body>`.
79+
80+
<Example name="drawer.bodyScrolling" />
81+
82+
## Backdrop
83+
84+
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.
85+
86+
Use the `backdrop="{true|false}"` attribute where you can disable or enable the backdrop element.
87+
88+
### Enabled (default)
89+
90+
Use this example to enable the backdrop element by default.
91+
92+
<Example name="drawer.backdrop" />
93+
94+
### Disabled
95+
96+
Use the `backdrop="false"` attribute to disable the backdrop element when the drawer is shown.
97+
98+
<Example name="drawer.noBackdrop" />
99+
100+
## Swipeable edge
101+
102+
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 `<DrawerHeader/>`.
103+
104+
<Example name="drawer.swipeableEdge" />
105+
106+
## Theme
107+
108+
To learn more about how to customize the appearance of components, please see the [Theme docs](/docs/customize/theme).
109+
110+
<Theme name="drawer" />
111+
112+
## References
113+
114+
- [Flowbite Drawer](https://flowbite.com/docs/components/drawer/)

apps/web/content/docs/components/forms.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ Use the `<ToggleSwitch>` component to ask users to enable or disable an option s
125125

126126
## Range slider
127127

128-
The `<RangeSlider>` component ca be used to allow users to select a number based on a minimum and maximum value.
128+
The `<RangeSlider>` component can be used to allow users to select a number based on a minimum and maximum value.
129129

130130
<Example name="forms.rangeSlider" />
131131

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
title: React Mega Menu - Flowbite
3+
description: Use the mega menu component as a full-width dropdown inside the navbar to show a list of menu items based on multiple sizes, variants, and styles.
4+
---
5+
6+
The mega menu component is a full-width dropdown that can be triggered by clicking on the menu item and it shows a list of links that you can use to navigate through the pages on a website.
7+
8+
To start using the mega menu component you need to import it from `flowbite-react`:
9+
10+
```jsx
11+
import { MegaMenu } from "flowbite-react";
12+
```
13+
14+
## Default mega menu
15+
16+
Use this example to show a list of links aligned on three columns inside the mega menu dropdown.
17+
18+
<Example name="megaMenu.root" />
19+
20+
## Mega menu with icons
21+
22+
This example of a mega menu dropdown can be used to also show an icon near the text of the link.
23+
24+
<Example name="megaMenu.icons" />
25+
26+
## Full width dropdown
27+
28+
Use this example to show a mega menu dropdown that spans the entire width of the document page.
29+
30+
<Example name="megaMenu.fullWidth" />
31+
32+
## Full width with CTA
33+
34+
This example can be used to also show a CTA button or link next to the menu items inside the dropdown.
35+
36+
<Example name="megaMenu.fullWidthCTA" />
37+
38+
## Full width with image
39+
40+
This example can be used to also show a CTA with a background image inside the dropdown next to the other menu items and links.
41+
42+
<Example name="megaMenu.fullWidthImage" />
43+
44+
## Theme
45+
46+
Note:
47+
48+
- `<MegaMenu>`'s theme has all of the same options as [`<Navbar>`](https://flowbite-react.com/docs/components/navbar)'s, with slightly different defaults
49+
- `<MegaMenu.Dropdown toggle={..} />`'s theme, `megaMenu.dropdown.toggle`, is identical to [`<Dropdown>`](https://flowbite-react.com/docs/components/dropdown), with slightly different defaults
50+
51+
<Theme name="megaMenu" />
52+
53+
## References
54+
55+
- [Flowbite Mega Menu](https://flowbite.com/docs/components/mega-menu/)

apps/web/data/docs-sidebar.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,13 @@ export const DOCS_SIDEBAR: DocsSidebarSection[] = [
6464
{ title: "Card", href: "/docs/components/card" },
6565
{ title: "Carousel", href: "/docs/components/carousel" },
6666
{ title: "Datepicker", href: "/docs/components/datepicker", isNew: true },
67+
{ title: "Drawer", href: "/docs/components/drawer", isNew: true },
6768
{ title: "Dropdown", href: "/docs/components/dropdown" },
6869
{ title: "Footer", href: "/docs/components/footer" },
6970
{ title: "Forms", href: "/docs/components/forms" },
7071
{ title: "KBD", href: "/docs/components/kbd", isNew: true },
7172
{ title: "List group", href: "/docs/components/list-group" },
73+
{ title: "Mega menu", href: "/docs/components/mega-menu", isNew: true },
7274
{ title: "Modal", href: "/docs/components/modal" },
7375
{ title: "Navbar", href: "/docs/components/navbar" },
7476
{ title: "Pagination", href: "/docs/components/pagination" },

apps/web/examples/accordion/accordion.collapseAll.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const code = `
66
77
import { Accordion } from "flowbite-react";
88
9-
function Component() {
9+
export function Component() {
1010
return (
1111
<Accordion collapseAll>
1212
<Accordion.Panel>
@@ -83,7 +83,7 @@ function Component() {
8383
const codeRSC = `
8484
import { Accordion, AccordionContent, AccordionPanel, AccordionTitle } from "flowbite-react";
8585
86-
function Component() {
86+
export function Component() {
8787
return (
8888
<Accordion collapseAll>
8989
<AccordionPanel>
@@ -157,7 +157,7 @@ function Component() {
157157
}
158158
`;
159159

160-
function Component() {
160+
export function Component() {
161161
return (
162162
<Accordion collapseAll>
163163
<AccordionPanel>

0 commit comments

Comments
 (0)