diff --git a/README.md b/README.md index 40e700a90..abf01219f 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Total Downloads - Version + Version

@@ -22,7 +22,7 @@ Total Downloads - Version + Version

diff --git a/docs-content/html/gallery/default-gallery.tsx b/docs-content/html/gallery/default-gallery.tsx new file mode 100644 index 000000000..8b64fef79 --- /dev/null +++ b/docs-content/html/gallery/default-gallery.tsx @@ -0,0 +1,69 @@ +export function DefaultGallery() { + return ( +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ ); +} diff --git a/docs-content/html/gallery/featured-image-gallery.tsx b/docs-content/html/gallery/featured-image-gallery.tsx new file mode 100644 index 000000000..8719463bc --- /dev/null +++ b/docs-content/html/gallery/featured-image-gallery.tsx @@ -0,0 +1,51 @@ +import React from "react"; +export function FeaturedImageGallery() { + return ( +
+
+ +
+
+
+ gallery-image +
+
+ gallery-image +
+
+ gallery-image +
+
+ gallery-image +
+
+ gallery-image +
+
+
+ ); +} diff --git a/docs-content/html/gallery/gallery-with-tab.tsx b/docs-content/html/gallery/gallery-with-tab.tsx new file mode 100644 index 000000000..6db5111f7 --- /dev/null +++ b/docs-content/html/gallery/gallery-with-tab.tsx @@ -0,0 +1,200 @@ +export function GalleryWithTab() { + return ( +
+
+ +
+
+
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+
+
+
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+
+
+
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+ +
+ image-photo +
+
+
+
+
+
+ ); +} diff --git a/docs-content/html/gallery/index.ts b/docs-content/html/gallery/index.ts new file mode 100644 index 000000000..f3fd84ad0 --- /dev/null +++ b/docs-content/html/gallery/index.ts @@ -0,0 +1,5 @@ +export * from "./default-gallery"; +export * from "./masonry-grid-gallery"; +export * from "./featured-image-gallery"; +export * from "./quad-gallery"; +export * from "./gallery-with-tab"; diff --git a/docs-content/html/gallery/masonry-grid-gallery.tsx b/docs-content/html/gallery/masonry-grid-gallery.tsx new file mode 100644 index 000000000..d21c0d775 --- /dev/null +++ b/docs-content/html/gallery/masonry-grid-gallery.tsx @@ -0,0 +1,91 @@ +export function MasonryGridGallery() { + return ( +
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+ ); +} diff --git a/docs-content/html/gallery/quad-gallery.tsx b/docs-content/html/gallery/quad-gallery.tsx new file mode 100644 index 000000000..8ce8c1fd2 --- /dev/null +++ b/docs-content/html/gallery/quad-gallery.tsx @@ -0,0 +1,36 @@ +export function QuadGallery() { + return ( +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ ); +} diff --git a/docs-content/html/mega-menu/index.ts b/docs-content/html/mega-menu/index.ts new file mode 100644 index 000000000..9a3c77c54 --- /dev/null +++ b/docs-content/html/mega-menu/index.ts @@ -0,0 +1 @@ +export * from "./mega-menu"; diff --git a/docs-content/html/mega-menu/mega-menu.tsx b/docs-content/html/mega-menu/mega-menu.tsx new file mode 100644 index 000000000..05fcbec25 --- /dev/null +++ b/docs-content/html/mega-menu/mega-menu.tsx @@ -0,0 +1,394 @@ +export function MegaMenuDefault() { + return ( + <> + + + + ); +} diff --git a/docs-content/html/plugins/clipboard/clipboard-default.tsx b/docs-content/html/plugins/clipboard/clipboard-default.tsx new file mode 100644 index 000000000..638c2fcfe --- /dev/null +++ b/docs-content/html/plugins/clipboard/clipboard-default.tsx @@ -0,0 +1,30 @@ +import React from "react"; +import { IconButton, Typography } from "@material-tailwind/react"; +import { useCopyToClipboard } from "usehooks-ts"; +import { CheckIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; + +export function ClipboardDefault() { + const [value, copy] = useCopyToClipboard(); + const [copied, setCopied] = React.useState(false); + + return ( +
+
+ npm i @material-tailwind + setCopied(false)} + onClick={() => { + copy("npm i @material-tailwind"); + setCopied(true); + }} + > + {copied ? ( + + ) : ( + + )} + +
+
+ ); +} diff --git a/docs-content/html/plugins/index.ts b/docs-content/html/plugins/index.ts index d48d75738..9e751f884 100644 --- a/docs-content/html/plugins/index.ts +++ b/docs-content/html/plugins/index.ts @@ -1 +1,3 @@ export * from "./date-picker"; +export * from "./text-editor"; +export * from "./clipboard/clipboard-default"; diff --git a/docs-content/html/plugins/test.html b/docs-content/html/plugins/test.html new file mode 100644 index 000000000..14e9542e7 --- /dev/null +++ b/docs-content/html/plugins/test.html @@ -0,0 +1,21 @@ +
+
+
+ +
+
+ +
\ No newline at end of file diff --git a/docs-content/html/plugins/text-editor.tsx b/docs-content/html/plugins/text-editor.tsx new file mode 100644 index 000000000..f6de613e3 --- /dev/null +++ b/docs-content/html/plugins/text-editor.tsx @@ -0,0 +1,421 @@ +import React from "react"; +import { Editor } from "@tiptap/core"; +import Placeholder from "@tiptap/extension-placeholder"; +import StarterKit from "@tiptap/starter-kit"; +import Paragraph from "@tiptap/extension-paragraph"; +import Bold from "@tiptap/extension-bold"; +import Underline from "@tiptap/extension-underline"; +import Link from "@tiptap/extension-link"; +import BulletList from "@tiptap/extension-bullet-list"; +import OrderedList from "@tiptap/extension-ordered-list"; +import Blockquote from "@tiptap/extension-blockquote"; + +export function TextEditor() { + React.useEffect(() => { + const editor = new Editor({ + element: document.querySelector( + "#hs-editor-tiptap [data-hs-editor-field]", + ), + extensions: [ + Placeholder.configure({ + placeholder: "Play around with the editor...", + emptyNodeClass: "text-gray-600", + }), + StarterKit, + Paragraph.configure({ + HTMLAttributes: { + class: "text-gray-600", + }, + }), + Bold.configure({ + HTMLAttributes: { + class: "font-bold", + }, + }), + Underline, + Link.configure({ + HTMLAttributes: { + class: + "inline-flex items-center gap-x-1 text-blue-500 decoration-2 hover:underline font-medium", + }, + }), + BulletList.configure({ + HTMLAttributes: { + class: "list-disc list-inside text-gray-800", + }, + }), + OrderedList.configure({ + HTMLAttributes: { + class: "list-decimal list-inside text-gray-800", + }, + }), + Blockquote.configure({ + HTMLAttributes: { + class: "text-gray-800 sm:text-xl", + }, + }), + ], + }); + const actions = [ + { + id: "#hs-editor-tiptap [data-hs-editor-bold]", + fn: () => editor.chain().focus().toggleBold().run(), + }, + { + id: "#hs-editor-tiptap [data-hs-editor-italic]", + fn: () => editor.chain().focus().toggleItalic().run(), + }, + { + id: "#hs-editor-tiptap [data-hs-editor-underline]", + fn: () => editor.chain().focus().toggleUnderline().run(), + }, + { + id: "#hs-editor-tiptap [data-hs-editor-strike]", + fn: () => editor.chain().focus().toggleStrike().run(), + }, + { + id: "#hs-editor-tiptap [data-hs-editor-link]", + fn: () => { + const url = window.prompt("URL"); + editor + .chain() + .focus() + .extendMarkRange("link") + .setLink({ href: url }) + .run(); + }, + }, + { + id: "#hs-editor-tiptap [data-hs-editor-ol]", + fn: () => editor.chain().focus().toggleOrderedList().run(), + }, + { + id: "#hs-editor-tiptap [data-hs-editor-ul]", + fn: () => editor.chain().focus().toggleBulletList().run(), + }, + { + id: "#hs-editor-tiptap [data-hs-editor-blockquote]", + fn: () => editor.chain().focus().toggleBlockquote().run(), + }, + { + id: "#hs-editor-tiptap [data-hs-editor-code]", + fn: () => editor.chain().focus().toggleCode().run(), + }, + ]; + + actions.forEach(({ id, fn }) => { + const action = document.querySelector(id); + + if (action === null) return; + + action.addEventListener("click", fn); + }); + }, []); + + return ( +
+
+
+ + + + + + + + +
+
+
+
+ ); +} diff --git a/docs-content/html/skeleton/card-placeholder-skeleton.tsx b/docs-content/html/skeleton/card-placeholder-skeleton.tsx new file mode 100644 index 000000000..f9d80c1be --- /dev/null +++ b/docs-content/html/skeleton/card-placeholder-skeleton.tsx @@ -0,0 +1,47 @@ +export function CardPlacehoderSkeleton() { + return ( +
+
+ + + +
+
+
+   +
+
+   +
+
+   +
+
+   +
+
+   +
+
+
+ +
+
+ ); +} diff --git a/docs-content/html/skeleton/default-skeleton.tsx b/docs-content/html/skeleton/default-skeleton.tsx new file mode 100644 index 000000000..5ee52d3d5 --- /dev/null +++ b/docs-content/html/skeleton/default-skeleton.tsx @@ -0,0 +1,21 @@ +export function DefaultSkeleton() { + return ( +
+
+   +
+
+   +
+
+   +
+
+   +
+
+   +
+
+ ); +} diff --git a/docs-content/html/skeleton/image-placeholder-skeleton.tsx b/docs-content/html/skeleton/image-placeholder-skeleton.tsx new file mode 100644 index 000000000..221efc4cf --- /dev/null +++ b/docs-content/html/skeleton/image-placeholder-skeleton.tsx @@ -0,0 +1,45 @@ +export function ImagePlacehoderSkeleton() { + return ( +
+
+ + + +
+
+
+   +
+
+   +
+
+   +
+
+   +
+
+   +
+
+   +
+
+   +
+
+
+ ); +} diff --git a/docs-content/html/skeleton/index.ts b/docs-content/html/skeleton/index.ts new file mode 100644 index 000000000..84a69c265 --- /dev/null +++ b/docs-content/html/skeleton/index.ts @@ -0,0 +1,4 @@ +export * from "./default-skeleton"; +export * from "./image-placeholder-skeleton"; +export * from "./video-placeholder-skeleton"; +export * from "./card-placeholder-skeleton"; diff --git a/docs-content/html/skeleton/video-placeholder-skeleton.tsx b/docs-content/html/skeleton/video-placeholder-skeleton.tsx new file mode 100644 index 000000000..948871af3 --- /dev/null +++ b/docs-content/html/skeleton/video-placeholder-skeleton.tsx @@ -0,0 +1,20 @@ +export function VideoPlacehoderSkeleton() { + return ( +
+ + + +
+ ); +} diff --git a/docs-content/react/gallery/default-gallery.tsx b/docs-content/react/gallery/default-gallery.tsx new file mode 100644 index 000000000..7fed763b7 --- /dev/null +++ b/docs-content/react/gallery/default-gallery.tsx @@ -0,0 +1,54 @@ +export function DefaultGallery() { + const data = [ + { + imageLink: + "https://images.unsplash.com/photo-1499696010180-025ef6e1a8f9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1432462770865-65b70566d673?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1497436072909-60f360e1d4b1?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2560&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + { + imageLink: + "https://demos.creative-tim.com/material-kit-pro/assets/img/examples/blog5.jpg", + }, + { + imageLink: + "https://material-taillwind-pro-ct-tailwind-team.vercel.app/img/content2.jpg", + }, + { + imageLink: + "https://images.unsplash.com/photo-1620064916958-605375619af8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1493&q=80", + }, + ]; + + return ( +
+ {data.map(({ imageLink }, index) => ( +
+ gallery-photo +
+ ))} +
+ ); +} diff --git a/docs-content/react/gallery/featured-image-gallery.tsx b/docs-content/react/gallery/featured-image-gallery.tsx new file mode 100644 index 000000000..bc82a3fbc --- /dev/null +++ b/docs-content/react/gallery/featured-image-gallery.tsx @@ -0,0 +1,53 @@ +import React from "react"; +export function FeaturedImageGallery() { + const data = [ + { + imgelink: + "https://images.unsplash.com/photo-1499696010180-025ef6e1a8f9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80", + }, + { + imgelink: + "https://images.unsplash.com/photo-1432462770865-65b70566d673?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80", + }, + { + imgelink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imgelink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imgelink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + ]; + + const [active, setActive] = React.useState( + "https://images.unsplash.com/photo-1499696010180-025ef6e1a8f9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80", + ); + + return ( +
+
+ +
+
+ {data.map(({ imgelink }, index) => ( +
+ setActive(imgelink)} + src={imgelink} + className="h-20 max-w-full cursor-pointer rounded-lg object-cover object-center" + alt="gallery-image" + /> +
+ ))} +
+
+ ); +} diff --git a/docs-content/react/gallery/gallery-with-carousel.tsx b/docs-content/react/gallery/gallery-with-carousel.tsx new file mode 100644 index 000000000..bf4739e15 --- /dev/null +++ b/docs-content/react/gallery/gallery-with-carousel.tsx @@ -0,0 +1,23 @@ +import { Carousel } from "@material-tailwind/react"; + +export function GalleryWithCarousel() { + return ( + + image 1 + image 2 + image 3 + + ); +} diff --git a/docs-content/react/gallery/gallery-with-tab.tsx b/docs-content/react/gallery/gallery-with-tab.tsx new file mode 100644 index 000000000..62f97b9f7 --- /dev/null +++ b/docs-content/react/gallery/gallery-with-tab.tsx @@ -0,0 +1,193 @@ +import { + Tabs, + TabsHeader, + TabsBody, + Tab, + TabPanel, +} from "@material-tailwind/react"; + +export function GalleryWithTab() { + const data = [ + { + label: "HTML", + value: "html", + images: [ + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + { + imageLink: + "https://demos.creative-tim.com/material-kit-pro/assets/img/examples/blog5.jpg", + }, + { + imageLink: + "https://material-taillwind-pro-ct-tailwind-team.vercel.app/img/content2.jpg", + }, + { + imageLink: + "https://images.unsplash.com/photo-1620064916958-605375619af8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1493&q=80", + }, + ], + }, + { + label: "React", + value: "react", + images: [ + { + imageLink: + "https://images.unsplash.com/photo-1499696010180-025ef6e1a8f9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1432462770865-65b70566d673?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1497436072909-60f360e1d4b1?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2560&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + ], + }, + { + label: "Vue", + value: "vue", + images: [ + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + { + imageLink: + "https://demos.creative-tim.com/material-kit-pro/assets/img/examples/blog5.jpg", + }, + { + imageLink: + "https://material-taillwind-pro-ct-tailwind-team.vercel.app/img/content2.jpg", + }, + { + imageLink: + "https://images.unsplash.com/photo-1620064916958-605375619af8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1493&q=80", + }, + ], + }, + { + label: "Angular", + value: "angular", + images: [ + { + imageLink: + "https://images.unsplash.com/photo-1499696010180-025ef6e1a8f9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1432462770865-65b70566d673?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1497436072909-60f360e1d4b1?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2560&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + ], + }, + { + label: "Svelte", + value: "svelte", + images: [ + { + imageLink: + "https://demos.creative-tim.com/material-kit-pro/assets/img/examples/blog5.jpg", + }, + { + imageLink: + "https://material-taillwind-pro-ct-tailwind-team.vercel.app/img/content2.jpg", + }, + { + imageLink: + "https://images.unsplash.com/photo-1620064916958-605375619af8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1493&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + ], + }, + ]; + + return ( + + + {data.map(({ label, value }) => ( + + {label} + + ))} + + + {data.map(({ value, images }) => ( + + {images?.map(({ imageLink }, index) => ( +
+ image-photo +
+ ))} +
+ ))} +
+
+ ); +} diff --git a/docs-content/react/gallery/index.ts b/docs-content/react/gallery/index.ts new file mode 100644 index 000000000..29f71ed07 --- /dev/null +++ b/docs-content/react/gallery/index.ts @@ -0,0 +1,6 @@ +export * from "./default-gallery"; +export * from "./masonry-grid-gallery"; +export * from "./featured-image-gallery"; +export * from "./quad-gallery"; +export * from "./gallery-with-carousel"; +export * from "./gallery-with-tab"; diff --git a/docs-content/react/gallery/masonry-grid-gallery.tsx b/docs-content/react/gallery/masonry-grid-gallery.tsx new file mode 100644 index 000000000..ba885c930 --- /dev/null +++ b/docs-content/react/gallery/masonry-grid-gallery.tsx @@ -0,0 +1,91 @@ +export function MasonryGridGallery() { + return ( +
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+ ); +} diff --git a/docs-content/react/gallery/quad-gallery.tsx b/docs-content/react/gallery/quad-gallery.tsx new file mode 100644 index 000000000..9f1f71b2f --- /dev/null +++ b/docs-content/react/gallery/quad-gallery.tsx @@ -0,0 +1,34 @@ +export function QuadGallery() { + const data = [ + { + imageLink: + "https://images.unsplash.com/photo-1499696010180-025ef6e1a8f9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1432462770865-65b70566d673?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1497436072909-60f360e1d4b1?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2560&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + ]; + + return ( +
+ {data.map(({ imageLink }, index) => ( +
+ +
+ ))} +
+ ); +} diff --git a/docs-content/react/mega-menu/index.ts b/docs-content/react/mega-menu/index.ts new file mode 100644 index 000000000..9da29892a --- /dev/null +++ b/docs-content/react/mega-menu/index.ts @@ -0,0 +1,3 @@ +export * from "./mega-menu"; +export * from "./mega-menu-with-hover"; +export * from "./mega-menu-placement"; diff --git a/docs-content/react/mega-menu/mega-menu-placement.tsx b/docs-content/react/mega-menu/mega-menu-placement.tsx new file mode 100644 index 000000000..0f81c4cb8 --- /dev/null +++ b/docs-content/react/mega-menu/mega-menu-placement.tsx @@ -0,0 +1,210 @@ +import React from "react"; +import { + Navbar, + Collapse, + Typography, + IconButton, + List, + ListItem, + Menu, + MenuHandler, + MenuList, + MenuItem, +} from "@material-tailwind/react"; +import { + ChevronDownIcon, + Bars3Icon, + XMarkIcon, +} from "@heroicons/react/24/outline"; +import { + Bars4Icon, + GlobeAmericasIcon, + PhoneIcon, + SquaresPlusIcon, + SunIcon, + UserGroupIcon, +} from "@heroicons/react/24/solid"; + +const navListMenuItems = [ + { + title: "Products", + description: "Find the perfect solution for your needs.", + icon: SquaresPlusIcon, + }, + { + title: "About Us", + description: "Meet and learn about our dedication", + icon: UserGroupIcon, + }, + { + title: "Blog", + description: "Find the perfect solution for your needs.", + icon: Bars4Icon, + }, + { + title: "Services", + description: "Learn how we can help you achieve your goals.", + icon: SunIcon, + }, + { + title: "Support", + description: "Reach out to us for assistance or inquiries", + icon: GlobeAmericasIcon, + }, + { + title: "Contact", + description: "Find the perfect solution for your needs.", + icon: PhoneIcon, + }, +]; + +function NavListMenu() { + const [isMenuOpen, setIsMenuOpen] = React.useState(false); + const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false); + const renderItems = navListMenuItems.map( + ({ icon, title, description }, key) => ( + + +
+ {" "} + {React.createElement(icon, { + strokeWidth: 2, + className: "h-6 text-gray-900 w-6", + })} +
+
+ + {title} + + + {description} + +
+
+
+ ), + ); + + return ( + + + + + setIsMobileMenuOpen((cur) => !cur)} + > + Resources + + + + + + +
    + {renderItems} +
+
+
+
+ {renderItems} +
+
+ ); +} + +function NavList() { + return ( + + + Home + + + + + Contact Us + + + + ); +} + +export function MegaMenuWithPlacement() { + const [openNav, setOpenNav] = React.useState(false); + + React.useEffect(() => { + window.addEventListener( + "resize", + () => window.innerWidth >= 960 && setOpenNav(false), + ); + }, []); + + return ( + +
+ + Material Tailwind + +
+ +
+ setOpenNav(!openNav)} + > + {openNav ? ( + + ) : ( + + )} + +
+ + + +
+ ); +} diff --git a/docs-content/react/mega-menu/mega-menu-with-hover.tsx b/docs-content/react/mega-menu/mega-menu-with-hover.tsx new file mode 100644 index 000000000..407ae81bb --- /dev/null +++ b/docs-content/react/mega-menu/mega-menu-with-hover.tsx @@ -0,0 +1,228 @@ +import React from "react"; +import { + Navbar, + Collapse, + Typography, + IconButton, + List, + ListItem, + Menu, + MenuHandler, + MenuList, + MenuItem, +} from "@material-tailwind/react"; +import { + ChevronDownIcon, + Bars3Icon, + XMarkIcon, +} from "@heroicons/react/24/outline"; +import { + Bars4Icon, + GlobeAmericasIcon, + NewspaperIcon, + PhoneIcon, + RectangleGroupIcon, + SquaresPlusIcon, + SunIcon, + TagIcon, + UserGroupIcon, +} from "@heroicons/react/24/solid"; + +const navListMenuItems = [ + { + title: "Products", + description: "Find the perfect solution for your needs.", + icon: SquaresPlusIcon, + }, + { + title: "About Us", + description: "Meet and learn about our dedication", + icon: UserGroupIcon, + }, + { + title: "Blog", + description: "Find the perfect solution for your needs.", + icon: Bars4Icon, + }, + { + title: "Services", + description: "Learn how we can help you achieve your goals.", + icon: SunIcon, + }, + { + title: "Support", + description: "Reach out to us for assistance or inquiries", + icon: GlobeAmericasIcon, + }, + { + title: "Contact", + description: "Find the perfect solution for your needs.", + icon: PhoneIcon, + }, + { + title: "News", + description: "Read insightful articles, tips, and expert opinions.", + icon: NewspaperIcon, + }, + { + title: "Products", + description: "Find the perfect solution for your needs.", + icon: RectangleGroupIcon, + }, + { + title: "Special Offers", + description: "Explore limited-time deals and bundles", + icon: TagIcon, + }, +]; + +function NavListMenu() { + const [isMenuOpen, setIsMenuOpen] = React.useState(false); + const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false); + const renderItems = navListMenuItems.map( + ({ icon, title, description }, key) => ( + + +
+ {" "} + {React.createElement(icon, { + strokeWidth: 2, + className: "h-6 text-gray-900 w-6", + })} +
+
+ + {title} + + + {description} + +
+
+
+ ), + ); + + return ( + + + + + setIsMobileMenuOpen((cur) => !cur)} + > + Resources + + + + + + +
    + {renderItems} +
