Skip to content

Commit

Permalink
feat(components): tabs
Browse files Browse the repository at this point in the history
Signed-off-by: ZTL-UwU <[email protected]>
  • Loading branch information
ZTL-UwU committed Jun 3, 2024
1 parent 19b6517 commit c06384a
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 119 deletions.
110 changes: 45 additions & 65 deletions components/content/CodeGroup.vue
Original file line number Diff line number Diff line change
@@ -1,73 +1,53 @@
<template>
<render class="[&:not(:first-child)]:mt-5" />
<UiCard class="[&:not(:first-child)]:mt-5">
<UiScrollArea>
<div class="border-b p-0.5 flex text-sm relative overflow-x-auto">
<div class="flex p-1">
<div
v-for="(slot, i) in ($slots.default?.() ?? [])"
:key="`${i}${slot?.props?.filename}`"
:value="slot?.props?.filename"
class="flex px-3 py-1.5 rounded-md text-muted-foreground transition-all duration-75 cursor-pointer"
:class="[activeTabIndex === i && 'bg-muted text-primary']"
@mousedown.left="activeTabIndex = i"
>
<Icon
v-if="getIcon(slot?.props?.filename, slot?.props?.language)"
:name="getIcon(slot?.props?.filename, slot?.props?.language)!"
class="self-center mr-1.5"
/>
{{ slot?.props?.filename }}
</div>
</div>
<CodeCopy
v-if="selected?.props?.code && selected?.type !== 'preview'"
class="self-center ml-auto mr-3 pl-2"
:code="selected.props.code"
/>
</div>
<ScrollBar orientation="horizontal" />
</UiScrollArea>

<div
v-for="(slot, i) in $slots.default?.() ?? []"
v-show="activeTabIndex === i"
:key="`${i}${slot?.props?.filename}`"
:value="slot?.props?.filename"
class="mt-0"
>
<component :is="slot" :in-group="true" />
</div>
</UiCard>
</template>

<script setup lang="ts">
import CodeGroupHeader from './CodeGroupHeader.vue';
import { Card as UiCard } from '@/components/ui/card/index';
const _slots = useSlots();
const activeTabIndex = ref(0);
const selected = computed(() => {
return useSlots().default?.()[activeTabIndex.value];
});
function isTag(slot: any, tag: string) {
return slot.type && slot.type.tag && slot.type.tag === tag;
}
function checkTag(slot: any) {
return isTag(slot, 'code-block') || isTag(slot, 'code') || isTag(slot, 'pre') || isTag(slot, 'preview');
}
function onChangeActiveTab(index: number) {
activeTabIndex.value = index;
}
function render() {
const _slotsDefault = _slots?.default?.() || [];
const tabs = _slotsDefault
.filter(slot => checkTag(slot))
.map((slot, index) => {
return {
label: slot?.props?.filename || slot?.props?.label || `${index}`,
language: slot?.props?.language || null,
code: slot?.props?.code || '',
};
});
return h(
UiCard,
() => [
h(
CodeGroupHeader,
{
'activeTabIndex': activeTabIndex.value,
tabs,
'onUpdate:activeTabIndex': onChangeActiveTab,
},
),
h(
'div',
_slotsDefault.map((slot, index) => {
if (slot.props && checkTag(slot))
slot.props.inGroup = true;
return h(
'div',
{
style: {
display: index === activeTabIndex.value ? 'block' : 'none',
},
},
[
checkTag(slot)
? slot
: h(
'div',
[(slot.children as any)?.default?.() || h('div')],
),
],
);
}),
),
],
);
const iconMap = new Map(Object.entries(useConfig().value.main.codeIcon));
function getIcon(filename: string, language: string) {
return iconMap.get(filename?.toLowerCase()) || iconMap.get(language);
}
</script>
49 changes: 0 additions & 49 deletions components/content/CodeGroupHeader.vue

This file was deleted.

2 changes: 1 addition & 1 deletion components/content/Preview.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="p-3 bg-muted/20">
<div class="p-3">
<slot />
</div>
</template>
Expand Down
2 changes: 1 addition & 1 deletion components/content/ProseCode.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<UiCard
class="[&:not(:first-child)]:mt-5 mb-5 overflow-hidden"
class="[&:not(:first-child)]:mt-5 [&:not(:last-child)]:mb-5 overflow-hidden"
:class="[inGroup && 'rounded-t-none border-none mb-0']"
>
<div v-if="!inGroup && filename" class="p-3 border-b flex text-sm font-mono">
Expand Down
25 changes: 25 additions & 0 deletions components/content/Tabs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<template>
<UiTabs
class="[&:not(:first-child)]:mt-5"
:default-value="($slots.default?.() ?? [])[0]?.props?.label"
>
<UiTabsList>
<UiTabsTrigger
v-for="(slot, i) in $slots.default?.() ?? []"
:key="`${i}${slot?.props?.label}`"
:value="slot?.props?.label"
>
<Icon v-if="slot?.props?.icon" :name="slot?.props?.icon" class="mr-1" />
{{ slot?.props?.label }}
</UiTabsTrigger>
</UiTabsList>

<UiTabsContent
v-for="(slot, i) in $slots.default?.() ?? []"
:key="`${i}${slot?.props?.label}`"
:value="slot?.props?.label"
>
<component :is="slot" />
</UiTabsContent>
</UiTabs>
</template>
2 changes: 1 addition & 1 deletion components/ui/tabs/TabsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<TabsList
v-bind="delegatedProps"
:class="cn(
'inline-flex h-10 items-center justify-center rounded-md p-1 text-muted-foreground',
'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',
props.class,
)"
>
Expand Down
2 changes: 1 addition & 1 deletion components/ui/tabs/TabsTrigger.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<TabsTrigger
v-bind="forwardedProps"
:class="cn(
'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-muted data-[state=active]:text-foreground',
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm',
props.class,
)"
>
Expand Down
93 changes: 93 additions & 0 deletions content/1.getting-started/3.writing/2.components.md
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,99 @@ npm i -D @iconify-json/collection-name
```
::

### Tabs

:badge[Nuxt UI Pro]{variant="outline" to="https://ui.nuxt.com/pro/prose/tabs" target="_blank"}

::code-group
::preview{filename="Preview"}
::tabs
::div{label="PostgreSQL" icon="lucide:database"}
### PostgreSQL column types

```ts
import { integer, pgTable } from 'drizzle-orm/pg-core';

