Skip to content

Commit

Permalink
Merge pull request #42 from xmimiex/feat/preview
Browse files Browse the repository at this point in the history
feat: add expand and title + description
  • Loading branch information
xmimiex authored Jun 2, 2024
2 parents 1414ef6 + 10f0975 commit 5d51cd2
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 31 deletions.
18 changes: 15 additions & 3 deletions src/components/CodeBlock/CodeBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const CodeBlock = component$<CodeBlockProps>(({ content, language }) => {
})

const copyLabel = useSignal('Copy')
const isCollapsed = useSignal(true)

const copy$ = $(() => {
navigator.clipboard.writeText(content)
Expand All @@ -43,18 +44,29 @@ export const CodeBlock = component$<CodeBlockProps>(({ content, language }) => {
})

return (
<div class="border-gray-200 border-y border-x dark:border-gray-600 rounded-b-lg pb-2">
<div class="border-gray-200 border-y border-x dark:border-gray-600 rounded-b-lg">
<div class="flex text-sm font-medium text-center justify-between text-gray-500 dark:text-gray-400 bg-gray-50 dark:bg-gray-700 border-gray-200 dark:border-gray-600 border-b">
<div class="inline-block p-2 px-3 text-gray-800 bg-gray-100 border-r border-gray-200 dark:text-white dark:bg-gray-800 dark:border-gray-600">
{language}
</div>
<div class="flex justify-end">
<Button onClick$={copy$} color="light" size="xs" prefix={IconCopySolid} title="Copy to clipboard">
<Button
onClick$={copy$}
color="light"
size="xs"
class="rounded-r-none border-t-0 border-r-0 border-b-0 rounded-l-none"
prefix={IconCopySolid}
title="Copy to clipboard"
>
{copyLabel}
</Button>
</div>
</div>
<pre dangerouslySetInnerHTML={highlightedContent.value} />
<pre dangerouslySetInnerHTML={highlightedContent.value} class={['p-4 overflow-auto', isCollapsed.value ? 'max-h-32' : 'max-h-none']} />

<Button color="dark" size="md" full class="rounded-t-none border-t" onClick$={() => (isCollapsed.value = !isCollapsed.value)}>
{isCollapsed.value ? 'Expand code' : 'Collapse code'}
</Button>
</div>
)
})
9 changes: 7 additions & 2 deletions src/components/__Preview/__Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import styles from './preview.css?inline'

type PreviewProps = PropsOf<'iframe'> & {
url: string
title: string
description?: string
}