+
+
+
+ {renderItems} +
+
+ ); +} + +function NavList() { + return ( + + + Home + + + + + Contact Us + + + + ); +} + +export function MegaMenuWithHover() { + const [openNav, setOpenNav] = React.useState(false); + + React.useEffect(() => { + window.addEventListener( + "resize", + () => window.innerWidth >= 960 && setOpenNav(false), + ); + }, []); + + return ( + +
+ + Material Tailwind + +
+ +
+ setOpenNav(!openNav)} + > + {openNav ? ( + + ) : ( + + )} + +
+ + + +
+ ); +} diff --git a/docs-content/react/mega-menu/mega-menu.tsx b/docs-content/react/mega-menu/mega-menu.tsx new file mode 100644 index 000000000..5c0641b8a --- /dev/null +++ b/docs-content/react/mega-menu/mega-menu.tsx @@ -0,0 +1,227 @@ +import React from "react"; +import { + Navbar, + Collapse, + Typography, + IconButton, + List, + ListItem, + Menu, + MenuHandler, + MenuList, + MenuItem, +} from "@material-tailwind/react"; +import { + ChevronDownIcon, + Bars3Icon, + XMarkIcon, +} from "@heroicons/react/24/outline"; +import { + Bars4Icon, + GlobeAmericasIcon, + NewspaperIcon, + PhoneIcon, + RectangleGroupIcon, + SquaresPlusIcon, + SunIcon, + TagIcon, + UserGroupIcon, +} from "@heroicons/react/24/solid"; + +const navListMenuItems = [ + { + title: "Products", + description: "Find the perfect solution for your needs.", + icon: SquaresPlusIcon, + }, + { + title: "About Us", + description: "Meet and learn about our dedication", + icon: UserGroupIcon, + }, + { + title: "Blog", + description: "Find the perfect solution for your needs.", + icon: Bars4Icon, + }, + { + title: "Services", + description: "Learn how we can help you achieve your goals.", + icon: SunIcon, + }, + { + title: "Support", + description: "Reach out to us for assistance or inquiries", + icon: GlobeAmericasIcon, + }, + { + title: "Contact", + description: "Find the perfect solution for your needs.", + icon: PhoneIcon, + }, + { + title: "News", + description: "Read insightful articles, tips, and expert opinions.", + icon: NewspaperIcon, + }, + { + title: "Products", + description: "Find the perfect solution for your needs.", + icon: RectangleGroupIcon, + }, + { + title: "Special Offers", + description: "Explore limited-time deals and bundles", + icon: TagIcon, + }, +]; + +function NavListMenu() { + const [isMenuOpen, setIsMenuOpen] = React.useState(false); + const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false); + const renderItems = navListMenuItems.map( + ({ icon, title, description }, key) => ( + + +
+ {" "} + {React.createElement(icon, { + strokeWidth: 2, + className: "h-6 text-gray-900 w-6", + })} +
+
+ + {title} + + + {description} + +
+
+
+ ), + ); + + return ( + + + + + setIsMobileMenuOpen((cur) => !cur)} + > + Resources + + + + + + +
    + {renderItems} +
