Skip to content

Commit

Permalink
example
Browse files Browse the repository at this point in the history
  • Loading branch information
unnoq committed Apr 3, 2024
1 parent 0e8ee7b commit 8f4a18d
Show file tree
Hide file tree
Showing 11 changed files with 515 additions and 76 deletions.
97 changes: 97 additions & 0 deletions apps/web/components/example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { Suspense, lazy } from 'react'
import { codeToHtml } from 'shiki'
import githubDarkDimmed from 'shiki/themes/github-dark-dimmed.mjs'

const exampleComponents = import.meta.glob('../examples/**/*.tsx') as {
[key: string]: () => Promise<{
default: React.ComponentType
}>
}

const exampleCodes = import.meta.glob('../examples/**/*.tsx', {
query: '?raw',
import: 'default',
}) as {
[key: string]: () => Promise<string>
}

export function Example({ path }: { path: string }) {
const fullPath = `../examples/${path}.tsx`

return (
<div>
<ExamplePreview fullPath={fullPath} />
<ExampleCode fullPath={fullPath} />
</div>
)
}

function ExamplePreview(props: { fullPath: string }) {
const loadComponent = exampleComponents[props.fullPath]

if (!loadComponent) {
throw new Error(`Component does not exists on [${props.fullPath}]`)
}

const Component = lazy(loadComponent)

return (
// TODO
<Suspense fallback="loading...">
<Component />
</Suspense>
)
}

function ExampleCode(props: { fullPath: string }) {
const loadCode = exampleCodes[props.fullPath]

if (!loadCode) {
throw new Error(`Component does not exists on [${props.fullPath}]`)
}

const Code = lazy(async () => {
const code = await loadCode()
const html = await codeToHtml(code, {
lang: 'tsx',
theme: 'github-light',
themes: {
light: 'github-light',
dark: githubDarkDimmed,
// dim: 'github-dimmed',
},
transformers: [
{
pre: (el) => {
el.properties.class += ' vocs_Pre'
return el
},
code: (el) => {
el.properties.class += ' vocs_Code'
return el
},
span: (el) => {
el.properties.class += ' vocs_Span'
return el
},
},
],
})
return {
default: () => {
return (
<div className="vocs_CodeBlock">
<div className="vocs_Pre_wrapper" dangerouslySetInnerHTML={{ __html: html }} />
</div>
)
},
}
})

return (
// TODO
<Suspense fallback="loading...">
<Code />
</Suspense>
)
}
29 changes: 29 additions & 0 deletions apps/web/examples/accordion-demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from '@dinui/react/accordion'

export default function AccordionDemo() {
return (
<Accordion type="single" collapsible className="w-full">
<AccordionItem value="item-1">
<AccordionTrigger>Is it accessible?</AccordionTrigger>
<AccordionContent>Yes. It adheres to the WAI-ARIA design pattern.</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>Is it styled?</AccordionTrigger>
<AccordionContent>
Yes. It comes with default styles that matches the other components&apos; aesthetic.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger>Is it animated?</AccordionTrigger>
<AccordionContent>
Yes. It's animated by default, but you can disable it if you prefer.
</AccordionContent>
</AccordionItem>
</Accordion>
)
}
3 changes: 2 additions & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"autoprefixer": "^10.4.19",
"postcss": "^8.4.38",
"tailwindcss": "^3.4.3",
"typescript": "^5.4.3"
"typescript": "^5.4.3",
"vite": "^5.2.7"
}
}
25 changes: 24 additions & 1 deletion apps/web/pages/ui/accordion.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
---
title: Accordion
description: A vertically stacked set of interactive headings that each reveal a section of content.
---

# Accordion
import { Example } from '@web/components/example'

<Example path="accordion-demo" />

## Usage

```tsx
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from '@dinui/react/accordion'
```

```tsx
<Accordion type="single" collapsible>
<AccordionItem value="item-1">
<AccordionTrigger>Is it accessible?</AccordionTrigger>
<AccordionContent>Yes. It adheres to the WAI-ARIA design pattern.</AccordionContent>
</AccordionItem>
</Accordion>
```
9 changes: 7 additions & 2 deletions apps/web/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"target": "ES2022",
"useDefineForClassFields": true,
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"types": [],
"types": ["vite/client"],
"module": "ESNext",
"skipLibCheck": true,

Expand All @@ -14,12 +14,17 @@
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"paths": {
"@web/*": ["./*"],
"@dinui/react/utils": ["../../packages/react-ui/utils"],
"@dinui/react/*": ["../../packages/react-ui/ui/*"]
},

/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"exclude": ["**/*.js", "**/*.cjs", "**/*.mjs"]
"exclude": ["**/*.js", "**/*.cjs", "**/*.mjs", "vocs.config.ts"]
}
10 changes: 10 additions & 0 deletions apps/web/vocs.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { resolve } from 'path'
import { defineConfig } from 'vocs'

export default defineConfig({
rootDir: '.',
vite: {
resolve: {
alias: {
'@web': resolve(__dirname, './'),
'@dinui/react/utils': resolve(__dirname, '../../packages/react-ui/utils'),
'@dinui/react': resolve(__dirname, '../../packages/react-ui/ui'),
},
},
},
title: 'DinUI',
sidebar: [
{
Expand Down
17 changes: 12 additions & 5 deletions packages/react-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
},
"license": "MIT",
"exports": {
"./button": {
"default": "./build/ui/button.jsx",
"import": "./build/ui/button.jsx",
"types": "./build/ui/button.d.ts"
"./accordion": {
"types": "./build/ui/accordion.d.ts",
"default": "./build/ui/accordion.jsx"
},
"./utils": {
"types": "./build/utils.d.ts",
"default": "./build/utils.jsx"
}
},
"scripts": {
Expand All @@ -32,6 +35,10 @@
"typescript": "^5.4.2"
},
"dependencies": {
"react": "^18.2.0"
"@radix-ui/react-accordion": "^1.1.2",
"clsx": "^2.1.0",
"react": "^18.2.0",
"tailwind-merge": "^2.2.2",
"tailwind-variants": "^0.2.1"
}
}
52 changes: 52 additions & 0 deletions packages/react-ui/ui/accordion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use client'

import { cx } from '../utils'
import * as AccordionPrimitive from '@radix-ui/react-accordion'
import { ChevronDownIcon } from '@radix-ui/react-icons'
import * as React from 'react'

const Accordion = AccordionPrimitive.Root

const AccordionItem = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
>(({ className, ...props }, ref) => (
<AccordionPrimitive.Item ref={ref} className={cx('border-b', className)} {...props} />
))
AccordionItem.displayName = 'AccordionItem'

const AccordionTrigger = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<AccordionPrimitive.Header className="flex">
<AccordionPrimitive.Trigger
ref={ref}
className={cx(
'flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
className,
)}
{...props}
>
{children}
<ChevronDownIcon className="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200" />
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>
))
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName

const AccordionContent = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<AccordionPrimitive.Content
ref={ref}
className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
{...props}
>
<div className={cx('pb-4 pt-0', className)}>{children}</div>
</AccordionPrimitive.Content>
))
AccordionContent.displayName = AccordionPrimitive.Content.displayName

export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
14 changes: 0 additions & 14 deletions packages/react-ui/ui/button.tsx

This file was deleted.

6 changes: 6 additions & 0 deletions packages/react-ui/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import clsx, { type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'

export function cx(...args: ClassValue[]) {
return twMerge(clsx(...args))
}
Loading

0 comments on commit 8f4a18d

Please sign in to comment.