diff --git a/public/showcase/7770ecce-d977-40dd-bf91-b3f7114e4003.png b/public/showcase/7770ecce-d977-40dd-bf91-b3f7114e4003.png new file mode 100644 index 00000000..5fb08cf4 Binary files /dev/null and b/public/showcase/7770ecce-d977-40dd-bf91-b3f7114e4003.png differ diff --git a/showcase/showcaseConfig.json b/showcase/showcaseConfig.json new file mode 100644 index 00000000..636c8227 --- /dev/null +++ b/showcase/showcaseConfig.json @@ -0,0 +1,20 @@ +{ + "content": [ + { + "id": "7770ecce-d977-40dd-bf91-b3f7114e4003", + "author": "redyf", + "title": "ghostty mentioned!", + "description": "ghostty mentioned!", + "tags": [ + "linux" + ], + "images": [ + { + "src": "/showcase/7770ecce-d977-40dd-bf91-b3f7114e4003.png", + "altText": "alt text" + } + ], + "code": "# Fonts\nfont-family = \"MonoLisa\"\nfont-size = 12\nfont-style = Bold \nfont-style-italic = Regular Italic\nfont-style-bold = Bold\nfont-style-bold-italic = Bold Italic\n\n# font-feature = -ss01, -ss02, -ss04 # Cartograph\nfont-feature = ss01\nfont-feature = ss02\nfont-feature = ss04\nfont-feature = ss07\nfont-feature = ss08\nfont-feature = ss10\nfont-feature = ss11\nfont-feature = ss13\nfont-feature = ss18\nfont-feature = zero\n# font-feature = ss01, ss02, ss04, ss07, ss08, ss10, ss11, ss13, ss18, zero # Monolisa\n# font-variation = \"wght=800\"\nfont-thicken = true\nbold-is-bright = true\n\n# adjust-cell-width =\n# adjust-cell-height =\n# adjust-font-baseline =\n# adjust-underline-position =\n# adjust-underline-thickness = 1\n# adjust-strikethrough-position = 1\n# adjust-strikethrough-thickness = 1\nadjust-cursor-thickness = 10\n\n# Cursor\n# cursor-color =\n# cursor-opacity =\n# cursor-text =\ncursor-style = block\ncursor-style-blink = false\ncursor-click-to-move = false\n\n# Mouse\nmouse-hide-while-typing = false\nmouse-scroll-multiplier = 1\n\n# Screen\nbackground-opacity = 1\nunfocused-split-opacity = 0.7\nfullscreen = false\n\n# Mappings\nkeybind = ctrl+comma=unbind\nkeybind = ctrl+alt+up=unbind\nkeybind = ctrl+page_down=unbind\nkeybind = ctrl+shift+v=paste_from_clipboard\nkeybind = shift+insert=paste_from_selection\nkeybind = ctrl+shift+a=unbind\nkeybind = shift+up=unbind\nkeybind = alt+five=unbind\nkeybind = super+ctrl+right_bracket=unbind\nkeybind = ctrl+shift+plus=increase_font_size:1\nkeybind = ctrl+shift+minus=decrease_font_size:1\nkeybind = ctrl+shift+o=unbind\nkeybind = ctrl+shift+c=copy_to_clipboard\nkeybind = ctrl+shift+q=unbind\nkeybind = ctrl+shift+n=unbind\nkeybind = ctrl+shift+page_down=unbind\nkeybind = ctrl+shift+comma=reload_config\nkeybind = shift+left=unbind\nkeybind = super+ctrl+shift+up=unbind\nkeybind = alt+eight=unbind\nkeybind = shift+page_up=unbind\nkeybind = ctrl+alt+shift+j=unbind\nkeybind = ctrl+shift+left=unbind\nkeybind = ctrl+shift+w=unbind\nkeybind = super+ctrl+shift+equal=unbind\nkeybind = shift+end=unbind\nkeybind = ctrl+shift+backspace=reset_font_size\nkeybind = alt+three=unbind\nkeybind = ctrl+shift+j=unbind\nkeybind = ctrl+enter=toggle_fullscreen\nkeybind = ctrl+page_up=unbind\nkeybind = shift+right=unbind\nkeybind = ctrl+alt+left=unbind\nkeybind = shift+page_down=unbind\nkeybind = ctrl+shift+right=unbind\nkeybind = ctrl+shift+page_up=unbind\nkeybind = alt+nine=unbind\nkeybind = ctrl+shift+t=unbind\nkeybind = shift+down=unbind\nkeybind = super+ctrl+shift+left=unbind\nkeybind = alt+two=unbind\nkeybind = ctrl+alt+down=unbind\nkeybind = super+ctrl+shift+down=unbind\nkeybind = super+ctrl+shift+right=unbind\nkeybind = ctrl+plus=unbind\nkeybind = alt+four=unbind\nkeybind = ctrl+shift+e=unbind\nkeybind = ctrl+alt+right=unbind\nkeybind = alt+f4=unbind\nkeybind = alt+one=unbind\nkeybind = ctrl+shift+enter=unbind\nkeybind = shift+home=unbind\nkeybind = super+ctrl+left_bracket=unbind\nkeybind = ctrl+shift+i=unbind\nkeybind = alt+six=unbind\nkeybind = alt+seven=unbind\n\n# Window\nwindow-padding-x = 5\nwindow-padding-y = 5\n# window-padding-balance = false\n# window-inherit-working-directory = true\n# window-inherit-font-size = true\n# window-decoration = true\n# window-theme = auto\n# window-save-state = default\n# window-new-tab-position = current\n\n# Clipboard (ask, allow or deny)\nclipboard-read = ask\nclipboard-trim-trailing-spaces = true\nclipboard-paste-protection = true\nclipboard-paste-bracketed-safe = true\ncopy-on-select = true\n\n# Close\nconfirm-close-surface = true\n\n# Shell\nshell-integration = zsh\nshell-integration-features = cursor,no-sudo,title\n\n# Advanced\n# linux-cgroup = single-instance\n\n# GTK\ngtk-single-instance = desktop\ngtk-titlebar = false\ngtk-tabs-location = top\ngtk-wide-tabs = true\n\ntheme = catppuccin-mocha\n\n# Scheme: Jabuti\n# Generated by Ghostty Base16 Converter\n# background = 292a37\n# foreground = c0cbe3\n#\n# selection-background = 3c3e51\n# selection-foreground = 292a37\n#\n# palette = 0=#292a37\n# palette = 1=#ec6a88\n# palette = 2=#3fdaa4\n# palette = 3=#e1c697\n# palette = 4=#3fc6de\n# palette = 5=#be95ff\n# palette = 6=#ff7eb6\n# palette = 7=#c0cbe3\n# palette = 8=#45475d\n# palette = 9=#ec6a88\n# palette = 10=#3fdaa4\n# palette = 11=#e1c697\n# palette = 12=#3fc6de\n# palette = 13=#be95ff\n# palette = 14=#ff7eb6\n# palette = 15=#ffffff\n# palette = 16=#efb993\n# palette = 17=#8b8da9\n# palette = 18=#343545\n# palette = 19=#3c3e51\n# palette = 20=#50526b\n# palette = \"21=#d9e0ee" + } + ] +} diff --git a/src/components/codeblock/index.tsx b/src/components/codeblock/index.tsx index 2b87a4ba..c9a929c4 100644 --- a/src/components/codeblock/index.tsx +++ b/src/components/codeblock/index.tsx @@ -6,11 +6,14 @@ import { CheckIcon, CopyIcon } from "lucide-react"; interface CodeblockProps { children?: React.ReactNode; + className?: string; } -export default function CodeBlock({ children }: CodeblockProps) { +export default function CodeBlock({ children, className }: CodeblockProps) { return ( -
+    
       {children}
       
     
diff --git a/src/components/showcase-list-item/ShowcaseListItem.module.css b/src/components/showcase-list-item/ShowcaseListItem.module.css new file mode 100644 index 00000000..7048483b --- /dev/null +++ b/src/components/showcase-list-item/ShowcaseListItem.module.css @@ -0,0 +1,27 @@ +.ListItem { + border: 1px solid var(--gray-2); + border-radius: 10px; + overflow: hidden; + + & img { + width: 100%; + height: auto; + } + + & .content { + padding: 12px 12px 16px; + + & .title { + margin-bottom: 8px; + } + + & .description { + margin-bottom: 8px; + } + + } + + & .tagList { + padding: 16px 0 0; + } +} diff --git a/src/components/showcase-list-item/index.tsx b/src/components/showcase-list-item/index.tsx new file mode 100644 index 00000000..af77ac4b --- /dev/null +++ b/src/components/showcase-list-item/index.tsx @@ -0,0 +1,37 @@ +"use client"; +import s from "./ShowcaseListItem.module.css"; +import Button from "@/components/button"; +import Image, { ImageProps } from "next/image"; +import { H3, P } from "@/components/text"; +import TagList from "@/components/tag-list"; +import { ShowcaseContent } from "@/types/showcase"; + +interface ListItemProps + extends Pick { + image: ImageProps; + onClick: () => void; +} +export default function ListItem({ + image, + title, + tags, + description, + onClick, +}: ListItemProps) { + return ( +
  • + +
    +

    {title}

    +

    {description}

    + + ({ name: tag, color: "white" }))} + /> +
    +
  • + ); +} diff --git a/src/components/showcase-modal/ShowcaseModal.module.css b/src/components/showcase-modal/ShowcaseModal.module.css new file mode 100644 index 00000000..f1d95b8a --- /dev/null +++ b/src/components/showcase-modal/ShowcaseModal.module.css @@ -0,0 +1,83 @@ +.modal { + top: 0; + left: 0; + z-index: 1; + width: 100%; + height: 100%; + display: flex; + position: fixed; + pointer-events: none; + background: color-mix(in srgb, var(--black) 60%, transparent); + + & .dialog { + pointer-events: all; + top: 20%; + overflow: hidden; + border: none; + border-radius: 10px; + width: 100%; + margin: 0 auto; + max-width: 700px; + + &:hover .closeContainer { + display: flex; + } + + & .closeContainer { + position: absolute; + top: 0; + right: -1px; + padding: 12px; + height: 80px; + width: 80px; + background: black; + clip-path: polygon(0% 0%, 100% 0%, 100% 100%); + align-items: flex-start; + justify-content: flex-end; + display: none; + + & button { + cursor: pointer; + color: white; + background: none; + border: none; + + } + } + + & img { + z-index: 1; + width: 100%; + height: auto; + } + + & .content { + padding: 12px; + + & .buttonContainer { + display: flex; + padding: 0 0 12px; + gap: 24px; + + >button { + flex-basis: calc(50% - 12px) + } + } + + & .title { + margin: 0 0 4px; + } + + & .author { + color: var(--gray-5); + margin: 0 0 16px; + } + } + + & .codeBlock { + padding: 8px; + max-height: 250px; + overflow: scroll; + } + } +} diff --git a/src/components/showcase-modal/index.tsx b/src/components/showcase-modal/index.tsx new file mode 100644 index 00000000..e9cda276 --- /dev/null +++ b/src/components/showcase-modal/index.tsx @@ -0,0 +1,71 @@ +import Button from "@/components/button"; +import Image from "next/image"; +import s from "./ShowcaseModal.module.css"; +import { H3, H5, P } from "@/components/text"; +import { useState } from "react"; +import CodeBlock from "@/components/codeblock"; +import { CircleX } from "lucide-react"; +import { ShowcaseContent } from "@/types/showcase"; + +interface ModalProps { + onClose: () => void; + content: ShowcaseContent; +} + +export default function Modal({ onClose, content }: ModalProps) { + const [viewMode, setViewMode] = useState<"detail" | "config">("detail"); + const { code, title, description, author, images } = content; + + return ( +
    + +
    + +
    + {images[0].alt} +
    +
    + + +
    + {viewMode === "detail" ? ( + + ) : ( + {code} + )} +
    +
    +
    + ); +} + +interface DetailContentProps { + title: string; + author: string; + description: string; +} + +function DetailContent({ title, author, description }: DetailContentProps) { + return ( + <> +

    {title}

    +
    {author}
    +

    {description}

    + + ); +} diff --git a/src/components/tag-list/index.tsx b/src/components/tag-list/index.tsx index 4c741d21..d145f35b 100644 --- a/src/components/tag-list/index.tsx +++ b/src/components/tag-list/index.tsx @@ -21,11 +21,12 @@ interface TagProps { interface TagListProps { tags: TagProps[]; + className?: string; } -export default function TagList({ tags }: TagListProps) { +export default function TagList({ tags, className }: TagListProps) { return ( -