+
+
+
+ {renderItems} +
+
+ ); +} + +function NavList() { + return ( + + + Home + + + + + Contact Us + + + + ); +} + +export function MegaMenuDefault() { + const [openNav, setOpenNav] = React.useState(false); + + React.useEffect(() => { + window.addEventListener( + "resize", + () => window.innerWidth >= 960 && setOpenNav(false), + ); + }, []); + + return ( + +
+ + Material Tailwind + +
+ +
+ setOpenNav(!openNav)} + > + {openNav ? ( + + ) : ( + + )} + +
+ + + +
+ ); +} diff --git a/docs-content/react/plugins/clipboard/clipboard-copy-button.tsx b/docs-content/react/plugins/clipboard/clipboard-copy-button.tsx new file mode 100644 index 000000000..1b63a6f1d --- /dev/null +++ b/docs-content/react/plugins/clipboard/clipboard-copy-button.tsx @@ -0,0 +1,32 @@ +import React from "react"; +import { Typography, Button } from "@material-tailwind/react"; +import { useCopyToClipboard } from "usehooks-ts"; +import { CheckIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; + +export function ClipboardCopyButton() { + const [value, copy] = useCopyToClipboard(); + const [copied, setCopied] = React.useState(false); + + return ( + + ); +} diff --git a/docs-content/react/plugins/clipboard/clipboard-copy-input.tsx b/docs-content/react/plugins/clipboard/clipboard-copy-input.tsx new file mode 100644 index 000000000..30ed7b438 --- /dev/null +++ b/docs-content/react/plugins/clipboard/clipboard-copy-input.tsx @@ -0,0 +1,53 @@ +import React from "react"; +import { Input, Button } from "@material-tailwind/react"; +import { useCopyToClipboard } from "usehooks-ts"; +import { CheckIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; + +export function ClipboardCopyInput() { + const [value, copy] = useCopyToClipboard(); + const [copied, setCopied] = React.useState(false); + const [inputValue, setInputValue] = React.useState( + "npm i @material-tailwind/react", + ); + + return ( +
+
+ { + setInputValue(e.target.value); + }} + containerProps={{ className: "min-w-[100px]" }} + /> +
+ +
+ ); +} diff --git a/docs-content/react/plugins/clipboard/clipboard-default.tsx b/docs-content/react/plugins/clipboard/clipboard-default.tsx new file mode 100644 index 000000000..c85d5f944 --- /dev/null +++ b/docs-content/react/plugins/clipboard/clipboard-default.tsx @@ -0,0 +1,30 @@ +import React from "react"; +import { IconButton, Typography } from "@material-tailwind/react"; +import { useCopyToClipboard } from "usehooks-ts"; +import { CheckIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; + +export function ClipboardDefault() { + const [value, copy] = useCopyToClipboard(); + const [copied, setCopied] = React.useState(false); + + return ( +
+
+ npm i @material-tailwind/react + setCopied(false)} + onClick={() => { + copy("npm i @material-tailwind/react"); + setCopied(true); + }} + > + {copied ? ( + + ) : ( + + )} + +
+
+ ); +} diff --git a/docs-content/react/plugins/clipboard/clipboard-with-tooltip.tsx b/docs-content/react/plugins/clipboard/clipboard-with-tooltip.tsx new file mode 100644 index 000000000..e92e636d6 --- /dev/null +++ b/docs-content/react/plugins/clipboard/clipboard-with-tooltip.tsx @@ -0,0 +1,34 @@ +import React from "react"; +import { Typography, Button, Tooltip } from "@material-tailwind/react"; +import { useCopyToClipboard } from "usehooks-ts"; +import { CheckIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; + +export function ClipboardWithTooltip() { + const [value, copy] = useCopyToClipboard(); + const [copied, setCopied] = React.useState(false); + + return ( + + + + ); +} diff --git a/docs-content/react/plugins/index.ts b/docs-content/react/plugins/index.ts index 891531dba..6a1246ca8 100644 --- a/docs-content/react/plugins/index.ts +++ b/docs-content/react/plugins/index.ts @@ -3,3 +3,8 @@ export * from "./algolia-search"; export * from "./charts/line-chart"; export * from "./charts/bar-chart"; export * from "./charts/pie-chart"; +export * from "./clipboard/clipboard-default"; +export * from "./clipboard/clipboard-copy-input"; +export * from "./clipboard/clipboard-copy-button"; +export * from "./clipboard/clipboard-with-tooltip"; +export * from "./text-editor-react"; diff --git a/docs-content/react/plugins/text-editor-react.tsx b/docs-content/react/plugins/text-editor-react.tsx new file mode 100644 index 000000000..e7ad7d9c4 --- /dev/null +++ b/docs-content/react/plugins/text-editor-react.tsx @@ -0,0 +1,1058 @@ +import { createPortal } from "react-dom"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { + List, + Input, + Button, + ListItem, + IconButton, + Typography, + ListItemPrefix, +} from "@material-tailwind/react"; + +// lexical +import { + $getNodeByKey, + $getSelection, + $isRangeSelection, + FORMAT_TEXT_COMMAND, + $createParagraphNode, + SELECTION_CHANGE_COMMAND, +} from "lexical"; +import { + $isListNode, + REMOVE_LIST_COMMAND, + INSERT_ORDERED_LIST_COMMAND, + INSERT_UNORDERED_LIST_COMMAND, +} from "@lexical/list"; +import { + QuoteNode, + HeadingNode, + $isHeadingNode, + $createQuoteNode, + $createHeadingNode, +} from "@lexical/rich-text"; +import { + $isCodeNode, + $createCodeNode, + getCodeLanguages, + getDefaultCodeLanguage, +} from "@lexical/code"; +import { ListItemNode, ListNode } from "@lexical/list"; +import { + AutoLinkNode, + LinkNode, + $isLinkNode, + TOGGLE_LINK_COMMAND, +} from "@lexical/link"; +import { CodeHighlightNode, CodeNode } from "@lexical/code"; +import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin"; +import { ListPlugin } from "@lexical/react/LexicalListPlugin"; +import { $wrapNodes, $isAtNodeEnd } from "@lexical/selection"; +import { LexicalComposer } from "@lexical/react/LexicalComposer"; +import { $getNearestNodeOfType, mergeRegister } from "@lexical/utils"; +import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin"; +import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin"; +import { ContentEditable } from "@lexical/react/LexicalContentEditable"; +import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext"; + +const LowPriority = 1; + +const supportedBlockTypes = new Set([ + "paragraph", + "quote", + "code", + "h1", + "h2", + "ul", + "ol", +]); + +const blockTypeToBlockName = { + code: "Code", + h1: "Large Heading", + h2: "Small Heading", + h3: "Heading", + h4: "Heading", + h5: "Heading", + ol: "Numbered List", + paragraph: "Normal", + quote: "Quote", + ul: "Bulleted List", +}; + +function Divider() { + return
; +} + +function Placeholder() { + return ( +
+ Play around with the editor... +
+ ); +} + +function Select({ onChange, className, options, value }) { + return ( + + ); +} + +function getSelectedNode(selection) { + const anchor = selection.anchor; + const focus = selection.focus; + const anchorNode = selection.anchor.getNode(); + const focusNode = selection.focus.getNode(); + if (anchorNode === focusNode) { + return anchorNode; + } + const isBackward = selection.isBackward(); + if (isBackward) { + return $isAtNodeEnd(focus) ? anchorNode : focusNode; + } else { + return $isAtNodeEnd(anchor) ? focusNode : anchorNode; + } +} + +function BlockOptionsDropdownList({ + editor, + blockType, + toolbarRef, + setShowBlockOptionsDropDown, +}) { + const dropDownRef = useRef(null); + + useEffect(() => { + const toolbar = toolbarRef.current; + const dropDown = dropDownRef.current; + + if (toolbar !== null && dropDown !== null) { + const { top, left } = toolbar.getBoundingClientRect(); + dropDown.style.top = `${top + 40}px`; + dropDown.style.left = `${left}px`; + } + }, [dropDownRef, toolbarRef]); + + useEffect(() => { + const dropDown = dropDownRef.current; + const toolbar = toolbarRef.current; + + if (dropDown !== null && toolbar !== null) { + const handle = (event) => { + const target = event.target; + + if (!dropDown.contains(target) && !toolbar.contains(target)) { + setShowBlockOptionsDropDown(false); + } + }; + document.addEventListener("click", handle); + + return () => { + document.removeEventListener("click", handle); + }; + } + }, [dropDownRef, setShowBlockOptionsDropDown, toolbarRef]); + + const formatParagraph = () => { + if (blockType !== "paragraph") { + editor.update(() => { + const selection = $getSelection(); + + if ($isRangeSelection(selection)) { + $wrapNodes(selection, () => $createParagraphNode()); + } + }); + } + setShowBlockOptionsDropDown(false); + }; + + const formatLargeHeading = () => { + if (blockType !== "h1") { + editor.update(() => { + const selection = $getSelection(); + + if ($isRangeSelection(selection)) { + $wrapNodes(selection, () => $createHeadingNode("h1")); + } + }); + } + setShowBlockOptionsDropDown(false); + }; + + const formatSmallHeading = () => { + if (blockType !== "h2") { + editor.update(() => { + const selection = $getSelection(); + + if ($isRangeSelection(selection)) { + $wrapNodes(selection, () => $createHeadingNode("h2")); + } + }); + } + setShowBlockOptionsDropDown(false); + }; + + const formatBulletList = () => { + if (blockType !== "ul") { + editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND); + } else { + editor.dispatchCommand(REMOVE_LIST_COMMAND); + } + setShowBlockOptionsDropDown(false); + }; + + const formatNumberedList = () => { + if (blockType !== "ol") { + editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND); + } else { + editor.dispatchCommand(REMOVE_LIST_COMMAND); + } + setShowBlockOptionsDropDown(false); + }; + + const formatQuote = () => { + if (blockType !== "quote") { + editor.update(() => { + const selection = $getSelection(); + + if ($isRangeSelection(selection)) { + $wrapNodes(selection, () => $createQuoteNode()); + } + }); + } + setShowBlockOptionsDropDown(false); + }; + + const formatCode = () => { + if (blockType !== "code") { + editor.update(() => { + const selection = $getSelection(); + + if ($isRangeSelection(selection)) { + $wrapNodes(selection, () => $createCodeNode()); + } + }); + } + setShowBlockOptionsDropDown(false); + }; + + return ( + + + + + + + + + Normal + + + + + + + + + + Large Heading + + + + + + + + + + + Small Heading + + + + + + + + + + + + + Bullet List + + + + + + + + + + + + + + Numbered List + + + + + + + + + Quote + + + + + + + + + + Code + + + ); +} + +function positionEditorElement(editor, rect) { + if (rect === null) { + editor.style.opacity = "0"; + editor.style.top = "-1000px"; + editor.style.left = "-1000px"; + } else { + editor.style.opacity = "1"; + editor.style.top = `${rect.top + rect.height + window.pageYOffset + 10}px`; + editor.style.left = `${ + rect.left + window.pageXOffset - editor.offsetWidth / 2 + rect.width / 2 + }px`; + } +} + +function FloatingLinkEditor({ editor }) { + const editorRef = useRef(null); + const inputRef = useRef(null); + const mouseDownRef = useRef(false); + const [linkUrl, setLinkUrl] = useState(""); + const [isEditMode, setEditMode] = useState(false); + const [lastSelection, setLastSelection] = useState(null); + + const updateLinkEditor = useCallback(() => { + const selection = $getSelection(); + if ($isRangeSelection(selection)) { + const node = getSelectedNode(selection); + const parent = node.getParent(); + if ($isLinkNode(parent)) { + setLinkUrl(parent.getURL()); + } else if ($isLinkNode(node)) { + setLinkUrl(node.getURL()); + } else { + setLinkUrl(""); + } + } + const editorElem = editorRef.current; + const nativeSelection = window.getSelection(); + const activeElement = document.activeElement; + + if (editorElem === null) { + return; + } + + const rootElement = editor.getRootElement(); + if ( + selection !== null && + !nativeSelection.isCollapsed && + rootElement !== null && + rootElement.contains(nativeSelection.anchorNode) + ) { + const domRange = nativeSelection.getRangeAt(0); + let rect; + if (nativeSelection.anchorNode === rootElement) { + let inner = rootElement; + while (inner.firstElementChild != null) { + inner = inner.firstElementChild; + } + rect = inner.getBoundingClientRect(); + } else { + rect = domRange.getBoundingClientRect(); + } + + if (!mouseDownRef.current) { + positionEditorElement(editorElem, rect); + } + setLastSelection(selection); + } else if (!activeElement || activeElement.className !== "link-input") { + positionEditorElement(editorElem, null); + setLastSelection(null); + setEditMode(false); + setLinkUrl(""); + } + + return true; + }, [editor]); + + useEffect(() => { + return mergeRegister( + editor.registerUpdateListener(({ editorState }) => { + editorState.read(() => { + updateLinkEditor(); + }); + }), + + editor.registerCommand( + SELECTION_CHANGE_COMMAND, + () => { + updateLinkEditor(); + return true; + }, + LowPriority, + ), + ); + }, [editor, updateLinkEditor]); + + useEffect(() => { + editor.getEditorState().read(() => { + updateLinkEditor(); + }); + }, [editor, updateLinkEditor]); + + useEffect(() => { + if (isEditMode && inputRef.current) { + inputRef.current.focus(); + } + }, [isEditMode]); + + return ( +
+ {isEditMode ? ( + { + setLinkUrl(event.target.value); + }} + onKeyDown={(event) => { + if (event.key === "Enter") { + event.preventDefault(); + if (lastSelection !== null) { + if (linkUrl !== "") { + editor.dispatchCommand(TOGGLE_LINK_COMMAND, linkUrl); + } + setEditMode(false); + } + } else if (event.key === "Escape") { + event.preventDefault(); + setEditMode(false); + } + }} + className="border-gray-200 !border-t-gray-200 focus:!border-gray-900 focus:!border-t-gray-900" + labelProps={{ + className: "hidden", + }} + /> + ) : ( + <> +
+ + {linkUrl} + + event.preventDefault()} + onClick={() => { + setEditMode(true); + }} + > + + + + +
+ + )} +
+ ); +} + +function ToolbarPlugin() { + const [editor] = useLexicalComposerContext(); + const toolbarRef = useRef(null); + const [blockType, setBlockType] = useState("paragraph"); + const [selectedElementKey, setSelectedElementKey] = useState(null); + const [showBlockOptionsDropDown, setShowBlockOptionsDropDown] = + useState(false); + const [codeLanguage, setCodeLanguage] = useState(""); + const [isLink, setIsLink] = useState(false); + const [isBold, setIsBold] = useState(false); + const [isItalic, setIsItalic] = useState(false); + const [isStrikethrough, setIsStrikethrough] = useState(false); + const [isCode, setIsCode] = useState(false); + + const updateToolbar = useCallback(() => { + const selection = $getSelection(); + if ($isRangeSelection(selection)) { + const anchorNode = selection.anchor.getNode(); + const element = + anchorNode.getKey() === "root" + ? anchorNode + : anchorNode.getTopLevelElementOrThrow(); + const elementKey = element.getKey(); + const elementDOM = editor.getElementByKey(elementKey); + if (elementDOM !== null) { + setSelectedElementKey(elementKey); + if ($isListNode(element)) { + const parentList = $getNearestNodeOfType(anchorNode, ListNode); + const type = parentList ? parentList.getTag() : element.getTag(); + setBlockType(type); + } else { + const type = $isHeadingNode(element) + ? element.getTag() + : element.getType(); + setBlockType(type); + if ($isCodeNode(element)) { + setCodeLanguage(element.getLanguage() || getDefaultCodeLanguage()); + } + } + } + // Update text format + setIsBold(selection.hasFormat("bold")); + setIsItalic(selection.hasFormat("italic")); + setIsStrikethrough(selection.hasFormat("strikethrough")); + setIsCode(selection.hasFormat("code")); + + // Update links + const node = getSelectedNode(selection); + const parent = node.getParent(); + if ($isLinkNode(parent) || $isLinkNode(node)) { + setIsLink(true); + } else { + setIsLink(false); + } + } + }, [editor]); + + useEffect(() => { + return mergeRegister( + editor.registerUpdateListener(({ editorState }) => { + editorState.read(() => { + updateToolbar(); + }); + }), + editor.registerCommand( + SELECTION_CHANGE_COMMAND, + (_payload, newEditor) => { + updateToolbar(); + return false; + }, + LowPriority, + ), + ); + }, [editor, updateToolbar]); + + const codeLanguges = useMemo(() => getCodeLanguages(), []); + const onCodeLanguageSelect = useCallback( + (e) => { + editor.update(() => { + if (selectedElementKey !== null) { + const node = $getNodeByKey(selectedElementKey); + if ($isCodeNode(node)) { + node.setLanguage(e.target.value); + } + } + }); + }, + [editor, selectedElementKey], + ); + + const insertLink = useCallback(() => { + if (!isLink) { + editor.dispatchCommand(TOGGLE_LINK_COMMAND, "https://"); + } else { + editor.dispatchCommand(TOGGLE_LINK_COMMAND, null); + } + }, [editor, isLink]); + + return ( +
+ {supportedBlockTypes.has(blockType) && ( + <> + + {showBlockOptionsDropDown && + createPortal( + , + document.body, + )} + + + )} + {blockType === "code" ? ( + <> + } + label="Search" + /> +
+ + + } + > + + handleOpen(1)} + className="border-b-0 p-3" + > + + + + + Dashboard + + + + + + + + + + Analytics + + + + + + Reporting + + + + + + Projects + + + + + + } + > + + handleOpen(2)} + className="border-b-0 p-3" + > + + + + + E-Commerce + + + + + + + + + + Orders + + + + + + Products + + + + +
+ + + + + Inbox + + + + + + + + + Profile + + + + + + Settings + + + + + + Log Out + +
+ setOpenAlert(false)} + > + + + Upgrade to PRO + + + Upgrade to Material Tailwind PRO and get even more components, + plugins, advanced features and premium. + +
+ setOpenAlert(false)} + > + Dismiss + + + Upgrade Now + +
+
+ + + + ); +} diff --git a/docs-content/react/skeleton/card-placeholder-skeleton.tsx b/docs-content/react/skeleton/card-placeholder-skeleton.tsx new file mode 100644 index 000000000..352471648 --- /dev/null +++ b/docs-content/react/skeleton/card-placeholder-skeleton.tsx @@ -0,0 +1,79 @@ +import { Button, Typography } from "@material-tailwind/react"; +import Card, { + CardBody, + CardFooter, + CardHeader, +} from "packages/material-tailwind-react/src/components/Card"; + +export function CardPlacehoderSkeleton() { + return ( + + + + + + + + +   + + +   + + +   + + +   + + +   + + + + + + + ); +} diff --git a/docs-content/react/skeleton/default-skeleton.tsx b/docs-content/react/skeleton/default-skeleton.tsx new file mode 100644 index 000000000..45753c6b3 --- /dev/null +++ b/docs-content/react/skeleton/default-skeleton.tsx @@ -0,0 +1,43 @@ +import { Typography } from "@material-tailwind/react"; + +export function DefaultSkeleton() { + return ( +
+ +   + + +   + + +   + + +   + + +   + +
+ ); +} diff --git a/docs-content/react/skeleton/image-placeholder-skeleton.tsx b/docs-content/react/skeleton/image-placeholder-skeleton.tsx new file mode 100644 index 000000000..a86c9bcb9 --- /dev/null +++ b/docs-content/react/skeleton/image-placeholder-skeleton.tsx @@ -0,0 +1,75 @@ +import { Typography } from "@material-tailwind/react"; + +export function ImagePlacehoderSkeleton() { + return ( +
+
+ + + +
+
+ +   + + +   + + +   + + +   + + +   + + +   + + +   + +
+
+ ); +} diff --git a/docs-content/react/skeleton/index.ts b/docs-content/react/skeleton/index.ts new file mode 100644 index 000000000..84a69c265 --- /dev/null +++ b/docs-content/react/skeleton/index.ts @@ -0,0 +1,4 @@ +export * from "./default-skeleton"; +export * from "./image-placeholder-skeleton"; +export * from "./video-placeholder-skeleton"; +export * from "./card-placeholder-skeleton"; diff --git a/docs-content/react/skeleton/video-placeholder-skeleton.tsx b/docs-content/react/skeleton/video-placeholder-skeleton.tsx new file mode 100644 index 000000000..f24766c0d --- /dev/null +++ b/docs-content/react/skeleton/video-placeholder-skeleton.tsx @@ -0,0 +1,22 @@ +import { Typography } from "@material-tailwind/react"; + +export function VideoPlacehoderSkeleton() { + return ( +
+ + + +
+ ); +} diff --git a/documentation/html/accordion.mdx b/documentation/html/accordion.mdx index 89eb12dcc..e22364f01 100644 --- a/documentation/html/accordion.mdx +++ b/documentation/html/accordion.mdx @@ -21,7 +21,7 @@ Use our Tailwind CSS accordion component to allow the user to show and hide sect See below our simple and versatile accordion example that you can use in your Tailwind CSS projects. We also included some accordion props that are available. -To use an accordion example that has items expanded, add the .open class on the .collapse `
`. +To use an accordion example that has items expanded, add the .open class on the .collapse `
`.
@@ -104,7 +104,7 @@ To use an accordion example that has items expanded, add the .op ## Custom Accordion Icon -You can use custom icons for the accordion trigger element and using the group-open attribute selector in tailwind css you can control the icon for open and close states of accordion. +You can use custom icons for the accordion trigger element and using the group-open attribute selector in tailwind css you can control the icon for open and close states of accordion. i tag. +You can add an icon at the beginning of alert component using the i tag. data-dismissible="{`alertName`}" data attribute to the alert element and the data-dismissible-target="{`alertName`}" data attribute to the element that you want to close the alert with. +You can make an alert dismissible by adding the data-dismissible="alertName" data attribute to the alert element and the data-dismissible-target="{`alertName`}" data attribute to the element that you want to close the alert with. w-full class. +A breadcrumbs could be a block level component as well that get's all the available space in a row. You can display a breadcrumbs as a block level element using the w-full class. w-full class. +A button could be a block-level component as well that gets all the available space in a row. You can render a button as a block-level element using the w-full class. rounded-full class with Button to create rounded buttons. +You can use tailwind css rounded-full class with Button to create rounded buttons. rounded-full class with Button to cre ### Button With Link -You can wrap Button component with {``} tag to make it a link. +You can wrap Button component with {``} tag to make it a link. Button component with {``} t ## Button Ripple Effect -You can turn on/off the ripple effect for the button component by changing data-ripple-light or data-ripple-dark data attributes to true/false. +You can turn on/off the ripple effect for the button component by changing data-ripple-light or data-ripple-dark data attributes to true/false. Button to create beautiful buttons for different purposes, below you can use some button examples used for authentication with social media and web 3.0. +You can use tailwind css classes with Button to create beautiful buttons for different purposes, below you can use some button examples used for authentication with social media and web 3.0. data-dismissible="{`chipName`}" data attribute to the chip element and the data-dismissible-target="{`chipName`}" data attribute to the element that you want to close the chip with. +You can make a chip dismissible by adding the data-dismissible="{`chipName`}" data attribute to the chip element and the data-dismissible-target="{`chipName`}" data attribute to the element that you want to close the chip with. colors object for the tailwind.config.js file. +You just need to modify the colors object for the tailwind.config.js file. ```js module.exports = withMT({ @@ -338,7 +338,7 @@ module.exports = withMT({ You can add new color to @material-tailwind/html color palette very easy and straightforward, it's the same as adding new color for tailwindcss. -You just need to add your own color to the extend and colors object for tailwind.config.js file. +You just need to add your own color to the extend and colors object for tailwind.config.js file. ```js {5-16} module.exports = withMT({ diff --git a/documentation/html/dialog.mdx b/documentation/html/dialog.mdx index d66b3f0bd..5b0ab9268 100644 --- a/documentation/html/dialog.mdx +++ b/documentation/html/dialog.mdx @@ -27,9 +27,9 @@ A dialog is a type of modal window with critical information which disable all a See below our dialog example that you can use for your Tailwind CSS project. -You can initialize a new dialog by adding the data-dialog-target="`{dialog}`" data attribute to the trigger element, the data-dialog-backdrop="`{dialogName}`" to the backdrop element and the
data-dialog="`{dialogName}`" to the dialog element itself and make sure that the values for those data attributes are the same. +You can initialize a new dialog by adding the data-dialog-target="`{dialog}`" data attribute to the trigger element, the data-dialog-backdrop="`{dialogName}`" to the backdrop element and the
data-dialog="`{dialogName}`" to the dialog element itself and make sure that the values for those data attributes are the same. -You can also use the data-dialog-close="true" for the element that you want to close the dialog with when clicking. +You can also use the data-dialog-close="true" for the element that you want to close the dialog with when clicking.
@@ -88,7 +88,7 @@ You can set the size of the dialog by your own using the tailwind css classes, c
@@ -119,7 +119,7 @@ You can set the size of the dialog by your own using the tailwind css classes, c
@@ -150,7 +150,7 @@ You can set the size of the dialog by your own using the tailwind css classes, c
@@ -158,23 +158,23 @@ You can set the size of the dialog by your own using the tailwind css classes, c class="relative m-4 w-2/5 min-w-[40%] max-w-[40%] rounded-lg bg-white font-sans text-base font-light leading-relaxed text-blue-gray-500 antialiased shadow-2xl">
- {`Its a simple dialog.`} + Its a simple dialog.
- {`The key to more success is to have a lot of pillows. Put it this way, it took me + The key to more success is to have a lot of pillows. Put it this way, it took me twenty five years to get these plants, twenty five years of blood sweat and tears, and I'm never giving up, I'm just getting started. I'm up to something. Fan - luv.`} + luv.
@@ -183,7 +183,7 @@ You can set the size of the dialog by your own using the tailwind css classes, c
@@ -214,7 +214,7 @@ You can set the size of the dialog by your own using the tailwind css classes, c
@@ -245,7 +245,7 @@ You can set the size of the dialog by your own using the tailwind css classes, c
@@ -253,23 +253,23 @@ You can set the size of the dialog by your own using the tailwind css classes, c class="relative h-screen w-screen min-w-[100vw] max-w-[100vw] bg-white font-sans text-base font-light leading-relaxed text-blue-gray-500 antialiased">
- {`Its a simple dialog.`} + Its a simple dialog.
- {`The key to more success is to have a lot of pillows. Put it this way, it took me + The key to more success is to have a lot of pillows. Put it this way, it took me twenty five years to get these plants, twenty five years of blood sweat and tears, and I'm never giving up, I'm just getting started. I'm up to something. Fan - luv.`} + luv.
@@ -282,7 +282,7 @@ You can set the size of the dialog by your own using the tailwind css classes, c ## Custom Dialog Animation -You can modify the open/close state animation for dialog by adding the data-dialog-mount="`{opacity-100}`", data-dialog-unmount="`{opacity-0}`" and data-dialog-transition="`{transition-opacity}`" data attributes to the dialog element. You can pass tailwind css classnames for those data attributes for animating the dialog.
Check more about animation data attributes for dialog
here. +You can modify the open/close state animation for dialog by adding the data-dialog-mount="`{opacity-100}`", data-dialog-unmount="`{opacity-0}`" and data-dialog-transition="`{transition-opacity}`" data attributes to the dialog element. You can pass tailwind css classnames for those data attributes for animating the dialog.
Check more about animation data attributes for dialog here. - {`Open Dialog`} + Open Dialog
@@ -661,9 +661,9 @@ The following data attributes are available for dialog element. | Attribute | Description | Default | | ------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | `data-dialog` | Set the name of the dialog and reference it to the
dialog trigger and backdrop elements. | | -| `data-popover-mount` | Set the classnaes that should be used when the
dialog is visible. | opacity-1
translate-y-0 | -| `data-popover-unmount` | Set the classnaes that should be used when the
dialog is hidden. | opacity-0
-translate-y-14
pointer-events-none | -| `data-popover-transition` | Set the classnaes that should be used for
transition of the dialog. | transition-all
duration-300 | +| `data-popover-mount` | Set the classnaes that should be used when the
dialog is visible. | opacity-1
translate-y-0 | +| `data-popover-unmount` | Set the classnaes that should be used when the
dialog is hidden. | opacity-0
-translate-y-14
pointer-events-none | +| `data-popover-transition` | Set the classnaes that should be used for
transition of the dialog. | transition-all
duration-300 | --- diff --git a/documentation/html/fonts.mdx b/documentation/html/fonts.mdx index 0191987fc..7ab236681 100644 --- a/documentation/html/fonts.mdx +++ b/documentation/html/fonts.mdx @@ -45,7 +45,7 @@ const fontFamily = { You can customize the default font families for @material-tailwind/html very easy and straightforward, it's the same as customizing font families for tailwindcss. -You just need to customize the font family that you like through the fontFamily object for tailwind.config.js file. +You just need to customize the font family that you like through the fontFamily object for tailwind.config.js file. ```js {4} module.exports = withMT({ diff --git a/documentation/html/gallery.mdx b/documentation/html/gallery.mdx new file mode 100644 index 000000000..7dbdff023 --- /dev/null +++ b/documentation/html/gallery.mdx @@ -0,0 +1,404 @@ +--- +title: Tailwind CSS Gallery for HTML - Material Tailwind +description: Customise your web projects with our easy-to-use gallery component for Tailwind CSS and HTML using Material Design guidelines. +navigation: + [ + "gallery", + "masonry-grid-gallery", + "featured-image-gallery", + "quad-gallery", + "gallery-with-tab" + ] +github: skeleton +prev: form +next: icon-button +--- + + +# Tailwind CSS Gallery - HTML + + +Use the image gallery component + +See below our simple Gallery example that you can use in your Tailwind CSS and HTML project. + +
+ +}> +```html +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+``` +
+ +--- + + + +## Masonry Grid Galery - React + +
+ +}> +```html +
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+``` +
+ +--- + + + +## Featured Image Galery + +
+ +}> +```html +
+
+ +
+
+
+ gallery-image +
+
+ gallery-image +
+
+ gallery-image +
+
+ gallery-image +
+
+ gallery-image +
+
+
+``` +
+ +--- + + + + +## Quad Galery + +
+ +}> +```html +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+``` +
+ +--- + + + +## Gallery With Tab + +
+ +}> +```html +
+
+ +
+
+
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+ image-photo +
+
+
+ + +
+
+
+``` +
+ +--- diff --git a/documentation/html/guide/angular.mdx b/documentation/html/guide/angular.mdx new file mode 100644 index 000000000..581ca84b6 --- /dev/null +++ b/documentation/html/guide/angular.mdx @@ -0,0 +1,147 @@ +--- +title: Angular - Installation Guide +description: Learn how to use Material Tailwind components with Angular and Tailwind CSS to easily create elegant and flexible pages. +navigation: + [ + "installation", + "npm", + "yarn", + "pnpm", + "tailwindcss-config", + "ripple-effect", + "example", + ] +github: guide/angular +prev: installation +next: license +--- + +# Material Tailwind with Angular + + +Learn how to setup and install @material-tailwind/html with Angular. + +
+
+ +First you need to create a new project using Angular, for more details check the Angular Official Documentation + +```bash +ng new my-project +``` + +
+ +Then you need to install Tailwind CSS since @material-tailwind/html is working with Tailwind CSS classes and you need to have Tailwind CSS installed on your project. Check Tailwind CSS Installation for Angular on Tailwind CSS Documentation. + +--- + + +## Using NPM + + +Install @material-tailwind/html as a dependency using NPM by running the following command: + + + +```bash +npm i @material-tailwind/html +``` + +--- + + +## Using Yarn + + +Install @material-tailwind/html as a dependency using Yarn by running the following command: + + + +```bash +yarn add @material-tailwind/html +``` + +--- + +## Using PNPM + +Install @material-tailwind/html as a dependency using PNPM by running the following command: + + + +```bash +pnpm i @material-tailwind/html +``` + +--- + + +## TailwindCSS Configurations + + + + +Once you install @material-tailwind/html you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/html/utils. + +```js {1, 4, 12} +import withMT from "@material-tailwind/html/utils/withMT"; + +/** @type {import('tailwindcss').Config} */ +module.exports = withMT({ + content: [ + "./src/**/*.{html,ts}", + ], + theme: { + extend: {}, + }, + plugins: [], +}); +``` + +--- + +## Ripple Effect + + + +@material-tailwind/html comes with a ripple effect script file same as Material Design ripple effect and you can simply use it by adding it's CDN link to you project and add the data-ripple-light="true" for light ripple effect and data-ripple-dark="true" for dark ripple effect as an attribute for components + +The ripple effect used in @material-tailwind/html is a separate package called material-ripple-effect + + +```html + +"scripts": ["./node_modules/@material-tailwind/html/scripts/ripple.js"] + + + +``` + +--- + + +## Example + + +Now you're good to go and use @material-tailwind/html in your project. + + + Button + +}> +```html + +``` + diff --git a/documentation/html/guide/django.mdx b/documentation/html/guide/django.mdx new file mode 100644 index 000000000..11cb4ac2a --- /dev/null +++ b/documentation/html/guide/django.mdx @@ -0,0 +1,283 @@ +--- +title: Django - Installation Guide +description: Learn how to use Material Tailwind components with Django and Tailwind CSS to easily create elegant and flexible pages. +navigation: + [ + "installation", + "npm", + "yarn", + "pnpm", + "tailwindcss-config", + "ripple-effect", + "example", + ] +github: guide/django +prev: installation +next: license +--- + +# Material Tailwind with Django + + +Learn how to setup and install @material-tailwind/html with Django. + +
+
+ +First you need to create a new project using Django, for more details check the Django Official Documentation + +```bash +django-admin startproject mysite +``` +
+ +Create a new **templates** directory inside the project folder and update **settings.py** file: + +```php +TEMPLATES = [ + { + ... + 'DIRS': [BASE_DIR / 'templates'], + ... + }, +] +``` +
+ +Install the **django-compressor** by running the following command in your terminal: + +```bash +python -m pip install django-compressor +``` +
+And add the **compressor** to the installed apps inside the **settings.py** file: + +```php +INSTALLED_APPS = [ + ... + 'compressor', +] +``` + +
+ +Configure the **compressor** inside the **settings.py** file: + +```php +COMPRESS_ROOT = BASE_DIR / 'static' + +COMPRESS_ENABLED = True + +STATICFILES_FINDERS = ('compressor.finders.CompressorFinder',) +``` +
+ +Create two new folders and an **input.css** file inside the **static/src/** folder: +```bash +static +└── src + └── input.css +``` + +
+ +Create a new **views.py** file inside `mysite/` next to **urls.py** and add the following code: + +```php +from django.shortcuts import render + +def index(request): + return render(request, 'index.html') +``` + +
+Import the newly created view instance inside the **urls.py** file: + +```php +from .views import index + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', index, name='index') +] +``` + +
+Create a new **_base.html** file inside the **templates** directory and the following code: + +```html +{% load compress %} +{% load static %} + + + + + + + + + Material Tailwind with Django + + {% compress css %} + + {% endcompress %} + + + + + {% block content %} {% endblock content %} + + + +``` +
+Create an **index.html** file inside the **templates** folder that will serve as the homepage. At the moment ignore the Tailwind CSS classes as we will install it shortly. +```html +{% extends "_base.html" %} + +{% block content %} +

+ Material Tailwind with Django! +

+{% endblock content %} +``` +
+ +Then you need to install Tailwind CSS since @material-tailwind/html works with Tailwind CSS classes and you need to have Tailwind CSS installed on your project. +```bash +npm install -D tailwindcss +npx tailwindcss init +``` + +--- + + +## Using NPM + + +Install @material-tailwind/html as a dependency using NPM by running the following command: + + + +```bash +npm i @material-tailwind/html +``` + +--- + + +## Using Yarn + + +Install @material-tailwind/html as a dependency using Yarn by running the following command: + + + +```bash +yarn add @material-tailwind/html +``` + +--- + +## Using PNPM + +Install @material-tailwind/html as a dependency using PNPM by running the following command: + + + +```bash +pnpm i @material-tailwind/html +``` + +--- + + +## TailwindCSS Configurations + + + + +Once you install @material-tailwind/html you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/html/utils. + +```js {1, 4,6, 12} +import withMT from "@material-tailwind/html/utils/withMT"; + +/** @type {import('tailwindcss').Config} */ +module.exports = withMT({ + content: [ + './templates/**/*.html' + ], + theme: { + extend: {}, + }, + plugins: [], +}); +``` +
+Import the Tailwind CSS directives inside the **input.css** file: +```css +/* static/src/input.css */ + +@tailwind base; +@tailwind components; +@tailwind utilities; +``` +
+Run the following command to watch for changes and compile the Tailwind CSS code: + +```bash +npx tailwindcss -i ./static/src/input.css -o ./static/src/output.css --watch +``` +
+ +Finally, create a local server by running the following command: +```bash +python manage.py runserver +``` +--- + +
+## Ripple Effect + + + +@material-tailwind/html comes with a ripple effect script file same as Material Design ripple effect and you can simply use it by adding it's CDN link to you project and add the data-ripple-light="true" for light ripple effect and data-ripple-dark="true" for dark ripple effect as an attribute for components + +The ripple effect used in @material-tailwind/html is a separate package called material-ripple-effect + + +```html + + + + + +``` + +--- + + +## Example + + +Now you're good to go and use @material-tailwind/html in your project. + + + Button + +}> +```html + +``` + diff --git a/documentation/html/guide/flask.mdx b/documentation/html/guide/flask.mdx new file mode 100644 index 000000000..d07780982 --- /dev/null +++ b/documentation/html/guide/flask.mdx @@ -0,0 +1,245 @@ +--- +title: Flask - Installation Guide +description: Learn how to use Material Tailwind components with Flask and Tailwind CSS to easily create elegant and flexible pages. +navigation: + [ + "installation", + "npm", + "yarn", + "pnpm", + "tailwindcss-config", + "ripple-effect", + "example", + ] +github: guide/flask +prev: installation +next: license +--- + +# Material Tailwind with Flask + + +Learn how to setup and install @material-tailwind/html with Flask. + +
+
+ +First you need to create a new project using Flask, for more details check the Flask Official Documentation. +Then, in the root of your project folder create a new file called **app.py** with the following content: + +```js +from flask import Flask, render_template + +app = Flask(__name__) + +@app.route("/") +@app.route("/index") +def index(): + return render_template("index.html") + +if __name__ == '__main__': + app.run(debug=True) +``` + +
+ +Then create two folders naming **templates** and **static** and inside the **templates** folder create an **index.html** file with a basic structure such as: + +```html + + + + + + + Material Tailwind with Flask + + +