type PreviewDisplaySize = 'mobile' | 'tablet' | 'desktop'
Expand All @@ -24,10 +26,11 @@ const getExampleFilePath = server$(function (url: string) {
const getExampleCode = server$(function (url: string) {
const rootDir = process.cwd()
const exampleUrl = `${rootDir}/src/routes${url}/index@examples.tsx`
return fs.readFileSync(exampleUrl, 'utf-8')
const codeContent = fs.readFileSync(exampleUrl, 'utf-8')
return codeContent.replace(/\/\*\*[\s\S]*?\*\//, '').trim()
})

export const Preview = component$<PreviewProps>(({ url, class: classNames, ...props }) => {
export const Preview = component$<PreviewProps>(({ url, class: classNames, title, ...props }) => {
useStyles$(styles)
const { isDark } = useDark()

Expand Down Expand Up @@ -63,6 +66,8 @@ export const Preview = component$<PreviewProps>(({ url, class: classNames, ...pr

return (
<div>
<h2 class="text-2xl font-bold text-gray-800 dark:text-gray-100 mb-3">{title}</h2>
{props.description && <p class="text-gray-600 dark:text-gray-400 mb-4">{props.description}</p>}
<div class="flex justify-between p-4 bg-gray-50 w-full border border-gray-200 rounded-t-xl dark:border-gray-600 dark:bg-gray-700">
<ul>
<li>
Expand Down
64 changes: 40 additions & 24 deletions src/routes/docs/components/accordion/index.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,49 @@
import { component$ } from '@builder.io/qwik'
import { component$, useComputed$ } from '@builder.io/qwik'
import { server$ } from '@builder.io/qwik-city'
import { Preview } from '~/components/__Preview/__Preview'
import fs from 'fs'

export default component$(() => {
return (
<section id="accordions">
<div>
<h2 class="my-3">Default accordion</h2>
<Preview url="/examples/accordion/default-accordion" height="300" />
</div>
export const getAccordionsPreview = server$(() => {
function getTitleAndDescription(fileContent: string) {
const pattern = /\/\*\*[^]*?title:\s*(.*?)\s*\*[^]*?description:\s*(.*?)\s*\*\//
const match = pattern.exec(fileContent)

<div>
<h2 class="my-3">Always open accordion</h2>
<Preview url="/examples/accordion/always-open-accordion" height="300" />
</div>
let title = ''
let description = ''

<div>
<h2 class="my-3">Flush accordion</h2>
<Preview url="/examples/accordion/flush-accordion" height="300" />
</div>
if (match) {
title = match[1].trim()
description = match[2].trim()
}

<div>
<h2 class="my-3">Styling accordion</h2>
<Preview url="/examples/accordion/styling-accordion" height="300" />
</div>
return {
title,
description,
}
}

const accordions = fs.readdirSync('src/routes/examples/accordion').map((file) => {
const path = 'src/routes/examples/accordion/' + file
const content = fs.readFileSync(path + '/index@examples.tsx', 'utf-8')
const { title, description } = getTitleAndDescription(content)
return {
title,
description,
url: '/examples/accordion/' + file,
height: '300',
}
})
return accordions
})

<div>
<h2 class="my-3">Closed first item</h2>
<Preview url="/examples/accordion/closed-first-accordion" height="300" />
</div>
export default component$(() => {
const accordions = useComputed$(() => getAccordionsPreview())

return (
<section class="flex flex-col gap-8">
{accordions.value.map((accordion) => (
<Preview title={accordion.title} url={accordion.url} description={accordion.description} height={accordion.height} />
))}
</section>
)
})
8 changes: 6 additions & 2 deletions src/routes/docs/components/navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ export default component$(() => {
return (
<section id="navbars">
<div>
<h2 class="my-3">Default navbar</h2>
<Preview url="/examples/navbar/default-navbar" height="300" />
<Preview
title="Default navbar"
url="/examples/navbar/default-navbar"
description="Use this example of a navigation bar built with the utility classes from Tailwind CSS to enable users to navigate across the pages of your website."
height="300"
/>
</div>

<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* title: Always open accordion
* description: Always open prop to makes accordion able to open multiple elements.
*/
import { component$ } from '@builder.io/qwik'
import { Accordion, AccordionContent, AccordionHeader, AccordionPanel } from '~/components/Accordion'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* title: Closed first accordion
* description: First item is not open by default
*/
import { component$ } from '@builder.io/qwik'
import { Accordion, AccordionContent, AccordionHeader, AccordionPanel } from '~/components/Accordion'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* title: Default accordion
* description: Use this example to basic accordion.
*/

import { component$ } from '@builder.io/qwik'
import { Accordion, AccordionContent, AccordionHeader, AccordionPanel } from '~/components/Accordion'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* title: Flush accordion
* description: Flush prop removes background color, side borders, and rounded corners
*/

import { component$ } from '@builder.io/qwik'
import { Accordion, AccordionContent, AccordionHeader, AccordionPanel } from '~/components/Accordion'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* title: Styling accordion
* description: You can style accordion content and headers by passing tailwind classes into them.
*/

import { component$ } from '@builder.io/qwik'
import { Accordion, AccordionContent, AccordionHeader, AccordionPanel } from '~/components/Accordion'

Expand Down

0 comments on commit 5d51cd2

Please sign in to comment.