├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── components ├── Card │ ├── Card.tsx │ └── index.tsx └── LinkPreview │ ├── LinkPreview.tsx │ └── index.ts ├── data ├── snippets.tsx └── snippets │ ├── ActiveUnderlineLeftRight.tsx │ ├── BackgroundPulse.tsx │ ├── FlickUp.tsx │ ├── GradientTilt.tsx │ ├── HoverActiveScaleButton.tsx │ ├── HoverScaleButton.tsx │ ├── KeyboardButton.tsx │ ├── MaterialTextInput.tsx │ ├── Pulse.tsx │ ├── Shimmer.tsx │ ├── Spinner.tsx │ ├── Swing.tsx │ ├── TextShimmer.tsx │ ├── TextTransformColor.tsx │ ├── ThreeDotsLoader.tsx │ ├── UnderlayExpandingCircle.tsx │ ├── UnderlayLeft.tsx │ ├── UnderlayLeftRight.tsx │ ├── UnderlayMarker.tsx │ ├── UnderlineBottomTop.tsx │ ├── UnderlineLeftRight.tsx │ └── UnderlineSquiggle.tsx ├── lib └── classNames.ts ├── next-env.d.ts ├── next.config.js ├── package-lock.json ├── package.json ├── pages ├── _app.tsx ├── _document.tsx └── index.tsx ├── postcss.config.js ├── public ├── beams.png ├── favicon.ico ├── grid.svg ├── playground.html ├── readme.png ├── squiggle.svg ├── thumbnail.png └── twitter-preview.png ├── tailwind.config.js ├── tsconfig.json └── types.d.ts /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | 36 | # typescript 37 | *.tsbuildinfo 38 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "editor.formatOnSave": true, 4 | "editor.formatOnPaste": false 5 | } 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Alexandru Turcanu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![image](/public/readme.png) 2 | 3 | ### Credits 4 | This collection of snippets would have not been possible without the hard work of many talented engineers and designers. It would only be fair to give back credit to the authors that inspired some of the snippets:  5 | 6 | * This project started as a port of [ui-snippets.dev](https://ui-snippets.dev/) for TailwindCSS, special kudos to Emil Kowalski for originally creating that. 7 | * Gradient Tilt inspired by [linear.app](https://linear.app/). 8 | * Underline Squiggle inspired by [edgeandnode.com](https://edgeandnode.com/). 9 | -------------------------------------------------------------------------------- /components/Card/Card.tsx: -------------------------------------------------------------------------------- 1 | import { useRef } from "react" 2 | import ReactDOMServer from "react-dom/server" 3 | import * as ContextMenu from "@radix-ui/react-context-menu" 4 | import { CodeIcon, MagicWandIcon, PlayIcon, GitHubLogoIcon } from "@radix-ui/react-icons" 5 | import { useHotkeys } from "react-hotkeys-hook" 6 | import { trackGoal } from "fathom-client" 7 | 8 | export default function Card({ source, animation, editLink, playgroundLink }: ISnippet): JSX.Element { 9 | const copySourceRef = useRef(null) 10 | const copyAnimationRef = useRef(null) 11 | const openPlaygroundRef = useRef(null) 12 | const openGithubRef = useRef(null) 13 | 14 | const itemStyle = 15 | "flex items-center px-2 py-2 text-xs rounded-md outline-none cursor-default select-none text-gray-500 focus:bg-white/5 radix-disabled:opacity-50 radix-disabled:cursor-not-allowed transition-colors ease-out duration-200 disabled:opacity-75" 16 | const itemTextStyle = "ml-2 flex-grow text-gray-200" 17 | 18 | // Copy Source 19 | useHotkeys("s", () => copySourceRef.current?.click()) 20 | function handleCopySource() { 21 | navigator.clipboard.writeText(ReactDOMServer.renderToStaticMarkup(source)) 22 | trackGoal("GHMTI4HH", 1) 23 | } 24 | 25 | // Copy Animation 26 | useHotkeys("k", () => copyAnimationRef.current?.click()) 27 | function handleCopyAnimation() { 28 | navigator.clipboard.writeText(animation || "no custom animation used") 29 | } 30 | 31 | // Open in Playground 32 | useHotkeys("p", () => openPlaygroundRef.current?.click()) 33 | function handleOpenInPlayground() { 34 | window.open(playgroundLink, "_blank") 35 | } 36 | 37 | // Open in Github 38 | useHotkeys("g", () => openGithubRef.current?.click()) 39 | function handleOpenInGithub() { 40 | window.open(editLink, "_blank") 41 | } 42 | 43 | return ( 44 | 45 | 46 |
47 |
{source}
48 |
49 |
50 | 51 | {/* Copy Source */} 52 | handleCopySource()}> 53 | 54 | Copy Source 55 | S 56 | 57 | 58 | {/* Copy Animation */} 59 | handleCopyAnimation()} 64 | > 65 | 66 | Copy Keyframes 67 | K 68 | 69 | 70 | 71 | 72 | {/* Open in Playground */} 73 | handleOpenInPlayground()} 78 | > 79 | 80 | Open in Playground 81 | P 82 | 83 | 84 | {/* Open in Github */} 85 | handleOpenInGithub()}> 86 | 87 | Open in Github 88 | G 89 | 90 | 91 |
92 | ) 93 | } 94 | -------------------------------------------------------------------------------- /components/Card/index.tsx: -------------------------------------------------------------------------------- 1 | export { default } from "./Card" 2 | -------------------------------------------------------------------------------- /components/LinkPreview/LinkPreview.tsx: -------------------------------------------------------------------------------- 1 | import Image from "next/image" 2 | import * as Tooltip from "@radix-ui/react-tooltip" 3 | import classNames from "@lib/classNames" 4 | 5 | interface ILinkPreview { 6 | name: string 7 | href: string 8 | preview?: string 9 | alt: string 10 | } 11 | 12 | export default function LinkPreview({ name, href, alt, preview }: ILinkPreview) { 13 | const shimmer = (w: number, h: number) => ` 14 | 15 | 16 | 17 | ` 18 | 19 | const toBase64 = (str: string) => 20 | typeof window === "undefined" ? Buffer.from(str).toString("base64") : window.btoa(str) 21 | 22 | return ( 23 | 24 | 25 | 34 | {name} 35 | 36 | 37 | 42 | {alt} 55 | 56 | 57 | ) 58 | } 59 | -------------------------------------------------------------------------------- /components/LinkPreview/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./LinkPreview" 2 | -------------------------------------------------------------------------------- /data/snippets.tsx: -------------------------------------------------------------------------------- 1 | import UnderlineLeftRight from "./snippets/UnderlineLeftRight" 2 | import Pulse from "./snippets/Pulse" 3 | import KeyboardButton from "./snippets/KeyboardButton" 4 | import UnderlayMarker from "./snippets/UnderlayMarker" 5 | import UnderlayLeft from "./snippets/UnderlayLeft" 6 | import Spinner from "./snippets/Spinner" 7 | import HoverActiveScaleButton from "./snippets/HoverActiveScaleButton" 8 | import Swing from "./snippets/Swing" 9 | import UnderlineBottomTop from "./snippets/UnderlineBottomTop" 10 | import UnderlayLeftRight from "./snippets/UnderlayLeftRight" 11 | import TextTransformColor from "./snippets/TextTransformColor" 12 | import Shimmer from "./snippets/Shimmer" 13 | import UnderlayExpandingCircle from "./snippets/UnderlayExpandingCircle" 14 | import ThreeDotsLoader from "./snippets/ThreeDotsLoader" 15 | import HoverScaleButton from "./snippets/HoverScaleButton" 16 | import ActiveUnderlineLeftRight from "./snippets/ActiveUnderlineLeftRight" 17 | import FlickUp from "./snippets/FlickUp" 18 | import GradientTilt from "./snippets/GradientTilt" 19 | import BackgroundPulse from "./snippets/BackgroundPulse" 20 | import UnderlineSquiggle from "./snippets/UnderlineSquiggle" 21 | import MaterialTextInput from "./snippets/MaterialTextInput" 22 | import TextShimmer from "./snippets/TextShimmer" 23 | 24 | const snippets: ISnippet[] = [ 25 | UnderlineLeftRight, 26 | UnderlineBottomTop, 27 | ActiveUnderlineLeftRight, 28 | UnderlineSquiggle, 29 | 30 | UnderlayLeft, 31 | UnderlayLeftRight, 32 | UnderlayExpandingCircle, 33 | GradientTilt, 34 | 35 | UnderlayMarker, 36 | Swing, 37 | FlickUp, 38 | TextTransformColor, 39 | 40 | KeyboardButton, 41 | HoverScaleButton, 42 | HoverActiveScaleButton, 43 | MaterialTextInput, 44 | 45 | Spinner, 46 | BackgroundPulse, 47 | ThreeDotsLoader, 48 | Shimmer, 49 | 50 | Pulse, 51 | TextShimmer, 52 | ] 53 | 54 | export default snippets 55 | -------------------------------------------------------------------------------- /data/snippets/ActiveUnderlineLeftRight.tsx: -------------------------------------------------------------------------------- 1 | const ActiveUnderlineLeftRight: ISnippet = { 2 | title: "Active Underline Left Right", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/ActiveUnderlineLeftRight.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/uDx5TA9jhf", 5 | source: ( 6 |
7 | Hover over me 8 |
9 | ), 10 | } 11 | 12 | export default ActiveUnderlineLeftRight 13 | -------------------------------------------------------------------------------- /data/snippets/BackgroundPulse.tsx: -------------------------------------------------------------------------------- 1 | const BackgroundPulse: ISnippet = { 2 | title: "Background Pulse", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/BackgroundPulse.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/Mf77KHXg25", 5 | source:
, 6 | } 7 | 8 | export default BackgroundPulse 9 | -------------------------------------------------------------------------------- /data/snippets/FlickUp.tsx: -------------------------------------------------------------------------------- 1 | const FlickUp: ISnippet = { 2 | title: "Flick Up", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/FlickUp.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/n22Rh5HMTY", 5 | source: ( 6 |
7 | Hover over me 8 | 9 | Hover over me 10 | 11 | 12 | Hover over me 13 | 14 |
15 | ), 16 | } 17 | 18 | export default FlickUp 19 | -------------------------------------------------------------------------------- /data/snippets/GradientTilt.tsx: -------------------------------------------------------------------------------- 1 | const GradientTilt: ISnippet = { 2 | title: "Gradient Tilt", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/GradientTilt.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/GMTiinWZXq?file=config", 5 | source: ( 6 |
7 |
8 |
Hover over me
9 |
10 | ), 11 | animation: `keyframes: { 12 | tilt: { 13 | "0%, 50%, 100%": { transform: "rotate(0deg)" }, 14 | "25%": { transform: "rotate(0.5deg)" }, 15 | "75%": { transform: "rotate(-0.5deg)" }, 16 | }, 17 | }, 18 | animation: { 19 | tilt: "tilt 10s infinite linear", 20 | },`, 21 | } 22 | 23 | export default GradientTilt 24 | -------------------------------------------------------------------------------- /data/snippets/HoverActiveScaleButton.tsx: -------------------------------------------------------------------------------- 1 | const HoverActiveScaleButton: ISnippet = { 2 | title: "Hover & Active Scale Button", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/HoverActiveScaleButton.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/hxZ37q2LAv", 5 | source: ( 6 |
7 | Hover & hold me 8 |
9 | ), 10 | } 11 | 12 | export default HoverActiveScaleButton 13 | -------------------------------------------------------------------------------- /data/snippets/HoverScaleButton.tsx: -------------------------------------------------------------------------------- 1 | const HoverScaleButton: ISnippet = { 2 | title: "Hover Scale Button", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/HoverScaleButton.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/ll5x3lzO6V", 5 | source: ( 6 |
7 | Hover over me 8 |
9 | ), 10 | } 11 | 12 | export default HoverScaleButton 13 | -------------------------------------------------------------------------------- /data/snippets/KeyboardButton.tsx: -------------------------------------------------------------------------------- 1 | const KeyboardButton: ISnippet = { 2 | title: "Keyboard Button", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/KeyboardButton.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/mIS0tN3dQ9", 5 | source: ( 6 |
7 | Hover over me 8 |
9 | ), 10 | } 11 | 12 | export default KeyboardButton 13 | -------------------------------------------------------------------------------- /data/snippets/MaterialTextInput.tsx: -------------------------------------------------------------------------------- 1 | const MaterialTextInput: ISnippet = { 2 | title: "Material Text Input", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/MaterialTextInput.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/DPlIUMU7jB", 5 | source: ( 6 |
7 |
8 | 15 | 21 |
22 |
23 | ), 24 | } 25 | 26 | export default MaterialTextInput 27 | -------------------------------------------------------------------------------- /data/snippets/Pulse.tsx: -------------------------------------------------------------------------------- 1 | const Pulse: ISnippet = { 2 | title: "Pulse", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/Pulse.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/Lua057Ji2l", 5 | source: ( 6 |
7 | 8 | 9 |
10 | ), 11 | } 12 | 13 | export default Pulse 14 | -------------------------------------------------------------------------------- /data/snippets/Shimmer.tsx: -------------------------------------------------------------------------------- 1 | const Shimmer: ISnippet = { 2 | title: "Shimmer", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/Shimmer.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/pE7XMJWPbK", 5 | source: ( 6 |
7 | ), 8 | animation: `keyframes: { 9 | shimmer: { 10 | from: { backgroundPosition: "200% 0" }, 11 | to: { backgroundPosition: "-200% 0" }, 12 | }, 13 | }, 14 | animation: { 15 | shimmer: "shimmer 8s ease-in-out infinite", 16 | },`, 17 | } 18 | 19 | export default Shimmer 20 | -------------------------------------------------------------------------------- /data/snippets/Spinner.tsx: -------------------------------------------------------------------------------- 1 | const Spinner: ISnippet = { 2 | title: "Spinner", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/Spinner.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/S7AMIMNDYf", 5 | source: ( 6 | 7 | 8 | 13 | 14 | ), 15 | } 16 | 17 | export default Spinner 18 | -------------------------------------------------------------------------------- /data/snippets/Swing.tsx: -------------------------------------------------------------------------------- 1 | const Swing: ISnippet = { 2 | title: "Swing", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/Swing.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/7HznJM2eA0", 5 | source:
Hover over me
, 6 | animation: `keyframes: { 7 | swing: { 8 | "15%": { transform: "translateX(5px)" }, 9 | "30%": { transform: "translateX(-5px)" }, 10 | "50%": { transform: "translateX(3px)" }, 11 | "80%": { transform: "translateX(2px)" }, 12 | "100%": { transform: "translateX(0)" }, 13 | }, 14 | }, 15 | animation: { 16 | swing: "swing 1s ease 1", 17 | },`, 18 | } 19 | 20 | export default Swing 21 | -------------------------------------------------------------------------------- /data/snippets/TextShimmer.tsx: -------------------------------------------------------------------------------- 1 | const TextShimmer: ISnippet = { 2 | title: "Shimmer", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/TextShimmer.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/iOPPOIJo2q", 5 | source: ( 6 |
7 | Text Shimmer Effect 8 |
9 | ), 10 | animation: `keyframes: { 11 | "text-shimmer": { 12 | from: { backgroundPosition: "0 0" }, 13 | to: { backgroundPosition: "-200% 0" }, 14 | }, 15 | }, 16 | animation: { 17 | "text-shimmer": "text-shimmer 2.5s ease-out infinite alternate", 18 | },`, 19 | } 20 | 21 | export default TextShimmer 22 | -------------------------------------------------------------------------------- /data/snippets/TextTransformColor.tsx: -------------------------------------------------------------------------------- 1 | const TextTransformColor: ISnippet = { 2 | title: "Text Transform & Color", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/TextTransformColor.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/YQEPZafzdC", 5 | source: ( 6 |
7 | Hover over me{" "} 8 | 14 |
15 | ), 16 | } 17 | 18 | export default TextTransformColor 19 | -------------------------------------------------------------------------------- /data/snippets/ThreeDotsLoader.tsx: -------------------------------------------------------------------------------- 1 | const ThreeDotsLoader: ISnippet = { 2 | title: "Three Dots Loader", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/ThreeDotsLoader.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/i12OeK41ZE", 5 | source: ( 6 |
7 | 8 | 9 | 10 |
11 | ), 12 | animation: `keyframes: { 13 | flash: { 14 | "0%": { opacity: "0.2" }, 15 | "20%": { opacity: "1" }, 16 | "100%": { opacity: "0.2" }, 17 | }, 18 | }, 19 | animation: { 20 | flash: "flash 1.4s infinite linear", 21 | },`, 22 | } 23 | 24 | export default ThreeDotsLoader 25 | -------------------------------------------------------------------------------- /data/snippets/UnderlayExpandingCircle.tsx: -------------------------------------------------------------------------------- 1 | const UnderlayExpandingCircle: ISnippet = { 2 | title: "Underlay Expanding Circle", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/UnderlayExpandingCircle.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/nEHCtBr6iK", 5 | source: ( 6 |
7 | 8 | Hover over me 9 | 10 |
11 | ), 12 | } 13 | 14 | export default UnderlayExpandingCircle 15 | -------------------------------------------------------------------------------- /data/snippets/UnderlayLeft.tsx: -------------------------------------------------------------------------------- 1 | const UnderlayLeft: ISnippet = { 2 | title: "Underlay Left", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/UnderlayLeft.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/1eXQZT8CqF", 5 | source: ( 6 |
7 | 8 | Hover over me 9 | 10 |
11 | ), 12 | } 13 | 14 | export default UnderlayLeft 15 | -------------------------------------------------------------------------------- /data/snippets/UnderlayLeftRight.tsx: -------------------------------------------------------------------------------- 1 | const UnderlayLeftRight: ISnippet = { 2 | title: "Underlay Left Right", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/UnderlayLeftRight.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/L7dQEa01J0", 5 | source: ( 6 |
7 | 8 | Hover over me 9 | 10 |
11 | ), 12 | } 13 | 14 | export default UnderlayLeftRight 15 | -------------------------------------------------------------------------------- /data/snippets/UnderlayMarker.tsx: -------------------------------------------------------------------------------- 1 | const UnderlayMarker: ISnippet = { 2 | title: "Underlay Marker", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/UnderlayMarker.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/mBEHHzveWs", 5 | source: ( 6 |
7 | Hover over me 8 |
9 | ), 10 | } 11 | 12 | export default UnderlayMarker 13 | -------------------------------------------------------------------------------- /data/snippets/UnderlineBottomTop.tsx: -------------------------------------------------------------------------------- 1 | const UnderlineBottomTop: ISnippet = { 2 | title: "Underline Bottom Top", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/UnderlineBottomTop.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/CpfdeRMOF0", 5 | source: ( 6 |
7 | Hover over me 8 |
9 | ), 10 | } 11 | 12 | export default UnderlineBottomTop 13 | -------------------------------------------------------------------------------- /data/snippets/UnderlineLeftRight.tsx: -------------------------------------------------------------------------------- 1 | const UnderlineLeftRight: ISnippet = { 2 | title: "Underline Left Right", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/UnderlineLeftRight.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/wu05IAG55F", 5 | source: ( 6 |
7 | Hover over me 8 |
9 | ), 10 | } 11 | 12 | export default UnderlineLeftRight 13 | -------------------------------------------------------------------------------- /data/snippets/UnderlineSquiggle.tsx: -------------------------------------------------------------------------------- 1 | const UnderlineSquiggle: ISnippet = { 2 | title: "Underline Squiggle", 3 | editLink: "https://github.com/Pondorasti/tailwindcss-snippets/blob/main/data/snippets/UnderlineSquiggle.tsx", 4 | playgroundLink: "https://play.tailwindcss.com/b30QFEAPpZ", 5 | source: ( 6 |
7 | Hover over me 8 |
9 | ), 10 | } 11 | 12 | export default UnderlineSquiggle 13 | -------------------------------------------------------------------------------- /lib/classNames.ts: -------------------------------------------------------------------------------- 1 | export default function classNames(...classes: string[]): string { 2 | return classes.filter(Boolean).join(" ") 3 | } 4 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | module.exports = { 3 | reactStrictMode: true, 4 | images: { 5 | domains: ["api.microlink.io"], 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tailwindcss-snippets", 3 | "private": true, 4 | "scripts": { 5 | "dev": "next dev", 6 | "build": "next build", 7 | "start": "next start", 8 | "lint": "next lint", 9 | "lint:fix": "next lint --fix" 10 | }, 11 | "eslintConfig": { 12 | "extends": [ 13 | "next/core-web-vitals", 14 | "plugin:prettier/recommended" 15 | ] 16 | }, 17 | "prettier": { 18 | "printWidth": 120, 19 | "tabwidth": 2, 20 | "useTabs": false, 21 | "semi": false, 22 | "trailingComma": "es5", 23 | "bracketSpacing": true, 24 | "arrowparens": "avoid" 25 | }, 26 | "dependencies": { 27 | "@radix-ui/react-context-menu": "^0.1.4", 28 | "@radix-ui/react-icons": "^1.0.3", 29 | "@radix-ui/react-tooltip": "^0.1.6", 30 | "fathom-client": "^3.2.0", 31 | "next": "12.0.7", 32 | "react": "17.0.2", 33 | "react-dom": "17.0.2", 34 | "react-hotkeys-hook": "^3.4.4", 35 | "tailwindcss-radix": "^1.6.0" 36 | }, 37 | "devDependencies": { 38 | "@types/node": "17.0.6", 39 | "@types/react": "17.0.38", 40 | "@types/react-dom": "^17.0.11", 41 | "autoprefixer": "^10.4.1", 42 | "eslint": "8.6.0", 43 | "eslint-config-next": "12.0.7", 44 | "eslint-config-prettier": "^8.3.0", 45 | "eslint-plugin-prettier": "^4.0.0", 46 | "postcss": "^8.4.5", 47 | "prettier": "^2.5.1", 48 | "tailwindcss": "^3.0.8", 49 | "typescript": "4.5.4" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import "tailwindcss/tailwind.css" 2 | import { useEffect } from "react" 3 | import type { AppProps } from "next/app" 4 | import { useRouter } from "next/router" 5 | import * as Fathom from "fathom-client" 6 | 7 | function MyApp({ Component, pageProps }: AppProps) { 8 | // Fathom Analytics 9 | // Source: https://vercel.com/guides/deploying-nextjs-using-fathom-analytics-with-vercel 10 | const router = useRouter() 11 | useEffect(() => { 12 | Fathom.load("LTCIFPOU", { 13 | url: "https://rook.alexandru.so/script.js", 14 | includedDomains: ["snippets.alexandru.so"], 15 | }) 16 | 17 | function onRouteChangeComplete() { 18 | Fathom.trackPageview() 19 | } 20 | // Record a pageview when route changes 21 | router.events.on("routeChangeComplete", onRouteChangeComplete) 22 | 23 | return () => { 24 | router.events.off("routeChangeComplete", onRouteChangeComplete) 25 | } 26 | }, []) 27 | return 28 | } 29 | 30 | export default MyApp 31 | -------------------------------------------------------------------------------- /pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import NextDocument, { Html, Head, Main, NextScript } from "next/document" 2 | 3 | export default class Document extends NextDocument { 4 | render(): JSX.Element { 5 | const title = "TailwindCSS Snippets" 6 | const description = "A collection of animation snippets made with TailwindCSS" 7 | const image = "https://snippets.alexandru.so/thumbnail.png" 8 | 9 | return ( 10 | 11 | 12 | {/* eslint-disable-next-line @next/next/no-title-in-document-head */} 13 | Snippets 14 | 15 | 16 | 17 | {/* Title */} 18 | {title} 19 | 20 | 21 | {/* Description */} 22 | 23 | 24 | 25 | {/* Image */} 26 | 27 | 28 | 29 | {/* URL */} 30 | 31 | 32 | {/* General */} 33 | 34 | 35 | 36 | 37 | 38 | 39 | {/* Inter Font */} 40 | 41 | 45 | 46 | 47 |
48 |
49 |
50 |
51 | 52 | 53 | 54 | ) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /pages/index.tsx: -------------------------------------------------------------------------------- 1 | import Card from "@components/Card" 2 | import LinkPreview from "@components/LinkPreview" 3 | import snippets from "@data/snippets" 4 | 5 | function Home(): JSX.Element { 6 | const linkStyle = "text-sm font-medium text-gray-200 opacity-70 hover:opacity-100 transition-[opacity] duration-200" 7 | const iconStyle = "h-6 w-6" 8 | 9 | return ( 10 |
11 |
12 |
TailwindCSS Snippets
13 | 37 |
38 | 39 |
40 |

41 | Right click the animation
to copy the source 42 |

43 |
44 |
45 | {snippets.map(({ title, editLink, playgroundLink, source, animation }) => ( 46 | 53 | ))} 54 |
55 |
56 | 57 |
58 |
59 |
60 | Crafted by{" "} 61 | 62 | 68 | 69 |
70 |
71 |
72 | ) 73 | } 74 | 75 | export default Home 76 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/beams.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pondorasti/tailwindcss-snippets/b66f2caf7589cb5d4a957cb19239f91d1ed481dc/public/beams.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pondorasti/tailwindcss-snippets/b66f2caf7589cb5d4a957cb19239f91d1ed481dc/public/favicon.ico -------------------------------------------------------------------------------- /public/grid.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/playground.html: -------------------------------------------------------------------------------- 1 | 11 |
12 |
13 |
14 | 15 |
17 |
18 | 19 | 20 |
21 |
22 |
-------------------------------------------------------------------------------- /public/readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pondorasti/tailwindcss-snippets/b66f2caf7589cb5d4a957cb19239f91d1ed481dc/public/readme.png -------------------------------------------------------------------------------- /public/squiggle.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /public/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pondorasti/tailwindcss-snippets/b66f2caf7589cb5d4a957cb19239f91d1ed481dc/public/thumbnail.png -------------------------------------------------------------------------------- /public/twitter-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pondorasti/tailwindcss-snippets/b66f2caf7589cb5d4a957cb19239f91d1ed481dc/public/twitter-preview.png -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | const defaultTheme = require("tailwindcss/defaultTheme") 2 | const colors = require("tailwindcss/colors") 3 | const plugin = require("tailwindcss/plugin") 4 | 5 | module.exports = { 6 | content: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}", "./data/**/*.{js,ts,jsx,tsx}"], 7 | theme: { 8 | extend: { 9 | fontFamily: { 10 | sans: ["Inter", ...defaultTheme.fontFamily.sans], 11 | }, 12 | colors: { 13 | gray: colors.slate, 14 | }, 15 | keyframes: { 16 | tilt: { 17 | "0%, 50%, 100%": { transform: "rotate(0deg)" }, 18 | "25%": { transform: "rotate(0.5deg)" }, 19 | "75%": { transform: "rotate(-0.5deg)" }, 20 | }, 21 | flash: { 22 | "0%": { opacity: "0.2" }, 23 | "20%": { opacity: "1" }, 24 | "100%": { opacity: "0.2" }, 25 | }, 26 | shimmer: { 27 | from: { backgroundPosition: "200% 0" }, 28 | to: { backgroundPosition: "-200% 0" }, 29 | }, 30 | "text-shimmer": { 31 | from: { backgroundPosition: "0 0" }, 32 | to: { backgroundPosition: "-200% 0" }, 33 | }, 34 | swing: { 35 | "15%": { transform: "translateX(5px)" }, 36 | "30%": { transform: "translateX(-5px)" }, 37 | "50%": { transform: "translateX(3px)" }, 38 | "80%": { transform: "translateX(2px)" }, 39 | "100%": { transform: "translateX(0)" }, 40 | }, 41 | "fade-in": { 42 | from: { opacity: 0, transform: "scale(0.9)" }, 43 | to: { opacity: 1, transform: "scale(1.0)" }, 44 | }, 45 | "fade-out": { 46 | from: { opacity: 1, transform: "scale(1.0)" }, 47 | to: { opacity: 0, transform: "scale(0.9)" }, 48 | }, 49 | "slide-in": { 50 | "0%": { opacity: 0, transform: "translateY(16px)" }, 51 | "100%": { opacity: 1, transform: "translateY(0)" }, 52 | }, 53 | "slide-out": { 54 | "0%": { opacity: 1, transform: "translateY(0px)" }, 55 | "100%": { opacity: 0, transform: "translateY(16px)" }, 56 | }, 57 | }, 58 | animation: { 59 | tilt: "tilt 10s infinite linear", 60 | flash: "flash 1.4s infinite linear", 61 | shimmer: "shimmer 8s ease-in-out infinite", 62 | "text-shimmer": "text-shimmer 2.5s ease-out infinite alternate", 63 | swing: "swing 1s ease 1", 64 | "fade-in": "fade-in 0.1s ease-out", 65 | "fade-out": "fade-out 0.1s ease-in", 66 | "slide-in": "slide-in 0.2s ease-out", 67 | "slide-out": "slide-out 0.2s ease", 68 | }, 69 | }, 70 | }, 71 | plugins: [ 72 | require("tailwindcss-radix")(), 73 | plugin(function ({ addBase }) { 74 | addBase({ 75 | hr: { 76 | "@apply mt-16 mx-auto h-px w-12 opacity-10": {}, 77 | }, 78 | kbd: { 79 | "@apply p-1 bg-gray-700 text-gray-300 text-[10px] min-w-[16px] h-4 rounded inline-flex items-center justify-center": 80 | {}, 81 | "box-shadow": "inset 0 -1.5px 0 0 rgb(255 255 255 / 5%)", 82 | }, 83 | }) 84 | }), 85 | ], 86 | } 87 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "@components/*": ["components/*"], 20 | "@data/*": ["data/*"], 21 | "@lib/*": ["lib/*"] 22 | } 23 | }, 24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /types.d.ts: -------------------------------------------------------------------------------- 1 | interface ISnippet { 2 | title?: string 3 | editLink: string 4 | playgroundLink?: string 5 | source: JSX.Element 6 | animation?: string 7 | } 8 | --------------------------------------------------------------------------------