Hello, Flask!

+ + +``` +
+ +Then you need to install Tailwind CSS since @material-tailwind/html is working with Tailwind CSS classes and you need to have Tailwind CSS installed on your project. + +```bash +npm install -D tailwindcss +npx tailwindcss init +``` +
+ +Create a new **static/src/** folder and add a new **input.css** file and add the `@tailwind` directives for each of Tailwind’s layers: + +```css +@tailwind base; +@tailwind components; +@tailwind utilities; +``` +
+ +Configure the template files inside the tailwind.config.js: + +```bash {3-6} +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + "./templates/**/*.html", + "./static/src/**/*.js" + ], + theme: { + extend: {}, + }, + plugins: [], +} +``` +
+ +Run the following command to compile and watch for the changes in the Tailwind CSS file: + +```bash +npx tailwindcss -i ./static/src/input.css -o ./static/dist/css/out.css --watch +``` +
+ +This will generate a new **output.css** file inside the `/static/dist/css/` folder that we now need to include in our **index.html**. + +```html {8-11} + + + + + + + Material Tailwind with Flask + + + +

Hello, Flask!

+ + +``` + +--- + + +## Using NPM + + +Install @material-tailwind/html as a dependency using NPM by running the following command: + + + +```bash +npm i @material-tailwind/html +``` + +--- + + +## Using Yarn + + +Install @material-tailwind/html as a dependency using Yarn by running the following command: + + + +```bash +yarn add @material-tailwind/html +``` + +--- + +## Using PNPM + +Install @material-tailwind/html as a dependency using PNPM by running the following command: + + + +```bash +pnpm i @material-tailwind/html +``` + +--- + + +## TailwindCSS Configurations + + + + +Once you install @material-tailwind/html you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/html/utils. + +```js {3, 5, 14} +/** @type {import('tailwindcss').Config} */ + +import withMT from "@material-tailwind/html/utils/withMT"; + +module.exports = withMT({ + content: [ + "./templates/**/*.html", + "./static/src/**/*.js" + ], + theme: { + extend: {}, + }, + plugins: [], +}); +``` + +
+ +Activate the environment and start the local server by running: +```bash +. venv/bin/activate && python app.py +``` + +--- + +## Ripple Effect + + + +@material-tailwind/html comes with a ripple effect script file same as Material Design ripple effect and you can simply use it by adding it's CDN link to you project and add the data-ripple-light="true" for light ripple effect and data-ripple-dark="true" for dark ripple effect as an attribute for components + +The ripple effect used in @material-tailwind/html is a separate package called material-ripple-effect + + +```html + + + + + +``` + +--- + + +## Example + + +Now you're good to go and use @material-tailwind/html in your project. + + + Button + +}> +```html + +``` + diff --git a/documentation/html/guide/gatsby.mdx b/documentation/html/guide/gatsby.mdx new file mode 100644 index 000000000..6515ed197 --- /dev/null +++ b/documentation/html/guide/gatsby.mdx @@ -0,0 +1,149 @@ +--- +title: Gatsby - Installation Guide +description: Learn how to use Material Tailwind components with Gatsby and Tailwind CSS to easily create elegant and flexible pages. +navigation: + [ + "installation", + "npm", + "yarn", + "pnpm", + "tailwindcss-config", + "ripple-effect", + "example", + ] +github: guide/gatsby +prev: installation +next: license +--- + +# Material Tailwind with Gatsby + + +Learn how to setup and install @material-tailwind/html with Gatsby. + +
+
+ +First you need to create a new project using Gatsby, for more details check the Gatsby Official Documentation + +```bash +gatsby new my-project +``` + +
+ +Then you need to install Tailwind CSS since @material-tailwind/html is working with Tailwind CSS classes and you need to have Tailwind CSS installed on your project. Check Tailwind CSS Installation for Gatsby on Tailwind CSS Documentation. + +--- + + +## Using NPM + + +Install @material-tailwind/html as a dependency using NPM by running the following command: + + + +```bash +npm i @material-tailwind/html +``` + +--- + + +## Using Yarn + + +Install @material-tailwind/html as a dependency using Yarn by running the following command: + + + +```bash +yarn add @material-tailwind/html +``` + +--- + +## Using PNPM + +Install @material-tailwind/html as a dependency using PNPM by running the following command: + + + +```bash +pnpm i @material-tailwind/html +``` + +--- + + +## TailwindCSS Configurations + + + + +Once you install @material-tailwind/html you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/html/utils. + +```js {3, 5, 14} +/** @type {import('tailwindcss').Config} */ + +import withMT from "@material-tailwind/html/utils/withMT"; + +module.exports = withMT({ + content: [ + "./src/pages/**/*.{js,jsx,ts,tsx}", + "./src/components/**/*.{js,jsx,ts,tsx}", + ], + theme: { + extend: {}, + }, + plugins: [], +}); +``` + +--- + +## Ripple Effect + + + +@material-tailwind/html comes with a ripple effect script file same as Material Design ripple effect and you can simply use it by adding it's CDN link to you project and add the data-ripple-light="true" for light ripple effect and data-ripple-dark="true" for dark ripple effect as an attribute for components + +The ripple effect used in @material-tailwind/html is a separate package called material-ripple-effect + + +```html + + + + + +``` + +--- + + +## Example + + +Now you're good to go and use @material-tailwind/html in your project. + + + Button + +}> +```html + +``` + diff --git a/documentation/html/guide/laravel.mdx b/documentation/html/guide/laravel.mdx index 3c9e87426..3e76eaf46 100644 --- a/documentation/html/guide/laravel.mdx +++ b/documentation/html/guide/laravel.mdx @@ -57,7 +57,6 @@ export default { "./resources/**/*.blade.php", "./resources/**/*.js", "./resources/**/*.vue", - "./node_modules/flowbite/**/*.js", ], theme: { extend: {}, @@ -129,7 +128,6 @@ export default withMT({ "./resources/**/*.blade.php", "./resources/**/*.js", "./resources/**/*.vue", - "./node_modules/flowbite/**/*.js", ], theme: { extend: {}, @@ -151,7 +149,7 @@ The ripple effect used in @material-tailwind/html is a separate package called < ```html - + diff --git a/documentation/html/guide/meteor.mdx b/documentation/html/guide/meteor.mdx new file mode 100644 index 000000000..2981e2e33 --- /dev/null +++ b/documentation/html/guide/meteor.mdx @@ -0,0 +1,149 @@ +--- +title: Meteor - Installation Guide +description: Learn how to use Material Tailwind components with Meteor and Tailwind CSS to easily create elegant and flexible pages. +navigation: + [ + "installation", + "npm", + "yarn", + "pnpm", + "tailwindcss-config", + "ripple-effect", + "example", + ] +github: guide/meteor +prev: installation +next: license +--- + +# Material Tailwind with Meteor + + +Learn how to setup and install @material-tailwind/html with Meteor. + +
+
+ +First you need to create a new project using Meteor, for more details check the Meteor Official Documentation + +```bash +meteor create my-project +``` + +
+ +Then you need to install Tailwind CSS since @material-tailwind/html is working with Tailwind CSS classes and you need to have Tailwind CSS installed on your project. Check Tailwind CSS Installation for Meteor on Tailwind CSS Documentation. + +--- + + +## Using NPM + + +Install @material-tailwind/html as a dependency using NPM by running the following command: + + + +```bash +npm i @material-tailwind/html +``` + +--- + + +## Using Yarn + + +Install @material-tailwind/html as a dependency using Yarn by running the following command: + + + +```bash +yarn add @material-tailwind/html +``` + +--- + +## Using PNPM + +Install @material-tailwind/html as a dependency using PNPM by running the following command: + + + +```bash +pnpm i @material-tailwind/html +``` + +--- + + +## TailwindCSS Configurations + + + + +Once you install @material-tailwind/html you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/html/utils. + +```js {3, 5, 14} +/** @type {import('tailwindcss').Config} */ + +import withMT from "@material-tailwind/html/utils/withMT"; + +module.exports = withMT({ + content: [ + "./imports/ui/**/*.{js,jsx,ts,tsx}", + "./client/*.html", + ], + theme: { + extend: {}, + }, + plugins: [], +}); +``` + +--- + +## Ripple Effect + + + +@material-tailwind/html comes with a ripple effect script file same as Material Design ripple effect and you can simply use it by adding it's CDN link to you project and add the data-ripple-light="true" for light ripple effect and data-ripple-dark="true" for dark ripple effect as an attribute for components + +The ripple effect used in @material-tailwind/html is a separate package called material-ripple-effect + + +```html + + + + + +``` + +--- + + +## Example + + +Now you're good to go and use @material-tailwind/html in your project. + + + Button + +}> +```html + +``` + diff --git a/documentation/html/guide/next.mdx b/documentation/html/guide/next.mdx index d00891a41..1e6fe9e16 100644 --- a/documentation/html/guide/next.mdx +++ b/documentation/html/guide/next.mdx @@ -114,7 +114,7 @@ Add the following script tag to the `/src/app/layout.js` file in your project. ```html - + diff --git a/documentation/html/guide/nuxt.mdx b/documentation/html/guide/nuxt.mdx index 2ded2e9f1..ec391d6f9 100644 --- a/documentation/html/guide/nuxt.mdx +++ b/documentation/html/guide/nuxt.mdx @@ -125,7 +125,7 @@ export default defineNuxtConfig({ script: [ { async: true, - src: "https://unpkg.com/@material-tailwind/html@latest/scripts/ripple.js", + src: "https://unpkg.com/@material-tailwind/html/scripts/ripple.js", }, ], }, diff --git a/documentation/html/guide/phoenix.mdx b/documentation/html/guide/phoenix.mdx new file mode 100644 index 000000000..d3350e3ae --- /dev/null +++ b/documentation/html/guide/phoenix.mdx @@ -0,0 +1,147 @@ +--- +title: Phoenix - Installation Guide +description: Learn how to use Material Tailwind components with Phoenix and Tailwind CSS to easily create elegant and flexible pages. +navigation: + [ + "installation", + "npm", + "yarn", + "pnpm", + "tailwindcss-config", + "ripple-effect", + "example", + ] +github: guide/phoenix +prev: installation +next: license +--- + +# Material Tailwind with Phoenix + + +Learn how to setup and install @material-tailwind/html with Phoenix. + +
+
+ +First you need to create a new project using Phoenix, for more details check the Phoenix Official Documentation + +```bash +mix phx.new my_app +``` + +
+ +Then you need to install Tailwind CSS since @material-tailwind/html is working with Tailwind CSS classes and you need to have Tailwind CSS installed on your project. Check Tailwind CSS Installation for Phoenix on Tailwind CSS Documentation. + +--- + + +## Using NPM + + +Install @material-tailwind/html as a dependency using NPM by running the following command: + + + +```bash +npm i @material-tailwind/html +``` + +--- + + +## Using Yarn + + +Install @material-tailwind/html as a dependency using Yarn by running the following command: + + + +```bash +yarn add @material-tailwind/html +``` + +--- + +## Using PNPM + +Install @material-tailwind/html as a dependency using PNPM by running the following command: + + + +```bash +pnpm i @material-tailwind/html +``` + +--- + + +## TailwindCSS Configurations + + + + +Once you install @material-tailwind/html you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/html/utils. + +```js {5, 7, 15} +const plugin = require("tailwindcss/plugin") +const fs = require("fs") +const path = require("path") + +const withMT = require("@material-tailwind/html/utils/withMT") + +module.exports = withMT({ + content: [ + './js/**/*.js', + '../lib/*_web.ex', + '../lib/*_web/**/*.*ex', + ], + theme: {}, + plugins: [] +}); +``` + +--- + +## Ripple Effect + + + +@material-tailwind/html comes with a ripple effect script file same as Material Design ripple effect and you can simply use it by adding it's CDN link to you project and add the data-ripple-light="true" for light ripple effect and data-ripple-dark="true" for dark ripple effect as an attribute for components + +The ripple effect used in @material-tailwind/html is a separate package called material-ripple-effect + + +```html + + +``` + +--- + + +## Example + + +Now you're good to go and use @material-tailwind/html in your project. + + + Button + +}> +```html + +``` + diff --git a/documentation/html/guide/qwik.mdx b/documentation/html/guide/qwik.mdx new file mode 100644 index 000000000..3be6d7b0c --- /dev/null +++ b/documentation/html/guide/qwik.mdx @@ -0,0 +1,148 @@ +--- +title: Qwik - Installation Guide +description: Learn how to use Material Tailwind components with Qwik and Tailwind CSS to easily create elegant and flexible pages. +navigation: + [ + "installation", + "npm", + "yarn", + "pnpm", + "tailwindcss-config", + "ripple-effect", + "example", + ] +github: guide/Qwik +prev: installation +next: license +--- + +# Material Tailwind with Qwik + + +Learn how to setup and install @material-tailwind/html with Qwik. + +
+
+ +First you need to create a new project using Qwik, for more details check the Qwik Official Documentation + +```bash +npm create qwik@latest +``` + +
+ +Then you need to install Tailwind CSS since @material-tailwind/html is working with Tailwind CSS classes and you need to have Tailwind CSS installed on your project. Check Tailwind CSS Installation for Qwik on Tailwind CSS Documentation. + +--- + + +## Using NPM + + +Install @material-tailwind/html as a dependency using NPM by running the following command: + + + +```bash +npm i @material-tailwind/html +``` + +--- + + +## Using Yarn + + +Install @material-tailwind/html as a dependency using Yarn by running the following command: + + + +```bash +yarn add @material-tailwind/html +``` + +--- + +## Using PNPM + +Install @material-tailwind/html as a dependency using PNPM by running the following command: + + + +```bash +pnpm i @material-tailwind/html +``` + +--- + + +## TailwindCSS Configurations + + + + +Once you install @material-tailwind/html you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/html/utils. + +```js {3, 5, 13} +/** @type {import('tailwindcss').Config} */ + +import withMT from "@material-tailwind/html/utils/withMT"; + +module.exports = withMT({ + content: [ + "./src/**/*.{js,ts,jsx,tsx,mdx}", + ], + theme: { + extend: {}, + }, + plugins: [], +}); +``` + +--- + +## Ripple Effect + + + +@material-tailwind/html comes with a ripple effect script file same as Material Design ripple effect and you can simply use it by adding it's CDN link to you project and add the data-ripple-light="true" for light ripple effect and data-ripple-dark="true" for dark ripple effect as an attribute for components + +The ripple effect used in @material-tailwind/html is a separate package called material-ripple-effect + + +```html + + + + + +``` + +--- + + +## Example + + +Now you're good to go and use @material-tailwind/html in your project. + + + Button + +}> +```html + +``` + diff --git a/documentation/html/guide/react-vite.mdx b/documentation/html/guide/react-vite.mdx index 50bb66b0a..e492dc2d2 100644 --- a/documentation/html/guide/react-vite.mdx +++ b/documentation/html/guide/react-vite.mdx @@ -111,7 +111,7 @@ Add the following script tag to the `index.html` file in your project. ```html - + diff --git a/documentation/html/guide/remix.mdx b/documentation/html/guide/remix.mdx new file mode 100644 index 000000000..94597f1b2 --- /dev/null +++ b/documentation/html/guide/remix.mdx @@ -0,0 +1,146 @@ +--- +title: Remix - Installation Guide +description: Learn how to use Material Tailwind components with Remix and Tailwind CSS to easily create elegant and flexible pages. +navigation: + [ + "installation", + "npm", + "yarn", + "pnpm", + "tailwindcss-config", + "ripple-effect", + "example", + ] +github: guide/remix +prev: installation +next: license +--- + +# Material Tailwind with Remix + + +Learn how to setup and install @material-tailwind/html with Remix. + +
+
+ +First you need to create a new project using Remix, for more details check the Remix Official Documentation + +```bash +npx create-remix@latest remix-app +``` + +
+ +Then you need to install Tailwind CSS since @material-tailwind/html is working with Tailwind CSS classes and you need to have Tailwind CSS installed on your project. Check Tailwind CSS Installation for Remix on Tailwind CSS Documentation. + +--- + + +## Using NPM + + +Install @material-tailwind/html as a dependency using NPM by running the following command: + + + +```bash +npm i @material-tailwind/html +``` + +--- + + +## Using Yarn + + +Install @material-tailwind/html as a dependency using Yarn by running the following command: + + + +```bash +yarn add @material-tailwind/html +``` + +--- + +## Using PNPM + +Install @material-tailwind/html as a dependency using PNPM by running the following command: + + + +```bash +pnpm i @material-tailwind/html +``` + +--- + + +## TailwindCSS Configurations + + + + +Once you install @material-tailwind/html you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/html/utils. + +```js {3, 5, 11} +import type { Config } from "tailwindcss"; + +import withMT from "@material-tailwind/html/utils/withMT"; + +export default withMT({ + content: ["./app/**/*.{js,jsx,ts,tsx}"], + theme: { + extend: {}, + }, + plugins: [], +} satisfies Config); +``` + +--- + +## Ripple Effect + + + +@material-tailwind/html comes with a ripple effect script file same as Material Design ripple effect and you can simply use it by adding it's CDN link to you project and add the data-ripple-light="true" for light ripple effect and data-ripple-dark="true" for dark ripple effect as an attribute for components + +The ripple effect used in @material-tailwind/html is a separate package called material-ripple-effect + + +```html + + + + + +``` + +--- + + +## Example + + +Now you're good to go and use @material-tailwind/html in your project. + + + Button + +}> +```html + +``` + diff --git a/documentation/html/guide/solid.mdx b/documentation/html/guide/solid.mdx new file mode 100644 index 000000000..c0eda7390 --- /dev/null +++ b/documentation/html/guide/solid.mdx @@ -0,0 +1,148 @@ +--- +title: Solid - Installation Guide +description: Learn how to use Material Tailwind components with Solid and Tailwind CSS to easily create elegant and flexible pages. +navigation: + [ + "installation", + "npm", + "yarn", + "pnpm", + "tailwindcss-config", + "ripple-effect", + "example", + ] +github: guide/solid +prev: installation +next: license +--- + +# Material Tailwind with Solid + + +Learn how to setup and install @material-tailwind/html with Solid. + +
+
+ +First you need to create a new project using Solid, for more details check the Solid Official Documentation + +```bash +npm create vite@latest my-app -- --template solid +``` + +
+ +Then you need to install Tailwind CSS since @material-tailwind/html is working with Tailwind CSS classes and you need to have Tailwind CSS installed on your project. Check Tailwind CSS Installation for Solid on Tailwind CSS Documentation. + +--- + + +## Using NPM + + +Install @material-tailwind/html as a dependency using NPM by running the following command: + + + +```bash +npm i @material-tailwind/html +``` + +--- + + +## Using Yarn + + +Install @material-tailwind/html as a dependency using Yarn by running the following command: + + + +```bash +yarn add @material-tailwind/html +``` + +--- + +## Using PNPM + +Install @material-tailwind/html as a dependency using PNPM by running the following command: + + + +```bash +pnpm i @material-tailwind/html +``` + +--- + + +## TailwindCSS Configurations + + + + +Once you install @material-tailwind/html you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/html/utils. + +```js {3, 5, 13} +/** @type {import('tailwindcss').Config} */ + +import withMT from "@material-tailwind/html/utils/withMT"; + +export default withMT({ + content: [ + "./src/**/*.{js,jsx,ts,tsx}", + ], + theme: { + extend: {}, + }, + plugins: [], +}); +``` + +--- + +## Ripple Effect + + + +@material-tailwind/html comes with a ripple effect script file same as Material Design ripple effect and you can simply use it by adding it's CDN link to you project and add the data-ripple-light="true" for light ripple effect and data-ripple-dark="true" for dark ripple effect as an attribute for components + +The ripple effect used in @material-tailwind/html is a separate package called material-ripple-effect + + +```html + + + + + +``` + +--- + + +## Example + + +Now you're good to go and use @material-tailwind/html in your project. + + + Button + +}> +```html + +``` + diff --git a/documentation/html/guide/svelte.mdx b/documentation/html/guide/svelte.mdx index b60c8c2c6..1a6f12f64 100644 --- a/documentation/html/guide/svelte.mdx +++ b/documentation/html/guide/svelte.mdx @@ -112,7 +112,7 @@ Add the following script tag to the `/src/app.html` file in your project. ```html - + diff --git a/documentation/html/guide/symfony.mdx b/documentation/html/guide/symfony.mdx new file mode 100644 index 000000000..e03958ec9 --- /dev/null +++ b/documentation/html/guide/symfony.mdx @@ -0,0 +1,155 @@ +--- +title: Symfony - Installation Guide +description: Learn how to use Material Tailwind components with Symfony and Tailwind CSS to easily create elegant and flexible pages. +navigation: + [ + "installation", + "npm", + "yarn", + "pnpm", + "tailwindcss-config", + "ripple-effect", + "example", + ] +github: guide/symfony +prev: installation +next: license +--- + +# Material Tailwind with Symfony + + +Learn how to setup and install @material-tailwind/html with Symfony. + +
+
+ +First you need to create a new project using Symfony, for more details check the Symfony Official Documentation + +```bash +symfony new --webapp my_project +``` +
+ +To enable front-end integration via Composer, it is recommended to install the Symfony Webpack Encore bundle. + +```bash +composer require symfony/webpack-encore-bundle +``` +
+ +Then you need to install Tailwind CSS since @material-tailwind/html is working with Tailwind CSS classes and you need to have Tailwind CSS installed on your project. Check Tailwind CSS Installation for Symfony on Tailwind CSS Documentation. + +--- + + +## Using NPM + + +Install @material-tailwind/html as a dependency using NPM by running the following command: + + + +```bash +npm i @material-tailwind/html +``` + +--- + + +## Using Yarn + + +Install @material-tailwind/html as a dependency using Yarn by running the following command: + + + +```bash +yarn add @material-tailwind/html +``` + +--- + +## Using PNPM + +Install @material-tailwind/html as a dependency using PNPM by running the following command: + + + +```bash +pnpm i @material-tailwind/html +``` + +--- + + +## TailwindCSS Configurations + + + + +Once you install @material-tailwind/html you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/html/utils. + +```js {3, 5, 14} +/** @type {import('tailwindcss').Config} */ + +import withMT from "@material-tailwind/html/utils/withMT"; + +module.exports = withMT({ + content: [ + "./assets/**/*.js", + "./templates/**/*.html.twig", + ], + theme: { + extend: {}, + }, + plugins: [], +}); +``` + +--- + +## Ripple Effect + + + +@material-tailwind/html comes with a ripple effect script file same as Material Design ripple effect and you can simply use it by adding it's CDN link to you project and add the data-ripple-light="true" for light ripple effect and data-ripple-dark="true" for dark ripple effect as an attribute for components + +The ripple effect used in @material-tailwind/html is a separate package called material-ripple-effect + + +```html + + + + + +``` + +--- + + +## Example + + +Now you're good to go and use @material-tailwind/html in your project. + + + Button + +}> +```html + +``` + diff --git a/documentation/html/guide/vue-vite.mdx b/documentation/html/guide/vue-vite.mdx index b476ae225..02ccaac8c 100644 --- a/documentation/html/guide/vue-vite.mdx +++ b/documentation/html/guide/vue-vite.mdx @@ -111,7 +111,7 @@ Add the following script tag to the `index.html` file in your project. ```html - + diff --git a/documentation/html/icon-button.mdx b/documentation/html/icon-button.mdx index 31d07a1d2..e52c9362d 100644 --- a/documentation/html/icon-button.mdx +++ b/documentation/html/icon-button.mdx @@ -255,7 +255,7 @@ Use this example to create a icon button with link element for your Tailwind CS ## Icon Button Ripple Effect -You can turn on/off the ripple effect for the icon button component by changing data-ripple-light or data-ripple-dark data attributes to true/false. +You can turn on/off the ripple effect for the icon button component by changing data-ripple-light or data-ripple-dark data attributes to true/false. -Once you install @material-tailwind/html you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/html/utils. +Once you install @material-tailwind/html you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/html/utils. ```js {1, 3, 9} const withMT = require("@material-tailwind/html/utils/withMT"); @@ -97,7 +97,7 @@ module.exports = withMT({ -@material-tailwind/html comes with a ripple effect script file same as Material Design ripple effect and you can simply use it by adding it's CDN link to you project and add the data-ripple-light="true" for light ripple effect and data-ripple-dark="true" for dark ripple effect as an attribute for components +@material-tailwind/html comes with a ripple effect script file same as Material Design ripple effect and you can simply use it by adding it's CDN link to you project and add the data-ripple-light="true" for light ripple effect and data-ripple-dark="true" for dark ripple effect as an attribute for components The ripple effect used in @material-tailwind/html is a separate package called material-ripple-effect @@ -162,19 +162,146 @@ Now you're good to go and use @material-tailwind/html in your project. id="example" component={ } > - ```html +```html - ``` +``` + +--- + + +## Frameworks Integration + + +Framework-specific guides that cover our recommended approach to installing @material-tailwind/html in a number of popular environments. Select your preferred framework from the list below and follow the instructions. + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/documentation/html/mega-menu.mdx b/documentation/html/mega-menu.mdx new file mode 100644 index 000000000..5150c42d8 --- /dev/null +++ b/documentation/html/mega-menu.mdx @@ -0,0 +1,417 @@ +--- +title: Tailwind CSS Mega Menu for HTML - Material Tailwind +description: Customise your web projects with our mega menu component for Tailwind CSS and React using Material Design guidelines. +navigation: + [ + "mega-menu", + ] +github: menu +prev: input +next: navbar +--- + + +# Tailwind CSS Mega Menu - React + + +Use our responsive Tailwind CSS Mega Menu, that can take the user anywhere on your web app! + + +See below our Mega Menu example that you can use in your Tailwind CSS and HTML project. + +
+ +}> +```html +<> + + +``` + + diff --git a/documentation/html/menu.mdx b/documentation/html/menu.mdx index f70ce83e5..7198e90db 100644 --- a/documentation/html/menu.mdx +++ b/documentation/html/menu.mdx @@ -23,7 +23,7 @@ A menu displays a list of choices on temporary surfaces. It appears when users i See below our menu examples that you can use in your Tailwind CSS project. The example comes in different colors and styles, so you can adapt them easily to your needs. -To create a menu you can use the data-popover-target="`{menuName}`" and data-popover="`{menuName}`" data attributes. +To create a menu you can use the data-popover-target="`{menuName}`" and data-popover="`{menuName}`" data attributes.
@@ -35,21 +35,21 @@ To create a menu you can use the - {`Open Menu`} + Open Menu ``` @@ -59,7 +59,7 @@ To create a menu you can use the data-popover-nested="true" data attribure to the menu trigger element. +You can created nested/multi-level menus by setting the data-popover-nested="true" data attribure to the menu trigger element. - {`Open Nested Menu`} + Open Nested Menu ``` diff --git a/documentation/html/plugins/clipboard.mdx b/documentation/html/plugins/clipboard.mdx new file mode 100644 index 000000000..4b8133ae8 --- /dev/null +++ b/documentation/html/plugins/clipboard.mdx @@ -0,0 +1,126 @@ +--- +title: Tailwind CSS Clipboard for HTML - Material Tailwind +description: Customise your web projects with our easy-to-use clipboard example for Tailwind CSS and React using Material Design guidelines. +navigation: + [ + "clipboard", + "clipboard-copy-input", + "clipboard-copy-button", + ] +github: plugins/clipboard +prev: plugins/charts +next: plugins/date-picker +--- + + +# Tailwind CSS Clipboard - HTML + + +Use our Tailwind CSS Clipboard example to to facilitate the copying and pasting of data within an application. + +See below our beautiful clipboard example that you can use in your Tailwind CSS and HTML project. The example below is using the `clipboard` libraries, make sure to install them before using the example. + +```bash +npm install clipboard +``` + +
+
+ +}> +```html +
+
+

+ npm i @material-tailwind/html +

+ +
+
+ + +``` +
+ +--- + + +## Copy from Input + + +}> +```html +
+
+
+
+ + +
+
+ +
+
+ + + +``` +
+ +--- + + + +## Copy Button + + +}> +```html +
+ +
+ + +``` +
+ diff --git a/documentation/html/plugins/text-editor.mdx b/documentation/html/plugins/text-editor.mdx new file mode 100644 index 000000000..1275719d7 --- /dev/null +++ b/documentation/html/plugins/text-editor.mdx @@ -0,0 +1,486 @@ +--- +title: Tailwind CSS WYSIWYG Editor - Material Tailwind +description: Customise your web projects with our easy-to-use WYSIWYG Editor example for Tailwind CSS using Material Design guidelines. +navigation: + [ + "wysiwyg-editor", + "plugins-installation", + "adding-styles", + ] +github: plugins/text-editor +prev: table +next: plugins/algolia-search +--- + + +# Tailwind CSS WYSIWYG Editor + + +Use our Tailwind CSS WYSIWYG Editor in your web projects. + +See below our beautiful WYSIWYG Editor example that you can use in your Tailwind CSS project. The example below is using the tiptap library, make sure to install it before using the example. + +```bash +npm install --save @tiptap/core +``` + +
+
+ + +## Plugins Installation + + +Tiptap provides a set of plugins that you can use to extend the functionality of the editor. In the example below we are using some of the plugins and you need to install them, run the below command to install the plugins. + +
+
+ +```bash +npm install --save @tiptap/extension-placeholder @tiptap/starter-kit @tiptap/extension-paragraph @tiptap/extension-bold @tiptap/extension-underline @tiptap/extension-link @tiptap/extension-bullet-list @tiptap/extension-ordered-list @tiptap/extension-blockquote +``` + +
+
+ +}> +```html +
+
+
+ + + + + + + + +
+
+
+
+ + +``` +
+ +
+
+ + +## Adding Styles + + +You need to put the below code to your tailwind css stylesheet file, this will add the styles for elements and formatters of the editor. + +```css +.tiptap ul p, +.tiptap ol p { + @apply inline; +} + +.tiptap p.is-editor-empty:first-child::before { + @apply pointer-events-none float-left h-0 text-sm; +} +``` \ No newline at end of file diff --git a/documentation/html/popover.mdx b/documentation/html/popover.mdx index 81108d172..c8a547413 100644 --- a/documentation/html/popover.mdx +++ b/documentation/html/popover.mdx @@ -27,7 +27,7 @@ See below our popover component examples.
-You can initialize a new popover by adding the data-popover-target="`{popoverName}`" data attribute to the trigger element and the data-popover="`{popoverName}`" to the element that you want to use as the popover. +You can initialize a new popover by adding the data-popover-target="`{popoverName}`" data attribute to the trigger element and the data-popover="`{popoverName}`" to the element that you want to use as the popover. data-popover-target="` ```html
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
```
@@ -50,7 +50,7 @@ You can initialize a new popover by adding the data-popover-target="` ## Popover Placement -You can change the position of the popover relative to it's trigger element by adding the data-popover-placement="`{top}`" data attribute to the popover element by default it set's to top.
Check the placement values for popover here. +You can change the position of the popover relative to it's trigger element by adding the data-popover-placement="`{top}`" data attribute to the popover element by default it set's to top.
Check the placement values for popover here.
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
``` @@ -169,7 +169,7 @@ You can change the position of the popover relative to it's trigger element by a ## Custom Popover Animation -You can modify the open/close state animation for popover by adding the data-popover-mount="`{opacity-100}`", data-popover-unmount="`{opacity-0}`" and data-popover-transition="`{transition-opacity}`" data attributes to the popover element. You can pass tailwind css classnames for those data attributes for animation the popover.
Check more about animation data attributes for popover here. +You can modify the open/close state animation for popover by adding the data-popover-mount="`{opacity-100}`", data-popover-unmount="`{opacity-0}`" and data-popover-transition="`{transition-opacity}`" data attributes to the popover element. You can pass tailwind css classnames for those data attributes for animation the popover.
Check more about animation data attributes for popover here. - {`POPOVER`} + POPOVER
- {`This is a very beautiful popover, show some love.`} + This is a very beautiful popover, show some love.
```
@@ -441,10 +441,10 @@ The following data attributes are available for popover element. | ------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | | `data-popover` | Set the name of the popover and reference it to the
popover trigger element. | | | `data-popover-offset` | Set the offset between the popover and the popover trigger element. | 5 | -| `data-popover-placement` | Set the position of the popover relative to it's trigger element. | top | -| `data-popover-mount` | Set the classnaes that should be used when the
popover is visible. | opacity-1 | -| `data-popover-unmount` | Set the classnaes that should be used when the
popover is hidden. | opacity-0
pointer-events-none | -| `data-popover-transition` | Set the classnaes that should be used for
transition of the popover. | transition-opacity
duration-300 | +| `data-popover-placement` | Set the position of the popover relative to it's trigger element. | top | +| `data-popover-mount` | Set the classnaes that should be used when the
popover is visible. | opacity-1 | +| `data-popover-unmount` | Set the classnaes that should be used when the
popover is hidden. | opacity-0
pointer-events-none | +| `data-popover-transition` | Set the classnaes that should be used for
transition of the popover. | transition-opacity
duration-300 | --- diff --git a/documentation/html/screens.mdx b/documentation/html/screens.mdx index 68b201ea4..9c94cb9d8 100644 --- a/documentation/html/screens.mdx +++ b/documentation/html/screens.mdx @@ -40,7 +40,7 @@ const screens = { You can customize the default breakpoints for @material-tailwind/html very easy and straightforward, it's the same as customizing breakpoints for tailwindcss. -You just need to customize the breakpoint that you like through the screens object for tailwind.config.js file. +You just need to customize the breakpoint that you like through the screens object for tailwind.config.js file. ```js {4} module.exports = withMT({ @@ -61,7 +61,7 @@ module.exports = withMT({ You can add new breakpoint for @material-tailwind/html very easy and straightforward, it's the same as adding new breakpoint for tailwindcss. -You just need to add your own breakpoint to the extend and screens object for tailwind.config.js file. +You just need to add your own breakpoint to the extend and screens object for tailwind.config.js file. ```js {5} module.exports = withMT({ diff --git a/documentation/html/shadows.mdx b/documentation/html/shadows.mdx index 8159c7a6b..59afb7d7f 100644 --- a/documentation/html/shadows.mdx +++ b/documentation/html/shadows.mdx @@ -42,7 +42,7 @@ const boxShadow = { You can customize the default box shadow values for @material-tailwind/html very easy and straightforward, it's the same as customizing box shadow values for tailwindcss. -You just need to customize the box shadow value that you like through the boxShadow object for tailwind.config.js file. +You just need to customize the box shadow value that you like through the boxShadow object for tailwind.config.js file. ```js {4} module.exports = withMT({ @@ -63,7 +63,7 @@ module.exports = withMT({ You can add new box shadow value for @material-tailwind/html very easy and straightforward, it's the same as adding new box shadow value for tailwindcss. -You just need to add your own box shadow value to the extend and boxShadow object for tailwind.config.js file. +You just need to add your own box shadow value to the extend and boxShadow object for tailwind.config.js file. ```js {5} module.exports = withMT({ diff --git a/documentation/html/skeleton.mdx b/documentation/html/skeleton.mdx new file mode 100644 index 000000000..e72eee942 --- /dev/null +++ b/documentation/html/skeleton.mdx @@ -0,0 +1,180 @@ +--- +title: Tailwind CSS Skeleton for HTML - Material Tailwind +description: Customise your web projects with our easy-to-use skeleton component for Tailwind CSS and HTML using Material Design guidelines. +navigation: + [ + "skeleton", + "image-placeholder-skeleton", + "video-placeholder-skeleton", + "text-placeholder-skeleton", + "card-placeholder-skeleton", + "testimonial-placeholder-skeleton" + ] +github: skeleton +prev: sidebar +next: speed-dial +--- + + +# Tailwind CSS Skeleton - HTML + + +The skeleton component can be used as an alternative loading indicator to the spinner by mimicking the content that will be loaded such as text, images, or video + +See below our simple Skeleton example that you can use in your Tailwind CSS and HTML project. + +
+ +}> +```jsx +
+
+   +
+
+   +
+
+   +
+
+   +
+
+   +
+
+``` +
+ +--- + + +## Image placeholder Skeleton + + +}> +```html +
+
+ + + + +
+
+
+   +
+
+   +
+
+   +
+
+   +
+
+   +
+
+   +
+
+   +
+
+
+``` +
+ +--- + + + +## Video placeholder Skeleton + + +}> +```html +
+ + + + +
+``` +
+ +--- + + + + +## Card placeholder Skeleton + + +}> +```html +
+
+ + + + +
+
+
+   +
+
+   +
+
+   +
+
+   +
+
+   +
+
+
+ +
+
+``` +
+ +--- diff --git a/documentation/html/tabs.mdx b/documentation/html/tabs.mdx index 95adba07f..eaa091f5a 100644 --- a/documentation/html/tabs.mdx +++ b/documentation/html/tabs.mdx @@ -135,7 +135,7 @@ The tabs component comes with different variants including icons. ## Tabs with Content -You can reference a specific content for each tab option, using the data-tab-content data attribute. +You can reference a specific content for each tab option, using the data-tab-content data attribute. tailwind.config.js
and you can set your own theme and styles through the Tailwind CSS configurations for all of the components. +@material-tailwind/html is customizable using the tailwind.config.js and you can set your own theme and styles through the Tailwind CSS configurations for all of the components. --- @@ -22,11 +22,11 @@ style. -Each component has a class attribute that you can use to add tailwindcss classnames or your own custom classnames. +Each component has a class attribute that you can use to add tailwindcss classnames or your own custom classnames. -The class attribute overrides the tailwindcss classnames for a component and sometimes you need to use the ! modifier before the tailwindcss classnames to override the classnames for a component. +The class attribute overrides the tailwindcss classnames for a component and sometimes you need to use the ! modifier before the tailwindcss classnames to override the classnames for a component. -e.g. !text-blue-500 +e.g. !text-blue-500 ```html
- {`Material Tailwind`} + Material Tailwind
```
@@ -48,7 +48,7 @@ You can initialize a new tooltip by adding the data-tooltip-target="` ## Tooltip Placement -You can change the position of the tooltip relative to it's trigger element by adding the data-tooltip-placement="`{top}`" data attribute to the tooltip element by default it set's to top.
Check the placement values for tooltip here. +You can change the position of the tooltip relative to it's trigger element by adding the data-tooltip-placement="`{top}`" data attribute to the tooltip element by default it set's to top.
Check the placement values for tooltip here.
- {`Material Tailwind`} + Material Tailwind
- {`Material Tailwind`} + Material Tailwind
- {`Material Tailwind`} + Material Tailwind
- {`Material Tailwind`} + Material Tailwind
- {`Material Tailwind`} + Material Tailwind
- {`Material Tailwind`} + Material Tailwind
- {`Material Tailwind`} + Material Tailwind
- {`Material Tailwind`} + Material Tailwind
- {`Material Tailwind`} + Material Tailwind
- {`Material Tailwind`} + Material Tailwind
- {`Material Tailwind`} + Material Tailwind
- {`Material Tailwind`} + Material Tailwind
``` @@ -167,7 +167,7 @@ You can change the position of the tooltip relative to it's trigger element by a ## Custom Tooltip Animation -You can modify the open/close state animation for tooltip by adding the data-tooltip-mount="`{opacity-100}`", data-tooltip-unmount="`{opacity-0}`" and data-tooltip-transition="`{transition-opacity}`" data attributes to the tooltip element. You can pass tailwind css classnames for those data attributes for animation the tooltip.
Check more about animation data attributes for tooltip here. +You can modify the open/close state animation for tooltip by adding the data-tooltip-mount="`{opacity-100}`", data-tooltip-unmount="`{opacity-0}`" and data-tooltip-transition="`{transition-opacity}`" data attributes to the tooltip element. You can pass tailwind css classnames for those data attributes for animation the tooltip.
Check more about animation data attributes for tooltip here. - {`Show Tooltip`} + Show Tooltip
- {`Material Tailwind`} + Material Tailwind
```
@@ -210,10 +210,10 @@ The following data attributes are available for tooltip element. | ------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | | `data-tooltip` | Set the name of the tooltip and reference it to the
tooltip trigger element. | | | `data-tooltip-offset` | Set the offset between the tooltip and the tooltip trigger element. | 5 | -| `data-tooltip-placement` | Set the position of the tooltip relative to it's trigger element. | top | -| `data-tooltip-mount` | Set the classnaes that should be used when the
tooltip is visible. | opacity-1 | -| `data-tooltip-unmount` | Set the classnaes that should be used when the
tooltip is hidden. | opacity-0
pointer-events-none | -| `data-tooltip-transition` | Set the classnaes that should be used for
transition of the tooltip. | transition-opacity
duration-300 | +| `data-tooltip-placement` | Set the position of the tooltip relative to it's trigger element. | top | +| `data-tooltip-mount` | Set the classnaes that should be used when the
tooltip is visible. | opacity-1 | +| `data-tooltip-unmount` | Set the classnaes that should be used when the
tooltip is hidden. | opacity-0
pointer-events-none | +| `data-tooltip-transition` | Set the classnaes that should be used for
transition of the tooltip. | transition-opacity
duration-300 | --- diff --git a/documentation/react/gallery.mdx b/documentation/react/gallery.mdx new file mode 100644 index 000000000..ec2898a66 --- /dev/null +++ b/documentation/react/gallery.mdx @@ -0,0 +1,549 @@ +--- +title: Tailwind CSS Gallery for React - Material Tailwind +description: Customise your web projects with our easy-to-use gallery component for Tailwind CSS and React using Material Design guidelines. +navigation: + [ + "gallery", + "masonry-grid-gallery", + "featured-image-gallery", + "quad-gallery", + "gallery-with-carousel", + "gallery-with-tab" + ] +github: skeleton +prev: form +next: icon-button +--- + + +# Tailwind CSS Gallery - React + + +Use the image gallery component + +See below our simple Gallery example that you can use in your Tailwind CSS and React project. + +
+ +}> +```jsx +export function DefaultGallery() { + const data = [ + { + imageLink: + "https://images.unsplash.com/photo-1499696010180-025ef6e1a8f9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1432462770865-65b70566d673?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1497436072909-60f360e1d4b1?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2560&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + { + imageLink: + "https://demos.creative-tim.com/material-kit-pro/assets/img/examples/blog5.jpg", + }, + { + imageLink: + "https://material-taillwind-pro-ct-tailwind-team.vercel.app/img/content2.jpg", + }, + { + imageLink: + "https://images.unsplash.com/photo-1620064916958-605375619af8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1493&q=80", + }, + ]; + + return ( +
+ {data.map(({ imageLink }, index) => ( +
+ gallery-photo +
+ ))} +
+ ); +} + +``` +
+ +--- + + + +## Masonry Grid Galery - React + +
+ +}> +```jsx +export function MasonryGridGallery() { + return ( +
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+
+ gallery-photo +
+
+ gallery-photo +
+
+
+ ); +} +``` +
+ +--- + + + +## Featured Image Galery + +
+ +}> +```jsx +import React from "react"; +export function FeaturedImageGallery() { + const data = [ + { + imgelink: + "https://images.unsplash.com/photo-1499696010180-025ef6e1a8f9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80", + }, + { + imgelink: + "https://images.unsplash.com/photo-1432462770865-65b70566d673?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80", + }, + { + imgelink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imgelink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imgelink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + ]; + + const [active, setActive] = React.useState( + "https://images.unsplash.com/photo-1499696010180-025ef6e1a8f9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80", + ); + + return ( +
+
+ +
+
+ {data.map(({ imgelink }, index) => ( +
+ setActive(imgelink)} + src={imgelink} + className="h-20 max-w-full cursor-pointer rounded-lg object-cover object-center" + alt="gallery-image" + /> +
+ ))} +
+
+ ); +} +``` +
+ +--- + + + + +## Quad Galery + +
+ +}> +```jsx +export function QuadGallery() { + const data = [ + { + imageLink: + "https://images.unsplash.com/photo-1499696010180-025ef6e1a8f9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1432462770865-65b70566d673?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1497436072909-60f360e1d4b1?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2560&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + ]; + + return ( +
+ {data.map(({ imageLink }, index) => ( +
+ +
+ ))} +
+ ); +} +``` +
+ +--- + + + + +## Gallery With Carousel + +
+ +}> +```jsx +import { Carousel } from "@material-tailwind/react"; + +export function GalleryWithCarousel() { + return ( + + image 1 + image 2 + image 3 + + ); +} +``` + + +--- + + + +## Gallery With Tab - React + +
+ +}> +```jsx +import { + Tabs, + TabsHeader, + TabsBody, + Tab, + TabPanel, +} from "@material-tailwind/react"; + +export function GalleryWithTab() { + const data = [ + { + label: "HTML", + value: "html", + images: [ + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + { + imageLink: + "https://demos.creative-tim.com/material-kit-pro/assets/img/examples/blog5.jpg", + }, + { + imageLink: + "https://material-taillwind-pro-ct-tailwind-team.vercel.app/img/content2.jpg", + }, + { + imageLink: + "https://images.unsplash.com/photo-1620064916958-605375619af8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1493&q=80", + }, + ], + }, + { + label: "React", + value: "react", + images: [ + { + imageLink: + "https://images.unsplash.com/photo-1499696010180-025ef6e1a8f9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1432462770865-65b70566d673?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1497436072909-60f360e1d4b1?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2560&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + ], + }, + { + label: "Vue", + value: "vue", + images: [ + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + { + imageLink: + "https://demos.creative-tim.com/material-kit-pro/assets/img/examples/blog5.jpg", + }, + { + imageLink: + "https://material-taillwind-pro-ct-tailwind-team.vercel.app/img/content2.jpg", + }, + { + imageLink: + "https://images.unsplash.com/photo-1620064916958-605375619af8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1493&q=80", + }, + ], + }, + { + label: "Angular", + value: "angular", + images: [ + { + imageLink: + "https://images.unsplash.com/photo-1499696010180-025ef6e1a8f9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1432462770865-65b70566d673?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1497436072909-60f360e1d4b1?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2560&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + ], + }, + { + label: "Svelte", + value: "svelte", + images: [ + { + imageLink: + "https://demos.creative-tim.com/material-kit-pro/assets/img/examples/blog5.jpg", + }, + { + imageLink: + "https://material-taillwind-pro-ct-tailwind-team.vercel.app/img/content2.jpg", + }, + { + imageLink: + "https://images.unsplash.com/photo-1620064916958-605375619af8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1493&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1518623489648-a173ef7824f3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2762&q=80", + }, + { + imageLink: + "https://images.unsplash.com/photo-1682407186023-12c70a4a35e0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=80", + }, + ], + }, + ]; + + return ( + + + {data.map(({ label, value }) => ( + + {label} + + ))} + + + {data.map(({ value, images }) => ( + + {images?.map(({ imageLink }, index) => ( +
+ image-photo +
+ ))} +
+ ))} +
+
+ ); +} +``` +
+ +--- diff --git a/documentation/react/installation.mdx b/documentation/react/installation.mdx index 9d88fc492..715c6a5b0 100644 --- a/documentation/react/installation.mdx +++ b/documentation/react/installation.mdx @@ -34,6 +34,66 @@ Learn how to use @material-tailwind/react components from this documentation to

