Skip to content

Commit

Permalink
feat: Tree (#976)
Browse files Browse the repository at this point in the history
* chore: wip

* chore: wip (very crude impl)

* chore: another crude wip

* fix: improve typing

* chore: move constants to shared

* refactor: tree item, add virtualizer

* refactor: roving focus to use new collection

* feat: virtualizer

* refactor: improve tree

* fix: build

* fix: missing value for comboboxitem

* feat: export component, run docsgen

* docs: tree, demo

* docs: fix wrong demo

* chore: expose more internal slot

* test: add test for tree componetn

* fix: missing aria condition

* refactor: expose more function, cater for checkbox

* chore: add dnd example

* chore: cleanup dnd, add stackblitz docs

* docs: update sb link

* chore: lint

* chore: improve story styling

* feat: cater for async mode

* chore: add story for nested dom case

* chore: update docs

* fix: direction
  • Loading branch information
zernonia authored Jul 1, 2024
1 parent 4d7954e commit 9ce671b
Show file tree
Hide file tree
Showing 61 changed files with 2,233 additions and 111 deletions.
1 change: 1 addition & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export default defineConfig({
{ text: 'Toggle Group', link: '/components/toggle-group' },
{ text: 'Toolbar', link: '/components/toolbar' },
{ text: 'Tooltip', link: '/components/tooltip' },
{ text: `Tree ${BadgeHTML('Alpha')}`, link: '/components/tree' },
],
},
{
Expand Down
4 changes: 4 additions & 0 deletions docs/components/Demos.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import ToggleDemo from './demo/Toggle/tailwind/index.vue'
import ToggleGroupDemo from './demo/ToggleGroup/tailwind/index.vue'
import ToolbarDemo from './demo/Toolbar/tailwind/index.vue'
import TooltipDemo from './demo/Tooltip/tailwind/index.vue'
import TreeDemo from './demo/Tree/tailwind/index.vue'
import DemoContainer from './DemoContainer.vue'
</script>
Expand Down Expand Up @@ -171,5 +172,8 @@ import DemoContainer from './DemoContainer.vue'
<DemoContainer title="tooltip">
<TooltipDemo />
</DemoContainer>
<DemoContainer title="tree">
<TreeDemo />
</DemoContainer>
</div>
</template>
8 changes: 4 additions & 4 deletions docs/components/demo/CalendarYearIncrement/css/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
import { Icon } from '@iconify/vue'
import { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading, CalendarNext, CalendarPrev, CalendarRoot, type CalendarRootProps } from 'radix-vue'
import './styles.css'
import type { DateValue } from '@internationalized/date';
import type { DateValue } from '@internationalized/date'
const isDateUnavailable: CalendarRootProps['isDateUnavailable'] = (date) => {
return date.day === 17 || date.day === 18
}
const pagingFunc = (date: DateValue, sign: -1 | 1) => {
function pagingFunc(date: DateValue, sign: -1 | 1) {
if (sign === -1)
return date.subtract({ years: 1})
return date.add({ years: 1})
return date.subtract({ years: 1 })
return date.add({ years: 1 })
}
</script>

Expand Down
8 changes: 4 additions & 4 deletions docs/components/demo/CalendarYearIncrement/tailwind/index.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<script setup lang="ts">
import { Icon } from '@iconify/vue'
import type { DateValue } from '@internationalized/date';
import type { DateValue } from '@internationalized/date'
import { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading, CalendarNext, CalendarPrev, CalendarRoot, type CalendarRootProps } from 'radix-vue'
const isDateUnavailable: CalendarRootProps['isDateUnavailable'] = (date) => {
return date.day === 17 || date.day === 18
}
const pagingFunc = (date: DateValue, sign: -1 | 1) => {
function pagingFunc(date: DateValue, sign: -1 | 1) {
if (sign === -1)
return date.subtract({ years: 1})
return date.add({ years: 1})
return date.subtract({ years: 1 })
return date.add({ years: 1 })
}
</script>

Expand Down
61 changes: 61 additions & 0 deletions docs/components/demo/Tree/css/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<script setup lang="ts">
import { TreeItem, TreeRoot } from 'radix-vue'
import { Icon } from '@iconify/vue'
const items = [
{
title: 'composables',
icon: 'lucide:folder',
children: [
{ title: 'useAuth.ts', icon: 'vscode-icons:file-type-typescript' },
{ title: 'useUser.ts', icon: 'vscode-icons:file-type-typescript' },
],
},
{
title: 'components',
icon: 'lucide:folder',
children: [
{
title: 'Home',
icon: 'lucide:folder',
children: [
{ title: 'Card.vue', icon: 'vscode-icons:file-type-vue' },
{ title: 'Button.vue', icon: 'vscode-icons:file-type-vue' },
],
},
],
},
{ title: 'app.vue', icon: 'vscode-icons:file-type-vue' },
{ title: 'nuxt.config.ts', icon: 'vscode-icons:file-type-nuxt' },
]
</script>

<template>
<TreeRoot
v-slot="{ flattenItems }"
class="list-none select-none w-56 bg-white text-blackA11 rounded-lg p-2 text-sm font-medium" :items="items"
:get-key="(item) => item.title"
:default-expanded="['components']"
>
<h2 class="font-semibold !text-base text-blackA11 px-2 pt-1">
Directory Structure
</h2>
<TreeItem
v-for="item in flattenItems"
v-slot="{ isExpanded }"
:key="item._id"
:style="{ 'padding-left': `${item.level + 0.5}rem` }"
v-bind="item.bind"
class="flex items-center py-1 px-2 my-0.5 rounded outline-none focus:ring-grass8 focus:ring-2 data-[selected]:bg-grass4"
>
<template v-if="item.hasChildren">
<Icon v-if="!isExpanded" icon="lucide:folder" class="h-4 w-4" />
<Icon v-else icon="lucide:folder-open" class="h-4 w-4" />
</template>
<Icon v-else :icon="item.value.icon || 'lucide:file'" class="h-4 w-4" />
<div class="pl-2">
{{ item.value.title }}
</div>
</TreeItem>
</TreeRoot>
</template>
74 changes: 74 additions & 0 deletions docs/components/demo/Tree/tailwind/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<script setup lang="ts">
import { TreeItem, TreeRoot } from 'radix-vue'
import { Icon } from '@iconify/vue'
const items = [
{
title: 'composables',
icon: 'lucide:folder',
children: [
{ title: 'useAuth.ts', icon: 'vscode-icons:file-type-typescript' },
{ title: 'useUser.ts', icon: 'vscode-icons:file-type-typescript' },
],
},
{
title: 'components',
icon: 'lucide:folder',
children: [
{
title: 'Home',
icon: 'lucide:folder',
children: [
{ title: 'Card.vue', icon: 'vscode-icons:file-type-vue' },
{ title: 'Button.vue', icon: 'vscode-icons:file-type-vue' },
],
},
],
},
{ title: 'app.vue', icon: 'vscode-icons:file-type-vue' },
{ title: 'nuxt.config.ts', icon: 'vscode-icons:file-type-nuxt' },
]
</script>

<template>
<TreeRoot
v-slot="{ flattenItems }"
class="list-none select-none w-56 bg-white text-blackA11 rounded-lg p-2 text-sm font-medium"
:items="items"
:get-key="(item) => item.title"
:default-expanded="['components']"
>
<h2 class="font-semibold !text-base text-blackA11 px-2 pt-1">
Directory Structure
</h2>
<TreeItem
v-for="item in flattenItems"
v-slot="{ isExpanded }"
:key="item._id"
:style="{ 'padding-left': `${item.level - 0.5}rem` }"
v-bind="item.bind"
class="flex items-center py-1 px-2 my-0.5 rounded outline-none focus:ring-grass8 focus:ring-2 data-[selected]:bg-grass4"
>
<template v-if="item.hasChildren">
<Icon
v-if="!isExpanded"
icon="lucide:folder"
class="h-4 w-4"
/>
<Icon
v-else
icon="lucide:folder-open"
class="h-4 w-4"
/>
</template>
<Icon
v-else
:icon="item.value.icon || 'lucide:file'"
class="h-4 w-4"
/>
<div class="pl-2">
{{ item.value.title }}
</div>
</TreeItem>
</TreeRoot>
</template>
15 changes: 15 additions & 0 deletions docs/components/demo/Tree/tailwind/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const { green, grass } = require('@radix-ui/colors')

/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./**/*.vue'],
theme: {
extend: {
colors: {
...green,
...grass,
},
},
},
plugins: [],
}
2 changes: 2 additions & 0 deletions docs/content/components/number-field.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ aria: https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton

# Number Field

<Badge>Alpha</Badge>

<Description>
A number field allows a user to enter a number and increment or decrement the value using stepper buttons.
</Description>
Expand Down
Loading

0 comments on commit 9ce671b

Please sign in to comment.