export const table = pgTable('table', {
int: integer('int')
});
```
::
::div{label="MySQL"}
### MySQL column types

```ts
import { int, mysqlTable } from 'drizzle-orm/mysql-core';

const table = mysqlTable('table', {
int: int('int')
});
```
::
::div{label="SQLite"}
### SQLite column types

```ts
import { integer, sqliteTable } from 'drizzle-orm/sqlite-core';

const table = sqliteTable('table', {
id: integer('id')
});

// you can customize integer mode to be number, boolean, timestamp, timestamp_ms
integer('id', { mode: 'number' });
integer('id', { mode: 'boolean' });
integer('id', { mode: 'timestamp_ms' });
integer('id', { mode: 'timestamp' }); // Date
```
::
::
::
```mdc [Code]
::tabs
::div{label="PostgreSQL" icon="lucide:database"}
### PostgreSQL column types
```ts
import { integer, pgTable } from 'drizzle-orm/pg-core';
export const table = pgTable('table', {
int: integer('int')
});
```
::
::div{label="MySQL"}
### MySQL column types
```ts
import { int, mysqlTable } from 'drizzle-orm/mysql-core';
const table = mysqlTable('table', {
int: int('int')
});
```
::
::div{label="SQLite"}
### SQLite column types
```ts
import { integer, sqliteTable } from 'drizzle-orm/sqlite-core';
const table = sqliteTable('table', {
id: integer('id')
});
// you can customize integer mode to be number, boolean, timestamp, timestamp_ms
integer('id', { mode: 'number' });
integer('id', { mode: 'boolean' });
integer('id', { mode: 'timestamp_ms' });
integer('id', { mode: 'timestamp' }); // Date
```
::
::
```
::

## Landing Page Components

### Hero
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "shadcn-docs-nuxt",
"type": "module",
"version": "0.1.1",
"version": "0.1.2",
"author": "Tony Zhang <[email protected]>",
"license": "MIT",
"homepage": "https://shadcn-docs-nuxt.vercel.app/",
Expand Down

0 comments on commit c06384a

Please sign in to comment.