+## Using NPM + +Install @material-tailwind/react as a dependency using NPM by running the following command: + + + +```bash +npm i @material-tailwind/react +``` + +--- + +## Using Yarn + +Install @material-tailwind/react as a dependency using Yarn by running the following command: + + + +```bash +yarn add @material-tailwind/react +``` + +--- + +## Using PNPM + +Install @material-tailwind/react as a dependency using PNPM by running the following command: + + + +```bash +pnpm i @material-tailwind/react +``` + +--- + +## TailwindCSS Configurations + + + +Once you install @material-tailwind/react you need to wrap your tailwind css configurations with the withMT() function coming from @material-tailwind/react/utils. + +```js {1, 3, 9} +const withMT = require("@material-tailwind/react/utils/withMT"); + +module.exports = withMT({ + content: [], + theme: { + extend: {}, + }, + plugins: [], +}); +``` + +
+ +For more guides on how to use @material-tailwind/react with different frameworks, check the Frameworks Integration section. + +--- + ## Frameworks Integration diff --git a/documentation/react/mega-menu.mdx b/documentation/react/mega-menu.mdx new file mode 100644 index 000000000..7b62f6cce --- /dev/null +++ b/documentation/react/mega-menu.mdx @@ -0,0 +1,724 @@ +--- +title: Tailwind CSS Mega Menu for React - Material Tailwind +description: Customise your web projects with our mega menu component for Tailwind CSS and React using Material Design guidelines. +navigation: + [ + "mega-menu", + "mega-menu-with-hover", + "mage-menu-placement", + + ] +github: menu +prev: input +next: navbar +--- + + +# Tailwind CSS Mega Menu - React + + +Use our responsive Tailwind CSS Mega Menu, that can take the user anywhere on your web app! + + +See below our Mega Menu example that you can use in your Tailwind CSS and React project. + +
+ +}> +```jsx +import React from "react"; +import { + Navbar, + Collapse, + Typography, + IconButton, + List, + ListItem, + Menu, + MenuHandler, + MenuList, + MenuItem, +} from "@material-tailwind/react"; +import { + ChevronDownIcon, + Bars3Icon, + XMarkIcon, +} from "@heroicons/react/24/outline"; +import { + Bars4Icon, + GlobeAmericasIcon, + NewspaperIcon, + PhoneIcon, + RectangleGroupIcon, + SquaresPlusIcon, + SunIcon, + TagIcon, + UserGroupIcon, +} from "@heroicons/react/24/solid"; + +const navListMenuItems = [ + { + title: "Products", + description: "Find the perfect solution for your needs.", + icon: SquaresPlusIcon, + }, + { + title: "About Us", + description: "Meet and learn about our dedication", + icon: UserGroupIcon, + }, + { + title: "Blog", + description: "Find the perfect solution for your needs.", + icon: Bars4Icon, + }, + { + title: "Services", + description: "Learn how we can help you achieve your goals.", + icon: SunIcon, + }, + { + title: "Support", + description: "Reach out to us for assistance or inquiries", + icon: GlobeAmericasIcon, + }, + { + title: "Contact", + description: "Find the perfect solution for your needs.", + icon: PhoneIcon, + }, + { + title: "News", + description: "Read insightful articles, tips, and expert opinions.", + icon: NewspaperIcon, + }, + { + title: "Products", + description: "Find the perfect solution for your needs.", + icon: RectangleGroupIcon, + }, + { + title: "Special Offers", + description: "Explore limited-time deals and bundles", + icon: TagIcon, + }, +]; + +function NavListMenu() { + const [isMenuOpen, setIsMenuOpen] = React.useState(false); + const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false); + const renderItems = navListMenuItems.map( + ({ icon, title, description }, key) => ( + + +
+ {" "} + {React.createElement(icon, { + strokeWidth: 2, + className: "h-6 text-gray-900 w-6", + })} +
+
+ + {title} + + + {description} + +
+
+
+ ), + ); + + return ( + + + + + setIsMobileMenuOpen((cur) => !cur)} + > + Resources + + + + + + +
    + {renderItems} +
+
+
+
+ {renderItems} +
+
+ ); +} + +function NavList() { + return ( + + + Home + + + + + Contact Us + + + + ); +} + +export function MegaMenuDefault() { + const [openNav, setOpenNav] = React.useState(false); + + React.useEffect(() => { + window.addEventListener( + "resize", + () => window.innerWidth >= 960 && setOpenNav(false), + ); + }, []); + + return ( + +
+ + Material Tailwind + +
+ +
+ setOpenNav(!openNav)} + > + {openNav ? ( + + ) : ( + + )} + +
+ + + +
+ ); +} +``` +
+ +--- + + + +## Mega Menu With Hover + + +The default trigger mode is click, you can change it hover by changing allowHover props. + +}> +```jsx +import React from "react"; +import { + Navbar, + Collapse, + Typography, + IconButton, + List, + ListItem, + Menu, + MenuHandler, + MenuList, + MenuItem, +} from "@material-tailwind/react"; +import { + ChevronDownIcon, + Bars3Icon, + XMarkIcon, +} from "@heroicons/react/24/outline"; +import { + Bars4Icon, + GlobeAmericasIcon, + NewspaperIcon, + PhoneIcon, + RectangleGroupIcon, + SquaresPlusIcon, + SunIcon, + TagIcon, + UserGroupIcon, +} from "@heroicons/react/24/solid"; + +const navListMenuItems = [ + { + title: "Products", + description: "Find the perfect solution for your needs.", + icon: SquaresPlusIcon, + }, + { + title: "About Us", + description: "Meet and learn about our dedication", + icon: UserGroupIcon, + }, + { + title: "Blog", + description: "Find the perfect solution for your needs.", + icon: Bars4Icon, + }, + { + title: "Services", + description: "Learn how we can help you achieve your goals.", + icon: SunIcon, + }, + { + title: "Support", + description: "Reach out to us for assistance or inquiries", + icon: GlobeAmericasIcon, + }, + { + title: "Contact", + description: "Find the perfect solution for your needs.", + icon: PhoneIcon, + }, + { + title: "News", + description: "Read insightful articles, tips, and expert opinions.", + icon: NewspaperIcon, + }, + { + title: "Products", + description: "Find the perfect solution for your needs.", + icon: RectangleGroupIcon, + }, + { + title: "Special Offers", + description: "Explore limited-time deals and bundles", + icon: TagIcon, + }, +]; + +function NavListMenu() { + const [isMenuOpen, setIsMenuOpen] = React.useState(false); + const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false); + const renderItems = navListMenuItems.map( + ({ icon, title, description }, key) => ( + + +
+ {" "} + {React.createElement(icon, { + strokeWidth: 2, + className: "h-6 text-gray-900 w-6", + })} +
+
+ + {title} + + + {description} + +
+
+
+ ), + ); + + return ( + + + + + setIsMobileMenuOpen((cur) => !cur)} + > + Resources + + + + + + +
    + {renderItems} +
