feat: populate getting-started area
This commit is contained in:
parent
91d6c400ea
commit
a0f2f0a37f
26
apps/www/.vitepress/theme/components/Callout.vue
Normal file
26
apps/www/.vitepress/theme/components/Callout.vue
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
Alert,
|
||||||
|
AlertDescription,
|
||||||
|
AlertTitle,
|
||||||
|
} from '@/lib/registry/default/ui/alert'
|
||||||
|
|
||||||
|
interface CalloutProps {
|
||||||
|
icon?: string
|
||||||
|
title?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
defineProps<CalloutProps>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Alert class="not-docs">
|
||||||
|
<span v-if="icon" class="mr-4 text-2xl">{{ icon }}</span>
|
||||||
|
<AlertTitle v-if="title">
|
||||||
|
{{ title }}
|
||||||
|
</AlertTitle>
|
||||||
|
<AlertDescription>
|
||||||
|
<slot />
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
</template>
|
||||||
|
|
@ -17,7 +17,7 @@ const Component = defineAsyncComponent({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="group relative my-4 flex flex-col space-y-2">
|
<div class="not-docs group relative my-4 flex flex-col space-y-2">
|
||||||
<Tabs default-value="preview" class="relative mr-auto w-full">
|
<Tabs default-value="preview" class="relative mr-auto w-full">
|
||||||
<div class="flex items-center justify-between pb-3">
|
<div class="flex items-center justify-between pb-3">
|
||||||
<TabsList class="w-full justify-start rounded-none border-b bg-transparent p-0">
|
<TabsList class="w-full justify-start rounded-none border-b bg-transparent p-0">
|
||||||
|
|
|
||||||
7
apps/www/.vitepress/theme/components/Steps.vue
Normal file
7
apps/www/.vitepress/theme/components/Steps.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="[&>h3]:step mb-12 ml-4 border-l pl-8 [counter-reset:step]"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -1,2 +1,4 @@
|
||||||
export { default as ComponentPreview } from './ComponentPreview.vue'
|
export { default as ComponentPreview } from './ComponentPreview.vue'
|
||||||
|
export { default as Callout } from './Callout.vue'
|
||||||
export { default as ManualInstall } from './ManualInstall.vue'
|
export { default as ManualInstall } from './ManualInstall.vue'
|
||||||
|
export { default as Steps } from './Steps.vue'
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ export const docsConfig: DocsConfig = {
|
||||||
mainNav: [
|
mainNav: [
|
||||||
{
|
{
|
||||||
title: 'Documentation',
|
title: 'Documentation',
|
||||||
href: '/docs',
|
href: '/docs/introduction',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Components',
|
title: 'Components',
|
||||||
|
|
@ -40,7 +40,7 @@ export const docsConfig: DocsConfig = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'GitHub',
|
title: 'GitHub',
|
||||||
href: 'https://github.com/huntabyte/shadcn-svelte',
|
href: 'https://github.com/radix-vue/shadcn-vue',
|
||||||
external: true,
|
external: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -50,7 +50,7 @@ export const docsConfig: DocsConfig = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
title: 'Introduction',
|
title: 'Introduction',
|
||||||
href: '/docs',
|
href: '/docs/introduction',
|
||||||
items: [],
|
items: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useDark, useToggle } from '@vueuse/core'
|
import { useDark, useToggle } from '@vueuse/core'
|
||||||
import { Content, useData, useRoute } from 'vitepress'
|
import { Content, useData, useRoute } from 'vitepress'
|
||||||
|
import { docsConfig } from '../config/docs'
|
||||||
import { Button } from '@/lib/registry/default/ui/button'
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
import { Kbd } from '@/lib/registry/default/ui/kbd'
|
import { Kbd } from '@/lib/registry/default/ui/kbd'
|
||||||
import RadixIconsGithubLogo from '~icons/radix-icons/github-logo'
|
import RadixIconsGithubLogo from '~icons/radix-icons/github-logo'
|
||||||
|
|
@ -65,19 +66,19 @@ const links = [
|
||||||
<a href="/" class="text-md font-bold"> shadcn-vue </a>
|
<a href="/" class="text-md font-bold"> shadcn-vue </a>
|
||||||
|
|
||||||
<nav
|
<nav
|
||||||
v-for="route in routes"
|
v-for="route in docsConfig.mainNav"
|
||||||
:key="route.name"
|
:key="route.title"
|
||||||
class="flex items-center space-x-6 text-sm font-medium"
|
class="flex items-center space-x-6 text-sm font-medium"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
:href="route.path"
|
:href="route.href"
|
||||||
:target="route.target"
|
:target="route.external ? '_target' : undefined"
|
||||||
class="transition-colors hover:text-foreground/80 text-foreground/60"
|
class="transition-colors hover:text-foreground/80 text-foreground/60"
|
||||||
:class="{
|
:class="{
|
||||||
'font-semibold !text-foreground': $route.path === `${route.path}.html`,
|
'font-semibold !text-foreground': $route.path === `${route.href}.html`,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ route.name }}
|
{{ route.title }}
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
--shiki-color-background: #ffffff;
|
--shiki-color-background: #ffffff;
|
||||||
--shiki-token-constant: #ffffff;
|
--shiki-token-constant: #ffffff;
|
||||||
--shiki-token-string: #ffffff88;
|
--shiki-token-string: #ffffff88;
|
||||||
--shiki-token-comment: #880000;
|
--shiki-token-comment: #ffffff88;
|
||||||
--shiki-token-keyword: #ffffff88;
|
--shiki-token-keyword: #ffffff88;
|
||||||
--shiki-token-parameter: #AA0000;
|
--shiki-token-parameter: #AA0000;
|
||||||
--shiki-token-function: #ffffff;
|
--shiki-token-function: #ffffff;
|
||||||
|
|
|
||||||
|
|
@ -10,24 +10,24 @@
|
||||||
* Headings
|
* Headings
|
||||||
* -------------------------------------------------------------------------- */
|
* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
.vp-doc h1,
|
.vp-doc h1:not(:where(.not-docs *)),
|
||||||
.vp-doc h2,
|
.vp-doc h2:not(:where(.not-docs *)),
|
||||||
.vp-doc h3,
|
.vp-doc h3:not(:where(.not-docs *)),
|
||||||
.vp-doc h4,
|
.vp-doc h4:not(:where(.not-docs *)),
|
||||||
.vp-doc h5,
|
.vp-doc h5:not(:where(.not-docs *)),
|
||||||
.vp-doc h6 {
|
.vp-doc h6:not(:where(.not-docs *)) {
|
||||||
position: relative;
|
position: relative;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc h1 {
|
.vp-doc h1:not(:where(.not-docs *)) {
|
||||||
letter-spacing: -0.02em;
|
letter-spacing: -0.02em;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc h2 {
|
.vp-doc h2:not(:where(.not-docs *)) {
|
||||||
/* margin: 48px 0 16px; */
|
/* margin: 48px 0 16px; */
|
||||||
margin: 16px 0 16px;
|
margin: 16px 0 16px;
|
||||||
border-top: 1px solid var(--vp-c-divider);
|
border-top: 1px solid var(--vp-c-divider);
|
||||||
|
|
@ -37,14 +37,14 @@
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc h3 {
|
.vp-doc h3:not(:where(.not-docs *)) {
|
||||||
margin: 32px 0 0;
|
margin: 32px 0 0;
|
||||||
letter-spacing: -0.01em;
|
letter-spacing: -0.01em;
|
||||||
line-height: 28px;
|
line-height: 28px;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .header-anchor {
|
.vp-doc .header-anchor:not(:where(.not-docs *)) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
opacity 0.25s;
|
opacity 0.25s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .header-anchor:before {
|
.vp-doc .header-anchor:before:not(:where(.not-docs *)) {
|
||||||
content: var(--vp-header-anchor-symbol);
|
content: var(--vp-header-anchor-symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,14 +78,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
.vp-doc h1 {
|
.vp-doc h1:not(:where(.not-docs *)) {
|
||||||
letter-spacing: -0.02em;
|
letter-spacing: -0.02em;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc h2 .header-anchor {
|
.vp-doc h2 .header-anchor:not(:where(.not-docs *)) {
|
||||||
top: 24px;
|
top: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,30 +93,30 @@
|
||||||
* Paragraph and inline elements
|
* Paragraph and inline elements
|
||||||
* -------------------------------------------------------------------------- */
|
* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* .vp-doc p,
|
.vp-doc p:not(:where(.not-docs *)),
|
||||||
.vp-doc summary {
|
.vp-doc summary:not(:where(.not-docs *)) {
|
||||||
margin: 16px 0;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc p {
|
.vp-doc p:not(:where(.not-docs *)) {
|
||||||
line-height: 28px;
|
line-height: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc blockquote {
|
.vp-doc blockquote:not(:where(.not-docs *)) {
|
||||||
margin: 16px 0;
|
margin: 16px 0;
|
||||||
border-left: 2px solid var(--vp-c-divider);
|
border-left: 2px solid var(--vp-c-divider);
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
transition: border-color 0.5s;
|
transition: border-color 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc blockquote > p {
|
.vp-doc blockquote > p:not(:where(.not-docs *)) {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: var(--vp-c-text-2);
|
color: var(--vp-c-text-2);
|
||||||
transition: color 0.5s;
|
transition: color 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc a {
|
.vp-doc a:not(:where(.not-docs *)) {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: var(--vp-c-brand-1);
|
color: var(--vp-c-brand-1);
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
|
@ -126,38 +126,38 @@
|
||||||
opacity 0.25s;
|
opacity 0.25s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc a:hover {
|
.vp-doc a:hover:not(:where(.not-docs *)) {
|
||||||
color: var(--vp-c-brand-2);
|
color: var(--vp-c-brand-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc strong {
|
.vp-doc strong:not(:where(.not-docs *)) {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
} */
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists
|
* Lists
|
||||||
* -------------------------------------------------------------------------- */
|
* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
.vp-doc ul:not(:where(.preview *)),
|
.vp-doc ul:not(:where(.not-docs *)),
|
||||||
.vp-doc ol:not(:where(.preview *)) {
|
.vp-doc ol:not(:where(.not-docs *)) {
|
||||||
padding-left: 1.25rem;
|
padding-left: 1.25rem;
|
||||||
margin: 16px 0;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc ul:not(:where(.preview *)) {
|
.vp-doc ul:not(:where(.not-docs *)) {
|
||||||
list-style: disc;
|
list-style: disc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc ol:not(:where(.preview *)) {
|
.vp-doc ol:not(:where(.not-docs *)) {
|
||||||
list-style: decimal;
|
list-style: decimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc li + li:not(:where(.preview *)) {
|
.vp-doc li + li:not(:where(.not-docs *)) {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc li > ol:not(:where(.preview *)),
|
.vp-doc li > ol:not(:where(.not-docs *)),
|
||||||
.vp-doc li > ul:not(:where(.preview *)) {
|
.vp-doc li > ul:not(:where(.not-docs *)) {
|
||||||
margin: 8px 0 0;
|
margin: 8px 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -247,7 +247,7 @@
|
||||||
|
|
||||||
/* inline code */
|
/* inline code */
|
||||||
.vp-doc :not(pre, h1, h2, h3, h4, h5, h6) > code {
|
.vp-doc :not(pre, h1, h2, h3, h4, h5, h6) > code {
|
||||||
font-size: var(--vp-code-font-size);
|
font-size: 14px;
|
||||||
color: var(--vp-code-color);
|
color: var(--vp-code-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -343,10 +343,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc [class*='language-'] code .highlighted {
|
.vp-doc [class*='language-'] code .highlighted {
|
||||||
background-color: var(--vp-code-line-highlight-color);
|
background-color: hsl(var(--muted));
|
||||||
transition: background-color 0.5s;
|
transition: background-color 0.5s;
|
||||||
margin: 0 -24px;
|
/* margin: 0 -24px;
|
||||||
padding: 0 24px;
|
padding: 0 24px; */
|
||||||
width: calc(100% + 2 * 24px);
|
width: calc(100% + 2 * 24px);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
apps/www/src/content/docs/about.md
Normal file
20
apps/www/src/content/docs/about.md
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
title: About
|
||||||
|
description: Powered by amazing open source projects.
|
||||||
|
---
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
[shadcn-svelte](https://shadcn-svelte.com) is a port of [shadcn/ui](https://ui.shadcn.com) for Svelte/SvelteKit. It's maintained by [huntabyte](https://twitter.com/huntabyte).
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
- [shadcn](https://twitter.com/shadcn) - The brilliant mind behind the designs, methodology, and implementation of the original [shadcn/ui](https://ui.shadcn.com).
|
||||||
|
- [Radix Vue](https://radix-vue.com) - The headless components that power this project.
|
||||||
|
- [Radix UI](https://radix-ui.com) - The headless components and examples that the original [shadcn/ui](https://ui.shadcn.com) was built on.
|
||||||
|
- [Shu Ding](https://shud.in) - The typography style is adapted from his work on Nextra.
|
||||||
|
- [Cal](https://cal.com) - Where shad copied the styles for the first component: the `Button`.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT © [shadcn](https://shadcn.com) & [radix-vue](https://github.com/radix-vue)
|
||||||
3
apps/www/src/content/docs/changelog.md
Normal file
3
apps/www/src/content/docs/changelog.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
title: Changelog
|
||||||
|
---
|
||||||
101
apps/www/src/content/docs/cli.md
Normal file
101
apps/www/src/content/docs/cli.md
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
---
|
||||||
|
title: CLI
|
||||||
|
description: Use the CLI to add components to your project.
|
||||||
|
---
|
||||||
|
|
||||||
|
## init
|
||||||
|
|
||||||
|
Use the `init` command to initialize dependencies for a new project.
|
||||||
|
|
||||||
|
The `init` command installs dependencies, adds the `cn` util, configures `tailwind.config.cjs`, and creates CSS variables for the project.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx shadcn-vue@latest init
|
||||||
|
```
|
||||||
|
|
||||||
|
You will be asked a few questions to configure `components.json`:
|
||||||
|
|
||||||
|
```txt showLineNumbers
|
||||||
|
Which style would you like to use? › Default
|
||||||
|
Which color would you like to use as base color? › Slate
|
||||||
|
Where is your global CSS file? › src/app.postcss
|
||||||
|
Where is your tailwind.config.[cjs|js|ts] located? › tailwind.config.js
|
||||||
|
Configure the import alias for components: › $lib/components
|
||||||
|
Configure the import alias for utils: › $lib/utils
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```txt
|
||||||
|
Usage: shadcn-vue init [options]
|
||||||
|
|
||||||
|
initialize your project and install dependencies
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-y, --yes skip confirmation prompt. (default: false)
|
||||||
|
-c, --cwd <cwd> the working directory. (default: the current directory)
|
||||||
|
-h, --help display help for command
|
||||||
|
```
|
||||||
|
|
||||||
|
## add
|
||||||
|
|
||||||
|
Use the `add` command to add components and dependencies to your project.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx shadcn-vue@latest add [component]
|
||||||
|
```
|
||||||
|
|
||||||
|
You will be presented with a list of components to choose from:
|
||||||
|
|
||||||
|
```txt
|
||||||
|
Which components would you like to add? › Space to select. Return to submit.
|
||||||
|
|
||||||
|
◯ accordion
|
||||||
|
◯ alert
|
||||||
|
◯ alert-dialog
|
||||||
|
◯ aspect-ratio
|
||||||
|
◯ avatar
|
||||||
|
◯ badge
|
||||||
|
◯ button
|
||||||
|
◯ card
|
||||||
|
◯ checkbox
|
||||||
|
◯ collapsible
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```txt
|
||||||
|
Usage: shadcn-vue add [options] [components...]
|
||||||
|
|
||||||
|
add components to your project
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
components name of components
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--nodep disable adding & installing dependencies (advanced) (default: false)
|
||||||
|
-y, --yes Skip confirmation prompt. (default: false)
|
||||||
|
-o, --overwrite overwrite existing files. (default: false)
|
||||||
|
-c, --cwd <cwd> the working directory. (default: the current directory)
|
||||||
|
-p, --path <path> the path to add the component to.
|
||||||
|
-h, --help display help for command
|
||||||
|
```
|
||||||
|
|
||||||
|
## update
|
||||||
|
|
||||||
|
Use the `update` command to update components in your project. This will overwrite any modifications you've made to the components, so be sure to commit your changes before running this command.
|
||||||
|
|
||||||
|
We plan on improving this command in the future to improve the update experience.
|
||||||
|
|
||||||
|
```txt
|
||||||
|
Usage: shadcn-vue update [options] [components...]
|
||||||
|
|
||||||
|
update components in your project
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
components name of components
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-c, --cwd <cwd> the working directory. (default: the current directory)
|
||||||
|
-h, --help display help for command
|
||||||
|
```
|
||||||
123
apps/www/src/content/docs/components-json.md
Normal file
123
apps/www/src/content/docs/components-json.md
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
---
|
||||||
|
title: components.json
|
||||||
|
description: Configuration for your project.
|
||||||
|
---
|
||||||
|
|
||||||
|
The `components.json` file holds configuration for your project.
|
||||||
|
|
||||||
|
We use it to understand how your project is set up and how to generate components customized for your project.
|
||||||
|
|
||||||
|
<Callout class="mt-6">
|
||||||
|
Note: The <code>components.json</code> file is optional and **only required if you're
|
||||||
|
using the CLI** to add components to your project. If you're using the copy
|
||||||
|
and paste method, you don't need this file.
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
You can create a `components.json` file in your project by running the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx shadcn-svelte@latest init
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [CLI section](/docs/cli) for more information.
|
||||||
|
|
||||||
|
## $schema
|
||||||
|
|
||||||
|
You can see the JSON Schema for `components.json` [here](https://shadcn-svelte.com/schema.json).
|
||||||
|
|
||||||
|
```json title="components.json"
|
||||||
|
{
|
||||||
|
"$schema": "https://shadcn-svelte.com/schema.json"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## style
|
||||||
|
|
||||||
|
The style for your components. **This cannot be changed after initialization.**
|
||||||
|
|
||||||
|
<!-- eslint-skip -->
|
||||||
|
```json title="components.json"
|
||||||
|
{
|
||||||
|
"style": "default" | "new-york"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<ComponentPreview name="card-with-form">
|
||||||
|
|
||||||
|
<div />
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## tailwind
|
||||||
|
|
||||||
|
Configuration to help the CLI understand how Tailwind CSS is set up in your project.
|
||||||
|
|
||||||
|
See the [installation section](/docs/installation) for how to set up Tailwind CSS.
|
||||||
|
|
||||||
|
### tailwind.config
|
||||||
|
|
||||||
|
Path to where your `tailwind.config.js` file is located.
|
||||||
|
|
||||||
|
<!-- eslint-skip -->
|
||||||
|
```json title="components.json"
|
||||||
|
{
|
||||||
|
"tailwind": {
|
||||||
|
"config": "tailwind.config.js" | "tailwind.config.ts"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### tailwind.css
|
||||||
|
|
||||||
|
Path to the CSS file that imports Tailwind CSS into your project.
|
||||||
|
|
||||||
|
```json title="components.json"
|
||||||
|
{
|
||||||
|
"tailwind": {
|
||||||
|
"css": "src/app.postcss"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### tailwind.baseColor
|
||||||
|
|
||||||
|
This is used to generate the default color palette for your components. **This cannot be changed after initialization.**
|
||||||
|
|
||||||
|
<!-- eslint-skip -->
|
||||||
|
```json title="components.json"
|
||||||
|
{
|
||||||
|
"tailwind": {
|
||||||
|
"baseColor": "gray" | "neutral" | "slate" | "stone" | "zinc"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## aliases
|
||||||
|
|
||||||
|
The CLI uses these values and the `alias` config from your `svelte.config.js` file to place generated components in the correct location.
|
||||||
|
|
||||||
|
Path aliases have to be set up in your `svelte.config.js` file.
|
||||||
|
|
||||||
|
### aliases.utils
|
||||||
|
|
||||||
|
Import alias for your utility functions.
|
||||||
|
|
||||||
|
```json title="components.json"
|
||||||
|
{
|
||||||
|
"aliases": {
|
||||||
|
"utils": "$lib/utils"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### aliases.components
|
||||||
|
|
||||||
|
Import alias for your components.
|
||||||
|
|
||||||
|
```json title="components.json"
|
||||||
|
{
|
||||||
|
"aliases": {
|
||||||
|
"components": "$lib/components"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
21
apps/www/src/content/docs/figma.md
Normal file
21
apps/www/src/content/docs/figma.md
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
title: Figma
|
||||||
|
description: Every component recreated in Figma. With customizable props, typography and icons.
|
||||||
|
---
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { AspectRatio } from '@/lib/registry/default/ui/aspect-ratio';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
The Figma UI Kit is open sourced by [Pietro Schirano](https://twitter.com/skirano).
|
||||||
|
|
||||||
|
<AspectRatio :ratio="16 / 9" class="w-full mt-4">
|
||||||
|
<iframe
|
||||||
|
src="https://embed.figma.com/file/1203061493325953101/hf_embed?community_viewer=true&embed_host=shadcn&hub_file_id=1203061493325953101&kind=&viewer=1"
|
||||||
|
class="h-full w-full overflow-hidden rounded-lg border bg-muted"
|
||||||
|
/>
|
||||||
|
</AspectRatio>
|
||||||
|
|
||||||
|
## Grab a copy
|
||||||
|
|
||||||
|
https://www.figma.com/community/file/1203061493325953101
|
||||||
415
apps/www/src/content/docs/installation.md
Normal file
415
apps/www/src/content/docs/installation.md
Normal file
|
|
@ -0,0 +1,415 @@
|
||||||
|
---
|
||||||
|
title: Installation
|
||||||
|
description: How to install dependencies and structure your app.
|
||||||
|
---
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { Alert, AlertDescription } from "@/lib/registry/default/ui/alert";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
Unlike the original [shadcn/ui](https://ui.shadcn.com) for React, where the full components can exist in a single file, components in this port are split into multiple files. This is because Svelte doesn't support defining multiple components in a single file, so utilizing the CLI to add components will be the optimal approach.
|
||||||
|
|
||||||
|
The CLI will create a folder for _each_ component, which will sometimes just contain a single Svelte file, and in other times, multiple files. Within each folder, there will be an `index.ts` file that exports the component(s), so you can import them from a single file.
|
||||||
|
|
||||||
|
For example, the Accordion component is split into four `.svelte` files:
|
||||||
|
|
||||||
|
- `Accordion.svelte`
|
||||||
|
- `AccordionContent.svelte`
|
||||||
|
- `AccordionItem.svelte`
|
||||||
|
- `AccordionTrigger.svelte`
|
||||||
|
|
||||||
|
They can then be imported from the `accordion/index.ts` file like so:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import * as Accordion from '$lib/components/ui/accordion'
|
||||||
|
|
||||||
|
// or
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionContent,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionTrigger
|
||||||
|
} from '$lib/components/ui/accordion'
|
||||||
|
```
|
||||||
|
|
||||||
|
Regardless of the import approach you take, the components will be tree-shaken by Rollup, so you don't have to worry about unused components being bundled into your app.
|
||||||
|
|
||||||
|
## New Project
|
||||||
|
|
||||||
|
<Steps>
|
||||||
|
|
||||||
|
### Create project
|
||||||
|
|
||||||
|
Use the SvelteKit CLI to create a new project.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm create svelte@latest my-app
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add TailwindCSS
|
||||||
|
|
||||||
|
Use the `svelte-add` CLI to add Tailwind CSS to your project.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx svelte-add@latest tailwindcss
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install dependencies
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run the CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx shadcn-svelte@latest init
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configure components.json
|
||||||
|
|
||||||
|
You will be asked a few questions to configure `components.json`:
|
||||||
|
|
||||||
|
```txt showLineNumbers
|
||||||
|
Which style would you like to use? › Default
|
||||||
|
Which color would you like to use as base color? › Slate
|
||||||
|
Where is your global CSS file? › src/app.postcss
|
||||||
|
Where is your tailwind.config.[cjs|js|ts] located? › tailwind.config.js
|
||||||
|
Configure the import alias for components: › $lib/components
|
||||||
|
Configure the import alias for utils: › $lib/utils
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setup path aliases
|
||||||
|
|
||||||
|
If you changed the path aliases from the default, you'll also need to update your `svelte.config.js` file to include those aliases.
|
||||||
|
|
||||||
|
```js title="svelte.config.js"
|
||||||
|
const config = {
|
||||||
|
// ... other config
|
||||||
|
kit: {
|
||||||
|
// ... other config
|
||||||
|
alias: {
|
||||||
|
'$lib': './src/lib',
|
||||||
|
'$lib/*': './src/lib/*'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</Steps>
|
||||||
|
|
||||||
|
## Manual Installation
|
||||||
|
|
||||||
|
<Steps>
|
||||||
|
|
||||||
|
### Create project
|
||||||
|
|
||||||
|
Use the SvelteKit CLI to create a new project.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm create svelte@latest my-app
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Tailwind
|
||||||
|
|
||||||
|
Use the `svelte-add` CLI to add Tailwind CSS to your project.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx svelte-add@latest tailwindcss
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add dependencies
|
||||||
|
|
||||||
|
Add the following dependencies to your project:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install tailwind-variants clsx tailwind-merge
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configure tailwind.config.js
|
||||||
|
|
||||||
|
This is what this project's `tailwind.config.js` file looks like:
|
||||||
|
|
||||||
|
```javascript title="tailwind.config.js"
|
||||||
|
import { fontFamily } from "tailwindcss/defaultTheme";
|
||||||
|
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
const config = {
|
||||||
|
darkMode: ["class"],
|
||||||
|
content: ["./src/**/*.{html,js,svelte,ts}"],
|
||||||
|
theme: {
|
||||||
|
container: {
|
||||||
|
center: true,
|
||||||
|
padding: "2rem",
|
||||||
|
screens: {
|
||||||
|
"2xl": "1400px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
border: "hsl(var(--border))",
|
||||||
|
input: "hsl(var(--input))",
|
||||||
|
ring: "hsl(var(--ring))",
|
||||||
|
background: "hsl(var(--background))",
|
||||||
|
foreground: "hsl(var(--foreground))",
|
||||||
|
primary: {
|
||||||
|
DEFAULT: "hsl(var(--primary))",
|
||||||
|
foreground: "hsl(var(--primary-foreground))"
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
DEFAULT: "hsl(var(--secondary))",
|
||||||
|
foreground: "hsl(var(--secondary-foreground))"
|
||||||
|
},
|
||||||
|
destructive: {
|
||||||
|
DEFAULT: "hsl(var(--destructive))",
|
||||||
|
foreground: "hsl(var(--destructive-foreground))"
|
||||||
|
},
|
||||||
|
muted: {
|
||||||
|
DEFAULT: "hsl(var(--muted))",
|
||||||
|
foreground: "hsl(var(--muted-foreground))"
|
||||||
|
},
|
||||||
|
accent: {
|
||||||
|
DEFAULT: "hsl(var(--accent))",
|
||||||
|
foreground: "hsl(var(--accent-foreground))"
|
||||||
|
},
|
||||||
|
popover: {
|
||||||
|
DEFAULT: "hsl(var(--popover))",
|
||||||
|
foreground: "hsl(var(--popover-foreground))"
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
DEFAULT: "hsl(var(--card))",
|
||||||
|
foreground: "hsl(var(--card-foreground))"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
borderRadius: {
|
||||||
|
lg: "var(--radius)",
|
||||||
|
md: "calc(var(--radius) - 2px)",
|
||||||
|
sm: "calc(var(--radius) - 4px)"
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
sans: ["Inter", ...fontFamily.sans]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [tailwindcssAnimate]
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
|
```
|
||||||
|
|
||||||
|
Feel free to add or modify as needed to suit your project.
|
||||||
|
|
||||||
|
### Configure styles
|
||||||
|
|
||||||
|
Add the following to your `src/app.postcss` file. You can learn more about using CSS variables for theming in the [theming section](/docs/theming).
|
||||||
|
|
||||||
|
```css title="src/app.postcss"
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
:root {
|
||||||
|
--background: 0 0% 100%;
|
||||||
|
--foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--muted: 210 40% 96.1%;
|
||||||
|
--muted-foreground: 215.4 16.3% 46.9%;
|
||||||
|
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--border: 214.3 31.8% 91.4%;
|
||||||
|
--input: 214.3 31.8% 91.4%;
|
||||||
|
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--primary: 222.2 47.4% 11.2%;
|
||||||
|
--primary-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--secondary: 210 40% 96.1%;
|
||||||
|
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--accent: 210 40% 96.1%;
|
||||||
|
--accent-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--destructive: 0 92% 38%;
|
||||||
|
--destructive-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--ring: 215 20.2% 65.1%;
|
||||||
|
|
||||||
|
--radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--background: 224 71% 4%;
|
||||||
|
--foreground: 213 31% 91%;
|
||||||
|
|
||||||
|
--muted: 223 47% 11%;
|
||||||
|
--muted-foreground: 215.4 16.3% 56.9%;
|
||||||
|
|
||||||
|
--accent: 216 34% 17%;
|
||||||
|
--accent-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--popover: 224 71% 4%;
|
||||||
|
--popover-foreground: 215 20.2% 65.1%;
|
||||||
|
|
||||||
|
--border: 216 34% 17%;
|
||||||
|
--input: 216 34% 17%;
|
||||||
|
|
||||||
|
--card: 224 71% 4%;
|
||||||
|
--card-foreground: 213 31% 91%;
|
||||||
|
|
||||||
|
--primary: 210 40% 98%;
|
||||||
|
--primary-foreground: 222.2 47.4% 1.2%;
|
||||||
|
|
||||||
|
--secondary: 222.2 47.4% 11.2%;
|
||||||
|
--secondary-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--destructive: 359 51% 48%;
|
||||||
|
--destructive-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--ring: 216 34% 17%;
|
||||||
|
|
||||||
|
--radius: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
* {
|
||||||
|
@apply border-border;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
@apply bg-background text-foreground;
|
||||||
|
font-feature-settings: "rlig" 1, "calt" 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configure utils
|
||||||
|
|
||||||
|
You'll want to create a `cn` helper to make it easier to conditionally add Tailwind CSS classes. Additionally, you'll want to add the custom transition that is used by various components.
|
||||||
|
|
||||||
|
```ts title="src/lib/utils.ts"
|
||||||
|
import { type ClassValue, clsx } from 'clsx'
|
||||||
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
import { cubicOut } from 'svelte/easing'
|
||||||
|
import type { TransitionConfig } from 'svelte/transition'
|
||||||
|
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs))
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FlyAndScaleParams {
|
||||||
|
y?: number
|
||||||
|
x?: number
|
||||||
|
start?: number
|
||||||
|
duration?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function flyAndScale(node: Element,
|
||||||
|
params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }): TransitionConfig {
|
||||||
|
const style = getComputedStyle(node)
|
||||||
|
const transform = style.transform === 'none' ? '' : style.transform
|
||||||
|
|
||||||
|
const scaleConversion = (
|
||||||
|
valueA: number,
|
||||||
|
scaleA: [number, number],
|
||||||
|
scaleB: [number, number]
|
||||||
|
) => {
|
||||||
|
const [minA, maxA] = scaleA
|
||||||
|
const [minB, maxB] = scaleB
|
||||||
|
|
||||||
|
const percentage = (valueA - minA) / (maxA - minA)
|
||||||
|
const valueB = percentage * (maxB - minB) + minB
|
||||||
|
|
||||||
|
return valueB
|
||||||
|
}
|
||||||
|
|
||||||
|
const styleToString = (
|
||||||
|
style: Record<string, number | string | undefined>
|
||||||
|
): string => {
|
||||||
|
return Object.keys(style).reduce((str, key) => {
|
||||||
|
if (style[key] === undefined)
|
||||||
|
return str
|
||||||
|
return `${str + key}:${style[key]};`
|
||||||
|
}, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
duration: params.duration ?? 200,
|
||||||
|
delay: 0,
|
||||||
|
css: (t) => {
|
||||||
|
const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0])
|
||||||
|
const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0])
|
||||||
|
const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1])
|
||||||
|
|
||||||
|
return styleToString({
|
||||||
|
transform:
|
||||||
|
`${transform
|
||||||
|
}translate3d(${
|
||||||
|
x
|
||||||
|
}px, ${
|
||||||
|
y
|
||||||
|
}px, 0) scale(${
|
||||||
|
scale
|
||||||
|
})`,
|
||||||
|
opacity: t
|
||||||
|
})
|
||||||
|
},
|
||||||
|
easing: cubicOut
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Import styles to your app
|
||||||
|
|
||||||
|
Create `src/routes/+layout.svelte` and import the styles:
|
||||||
|
|
||||||
|
```svelte title="src/routes/+layout.svelte"
|
||||||
|
<script lang="ts">
|
||||||
|
import "../app.postcss";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<slot />
|
||||||
|
```
|
||||||
|
|
||||||
|
</Steps>
|
||||||
|
|
||||||
|
## Icons
|
||||||
|
|
||||||
|
This project uses icons from [Lucide](https://lucide.dev/) for the `default` style, and [Radix](https://radix-ui.com/icons) for the `new-york` style, but feel free to use any icon library.
|
||||||
|
|
||||||
|
## App structure
|
||||||
|
|
||||||
|
Here's a recommended, but not required app structure:
|
||||||
|
|
||||||
|
```txt {4-11,15,19}
|
||||||
|
src
|
||||||
|
├── lib
|
||||||
|
│ ├── components
|
||||||
|
│ │ ├── ui
|
||||||
|
│ │ │ ├── alert-dialog
|
||||||
|
│ │ │ │ ├── index.ts
|
||||||
|
│ │ │ │ └── alert.svelte
|
||||||
|
│ │ │ ├── button
|
||||||
|
│ │ │ │ ├── index.ts
|
||||||
|
│ │ │ │ └── button.svelte
|
||||||
|
│ │ │ └── ...
|
||||||
|
│ │ ├── navigation.svelte
|
||||||
|
│ │ ├── page-header.svelte
|
||||||
|
│ │ └── ...
|
||||||
|
│ └── utils.ts
|
||||||
|
├── routes
|
||||||
|
│ ├── +page.svelte
|
||||||
|
│ └── +layout.svelte
|
||||||
|
├── app.postcss
|
||||||
|
```
|
||||||
|
|
||||||
|
- Place the UI components in the `lib/components/ui` folder.
|
||||||
|
- The rest of the components such as `<PageHeader />` and `<Navigation />` are placed in the `lib/components` folder.
|
||||||
|
- The `lib/utils.ts` file is where you can define the `cn` helper.
|
||||||
|
- The `app.postcss` file contains the global CSS.
|
||||||
|
|
||||||
|
That's it. You can now start adding components to your project.
|
||||||
63
apps/www/src/content/docs/introduction.md
Normal file
63
apps/www/src/content/docs/introduction.md
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
---
|
||||||
|
title: Introduction
|
||||||
|
description: Re-usable components built with Radix Vue, and Tailwind CSS.
|
||||||
|
---
|
||||||
|
|
||||||
|
<script setup >
|
||||||
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/lib/registry/default/ui/accordion'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
An unofficial, community-led [Vue](https://vuejs.org/) port of [shadcn/ui](https://ui.shadcn.com). We are not affiliated with [shadcn](https://twitter.com/shadcn), but we did get his blessing before creating a Vue version of his work. This project was born out of the need for a similar project for the Vue ecosystem.
|
||||||
|
|
||||||
|
This is **NOT** a component library. It's a collection of re-usable components that you can copy and paste or use the CLI to add to your apps.
|
||||||
|
|
||||||
|
**What do you mean not a component library?**
|
||||||
|
|
||||||
|
It means you do not install it as a dependency. It is not available or distributed via npm, with no plans to publish it.
|
||||||
|
|
||||||
|
Pick the components you need. Use the CLI to automatically add the components, or copy and paste the code into your project and customize to your needs. The code is yours.
|
||||||
|
|
||||||
|
_Use this as a reference to build your own component libraries._
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
|
||||||
|
<AccordionRoot multiple>
|
||||||
|
|
||||||
|
<AccordionItem value="faq-1">
|
||||||
|
<AccordionTrigger>
|
||||||
|
|
||||||
|
Why not packaged as a dependency?
|
||||||
|
|
||||||
|
</AccordionTrigger>
|
||||||
|
<AccordionContent>
|
||||||
|
|
||||||
|
The idea behind this is to give you ownership and control over the code, allowing you to decide how the components are built and styled.
|
||||||
|
|
||||||
|
Start with some sensible defaults, then customize the components to your needs.
|
||||||
|
|
||||||
|
One of the drawback of packaging the components in an npm package is that the style is coupled with the implementation. _The design of your components should be separate from their implementation._
|
||||||
|
|
||||||
|
</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
<AccordionItem value="faq-2">
|
||||||
|
<AccordionTrigger>
|
||||||
|
Which frameworks are supported?
|
||||||
|
</AccordionTrigger>
|
||||||
|
<AccordionContent>
|
||||||
|
|
||||||
|
This port is built to be used with Vue/Nuxt.
|
||||||
|
|
||||||
|
</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
<AccordionItem value="faq-3">
|
||||||
|
<AccordionTrigger>
|
||||||
|
Can I use this in my project?
|
||||||
|
</AccordionTrigger>
|
||||||
|
<AccordionContent>
|
||||||
|
Yes. Free to use for personal and commercial projects. No attribution required.
|
||||||
|
|
||||||
|
But let us know if you do use it. We'd love to see what you build with it.
|
||||||
|
</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
</AccordionRoot>
|
||||||
184
apps/www/src/content/docs/theming.md
Normal file
184
apps/www/src/content/docs/theming.md
Normal file
|
|
@ -0,0 +1,184 @@
|
||||||
|
---
|
||||||
|
title: Theming
|
||||||
|
description: Use CSS Variables to customize the look and feel of your application.
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
We use CSS variables for styling. This allows you to easily change the colors of components without having to update class names.
|
||||||
|
|
||||||
|
**CSS variables must be defined without the color space function**. See the [Tailwind CSS documentation](https://tailwindcss.com/docs/customizing-colors#using-css-variables) for more information.
|
||||||
|
|
||||||
|
## Hex -> Color Channel
|
||||||
|
|
||||||
|
You can use this tool to convert your HEX color to HSL without the color space function. Simply add your color in hex format, copy one of the generated values, then add them to the CSS variable.
|
||||||
|
|
||||||
|
<!-- <HexToChannels /> -->
|
||||||
|
|
||||||
|
## Convention
|
||||||
|
|
||||||
|
We use a simple `background` and `foreground` convention for colors. The `background` variable is used for the background color of the component and the `foreground` variable is used for the text color.
|
||||||
|
|
||||||
|
<Callout>
|
||||||
|
|
||||||
|
The `background` suffix can be omitted if the variable is used for the background color of the component.
|
||||||
|
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
Given the following CSS variables:
|
||||||
|
|
||||||
|
```css
|
||||||
|
--primary: 222.2 47.4% 11.2%;
|
||||||
|
--primary-foreground: 210 40% 98%;
|
||||||
|
```
|
||||||
|
|
||||||
|
The `background` color of the following component will be `hsl(var(--primary))` and the `foreground` color will be `hsl(var(--primary-foreground))`.
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<div class="bg-primary text-primary-foreground">Hello</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
## CSS Variables
|
||||||
|
|
||||||
|
Here's the list of variables available for customization:
|
||||||
|
|
||||||
|
```css title="Default background color of <body />...etc"
|
||||||
|
--background: 0 0% 100%;
|
||||||
|
--foreground: 222.2 47.4% 11.2%;
|
||||||
|
```
|
||||||
|
|
||||||
|
```css title="Muted backgrounds such as <TabsList />, <Skeleton /> and <Switch />"
|
||||||
|
--muted: 210 40% 96.1%;
|
||||||
|
--muted-foreground: 215.4 16.3% 46.9%;
|
||||||
|
```
|
||||||
|
|
||||||
|
```css title="Background color for <Card />"
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 222.2 47.4% 11.2%;
|
||||||
|
```
|
||||||
|
|
||||||
|
```css title="Background color for popovers such as <DropdownMenu />, <HoverCard />, <Popover />"
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 222.2 47.4% 11.2%;
|
||||||
|
```
|
||||||
|
|
||||||
|
```css title="Default border color"
|
||||||
|
--border: 214.3 31.8% 91.4%;
|
||||||
|
```
|
||||||
|
|
||||||
|
```css title="Border color for inputs such as <Input />, <Select />, <Textarea />"
|
||||||
|
--input: 214.3 31.8% 91.4%;
|
||||||
|
```
|
||||||
|
|
||||||
|
```css title="Primary colors for <Button />"
|
||||||
|
--primary: 222.2 47.4% 11.2%;
|
||||||
|
--primary-foreground: 210 40% 98%;
|
||||||
|
```
|
||||||
|
|
||||||
|
```css title="Secondary colors for <Button />"
|
||||||
|
--secondary: 210 40% 96.1%;
|
||||||
|
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||||
|
```
|
||||||
|
|
||||||
|
```css title="Used for accents such as hover effects on <DropdownMenuItem>, <SelectItem>...etc"
|
||||||
|
--accent: 210 40% 96.1%;
|
||||||
|
--accent-foreground: 222.2 47.4% 11.2%;
|
||||||
|
```
|
||||||
|
|
||||||
|
```css title="Used for destructive actions such as <Button variant='destructive'>"
|
||||||
|
--destructive: 0 100% 50%;
|
||||||
|
--destructive-foreground: 210 40% 98%;
|
||||||
|
```
|
||||||
|
|
||||||
|
```css title="Used for focus ring"
|
||||||
|
--ring: 215 20.2% 65.1%;
|
||||||
|
```
|
||||||
|
|
||||||
|
```css title="Border radius for card, input and buttons"
|
||||||
|
--radius: 0.5rem;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Default
|
||||||
|
|
||||||
|
The following is the default color palette used by the components.
|
||||||
|
|
||||||
|
```css title="src/app.postcss"
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
:root {
|
||||||
|
--background: 0 0% 100%;
|
||||||
|
--foreground: 240 10% 3.9%;
|
||||||
|
|
||||||
|
--muted: 240 4.8% 95.9%;
|
||||||
|
--muted-foreground: 240 3.8% 46.1%;
|
||||||
|
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 240 10% 3.9%;
|
||||||
|
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 240 10% 3.9%;
|
||||||
|
|
||||||
|
--border: 240 5.9% 90%;
|
||||||
|
--input: 240 5.9% 90%;
|
||||||
|
|
||||||
|
--primary: 240 5.9% 10%;
|
||||||
|
--primary-foreground: 0 0% 98%;
|
||||||
|
|
||||||
|
--secondary: 240 4.8% 95.9%;
|
||||||
|
--secondary-foreground: 240 5.9% 10%;
|
||||||
|
|
||||||
|
--accent: 240 4.8% 95.9%;
|
||||||
|
--accent-foreground: 240 5.9% 10%;
|
||||||
|
|
||||||
|
--destructive: 0 84.2% 60.2%;
|
||||||
|
--destructive-foreground: 0 0% 98%;
|
||||||
|
|
||||||
|
--ring: 240 5% 64.9%;
|
||||||
|
|
||||||
|
--radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--background: 240 10% 3.9%;
|
||||||
|
--foreground: 0 0% 98%;
|
||||||
|
|
||||||
|
--muted: 240 3.7% 15.9%;
|
||||||
|
--muted-foreground: 240 5% 64.9%;
|
||||||
|
|
||||||
|
--popover: 240 10% 3.9%;
|
||||||
|
--popover-foreground: 0 0% 98%;
|
||||||
|
|
||||||
|
--card: 240 10% 3.9%;
|
||||||
|
--card-foreground: 0 0% 98%;
|
||||||
|
|
||||||
|
--border: 240 3.7% 15.9%;
|
||||||
|
--input: 240 3.7% 15.9%;
|
||||||
|
|
||||||
|
--primary: 0 0% 98%;
|
||||||
|
--primary-foreground: 240 5.9% 10%;
|
||||||
|
|
||||||
|
--secondary: 240 3.7% 15.9%;
|
||||||
|
--secondary-foreground: 0 0% 98%;
|
||||||
|
|
||||||
|
--accent: 240 3.7% 15.9%;
|
||||||
|
--accent-foreground: 0 0% 98%;
|
||||||
|
|
||||||
|
--destructive: 0 62.8% 30.6%;
|
||||||
|
--destructive-foreground: 0 85.7% 97.3%;
|
||||||
|
|
||||||
|
--ring: 240 3.7% 15.9%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
* {
|
||||||
|
@apply border-border;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
@apply bg-background text-foreground;
|
||||||
|
font-feature-settings: "rlig" 1, "calt" 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
115
apps/www/src/content/docs/typography.md
Normal file
115
apps/www/src/content/docs/typography.md
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
---
|
||||||
|
title: Typography
|
||||||
|
description: Styles for headings, paragraphs, lists...etc
|
||||||
|
component: true
|
||||||
|
---
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyDemo">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## h1
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyH1">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## h2
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyH2">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## h3
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyH3">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## h4
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyH4">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## p
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyP">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## blockquote
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyBlockquote">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## table
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyTable">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## list
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyList">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## Inline code
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyInlineCode">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## Lead
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyLead">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## Large
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyLarge">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## Small
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographySmall">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
||||||
|
## Muted
|
||||||
|
|
||||||
|
<ComponentPreview name="TypographyMuted">
|
||||||
|
|
||||||
|
<div/>
|
||||||
|
|
||||||
|
</ComponentPreview>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<template>
|
||||||
|
<blockquote class="mt-6 border-l-2 pl-6 italic">
|
||||||
|
"After all," he said, "everyone enjoys a good joke, so it's only fair that
|
||||||
|
they should pay for the privilege."
|
||||||
|
</blockquote>
|
||||||
|
</template>
|
||||||
136
apps/www/src/lib/registry/default/examples/TypographyDemo.vue
Normal file
136
apps/www/src/lib/registry/default/examples/TypographyDemo.vue
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1 class="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
|
||||||
|
The Joke Tax Chronicles
|
||||||
|
</h1>
|
||||||
|
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||||
|
Once upon a time, in a far-off land, there was a very lazy king who
|
||||||
|
spent all day lounging on his throne. One day, his advisors came to him
|
||||||
|
with a problem: the kingdom was running out of money.
|
||||||
|
</p>
|
||||||
|
<h2
|
||||||
|
class="mt-10 scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0"
|
||||||
|
>
|
||||||
|
The King's Plan
|
||||||
|
</h2>
|
||||||
|
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||||
|
The king thought long and hard, and finally came up with{" "}
|
||||||
|
<!-- svelte-ignore a11y-invalid-attribute -->
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
class="font-medium text-primary underline underline-offset-4"
|
||||||
|
>
|
||||||
|
a brilliant plan
|
||||||
|
</a>
|
||||||
|
: he would tax the jokes in the kingdom.
|
||||||
|
</p>
|
||||||
|
<blockquote class="mt-6 border-l-2 pl-6 italic">
|
||||||
|
"After all," he said, "everyone enjoys a good joke, so it's only fair
|
||||||
|
that they should pay for the privilege."
|
||||||
|
</blockquote>
|
||||||
|
<h3 class="mt-8 scroll-m-20 text-2xl font-semibold tracking-tight">
|
||||||
|
The Joke Tax
|
||||||
|
</h3>
|
||||||
|
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||||
|
The king's subjects were not amused. They grumbled and complained, but
|
||||||
|
the king was firm:
|
||||||
|
</p>
|
||||||
|
<ul class="my-6 ml-6 list-disc [&>li]:mt-2">
|
||||||
|
<li>1st level of puns: 5 gold coins</li>
|
||||||
|
<li>2nd level of jokes: 10 gold coins</li>
|
||||||
|
<li>3rd level of one-liners : 20 gold coins</li>
|
||||||
|
</ul>
|
||||||
|
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||||
|
As a result, people stopped telling jokes, and the kingdom fell into a
|
||||||
|
gloom. But there was one person who refused to let the king's
|
||||||
|
foolishness get him down: a court jester named Jokester.
|
||||||
|
</p>
|
||||||
|
<h3 class="mt-8 scroll-m-20 text-2xl font-semibold tracking-tight">
|
||||||
|
Jokester's Revolt
|
||||||
|
</h3>
|
||||||
|
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||||
|
Jokester began sneaking into the castle in the middle of the night and
|
||||||
|
leaving jokes all over the place: under the king's pillow, in his soup,
|
||||||
|
even in the royal toilet. The king was furious, but he couldn't seem to
|
||||||
|
stop Jokester.
|
||||||
|
</p>
|
||||||
|
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||||
|
And then, one day, the people of the kingdom discovered that the jokes
|
||||||
|
left by Jokester were so funny that they couldn't help but laugh. And
|
||||||
|
once they started laughing, they couldn't stop.
|
||||||
|
</p>
|
||||||
|
<h3 class="mt-8 scroll-m-20 text-2xl font-semibold tracking-tight">
|
||||||
|
The People's Rebellion
|
||||||
|
</h3>
|
||||||
|
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||||
|
The people of the kingdom, feeling uplifted by the laughter, started to
|
||||||
|
tell jokes and puns again, and soon the entire kingdom was in on the
|
||||||
|
joke.
|
||||||
|
</p>
|
||||||
|
<div class="my-6 w-full overflow-y-auto">
|
||||||
|
<table class="w-full">
|
||||||
|
<thead>
|
||||||
|
<tr class="m-0 border-t p-0 even:bg-muted">
|
||||||
|
<th
|
||||||
|
class="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
King's Treasury
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
People's happiness
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr class="m-0 border-t p-0 even:bg-muted">
|
||||||
|
<td
|
||||||
|
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
Empty
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
Overflowing
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="m-0 border-t p-0 even:bg-muted">
|
||||||
|
<td
|
||||||
|
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
Modest
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
Satisfied
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="m-0 border-t p-0 even:bg-muted">
|
||||||
|
<td
|
||||||
|
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
Full
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
Ecstatic
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||||
|
The king, seeing how much happier his subjects were, realized the error
|
||||||
|
of his ways and repealed the joke tax. Jokester was declared a hero, and
|
||||||
|
the kingdom lived happily ever after.
|
||||||
|
</p>
|
||||||
|
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||||
|
The moral of the story is: never underestimate the power of a good laugh
|
||||||
|
and always be careful of bad ideas.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<template>
|
||||||
|
<h1 class="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
|
||||||
|
Taxing Laughter: The Joke Tax Chronicles
|
||||||
|
</h1>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<h2
|
||||||
|
class="scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0"
|
||||||
|
>
|
||||||
|
The People of the Kingdom
|
||||||
|
</h2>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<template>
|
||||||
|
<h3 class="scroll-m-20 text-2xl font-semibold tracking-tight">
|
||||||
|
The Joke Tax
|
||||||
|
</h3>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<template>
|
||||||
|
<h4 class="scroll-m-20 text-xl font-semibold tracking-tight">
|
||||||
|
People stopped telling jokes
|
||||||
|
</h4>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<code
|
||||||
|
class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold"
|
||||||
|
>
|
||||||
|
radix-vue
|
||||||
|
</code>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<template>
|
||||||
|
<div class="text-lg font-semibold">
|
||||||
|
Are you sure absolutely sure?
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<template>
|
||||||
|
<p class="text-xl text-muted-foreground">
|
||||||
|
A modal dialog that interrupts the user with important content and expects a
|
||||||
|
response.
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<ul class="my-6 ml-6 list-disc [&>li]:mt-2">
|
||||||
|
<li>1st level of puns: 5 gold coins</li>
|
||||||
|
<li>2nd level of jokes: 10 gold coins</li>
|
||||||
|
<li>3rd level of one-liners : 20 gold coins</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<template>
|
||||||
|
<p class="text-sm text-muted-foreground">
|
||||||
|
Enter your email address.
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<template>
|
||||||
|
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||||
|
The king, seeing how much happier his subjects were, realized the error of
|
||||||
|
his ways and repealed the joke tax.
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<template>
|
||||||
|
<small class="text-sm font-medium leading-none">
|
||||||
|
Email address
|
||||||
|
</small>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
<template>
|
||||||
|
<div class="my-6 w-full overflow-y-auto">
|
||||||
|
<table class="w-full">
|
||||||
|
<thead>
|
||||||
|
<tr class="m-0 border-t p-0 even:bg-muted">
|
||||||
|
<th
|
||||||
|
class="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
King's Treasury
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
People's happiness
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr class="m-0 border-t p-0 even:bg-muted">
|
||||||
|
<td
|
||||||
|
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
Empty
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
Overflowing
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="m-0 border-t p-0 even:bg-muted">
|
||||||
|
<td
|
||||||
|
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
Modest
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
Satisfied
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="m-0 border-t p-0 even:bg-muted">
|
||||||
|
<td
|
||||||
|
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
Full
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||||
|
>
|
||||||
|
Ecstatic
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {
|
import {
|
||||||
AccordionRoot,
|
AccordionRoot,
|
||||||
|
type AccordionRootEmits,
|
||||||
type AccordionRootProps,
|
type AccordionRootProps,
|
||||||
} from 'radix-vue'
|
} from 'radix-vue'
|
||||||
|
import { useEmitAsProps } from '@/lib/utils'
|
||||||
|
|
||||||
const props = defineProps<AccordionRootProps>()
|
const props = defineProps<AccordionRootProps>()
|
||||||
|
const emits = defineEmits<AccordionRootEmits>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<AccordionRoot v-bind="props" class="accordion">
|
<AccordionRoot v-bind="{ ...props, ...useEmitAsProps(emits) }">
|
||||||
<slot />
|
<slot />
|
||||||
</AccordionRoot>
|
</AccordionRoot>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const props = defineProps<AccordionContentProps & { class?: string }>()
|
||||||
v-bind="props"
|
v-bind="props"
|
||||||
:class="
|
:class="
|
||||||
cn(
|
cn(
|
||||||
'overflow-hidden text-sm transition-all data-[state=open]:animate-accordion-down data-[state=closed]:animate-accordion-up',
|
'overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down',
|
||||||
props.class,
|
props.class,
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const props = defineProps<AccordionItemProps & { class?: string }>()
|
||||||
<template>
|
<template>
|
||||||
<AccordionItem
|
<AccordionItem
|
||||||
v-bind="props"
|
v-bind="props"
|
||||||
:class="cn('border-b text-foreground border-border', props.class ?? '')"
|
:class="cn('border-b', props.class ?? '')"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,14 @@ const props = defineProps<AccordionTriggerProps & { class?: string }>()
|
||||||
v-bind="props"
|
v-bind="props"
|
||||||
:class="
|
:class="
|
||||||
cn(
|
cn(
|
||||||
'flex flex-1 group items-center justify-between py-4 font-medium transition-all hover:underline',
|
'flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
|
||||||
props.class,
|
props.class,
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
<ChevronDown
|
<ChevronDown
|
||||||
class="w-4 h-4 shrink-0 transition-transform duration-300 group-data-[state=open]:rotate-180"
|
class="h-4 w-4 shrink-0 transition-transform duration-200"
|
||||||
/>
|
/>
|
||||||
</AccordionTrigger>
|
</AccordionTrigger>
|
||||||
</AccordionHeader>
|
</AccordionHeader>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user