├── .DS_Store
├── .contentlayer
├── .cache
│ └── v0.5.1
│ │ ├── compiled-contentlayer-config-R5EPTL46.mjs
│ │ ├── compiled-contentlayer-config-R5EPTL46.mjs.map
│ │ ├── data-6J7PXMQO.json
│ │ ├── data-DU4B7RQS.json
│ │ ├── data-HSCCEERK.json
│ │ ├── data-M7T6QIXT.json
│ │ ├── data-N6DGWP76.json
│ │ ├── data-OGSGRIE3.json
│ │ ├── data-OQWPKB4N.json
│ │ ├── data-QM22GU5T.json
│ │ ├── data-QX7RG4LG.json
│ │ ├── data-QY5FWJKK.json
│ │ ├── data-R5EPTL46.json
│ │ ├── data-RKUOJATL.json
│ │ ├── data-SUWRVOCL.json
│ │ └── data-TFUQY5HB.json
├── generated
│ ├── Blogs
│ │ ├── _index.json
│ │ ├── _index.mjs
│ │ ├── blogs__eslint-setup.mdx.json
│ │ ├── blogs__lemon-squeezy.mdx.json
│ │ ├── blogs__making-website.mdx.json
│ │ └── blogs__my-experience.mdx.json
│ ├── TwitterContents
│ │ ├── _index.json
│ │ ├── _index.mjs
│ │ ├── twitter-contents__1.mdx.json
│ │ ├── twitter-contents__10.mdx.json
│ │ ├── twitter-contents__11.mdx.json
│ │ ├── twitter-contents__12.mdx.json
│ │ ├── twitter-contents__13.mdx.json
│ │ ├── twitter-contents__14.mdx.json
│ │ ├── twitter-contents__15.mdx.json
│ │ ├── twitter-contents__16.mdx.json
│ │ ├── twitter-contents__17.mdx.json
│ │ ├── twitter-contents__18.mdx.json
│ │ ├── twitter-contents__19.mdx.json
│ │ ├── twitter-contents__2.mdx.json
│ │ ├── twitter-contents__20.mdx.json
│ │ ├── twitter-contents__21.mdx.json
│ │ ├── twitter-contents__22.mdx.json
│ │ ├── twitter-contents__23.mdx.json
│ │ ├── twitter-contents__24.mdx.json
│ │ ├── twitter-contents__25.mdx.json
│ │ ├── twitter-contents__3.mdx.json
│ │ ├── twitter-contents__4.mdx.json
│ │ ├── twitter-contents__5.mdx.json
│ │ ├── twitter-contents__6.mdx.json
│ │ ├── twitter-contents__7.mdx.json
│ │ ├── twitter-contents__8.mdx.json
│ │ └── twitter-contents__9.mdx.json
│ ├── Works
│ │ ├── _index.json
│ │ ├── _index.mjs
│ │ ├── blogs__eslint-setup.mdx.json
│ │ ├── blogs__making-website.mdx.json
│ │ ├── works__1.mdx.json
│ │ ├── works__10.mdx.json
│ │ ├── works__11.mdx.json
│ │ ├── works__12.mdx.json
│ │ ├── works__13.mdx.json
│ │ ├── works__14.mdx.json
│ │ ├── works__15 copy.mdx.json
│ │ ├── works__15.mdx.json
│ │ ├── works__16.mdx.json
│ │ ├── works__17.mdx.json
│ │ ├── works__18.mdx.json
│ │ ├── works__19.mdx.json
│ │ ├── works__2.mdx.json
│ │ ├── works__20.mdx.json
│ │ ├── works__21.mdx.json
│ │ ├── works__22.mdx.json
│ │ ├── works__23.mdx.json
│ │ ├── works__24.mdx.json
│ │ ├── works__3.mdx.json
│ │ ├── works__4.mdx.json
│ │ ├── works__5.mdx.json
│ │ ├── works__6.mdx.json
│ │ ├── works__7.mdx.json
│ │ ├── works__8.mdx.json
│ │ ├── works__9.mdx.json
│ │ └── works__helping.mdx.json
│ ├── buildData
│ │ ├── _index.json
│ │ ├── _index.mjs
│ │ └── build-data__requirements.mdx.json
│ ├── buildFast
│ │ ├── _index.json
│ │ ├── _index.mjs
│ │ ├── build-fast__designs__charts.mdx.json
│ │ ├── build-fast__error-handling.mdx.json
│ │ ├── build-fast__links.mdx.json
│ │ ├── build-fast__mdx-setup.mdx.json
│ │ ├── build-fast__npm-packages.mdx.json
│ │ ├── build-fast__react-libraries__general-hooks.mdx.json
│ │ ├── build-fast__react-libraries__react-hotkeys-hook.mdx.json
│ │ ├── build-fast__react-libraries__react-pdf.mdx.json
│ │ ├── build-fast__react-libries__general-hooks.mdx.json
│ │ ├── build-fast__react-libries__react-hotkeys-hook.mdx.json
│ │ ├── build-fast__react-libries__react-pdf.mdx.json
│ │ ├── build-fast__requirements copy.mdx.json
│ │ ├── build-fast__requirements.mdx.json
│ │ ├── build-fast__reusable-components__button.mdx.json
│ │ ├── build-fast__server.mdx.json
│ │ ├── build-fast__supbase.mdx.json
│ │ ├── build-fast__third-party__framer-motion.mdx.json
│ │ ├── build-fast__third-party__input-otp.mdx.json
│ │ ├── build-fast__third-party__uuid.mdx.json
│ │ ├── build-fast__ui__button.mdx.json
│ │ └── build-fast__ui__useful-components.mdx.json
│ ├── index.d.ts
│ ├── index.mjs
│ └── types.d.ts
└── package.json
├── .eslintrc.json
├── .gitignore
├── .prettierignore
├── .prettierrc
├── README.md
├── __registry__
└── index.tsx
├── app
├── api
│ └── send
│ │ └── route.ts
├── blog
│ └── [slug]
│ │ └── page.tsx
├── build-fast
│ └── [...slug]
│ │ ├── Menu.tsx
│ │ ├── Navbar.tsx
│ │ └── page.tsx
├── favicon.ico
├── fonts
│ ├── GeistMonoVF.woff
│ └── GeistVF.woff
├── globals.css
├── helping
│ └── layout-id-issue
│ │ └── page.tsx
├── layout.tsx
├── not-found.tsx
├── page.tsx
├── recording
│ └── [slug]
│ │ └── page.tsx
├── volleyball
│ └── page.tsx
├── work
│ └── [...slug]
│ │ └── page.tsx
└── x-content
│ └── [slug]
│ └── page.tsx
├── components.json
├── components
├── AnimationSpeed.tsx
├── CodePreview.tsx
├── ColorPicker.tsx
├── ComponentPreview.tsx
├── CopyButton.tsx
├── EmailTemplate.tsx
├── FilesTab.tsx
├── FixedImage.tsx
├── GithubTheme.tsx
├── IphoneSimulator.tsx
├── MDX
│ ├── MDXContent.blog.tsx
│ └── MDXContent.work.tsx
├── NavigatingClick.tsx
├── SyntaxHighlighter.tsx
├── Tabs.tsx
├── TechIcons.tsx
├── TwitterContentsElement.tsx
├── apps.tsx
├── experience.tsx
├── hire-me.tsx
└── ui
│ ├── badge.tsx
│ ├── button.tsx
│ ├── dialog.tsx
│ ├── drawer.tsx
│ ├── input.tsx
│ ├── label.tsx
│ ├── select.tsx
│ ├── separator.tsx
│ ├── sheet.tsx
│ ├── slider.tsx
│ ├── sonner.tsx
│ ├── text.tsx
│ ├── textarea.tsx
│ └── tooltip.tsx
├── contentlayer.config.js
├── contents
├── blogs
│ ├── eslint-setup.mdx
│ ├── lemon-squeezy.mdx
│ ├── making-website.mdx
│ └── my-experience.mdx
├── build-fast
│ ├── error-handling.mdx
│ ├── links.mdx
│ ├── mdx-setup.mdx
│ ├── npm-packages.mdx
│ ├── react-libraries
│ │ ├── general-hooks.mdx
│ │ ├── react-hotkeys-hook.mdx
│ │ └── react-pdf.mdx
│ ├── requirements.mdx
│ ├── server.mdx
│ ├── supbase.mdx
│ └── ui
│ │ └── useful-components.mdx
└── twitter-contents
│ ├── 1.mdx
│ ├── 10.mdx
│ ├── 11.mdx
│ ├── 12.mdx
│ ├── 13.mdx
│ ├── 14.mdx
│ ├── 15.mdx
│ ├── 16.mdx
│ ├── 17.mdx
│ ├── 18.mdx
│ ├── 19.mdx
│ ├── 2.mdx
│ ├── 20.mdx
│ ├── 21.mdx
│ ├── 22.mdx
│ ├── 23.mdx
│ ├── 24.mdx
│ ├── 25.mdx
│ ├── 3.mdx
│ ├── 4.mdx
│ ├── 5.mdx
│ ├── 6.mdx
│ ├── 7.mdx
│ ├── 8.mdx
│ └── 9.mdx
├── lib
└── utils.ts
├── middleware.tsx
├── next.config.js
├── package.json
├── pnpm-lock.yaml
├── postcss.config.mjs
├── preview
├── build-fast
│ ├── hotKeys.tsx
│ ├── input-otp.tsx
│ ├── react-pdf.tsx
│ ├── use-click-outside.tsx
│ ├── use-debounced-state.tsx
│ ├── use-fullscreen.tsx
│ ├── use-media-query.tsx
│ └── uuid.tsx
└── twitter-contents
│ ├── 5
│ ├── design-1.tsx
│ ├── design-2.tsx
│ └── index.tsx
│ ├── 6
│ ├── block-elements.tsx
│ └── inline-elements.tsx
│ ├── 1.tsx
│ ├── 10.tsx
│ ├── 11.tsx
│ ├── 12.tsx
│ ├── 13.tsx
│ ├── 14.tsx
│ ├── 15.tsx
│ ├── 16.tsx
│ ├── 17.tsx
│ ├── 18.tsx
│ ├── 19.tsx
│ ├── 2.tsx
│ ├── 20.tsx
│ ├── 21.tsx
│ ├── 22.tsx
│ ├── 23.tsx
│ ├── 24.tsx
│ ├── 25.tsx
│ ├── 3.tsx
│ ├── 4.tsx
│ ├── 7.tsx
│ ├── 8.tsx
│ └── 9.tsx
├── public
├── air-canada-vector-logo.png
├── building-website.png
├── canada-airplane.png
├── eslint-setup.png
├── lemon-squeezy-api.png
└── my-image.png
├── scripts
└── build-registry.js
├── tailwind.config.ts
└── tsconfig.json
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alisamadiii/Portfolio/51f097c3c5de225d20c0975b0edca9e95f09dc7e/.DS_Store
--------------------------------------------------------------------------------
/.contentlayer/.cache/v0.5.1/compiled-contentlayer-config-R5EPTL46.mjs:
--------------------------------------------------------------------------------
1 | // contentlayer.config.js
2 | import { defineDocumentType, makeSource } from "contentlayer2/source-files";
3 | import remarkGfm from "remark-gfm";
4 | import rehypePrettyCode from "rehype-pretty-code";
5 | import rehypeAutolinkHeadings from "rehype-autolink-headings";
6 | import rehypeSlug from "rehype-slug";
7 | var computedFields = {
8 | slug: {
9 | type: "string",
10 | resolve: (doc) => `/${doc._raw.flattenedPath}`
11 | },
12 | slugAsParams: {
13 | type: "string",
14 | resolve: (doc) => doc._raw.flattenedPath.split("/").slice(1).join("/")
15 | },
16 | folder: {
17 | type: "string",
18 | resolve: (doc) => {
19 | const pathParts = doc._raw.flattenedPath.split("/");
20 | return pathParts.length > 1 ? pathParts[pathParts.length - 2] : null;
21 | }
22 | }
23 | };
24 | var Blogs = defineDocumentType(() => ({
25 | name: "Blogs",
26 | filePathPattern: "./blogs/**/*.mdx",
27 | contentType: "mdx",
28 | fields: {
29 | title: {
30 | type: "string",
31 | required: true
32 | },
33 | description: {
34 | type: "string",
35 | required: true
36 | },
37 | image: {
38 | type: "string",
39 | required: true
40 | },
41 | hidden: {
42 | type: "boolean"
43 | }
44 | },
45 | computedFields
46 | }));
47 | var Works = defineDocumentType(() => ({
48 | name: "Works",
49 | filePathPattern: "./works/**/*.mdx",
50 | contentType: "mdx",
51 | fields: {
52 | title: {
53 | type: "string",
54 | required: true
55 | }
56 | },
57 | computedFields
58 | }));
59 | var TwitterContents = defineDocumentType(() => ({
60 | name: "TwitterContents",
61 | filePathPattern: "./twitter-contents/**/*.mdx",
62 | contentType: "mdx",
63 | fields: {
64 | title: {
65 | type: "string",
66 | required: true
67 | },
68 | tech: {
69 | type: "string",
70 | required: true
71 | }
72 | },
73 | computedFields
74 | }));
75 | var buildFast = defineDocumentType(() => ({
76 | name: "buildFast",
77 | filePathPattern: "./build-fast/**/*.mdx",
78 | contentType: "mdx",
79 | fields: {
80 | title: {
81 | type: "string",
82 | required: true
83 | },
84 | order: {
85 | type: "string"
86 | }
87 | },
88 | computedFields
89 | }));
90 | var contentlayer_config_default = makeSource({
91 | contentDirPath: "./contents",
92 | documentTypes: [Blogs, Works, TwitterContents, buildFast],
93 | mdx: {
94 | remarkPlugins: [remarkGfm],
95 | rehypePlugins: [
96 | rehypeSlug,
97 | [
98 | rehypePrettyCode,
99 | {
100 | theme: { light: "github-light-default", dark: "github-dark-dimmed" },
101 | keepBackground: false
102 | }
103 | ],
104 | [
105 | rehypeAutolinkHeadings,
106 | {
107 | behavior: "wrap",
108 | content: (node) => node.children,
109 | properties: {
110 | className: ["subheading-anchor"],
111 | ariaLabel: "Link to section"
112 | }
113 | }
114 | ]
115 | ]
116 | }
117 | });
118 | export {
119 | contentlayer_config_default as default
120 | };
121 | //# sourceMappingURL=compiled-contentlayer-config-R5EPTL46.mjs.map
122 |
--------------------------------------------------------------------------------
/.contentlayer/generated/Blogs/_index.mjs:
--------------------------------------------------------------------------------
1 | // NOTE This file is auto-generated by Contentlayer
2 |
3 | import blogs__eslintSetupMdx from './blogs__eslint-setup.mdx.json' with { type: 'json' }
4 | import blogs__lemonSqueezyMdx from './blogs__lemon-squeezy.mdx.json' with { type: 'json' }
5 | import blogs__makingWebsiteMdx from './blogs__making-website.mdx.json' with { type: 'json' }
6 | import blogs__myExperienceMdx from './blogs__my-experience.mdx.json' with { type: 'json' }
7 |
8 | export const allBlogs = [blogs__eslintSetupMdx, blogs__lemonSqueezyMdx, blogs__makingWebsiteMdx, blogs__myExperienceMdx]
9 |
--------------------------------------------------------------------------------
/.contentlayer/generated/TwitterContents/_index.mjs:
--------------------------------------------------------------------------------
1 | // NOTE This file is auto-generated by Contentlayer
2 |
3 | import twitterContents__1Mdx from './twitter-contents__1.mdx.json' with { type: 'json' }
4 | import twitterContents__10Mdx from './twitter-contents__10.mdx.json' with { type: 'json' }
5 | import twitterContents__11Mdx from './twitter-contents__11.mdx.json' with { type: 'json' }
6 | import twitterContents__12Mdx from './twitter-contents__12.mdx.json' with { type: 'json' }
7 | import twitterContents__13Mdx from './twitter-contents__13.mdx.json' with { type: 'json' }
8 | import twitterContents__14Mdx from './twitter-contents__14.mdx.json' with { type: 'json' }
9 | import twitterContents__15Mdx from './twitter-contents__15.mdx.json' with { type: 'json' }
10 | import twitterContents__16Mdx from './twitter-contents__16.mdx.json' with { type: 'json' }
11 | import twitterContents__17Mdx from './twitter-contents__17.mdx.json' with { type: 'json' }
12 | import twitterContents__18Mdx from './twitter-contents__18.mdx.json' with { type: 'json' }
13 | import twitterContents__19Mdx from './twitter-contents__19.mdx.json' with { type: 'json' }
14 | import twitterContents__2Mdx from './twitter-contents__2.mdx.json' with { type: 'json' }
15 | import twitterContents__20Mdx from './twitter-contents__20.mdx.json' with { type: 'json' }
16 | import twitterContents__21Mdx from './twitter-contents__21.mdx.json' with { type: 'json' }
17 | import twitterContents__22Mdx from './twitter-contents__22.mdx.json' with { type: 'json' }
18 | import twitterContents__23Mdx from './twitter-contents__23.mdx.json' with { type: 'json' }
19 | import twitterContents__24Mdx from './twitter-contents__24.mdx.json' with { type: 'json' }
20 | import twitterContents__25Mdx from './twitter-contents__25.mdx.json' with { type: 'json' }
21 | import twitterContents__3Mdx from './twitter-contents__3.mdx.json' with { type: 'json' }
22 | import twitterContents__4Mdx from './twitter-contents__4.mdx.json' with { type: 'json' }
23 | import twitterContents__5Mdx from './twitter-contents__5.mdx.json' with { type: 'json' }
24 | import twitterContents__6Mdx from './twitter-contents__6.mdx.json' with { type: 'json' }
25 | import twitterContents__7Mdx from './twitter-contents__7.mdx.json' with { type: 'json' }
26 | import twitterContents__8Mdx from './twitter-contents__8.mdx.json' with { type: 'json' }
27 | import twitterContents__9Mdx from './twitter-contents__9.mdx.json' with { type: 'json' }
28 |
29 | export const allTwitterContents = [twitterContents__1Mdx, twitterContents__10Mdx, twitterContents__11Mdx, twitterContents__12Mdx, twitterContents__13Mdx, twitterContents__14Mdx, twitterContents__15Mdx, twitterContents__16Mdx, twitterContents__17Mdx, twitterContents__18Mdx, twitterContents__19Mdx, twitterContents__2Mdx, twitterContents__20Mdx, twitterContents__21Mdx, twitterContents__22Mdx, twitterContents__23Mdx, twitterContents__24Mdx, twitterContents__25Mdx, twitterContents__3Mdx, twitterContents__4Mdx, twitterContents__5Mdx, twitterContents__6Mdx, twitterContents__7Mdx, twitterContents__8Mdx, twitterContents__9Mdx]
30 |
--------------------------------------------------------------------------------
/.contentlayer/generated/TwitterContents/twitter-contents__1.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Mix Blend Mode",
3 | "tech": "css",
4 | "body": {
5 | "raw": "\n \n",
6 | "code": "var Component=(()=>{var x=Object.create;var r=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var M=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),_=(t,e)=>{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let o of a(e))!w.call(t,o)&&o!==n&&r(t,o,{get:()=>e[o],enumerable:!(c=p(e,o))||c.enumerable});return t};var j=(t,e,n)=>(n=t!=null?x(l(t)):{},s(e||!t||!t.__esModule?r(n,\"default\",{value:t,enumerable:!0}):n,t)),C=t=>s(r({},\"__esModule\",{value:!0}),t);var d=M((g,m)=>{m.exports=_jsx_runtime});var y={};_(y,{default:()=>u,frontmatter:()=>h});var i=j(d()),h={title:\"Mix Blend Mode\",tech:\"css\"};function f(t){let{ComponentPreview:e}=t.components||{};return e||v(\"ComponentPreview\",!0),(0,i.jsx)(e,{name:\"twitter-contents-1\"})}function u(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(f,{...t})}):f(t)}function v(t,e){throw new Error(\"Expected \"+(e?\"component\":\"object\")+\" `\"+t+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return C(y);})();\n;return Component;"
7 | },
8 | "_id": "twitter-contents/1.mdx",
9 | "_raw": {
10 | "sourceFilePath": "twitter-contents/1.mdx",
11 | "sourceFileName": "1.mdx",
12 | "sourceFileDir": "twitter-contents",
13 | "contentType": "mdx",
14 | "flattenedPath": "twitter-contents/1"
15 | },
16 | "type": "TwitterContents",
17 | "slug": "/twitter-contents/1",
18 | "slugAsParams": "1",
19 | "folder": "twitter-contents"
20 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/TwitterContents/twitter-contents__12.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Input Number Format",
3 | "tech": "html",
4 | "body": {
5 | "raw": "\nMake sure to use it in your phone.\n\n```html title=\"index.html\"\n \n```\n\n \n",
6 | "code": "var Component=(()=>{var p=Object.create;var a=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var f=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),y=(t,e)=>{for(var n in e)a(t,n,{get:e[n],enumerable:!0})},d=(t,e,n,h)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let r of u(e))!k.call(t,r)&&r!==n&&a(t,r,{get:()=>e[r],enumerable:!(h=g(e,r))||h.enumerable});return t};var F=(t,e,n)=>(n=t!=null?p(m(t)):{},d(e||!t||!t.__esModule?a(n,\"default\",{value:t,enumerable:!0}):n,t)),x=t=>d(a({},\"__esModule\",{value:!0}),t);var l=f((_,s)=>{s.exports=_jsx_runtime});var C={};y(C,{default:()=>c,frontmatter:()=>A});var i=F(l()),A={title:\"Input Number Format\",tech:\"html\"};function o(t){let e={code:\"code\",figcaption:\"figcaption\",figure:\"figure\",p:\"p\",pre:\"pre\",span:\"span\",...t.components},{ComponentPreview:n}=e;return n||b(\"ComponentPreview\",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.p,{children:\"Make sure to use it in your phone.\"}),`\n`,(0,i.jsxs)(e.figure,{\"data-rehype-pretty-code-figure\":\"\",children:[(0,i.jsx)(e.figcaption,{\"data-rehype-pretty-code-title\":\"\",\"data-language\":\"html\",\"data-theme\":\"github-light-default github-dark-dimmed\",children:\"index.html\"}),(0,i.jsx)(e.pre,{tabIndex:\"0\",\"data-language\":\"html\",\"data-theme\":\"github-light-default github-dark-dimmed\",children:(0,i.jsx)(e.code,{\"data-language\":\"html\",\"data-theme\":\"github-light-default github-dark-dimmed\",style:{display:\"grid\"},children:(0,i.jsxs)(e.span,{\"data-line\":\"\",children:[(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#1F2328\",\"--shiki-dark\":\"#ADBAC7\"},children:\"<\"}),(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#116329\",\"--shiki-dark\":\"#8DDB8C\"},children:\"input\"}),(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#0550AE\",\"--shiki-dark\":\"#6CB6FF\"},children:\" type\"}),(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#1F2328\",\"--shiki-dark\":\"#ADBAC7\"},children:\"=\"}),(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#0A3069\",\"--shiki-dark\":\"#96D0FF\"},children:'\"number\"'}),(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#0550AE\",\"--shiki-dark\":\"#6CB6FF\"},children:\" inputmode\"}),(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#1F2328\",\"--shiki-dark\":\"#ADBAC7\"},children:\"=\"}),(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#0A3069\",\"--shiki-dark\":\"#96D0FF\"},children:'\"numeric\"'}),(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#1F2328\",\"--shiki-dark\":\"#ADBAC7\"},children:\" />\"})]})})})]}),`\n`,(0,i.jsx)(n,{name:\"twitter-contents-12\"})]})}function c(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(o,{...t})}):o(t)}function b(t,e){throw new Error(\"Expected \"+(e?\"component\":\"object\")+\" `\"+t+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return x(C);})();\n;return Component;"
7 | },
8 | "_id": "twitter-contents/12.mdx",
9 | "_raw": {
10 | "sourceFilePath": "twitter-contents/12.mdx",
11 | "sourceFileName": "12.mdx",
12 | "sourceFileDir": "twitter-contents",
13 | "contentType": "mdx",
14 | "flattenedPath": "twitter-contents/12"
15 | },
16 | "type": "TwitterContents",
17 | "slug": "/twitter-contents/12",
18 | "slugAsParams": "12",
19 | "folder": "twitter-contents"
20 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/TwitterContents/twitter-contents__18.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Text Gradient",
3 | "tech": "CSS",
4 | "body": {
5 | "raw": "\n \n",
6 | "code": "var Component=(()=>{var a=Object.create;var r=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var w=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var C=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),_=(t,e)=>{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},m=(t,e,n,c)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let o of p(e))!l.call(t,o)&&o!==n&&r(t,o,{get:()=>e[o],enumerable:!(c=d(e,o))||c.enumerable});return t};var j=(t,e,n)=>(n=t!=null?a(w(t)):{},m(e||!t||!t.__esModule?r(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=>m(r({},\"__esModule\",{value:!0}),t);var f=C((g,s)=>{s.exports=_jsx_runtime});var y={};_(y,{default:()=>x,frontmatter:()=>h});var i=j(f()),h={title:\"Text Gradient\",tech:\"CSS\"};function u(t){let{ComponentPreview:e}=t.components||{};return e||v(\"ComponentPreview\",!0),(0,i.jsx)(e,{name:\"twitter-contents-18\"})}function x(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(u,{...t})}):u(t)}function v(t,e){throw new Error(\"Expected \"+(e?\"component\":\"object\")+\" `\"+t+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return M(y);})();\n;return Component;"
7 | },
8 | "_id": "twitter-contents/18.mdx",
9 | "_raw": {
10 | "sourceFilePath": "twitter-contents/18.mdx",
11 | "sourceFileName": "18.mdx",
12 | "sourceFileDir": "twitter-contents",
13 | "contentType": "mdx",
14 | "flattenedPath": "twitter-contents/18"
15 | },
16 | "type": "TwitterContents",
17 | "slug": "/twitter-contents/18",
18 | "slugAsParams": "18",
19 | "folder": "twitter-contents"
20 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/TwitterContents/twitter-contents__2.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Border",
3 | "tech": "css",
4 | "body": {
5 | "raw": "\n \n",
6 | "code": "var Component=(()=>{var p=Object.create;var r=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var w=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var _=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=>{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let o of a(e))!l.call(t,o)&&o!==n&&r(t,o,{get:()=>e[o],enumerable:!(c=x(e,o))||c.enumerable});return t};var C=(t,e,n)=>(n=t!=null?p(w(t)):{},s(e||!t||!t.__esModule?r(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=>s(r({},\"__esModule\",{value:!0}),t);var f=_((g,m)=>{m.exports=_jsx_runtime});var y={};j(y,{default:()=>d,frontmatter:()=>h});var i=C(f()),h={title:\"Border\",tech:\"css\"};function u(t){let{ComponentPreview:e}=t.components||{};return e||v(\"ComponentPreview\",!0),(0,i.jsx)(e,{name:\"twitter-contents-2\"})}function d(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(u,{...t})}):u(t)}function v(t,e){throw new Error(\"Expected \"+(e?\"component\":\"object\")+\" `\"+t+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return M(y);})();\n;return Component;"
7 | },
8 | "_id": "twitter-contents/2.mdx",
9 | "_raw": {
10 | "sourceFilePath": "twitter-contents/2.mdx",
11 | "sourceFileName": "2.mdx",
12 | "sourceFileDir": "twitter-contents",
13 | "contentType": "mdx",
14 | "flattenedPath": "twitter-contents/2"
15 | },
16 | "type": "TwitterContents",
17 | "slug": "/twitter-contents/2",
18 | "slugAsParams": "2",
19 | "folder": "twitter-contents"
20 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/TwitterContents/twitter-contents__24.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "CSS Caret",
3 | "tech": "CSS",
4 | "body": {
5 | "raw": "\n```css title=\"style.css\"\ninput {\n caret-color: ;\n}\n```\n\n \n",
6 | "code": "var Component=(()=>{var g=Object.create;var r=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var k=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),y=(t,e)=>{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,d)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let a of u(e))!f.call(t,a)&&a!==n&&r(t,a,{get:()=>e[a],enumerable:!(d=p(e,a))||d.enumerable});return t};var x=(t,e,n)=>(n=t!=null?g(m(t)):{},s(e||!t||!t.__esModule?r(n,\"default\",{value:t,enumerable:!0}):n,t)),C=t=>s(r({},\"__esModule\",{value:!0}),t);var l=k((F,o)=>{o.exports=_jsx_runtime});var A={};y(A,{default:()=>h,frontmatter:()=>b});var i=x(l()),b={title:\"CSS Caret\",tech:\"CSS\"};function c(t){let e={code:\"code\",figcaption:\"figcaption\",figure:\"figure\",pre:\"pre\",span:\"span\",...t.components},{ComponentPreview:n}=e;return n||_(\"ComponentPreview\",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(e.figure,{\"data-rehype-pretty-code-figure\":\"\",children:[(0,i.jsx)(e.figcaption,{\"data-rehype-pretty-code-title\":\"\",\"data-language\":\"css\",\"data-theme\":\"github-light-default github-dark-dimmed\",children:\"style.css\"}),(0,i.jsx)(e.pre,{tabIndex:\"0\",\"data-language\":\"css\",\"data-theme\":\"github-light-default github-dark-dimmed\",children:(0,i.jsxs)(e.code,{\"data-language\":\"css\",\"data-theme\":\"github-light-default github-dark-dimmed\",style:{display:\"grid\"},children:[(0,i.jsxs)(e.span,{\"data-line\":\"\",children:[(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#116329\",\"--shiki-dark\":\"#8DDB8C\"},children:\"input\"}),(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#1F2328\",\"--shiki-dark\":\"#ADBAC7\"},children:\" {\"})]}),`\n`,(0,i.jsxs)(e.span,{\"data-line\":\"\",children:[(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#0550AE\",\"--shiki-dark\":\"#6CB6FF\"},children:\" caret-color\"}),(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#1F2328\",\"--shiki-dark\":\"#ADBAC7\"},children:\": ;\"})]}),`\n`,(0,i.jsx)(e.span,{\"data-line\":\"\",children:(0,i.jsx)(e.span,{style:{\"--shiki-light\":\"#1F2328\",\"--shiki-dark\":\"#ADBAC7\"},children:\"}\"})})]})})]}),`\n`,(0,i.jsx)(n,{name:\"twitter-contents-24\"})]})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(c,{...t})}):c(t)}function _(t,e){throw new Error(\"Expected \"+(e?\"component\":\"object\")+\" `\"+t+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return C(A);})();\n;return Component;"
7 | },
8 | "_id": "twitter-contents/24.mdx",
9 | "_raw": {
10 | "sourceFilePath": "twitter-contents/24.mdx",
11 | "sourceFileName": "24.mdx",
12 | "sourceFileDir": "twitter-contents",
13 | "contentType": "mdx",
14 | "flattenedPath": "twitter-contents/24"
15 | },
16 | "type": "TwitterContents",
17 | "slug": "/twitter-contents/24",
18 | "slugAsParams": "24",
19 | "folder": "twitter-contents"
20 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/TwitterContents/twitter-contents__3.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "::selection",
3 | "tech": "css",
4 | "body": {
5 | "raw": "\n \n",
6 | "code": "var Component=(()=>{var x=Object.create;var r=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var _=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=>{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let o of d(e))!w.call(t,o)&&o!==n&&r(t,o,{get:()=>e[o],enumerable:!(c=a(e,o))||c.enumerable});return t};var C=(t,e,n)=>(n=t!=null?x(l(t)):{},s(e||!t||!t.__esModule?r(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=>s(r({},\"__esModule\",{value:!0}),t);var f=_((g,m)=>{m.exports=_jsx_runtime});var y={};j(y,{default:()=>p,frontmatter:()=>h});var i=C(f()),h={title:\"::selection\",tech:\"css\"};function u(t){let{ComponentPreview:e}=t.components||{};return e||v(\"ComponentPreview\",!0),(0,i.jsx)(e,{name:\"twitter-contents-3\"})}function p(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(u,{...t})}):u(t)}function v(t,e){throw new Error(\"Expected \"+(e?\"component\":\"object\")+\" `\"+t+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return M(y);})();\n;return Component;"
7 | },
8 | "_id": "twitter-contents/3.mdx",
9 | "_raw": {
10 | "sourceFilePath": "twitter-contents/3.mdx",
11 | "sourceFileName": "3.mdx",
12 | "sourceFileDir": "twitter-contents",
13 | "contentType": "mdx",
14 | "flattenedPath": "twitter-contents/3"
15 | },
16 | "type": "TwitterContents",
17 | "slug": "/twitter-contents/3",
18 | "slugAsParams": "3",
19 | "folder": "twitter-contents"
20 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/TwitterContents/twitter-contents__4.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Position",
3 | "tech": "css",
4 | "body": {
5 | "raw": "\n \n",
6 | "code": "var Component=(()=>{var x=Object.create;var r=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var w=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var _=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=>{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let o of d(e))!l.call(t,o)&&o!==n&&r(t,o,{get:()=>e[o],enumerable:!(c=a(e,o))||c.enumerable});return t};var C=(t,e,n)=>(n=t!=null?x(w(t)):{},s(e||!t||!t.__esModule?r(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=>s(r({},\"__esModule\",{value:!0}),t);var f=_((b,m)=>{m.exports=_jsx_runtime});var y={};j(y,{default:()=>p,frontmatter:()=>h});var i=C(f()),h={title:\"Position\",tech:\"css\"};function u(t){let{ComponentPreview:e}=t.components||{};return e||v(\"ComponentPreview\",!0),(0,i.jsx)(e,{name:\"twitter-contents-4\"})}function p(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(u,{...t})}):u(t)}function v(t,e){throw new Error(\"Expected \"+(e?\"component\":\"object\")+\" `\"+t+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return M(y);})();\n;return Component;"
7 | },
8 | "_id": "twitter-contents/4.mdx",
9 | "_raw": {
10 | "sourceFilePath": "twitter-contents/4.mdx",
11 | "sourceFileName": "4.mdx",
12 | "sourceFileDir": "twitter-contents",
13 | "contentType": "mdx",
14 | "flattenedPath": "twitter-contents/4"
15 | },
16 | "type": "TwitterContents",
17 | "slug": "/twitter-contents/4",
18 | "slugAsParams": "4",
19 | "folder": "twitter-contents"
20 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/TwitterContents/twitter-contents__6.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "HTML Elements",
3 | "tech": "html",
4 | "body": {
5 | "raw": "\n### Block Elements\n\n \n\n### Inline Elements\n\n \n",
6 | "code": "var Component=(()=>{var d=Object.create;var r=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty;var b=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports),_=(n,e)=>{for(var o in e)r(n,o,{get:e[o],enumerable:!0})},l=(n,e,o,s)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let i of u(e))!p.call(n,i)&&i!==o&&r(n,i,{get:()=>e[i],enumerable:!(s=f(e,i))||s.enumerable});return n};var k=(n,e,o)=>(o=n!=null?d(x(n)):{},l(e||!n||!n.__esModule?r(o,\"default\",{value:n,enumerable:!0}):o,n)),w=n=>l(r({},\"__esModule\",{value:!0}),n);var a=b((C,c)=>{c.exports=_jsx_runtime});var E={};_(E,{default:()=>h,frontmatter:()=>g});var t=k(a()),g={title:\"HTML Elements\",tech:\"html\"};function m(n){let e={a:\"a\",h3:\"h3\",...n.components},{ComponentPreview:o}=e;return o||j(\"ComponentPreview\",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h3,{id:\"block-elements\",children:(0,t.jsx)(e.a,{className:\"subheading-anchor\",\"aria-label\":\"Link to section\",href:\"#block-elements\",children:\"Block Elements\"})}),`\n`,(0,t.jsx)(o,{name:\"twitter-contents-6-block-elements\"}),`\n`,(0,t.jsx)(e.h3,{id:\"inline-elements\",children:(0,t.jsx)(e.a,{className:\"subheading-anchor\",\"aria-label\":\"Link to section\",href:\"#inline-elements\",children:\"Inline Elements\"})}),`\n`,(0,t.jsx)(o,{name:\"twitter-contents-6-inline-elements\"})]})}function h(n={}){let{wrapper:e}=n.components||{};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(m,{...n})}):m(n)}function j(n,e){throw new Error(\"Expected \"+(e?\"component\":\"object\")+\" `\"+n+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return w(E);})();\n;return Component;"
7 | },
8 | "_id": "twitter-contents/6.mdx",
9 | "_raw": {
10 | "sourceFilePath": "twitter-contents/6.mdx",
11 | "sourceFileName": "6.mdx",
12 | "sourceFileDir": "twitter-contents",
13 | "contentType": "mdx",
14 | "flattenedPath": "twitter-contents/6"
15 | },
16 | "type": "TwitterContents",
17 | "slug": "/twitter-contents/6",
18 | "slugAsParams": "6",
19 | "folder": "twitter-contents"
20 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/TwitterContents/twitter-contents__7.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "CSS Variables",
3 | "tech": "css",
4 | "body": {
5 | "raw": "\n \n",
6 | "code": "var Component=(()=>{var p=Object.create;var r=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var C=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),_=(t,e)=>{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let o of d(e))!w.call(t,o)&&o!==n&&r(t,o,{get:()=>e[o],enumerable:!(c=x(e,o))||c.enumerable});return t};var j=(t,e,n)=>(n=t!=null?p(l(t)):{},s(e||!t||!t.__esModule?r(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=>s(r({},\"__esModule\",{value:!0}),t);var a=C((g,m)=>{m.exports=_jsx_runtime});var v={};_(v,{default:()=>u,frontmatter:()=>b});var i=j(a()),b={title:\"CSS Variables\",tech:\"css\"};function f(t){let{ComponentPreview:e}=t.components||{};return e||h(\"ComponentPreview\",!0),(0,i.jsx)(e,{name:\"twitter-contents-7\"})}function u(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(f,{...t})}):f(t)}function h(t,e){throw new Error(\"Expected \"+(e?\"component\":\"object\")+\" `\"+t+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return M(v);})();\n;return Component;"
7 | },
8 | "_id": "twitter-contents/7.mdx",
9 | "_raw": {
10 | "sourceFilePath": "twitter-contents/7.mdx",
11 | "sourceFileName": "7.mdx",
12 | "sourceFileDir": "twitter-contents",
13 | "contentType": "mdx",
14 | "flattenedPath": "twitter-contents/7"
15 | },
16 | "type": "TwitterContents",
17 | "slug": "/twitter-contents/7",
18 | "slugAsParams": "7",
19 | "folder": "twitter-contents"
20 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/TwitterContents/twitter-contents__8.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Proper Rounded Corners",
3 | "tech": "css",
4 | "body": {
5 | "raw": "\n \n",
6 | "code": "var Component=(()=>{var p=Object.create;var r=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var w=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var C=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),_=(e,t)=>{for(var n in t)r(e,n,{get:t[n],enumerable:!0})},s=(e,t,n,c)=>{if(t&&typeof t==\"object\"||typeof t==\"function\")for(let o of a(t))!l.call(e,o)&&o!==n&&r(e,o,{get:()=>t[o],enumerable:!(c=x(t,o))||c.enumerable});return e};var j=(e,t,n)=>(n=e!=null?p(w(e)):{},s(t||!e||!e.__esModule?r(n,\"default\",{value:e,enumerable:!0}):n,e)),M=e=>s(r({},\"__esModule\",{value:!0}),e);var u=C((b,m)=>{m.exports=_jsx_runtime});var y={};_(y,{default:()=>f,frontmatter:()=>h});var i=j(u()),h={title:\"Proper Rounded Corners\",tech:\"css\"};function d(e){let{ComponentPreview:t}=e.components||{};return t||v(\"ComponentPreview\",!0),(0,i.jsx)(t,{name:\"twitter-contents-8\"})}function f(e={}){let{wrapper:t}=e.components||{};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}function v(e,t){throw new Error(\"Expected \"+(t?\"component\":\"object\")+\" `\"+e+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return M(y);})();\n;return Component;"
7 | },
8 | "_id": "twitter-contents/8.mdx",
9 | "_raw": {
10 | "sourceFilePath": "twitter-contents/8.mdx",
11 | "sourceFileName": "8.mdx",
12 | "sourceFileDir": "twitter-contents",
13 | "contentType": "mdx",
14 | "flattenedPath": "twitter-contents/8"
15 | },
16 | "type": "TwitterContents",
17 | "slug": "/twitter-contents/8",
18 | "slugAsParams": "8",
19 | "folder": "twitter-contents"
20 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/Works/_index.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/.contentlayer/generated/Works/_index.mjs:
--------------------------------------------------------------------------------
1 | // NOTE This file is auto-generated by Contentlayer
2 |
3 |
4 |
5 | export const allWorks = []
6 |
--------------------------------------------------------------------------------
/.contentlayer/generated/Works/works__13.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "iOS Volume",
3 | "body": {
4 | "raw": "\n \n",
5 | "code": "var Component=(()=>{var p=Object.create;var r=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var _=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),j=(e,t)=>{for(var o in t)r(e,o,{get:t[o],enumerable:!0})},m=(e,t,o,c)=>{if(t&&typeof t==\"object\"||typeof t==\"function\")for(let n of d(t))!w.call(e,n)&&n!==o&&r(e,n,{get:()=>t[n],enumerable:!(c=x(t,n))||c.enumerable});return e};var C=(e,t,o)=>(o=e!=null?p(l(e)):{},m(t||!e||!e.__esModule?r(o,\"default\",{value:e,enumerable:!0}):o,e)),M=e=>m(r({},\"__esModule\",{value:!0}),e);var a=_((h,s)=>{s.exports=_jsx_runtime});var v={};j(v,{default:()=>f,frontmatter:()=>b});var i=C(a()),b={title:\"iOS Volume\"};function u(e){let{ComponentPreview:t}=e.components||{};return t||g(\"ComponentPreview\",!0),(0,i.jsx)(t,{name:\"works-13\",className:\"bg-natural-900\"})}function f(e={}){let{wrapper:t}=e.components||{};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}function g(e,t){throw new Error(\"Expected \"+(t?\"component\":\"object\")+\" `\"+e+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return M(v);})();\n;return Component;"
6 | },
7 | "_id": "works/13.mdx",
8 | "_raw": {
9 | "sourceFilePath": "works/13.mdx",
10 | "sourceFileName": "13.mdx",
11 | "sourceFileDir": "works",
12 | "contentType": "mdx",
13 | "flattenedPath": "works/13"
14 | },
15 | "type": "Works",
16 | "slug": "/works/13",
17 | "slugAsParams": "13",
18 | "folder": "works"
19 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/Works/works__15 copy.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Works-15",
3 | "body": {
4 | "raw": "\n \n",
5 | "code": "var Component=(()=>{var x=Object.create;var r=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var w=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var _=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),j=(e,t)=>{for(var o in t)r(e,o,{get:t[o],enumerable:!0})},s=(e,t,o,c)=>{if(t&&typeof t==\"object\"||typeof t==\"function\")for(let n of d(t))!l.call(e,n)&&n!==o&&r(e,n,{get:()=>t[n],enumerable:!(c=a(t,n))||c.enumerable});return e};var C=(e,t,o)=>(o=e!=null?x(w(e)):{},s(t||!e||!e.__esModule?r(o,\"default\",{value:e,enumerable:!0}):o,e)),M=e=>s(r({},\"__esModule\",{value:!0}),e);var f=_((g,m)=>{m.exports=_jsx_runtime});var y={};j(y,{default:()=>p,frontmatter:()=>k});var i=C(f()),k={title:\"Works-15\"};function u(e){let{ComponentPreview:t}=e.components||{};return t||v(\"ComponentPreview\",!0),(0,i.jsx)(t,{name:\"works-15\"})}function p(e={}){let{wrapper:t}=e.components||{};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}function v(e,t){throw new Error(\"Expected \"+(t?\"component\":\"object\")+\" `\"+e+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return M(y);})();\n;return Component;"
6 | },
7 | "_id": "works/15 copy.mdx",
8 | "_raw": {
9 | "sourceFilePath": "works/15 copy.mdx",
10 | "sourceFileName": "15 copy.mdx",
11 | "sourceFileDir": "works",
12 | "contentType": "mdx",
13 | "flattenedPath": "works/15 copy"
14 | },
15 | "type": "Works",
16 | "slug": "/works/15 copy",
17 | "slugAsParams": "15 copy",
18 | "folder": "works"
19 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/Works/works__16.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Todo List Information",
3 | "body": {
4 | "raw": "\n \n",
5 | "code": "var Component=(()=>{var d=Object.create;var r=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var w=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var _=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=>{for(var o in e)r(t,o,{get:e[o],enumerable:!0})},m=(t,e,o,c)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let n of x(e))!l.call(t,n)&&n!==o&&r(t,n,{get:()=>e[n],enumerable:!(c=p(e,n))||c.enumerable});return t};var C=(t,e,o)=>(o=t!=null?d(w(t)):{},m(e||!t||!t.__esModule?r(o,\"default\",{value:t,enumerable:!0}):o,t)),M=t=>m(r({},\"__esModule\",{value:!0}),t);var f=_((h,s)=>{s.exports=_jsx_runtime});var b={};j(b,{default:()=>a,frontmatter:()=>v});var i=C(f()),v={title:\"Todo List Information\"};function u(t){let{ComponentPreview:e}=t.components||{};return e||y(\"ComponentPreview\",!0),(0,i.jsx)(e,{name:\"works-16\"})}function a(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(u,{...t})}):u(t)}function y(t,e){throw new Error(\"Expected \"+(e?\"component\":\"object\")+\" `\"+t+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return M(b);})();\n;return Component;"
6 | },
7 | "_id": "works/16.mdx",
8 | "_raw": {
9 | "sourceFilePath": "works/16.mdx",
10 | "sourceFileName": "16.mdx",
11 | "sourceFileDir": "works",
12 | "contentType": "mdx",
13 | "flattenedPath": "works/16"
14 | },
15 | "type": "Works",
16 | "slug": "/works/16",
17 | "slugAsParams": "16",
18 | "folder": "works"
19 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/Works/works__23.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Folder Closed",
3 | "body": {
4 | "raw": "\n \n",
5 | "code": "var Component=(()=>{var p=Object.create;var r=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var C=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),_=(e,t)=>{for(var o in t)r(e,o,{get:t[o],enumerable:!0})},s=(e,t,o,c)=>{if(t&&typeof t==\"object\"||typeof t==\"function\")for(let n of a(t))!w.call(e,n)&&n!==o&&r(e,n,{get:()=>t[n],enumerable:!(c=x(t,n))||c.enumerable});return e};var j=(e,t,o)=>(o=e!=null?p(l(e)):{},s(t||!e||!e.__esModule?r(o,\"default\",{value:e,enumerable:!0}):o,e)),M=e=>s(r({},\"__esModule\",{value:!0}),e);var d=C((h,m)=>{m.exports=_jsx_runtime});var b={};_(b,{default:()=>u,frontmatter:()=>v});var i=j(d()),v={title:\"Folder Closed\"};function f(e){let{ComponentPreview:t}=e.components||{};return t||y(\"ComponentPreview\",!0),(0,i.jsx)(t,{name:\"works-23\"})}function u(e={}){let{wrapper:t}=e.components||{};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(f,{...e})}):f(e)}function y(e,t){throw new Error(\"Expected \"+(t?\"component\":\"object\")+\" `\"+e+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return M(b);})();\n;return Component;"
6 | },
7 | "_id": "works/23.mdx",
8 | "_raw": {
9 | "sourceFilePath": "works/23.mdx",
10 | "sourceFileName": "23.mdx",
11 | "sourceFileDir": "works",
12 | "contentType": "mdx",
13 | "flattenedPath": "works/23"
14 | },
15 | "type": "Works",
16 | "slug": "/works/23",
17 | "slugAsParams": "23",
18 | "folder": "works"
19 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/Works/works__helping.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Helping",
3 | "body": {
4 | "raw": "\n \n",
5 | "code": "var Component=(()=>{var x=Object.create;var r=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var _=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),g=(e,t)=>{for(var n in t)r(e,n,{get:t[n],enumerable:!0})},m=(e,t,n,c)=>{if(t&&typeof t==\"object\"||typeof t==\"function\")for(let o of d(t))!w.call(e,o)&&o!==n&&r(e,o,{get:()=>t[o],enumerable:!(c=a(t,o))||c.enumerable});return e};var j=(e,t,n)=>(n=e!=null?x(l(e)):{},m(t||!e||!e.__esModule?r(n,\"default\",{value:e,enumerable:!0}):n,e)),C=e=>m(r({},\"__esModule\",{value:!0}),e);var p=_((b,s)=>{s.exports=_jsx_runtime});var v={};g(v,{default:()=>u,frontmatter:()=>M});var i=j(p()),M={title:\"Helping\"};function f(e){let{ComponentPreview:t}=e.components||{};return t||h(\"ComponentPreview\",!0),(0,i.jsx)(t,{name:\"works-helping\"})}function u(e={}){let{wrapper:t}=e.components||{};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(f,{...e})}):f(e)}function h(e,t){throw new Error(\"Expected \"+(t?\"component\":\"object\")+\" `\"+e+\"` to be defined: you likely forgot to import, pass, or provide it.\")}return C(v);})();\n;return Component;"
6 | },
7 | "_id": "works/helping.mdx",
8 | "_raw": {
9 | "sourceFilePath": "works/helping.mdx",
10 | "sourceFileName": "helping.mdx",
11 | "sourceFileDir": "works",
12 | "contentType": "mdx",
13 | "flattenedPath": "works/helping"
14 | },
15 | "type": "Works",
16 | "slug": "/works/helping",
17 | "slugAsParams": "helping"
18 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/buildData/_index.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "title": "requirements",
4 | "body": {
5 | "raw": "\n# Requirements",
6 | "code": "var Component=(()=>{var l=Object.create;var i=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var q=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),j=(e,t)=>{for(var n in t)i(e,n,{get:t[n],enumerable:!0})},s=(e,t,n,a)=>{if(t&&typeof t==\"object\"||typeof t==\"function\")for(let r of x(t))!_.call(e,r)&&r!==n&&i(e,r,{get:()=>t[r],enumerable:!(a=d(t,r))||a.enumerable});return e};var p=(e,t,n)=>(n=e!=null?l(f(e)):{},s(t||!e||!e.__esModule?i(n,\"default\",{value:e,enumerable:!0}):n,e)),M=e=>s(i({},\"__esModule\",{value:!0}),e);var m=q((L,c)=>{c.exports=_jsx_runtime});var C={};j(C,{default:()=>h,frontmatter:()=>b});var o=p(m()),b={title:\"requirements\"};function u(e){let t={a:\"a\",h1:\"h1\",...e.components};return(0,o.jsx)(t.h1,{id:\"requirements\",children:(0,o.jsx)(t.a,{className:\"subheading-anchor\",\"aria-label\":\"Link to section\",href:\"#requirements\",children:\"Requirements\"})})}function h(e={}){let{wrapper:t}=e.components||{};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}return M(C);})();\n;return Component;"
7 | },
8 | "_id": "build-data/requirements.mdx",
9 | "_raw": {
10 | "sourceFilePath": "build-data/requirements.mdx",
11 | "sourceFileName": "requirements.mdx",
12 | "sourceFileDir": "build-data",
13 | "contentType": "mdx",
14 | "flattenedPath": "build-data/requirements"
15 | },
16 | "type": "buildData",
17 | "slug": "/build-data/requirements",
18 | "slugAsParams": "requirements"
19 | }
20 | ]
--------------------------------------------------------------------------------
/.contentlayer/generated/buildData/_index.mjs:
--------------------------------------------------------------------------------
1 | // NOTE This file is auto-generated by Contentlayer
2 |
3 | import buildData__requirementsMdx from './build-data__requirements.mdx.json' with { type: 'json' }
4 |
5 | export const allBuildData = [buildData__requirementsMdx]
6 |
--------------------------------------------------------------------------------
/.contentlayer/generated/buildData/build-data__requirements.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "requirements",
3 | "body": {
4 | "raw": "\n# Requirements",
5 | "code": "var Component=(()=>{var l=Object.create;var i=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var q=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),j=(e,t)=>{for(var n in t)i(e,n,{get:t[n],enumerable:!0})},s=(e,t,n,a)=>{if(t&&typeof t==\"object\"||typeof t==\"function\")for(let r of x(t))!_.call(e,r)&&r!==n&&i(e,r,{get:()=>t[r],enumerable:!(a=d(t,r))||a.enumerable});return e};var p=(e,t,n)=>(n=e!=null?l(f(e)):{},s(t||!e||!e.__esModule?i(n,\"default\",{value:e,enumerable:!0}):n,e)),M=e=>s(i({},\"__esModule\",{value:!0}),e);var m=q((L,c)=>{c.exports=_jsx_runtime});var C={};j(C,{default:()=>h,frontmatter:()=>b});var o=p(m()),b={title:\"requirements\"};function u(e){let t={a:\"a\",h1:\"h1\",...e.components};return(0,o.jsx)(t.h1,{id:\"requirements\",children:(0,o.jsx)(t.a,{className:\"subheading-anchor\",\"aria-label\":\"Link to section\",href:\"#requirements\",children:\"Requirements\"})})}function h(e={}){let{wrapper:t}=e.components||{};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}return M(C);})();\n;return Component;"
6 | },
7 | "_id": "build-data/requirements.mdx",
8 | "_raw": {
9 | "sourceFilePath": "build-data/requirements.mdx",
10 | "sourceFileName": "requirements.mdx",
11 | "sourceFileDir": "build-data",
12 | "contentType": "mdx",
13 | "flattenedPath": "build-data/requirements"
14 | },
15 | "type": "buildData",
16 | "slug": "/build-data/requirements",
17 | "slugAsParams": "requirements"
18 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/buildFast/_index.mjs:
--------------------------------------------------------------------------------
1 | // NOTE This file is auto-generated by Contentlayer
2 |
3 | import buildFast__errorHandlingMdx from './build-fast__error-handling.mdx.json' with { type: 'json' }
4 | import buildFast__linksMdx from './build-fast__links.mdx.json' with { type: 'json' }
5 | import buildFast__mdxSetupMdx from './build-fast__mdx-setup.mdx.json' with { type: 'json' }
6 | import buildFast__npmPackagesMdx from './build-fast__npm-packages.mdx.json' with { type: 'json' }
7 | import buildFast__requirementsMdx from './build-fast__requirements.mdx.json' with { type: 'json' }
8 | import buildFast__serverMdx from './build-fast__server.mdx.json' with { type: 'json' }
9 | import buildFast__supbaseMdx from './build-fast__supbase.mdx.json' with { type: 'json' }
10 | import buildFast__reactLibraries__generalHooksMdx from './build-fast__react-libraries__general-hooks.mdx.json' with { type: 'json' }
11 | import buildFast__reactLibraries__reactHotkeysHookMdx from './build-fast__react-libraries__react-hotkeys-hook.mdx.json' with { type: 'json' }
12 | import buildFast__reactLibraries__reactPdfMdx from './build-fast__react-libraries__react-pdf.mdx.json' with { type: 'json' }
13 | import buildFast__ui__usefulComponentsMdx from './build-fast__ui__useful-components.mdx.json' with { type: 'json' }
14 |
15 | export const allBuildFasts = [buildFast__errorHandlingMdx, buildFast__linksMdx, buildFast__mdxSetupMdx, buildFast__npmPackagesMdx, buildFast__requirementsMdx, buildFast__serverMdx, buildFast__supbaseMdx, buildFast__reactLibraries__generalHooksMdx, buildFast__reactLibraries__reactHotkeysHookMdx, buildFast__reactLibraries__reactPdfMdx, buildFast__ui__usefulComponentsMdx]
16 |
--------------------------------------------------------------------------------
/.contentlayer/generated/buildFast/build-fast__designs__charts.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Charts",
3 | "body": {
4 | "raw": "\n# Charts\n\n",
5 | "code": "var Component=(()=>{var u=Object.create;var o=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var C=(t,n)=>()=>(n||t((n={exports:{}}).exports,n),n.exports),j=(t,n)=>{for(var e in n)o(t,e,{get:n[e],enumerable:!0})},s=(t,n,e,c)=>{if(n&&typeof n==\"object\"||typeof n==\"function\")for(let r of x(n))!_.call(t,r)&&r!==e&&o(t,r,{get:()=>n[r],enumerable:!(c=d(n,r))||c.enumerable});return t};var p=(t,n,e)=>(e=t!=null?u(f(t)):{},s(n||!t||!t.__esModule?o(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=>s(o({},\"__esModule\",{value:!0}),t);var i=C((X,h)=>{h.exports=_jsx_runtime});var D={};j(D,{default:()=>m,frontmatter:()=>b});var a=p(i()),b={title:\"Charts\"};function l(t){let n={a:\"a\",h1:\"h1\",...t.components};return(0,a.jsx)(n.h1,{id:\"charts\",children:(0,a.jsx)(n.a,{className:\"subheading-anchor\",\"aria-label\":\"Link to section\",href:\"#charts\",children:\"Charts\"})})}function m(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,{...t,children:(0,a.jsx)(l,{...t})}):l(t)}return M(D);})();\n;return Component;"
6 | },
7 | "_id": "build-fast/designs/charts.mdx",
8 | "_raw": {
9 | "sourceFilePath": "build-fast/designs/charts.mdx",
10 | "sourceFileName": "charts.mdx",
11 | "sourceFileDir": "build-fast/designs",
12 | "contentType": "mdx",
13 | "flattenedPath": "build-fast/designs/charts"
14 | },
15 | "type": "buildFast",
16 | "slug": "/build-fast/designs/charts",
17 | "slugAsParams": "designs/charts",
18 | "folder": "designs"
19 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/buildFast/build-fast__links.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Links",
3 | "body": {
4 | "raw": "\n# Links\n\n- [Easing Graph](https://www.easing.dev/)\n- [Fancy Border Radius](https://9elements.github.io/fancy-border-radius/)\n\n## Gooey Effect\n\n- [Gooey Effect Blog](https://css-tricks.com/gooey-effect/)\n- [Gooey Effect Demo](https://x.com/jh3yy/status/1816899351152844947)\n- [Gooey Effect Demo 2](https://x.com/jh3yy/status/1816907840973627776)\n\n\n## Tricks\n\n- [Text Responds to Background Colors](https://x.com/JohnPhamous/status/1834345792494293453)\n- [Text Shadow on Scroll](https://x.com/samselikoff/status/1831847223287803985)\n",
5 | "code": "var Component=(()=>{var f=Object.create;var c=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,y=Object.prototype.hasOwnProperty;var g=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),k=(t,e)=>{for(var i in e)c(t,i,{get:e[i],enumerable:!0})},o=(t,e,i,h)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let r of m(e))!y.call(t,r)&&r!==i&&c(t,r,{get:()=>e[r],enumerable:!(h=u(e,r))||h.enumerable});return t};var p=(t,e,i)=>(i=t!=null?f(x(t)):{},o(e||!t||!t.__esModule?c(i,\"default\",{value:t,enumerable:!0}):i,t)),b=t=>o(c({},\"__esModule\",{value:!0}),t);var a=g((w,s)=>{s.exports=_jsx_runtime});var _={};k(_,{default:()=>d,frontmatter:()=>j});var n=p(a()),j={title:\"Links\"};function l(t){let e={a:\"a\",h1:\"h1\",h2:\"h2\",li:\"li\",ul:\"ul\",...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:\"links\",children:(0,n.jsx)(e.a,{className:\"subheading-anchor\",\"aria-label\":\"Link to section\",href:\"#links\",children:\"Links\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.easing.dev/\",children:\"Easing Graph\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://9elements.github.io/fancy-border-radius/\",children:\"Fancy Border Radius\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"gooey-effect\",children:(0,n.jsx)(e.a,{className:\"subheading-anchor\",\"aria-label\":\"Link to section\",href:\"#gooey-effect\",children:\"Gooey Effect\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://css-tricks.com/gooey-effect/\",children:\"Gooey Effect Blog\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://x.com/jh3yy/status/1816899351152844947\",children:\"Gooey Effect Demo\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://x.com/jh3yy/status/1816907840973627776\",children:\"Gooey Effect Demo 2\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"tricks\",children:(0,n.jsx)(e.a,{className:\"subheading-anchor\",\"aria-label\":\"Link to section\",href:\"#tricks\",children:\"Tricks\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://x.com/JohnPhamous/status/1834345792494293453\",children:\"Text Responds to Background Colors\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://x.com/samselikoff/status/1831847223287803985\",children:\"Text Shadow on Scroll\"})}),`\n`]})]})}function d(t={}){let{wrapper:e}=t.components||{};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(l,{...t})}):l(t)}return b(_);})();\n;return Component;"
6 | },
7 | "_id": "build-fast/links.mdx",
8 | "_raw": {
9 | "sourceFilePath": "build-fast/links.mdx",
10 | "sourceFileName": "links.mdx",
11 | "sourceFileDir": "build-fast",
12 | "contentType": "mdx",
13 | "flattenedPath": "build-fast/links"
14 | },
15 | "type": "buildFast",
16 | "slug": "/build-fast/links",
17 | "slugAsParams": "links",
18 | "folder": "build-fast"
19 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/buildFast/build-fast__npm-packages.mdx.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "NPM Packages",
3 | "body": {
4 | "raw": "\n# NPM Packages",
5 | "code": "var Component=(()=>{var u=Object.create;var c=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var g=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports),k=(n,e)=>{for(var t in e)c(n,t,{get:e[t],enumerable:!0})},s=(n,e,t,r)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let a of p(e))!f.call(n,a)&&a!==t&&c(n,a,{get:()=>e[a],enumerable:!(r=d(e,a))||r.enumerable});return n};var M=(n,e,t)=>(t=n!=null?u(x(n)):{},s(e||!n||!n.__esModule?c(t,\"default\",{value:n,enumerable:!0}):t,n)),_=n=>s(c({},\"__esModule\",{value:!0}),n);var m=g((b,i)=>{i.exports=_jsx_runtime});var j={};k(j,{default:()=>l,frontmatter:()=>P});var o=M(m()),P={title:\"NPM Packages\"};function h(n){let e={a:\"a\",h1:\"h1\",...n.components};return(0,o.jsx)(e.h1,{id:\"npm-packages\",children:(0,o.jsx)(e.a,{className:\"subheading-anchor\",\"aria-label\":\"Link to section\",href:\"#npm-packages\",children:\"NPM Packages\"})})}function l(n={}){let{wrapper:e}=n.components||{};return e?(0,o.jsx)(e,{...n,children:(0,o.jsx)(h,{...n})}):h(n)}return _(j);})();\n;return Component;"
6 | },
7 | "_id": "build-fast/npm-packages.mdx",
8 | "_raw": {
9 | "sourceFilePath": "build-fast/npm-packages.mdx",
10 | "sourceFileName": "npm-packages.mdx",
11 | "sourceFileDir": "build-fast",
12 | "contentType": "mdx",
13 | "flattenedPath": "build-fast/npm-packages"
14 | },
15 | "type": "buildFast",
16 | "slug": "/build-fast/npm-packages",
17 | "slugAsParams": "npm-packages",
18 | "folder": "build-fast"
19 | }
--------------------------------------------------------------------------------
/.contentlayer/generated/index.d.ts:
--------------------------------------------------------------------------------
1 | // NOTE This file is auto-generated by Contentlayer
2 |
3 | import { Blogs, Works, TwitterContents, buildFast, DocumentTypes, DataExports } from './types'
4 | import { SourceProvideSchemaErrorJSON, SourceFetchDataErrorJSON } from 'contentlayer2/core'
5 |
6 | export * from './types'
7 |
8 | export declare const allBlogs: Blogs[]
9 | export declare const allWorks: Works[]
10 | export declare const allTwitterContents: TwitterContents[]
11 | export declare const allBuildFasts: buildFast[]
12 |
13 | export declare const allDocuments: DocumentTypes[]
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.contentlayer/generated/index.mjs:
--------------------------------------------------------------------------------
1 | // NOTE This file is auto-generated by Contentlayer
2 |
3 | export { isType } from 'contentlayer2/client'
4 |
5 | // NOTE During development Contentlayer imports from `.mjs` files to improve HMR speeds.
6 | // During (production) builds Contentlayer it imports from `.json` files to improve build performance.
7 | import { allBlogs } from './Blogs/_index.mjs'
8 | import { allWorks } from './Works/_index.mjs'
9 | import { allTwitterContents } from './TwitterContents/_index.mjs'
10 | import { allBuildFasts } from './buildFast/_index.mjs'
11 |
12 | export { allBlogs, allWorks, allTwitterContents, allBuildFasts }
13 |
14 | export const allDocuments = [...allBlogs, ...allWorks, ...allTwitterContents, ...allBuildFasts]
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.contentlayer/generated/types.d.ts:
--------------------------------------------------------------------------------
1 | // NOTE This file is auto-generated by Contentlayer
2 |
3 | import type { Markdown, MDX, ImageFieldData, IsoDateTimeString } from 'contentlayer2/core'
4 | import * as Local from 'contentlayer2/source-files'
5 |
6 | export { isType } from 'contentlayer2/client'
7 |
8 | export type { Markdown, MDX, ImageFieldData, IsoDateTimeString }
9 |
10 | /** Document types */
11 | export type Blogs = {
12 | /** File path relative to `contentDirPath` */
13 | _id: string
14 | _raw: Local.RawDocumentData
15 | type: 'Blogs'
16 | title: string
17 | description: string
18 | image: string
19 | hidden?: boolean | undefined
20 | /** MDX file body */
21 | body: MDX
22 | slug: string
23 | slugAsParams: string
24 | folder: string
25 | }
26 |
27 | export type buildFast = {
28 | /** File path relative to `contentDirPath` */
29 | _id: string
30 | _raw: Local.RawDocumentData
31 | type: 'buildFast'
32 | title: string
33 | order?: string | undefined
34 | /** MDX file body */
35 | body: MDX
36 | slug: string
37 | slugAsParams: string
38 | folder: string
39 | }
40 |
41 | export type TwitterContents = {
42 | /** File path relative to `contentDirPath` */
43 | _id: string
44 | _raw: Local.RawDocumentData
45 | type: 'TwitterContents'
46 | title: string
47 | tech: string
48 | /** MDX file body */
49 | body: MDX
50 | slug: string
51 | slugAsParams: string
52 | folder: string
53 | }
54 |
55 | export type Works = {
56 | /** File path relative to `contentDirPath` */
57 | _id: string
58 | _raw: Local.RawDocumentData
59 | type: 'Works'
60 | title: string
61 | /** MDX file body */
62 | body: MDX
63 | slug: string
64 | slugAsParams: string
65 | folder: string
66 | }
67 |
68 | /** Nested types */
69 |
70 |
71 | /** Helper types */
72 |
73 | export type AllTypes = DocumentTypes | NestedTypes
74 | export type AllTypeNames = DocumentTypeNames | NestedTypeNames
75 |
76 | export type DocumentTypes = Blogs | buildFast | TwitterContents | Works
77 | export type DocumentTypeNames = 'Blogs' | 'buildFast' | 'TwitterContents' | 'Works'
78 |
79 | export type NestedTypes = never
80 | export type NestedTypeNames = never
81 |
82 | export type DataExports = {
83 | allDocuments: DocumentTypes[]
84 | allBlogs: Blogs[]
85 | allWorks: Works[]
86 | allTwitterContents: TwitterContents[]
87 | allBuildFasts: buildFast[]
88 | }
89 |
90 |
91 | export interface ContentlayerGenTypes {
92 | documentTypes: DocumentTypes
93 | documentTypeMap: DocumentTypeMap
94 | documentTypeNames: DocumentTypeNames
95 | nestedTypes: NestedTypes
96 | nestedTypeMap: NestedTypeMap
97 | nestedTypeNames: NestedTypeNames
98 | allTypeNames: AllTypeNames
99 | dataExports: DataExports
100 | }
101 |
102 | declare global {
103 | interface ContentlayerGen extends ContentlayerGenTypes {}
104 | }
105 |
106 | export type DocumentTypeMap = {
107 | Blogs: Blogs
108 | buildFast: buildFast
109 | TwitterContents: TwitterContents
110 | Works: Works
111 | }
112 |
113 | export type NestedTypeMap = {
114 |
115 | }
116 |
117 |
--------------------------------------------------------------------------------
/.contentlayer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dot-contentlayer",
3 | "description": "This package is auto-generated by Contentlayer",
4 | "version": "0.0.0-R5EPTL46",
5 | "exports": {
6 | "./generated": {
7 | "import": "./generated/index.mjs"
8 | }
9 | },
10 | "typesVersions": {
11 | "*": {
12 | "generated": [
13 | "./generated"
14 | ]
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next/core-web-vitals", "next/typescript"],
3 | "rules": {
4 | "@typescript-eslint/ban-ts-comment": "off",
5 | "@typescript-eslint/no-explicit-any": "off",
6 | "@typescript-eslint/no-empty-object-type": "off"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/.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 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | /tailwind-playground
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alisamadiii/Portfolio/51f097c3c5de225d20c0975b0edca9e95f09dc7e/.prettierignore
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["prettier-plugin-tailwindcss"],
3 | "trailingComma": "es5",
4 | "tabWidth": 2,
5 | "semi": true,
6 | "singleQuote": false,
7 | "bracketSpacing": true,
8 | "bracketSameLine": false,
9 | "singleAttributePerLine": false
10 | }
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Portfolio
2 |
3 | This is a portfolio website built with Next.js, and Tailwind CSS. I use this website to showcase my projects and skills.
4 |
5 | ## Links
6 |
7 | - [Works](https://www.alirezasamadi.com/work/1)
8 | - [Build Fast](https://www.alirezasamadi.com/build-fast/requirements) (Adding most of the things that could speed up the development process)
9 | - [NowShip](https://github.com/NowShip) (An organization to help me ship my projects faster)
10 | - [Blog](https://www.alirezasamadi.com/blog/eslint-setup)
11 | - [Experience](https://www.alirezasamadi.com/?experience=true)
12 | - [Twitter Contents](https://www.alirezasamadi.com/twitter-content/1)
13 |
--------------------------------------------------------------------------------
/app/api/send/route.ts:
--------------------------------------------------------------------------------
1 | import { Resend } from "resend";
2 | import { NextRequest } from "next/server";
3 |
4 | import { EmailTemplate } from "@/components/EmailTemplate";
5 |
6 | const resend = new Resend(process.env.RESEND_API_KEY);
7 |
8 | export async function POST(req: NextRequest) {
9 | const resData = await req.json();
10 |
11 | try {
12 | const { data, error } = await resend.emails.send({
13 | from: "hireme@alirezasamadi.com",
14 | to: ["alirs.dev@gmail.com"],
15 | subject: "Hire me",
16 | react: EmailTemplate({
17 | firstName: resData.firstName,
18 | email: resData.email,
19 | description: resData.description,
20 | companyName: resData.companyName,
21 | }),
22 | });
23 |
24 | if (error) {
25 | return Response.json({ error }, { status: 500 });
26 | }
27 |
28 | return Response.json(data);
29 | } catch (error) {
30 | return Response.json({ error }, { status: 500 });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/blog/[slug]/page.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { notFound } from "next/navigation";
3 | import Link from "next/link";
4 | import { allBlogs } from "contentlayer/generated";
5 |
6 | import { Mdx } from "@/components/MDX/MDXContent.blog";
7 |
8 | type Props = {
9 | params: { slug: string };
10 | };
11 |
12 | export async function generateStaticParams() {
13 | return allBlogs.map((post) => ({
14 | slug: post.slugAsParams,
15 | }));
16 | }
17 |
18 | export async function generateMetadata({ params }: Props) {
19 | const findingGoal = allBlogs.find(
20 | (post) => params.slug === post.slugAsParams
21 | );
22 |
23 | return {
24 | title: findingGoal?.title,
25 | description: findingGoal?.description,
26 | };
27 | }
28 |
29 | export default function DocsPage({ params: { slug } }: Props) {
30 | const findingGoal = allBlogs.find((post) => slug === post.slugAsParams);
31 |
32 | if (!findingGoal) {
33 | return notFound();
34 | }
35 |
36 | return (
37 |
38 |
39 |
40 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
61 |
62 |
63 |
64 |
65 |
66 | );
67 | }
68 |
--------------------------------------------------------------------------------
/app/build-fast/[...slug]/Menu.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import React, { useState } from "react";
4 |
5 | import {
6 | Drawer,
7 | DrawerTrigger,
8 | DrawerContent,
9 | DrawerClose,
10 | } from "@/components/ui/drawer";
11 | import { cn } from "@/lib/utils";
12 | import { allBuildFasts } from "@/.contentlayer/generated";
13 | import { MenuIcon } from "lucide-react";
14 | import { useRouter } from "next/navigation";
15 |
16 | type Props = {
17 | slug: string;
18 | };
19 |
20 | const folders = ["ui", "react-libraries"];
21 |
22 | export default function Menu({ slug }: Props) {
23 | const [open, setOpen] = useState(false);
24 | const router = useRouter();
25 |
26 | return (
27 |
28 |
29 |
30 |
31 |
32 | {allBuildFasts
33 | .filter((post) => post.folder === "build-fast")
34 | .sort((a, b) => {
35 | if (!a.order && !b.order) return 0;
36 | if (!a.order) return 1;
37 | if (!b.order) return -1;
38 | return Number(a.order) - Number(b.order);
39 | })
40 | .map((post) => (
41 | router.push(`/build-fast/${post.slugAsParams}`)}
44 | className={cn("rounded-md p-1 text-start", {
45 | "bg-neutral-200": post.slugAsParams === slug,
46 | })}
47 | >
48 | {post.title}
49 |
50 | ))}
51 |
52 | {folders.map((folder) => (
53 |
54 |
55 | {folder.replace("-", " ")}
56 |
57 | {allBuildFasts
58 | .filter((post) => post.folder === folder)
59 | .map((post) => (
60 |
63 | router.push(`/build-fast/${post.slugAsParams}`)
64 | }
65 | className={cn("rounded-md p-1 text-start", {
66 | "bg-neutral-200": post.slugAsParams === slug,
67 | })}
68 | >
69 | {post.title}
70 |
71 | ))}
72 |
73 | ))}
74 |
75 |
76 | );
77 | }
78 |
--------------------------------------------------------------------------------
/app/build-fast/[...slug]/Navbar.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import React from "react";
4 | import { allBuildFasts } from "contentlayer/generated";
5 | import Link from "next/link";
6 | import { cn } from "@/lib/utils";
7 |
8 | type Props = {
9 | slug: string;
10 | };
11 |
12 | const folders = ["ui", "react-libraries"];
13 |
14 | export default function Navbar({ slug }: Props) {
15 | return (
16 |
17 | {allBuildFasts
18 | .filter((post) => post.folder === "build-fast")
19 | .sort((a, b) => {
20 | if (!a.order && !b.order) return 0;
21 | if (!a.order) return 1;
22 | if (!b.order) return -1;
23 | return Number(a.order) - Number(b.order);
24 | })
25 | .map((post) => (
26 |
33 | {post.title}
34 |
35 | ))}
36 |
37 | {folders.map((folder) => (
38 |
39 |
40 | {folder.replace("-", " ")}
41 |
42 | {allBuildFasts
43 | .filter((post) => post.folder === folder)
44 | .map((post) => (
45 |
52 | {post.title}
53 |
54 | ))}
55 |
56 | ))}
57 |
58 | );
59 | }
60 |
--------------------------------------------------------------------------------
/app/build-fast/[...slug]/page.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { notFound } from "next/navigation";
3 | import Link from "next/link";
4 | import { allBuildFasts } from "contentlayer/generated";
5 |
6 | import { Mdx } from "@/components/MDX/MDXContent.blog";
7 | import Navbar from "./Navbar";
8 | import Menu from "./Menu";
9 |
10 | type Props = {
11 | params: { slug: string[] };
12 | };
13 | export async function generateStaticParams() {
14 | return allBuildFasts.map((post) => ({
15 | slug: post.slugAsParams.split("/"),
16 | }));
17 | }
18 |
19 | export async function generateMetadata({ params }: Props) {
20 | const findingGoal = allBuildFasts.find(
21 | (post) => params.slug.join("/") === post.slugAsParams
22 | );
23 |
24 | return {
25 | title: findingGoal?.title,
26 | };
27 | }
28 |
29 | export default function DocsPage({ params: { slug } }: Props) {
30 | const findingGoal = allBuildFasts.find(
31 | (post) => slug.join("/") === post.slugAsParams
32 | );
33 |
34 | if (!findingGoal) {
35 | return notFound();
36 | }
37 |
38 | return (
39 |
40 |
41 |
42 |
43 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
65 |
66 |
67 |
68 |
69 |
70 | );
71 | }
72 |
--------------------------------------------------------------------------------
/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alisamadiii/Portfolio/51f097c3c5de225d20c0975b0edca9e95f09dc7e/app/favicon.ico
--------------------------------------------------------------------------------
/app/fonts/GeistMonoVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alisamadiii/Portfolio/51f097c3c5de225d20c0975b0edca9e95f09dc7e/app/fonts/GeistMonoVF.woff
--------------------------------------------------------------------------------
/app/fonts/GeistVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alisamadiii/Portfolio/51f097c3c5de225d20c0975b0edca9e95f09dc7e/app/fonts/GeistVF.woff
--------------------------------------------------------------------------------
/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import { Lora, Inter } from "next/font/google";
3 | import "./globals.css";
4 |
5 | import { Toaster } from "@/components/ui/sonner";
6 | // import HireMe from "@/components/hire-me";
7 |
8 | const lora = Lora({
9 | subsets: ["latin"],
10 | variable: "--font-lora",
11 | });
12 | const inter = Inter({
13 | subsets: ["latin"],
14 | variable: "--font-inter",
15 | });
16 |
17 | export const metadata: Metadata = {
18 | title: "Ali Samadi - Portfolio",
19 | description: "Building Website is My Passion!",
20 | };
21 |
22 | export default function RootLayout({
23 | children,
24 | }: Readonly<{
25 | children: React.ReactNode;
26 | }>) {
27 | return (
28 |
29 |
32 | {/* */}
33 |
34 | {children}
35 |
36 |
37 |
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/app/not-found.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Text } from "../components/ui/text";
3 | import Link from "next/link";
4 | import { buttonVariants } from "../components/ui/button";
5 |
6 | export default function NotFound() {
7 | return (
8 |
9 |
10 |
11 | 404
12 |
13 |
14 | Page Not Found!
15 |
16 |
17 |
18 |
25 | Home
26 |
27 |
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/app/recording/[slug]/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import React from "react";
4 |
5 | import { Index } from "@/__registry__";
6 |
7 | type Props = {
8 | params: { slug: string };
9 | };
10 |
11 | export default function DocsPage({ params: { slug } }: Props) {
12 | const Component = Index[`works-${slug}`].component;
13 |
14 | return (
15 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/app/work/[...slug]/page.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Link from "next/link";
3 |
4 | export default function WorkPage() {
5 | return (
6 |
7 |
8 |
9 | Source Code Access Changed
10 |
11 |
12 | This project is no longer open source. To access the complete source
13 | code, please visit:
14 |
15 |
19 | motion.alismadii.com
20 |
21 |
22 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/app/x-content/[slug]/page.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Link from "next/link";
3 |
4 | import { allTwitterContents } from "contentlayer/generated";
5 | import { Mdx } from "@/components/MDX/MDXContent.work";
6 | import { notFound } from "next/navigation";
7 | import { Button } from "@/components/ui/button";
8 | import { ChevronLeft, ChevronRight } from "lucide-react";
9 | import { Badge } from "@/components/ui/badge";
10 | import { Text } from "@/components/ui/text";
11 |
12 | type Props = {
13 | params: { slug: string };
14 | };
15 |
16 | export async function generateStaticParams() {
17 | return allTwitterContents.map((post) => ({
18 | slug: post.slugAsParams,
19 | }));
20 | }
21 |
22 | export async function generateMetadata({ params }: Props) {
23 | const findingGoal = allTwitterContents.find(
24 | (post) => params.slug === post.slugAsParams
25 | );
26 |
27 | return {
28 | title: findingGoal?.title,
29 | };
30 | }
31 |
32 | export default function DocsPage({ params: { slug } }: Props) {
33 | const findingGoal = allTwitterContents.find(
34 | (post) => slug === post.slugAsParams
35 | );
36 |
37 | if (!findingGoal) {
38 | return notFound();
39 | }
40 |
41 | return (
42 | <>
43 |
46 |
47 |
48 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | {String(Number(slug)).padStart(2, "0")}
62 | {" "}
63 | / {" "}
64 | {String(allTwitterContents.length).padStart(2, "0")}
65 | {findingGoal.tech && (
66 | {findingGoal.tech}
67 | )}
68 |
69 |
70 |
75 |
76 |
77 |
78 |
79 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
97 | {findingGoal.title}
98 |
99 |
100 |
101 | >
102 | );
103 | }
104 |
--------------------------------------------------------------------------------
/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "app/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils",
16 | "ui": "@/components/ui",
17 | "lib": "@/lib",
18 | "hooks": "@/hooks"
19 | }
20 | }
--------------------------------------------------------------------------------
/components/AnimationSpeed.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { ClockArrowDown } from "lucide-react";
3 | import { AnimatePresence, motion } from "framer-motion";
4 |
5 | type Props = {
6 | onValueChange: (value: number) => void;
7 | speeds: number[];
8 | };
9 |
10 | export default function AnimationSpeed({ onValueChange, speeds }: Props) {
11 | const [currentIndex, setCurrentIndex] = useState(0);
12 |
13 | const onClickHandler = () => {
14 | if (currentIndex === speeds.length - 1) {
15 | setCurrentIndex(0);
16 | onValueChange(speeds[0]);
17 | } else {
18 | setCurrentIndex(currentIndex + 1);
19 | onValueChange(speeds[currentIndex]);
20 | }
21 | };
22 |
23 | return (
24 |
28 |
29 |
36 | {speeds[currentIndex]}s
37 |
38 |
39 |
40 |
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/components/CodePreview.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, ReactNode } from "react";
2 |
3 | import { motion } from "framer-motion";
4 |
5 | import { Button } from "./ui/button";
6 | import { Text } from "./ui/text";
7 |
8 | import { Sheet, SheetContent } from "@/components/ui/sheet";
9 |
10 | interface FilesProps {
11 | id: string;
12 | children: ReactNode;
13 | }
14 |
15 | export const CodePreview: React.FC = ({ children }) => {
16 | const [isCode, setIsCode] = useState(false);
17 |
18 | return (
19 | <>
20 |
21 |
25 | {!isCode && (
26 |
32 | )}
33 | Preview
34 |
35 | setIsCode(!isCode)}
39 | >
40 | {isCode && (
41 |
47 | )}
48 | Code
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | Code
57 |
58 | setIsCode(false)}>
59 |
66 |
67 |
71 |
72 |
73 |
74 |
75 | {children}
76 |
77 |
78 | >
79 | );
80 | };
81 |
--------------------------------------------------------------------------------
/components/ColorPicker.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { cn } from "@/lib/utils";
3 |
4 | interface ColorPickerProps {
5 | value: string;
6 | onValueChange: (color: string) => void;
7 | label?: string;
8 | }
9 |
10 | const famousColors = [
11 | { name: "Spotify Black", hex: "#191414" },
12 | { name: "Facebook Blue", hex: "#1877F2" },
13 | { name: "Twitter Blue", hex: "#1DA1F2" },
14 | { name: "LinkedIn Blue", hex: "#0A66C2" },
15 | { name: "Instagram Purple", hex: "#C13584" },
16 | { name: "YouTube Red", hex: "#FF0000" },
17 | { name: "Snapchat Yellow", hex: "#FFFC00" },
18 | { name: "Apple White", hex: "#FFFFFF" },
19 | ];
20 |
21 | const ColorPicker: React.FC = ({
22 | value,
23 | onValueChange,
24 | label,
25 | }) => {
26 | return (
27 |
28 | {label &&
{label}
}
29 |
30 | {famousColors.map((color) => (
31 | onValueChange(color.hex)}
40 | title={`${color.name} (${color.hex})`}
41 | />
42 | ))}
43 |
44 |
45 | );
46 | };
47 |
48 | export default ColorPicker;
49 |
--------------------------------------------------------------------------------
/components/ComponentPreview.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import React, { useRef } from "react";
4 |
5 | import { cn } from "@/lib/utils";
6 | import { Index } from "../__registry__";
7 |
8 | interface Props {
9 | name: string;
10 | children: React.ReactNode;
11 | className?: string;
12 | }
13 |
14 | export default function ComponentPreview({ name, className }: Props) {
15 | const Component = Index[name].component;
16 |
17 | const ref = useRef(null);
18 |
19 | if (name.includes("twitter-contents")) {
20 | return ;
21 | }
22 |
23 | return (
24 | <>
25 |
33 |
34 |
35 |
36 | {
39 | if (ref.current) {
40 | ref.current.requestFullscreen();
41 | }
42 | }}
43 | >
44 | maximize
45 |
46 |
47 | >
48 | );
49 | }
50 |
--------------------------------------------------------------------------------
/components/CopyButton.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { cn } from "@/lib/utils";
3 |
4 | type Props = {
5 | value: string;
6 | className?: string;
7 | };
8 |
9 | export default function CopyButton({ value, className }: Props) {
10 | const [copied, setCopied] = useState(false);
11 |
12 | useEffect(() => {
13 | if (copied) {
14 | const timeout = setTimeout(() => {
15 | setCopied(false);
16 | }, 1500);
17 |
18 | return () => {
19 | clearTimeout(timeout);
20 | };
21 | }
22 | }, [copied]);
23 |
24 | const handleCopy = () => {
25 | navigator.clipboard.writeText(value || "");
26 |
27 | setCopied(true);
28 | };
29 |
30 | return (
31 |
39 |
48 |
55 |
56 |
67 |
74 |
75 |
76 | );
77 | }
78 |
--------------------------------------------------------------------------------
/components/EmailTemplate.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | interface EmailTemplateProps {
4 | firstName: string;
5 | email: string;
6 | description: string;
7 | companyName: string;
8 | }
9 |
10 | export const EmailTemplate: React.FC> = ({
11 | firstName,
12 | email,
13 | description,
14 | companyName,
15 | }) => (
16 |
17 |
18 | Hey Ali, you have got a new email from someone that is trying to hire you.
19 |
20 |
21 |
A message from {firstName}:
22 |
23 |
{description}
24 |
25 |
26 | Name: {firstName}
27 | Email: {email}
28 | Company name: {companyName}
29 |
30 |
31 | );
32 |
--------------------------------------------------------------------------------
/components/FilesTab.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, ReactNode } from "react";
2 | import { LayoutGroup } from "framer-motion";
3 |
4 | import { cn } from "@/lib/utils";
5 |
6 | interface FileProps {
7 | label: string;
8 | children: ReactNode;
9 | }
10 |
11 | export interface FilesProps {
12 | id: string;
13 | children: ReactNode;
14 | className?: string;
15 | }
16 |
17 | export const Files: React.FC = ({ children, id, className }) => {
18 | const [activeTab, setActiveTab] = useState(0);
19 |
20 | return (
21 | <>
22 |
28 |
29 | {React.Children.map(children, (child, index) => {
30 | if (!React.isValidElement(child)) return null;
31 |
32 | return (
33 | setActiveTab(index)}
36 | className={cn(
37 | "relative p-1 text-natural-700",
38 | activeTab !== index && "text-natural-500"
39 | )}
40 | >
41 | {child.props.label}
42 |
43 | );
44 | })}
45 |
46 |
47 | {React.Children.toArray(children)[activeTab]}
48 | >
49 | );
50 | };
51 |
52 | export const File: React.FC = ({ children }) => (
53 | {children}
54 | );
55 |
--------------------------------------------------------------------------------
/components/GithubTheme.tsx:
--------------------------------------------------------------------------------
1 | export const githubLight = {
2 | 'code[class*="language-"]': {
3 | color: "#24292e",
4 | background: "transparent",
5 | fontFamily: "var(--font-geist-mono)",
6 | direction: "ltr",
7 | textAlign: "left",
8 | whiteSpace: "pre",
9 | wordSpacing: "normal",
10 | wordBreak: "normal",
11 | lineHeight: "1",
12 | MozTabSize: "4",
13 | OTabSize: "4",
14 | tabSize: "4",
15 | WebkitHyphens: "none",
16 | MozHyphens: "none",
17 | msHyphens: "none",
18 | hyphens: "none",
19 | fontSize: "14px",
20 | },
21 | 'pre[class*="language-"]': {
22 | color: "#24292e",
23 | background: "var(--background)",
24 | fontFamily: "var(--font-geist-mono)",
25 | direction: "ltr",
26 | textAlign: "left",
27 | whiteSpace: "pre",
28 | wordSpacing: "normal",
29 | wordBreak: "normal",
30 | lineHeight: "1.3",
31 | MozTabSize: "4",
32 | OTabSize: "4",
33 | tabSize: "4",
34 | WebkitHyphens: "none",
35 | MozHyphens: "none",
36 | msHyphens: "none",
37 | hyphens: "none",
38 | padding: "1em",
39 | margin: ".5em 0",
40 | overflow: "auto",
41 | borderRadius: "0.3em",
42 | border: "1px solid hsl(0 0% 93%)",
43 | },
44 | ':not(pre) > code[class*="language-"]': {
45 | background: "#f6f8fa",
46 | color: "#24292e",
47 | padding: ".2em .4em",
48 | borderRadius: ".3em",
49 | },
50 | comment: {
51 | color: "#6a737d",
52 | },
53 | prolog: {
54 | color: "#6a737d",
55 | },
56 | doctype: {
57 | color: "#6a737d",
58 | },
59 | cdata: {
60 | color: "#6a737d",
61 | },
62 | punctuation: {
63 | color: "#393a34",
64 | },
65 | ".namespace": {
66 | Opacity: ".7",
67 | },
68 | property: {
69 | color: "#005cc5",
70 | },
71 | keyword: {
72 | color: "#d73a49",
73 | },
74 | tag: {
75 | color: "#22863a",
76 | },
77 | "class-name": {
78 | color: "#6f42c1",
79 | fontWeight: "bold",
80 | },
81 | boolean: {
82 | color: "#005cc5",
83 | },
84 | constant: {
85 | color: "#005cc5",
86 | },
87 | symbol: {
88 | color: "#e36209",
89 | },
90 | deleted: {
91 | color: "#d73a49",
92 | backgroundColor: "#ffeef0",
93 | },
94 | number: {
95 | color: "#005cc5",
96 | },
97 | selector: {
98 | color: "#22863a",
99 | },
100 | "attr-name": {
101 | color: "#d73a49",
102 | },
103 | string: {
104 | color: "#032f62",
105 | },
106 | char: {
107 | color: "#032f62",
108 | },
109 | builtin: {
110 | color: "#6f42c1",
111 | },
112 | inserted: {
113 | color: "#22863a",
114 | backgroundColor: "#f0fff4",
115 | },
116 | variable: {
117 | color: "#e36209",
118 | },
119 | operator: {
120 | color: "#d73a49",
121 | },
122 | entity: {
123 | color: "#22863a",
124 | cursor: "help",
125 | },
126 | url: {
127 | color: "#032f62",
128 | },
129 | ".language-css .token.string": {
130 | color: "#032f62",
131 | },
132 | ".style .token.string": {
133 | color: "#032f62",
134 | },
135 | atrule: {
136 | color: "#d73a49",
137 | },
138 | "attr-value": {
139 | color: "#005cc5",
140 | },
141 | function: {
142 | color: "#6f42c1",
143 | },
144 | regex: {
145 | color: "#032f62",
146 | },
147 | important: {
148 | color: "#005cc5",
149 | fontWeight: "bold",
150 | },
151 | bold: {
152 | fontWeight: "bold",
153 | },
154 | italic: {
155 | fontStyle: "italic",
156 | },
157 | };
158 |
--------------------------------------------------------------------------------
/components/IphoneSimulator.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { cn } from "@/lib/utils";
4 |
5 | type Props = {
6 | children: React.ReactNode;
7 | className?: string;
8 | classWrapper?: string;
9 | };
10 |
11 | export default function IphoneSimulator({
12 | children,
13 | className,
14 | classWrapper,
15 | }: Props) {
16 | return (
17 |
23 |
24 |
30 |
36 |
{children}
37 |
38 |
39 |
42 |
43 | );
44 | }
45 |
--------------------------------------------------------------------------------
/components/SyntaxHighlighter.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Prism } from "react-syntax-highlighter";
3 |
4 | import CopyButton from "./CopyButton";
5 | import { githubLight } from "./GithubTheme";
6 |
7 | type Props = {
8 | children?: React.ReactNode;
9 | language?: "css" | "html" | "javascript";
10 | };
11 |
12 | export default function SyntaxHighlighter({
13 | children,
14 | language = "javascript",
15 | }: Props) {
16 | const getTextFromChildren = (children: React.ReactNode): string => {
17 | if (typeof children === "string") {
18 | return children;
19 | }
20 | if (Array.isArray(children)) {
21 | return children
22 | .map((child) => (typeof child === "string" ? child : ""))
23 | .join("");
24 | }
25 | return "";
26 | };
27 |
28 | const codeText = getTextFromChildren(children);
29 |
30 | return (
31 |
32 | {/* @ts-ignore */}
33 |
34 | {children}
35 |
36 |
37 |
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/components/Tabs.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, ReactNode } from "react";
2 | import { LayoutGroup, motion } from "framer-motion";
3 | import { cn } from "@/lib/utils";
4 |
5 | interface TabProps {
6 | label: string;
7 | children: ReactNode;
8 | }
9 |
10 | export interface TabsProps {
11 | id: string;
12 | children: ReactNode;
13 | className?: string;
14 | }
15 |
16 | export const Tabs: React.FC = ({ children, id, className }) => {
17 | const [activeTab, setActiveTab] = useState(0);
18 |
19 | return (
20 |
21 |
24 | {React.Children.map(children, (child, index) => {
25 | if (!React.isValidElement(child)) return null;
26 | return (
27 | setActiveTab(index)}
30 | className={cn(
31 | "relative px-4 py-2 duration-200",
32 | activeTab !== index && "opacity-60"
33 | )}
34 | >
35 | {child.props.label}
36 |
37 | {activeTab === index && (
38 |
43 | )}
44 |
45 | );
46 | })}
47 |
48 | {React.Children.toArray(children)[activeTab]}
49 |
50 | );
51 | };
52 |
53 | export const Tab: React.FC = ({ children }) => {children}
;
54 |
--------------------------------------------------------------------------------
/components/TwitterContentsElement.tsx:
--------------------------------------------------------------------------------
1 | import React, { useRef } from "react";
2 | import { cn } from "@/lib/utils";
3 | import { Maximize } from "lucide-react";
4 | import { useFullscreen, useToggle } from "react-use";
5 |
6 | type Props = {
7 | children: React.ReactNode;
8 | className?: string;
9 | };
10 |
11 | export function Wrapper({ children, className }: Props) {
12 | return {children}
;
13 | }
14 |
15 | export function Code({ children, className }: Props) {
16 | return (
17 |
18 | {children}
19 |
20 | );
21 | }
22 |
23 | export function Preview({ children, className }: Props) {
24 | const ref = useRef(null);
25 |
26 | const [show, toggle] = useToggle(false);
27 | const isFullscreen = useFullscreen(ref, show, {
28 | onClose: () => toggle(false),
29 | });
30 |
31 | return (
32 |
33 |
40 | {children}
41 | {!isFullscreen && (
42 | toggle(true)}
45 | >
46 |
47 |
48 | )}
49 |
50 |
51 |
52 | );
53 | }
54 |
55 | export function Settings({ children, className }: Props) {
56 | return (
57 |
58 | {children}
59 |
60 | );
61 | }
62 |
--------------------------------------------------------------------------------
/components/apps.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { cn } from "@/lib/utils";
3 |
4 | import {
5 | Tooltip,
6 | TooltipContent,
7 | TooltipTrigger,
8 | TooltipProvider,
9 | } from "@/components/ui/tooltip";
10 |
11 | const icons = [
12 | {
13 | value: "Cursor AI",
14 | label: "Writing code and designing websites.",
15 | },
16 | {
17 | value: "Screen Studio",
18 | label: "Recording videos.",
19 | },
20 | {
21 | value: "Typefully",
22 | label: "Scheduling posts for X and LinkedIn.",
23 | },
24 | ];
25 |
26 | export default function Apps() {
27 | return (
28 |
29 | {icons.map((icon, index) => (
30 |
31 |
32 |
33 |
41 | {icon.value}
42 |
43 |
44 | {icon.label}
45 |
46 |
47 | ))}
48 |
49 | );
50 | }
51 |
--------------------------------------------------------------------------------
/components/experience.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { allBlogs } from "@/.contentlayer/generated";
4 | import { Mdx } from "./MDX/MDXContent.blog";
5 | import { DialogClose } from "./ui/dialog";
6 |
7 | export default function Experience() {
8 | const findingGoal = allBlogs.find(
9 | (post) => post.slugAsParams === "my-experience"
10 | );
11 |
12 | if (!findingGoal) return null;
13 |
14 | return (
15 |
16 |
17 | Close
18 |
19 |
20 |
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/components/hire-me.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import React, { useEffect, useState } from "react";
4 | import { AnimatePresence, motion } from "framer-motion";
5 | import { usePathname } from "next/navigation";
6 | import { X } from "lucide-react";
7 |
8 | import {
9 | Tooltip,
10 | TooltipContent,
11 | TooltipProvider,
12 | TooltipTrigger,
13 | } from "@/components/ui/tooltip";
14 |
15 | type Props = {};
16 |
17 | export default function HireMe({}: Props) {
18 | const [isOpen, setIsOpen] = useState(false);
19 | const pathname = usePathname();
20 |
21 | useEffect(() => {
22 | setTimeout(() => {
23 | setIsOpen(true);
24 | }, 1000);
25 | }, []);
26 |
27 | if (pathname === "/volleyball") {
28 | return null;
29 | }
30 |
31 | return (
32 |
33 | {isOpen && (
34 |
35 |
42 |
43 |
44 |
53 |
54 |
55 |
56 |
61 | cal.com/alisamadi
62 |
63 |
64 |
65 | Book a call with me
66 |
67 |
68 |
69 |
70 |
71 | {pathname !== "/" && (
72 |
setIsOpen(false)}
80 | className="absolute right-4 top-1/2 -translate-y-1/2 text-natural-600"
81 | >
82 |
83 |
84 | )}
85 |
86 | )}
87 |
88 | );
89 | }
90 |
--------------------------------------------------------------------------------
/components/ui/badge.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { cva, type VariantProps } from "class-variance-authority";
3 |
4 | import { cn } from "@/lib/utils";
5 |
6 | const badgeVariants = cva(
7 | "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8 | {
9 | variants: {
10 | variant: {
11 | default:
12 | "border-transparent bg-natural-200 text-natural-700 hover:bg-natural-300",
13 | secondary:
14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
15 | destructive:
16 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
17 | outline: "text-foreground",
18 | },
19 | },
20 | defaultVariants: {
21 | variant: "default",
22 | },
23 | }
24 | );
25 |
26 | export interface BadgeProps
27 | extends React.HTMLAttributes,
28 | VariantProps {}
29 |
30 | function Badge({ className, variant, ...props }: BadgeProps) {
31 | return (
32 |
33 | );
34 | }
35 |
36 | export { Badge, badgeVariants };
37 |
--------------------------------------------------------------------------------
/components/ui/button.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Slot } from "@radix-ui/react-slot";
3 | import { cva, type VariantProps } from "class-variance-authority";
4 |
5 | import { cn } from "@/lib/utils";
6 |
7 | const buttonVariants = cva(
8 | "inline-flex items-center justify-center whitespace-nowrap rounded-md font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
9 | {
10 | variants: {
11 | variant: {
12 | default:
13 | "bg-natural-900 border border-transparent text-primary-foreground hover:bg-primary/90",
14 | destructive:
15 | "bg-destructive text-destructive-foreground hover:bg-destructive/90",
16 | outline:
17 | "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
18 | secondary:
19 | "bg-secondary text-secondary-foreground hover:bg-secondary/80",
20 | ghost: "hover:bg-accent hover:text-accent-foreground",
21 | link: "text-primary underline-offset-4 hover:underline",
22 | },
23 | size: {
24 | default: "h-10 px-4 py-2",
25 | sm: "h-9 rounded-md px-3",
26 | lg: "h-12 w-fit px-6 md:px-0 md:h-[75px] rounded-full md:w-[216px]",
27 | icon: "h-10 w-10",
28 | },
29 | },
30 | defaultVariants: {
31 | variant: "default",
32 | size: "default",
33 | },
34 | }
35 | );
36 |
37 | export interface ButtonProps
38 | extends React.ButtonHTMLAttributes,
39 | VariantProps {
40 | asChild?: boolean;
41 | }
42 |
43 | const Button = React.forwardRef(
44 | ({ className, variant, size, asChild = false, ...props }, ref) => {
45 | const Comp = asChild ? Slot : "button";
46 | return (
47 |
52 | );
53 | }
54 | );
55 | Button.displayName = "Button";
56 |
57 | export { Button, buttonVariants };
58 |
--------------------------------------------------------------------------------
/components/ui/dialog.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as DialogPrimitive from "@radix-ui/react-dialog";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Dialog = DialogPrimitive.Root;
9 |
10 | const DialogTrigger = DialogPrimitive.Trigger;
11 |
12 | const DialogPortal = DialogPrimitive.Portal;
13 |
14 | const DialogClose = DialogPrimitive.Close;
15 |
16 | const DialogOverlay = React.forwardRef<
17 | React.ElementRef,
18 | React.ComponentPropsWithoutRef
19 | >(({ className, ...props }, ref) => (
20 |
28 | ));
29 | DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
30 |
31 | const DialogContent = React.forwardRef<
32 | React.ElementRef,
33 | React.ComponentPropsWithoutRef
34 | >(({ className, children, ...props }, ref) => (
35 |
36 |
37 |
45 | {children}
46 |
47 |
48 | ));
49 | DialogContent.displayName = DialogPrimitive.Content.displayName;
50 |
51 | const DialogHeader = ({
52 | className,
53 | ...props
54 | }: React.HTMLAttributes) => (
55 |
62 | );
63 | DialogHeader.displayName = "DialogHeader";
64 |
65 | const DialogFooter = ({
66 | className,
67 | ...props
68 | }: React.HTMLAttributes) => (
69 |
76 | );
77 | DialogFooter.displayName = "DialogFooter";
78 |
79 | const DialogTitle = React.forwardRef<
80 | React.ElementRef,
81 | React.ComponentPropsWithoutRef
82 | >(({ className, ...props }, ref) => (
83 |
91 | ));
92 | DialogTitle.displayName = DialogPrimitive.Title.displayName;
93 |
94 | const DialogDescription = React.forwardRef<
95 | React.ElementRef,
96 | React.ComponentPropsWithoutRef
97 | >(({ className, ...props }, ref) => (
98 |
103 | ));
104 | DialogDescription.displayName = DialogPrimitive.Description.displayName;
105 |
106 | export {
107 | Dialog,
108 | DialogPortal,
109 | DialogOverlay,
110 | DialogClose,
111 | DialogTrigger,
112 | DialogContent,
113 | DialogHeader,
114 | DialogFooter,
115 | DialogTitle,
116 | DialogDescription,
117 | };
118 |
--------------------------------------------------------------------------------
/components/ui/drawer.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import { Drawer as DrawerPrimitive } from "vaul";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Drawer = ({
9 | shouldScaleBackground = true,
10 | ...props
11 | }: React.ComponentProps) => (
12 |
16 | );
17 | Drawer.displayName = "Drawer";
18 |
19 | const DrawerTrigger = DrawerPrimitive.Trigger;
20 |
21 | const DrawerPortal = DrawerPrimitive.Portal;
22 |
23 | const DrawerClose = DrawerPrimitive.Close;
24 |
25 | const DrawerOverlay = React.forwardRef<
26 | React.ElementRef,
27 | React.ComponentPropsWithoutRef
28 | >(({ className, ...props }, ref) => (
29 |
34 | ));
35 | DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName;
36 |
37 | const DrawerContent = React.forwardRef<
38 | React.ElementRef,
39 | React.ComponentPropsWithoutRef
40 | >(({ className, children, ...props }, ref) => (
41 |
42 |
43 |
51 | {children}
52 |
53 |
54 | ));
55 | DrawerContent.displayName = "DrawerContent";
56 |
57 | const DrawerHeader = ({
58 | className,
59 | ...props
60 | }: React.HTMLAttributes) => (
61 |
65 | );
66 | DrawerHeader.displayName = "DrawerHeader";
67 |
68 | const DrawerFooter = ({
69 | className,
70 | ...props
71 | }: React.HTMLAttributes) => (
72 |
76 | );
77 | DrawerFooter.displayName = "DrawerFooter";
78 |
79 | const DrawerTitle = React.forwardRef<
80 | React.ElementRef,
81 | React.ComponentPropsWithoutRef
82 | >(({ className, ...props }, ref) => (
83 |
91 | ));
92 | DrawerTitle.displayName = DrawerPrimitive.Title.displayName;
93 |
94 | const DrawerDescription = React.forwardRef<
95 | React.ElementRef,
96 | React.ComponentPropsWithoutRef
97 | >(({ className, ...props }, ref) => (
98 |
103 | ));
104 | DrawerDescription.displayName = DrawerPrimitive.Description.displayName;
105 |
106 | export {
107 | Drawer,
108 | DrawerPortal,
109 | DrawerOverlay,
110 | DrawerTrigger,
111 | DrawerClose,
112 | DrawerContent,
113 | DrawerHeader,
114 | DrawerFooter,
115 | DrawerTitle,
116 | DrawerDescription,
117 | };
118 |
--------------------------------------------------------------------------------
/components/ui/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | import { cn } from "@/lib/utils";
4 |
5 | export interface InputProps
6 | extends React.InputHTMLAttributes {}
7 |
8 | const Input = React.forwardRef(
9 | ({ className, type, ...props }, ref) => {
10 | return (
11 |
20 | );
21 | }
22 | );
23 | Input.displayName = "Input";
24 |
25 | export { Input };
26 |
--------------------------------------------------------------------------------
/components/ui/label.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as LabelPrimitive from "@radix-ui/react-label";
5 | import { cva, type VariantProps } from "class-variance-authority";
6 |
7 | import { cn } from "@/lib/utils";
8 |
9 | const labelVariants = cva(
10 | "text-sm font-medium leading-none block peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
11 | );
12 |
13 | const Label = React.forwardRef<
14 | React.ElementRef,
15 | React.ComponentPropsWithoutRef &
16 | VariantProps
17 | >(({ className, ...props }, ref) => (
18 |
23 | ));
24 | Label.displayName = LabelPrimitive.Root.displayName;
25 |
26 | export { Label };
27 |
--------------------------------------------------------------------------------
/components/ui/separator.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as SeparatorPrimitive from "@radix-ui/react-separator"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const Separator = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(
12 | (
13 | { className, orientation = "horizontal", decorative = true, ...props },
14 | ref
15 | ) => (
16 |
27 | )
28 | )
29 | Separator.displayName = SeparatorPrimitive.Root.displayName
30 |
31 | export { Separator }
32 |
--------------------------------------------------------------------------------
/components/ui/slider.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as SliderPrimitive from "@radix-ui/react-slider";
5 | import { cn } from "@/lib/utils";
6 |
7 | const Slider = React.forwardRef<
8 | React.ElementRef,
9 | React.ComponentPropsWithoutRef
10 | >(({ className, ...props }, ref) => (
11 |
19 |
23 |
24 |
25 |
26 |
27 | ));
28 | Slider.displayName = SliderPrimitive.Root.displayName;
29 |
30 | export { Slider };
31 |
--------------------------------------------------------------------------------
/components/ui/sonner.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import { useTheme } from "next-themes"
4 | import { Toaster as Sonner } from "sonner"
5 |
6 | type ToasterProps = React.ComponentProps
7 |
8 | const Toaster = ({ ...props }: ToasterProps) => {
9 | const { theme = "system" } = useTheme()
10 |
11 | return (
12 |
28 | )
29 | }
30 |
31 | export { Toaster }
32 |
--------------------------------------------------------------------------------
/components/ui/text.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { cva, type VariantProps } from "class-variance-authority";
3 |
4 | import { cn } from "@/lib/utils";
5 |
6 | const textVariants = cva("", {
7 | variants: {
8 | variant: {
9 | h1: "text-[40px] font-lora font-semibold leading-[125%]",
10 | h2: "text-[24px] md:text-[32px] font-lora font-semibold leading-[125%]",
11 | h3: "text-2xl font-lora font-semibold leading-[125%]",
12 | h4: "text-lg font-lora font-semibold leading-[125%]",
13 | h5: "text-sm font-lora font-semibold leading-[125%]",
14 | "p1-r": "leading-[150%]",
15 | "p1-b": "leading-[150%] font-medium",
16 | "p2-r": "leading-[150%] text-sm",
17 | "p2-b": "leading-[150%] text-sm font-medium",
18 | "p3-r": "leading-[150%] text-xs",
19 | "p3-b": "leading-[150%] text-xs font-medium",
20 | label: "text-sm font-medium text-neutral-500",
21 | },
22 | },
23 | defaultVariants: {
24 | variant: "p1-r",
25 | },
26 | });
27 |
28 | export interface TextProps
29 | extends React.HTMLAttributes,
30 | VariantProps {
31 | element?: "h1" | "h2" | "h3" | "h4" | "h5" | "p" | "span";
32 | }
33 |
34 | const Text = React.forwardRef<
35 | HTMLElement | HTMLHeadingElement | HTMLParagraphElement | HTMLSpanElement,
36 | TextProps
37 | >(({ className, variant, element = "p", ...props }, ref) => {
38 | const Element = element;
39 |
40 | return (
41 |
46 | );
47 | });
48 | Text.displayName = "Text";
49 |
50 | export { Text, textVariants };
51 |
--------------------------------------------------------------------------------
/components/ui/textarea.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | import { cn } from "@/lib/utils";
4 |
5 | export interface TextareaProps
6 | extends React.TextareaHTMLAttributes {}
7 |
8 | const Textarea = React.forwardRef(
9 | ({ className, ...props }, ref) => {
10 | return (
11 |
19 | );
20 | }
21 | );
22 | Textarea.displayName = "Textarea";
23 |
24 | export { Textarea };
25 |
--------------------------------------------------------------------------------
/components/ui/tooltip.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as TooltipPrimitive from "@radix-ui/react-tooltip"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const TooltipProvider = TooltipPrimitive.Provider
9 |
10 | const Tooltip = TooltipPrimitive.Root
11 |
12 | const TooltipTrigger = TooltipPrimitive.Trigger
13 |
14 | const TooltipContent = React.forwardRef<
15 | React.ElementRef,
16 | React.ComponentPropsWithoutRef
17 | >(({ className, sideOffset = 4, ...props }, ref) => (
18 |
27 | ))
28 | TooltipContent.displayName = TooltipPrimitive.Content.displayName
29 |
30 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
31 |
--------------------------------------------------------------------------------
/contentlayer.config.js:
--------------------------------------------------------------------------------
1 | import { defineDocumentType, makeSource } from "contentlayer2/source-files";
2 | import remarkGfm from "remark-gfm";
3 | import rehypePrettyCode from "rehype-pretty-code";
4 | import rehypeAutolinkHeadings from "rehype-autolink-headings";
5 | import rehypeSlug from "rehype-slug";
6 |
7 | const computedFields = {
8 | slug: {
9 | type: "string",
10 | resolve: (doc) => `/${doc._raw.flattenedPath}`,
11 | },
12 | slugAsParams: {
13 | type: "string",
14 | resolve: (doc) => doc._raw.flattenedPath.split("/").slice(1).join("/"),
15 | },
16 | folder: {
17 | type: "string",
18 | resolve: (doc) => {
19 | const pathParts = doc._raw.flattenedPath.split("/");
20 | return pathParts.length > 1 ? pathParts[pathParts.length - 2] : null;
21 | },
22 | },
23 | };
24 |
25 | const Blogs = defineDocumentType(() => ({
26 | name: "Blogs",
27 | filePathPattern: "./blogs/**/*.mdx",
28 | contentType: "mdx",
29 | fields: {
30 | title: {
31 | type: "string",
32 | required: true,
33 | },
34 | description: {
35 | type: "string",
36 | required: true,
37 | },
38 | image: {
39 | type: "string",
40 | required: true,
41 | },
42 | hidden: {
43 | type: "boolean",
44 | },
45 | },
46 | computedFields,
47 | }));
48 |
49 | const Works = defineDocumentType(() => ({
50 | name: "Works",
51 | filePathPattern: "./works/**/*.mdx",
52 | contentType: "mdx",
53 | fields: {
54 | title: {
55 | type: "string",
56 | required: true,
57 | },
58 | },
59 | computedFields,
60 | }));
61 |
62 | const TwitterContents = defineDocumentType(() => ({
63 | name: "TwitterContents",
64 | filePathPattern: "./twitter-contents/**/*.mdx",
65 | contentType: "mdx",
66 | fields: {
67 | title: {
68 | type: "string",
69 | required: true,
70 | },
71 | tech: {
72 | type: "string",
73 | required: true,
74 | },
75 | },
76 | computedFields,
77 | }));
78 |
79 | const buildFast = defineDocumentType(() => ({
80 | name: "buildFast",
81 | filePathPattern: "./build-fast/**/*.mdx",
82 | contentType: "mdx",
83 | fields: {
84 | title: {
85 | type: "string",
86 | required: true,
87 | },
88 | order: {
89 | type: "string",
90 | },
91 | },
92 | computedFields,
93 | }));
94 |
95 | export default makeSource({
96 | contentDirPath: "./contents",
97 | documentTypes: [Blogs, Works, TwitterContents, buildFast],
98 | mdx: {
99 | remarkPlugins: [remarkGfm],
100 | rehypePlugins: [
101 | rehypeSlug,
102 | [
103 | rehypePrettyCode,
104 | {
105 | theme: { light: "github-light-default", dark: "github-dark-dimmed" },
106 | keepBackground: false,
107 | },
108 | ],
109 | [
110 | rehypeAutolinkHeadings,
111 | {
112 | behavior: "wrap",
113 | content: (node) => node.children,
114 | properties: {
115 | className: ["subheading-anchor"],
116 | ariaLabel: "Link to section",
117 | },
118 | },
119 | ],
120 | ],
121 | },
122 | });
123 |
--------------------------------------------------------------------------------
/contents/blogs/making-website.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Making Website
3 | description: I see lots of developers start coding straightforwardly without having any designs or plans before coding it.
4 | image: /building-website.png
5 | ---
6 |
7 | # How do I make a Website?
8 |
9 | I see lots of developers start coding straightforwardly without having any designs or plans before coding it.
10 |
11 | If I don’t make any designs and don’t build a website step by step, I would get confused and I would not know what I’m doing, and easily it’ll overwhelm me.
12 |
13 | If I read this blog, I’ll know how to make a website step by step without getting any confusion.
14 |
15 | Let's build a website step by step.
16 |
17 | and the first step is...
18 |
19 | ## Think about the design
20 |
21 | If I want to start coding and I don’t know what I should make or design, I need to think beforehand about the design I want to make.
22 |
23 | I should put most of my time into thinking about designs, like:
24 |
25 | - What should Navbar look like?
26 | - What should Header look like?
27 | - What should Footer look like?
28 | - and …
29 |
30 | When I am done thinking, I should go and do…
31 |
32 | ## Design it
33 |
34 | That’s right, I should design it so that I know what I am doing and how my website is going to look.
35 |
36 | There are a few applications that I can use for designing, e.g.
37 |
38 | I am going to make my portfolio. let’s make it step by step.
39 |
40 | I will use Figma for designing it, and it looks like the image below:
41 |
42 | ## Thinking while designing
43 |
44 | When I am designing the website, I have to think about how to code it, and also I have to make the code in my mind and ask myself “Will I be able to do it or not?”
45 |
46 | If Yes, then I have to continue my designing, If not, then I have to change and design it in a way that I can code it.
47 |
48 | Ex: How should I think about code when designing it?
49 |
50 | > “There should be an h1 at the top, and there have to be 2 divs, and I have to use a grid-box in this situation, and inside the first div, there have to be 3 buttons and inside another div, there has to be an image, and other information related to what content is and …" - It is easy to code, let's continue my designing -
51 |
52 | ## Make everything ready
53 |
54 | Before jumping to code, I need to make all the files and folders ready for the project and download all the packages.
55 |
56 | Let’s make it clear:
57 |
58 | - Make all the files, folders, and assets
59 | - Download all the packages
60 | - Add fonts
61 | - Store the colors in the CSS file that I’ll use later
62 |
63 | ## Make a Repo (optional)
64 |
65 | I have to save my codes somewhere that I can access very easily.
66 |
67 | GitHub is the best place to do so.
68 |
69 | If you don’t know anything about GitHub, follow one of these tutorials:
70 |
71 | ## Make an issue (optional)
72 |
73 | Why should I make an issue?
74 |
75 | Issues are for collaboration and assign to someone…
76 |
77 | But I can do one for myself, and write all the tasks that I have to make them one by one.
78 |
79 | I can add task lists, and whenever I’m done with the task I’m going to check the mark so that I can go and continue making other sections.
80 |
81 | ## Start Coding
82 |
83 | Now, I can start making the website.
84 |
85 | ## Conclusion
86 |
87 | The benefits of following these steps:
88 |
89 | - I know what to do
90 | - I know how to make it
91 | - I know about colors
92 | - I know how to make it responsive
93 | - I know it won’t overwhelm me
94 | - And many more…
95 |
--------------------------------------------------------------------------------
/contents/blogs/my-experience.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: My Experience
3 | description: Since 2023, I’ve been working with my very first client on a complex and challenging project.
4 | image: /my-experience.png
5 | hidden: true
6 | ---
7 |
8 | Since 2023, I’ve been working with my very first client on a `complex` and `challenging` project. As the lead developer from the start, I was responsible for building the website and implementing several intricate features, including:
9 |
10 | - Trimming and cropping elements.
11 | - Managing stored data across the entire site.
12 | - Developing seamless animations between panels, which turned out fantastic.
13 | - Exporting edited videos, initially using FFmpeg before transitioning this task to the backend for improved performance.
14 | - Creating smooth page animations.
15 | - Ensuring responsive design on various pages.
16 |
17 | This project allowed me to tackle new challenges, expand my skill set, and deliver high-quality results.
18 |
19 | Throughout the project, I encountered several key challenges, including:
20 |
21 | - Animations not working properly in Safari.
22 | - Issues with exporting images in Safari.
23 | - Perfecting the trimming tool for better functionality.
24 | - Frequent "application errors" that occasionally broke the website.
25 | - Finding the best approach for storing and managing data efficiently.
26 | - Getting 8 frames of a video + Converting video url to blob url
27 | - Creating a pixel-perfect website: One of the Figma design values was 12.31131px, which I initially implemented. However, my client suggested rounding it off for a cleaner look.
28 |
29 | The project involved posting and scheduling content across various social media platforms, including Shorts, Stories, Photos, Long Videos, and Texts. My primary challenge was to establish an effective data flow for storing post details.
30 |
31 | I explored numerous approaches to reach our current solution. Initially, I attempted to use separate data structures for each post type, but I quickly found this method overwhelming and code-intensive. After several iterations, I discovered that a more efficient solution was to use a single data structure for the first four post types, while keeping a separate structure for text posts. This approach significantly streamlined the code and improved overall data management.
32 |
33 | I am grateful to be a member of this project, as it has provided me with numerous learning opportunities.
34 |
35 | I noticed that our backend team is using FastAPI, and I have experience working with APIs, including how to cache and utilize them effectively.
36 |
--------------------------------------------------------------------------------
/contents/build-fast/error-handling.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Error Handling
3 | ---
4 |
5 | # Error Handling
6 |
7 | First, we need a function to return the error message:
8 |
9 | ```tsx title="utils/index.tsx"
10 | export const getErrorMessage = (error: unknown): string => {
11 | let message: string;
12 |
13 | if (error instanceof Error) {
14 | message = error.message;
15 | } else if (error && typeof error === "object" && "message" in error) {
16 | message = String(error.message);
17 | } else if (typeof error === "string") {
18 | message = error;
19 | } else {
20 | message = "Something went wrong";
21 | }
22 |
23 | return message;
24 | };
25 | ```
26 |
27 | ```ts
28 | export interface ApiResponse {
29 | data: T;
30 | message: string;
31 | status: number;
32 | }
33 | ```
34 |
35 | Let's fetch something:
36 |
37 | ```tsx title="action.ts" showLineNumbers
38 | "use server";
39 |
40 | export const fetchCurrentUser = async (): Promise> => {
41 | try {
42 | const res = await fetch("...");
43 |
44 | const data = await res.json();
45 |
46 | if (!res.ok) {
47 | return {
48 | data: {},
49 | message: data.message || "Something went wrong",
50 | status: res.status,
51 | };
52 | }
53 |
54 | return {
55 | data,
56 | message: "SUCCESS",
57 | status: res.status,
58 | };
59 | } catch (error) {
60 | return {
61 | data: {},
62 | message: getErrorMessage(error),
63 | status: 500,
64 | };
65 | }
66 | };
67 | ```
68 |
--------------------------------------------------------------------------------
/contents/build-fast/links.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Links
3 | ---
4 |
5 | # Links
6 |
7 | - [Easing Graph](https://www.easing.dev/)
8 | - [Fancy Border Radius](https://9elements.github.io/fancy-border-radius/)
9 |
10 | ## Gooey Effect
11 |
12 | - [Gooey Effect Blog](https://css-tricks.com/gooey-effect/)
13 | - [Gooey Effect Demo](https://x.com/jh3yy/status/1816899351152844947)
14 | - [Gooey Effect Demo 2](https://x.com/jh3yy/status/1816907840973627776)
15 |
16 |
17 | ## Tricks
18 |
19 | - [Text Responds to Background Colors](https://x.com/JohnPhamous/status/1834345792494293453)
20 | - [Text Shadow on Scroll](https://x.com/samselikoff/status/1831847223287803985)
21 |
--------------------------------------------------------------------------------
/contents/build-fast/npm-packages.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: NPM Packages
3 | ---
4 |
5 | # NPM Packages
--------------------------------------------------------------------------------
/contents/build-fast/react-libraries/react-hotkeys-hook.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: React hotkeys hook
3 | ---
4 |
5 | # React hotkeys hook
6 |
7 | ```bash title="Terminal"
8 | pnpm i react-hotkeys-hook
9 | ```
10 |
11 | A React hook for using keyboard shortcuts in components in a declarative way.
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | ```tsx title="[name].tsx" showLineNumbers
24 | import React, { useState } from "react";
25 | import { useHotkeys } from "react-hotkeys-hook";
26 |
27 | export default function HotKeys() {
28 | const [copy, setCopy] = useState(false);
29 |
30 | useHotkeys("mod+c", () => setCopy(!copy));
31 |
32 | return (
33 |
34 |
35 | {copy ? "Copied" : "Copy"}
36 |
37 |
38 | ctrl + c
39 |
40 |
41 | );
42 | }
43 |
44 | ```
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/contents/build-fast/server.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Server
3 | ---
4 |
5 | # Server
6 |
7 | ```bash title="Terminal"
8 | pip3 install "fastapi[standard]"
9 | ```
10 |
11 | ### pnpm dev
12 |
13 | ```bash
14 | python3 -m fastapi dev main.py
15 | ```
16 |
17 | ### package.json
18 |
19 | ```bash
20 | pip3 freeze > requirements.txt
21 | ```
22 |
23 | ### Prettier
24 |
25 | ```bash
26 | pip3 install black
27 | python3 -m black main.py
28 | ```
29 |
30 | ## Types
31 |
32 | ```python title="main.py"
33 | from typing import Annotated, Set, Union, List, Dict
34 | from typing_extensions import Annotated
35 | from uuid import UUID
36 | from datetime import datetime, time, timedelta
37 |
38 | from fastapi import Query, Path, Body
39 | from pydantic import BaseModel, HttpUrl, Field
40 | ```
41 |
42 | > [Search](https://fastapi.tiangolo.com/python-types/) them if you don't know
43 |
44 |
45 | > **Good to know**
46 | > - If you want to add new things to the returned data by using the body data, make sure to use `.model_dump()`, otherwise a thing can't read it.
--------------------------------------------------------------------------------
/contents/build-fast/supbase.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Supabase
3 | ---
4 |
5 | # Supabase
6 |
7 | ## TypeScript
8 |
9 | ```bash
10 | supabase gen types typescript --project-id abcdefghijklmnopqrst > database.types.ts
11 | ```
12 |
13 | ## Realtime
14 |
15 | Try to fetch content in the server
16 |
17 | ```tsx title="FetchingContent.tsx" showLineNumbers
18 | import { createClient } from "@/utils/supabase/server";
19 | import RealtimePosts from "./Realtime";
20 |
21 | export default async function Notes() {
22 | const supabase = createClient();
23 | const { data: notes, error } = await supabase.from("countries").select();
24 |
25 | if (!notes || error) {
26 | return null;
27 | }
28 |
29 | return ;
30 | }
31 | ```
32 |
33 | > The reason that I am using @supabase/ssr is how it updated the data.
34 |
35 | and use another component for getting realtime data
36 |
37 | ```tsx title="Realtime.tsx" showLineNumbers
38 | "use client";
39 |
40 | import { Database } from "@/database.types";
41 | import supabase from "@/utils/supabase/client";
42 | import { useEffect, useState } from "react";
43 |
44 | export default function RealtimePosts({
45 | serverPosts,
46 | }: {
47 | serverPosts: Database["public"]["Tables"]["countries"]["Insert"][];
48 | }) {
49 | const [posts, setPosts] = useState(serverPosts);
50 |
51 | useEffect(() => {
52 | const channel = supabase
53 | .channel("countries")
54 | .on(
55 | "postgres_changes",
56 | { event: "*", schema: "public", table: "countries" },
57 | (payload) => {
58 | if (payload.eventType === "DELETE") {
59 | setPosts((posts) =>
60 | posts.filter((data) => data.id !== payload.old.id)
61 | );
62 | } else if (payload.eventType === "INSERT") {
63 | setPosts((posts) => [...posts, payload.new]);
64 | } else if (payload.eventType === "UPDATE") {
65 | setPosts((posts) =>
66 | posts.map((post) => {
67 | if (post.id === payload.old.id) {
68 | return { ...post, ...payload.new };
69 | } else {
70 | return post;
71 | }
72 | })
73 | );
74 | }
75 |
76 | console.log(payload);
77 | }
78 | )
79 | .subscribe();
80 |
81 | return () => {
82 | supabase.removeChannel(channel);
83 | };
84 | }, [serverPosts]);
85 |
86 | console.log(posts);
87 |
88 | return {JSON.stringify(posts, null, 2)} ;
89 | }
90 | ```
91 |
--------------------------------------------------------------------------------
/contents/build-fast/ui/useful-components.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Useful Components
3 | ---
4 |
5 | # Useful Components
6 |
7 | ## From Shadcn
8 |
9 | - [Alert Dialog](https://ui.shadcn.com/docs/components/alert-dialog)
10 | - [Aspect Ratio](https://ui.shadcn.com/docs/components/aspect-ratio)
11 | - [Avatar](https://ui.shadcn.com/docs/components/avatar)
12 | - [Badge](https://ui.shadcn.com/docs/components/badge)
13 | - [Button](https://ui.shadcn.com/docs/components/button)
14 | - [Card](https://ui.shadcn.com/docs/components/card)
15 | - [Carousel](https://ui.shadcn.com/docs/components/carousel) from [Embla Carousel](https://www.embla-carousel.com/get-started/)
16 | - [Chart](https://ui.shadcn.com/docs/components/chart)
17 | - [Checkbox](https://ui.shadcn.com/docs/components/checkbox)
18 | - [Dialog](https://ui.shadcn.com/docs/components/dialog)
19 | - [Drawer](https://ui.shadcn.com/docs/components/drawer)
20 | - [Dropdown Menu](https://ui.shadcn.com/docs/components/dropdown-menu)
21 | - [Form](https://ui.shadcn.com/docs/components/form)
22 | - [Input](https://ui.shadcn.com/docs/components/input)
23 | - [Label](https://ui.shadcn.com/docs/components/label)
24 | - [Popover](https://ui.shadcn.com/docs/components/popover)
25 | - [Select](https://ui.shadcn.com/docs/components/select)
26 | - [Separator](https://ui.shadcn.com/docs/components/separator)
27 | - [Sheet](https://ui.shadcn.com/docs/components/sheet)
28 | - [Skeleton](https://ui.shadcn.com/docs/components/skeleton)
29 | - [Slider](https://ui.shadcn.com/docs/components/slider)
30 | - [Switch](https://ui.shadcn.com/docs/components/switch)
31 | - [Toaster](https://ui.shadcn.com/docs/components/toaster)
32 | - [Tooltip](https://ui.shadcn.com/docs/components/tooltip)
33 | - [Resizable](https://ui.shadcn.com/docs/components/resizable)
34 |
35 | ## Icons
36 |
37 | - [React Icons](https://react-icons.github.io/react-icons/)
38 | - [Lucide Icons](https://lucide.dev/)
39 |
40 | ## Others
41 |
42 | - [Textarea Autosize](https://www.npmjs.com/package/react-textarea-autosize)
43 | - [React Query](https://tanstack.com/query/latest/docs/framework/react/overview)
44 | - [Framer Motion](https://www.framer.com/motion/)
45 | - [Lodash](https://lodash.com/)
46 | - [Fuse.js](https://www.fusejs.io/) - for searching through arrays
47 | - [Zustand](https://zustand-docs.vercel.app/) - for state management
48 | - [UUID](https://www.npmjs.com/package/uuid) - for generating unique identifiers
49 | - [Input OTP](https://www.npmjs.com/package/input-otp)
50 | - [React Hotkeys Hook](https://www.npmjs.com/package/react-hotkeys-hook) - for handling keyboard shortcuts - [Demo](/build-fast/react-libraries/react-hotkeys-hook)
51 | - [Copy to Clipboard](https://www.npmjs.com/package/copy-to-clipboard)
52 | - [React Live](https://www.npmjs.com/package/react-live/v/2.2.3)
53 |
--------------------------------------------------------------------------------
/contents/twitter-contents/1.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Mix Blend Mode"
3 | tech: "css"
4 | ---
5 |
6 |
7 |
--------------------------------------------------------------------------------
/contents/twitter-contents/10.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Pause and Restart Animation
3 | tech: "js"
4 | ---
5 |
6 |
7 |
8 |
9 |
10 | ```js title="app.js"
11 | const pauseButton = document.querySelector(".pause-button");
12 | const animationElement = document.querySelector(".animate-progress");
13 |
14 | pauseButton.addEventListener("click", () => {
15 | if (
16 | animationElement.style.animationPlayState === "running" ||
17 | animationElement.style.animationPlayState === ""
18 | ) {
19 | animationElement.style.animationPlayState = "paused";
20 | // ... existing code ...
21 | } else {
22 | animationElement.style.animationPlayState = "running";
23 | // ... existing code ...
24 | }
25 | });
26 | ```
27 |
28 |
29 |
30 |
31 |
32 | ```js title="app.js"
33 | const pauseButton = document.querySelector(".pause-button");
34 | const animationElement = document.querySelector(".animate-progress");
35 |
36 | restartButton.addEventListener("click", () => {
37 | animationElement.classList.remove("animate-progress");
38 |
39 | requestAnimationFrame(() => {
40 | animationElement.classList.add("animate-progress");
41 | });
42 | });
43 | ```
44 |
45 | > Make sure that the `.animate-progress` is the class that the animation exists.
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/contents/twitter-contents/11.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Stopwatch
3 | tech: "js"
4 | ---
5 |
6 |
7 |
8 |
9 |
10 | ```html
11 | 00:00.000
12 |
13 | Start
14 | Pause
15 |
16 | ```
17 |
18 |
19 |
20 |
21 |
22 | ```js showLineNumbers
23 | const startButton = document.getElementById("start");
24 | const pauseButton = document.getElementById("pause");
25 | const stopwatch = document.getElementById("stopwatch");
26 |
27 | let startTime;
28 | let animationFrameId;
29 | let isRunning = false;
30 |
31 | function updateStopwatch() {
32 | if (!startTime) {
33 | startTime = performance.now();
34 | }
35 |
36 | const currentTime = performance.now();
37 | const elapsedTime = currentTime - startTime;
38 |
39 | const minutes = Math.floor(elapsedTime / 60000);
40 | const seconds = Math.floor((elapsedTime % 60000) / 1000);
41 | const milliseconds = Math.floor(elapsedTime % 1000);
42 |
43 | stopwatch.textContent = `${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}.${milliseconds.toString().padStart(3, "0")}`;
44 |
45 | animationFrameId = requestAnimationFrame(updateStopwatch);
46 | }
47 |
48 | startButton.addEventListener("click", () => {
49 | if (isRunning) return;
50 |
51 | pauseButton.textContent = "Pause";
52 | if (!startTime) {
53 | startTime = performance.now();
54 | } else {
55 | startTime = performance.now() - (performance.now() - startTime);
56 | }
57 | isRunning = true;
58 | requestAnimationFrame(updateStopwatch);
59 | });
60 |
61 | pauseButton.addEventListener("click", () => {
62 | cancelAnimationFrame(animationFrameId);
63 | isRunning = false;
64 | });
65 | ```
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/contents/twitter-contents/12.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Input Number Format
3 | tech: "html"
4 | ---
5 |
6 | Make sure to use it in your phone.
7 |
8 | ```html title="index.html"
9 |
10 | ```
11 |
12 |
13 |
--------------------------------------------------------------------------------
/contents/twitter-contents/13.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Browser Popup
3 | tech: "js"
4 | ---
5 |
6 |
7 |
8 |
9 |
10 | ```html title="index.html"
11 | Alert
12 | ```
13 |
14 | ```js title="index.js"
15 | const button = document.querySelector("button");
16 |
17 | button.addEventListener("click", () => {
18 | window.alert("Hello! This is a popup message.");
19 | });
20 | ```
21 |
22 |
23 |
24 |
25 |
26 | ```html title="index.html"
27 | Confirm
28 | ```
29 |
30 | ```js title="index.js"
31 | const button = document.querySelector("button");
32 |
33 | button.addEventListener("click", () => {
34 | const result = window.confirm("Do you want to proceed?");
35 | if (result) {
36 | window.alert("You clicked OK!");
37 | } else {
38 | window.alert("You clicked Cancel!");
39 | }
40 | });
41 | ```
42 |
43 |
44 |
45 |
46 |
47 | ```html title="index.html"
48 | Prompt
49 | ```
50 |
51 | ```js title="index.js"
52 | const button = document.querySelector("button");
53 |
54 | button.addEventListener("click", () => {
55 | const name = window.prompt("What's your name?", "Ali Samadi");
56 | if (name) {
57 | window.alert(`Hello, ${name}!`);
58 | } else {
59 | window.alert("You cancelled the prompt!");
60 | }
61 | });
62 | ```
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/contents/twitter-contents/14.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Clock
3 | tech: "js"
4 | ---
5 |
6 | ```js showLineNumbers title="app.js"
7 | const h1 = document.querySelector("h1");
8 |
9 | function updateClock() {
10 | const time = new Date();
11 | h1.textContent = time.toLocaleTimeString();
12 | }
13 |
14 | setInterval(updateClock, 1000);
15 | ```
16 |
17 |
18 |
--------------------------------------------------------------------------------
/contents/twitter-contents/15.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Popover
3 | tech: HTML
4 | ---
5 |
6 | ```html showLineNumbers title="index.html"
7 | Popover
8 |
9 |
10 |
Popover content
11 |
12 | ```
13 |
14 |
15 |
--------------------------------------------------------------------------------
/contents/twitter-contents/16.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Custom Checkbox
3 | tech: HTML
4 | ---
5 |
6 |
7 |
8 |
9 |
10 | ```html showLineNumbers
11 |
12 | checkbox
13 |
14 |
15 |
16 | ```
17 |
18 |
19 |
20 |
21 |
22 | ```css showLineNumbers
23 | label {
24 | display: flex;
25 | align-items: center;
26 | gap: 8px;
27 | }
28 |
29 | label span {
30 | display: flex;
31 | align-items: center;
32 | width: 46px;
33 | height: 28px;
34 | border-radius: 14px;
35 | background-color: rgba(120, 120, 128, 0.16);
36 | transition: 0.2s;
37 | }
38 |
39 | label span::before {
40 | content: "";
41 | display: inline-block;
42 | width: 21px;
43 | height: 21px;
44 | background-color: rgb(120, 120, 128);
45 | border-radius: 10px;
46 | transition: 0.2s;
47 | transform: translateX(4px);
48 | }
49 |
50 | label input[type="checkbox"] {
51 | display: none;
52 | }
53 |
54 | label input[type="checkbox"]:checked + span {
55 | background-color: #007bff;
56 | }
57 |
58 | label input[type="checkbox"]:checked + span::before {
59 | transform: translateX(21px);
60 | background-color: #fff;
61 | }
62 | ```
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/contents/twitter-contents/17.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Custom Cursor
3 | tech: CSS
4 | ---
5 |
6 |
7 |
8 |
9 |
10 | ```html showLineNumbers
11 | Hover me
12 | ```
13 |
14 |
15 |
16 |
17 |
18 | ```css showLineNumbers
19 | div {
20 | cursor: url('data:image/svg+xml, '),
21 | pointer;
22 | }
23 | /* You can include image as a cursor. */
24 | /* div {
25 | cursor: url('image.png'), pointer;
26 | } */
27 | ```
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/contents/twitter-contents/18.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Text Gradient
3 | tech: CSS
4 | ---
5 |
6 |
7 |
--------------------------------------------------------------------------------
/contents/twitter-contents/19.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Scrollbar Customization
3 | tech: CSS
4 | ---
5 |
6 | ```css title="style.css"
7 | .scrollbar-1::-webkit-scrollbar {
8 | width: 8px;
9 | background-color: #f5f5f5;
10 | }
11 | .scrollbar-1::-webkit-scrollbar-thumb {
12 | background: linear-gradient(45deg, #ff6b6b, #ffd93d);
13 | border-radius: 4px;
14 | border: 2px solid #f5f5f5;
15 | }
16 | .scrollbar-1::-webkit-scrollbar-track {
17 | background-color: #e2e2e2;
18 | border-radius: 4px;
19 | }
20 |
21 | /* 2 */
22 | .scrollbar-2::-webkit-scrollbar {
23 | width: 8px;
24 | background-color: #f5f5f5;
25 | }
26 | .scrollbar-2::-webkit-scrollbar-thumb {
27 | background: #4a90e2;
28 | border-radius: 10px;
29 | }
30 | .scrollbar-2::-webkit-scrollbar-track {
31 | background-color: #e2e2e2;
32 | border-radius: 10px;
33 | }
34 |
35 | /* 3 */
36 | .scrollbar-3::-webkit-scrollbar {
37 | width: 8px;
38 | background-color: #f5f5f5;
39 | }
40 | .scrollbar-3::-webkit-scrollbar-thumb {
41 | background: #50c878;
42 | border: 2px solid #f5f5f5;
43 | }
44 | .scrollbar-3::-webkit-scrollbar-track {
45 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
46 | }
47 |
48 | /* 4 */
49 | .scrollbar-4::-webkit-scrollbar {
50 | width: 8px;
51 | background-color: transparent;
52 | }
53 | .scrollbar-4::-webkit-scrollbar-thumb {
54 | background: #9b59b6;
55 | border-radius: 20px;
56 | }
57 | .scrollbar-4::-webkit-scrollbar-track {
58 | background-color: transparent;
59 | }
60 |
61 | /* 5 */
62 | .scrollbar-5::-webkit-scrollbar {
63 | width: 8px;
64 | background-color: #f5f5f5;
65 | }
66 | .scrollbar-5::-webkit-scrollbar-thumb {
67 | background: #e74c3c;
68 | border-radius: 4px;
69 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5);
70 | }
71 | .scrollbar-5::-webkit-scrollbar-track {
72 | background-color: #e2e2e2;
73 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.2);
74 | }
75 |
76 | /* 6 */
77 | .scrollbar-6::-webkit-scrollbar {
78 | width: 8px;
79 | background-color: #f5f5f5;
80 | }
81 | .scrollbar-6::-webkit-scrollbar-thumb {
82 | background: linear-gradient(45deg, #f1c40f, #e67e22, #e74c3c);
83 | border-radius: 8px;
84 | }
85 | .scrollbar-6::-webkit-scrollbar-track {
86 | background: linear-gradient(45deg, #ecf0f1, #bdc3c7);
87 | border-radius: 8px;
88 | }
89 | ```
90 |
91 |
92 |
--------------------------------------------------------------------------------
/contents/twitter-contents/2.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Border"
3 | tech: "css"
4 | ---
5 |
6 |
7 |
--------------------------------------------------------------------------------
/contents/twitter-contents/20.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Text Revealing Animation
3 | tech: CSS
4 | ---
5 |
6 |
7 |
8 |
9 |
10 | ```html
11 | Text Revealing Animation
12 | ```
13 |
14 |
15 |
16 |
17 |
18 | ```css
19 | .animate-text {
20 | opacity: 0;
21 | animation: reveal 0.5s var(--i) ease-in-out forwards;
22 | }
23 |
24 | @keyframes reveal {
25 | to {
26 | opacity: 1;
27 | }
28 | }
29 | ```
30 |
31 |
32 |
33 |
34 |
35 | ```js
36 | const text = document.querySelector("h1");
37 |
38 | text.innerHTML = text.textContent.replace(
39 | /\S/g,
40 | (char, index) =>
41 | `${char} `
42 | );
43 | ```
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/contents/twitter-contents/21.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Fixed Background
3 | tech: CSS
4 | ---
5 |
6 | ```css title="style.css"
7 | div {
8 | background-image: url(...);
9 | background-attachment: fixed;
10 | }
11 | ```
12 |
13 |
14 |
--------------------------------------------------------------------------------
/contents/twitter-contents/22.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Image Animation
3 | tech: CSS
4 | ---
5 |
6 | ```css title="style.css"
7 | .custom-image-animate {
8 | animation: element-in 0.5s ease-out forwards;
9 | }
10 |
11 | @keyframes element-in {
12 | from {
13 | opacity: 0;
14 | transform: translateY(40px) perspective(1000px) rotateX(-25deg);
15 | filter: blur(4px);
16 | }
17 | to {
18 | opacity: 1;
19 | transform: translateY(0) perspective(1000px) rotateX(0);
20 | filter: blur(0px);
21 | }
22 | }
23 | ```
24 |
25 |
26 |
--------------------------------------------------------------------------------
/contents/twitter-contents/23.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Align Icon with Text
3 | tech: CSS
4 | ---
5 |
6 | ```html title="index.html"
7 |
11 | ```
12 |
13 | ```css title="style.css"
14 | .icon {
15 | height: 1cap;
16 | width: 1cap;
17 | }
18 | ```
19 |
20 |
21 |
22 | This implementation was inspired by [this informative post](https://www.instagram.com/p/C8pM3oEyxPf/?img_index=1).
23 |
--------------------------------------------------------------------------------
/contents/twitter-contents/24.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: CSS Caret
3 | tech: CSS
4 | ---
5 |
6 | ```css title="style.css"
7 | input {
8 | caret-color: ;
9 | }
10 | ```
11 |
12 |
13 |
--------------------------------------------------------------------------------
/contents/twitter-contents/25.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: CSS Transition Easing
3 | tech: CSS
4 | ---
5 |
6 | ```css title="style.css"
7 | div {
8 | transition-timing-function: ;
9 | /*
10 | ease-in-out
11 | ease-in
12 | ease-out
13 | cubic-bezier(n, n, n, n)
14 | */
15 | }
16 | ```
17 |
18 |
19 |
--------------------------------------------------------------------------------
/contents/twitter-contents/3.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "::selection"
3 | tech: "css"
4 | ---
5 |
6 |
7 |
--------------------------------------------------------------------------------
/contents/twitter-contents/4.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Position"
3 | tech: "css"
4 | ---
5 |
6 |
7 |
--------------------------------------------------------------------------------
/contents/twitter-contents/5.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Dropdown HTML
3 | tech: "html"
4 | ---
5 |
6 |
7 |
8 | ### We can design it
9 |
10 | Tailwind CSS
11 |
12 |
13 |
14 |
15 |
16 | ```html showLineNumbers title="index.html"
17 |
18 |
21 | System Requirements
22 |
23 |
26 | Requires a computer running an operating system. The computer must have some
27 | memory and ideally some kind of long-term storage. An input device as well
28 | as some form of output device is recommended.
29 |
30 |
31 | ```
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | ```html showLineNumbers title="index.html"
40 |
41 |
44 | System Requirements
45 |
46 |
49 | Requires a computer running an operating system. The computer must have some
50 | memory and ideally some kind of long-term storage. An input device as well
51 | as some form of output device is recommended.
52 |
53 |
54 | ```
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/contents/twitter-contents/6.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: HTML Elements
3 | tech: "html"
4 | ---
5 |
6 | ### Block Elements
7 |
8 |
9 |
10 | ### Inline Elements
11 |
12 |
13 |
--------------------------------------------------------------------------------
/contents/twitter-contents/7.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: CSS Variables
3 | tech: "css"
4 | ---
5 |
6 |
7 |
--------------------------------------------------------------------------------
/contents/twitter-contents/8.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Proper Rounded Corners
3 | tech: "css"
4 | ---
5 |
6 |
7 |
--------------------------------------------------------------------------------
/contents/twitter-contents/9.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Password Validation
3 | tech: "js"
4 | ---
5 |
6 | ```js title="app.js"
7 | input.length >= 8;
8 | /[A-Z]/.test(input);
9 | /[a-z]/.test(input);
10 | /[0-9]/.test(input);
11 | /[!@#$%^&*]/.test(input);
12 | ```
13 |
14 |
15 |
--------------------------------------------------------------------------------
/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { clsx, type ClassValue } from "clsx";
2 | import { twMerge } from "tailwind-merge";
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs));
6 | }
7 |
8 | export const showcaseImage =
9 | "https://images.unsplash.com/photo-1515266591878-f93e32bc5937?q=80&w=2592&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D";
10 | export const showcaseImage2 =
11 | "https://images.unsplash.com/photo-1612714154350-80450de823e8?q=80&w=1829&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D";
12 |
13 | export const files = {
14 | image: {
15 | 1: "https://utfs.io/f/bTa5OaPXXZ6rlQlFl7aFatPcj5SGOUmnvzAsZWHDNKkbMqX9",
16 | 2: "https://utfs.io/f/bTa5OaPXXZ6reklU4xdQorh5JmOQZ92LR6AFwHXy3liYjGPs",
17 | 3: "https://utfs.io/f/bTa5OaPXXZ6rGHhDRAkNzR7Ye9xSJuaHPndtoDX0Q8TBlU3c",
18 | 4: "https://utfs.io/f/bTa5OaPXXZ6re3beIAQorh5JmOQZ92LR6AFwHXy3liYjGPsv",
19 | 5: "https://utfs.io/f/bTa5OaPXXZ6rrZwHUmhT7jwHVkB4xt6K9bNOfucCGZendEqS",
20 | 6: "https://utfs.io/f/bTa5OaPXXZ6rzBgvg9S0TjQSmocqUltP7HB2GOVC3vW8xLEr",
21 | // 16/9
22 | 7: "https://utfs.io/f/bTa5OaPXXZ6rP4xIwGO50MtkbV1F73hdQ4gqxsDOuywYeUA8",
23 | gladiator:
24 | "https://utfs.io/f/bTa5OaPXXZ6rdD0EDo7iwGBIholDNRf1yT62APcsvrUKML8S",
25 | },
26 | video: {
27 | 1: "https://utfs.io/f/bTa5OaPXXZ6rXyXvdMAcqyLVgEBIzP6St18lu72QJabsMUxG",
28 | },
29 | poster: {
30 | 1: "https://utfs.io/f/bTa5OaPXXZ6ruCmJRNrWLOa5DSFB2dW6KsUVlkNQpozXA19n",
31 | },
32 | };
33 |
--------------------------------------------------------------------------------
/middleware.tsx:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 | import type { NextRequest } from "next/server";
3 |
4 | export function middleware(request: NextRequest) {
5 | const { pathname } = request.nextUrl;
6 |
7 | console.log({ pathname });
8 |
9 | if (pathname.includes("twitter-content")) {
10 | const newPath = pathname.replace("twitter-content", "x-content");
11 | return NextResponse.redirect(new URL(newPath, request.url));
12 | }
13 |
14 | return NextResponse.next();
15 | }
16 |
17 | export const config = {
18 | matcher: "/((?!api|_next/static|_next/image|favicon.ico).*)",
19 | };
20 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 |
3 | const { withContentlayer } = require("next-contentlayer2");
4 |
5 | const nextConfig = {
6 | images: {
7 | remotePatterns: [
8 | {
9 | protocol: "https",
10 | hostname: "*",
11 | },
12 | ],
13 | },
14 | };
15 |
16 | module.exports = withContentlayer(nextConfig);
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "my-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint",
10 | "check-types": "tsc --pretty --noEmit",
11 | "build:registry": "node ./scripts/build-registry.js && prettier --write ./__registry__/index.tsx"
12 | },
13 | "dependencies": {
14 | "@mantine/hooks": "^7.13.1",
15 | "@number-flow/react": "^0.3.0",
16 | "@radix-ui/react-dialog": "^1.1.1",
17 | "@radix-ui/react-label": "^2.1.0",
18 | "@radix-ui/react-select": "^2.1.1",
19 | "@radix-ui/react-separator": "^1.1.0",
20 | "@radix-ui/react-slider": "^1.2.0",
21 | "@radix-ui/react-slot": "^1.1.0",
22 | "@radix-ui/react-tooltip": "^1.1.4",
23 | "@react-pdf/renderer": "^4.0.0",
24 | "@resvg/resvg-wasm": "^2.6.2",
25 | "class-variance-authority": "^0.7.0",
26 | "clsx": "^2.1.1",
27 | "contentlayer2": "^0.5.1",
28 | "framer-motion": "^11.8.0",
29 | "i": "^0.3.7",
30 | "input-otp": "^1.2.4",
31 | "lucide-react": "^0.446.0",
32 | "next": "14.2.13",
33 | "next-contentlayer2": "^0.5.1",
34 | "next-themes": "^0.3.0",
35 | "pnpm": "^9.11.0",
36 | "prettier": "^3.3.3",
37 | "prettier-plugin-tailwindcss": "^0.6.8",
38 | "rc-progress": "^4.0.0",
39 | "react": "^18",
40 | "react-dom": "^18",
41 | "react-hotkeys-hook": "^4.5.1",
42 | "react-syntax-highlighter": "^15.5.0",
43 | "react-use": "^17.5.1",
44 | "react-use-measure": "^2.1.1",
45 | "rehype-autolink-headings": "^7.1.0",
46 | "rehype-pretty-code": "^0.14.0",
47 | "rehype-slug": "^6.0.0",
48 | "remark-gfm": "^4.0.0",
49 | "resend": "^4.0.0",
50 | "satori": "^0.11.2",
51 | "sonner": "^1.5.0",
52 | "tailwind-merge": "^2.5.2",
53 | "tailwindcss-animate": "^1.0.7",
54 | "uuid": "^10.0.0",
55 | "vaul": "^1.0.0",
56 | "zustand": "5.0.0-rc.2"
57 | },
58 | "devDependencies": {
59 | "@types/node": "^20",
60 | "@types/react": "^18",
61 | "@types/react-dom": "^18",
62 | "@types/react-syntax-highlighter": "^15.5.13",
63 | "@types/uuid": "^10.0.0",
64 | "eslint": "^8",
65 | "eslint-config-next": "14.2.13",
66 | "postcss": "^8",
67 | "tailwindcss": "^3.4.1",
68 | "typescript": "^5"
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/preview/build-fast/hotKeys.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { useHotkeys } from "react-hotkeys-hook";
3 |
4 | export default function HotKeys() {
5 | const [copy, setCopy] = useState(false);
6 |
7 | useHotkeys("mod+c", () => setCopy(!copy));
8 |
9 | return (
10 |
11 |
12 | {copy ? "Copied" : "Copy"}
13 |
14 |
15 | ctrl + c
16 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/preview/build-fast/input-otp.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { OTPInput, SlotProps } from "input-otp";
3 |
4 | import { cn } from "@/lib/utils";
5 |
6 | export default function InputOtp() {
7 | const [isCompleted, setIsCompleted] = useState(false);
8 |
9 | const onCompleteHandler = (value: number) => {
10 | setIsCompleted(true);
11 |
12 | console.log(value);
13 | };
14 |
15 | return (
16 |
17 |
(
23 | <>
24 |
25 | {slots.slice(0, 3).map((slot, idx) => (
26 |
27 | ))}
28 |
29 |
30 |
31 |
32 |
33 | {slots.slice(3).map((slot, idx) => (
34 |
35 | ))}
36 |
37 | >
38 | )}
39 | />
40 |
41 | {isCompleted && "Processing"}
42 |
43 | );
44 | }
45 |
46 | function Slot(props: SlotProps) {
47 | return (
48 |
58 | {props.char !== null &&
{props.char}
}
59 | {props.hasFakeCaret &&
}
60 |
61 | );
62 | }
63 |
64 | function FakeCaret() {
65 | return (
66 |
69 | );
70 | }
71 |
72 | function FakeDash() {
73 | return (
74 |
77 | );
78 | }
79 |
--------------------------------------------------------------------------------
/preview/build-fast/react-pdf.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {
3 | PDFDownloadLink,
4 | Document,
5 | Page,
6 | Text,
7 | View,
8 | StyleSheet,
9 | Font,
10 | } from "@react-pdf/renderer";
11 |
12 | import { Button } from "@/components/ui/button";
13 |
14 | Font.register({
15 | family: "Open Sans",
16 | fonts: [
17 | {
18 | src: "https://cdn.jsdelivr.net/npm/open-sans-all@0.1.3/fonts/open-sans-regular.ttf",
19 | },
20 | {
21 | src: "https://cdn.jsdelivr.net/npm/open-sans-all@0.1.3/fonts/open-sans-600.ttf",
22 | fontWeight: 600,
23 | },
24 | ],
25 | });
26 |
27 | // Define the styles
28 | const styles = StyleSheet.create({
29 | page: {
30 | fontFamily: "Open Sans",
31 | padding: "30",
32 | backgroundColor: "#635BFF",
33 | color: "white",
34 | display: "flex",
35 | justifyContent: "center",
36 | alignItems: "center",
37 | },
38 | businessName: {
39 | width: 300,
40 | marginBottom: 20,
41 | fontSize: 12,
42 | },
43 | section: {
44 | backgroundColor: "white",
45 | color: "#7A7A7B",
46 | width: 300,
47 | borderRadius: 8,
48 | padding: 16,
49 | marginBottom: 16,
50 | },
51 | flexRow: {
52 | flexDirection: "row",
53 | justifyContent: "space-between",
54 | alignItems: "center",
55 | gap: 8,
56 | },
57 | wrapperText: {
58 | display: "flex",
59 | flexDirection: "column",
60 | gap: 2,
61 | borderBottom: "1px solid #E8E9EC",
62 | flexGrow: 1,
63 | paddingBottom: 16,
64 | },
65 | mutedText: {
66 | fontSize: 12,
67 | },
68 | price: {
69 | fontSize: 26,
70 | color: "black",
71 | fontWeight: "semibold",
72 | letterSpacing: -0.2,
73 | },
74 | bottomInfo: {
75 | gap: 4,
76 | marginTop: 16,
77 | },
78 | value: {
79 | fontSize: 12,
80 | color: "black",
81 | },
82 | });
83 |
84 | // Invoice Document Component
85 | const InvoiceDocument = () => (
86 |
87 |
88 | Stripe Shop
89 |
90 |
91 |
92 | Receipt from X
93 | $8.00
94 | Paid July 17, 2024
95 |
96 |
97 |
98 |
99 |
100 | Receipt number
101 | 2093 2391 1280
102 |
103 |
104 | Invoice number
105 | E12E963E-0002
106 |
107 |
108 | Payment methode
109 | Visa 1607
110 |
111 |
112 |
113 |
114 | Receipt #1232-3412-1313
115 |
116 |
117 |
118 | );
119 |
120 | export default function ReactPDF() {
121 | return (
122 |
123 |
} fileName="invoice.pdf">
124 |
Generate Invoice
125 |
126 |
127 | );
128 | }
129 |
--------------------------------------------------------------------------------
/preview/build-fast/use-click-outside.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { useClickOutside } from "@mantine/hooks";
3 |
4 | import { Button } from "@/components/ui/button";
5 |
6 | export default function UseClickOutside() {
7 | const [isOpen, setIsOpen] = useState(false);
8 |
9 | const ref = useClickOutside(() => setIsOpen(false));
10 |
11 | return (
12 |
13 |
setIsOpen(true)}>Open
14 |
15 | {isOpen && (
16 |
17 |
Lorem Ipsum
18 |
19 | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Nihil
20 | incidunt sequi suscipit placeat dolorum doloribus inventore minima
21 | excepturi dolore sit error quasi, tenetur autem harum impedit.
22 |
23 |
24 | )}
25 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/preview/build-fast/use-debounced-state.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useDebouncedState } from "@mantine/hooks";
3 |
4 | export default function UseDebouncedState() {
5 | const [value, setValue] = useDebouncedState("", 200);
6 |
7 | return (
8 |
9 |
setValue(event.currentTarget.value)}
14 | />
15 |
16 |
Debounced value: {value}
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/preview/build-fast/use-fullscreen.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useFullscreen } from "@mantine/hooks";
3 |
4 | import { Button } from "@/components/ui/button";
5 |
6 | export default function UseFullscreen() {
7 | const { toggle, fullscreen } = useFullscreen();
8 |
9 | return (
10 |
11 | {fullscreen ? "Exit" : "Enter"} Fullscreen
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/preview/build-fast/use-media-query.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useMediaQuery } from "@mantine/hooks";
3 |
4 | import { Button } from "@/components/ui/button";
5 |
6 | export default function UseMediaQuery() {
7 | const matches = useMediaQuery("(min-width: 768px)");
8 |
9 | return (
10 | Use Media Query
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/preview/build-fast/uuid.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { v4 as uuidv4 } from "uuid";
3 |
4 | export default function UUID() {
5 | const [uuid, setUuid] = useState(null);
6 |
7 | const onClickHandler = () => {
8 | setUuid(uuidv4());
9 | };
10 |
11 | return (
12 |
13 |
17 | Generate UUID
18 |
19 | {uuid &&
{uuid}
}
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/preview/twitter-contents/1.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import React, { useState } from "react";
4 |
5 | import SyntaxHighlighter from "@/components/SyntaxHighlighter";
6 | import * as Element from "@/components/TwitterContentsElement";
7 | import Image from "next/image";
8 | import { showcaseImage, showcaseImage2 } from "@/lib/utils";
9 | import { Button } from "@/components/ui/button";
10 |
11 | type MixBlendMode =
12 | | "normal"
13 | | "multiply"
14 | | "screen"
15 | | "overlay"
16 | | "darken"
17 | | "lighten"
18 | | "color-dodge"
19 | | "color-burn"
20 | | "hard-light"
21 | | "soft-light"
22 | | "difference"
23 | | "exclusion"
24 | | "hue"
25 | | "saturation"
26 | | "color"
27 | | "luminosity";
28 |
29 | const mixBlends: MixBlendMode[] = [
30 | "normal",
31 | "multiply",
32 | "screen",
33 | "overlay",
34 | "darken",
35 | "lighten",
36 | "color-dodge",
37 | "color-burn",
38 | "hard-light",
39 | "soft-light",
40 | "difference",
41 | "exclusion",
42 | "hue",
43 | "saturation",
44 | "color",
45 | "luminosity",
46 | ];
47 |
48 | export default function TwitterContents1() {
49 | const [mixBlend, setMixBlend] = useState("normal");
50 |
51 | const codeString = `div {
52 | mix-blend-mode: ${mixBlend};
53 | -webkit-mix-blend-mode: ${mixBlend};
54 | }`;
55 |
56 | return (
57 |
58 |
59 | {codeString}
60 |
61 |
62 |
63 |
69 |
70 |
74 | Text Mix Blend
75 |
76 |
77 |
78 |
79 |
85 |
86 |
90 |
96 |
97 |
98 |
99 | {mixBlends.map((value) => (
100 | setMixBlend(value)}
105 | >
106 | {value}
107 |
108 | ))}
109 |
110 |
111 | );
112 | }
113 |
--------------------------------------------------------------------------------
/preview/twitter-contents/10.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 |
3 | import { toast } from "sonner";
4 |
5 | import * as Element from "@/components/TwitterContentsElement";
6 | import { Button } from "@/components/ui/button";
7 |
8 | export default function TwitterContents10() {
9 | const [isPaused, setIsPaused] = useState(false);
10 | const [isEnded, setIsEnded] = useState(false);
11 | const [key, setKey] = useState(0);
12 |
13 | return (
14 |
15 |
16 |
17 |
setIsEnded(true)}
22 | >
23 |
24 |
25 |
26 | {
29 | if (isEnded) {
30 | toast("Animation is ended.");
31 | } else {
32 | setIsPaused(!isPaused);
33 | }
34 | }}
35 | >
36 | {isPaused ? "Resume" : "Pause"}
37 |
38 | {
41 | setKey((prevKey) => prevKey + 1);
42 | setIsPaused(false);
43 | setIsEnded(false);
44 | }}
45 | >
46 | Restart
47 |
48 |
49 |
50 |
51 | );
52 | }
53 |
--------------------------------------------------------------------------------
/preview/twitter-contents/11.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 | import { Button } from "@/components/ui/button";
5 |
6 | export default function TwitterContents11() {
7 | const [timer, setTimer] = useState(0);
8 |
9 | const [running, setRunning] = useState(false);
10 |
11 | const handleStart = () => {
12 | setRunning(true);
13 | };
14 |
15 | useEffect(() => {
16 | let startTime: number;
17 | let animationFrameId: number;
18 |
19 | if (running) {
20 | startTime = Date.now() - timer;
21 |
22 | const updateTimer = () => {
23 | setTimer(Date.now() - startTime);
24 | animationFrameId = requestAnimationFrame(updateTimer);
25 | };
26 |
27 | animationFrameId = requestAnimationFrame(updateTimer);
28 |
29 | return () => {
30 | cancelAnimationFrame(animationFrameId);
31 | };
32 | }
33 | }, [running, timer]);
34 |
35 | return (
36 |
37 |
38 |
39 | {`${Math.floor(timer / 60000)
40 | .toString()
41 | .padStart(
42 | 2,
43 | "0"
44 | )}:${((timer % 60000) / 1000).toFixed(3).padStart(6, "0")}`}
45 |
46 |
47 |
48 | Start
49 |
50 | setRunning(!running)}
52 | variant="outline"
53 | disabled={!running}
54 | >
55 | Pause
56 |
57 |
58 |
59 |
60 | );
61 | }
62 |
--------------------------------------------------------------------------------
/preview/twitter-contents/12.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 |
5 | import { Input } from "@/components/ui/input";
6 |
7 | export default function TwitterContents12() {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/preview/twitter-contents/13.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 | import { Button } from "@/components/ui/button";
5 |
6 | export default function TwitterContents13() {
7 | const handleAlert = () => {
8 | window.alert("Hello! This is a popup message.");
9 | };
10 |
11 | const handleConfirm = () => {
12 | const result = window.confirm("Do you want to proceed?");
13 | if (result) {
14 | window.alert("You clicked OK!");
15 | } else {
16 | window.alert("You clicked Cancel!");
17 | }
18 | };
19 |
20 | const handlePrompt = () => {
21 | const name = window.prompt("What's your name?", "Ali Samadi");
22 | if (name) {
23 | window.alert(`Hello, ${name}!`);
24 | } else {
25 | window.alert("You cancelled the prompt!");
26 | }
27 | };
28 |
29 | return (
30 |
31 |
32 | Alert
33 | Confirm
34 | Prompt
35 |
36 |
37 | );
38 | }
39 |
--------------------------------------------------------------------------------
/preview/twitter-contents/14.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 |
5 | export default function TwitterContents14() {
6 | const [time, setTime] = useState(new Date());
7 |
8 | useEffect(() => {
9 | const timer = setInterval(() => {
10 | setTime(new Date());
11 | }, 1000);
12 |
13 | return () => clearInterval(timer);
14 | }, []);
15 |
16 | return (
17 |
18 |
19 | {time.toLocaleTimeString()}
20 |
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/preview/twitter-contents/15.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import * as Element from "@/components/TwitterContentsElement";
3 | import { Button } from "@/components/ui/button";
4 |
5 | import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
6 |
7 | export default function TwitterContent15() {
8 | return (
9 |
10 |
11 |
12 |
13 | Popover
14 |
15 |
16 | Popover content
17 |
18 |
19 |
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/preview/twitter-contents/16.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import * as Element from "@/components/TwitterContentsElement";
3 |
4 | export default function TwitterContent16() {
5 | return (
6 |
7 |
8 |
9 | checkbox
10 |
11 |
12 |
13 |
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/preview/twitter-contents/17.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import * as Element from "@/components/TwitterContentsElement";
3 |
4 | type Props = {};
5 |
6 | export default function TwitterContent17({}: Props) {
7 | return (
8 |
9 |
10 | '), pointer`,
14 | }}
15 | >
16 | Hover me
17 |
18 |
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/preview/twitter-contents/18.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 | import SyntaxHighlighter from "@/components/SyntaxHighlighter";
5 | import { Slider } from "@/components/ui/slider";
6 | import { cn } from "@/lib/utils";
7 |
8 | type Props = {};
9 |
10 | export default function TwitterContent18({}: Props) {
11 | const [angle, setAngle] = useState(0);
12 |
13 | const codeString = `h1 {
14 | ${angle >= 1 ? "background: linear-gradient(to right, red, orange);" : ""}
15 | ${angle >= 2 ? "-webkit-background-clip: text;" : ""}
16 | ${angle >= 3 ? "-webkit-text-fill-color: transparent;" : ""}
17 | }`;
18 |
19 | return (
20 |
21 |
22 | {codeString}
23 |
24 |
25 |
26 |
setAngle(angle)}
32 | />
33 |
34 | Use this for understanding how each property works
35 |
36 |
37 | = 1 && "gradient-bg",
41 | angle >= 2 && "gradient-clip",
42 | angle >= 3 && "gradient-fill"
43 | )}
44 | >
45 | TEXT GRADIENT
46 |
47 |
48 |
49 | );
50 | }
51 |
--------------------------------------------------------------------------------
/preview/twitter-contents/19.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 |
5 | export default function TwitterContents19() {
6 | return (
7 |
8 |
9 |
12 |
15 |
18 |
21 |
24 |
27 |
28 |
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/preview/twitter-contents/2.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 | import SyntaxHighlighter from "@/components/SyntaxHighlighter";
5 | import { Slider } from "@/components/ui/slider";
6 | import {
7 | Select,
8 | SelectContent,
9 | SelectItem,
10 | SelectTrigger,
11 | SelectValue,
12 | } from "@/components/ui/select";
13 | import ColorPicker from "@/components/ColorPicker";
14 |
15 | export default function TwitterContents2() {
16 | const [border, setBorder] = useState({
17 | width: 4,
18 | color: "#ff0000",
19 | type: "solid",
20 | });
21 |
22 | const codeString = `div {
23 | border: ${border.width}px ${border.type} ${border.color};
24 | }`;
25 |
26 | return (
27 |
28 |
29 | {codeString}
30 |
31 |
32 |
38 |
44 |
45 |
46 |
47 | Width
48 | setBorder({ ...border, width: value[0] })}
54 | className="max-w-sm"
55 | />
56 |
57 | setBorder({ ...border, type: value })}
60 | >
61 |
62 |
63 |
64 |
65 | Solid
66 | Dashed
67 | Dotted
68 | Double
69 | Groove
70 | Ridge
71 | Inset
72 | Outset
73 | None
74 | Hidden
75 |
76 |
77 | setBorder({ ...border, color: value })}
80 | />
81 |
82 |
83 | );
84 | }
85 |
--------------------------------------------------------------------------------
/preview/twitter-contents/20.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import * as Element from "@/components/TwitterContentsElement";
3 | import { motion } from "framer-motion";
4 |
5 | export default function TwitterContent20() {
6 | const text = "Text Revealing Animation";
7 |
8 | return (
9 |
10 |
11 |
12 | {text.split("").map((char, index) => (
13 |
18 | {char}
19 |
20 | ))}
21 |
22 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/preview/twitter-contents/21.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import * as Element from "@/components/TwitterContentsElement";
3 | import { files } from "@/lib/utils";
4 |
5 | export default function TwitterContent21() {
6 | return (
7 |
8 |
9 |
10 |
19 |
Fixed Background
20 |
21 | The background image stays fixed while the content scrolls, creating
22 | a parallax-like effect.
23 |
24 |
25 |
26 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
27 | eiusmod tempor incididunt ut labore et dolore magna aliqua.
28 |
29 |
30 | Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
31 | nisi ut aliquip ex ea commodo consequat.
32 |
33 |
34 | Duis aute irure dolor in reprehenderit in voluptate velit esse
35 | cillum dolore eu fugiat nulla pariatur.
36 |
37 |
38 |
39 |
40 |
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/preview/twitter-contents/22.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 | import { files } from "@/lib/utils";
5 | import Image from "next/image";
6 | import { RotateCw } from "lucide-react";
7 | import { Button } from "@/components/ui/button";
8 |
9 | type Props = {};
10 |
11 | export default function TwitterContent22({}: Props) {
12 | const restartAnimation = async () => {
13 | const element = document.querySelector(
14 | ".custom-image-animate"
15 | ) as HTMLDivElement;
16 | if (element) {
17 | element.style.opacity = "0";
18 | element.classList.remove("custom-image-animate");
19 | await new Promise((resolve) => setTimeout(resolve, 150));
20 | element.classList.add("custom-image-animate");
21 | element.style.opacity = "1";
22 | }
23 | };
24 |
25 | return (
26 |
27 |
28 |
29 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | );
43 | }
44 |
--------------------------------------------------------------------------------
/preview/twitter-contents/23.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 | import { Bike } from "lucide-react";
5 | import { Slider } from "@/components/ui/slider";
6 |
7 | export default function TwitterContent22() {
8 | const [size, setSize] = useState(16);
9 |
10 | return (
11 |
12 |
13 |
14 |
18 |
19 |
20 |
21 |
Bike
22 |
23 |
24 |
28 | Size
29 |
30 | {
37 | if (value < 16) return;
38 | setSize(value);
39 | }}
40 | />
41 |
42 |
43 |
44 |
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/preview/twitter-contents/24.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 | import { Input } from "@/components/ui/input";
5 |
6 | const colors = [
7 | "#1a1a1a",
8 | "#f5f5f5",
9 | "#3b82f6",
10 | "#10b981",
11 | "#ef4444",
12 | "#f59e0b",
13 | ];
14 |
15 | export default function TwitterContent24() {
16 | return (
17 |
18 |
19 |
20 | {colors.map((color) => (
21 |
22 |
27 |
31 |
32 | ))}
33 |
34 |
35 |
36 | );
37 | }
38 |
--------------------------------------------------------------------------------
/preview/twitter-contents/25.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { motion } from "framer-motion";
3 |
4 | import * as Element from "@/components/TwitterContentsElement";
5 | import { Button } from "@/components/ui/button";
6 |
7 | const easing = [
8 | "ease-in",
9 | "ease-out",
10 | "ease-in-out",
11 | "linear",
12 | [0.25, 0.1, 0.25, 1.0],
13 | ];
14 |
15 | export default function TwitterContent25() {
16 | const [justify, setJustify] = useState<"start" | "end">("start");
17 |
18 | return (
19 |
20 |
21 |
22 | {easing.map((easing) => (
23 |
28 |
37 | i === 0
38 | ? word
39 | : word[0].toUpperCase() + word.slice(1)
40 | )
41 | .join("")
42 | : easing,
43 | }}
44 | className="size-10 shrink-0 rounded-full bg-neutral-900"
45 | />
46 |
52 | {typeof easing === "string"
53 | ? easing
54 | : `cubic-bezier(${easing[0]}, ${easing[1]}, ${easing[2]}, ${easing[3]})`}
55 |
56 |
57 | ))}
58 |
59 |
61 | setJustify((prev) => (prev === "start" ? "end" : "start"))
62 | }
63 | >
64 | Animate
65 |
66 |
67 |
68 | );
69 | }
70 |
--------------------------------------------------------------------------------
/preview/twitter-contents/5/design-1.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 |
5 | export default function TwitterContents5Design1() {
6 | return (
7 |
8 |
9 |
10 |
11 | System Requirements
12 |
13 |
14 | Requires a computer running an operating system. The computer must
15 | have some memory and ideally some kind of long-term storage. An
16 | input device as well as some form of output device is recommended.
17 |
18 |
19 |
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/preview/twitter-contents/5/design-2.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 |
5 | export default function TwitterContents5Design2() {
6 | return (
7 |
8 |
9 |
10 |
11 | System Requirements
12 |
13 |
14 | Requires a computer running an operating system. The computer must
15 | have some memory and ideally some kind of long-term storage. An
16 | input device as well as some form of output device is recommended.
17 |
18 |
19 |
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/preview/twitter-contents/5/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useRef, useState } from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 | import SyntaxHighlighter from "@/components/SyntaxHighlighter";
5 |
6 | export default function TwitterContents5() {
7 | const [open, setOpen] = useState(false);
8 |
9 | const detailsRef = useRef(null);
10 |
11 | const codeString = `
12 | System Requirements
13 |
14 | Requires a computer running an operating system. The computer must
15 | have some memory and ideally some kind of long-term storage. An
16 | input device as well as some form of output device is recommended.
17 |
18 | `;
19 |
20 | return (
21 |
22 |
23 | {codeString}
24 |
25 |
26 | setOpen(!open)}>
27 | System Requirements
28 |
29 | Requires a computer running an operating system. The computer must
30 | have some memory and ideally some kind of long-term storage. An
31 | input device as well as some form of output device is recommended.
32 |
33 |
34 |
35 | {/*
36 | {initialPositions.map((p) => (
37 | setPosition(p)}
42 | >
43 | {p}
44 |
45 | ))}
46 | */}
47 |
48 | );
49 | }
50 |
--------------------------------------------------------------------------------
/preview/twitter-contents/7.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 | import SyntaxHighlighter from "@/components/SyntaxHighlighter";
5 | import { Slider } from "@/components/ui/slider";
6 | import ColorPicker from "@/components/ColorPicker";
7 |
8 | export default function TwitterContents2() {
9 | const [values, setValues] = useState({
10 | primary: "#00ADB5",
11 | secondary: "#393E46",
12 | borderRadius: 4,
13 | });
14 |
15 | const codeString = `:root {
16 | --clr-primary: ${values.primary};
17 | --clr-secondary: ${values.secondary};
18 | --border-radius: ${values.borderRadius}px;
19 | }`;
20 |
21 | return (
22 |
23 |
24 | {codeString}
25 |
26 |
27 |
28 |
29 | Global Variables
30 |
31 |
32 | Using Global Variables is the best method to make your styling to
33 | next level.
34 |
35 |
42 | Learn more
43 |
44 |
45 |
46 |
47 |
51 | More examples
52 |
53 |
54 | Using Global Variables is the best method to make your styling to
55 | next level.
56 |
57 |
58 | {Array.from({ length: 6 }).map((_, index) => (
59 |
68 | ))}
69 |
70 |
71 |
72 |
73 | setValues({ ...values, primary: value })}
76 | />
77 | setValues({ ...values, secondary: value })}
80 | />
81 |
84 | setValues({ ...values, borderRadius: value[0] })
85 | }
86 | />
87 |
88 |
89 | );
90 | }
91 |
--------------------------------------------------------------------------------
/preview/twitter-contents/8.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 |
3 | import * as Element from "@/components/TwitterContentsElement";
4 | import SyntaxHighlighter from "@/components/SyntaxHighlighter";
5 | import { Slider } from "@/components/ui/slider";
6 | import { Label } from "@/components/ui/label";
7 |
8 | type Props = {};
9 |
10 | export default function TwitterContents8({}: Props) {
11 | const [values, setValues] = useState({
12 | padding: 12,
13 | borderOut: 12,
14 | borderIn: 4,
15 | });
16 |
17 | const codeString = `.border-out {
18 | border-radius: ${values.borderIn + values.padding}px;
19 | /* border-in + padding = ${values.borderIn} + ${values.padding} */
20 | }`;
21 |
22 | return (
23 |
24 |
25 | {codeString}
26 |
27 |
28 |
35 |
39 |
40 |
{values.padding}px
41 |
42 |
46 |
47 |
48 |
49 |
50 | Padding
51 |
54 | setValues({ ...values, padding: value[0] })
55 | }
56 | />
57 |
58 |
59 | Border In
60 |
63 | setValues({ ...values, borderIn: value[0] })
64 | }
65 | />
66 |
67 |
68 |
69 | );
70 | }
71 |
--------------------------------------------------------------------------------
/preview/twitter-contents/9.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { AnimatePresence, motion } from "framer-motion";
3 |
4 | import * as Element from "@/components/TwitterContentsElement";
5 | import { Input } from "@/components/ui/input";
6 | import { cn } from "@/lib/utils";
7 |
8 | export default function TwitterContents9() {
9 | const [password, setPassword] = useState("");
10 |
11 | return (
12 |
13 |
14 | setPassword(e.target.value)} />
15 |
16 |
17 | = 8} /> At least 8
18 | characters long
19 |
20 |
21 | Contains at
22 | least one uppercase letter
23 |
24 |
25 | Contains at
26 | least one lowercase letter
27 |
28 |
29 | Contains at
30 | least one number
31 |
32 |
33 |
34 | Contains at least one special character
35 |
36 |
37 |
38 |
39 | );
40 | }
41 |
42 | function Check({ valid }: { valid: boolean }) {
43 | return (
44 |
50 |
51 | {valid && (
52 |
58 | )}
59 |
60 |
61 | );
62 | }
63 |
--------------------------------------------------------------------------------
/public/air-canada-vector-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alisamadiii/Portfolio/51f097c3c5de225d20c0975b0edca9e95f09dc7e/public/air-canada-vector-logo.png
--------------------------------------------------------------------------------
/public/building-website.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alisamadiii/Portfolio/51f097c3c5de225d20c0975b0edca9e95f09dc7e/public/building-website.png
--------------------------------------------------------------------------------
/public/canada-airplane.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alisamadiii/Portfolio/51f097c3c5de225d20c0975b0edca9e95f09dc7e/public/canada-airplane.png
--------------------------------------------------------------------------------
/public/eslint-setup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alisamadiii/Portfolio/51f097c3c5de225d20c0975b0edca9e95f09dc7e/public/eslint-setup.png
--------------------------------------------------------------------------------
/public/lemon-squeezy-api.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alisamadiii/Portfolio/51f097c3c5de225d20c0975b0edca9e95f09dc7e/public/lemon-squeezy-api.png
--------------------------------------------------------------------------------
/public/my-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alisamadiii/Portfolio/51f097c3c5de225d20c0975b0edca9e95f09dc7e/public/my-image.png
--------------------------------------------------------------------------------
/scripts/build-registry.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | const fs = require("fs");
3 |
4 | const REGISTRY_PATH = path.join(process.cwd(), "/preview");
5 |
6 | function getFilesRecursive(directory) {
7 | const files = [];
8 | const items = fs.readdirSync(directory);
9 |
10 | // Remove the check for index.tsx
11 | for (const item of items) {
12 | const fullPath = path.join(directory, item);
13 | if (fs.statSync(fullPath).isDirectory()) {
14 | files.push(...getFilesRecursive(fullPath));
15 | } else if (item.endsWith(".tsx")) {
16 | files.push(fullPath);
17 | }
18 | }
19 |
20 | return files;
21 | }
22 |
23 | const READ_PATH = getFilesRecursive(REGISTRY_PATH);
24 |
25 | let index = `// @ts-nocheck
26 | import * as React from "react"
27 |
28 | import dynamic from "next/dynamic";
29 |
30 | export const Index: Record = {`;
31 |
32 | for (const file of READ_PATH) {
33 | const relativePath = path.relative(REGISTRY_PATH, file);
34 | let componentName = relativePath.replace(/\.tsx$/, "").replace(/\//g, "-");
35 |
36 | // Remove '_index' if it's an index file and remove '-index' if it's part of the folder name
37 | if (componentName.endsWith("_index")) {
38 | componentName = componentName.replace(/_index$/, "");
39 | } else {
40 | componentName = componentName.replace(/-index$/, "");
41 | }
42 |
43 | index += `
44 | "${componentName}": {
45 | name: "${componentName}",
46 | component: dynamic(() => import("@/preview/${relativePath.replace(/\\/g, "/")}"), { ssr: false }),
47 | },`;
48 | }
49 |
50 | index += `
51 | },`;
52 |
53 | fs.writeFileSync(path.join(process.cwd(), "__registry__/index.tsx"), index);
54 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "bundler",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve",
14 | "incremental": true,
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "paths": {
21 | "@/*": ["./*"],
22 | "contentlayer/generated": ["./.contentlayer/generated"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------