+
+
+
+ {renderItems} +
+
+ ); +} + +function NavList() { + return ( + + + Home + + + + + Contact Us + + + + ); +} + +export function MegaMenuWithHover() { + const [openNav, setOpenNav] = React.useState(false); + + React.useEffect(() => { + window.addEventListener( + "resize", + () => window.innerWidth >= 960 && setOpenNav(false), + ); + }, []); + + return ( + +
+ + Material Tailwind + +
+ +
+ setOpenNav(!openNav)} + > + {openNav ? ( + + ) : ( + + )} + +
+ + + +
+ ); +} +``` +
+ +--- + + +## Mega Menu Placement + + +You can change the position of the Mega Menu component using the placement prop. + +}> +```jsx +import React from "react"; +import { + Navbar, + Collapse, + Typography, + IconButton, + List, + ListItem, + Menu, + MenuHandler, + MenuList, + MenuItem, +} from "@material-tailwind/react"; +import { + ChevronDownIcon, + Bars3Icon, + XMarkIcon, +} from "@heroicons/react/24/outline"; +import { + Bars4Icon, + GlobeAmericasIcon, + PhoneIcon, + SquaresPlusIcon, + SunIcon, + UserGroupIcon, +} from "@heroicons/react/24/solid"; + +const navListMenuItems = [ + { + title: "Products", + description: "Find the perfect solution for your needs.", + icon: SquaresPlusIcon, + }, + { + title: "About Us", + description: "Meet and learn about our dedication", + icon: UserGroupIcon, + }, + { + title: "Blog", + description: "Find the perfect solution for your needs.", + icon: Bars4Icon, + }, + { + title: "Services", + description: "Learn how we can help you achieve your goals.", + icon: SunIcon, + }, + { + title: "Support", + description: "Reach out to us for assistance or inquiries", + icon: GlobeAmericasIcon, + }, + { + title: "Contact", + description: "Find the perfect solution for your needs.", + icon: PhoneIcon, + }, +]; + +function NavListMenu() { + const [isMenuOpen, setIsMenuOpen] = React.useState(false); + const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false); + const renderItems = navListMenuItems.map( + ({ icon, title, description }, key) => ( + + +
+ {" "} + {React.createElement(icon, { + strokeWidth: 2, + className: "h-6 text-gray-900 w-6", + })} +
+
+ + {title} + + + {description} + +
+
+
+ ), + ); + + return ( + + + + + setIsMobileMenuOpen((cur) => !cur)} + > + Resources + + + + + + +
    + {renderItems} +
