feat: resizable (splitter)
This commit is contained in:
parent
27fae5c24c
commit
4ffce6c3e7
|
|
@ -275,6 +275,12 @@ export const docsConfig: DocsConfig = {
|
||||||
href: '/docs/components/radio-group',
|
href: '/docs/components/radio-group',
|
||||||
items: [],
|
items: [],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Resizable',
|
||||||
|
href: '/docs/components/resizable',
|
||||||
|
label: 'New',
|
||||||
|
items: [],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'Scroll Area',
|
title: 'Scroll Area',
|
||||||
href: '/docs/components/scroll-area',
|
href: '/docs/components/scroll-area',
|
||||||
|
|
|
||||||
|
|
@ -556,6 +556,27 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/default/example/RangePickerWithSlot.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/default/example/RangePickerWithSlot.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/default/example/RangePickerWithSlot.vue"],
|
files: ["../src/lib/registry/default/example/RangePickerWithSlot.vue"],
|
||||||
},
|
},
|
||||||
|
"ResizableDemo": {
|
||||||
|
name: "ResizableDemo",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["resizable"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/ResizableDemo.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/ResizableDemo.vue"],
|
||||||
|
},
|
||||||
|
"ResizableHandleDemo": {
|
||||||
|
name: "ResizableHandleDemo",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["resizable"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/ResizableHandleDemo.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/ResizableHandleDemo.vue"],
|
||||||
|
},
|
||||||
|
"ResizableVerticalDemo": {
|
||||||
|
name: "ResizableVerticalDemo",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["resizable"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/ResizableVerticalDemo.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/ResizableVerticalDemo.vue"],
|
||||||
|
},
|
||||||
"ScrollAreaDemo": {
|
"ScrollAreaDemo": {
|
||||||
name: "ScrollAreaDemo",
|
name: "ScrollAreaDemo",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
@ -1509,6 +1530,27 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/new-york/example/RangePickerWithSlot.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/new-york/example/RangePickerWithSlot.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/new-york/example/RangePickerWithSlot.vue"],
|
files: ["../src/lib/registry/new-york/example/RangePickerWithSlot.vue"],
|
||||||
},
|
},
|
||||||
|
"ResizableDemo": {
|
||||||
|
name: "ResizableDemo",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["resizable"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/ResizableDemo.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/ResizableDemo.vue"],
|
||||||
|
},
|
||||||
|
"ResizableHandleDemo": {
|
||||||
|
name: "ResizableHandleDemo",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["resizable"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/ResizableHandleDemo.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/ResizableHandleDemo.vue"],
|
||||||
|
},
|
||||||
|
"ResizableVerticalDemo": {
|
||||||
|
name: "ResizableVerticalDemo",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["resizable"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/ResizableVerticalDemo.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/ResizableVerticalDemo.vue"],
|
||||||
|
},
|
||||||
"ScrollAreaDemo": {
|
"ScrollAreaDemo": {
|
||||||
name: "ScrollAreaDemo",
|
name: "ScrollAreaDemo",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
|
||||||
105
apps/www/src/content/docs/components/resizable.md
Normal file
105
apps/www/src/content/docs/components/resizable.md
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
---
|
||||||
|
title: Resizable
|
||||||
|
description: Accessible resizable panel groups and layouts with keyboard support.
|
||||||
|
source: apps/www/src/lib/registry/default/ui/resizable
|
||||||
|
primitive: https://www.radix-vue.com/components/splitter.html
|
||||||
|
---
|
||||||
|
|
||||||
|
<ComponentPreview name="ResizableDemo" />
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
<TabPreview name="CLI">
|
||||||
|
<template #CLI>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx shadcn-vue@latest add resizable
|
||||||
|
```
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #Manual>
|
||||||
|
|
||||||
|
<Steps>
|
||||||
|
|
||||||
|
### Install the following dependency:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install radix-vue
|
||||||
|
```
|
||||||
|
|
||||||
|
### Copy and paste the following code into your project:
|
||||||
|
|
||||||
|
</Steps>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</TabPreview>
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
ResizableHandle,
|
||||||
|
ResizablePanel,
|
||||||
|
ResizablePanelGroup,
|
||||||
|
} from '@/components/ui/resizable'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ResizablePanelGroup direction="horizontal">
|
||||||
|
<ResizablePanel>One</ResizablePanel>
|
||||||
|
<ResizableHandle />
|
||||||
|
<ResizablePanel>Two</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Vertical
|
||||||
|
|
||||||
|
Use the direction prop to set the direction of the resizable panels.
|
||||||
|
|
||||||
|
<ComponentPreview name="ResizableVerticalDemo" />
|
||||||
|
|
||||||
|
```vue:line-numbers {10}
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
ResizableHandle,
|
||||||
|
ResizablePanel,
|
||||||
|
ResizablePanelGroup,
|
||||||
|
} from '@/components/ui/resizable'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ResizablePanelGroup direction="horizontal">
|
||||||
|
<ResizablePanel>One</ResizablePanel>
|
||||||
|
<ResizableHandle />
|
||||||
|
<ResizablePanel>Two</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Handle
|
||||||
|
|
||||||
|
You can set or hide the handle by using the withHandle prop on the ResizableHandle component.
|
||||||
|
|
||||||
|
<ComponentPreview name="ResizableHandleDemo" />
|
||||||
|
|
||||||
|
```vue:line-numbers {12}
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
ResizableHandle,
|
||||||
|
ResizablePanel,
|
||||||
|
ResizablePanelGroup,
|
||||||
|
} from '@/components/ui/resizable'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ResizablePanelGroup direction="horizontal">
|
||||||
|
<ResizablePanel>One</ResizablePanel>
|
||||||
|
<ResizableHandle with-handle />
|
||||||
|
<ResizablePanel>Two</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
36
apps/www/src/lib/registry/default/example/ResizableDemo.vue
Normal file
36
apps/www/src/lib/registry/default/example/ResizableDemo.vue
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
ResizableHandle,
|
||||||
|
ResizablePanel,
|
||||||
|
ResizablePanelGroup,
|
||||||
|
} from '@/lib/registry/default/ui/resizable'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ResizablePanelGroup
|
||||||
|
direction="horizontal"
|
||||||
|
class="max-w-md rounded-lg border"
|
||||||
|
>
|
||||||
|
<ResizablePanel :default-size="50">
|
||||||
|
<div class="flex h-[200px] items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">One</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
<ResizableHandle />
|
||||||
|
<ResizablePanel :default-size="50">
|
||||||
|
<ResizablePanelGroup direction="vertical">
|
||||||
|
<ResizablePanel :default-size="25">
|
||||||
|
<div class="flex h-full items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">Two</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
<ResizableHandle />
|
||||||
|
<ResizablePanel :default-size="75">
|
||||||
|
<div class="flex h-full items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">Three</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
ResizableHandle,
|
||||||
|
ResizablePanel,
|
||||||
|
ResizablePanelGroup,
|
||||||
|
} from '@/lib/registry/default/ui/resizable'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ResizablePanelGroup
|
||||||
|
direction="horizontal"
|
||||||
|
class="min-h-[200px] max-w-md rounded-lg border"
|
||||||
|
>
|
||||||
|
<ResizablePanel :default-size="25">
|
||||||
|
<div class="flex h-full items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">Sidebar</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
<ResizableHandle with-handle />
|
||||||
|
<ResizablePanel :default-size="75">
|
||||||
|
<div class="flex h-full items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">Content</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
ResizableHandle,
|
||||||
|
ResizablePanel,
|
||||||
|
ResizablePanelGroup,
|
||||||
|
} from '@/lib/registry/default/ui/resizable'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ResizablePanelGroup
|
||||||
|
direction="vertical"
|
||||||
|
class="min-h-[200px] max-w-md rounded-lg border"
|
||||||
|
>
|
||||||
|
<ResizablePanel :default-size="25">
|
||||||
|
<div class="flex h-full items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">Header</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
<ResizableHandle />
|
||||||
|
<ResizablePanel :default-size="75">
|
||||||
|
<div class="flex h-full items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">Content</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { type HTMLAttributes, computed } from 'vue'
|
||||||
|
import { SplitterResizeHandle, type SplitterResizeHandleEmits, type SplitterResizeHandleProps, useForwardPropsEmits } from 'radix-vue'
|
||||||
|
import { GripVertical } from 'lucide-vue-next'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<SplitterResizeHandleProps & { class?: HTMLAttributes['class'], withHandle?: boolean }>()
|
||||||
|
const emits = defineEmits<SplitterResizeHandleEmits>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
|
||||||
|
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SplitterResizeHandle v-bind="forwarded" :class="cn('relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 [&[data-orientation=vertical]]:h-px [&[data-orientation=vertical]]:w-full [&[data-orientation=vertical]]:after:left-0 [&[data-orientation=vertical]]:after:h-1 [&[data-orientation=vertical]]:after:w-full [&[data-orientation=vertical]]:after:-translate-y-1/2 [&[data-orientation=vertical]]:after:translate-x-0 [&[data-orientation=vertical]>div]:rotate-90', props.class)">
|
||||||
|
<template v-if="props.withHandle">
|
||||||
|
<div class="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
|
||||||
|
<GripVertical class="h-2.5 w-2.5" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</SplitterResizeHandle>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { type HTMLAttributes, computed } from 'vue'
|
||||||
|
import { SplitterGroup, type SplitterGroupEmits, type SplitterGroupProps, useForwardPropsEmits } from 'radix-vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<SplitterGroupProps & { class?: HTMLAttributes['class'] }>()
|
||||||
|
const emits = defineEmits<SplitterGroupEmits>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
|
||||||
|
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SplitterGroup v-bind="forwarded" :class="cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', props.class)">
|
||||||
|
<slot />
|
||||||
|
</SplitterGroup>
|
||||||
|
</template>
|
||||||
3
apps/www/src/lib/registry/default/ui/resizable/index.ts
Normal file
3
apps/www/src/lib/registry/default/ui/resizable/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export { default as ResizablePanelGroup } from './ResizablePanelGroup.vue'
|
||||||
|
export { default as ResizableHandle } from './ResizableHandle.vue'
|
||||||
|
export { SplitterPanel as ResizablePanel } from 'radix-vue'
|
||||||
36
apps/www/src/lib/registry/new-york/example/ResizableDemo.vue
Normal file
36
apps/www/src/lib/registry/new-york/example/ResizableDemo.vue
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
ResizableHandle,
|
||||||
|
ResizablePanel,
|
||||||
|
ResizablePanelGroup,
|
||||||
|
} from '@/lib/registry/new-york/ui/resizable'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ResizablePanelGroup
|
||||||
|
direction="horizontal"
|
||||||
|
class="max-w-md rounded-lg border"
|
||||||
|
>
|
||||||
|
<ResizablePanel :default-size="50">
|
||||||
|
<div class="flex h-[200px] items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">One</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
<ResizableHandle />
|
||||||
|
<ResizablePanel :default-size="50">
|
||||||
|
<ResizablePanelGroup direction="vertical">
|
||||||
|
<ResizablePanel :default-size="25">
|
||||||
|
<div class="flex h-full items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">Two</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
<ResizableHandle />
|
||||||
|
<ResizablePanel :default-size="75">
|
||||||
|
<div class="flex h-full items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">Three</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
ResizableHandle,
|
||||||
|
ResizablePanel,
|
||||||
|
ResizablePanelGroup,
|
||||||
|
} from '@/lib/registry/new-york/ui/resizable'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ResizablePanelGroup
|
||||||
|
direction="horizontal"
|
||||||
|
class="min-h-[200px] max-w-md rounded-lg border"
|
||||||
|
>
|
||||||
|
<ResizablePanel :default-size="25">
|
||||||
|
<div class="flex h-full items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">Sidebar</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
<ResizableHandle with-handle />
|
||||||
|
<ResizablePanel :default-size="75">
|
||||||
|
<div class="flex h-full items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">Content</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
ResizableHandle,
|
||||||
|
ResizablePanel,
|
||||||
|
ResizablePanelGroup,
|
||||||
|
} from '@/lib/registry/new-york/ui/resizable'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ResizablePanelGroup
|
||||||
|
direction="vertical"
|
||||||
|
class="min-h-[200px] max-w-md rounded-lg border"
|
||||||
|
>
|
||||||
|
<ResizablePanel :default-size="25">
|
||||||
|
<div class="flex h-full items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">Header</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
<ResizableHandle />
|
||||||
|
<ResizablePanel :default-size="75">
|
||||||
|
<div class="flex h-full items-center justify-center p-6">
|
||||||
|
<span class="font-semibold">Content</span>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { type HTMLAttributes, computed } from 'vue'
|
||||||
|
import { SplitterResizeHandle, type SplitterResizeHandleEmits, type SplitterResizeHandleProps, useForwardPropsEmits } from 'radix-vue'
|
||||||
|
import { DragHandleDots2Icon } from '@radix-icons/vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<SplitterResizeHandleProps & { class?: HTMLAttributes['class'], withHandle?: boolean }>()
|
||||||
|
const emits = defineEmits<SplitterResizeHandleEmits>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
|
||||||
|
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SplitterResizeHandle v-bind="forwarded" :class="cn('relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 [&[data-orientation=vertical]]:h-px [&[data-orientation=vertical]]:w-full [&[data-orientation=vertical]]:after:left-0 [&[data-orientation=vertical]]:after:h-1 [&[data-orientation=vertical]]:after:w-full [&[data-orientation=vertical]]:after:-translate-y-1/2 [&[data-orientation=vertical]]:after:translate-x-0 [&[data-orientation=vertical]>div]:rotate-90', props.class)">
|
||||||
|
<template v-if="props.withHandle">
|
||||||
|
<div class="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
|
||||||
|
<DragHandleDots2Icon class="h-2.5 w-2.5" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</SplitterResizeHandle>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { type HTMLAttributes, computed } from 'vue'
|
||||||
|
import { SplitterGroup, type SplitterGroupEmits, type SplitterGroupProps, useForwardPropsEmits } from 'radix-vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<SplitterGroupProps & { class?: HTMLAttributes['class'] }>()
|
||||||
|
const emits = defineEmits<SplitterGroupEmits>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
|
||||||
|
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SplitterGroup v-bind="forwarded" :class="cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', props.class)">
|
||||||
|
<slot />
|
||||||
|
</SplitterGroup>
|
||||||
|
</template>
|
||||||
3
apps/www/src/lib/registry/new-york/ui/resizable/index.ts
Normal file
3
apps/www/src/lib/registry/new-york/ui/resizable/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export { default as ResizablePanelGroup } from './ResizablePanelGroup.vue'
|
||||||
|
export { default as ResizableHandle } from './ResizableHandle.vue'
|
||||||
|
export { SplitterPanel as ResizablePanel } from 'radix-vue'
|
||||||
|
|
@ -445,6 +445,19 @@
|
||||||
],
|
],
|
||||||
"type": "components:ui"
|
"type": "components:ui"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "resizable",
|
||||||
|
"dependencies": [],
|
||||||
|
"registryDependencies": [
|
||||||
|
"utils"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"ui/resizable/ResizableHandle.vue",
|
||||||
|
"ui/resizable/ResizablePanelGroup.vue",
|
||||||
|
"ui/resizable/index.ts"
|
||||||
|
],
|
||||||
|
"type": "components:ui"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "scroll-area",
|
"name": "scroll-area",
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
|
|
@ -685,4 +698,4 @@
|
||||||
],
|
],
|
||||||
"type": "components:ui"
|
"type": "components:ui"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
22
apps/www/src/public/registry/styles/default/resizable.json
Normal file
22
apps/www/src/public/registry/styles/default/resizable.json
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"name": "resizable",
|
||||||
|
"dependencies": [],
|
||||||
|
"registryDependencies": [
|
||||||
|
"utils"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"name": "ResizableHandle.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { SplitterResizeHandle, type SplitterResizeHandleEmits, type SplitterResizeHandleProps, useForwardPropsEmits } from 'radix-vue'\nimport { GripVertical } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SplitterResizeHandleProps & { class?: HTMLAttributes['class'], withHandle?: boolean }>()\nconst emits = defineEmits<SplitterResizeHandleEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SplitterResizeHandle v-bind=\"forwarded\" :class=\"cn('relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 [&[data-orientation=vertical]]:h-px [&[data-orientation=vertical]]:w-full [&[data-orientation=vertical]]:after:left-0 [&[data-orientation=vertical]]:after:h-1 [&[data-orientation=vertical]]:after:w-full [&[data-orientation=vertical]]:after:-translate-y-1/2 [&[data-orientation=vertical]]:after:translate-x-0 [&[data-orientation=vertical]>div]:rotate-90', props.class)\">\n <template v-if=\"props.withHandle\">\n <div class=\"z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border\">\n <GripVertical class=\"h-2.5 w-2.5\" />\n </div>\n </template>\n </SplitterResizeHandle>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ResizablePanelGroup.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { SplitterGroup, type SplitterGroupEmits, type SplitterGroupProps, useForwardPropsEmits } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SplitterGroupProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<SplitterGroupEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SplitterGroup v-bind=\"forwarded\" :class=\"cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', props.class)\">\n <slot />\n </SplitterGroup>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "index.ts",
|
||||||
|
"content": "export { default as ResizablePanelGroup } from './ResizablePanelGroup.vue'\nexport { default as ResizableHandle } from './ResizableHandle.vue'\nexport { SplitterPanel as ResizablePanel } from 'radix-vue'\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "components:ui"
|
||||||
|
}
|
||||||
22
apps/www/src/public/registry/styles/new-york/resizable.json
Normal file
22
apps/www/src/public/registry/styles/new-york/resizable.json
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"name": "resizable",
|
||||||
|
"dependencies": [],
|
||||||
|
"registryDependencies": [
|
||||||
|
"utils"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"name": "ResizableHandle.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { SplitterResizeHandle, type SplitterResizeHandleEmits, type SplitterResizeHandleProps, useForwardPropsEmits } from 'radix-vue'\nimport { DragHandleDots2Icon } from '@radix-icons/vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SplitterResizeHandleProps & { class?: HTMLAttributes['class'], withHandle?: boolean }>()\nconst emits = defineEmits<SplitterResizeHandleEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SplitterResizeHandle v-bind=\"forwarded\" :class=\"cn('relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 [&[data-orientation=vertical]]:h-px [&[data-orientation=vertical]]:w-full [&[data-orientation=vertical]]:after:left-0 [&[data-orientation=vertical]]:after:h-1 [&[data-orientation=vertical]]:after:w-full [&[data-orientation=vertical]]:after:-translate-y-1/2 [&[data-orientation=vertical]]:after:translate-x-0 [&[data-orientation=vertical]>div]:rotate-90', props.class)\">\n <template v-if=\"props.withHandle\">\n <div class=\"z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border\">\n <DragHandleDots2Icon class=\"h-2.5 w-2.5\" />\n </div>\n </template>\n </SplitterResizeHandle>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ResizablePanelGroup.vue",
|
||||||
|
"content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { SplitterGroup, type SplitterGroupEmits, type SplitterGroupProps, useForwardPropsEmits } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SplitterGroupProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<SplitterGroupEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SplitterGroup v-bind=\"forwarded\" :class=\"cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', props.class)\">\n <slot />\n </SplitterGroup>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "index.ts",
|
||||||
|
"content": "export { default as ResizablePanelGroup } from './ResizablePanelGroup.vue'\nexport { default as ResizableHandle } from './ResizableHandle.vue'\nexport { SplitterPanel as ResizablePanel } from 'radix-vue'\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "components:ui"
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user