+
+
+
+ {renderItems} +
+
+ ); +} + +function NavList() { + return ( + + + Home + + + + + Contact Us + + + + ); +} + +export function MegaMenuWithPlacement() { + const [openNav, setOpenNav] = React.useState(false); + + React.useEffect(() => { + window.addEventListener( + "resize", + () => window.innerWidth >= 960 && setOpenNav(false), + ); + }, []); + + return ( + +
+ + Material Tailwind + +
+ +
+ setOpenNav(!openNav)} + > + {openNav ? ( + + ) : ( + + )} + +
+ + + +
+ ); +} +``` +
+ +--- diff --git a/documentation/react/plugins/clipboard.mdx b/documentation/react/plugins/clipboard.mdx new file mode 100644 index 000000000..92b544a93 --- /dev/null +++ b/documentation/react/plugins/clipboard.mdx @@ -0,0 +1,226 @@ +--- +title: Tailwind CSS Clipboard for React - Material Tailwind +description: Customise your web projects with our easy-to-use clipboard example for Tailwind CSS and React using Material Design guidelines. +navigation: + [ + "clipboard", + "clipboard-copy-input", + "clipboard-copy-button", + "clipboard-with-tooltip", + + ] +github: plugins/clipboard +prev: plugins/charts +next: plugins/date-picker +--- + + +# Tailwind CSS Clipboard - React + + +Use our Tailwind CSS Date Picker example to to facilitate the copying and pasting of data within an application. + +See below our beautiful clipboard example that you can use in your Tailwind CSS and React project. The example below is using the `usehooks-ts` libraries, make sure to install them before using the example. + +```bash +npm i usehooks-ts +``` + +
+
+ +}> +```jsx +import React from "react"; +import { IconButton, Typography } from "@material-tailwind/react"; +import { useCopyToClipboard } from "usehooks-ts"; +import { CheckIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; + +export function ClipboardDefault() { + const [value, copy] = useCopyToClipboard(); + const [copied, setCopied] = React.useState(false); + + return ( +
+
+ npm i @material-tailwind/react + setCopied(false)} + onClick={() => { + copy("npm i @material-tailwind/react"); + setCopied(true); + }} + > + {copied ? ( + + ) : ( + + )} + +
+
+ ); +} +``` +
+ +--- + + + +## Copy from Input + + + +}> +```jsx +import React from "react"; +import { Input, Button } from "@material-tailwind/react"; +import { useCopyToClipboard } from "usehooks-ts"; +import { CheckIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; + +export function ClipboardCopyInput() { + const [value, copy] = useCopyToClipboard(); + const [copied, setCopied] = React.useState(false); + const [inputValue, setInputValue] = React.useState( + "npm i @material-tailwind/react", + ); + + return ( +
+
+ { + setInputValue(e.target.value); + }} + containerProps={{ className: "min-w-[100px]" }} + /> +
+ +
+ ); +} +``` +
+ +--- + + + +## Copy Button + + + +}> +```jsx +import React from "react"; +import { Typography, Button } from "@material-tailwind/react"; +import { useCopyToClipboard } from "usehooks-ts"; +import { CheckIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; + +export function ClipboardCopyButton() { + const [value, copy] = useCopyToClipboard(); + const [copied, setCopied] = React.useState(false); + + return ( + + ); +} +``` + + +--- + + + + +## Copy Button With Tooltip + + + +}> +```jsx +import React from "react"; +import { Typography, Button, Tooltip } from "@material-tailwind/react"; +import { useCopyToClipboard } from "usehooks-ts"; +import { CheckIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; + +export function ClipboardWithTooltip() { + const [value, copy] = useCopyToClipboard(); + const [copied, setCopied] = React.useState(false); + + return ( + + + + ); +} +``` + + +--- \ No newline at end of file diff --git a/documentation/react/plugins/text-editor.mdx b/documentation/react/plugins/text-editor.mdx new file mode 100644 index 000000000..e7690806a --- /dev/null +++ b/documentation/react/plugins/text-editor.mdx @@ -0,0 +1,1147 @@ +--- +title: Tailwind CSS WYSIWYG Editor for React - Material Tailwind +description: Customise your web projects with our easy-to-use WYSIWYG Editor example for Tailwind CSS and React using Material Design guidelines. +navigation: + [ + "wysiwyg-editor", + "plugins-installation", + "adding-styles", + ] +github: plugins/text-editor +prev: table +next: plugins/algolia-search +--- + + +# Tailwind CSS WYSIWYG Editor - React + + +Use our Tailwind CSS WYSIWYG Editor in your web projects. + +See below our beautiful WYSIWYG Editor example that you can use in your Tailwind CSS and React project. The example below is using the lexical and @lexical/react libraries, make sure to install them before using the example. + +```bash +npm install --save lexical @lexical/react +``` + +
+
+ + +## Plugins Installation + + +Lexical provides a set of plugins that you can use to extend the functionality of the editor. In the example below we are using some of the plugins and you need to install them, run the below command to install the plugins. + +
+
+ +```bash +npm install --save @lexical/list @lexical/rich-text @lexical/code @lexical/link @lexical/selection @lexical/utils +``` + +}> +```jsx +import { createPortal } from "react-dom"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { + List, + Input, + Button, + ListItem, + IconButton, + Typography, + ListItemPrefix, +} from "@material-tailwind/react"; + +// lexical +import { + $getNodeByKey, + $getSelection, + $isRangeSelection, + FORMAT_TEXT_COMMAND, + $createParagraphNode, + SELECTION_CHANGE_COMMAND, +} from "lexical"; +import { + $isListNode, + REMOVE_LIST_COMMAND, + INSERT_ORDERED_LIST_COMMAND, + INSERT_UNORDERED_LIST_COMMAND, +} from "@lexical/list"; +import { + QuoteNode, + HeadingNode, + $isHeadingNode, + $createQuoteNode, + $createHeadingNode, +} from "@lexical/rich-text"; +import { + $isCodeNode, + $createCodeNode, + getCodeLanguages, + getDefaultCodeLanguage, +} from "@lexical/code"; +import { ListItemNode, ListNode } from "@lexical/list"; +import { + AutoLinkNode, + LinkNode, + $isLinkNode, + TOGGLE_LINK_COMMAND, +} from "@lexical/link"; +import { CodeHighlightNode, CodeNode } from "@lexical/code"; +import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin"; +import { ListPlugin } from "@lexical/react/LexicalListPlugin"; +import { $wrapNodes, $isAtNodeEnd } from "@lexical/selection"; +import { LexicalComposer } from "@lexical/react/LexicalComposer"; +import { $getNearestNodeOfType, mergeRegister } from "@lexical/utils"; +import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin"; +import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin"; +import { ContentEditable } from "@lexical/react/LexicalContentEditable"; +import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext"; + +const LowPriority = 1; + +const supportedBlockTypes = new Set([ + "paragraph", + "quote", + "code", + "h1", + "h2", + "ul", + "ol", +]); + +const blockTypeToBlockName = { + code: "Code", + h1: "Large Heading", + h2: "Small Heading", + h3: "Heading", + h4: "Heading", + h5: "Heading", + ol: "Numbered List", + paragraph: "Normal", + quote: "Quote", + ul: "Bulleted List", +}; + +function Divider() { + return
; +} + +function Placeholder() { + return ( +
+ Play around with the editor... +
+ ); +} + +function Select({ onChange, className, options, value }) { + return ( + + ); +} + +function getSelectedNode(selection) { + const anchor = selection.anchor; + const focus = selection.focus; + const anchorNode = selection.anchor.getNode(); + const focusNode = selection.focus.getNode(); + if (anchorNode === focusNode) { + return anchorNode; + } + const isBackward = selection.isBackward(); + if (isBackward) { + return $isAtNodeEnd(focus) ? anchorNode : focusNode; + } else { + return $isAtNodeEnd(anchor) ? focusNode : anchorNode; + } +} + +function BlockOptionsDropdownList({ + editor, + blockType, + toolbarRef, + setShowBlockOptionsDropDown, +}) { + const dropDownRef = useRef(null); + + useEffect(() => { + const toolbar = toolbarRef.current; + const dropDown = dropDownRef.current; + + if (toolbar !== null && dropDown !== null) { + const { top, left } = toolbar.getBoundingClientRect(); + dropDown.style.top = `${top + 40}px`; + dropDown.style.left = `${left}px`; + } + }, [dropDownRef, toolbarRef]); + + useEffect(() => { + const dropDown = dropDownRef.current; + const toolbar = toolbarRef.current; + + if (dropDown !== null && toolbar !== null) { + const handle = (event) => { + const target = event.target; + + if (!dropDown.contains(target) && !toolbar.contains(target)) { + setShowBlockOptionsDropDown(false); + } + }; + document.addEventListener("click", handle); + + return () => { + document.removeEventListener("click", handle); + }; + } + }, [dropDownRef, setShowBlockOptionsDropDown, toolbarRef]); + + const formatParagraph = () => { + if (blockType !== "paragraph") { + editor.update(() => { + const selection = $getSelection(); + + if ($isRangeSelection(selection)) { + $wrapNodes(selection, () => $createParagraphNode()); + } + }); + } + setShowBlockOptionsDropDown(false); + }; + + const formatLargeHeading = () => { + if (blockType !== "h1") { + editor.update(() => { + const selection = $getSelection(); + + if ($isRangeSelection(selection)) { + $wrapNodes(selection, () => $createHeadingNode("h1")); + } + }); + } + setShowBlockOptionsDropDown(false); + }; + + const formatSmallHeading = () => { + if (blockType !== "h2") { + editor.update(() => { + const selection = $getSelection(); + + if ($isRangeSelection(selection)) { + $wrapNodes(selection, () => $createHeadingNode("h2")); + } + }); + } + setShowBlockOptionsDropDown(false); + }; + + const formatBulletList = () => { + if (blockType !== "ul") { + editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND); + } else { + editor.dispatchCommand(REMOVE_LIST_COMMAND); + } + setShowBlockOptionsDropDown(false); + }; + + const formatNumberedList = () => { + if (blockType !== "ol") { + editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND); + } else { + editor.dispatchCommand(REMOVE_LIST_COMMAND); + } + setShowBlockOptionsDropDown(false); + }; + + const formatQuote = () => { + if (blockType !== "quote") { + editor.update(() => { + const selection = $getSelection(); + + if ($isRangeSelection(selection)) { + $wrapNodes(selection, () => $createQuoteNode()); + } + }); + } + setShowBlockOptionsDropDown(false); + }; + + const formatCode = () => { + if (blockType !== "code") { + editor.update(() => { + const selection = $getSelection(); + + if ($isRangeSelection(selection)) { + $wrapNodes(selection, () => $createCodeNode()); + } + }); + } + setShowBlockOptionsDropDown(false); + }; + + return ( + + + + + + + + + Normal + + + + + + + + + + Large Heading + + + + + + + + + + + Small Heading + + + + + + + + + + + + + Bullet List + + + + + + + + + + + + + + Numbered List + + + + + + + + + Quote + + + + + + + + + + Code + + + ); +} + +function positionEditorElement(editor, rect) { + if (rect === null) { + editor.style.opacity = "0"; + editor.style.top = "-1000px"; + editor.style.left = "-1000px"; + } else { + editor.style.opacity = "1"; + editor.style.top = `${rect.top + rect.height + window.pageYOffset + 10}px`; + editor.style.left = `${ + rect.left + window.pageXOffset - editor.offsetWidth / 2 + rect.width / 2 + }px`; + } +} + +function FloatingLinkEditor({ editor }) { + const editorRef = useRef(null); + const inputRef = useRef(null); + const mouseDownRef = useRef(false); + const [linkUrl, setLinkUrl] = useState(""); + const [isEditMode, setEditMode] = useState(false); + const [lastSelection, setLastSelection] = useState(null); + + const updateLinkEditor = useCallback(() => { + const selection = $getSelection(); + if ($isRangeSelection(selection)) { + const node = getSelectedNode(selection); + const parent = node.getParent(); + if ($isLinkNode(parent)) { + setLinkUrl(parent.getURL()); + } else if ($isLinkNode(node)) { + setLinkUrl(node.getURL()); + } else { + setLinkUrl(""); + } + } + const editorElem = editorRef.current; + const nativeSelection = window.getSelection(); + const activeElement = document.activeElement; + + if (editorElem === null) { + return; + } + + const rootElement = editor.getRootElement(); + if ( + selection !== null && + !nativeSelection.isCollapsed && + rootElement !== null && + rootElement.contains(nativeSelection.anchorNode) + ) { + const domRange = nativeSelection.getRangeAt(0); + let rect; + if (nativeSelection.anchorNode === rootElement) { + let inner = rootElement; + while (inner.firstElementChild != null) { + inner = inner.firstElementChild; + } + rect = inner.getBoundingClientRect(); + } else { + rect = domRange.getBoundingClientRect(); + } + + if (!mouseDownRef.current) { + positionEditorElement(editorElem, rect); + } + setLastSelection(selection); + } else if (!activeElement || activeElement.className !== "link-input") { + positionEditorElement(editorElem, null); + setLastSelection(null); + setEditMode(false); + setLinkUrl(""); + } + + return true; + }, [editor]); + + useEffect(() => { + return mergeRegister( + editor.registerUpdateListener(({ editorState }) => { + editorState.read(() => { + updateLinkEditor(); + }); + }), + + editor.registerCommand( + SELECTION_CHANGE_COMMAND, + () => { + updateLinkEditor(); + return true; + }, + LowPriority, + ), + ); + }, [editor, updateLinkEditor]); + + useEffect(() => { + editor.getEditorState().read(() => { + updateLinkEditor(); + }); + }, [editor, updateLinkEditor]); + + useEffect(() => { + if (isEditMode && inputRef.current) { + inputRef.current.focus(); + } + }, [isEditMode]); + + return ( +
+ {isEditMode ? ( + { + setLinkUrl(event.target.value); + }} + onKeyDown={(event) => { + if (event.key === "Enter") { + event.preventDefault(); + if (lastSelection !== null) { + if (linkUrl !== "") { + editor.dispatchCommand(TOGGLE_LINK_COMMAND, linkUrl); + } + setEditMode(false); + } + } else if (event.key === "Escape") { + event.preventDefault(); + setEditMode(false); + } + }} + className="border-gray-200 !border-t-gray-200 focus:!border-gray-900 focus:!border-t-gray-900" + labelProps={{ + className: "hidden", + }} + /> + ) : ( + <> +
+ + {linkUrl} + + event.preventDefault()} + onClick={() => { + setEditMode(true); + }} + > + + + + +
+ + )} +
+ ); +} + +function ToolbarPlugin() { + const [editor] = useLexicalComposerContext(); + const toolbarRef = useRef(null); + const [blockType, setBlockType] = useState("paragraph"); + const [selectedElementKey, setSelectedElementKey] = useState(null); + const [showBlockOptionsDropDown, setShowBlockOptionsDropDown] = + useState(false); + const [codeLanguage, setCodeLanguage] = useState(""); + const [isLink, setIsLink] = useState(false); + const [isBold, setIsBold] = useState(false); + const [isItalic, setIsItalic] = useState(false); + const [isStrikethrough, setIsStrikethrough] = useState(false); + const [isCode, setIsCode] = useState(false); + + const updateToolbar = useCallback(() => { + const selection = $getSelection(); + if ($isRangeSelection(selection)) { + const anchorNode = selection.anchor.getNode(); + const element = + anchorNode.getKey() === "root" + ? anchorNode + : anchorNode.getTopLevelElementOrThrow(); + const elementKey = element.getKey(); + const elementDOM = editor.getElementByKey(elementKey); + if (elementDOM !== null) { + setSelectedElementKey(elementKey); + if ($isListNode(element)) { + const parentList = $getNearestNodeOfType(anchorNode, ListNode); + const type = parentList ? parentList.getTag() : element.getTag(); + setBlockType(type); + } else { + const type = $isHeadingNode(element) + ? element.getTag() + : element.getType(); + setBlockType(type); + if ($isCodeNode(element)) { + setCodeLanguage(element.getLanguage() || getDefaultCodeLanguage()); + } + } + } + // Update text format + setIsBold(selection.hasFormat("bold")); + setIsItalic(selection.hasFormat("italic")); + setIsStrikethrough(selection.hasFormat("strikethrough")); + setIsCode(selection.hasFormat("code")); + + // Update links + const node = getSelectedNode(selection); + const parent = node.getParent(); + if ($isLinkNode(parent) || $isLinkNode(node)) { + setIsLink(true); + } else { + setIsLink(false); + } + } + }, [editor]); + + useEffect(() => { + return mergeRegister( + editor.registerUpdateListener(({ editorState }) => { + editorState.read(() => { + updateToolbar(); + }); + }), + editor.registerCommand( + SELECTION_CHANGE_COMMAND, + (_payload, newEditor) => { + updateToolbar(); + return false; + }, + LowPriority, + ), + ); + }, [editor, updateToolbar]); + + const codeLanguges = useMemo(() => getCodeLanguages(), []); + const onCodeLanguageSelect = useCallback( + (e) => { + editor.update(() => { + if (selectedElementKey !== null) { + const node = $getNodeByKey(selectedElementKey); + if ($isCodeNode(node)) { + node.setLanguage(e.target.value); + } + } + }); + }, + [editor, selectedElementKey], + ); + + const insertLink = useCallback(() => { + if (!isLink) { + editor.dispatchCommand(TOGGLE_LINK_COMMAND, "https://"); + } else { + editor.dispatchCommand(TOGGLE_LINK_COMMAND, null); + } + }, [editor, isLink]); + + return ( +
+ {supportedBlockTypes.has(blockType) && ( + <> + + {showBlockOptionsDropDown && + createPortal( + , + document.body, + )} + + + )} + {blockType === "code" ? ( + <> + } + label="Search" + /> +
+ + + } + > + + handleOpen(1)} + className="border-b-0 p-3" + > + + + + + Dashboard + + + + + + + + + + Analytics + + + + + + Reporting + + + + + + Projects + + + + + + } + > + + handleOpen(2)} + className="border-b-0 p-3" + > + + + + + E-Commerce + + + + + + + + + + Orders + + + + + + Products + + + + +
+ + + + + Inbox + + + + + + + + + Profile + + + + + + Settings + + + + + + Log Out + +
+ setOpenAlert(false)} + > + + + Upgrade to PRO + + + Upgrade to Material Tailwind PRO and get even more components, + plugins, advanced features and premium. + +
+ setOpenAlert(false)} + > + Dismiss + + + Upgrade Now + +
+
+ + + + ); +} +``` \ No newline at end of file diff --git a/documentation/react/skeleton.mdx b/documentation/react/skeleton.mdx new file mode 100644 index 000000000..7c34b297b --- /dev/null +++ b/documentation/react/skeleton.mdx @@ -0,0 +1,285 @@ +--- +title: Tailwind CSS Skeleton for React - Material Tailwind +description: Customise your web projects with our easy-to-use skeleton component for Tailwind CSS and React using Material Design guidelines. +navigation: + [ + "skeleton", + "image-placeholder-skeleton", + "video-placeholder-skeleton", + "card-placeholder-skeleton", + "testimonial-placeholder-skeleton" + ] +github: skeleton +prev: sidebar +next: speed-dial +--- + + +# Tailwind CSS Skeleton - React + + +The skeleton component can be used as an alternative loading indicator to the spinner by mimicking the content that will be loaded such as text, images, or video + +See below our simple Skeleton example that you can use in your Tailwind CSS and React project. + +
+ +}> +```jsx +import { Typography } from "@material-tailwind/react"; + +export function DefaultSkeleton() { + return ( +
+ +   + + +   + + +   + + +   + + +   + +
+ ); +} +``` +
+ +--- + + +## Image placeholder Skeleton + + +}> +```jsx +import { Typography } from "@material-tailwind/react"; + +export function ImagePlacehoderSkeleton() { + return ( +
+
+ + + +
+
+ +   + + +   + + +   + + +   + + +   + + +   + + +   + +
+
+ ); +} +``` +
+ +--- + + + +## Video placeholder Skeleton + + +}> +```jsx +import { Typography } from "@material-tailwind/react"; + +export function VideoPlacehoderSkeleton() { + return ( +
+ + + +
+ ); +} +``` +
+ +--- + + + +## Card placeholder Skeleton + + +}> +```jsx +import { Button, Typography } from "@material-tailwind/react"; +import Card, { + CardBody, + CardFooter, + CardHeader, +} from "packages/material-tailwind-react/src/components/Card"; + +export function CardPlacehoderSkeleton() { + return ( + + + + + + + + +   + + +   + + +   + + +   + + +   + + + + + + + ); +} +``` + + diff --git a/package.json b/package.json index f3ac3ea0b..8e761e2b2 100644 --- a/package.json +++ b/package.json @@ -20,19 +20,41 @@ "@docsearch/react": "3.5.1", "@floating-ui/dom": "1.1.0", "@floating-ui/react": "0.19.0", - "@fullcalendar/core": "^6.1.9", - "@fullcalendar/daygrid": "^6.1.9", - "@fullcalendar/react": "^6.1.9", + "@fullcalendar/core": "6.1.9", + "@fullcalendar/daygrid": "6.1.9", + "@fullcalendar/react": "6.1.9", "@heroicons/react": "2.0.13", - "apexcharts": "^3.44.0", + "@lexical/code": "0.12.5", + "@lexical/link": "0.12.5", + "@lexical/list": "0.12.5", + "@lexical/markdown": "0.12.5", + "@lexical/react": "0.12.5", + "@lexical/rich-text": "0.12.5", + "@lexical/selection": "0.12.5", + "@lexical/table": "0.12.5", + "@lexical/utils": "0.12.5", + "@tiptap/core": "2.1.13", + "@tiptap/extension-blockquote": "2.1.13", + "@tiptap/extension-bold": "2.1.13", + "@tiptap/extension-bullet-list": "2.1.13", + "@tiptap/extension-link": "2.1.13", + "@tiptap/extension-list-item": "2.1.13", + "@tiptap/extension-ordered-list": "2.1.13", + "@tiptap/extension-paragraph": "2.1.13", + "@tiptap/extension-placeholder": "2.1.13", + "@tiptap/extension-underline": "2.1.13", + "@tiptap/starter-kit": "2.1.13", + "apexcharts": "3.44.0", "classnames": "2.3.2", + "clipboard": "2.0.11", "clsx": "1.2.1", - "date-fns": "^2.30.0", + "date-fns": "2.30.0", "deepmerge": "4.2.2", "flatpickr": "4.6.13", "framer-motion": "6.5.1", "gray-matter": "4.0.3", - "js-cookie": "^3.0.5", + "js-cookie": "3.0.5", + "lexical": "0.12.5", "material-ripple-effects": "2.0.1", "mdx-observable": "0.2.0", "next": "13.1.1", @@ -41,9 +63,9 @@ "prismjs": "1.29.0", "prop-types": "15.8.1", "react": "18.2.0", - "react-apexcharts": "^1.4.1", + "react-apexcharts": "1.4.1", "react-copy-to-clipboard": "5.1.0", - "react-day-picker": "^8.9.1", + "react-day-picker": "8.9.1", "react-dom": "18.2.0", "react-jsx-parser": "1.29.0", "react-simple-code-editor": "0.13.1", @@ -55,11 +77,11 @@ "tailwind-merge": "1.8.1", "un": "0.0.0", "use-react-countries": "1.1.0", - "usehooks-ts": "^2.9.1", + "usehooks-ts": "2.9.1", "uuid": "9.0.0" }, "devDependencies": { - "@types/js-cookie": "^3.0.6", + "@types/js-cookie": "3.0.6", "@types/node": "18.11.18", "@types/react": "18.0.26", "autoprefixer": "10.4.13", @@ -75,7 +97,7 @@ "prettier": "2.8.1", "prettier-plugin-tailwindcss": "0.1.13", "prompts": "2.4.2", - "tailwindcss": "3.2.4", + "tailwindcss": "3.3.6", "typescript": "4.9.4", "unbuild": "1.2.1" } diff --git a/packages/material-tailwind-html/README.md b/packages/material-tailwind-html/README.md index 49c02fc50..795bd8ce3 100644 --- a/packages/material-tailwind-html/README.md +++ b/packages/material-tailwind-html/README.md @@ -8,7 +8,7 @@ Total Downloads - Version + Version Licenese diff --git a/packages/material-tailwind-html/package.json b/packages/material-tailwind-html/package.json index 077fd5fa0..4f373ae90 100644 --- a/packages/material-tailwind-html/package.json +++ b/packages/material-tailwind-html/package.json @@ -1,7 +1,7 @@ { "name": "@material-tailwind/html", "homepage": "https://material-tailwind.com", - "version": "2.1.1", + "version": "2.1.2", "description": "@material-tailwind/html is an easy-to-use components library for Tailwind CSS inspired by Material Design.", "repository": "https://github.com/creativetimofficial/material-tailwind", "license": "MIT", diff --git a/packages/material-tailwind-react/README.md b/packages/material-tailwind-react/README.md index 2a36f9bb5..22a434641 100644 --- a/packages/material-tailwind-react/README.md +++ b/packages/material-tailwind-react/README.md @@ -8,7 +8,7 @@ Total Downloads - Version + Version Licenese diff --git a/packages/material-tailwind-react/package.json b/packages/material-tailwind-react/package.json index 440d3715b..692ace8a6 100644 --- a/packages/material-tailwind-react/package.json +++ b/packages/material-tailwind-react/package.json @@ -1,7 +1,7 @@ { "name": "@material-tailwind/react", "homepage": "https://material-tailwind.com", - "version": "2.1.7", + "version": "2.1.8", "description": "@material-tailwind/react is an easy-to-use components library for ReactJS & Tailwind CSS inspired by Material Design.", "repository": "https://github.com/creativetimofficial/material-tailwind", "license": "MIT", diff --git a/pages/_app.tsx b/pages/_app.tsx index 54b4d6439..8d5ba88a8 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -43,7 +43,7 @@ function MyApp({ Component, pageProps }) { -
+
+ + {" "} +