Skip to content

Commit

Permalink
[Page] [Layout] Support navigation children
Browse files Browse the repository at this point in the history
  • Loading branch information
qianmoQ committed Mar 24, 2024
1 parent c32e27b commit 124778d
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 9 deletions.
15 changes: 15 additions & 0 deletions src/components/ui/collapsible/Collapsible.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script setup lang="ts">
import { CollapsibleRoot, useForwardPropsEmits } from 'radix-vue'
import type { CollapsibleRootEmits, CollapsibleRootProps } from 'radix-vue'
const props = defineProps<CollapsibleRootProps>()
const emits = defineEmits<CollapsibleRootEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script>

<template>
<CollapsibleRoot v-slot="{ open }" v-bind="forwarded">
<slot :open="open" />
</CollapsibleRoot>
</template>
11 changes: 11 additions & 0 deletions src/components/ui/collapsible/CollapsibleContent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script setup lang="ts">
import { CollapsibleContent, type CollapsibleContentProps } from 'radix-vue'
const props = defineProps<CollapsibleContentProps>()
</script>

<template>
<CollapsibleContent v-bind="props" class="overflow-hidden transition-all data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down">
<slot />
</CollapsibleContent>
</template>
11 changes: 11 additions & 0 deletions src/components/ui/collapsible/CollapsibleTrigger.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script setup lang="ts">
import { CollapsibleTrigger, type CollapsibleTriggerProps } from 'radix-vue'
const props = defineProps<CollapsibleTriggerProps>()
</script>

<template>
<CollapsibleTrigger v-bind="props">
<slot />
</CollapsibleTrigger>
</template>
3 changes: 3 additions & 0 deletions src/components/ui/collapsible/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as Collapsible } from './Collapsible.vue'
export { default as CollapsibleTrigger } from './CollapsibleTrigger.vue'
export { default as CollapsibleContent } from './CollapsibleContent.vue'
7 changes: 6 additions & 1 deletion src/data/Navigation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NavigationModel, NavigationPosition } from '@/model/Navigation'
import NavigationService from '@/services/Navigation'
import { Home, LogIn, LogOut } from 'lucide-vue-next'
import { Ban, Home, LogIn, LogOut, StickyNote } from 'lucide-vue-next'

const createNavigation = (): void => {
NavigationService.addNavigation(createNavigationItem('common.common.home', undefined, '/home', Home, NavigationPosition.LEFT_TOP))
Expand Down Expand Up @@ -34,6 +34,11 @@ const createNavigation = (): void => {
[datacap],
'common.common.openProject')
NavigationService.addNavigation(openProject)

const page404 = createNavigationItem('common.common.page404', undefined, '/common/404', Ban, NavigationPosition.LEFT_TOP)
const pages = createNavigationItem('common.common.page', undefined, '/pages', StickyNote,
NavigationPosition.LEFT_TOP, [page404], undefined, 'common.common.page')
NavigationService.addNavigation(pages)
}

const createNavigationItem = (title?: string, label?: string, href?: string, icon?: any, position?: NavigationPosition, children?: NavigationModel[], group?: string, description?: string, blank?: boolean): NavigationModel => {
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/langs/en/Common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export default {
logout: 'Logout',
codeMirror: 'Code Mirror',
openProject: 'Open Project',
datacap: 'DataCap'
datacap: 'DataCap',
page: 'Page',
page404: '404'
},
tip: {
signInInfo: 'Enter your information to sign in to your account.',
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/langs/zhCn/Common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export default {
logout: '退出',
codeMirror: '代码仓库',
openProject: '开源项目',
datacap: 'DataCap'
datacap: 'DataCap',
page: '页面',
page404: '404'
},
tip: {
signInInfo: '输入您的信息以登录您的帐户。',
Expand Down
1 change: 1 addition & 0 deletions src/model/Navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface NavigationModel
group?: string
description?: string,
external?: boolean
opened?: boolean
position?: NavigationPosition
children?: NavigationModel[]
}
Expand Down
35 changes: 33 additions & 2 deletions src/views/layouts/base/components/components/NavigationClosed.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
<template>
<div v-if="navigator?.position === NavigationPosition.LEFT_TOP || navigator?.position === NavigationPosition.LEFT_BOTTOM">
<NavigationRouterLink :external="navigator?.external" :link="navigator?.href as string"
<Collapsible v-model="navigator.opened" v-if="navigator?.children && navigator.children.length > 0" class="cursor-pointer" @click="navigator.opened = !navigator.opened">
<CollapsibleTrigger as-child>
<Button as="a" size="sm" class="flex items-center justify-between text-wrap rounded-none h-10 w-full border-l border-l-slate-500 px-2"
:variant="$route.path === `${navigator?.href}` ? 'secondary' : 'ghost'">
<div class="flex items-center">
<component :is="navigator?.icon"/>
<div class="ml-2">{{ $t(navigator?.title as string) }}</div>
<div v-if="navigator?.label" class="ml-2 rounded-lg bg-primary px-2 mt-0.5 text-[0.625rem] text-primary-foreground">{{ navigator?.label }}</div>
</div>
<ChevronDown :class="`${navigator?.opened ? 'rotate-180' : 'rotate-0'}`"/>
</Button>
</CollapsibleTrigger>
<CollapsibleContent class="space-y-2">
<NavigationRouterLink v-for="item in navigator?.children" :external="item?.external" :link="item?.href as string"
:class="`my-1 ml-8 ${item?.position === NavigationPosition.LEFT_BOTTOM ? 'absolute bottom-0 left-0 right-0' : ''}`">
<Button as="a" size="sm" class="justify-start text-wrap rounded-none h-10 w-full border-l border-l-slate-500 px-2"
:variant="$route.path === `${item?.href}` ? 'secondary' : 'ghost'">
<component :is="item?.icon"/>
<div class="ml-2">{{ $t(item?.title as string) }}</div>
<div v-if="item?.label" class="ml-2 rounded-lg bg-primary px-2 mt-0.5 text-[0.625rem] text-primary-foreground">{{ item?.label }}</div>
</Button>
</NavigationRouterLink>
</CollapsibleContent>
</Collapsible>
<NavigationRouterLink v-else :external="navigator?.external" :link="navigator?.href as string"
:class="`${navigator?.position === NavigationPosition.LEFT_BOTTOM ? 'absolute bottom-0 left-0 right-0' : ''}`">
<Button as="a" size="sm" class="justify-start text-wrap rounded-none h-10 w-full border-l border-l-slate-500 px-2"
:variant="$route.path === `${navigator?.href}` ? 'secondary' : 'ghost'">
Expand All @@ -17,6 +41,8 @@ import { defineComponent } from 'vue'
import { Button } from '@/components/ui/button'
import { NavigationModel, NavigationPosition } from '@/model/Navigation'
import NavigationRouterLink from '@/views/layouts/base/components/components/NavigationRouterLink.vue'
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'
import { ChevronDown } from 'lucide-vue-next'
export default defineComponent({
name: 'NavigationClosed',
Expand All @@ -26,7 +52,12 @@ export default defineComponent({
return NavigationPosition
}
},
components: {NavigationRouterLink, Button},
components: {
Collapsible, CollapsibleTrigger, CollapsibleContent,
NavigationRouterLink,
Button,
ChevronDown
},
props: {
navigator: {
type: Object as () => NavigationModel
Expand Down
54 changes: 52 additions & 2 deletions src/views/layouts/base/components/components/NavigationOpened.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
<template>
<div v-if="navigator?.position === NavigationPosition.LEFT_TOP || navigator?.position === NavigationPosition.LEFT_BOTTOM">
<NavigationRouterLink :external="navigator?.external" :link="navigator?.href as string"
<DropdownMenu v-if="navigator?.children && navigator.children.length > 0">
<DropdownMenuTrigger class="cursor-pointer" as-child>
<Button as="a" size="icon" class="h-12 w-12" :variant="$route.path === `${navigator?.href}` ? 'secondary' : 'ghost'">
<component :is="navigator?.icon"/>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent side='right' align='start'>
<DropdownMenuLabel>
{{ $t(navigator?.title as string) }}
<span v-if="navigator?.label" class="ml-auto text-muted-foreground">({{ navigator?.label }})</span>
</DropdownMenuLabel>
<DropdownMenuSeparator/>
<DropdownMenuItem v-for="item in navigator?.children" class="cursor-pointer">
<NavigationRouterLink :external="item?.external" :link="item?.href as string">
<Button as="a" size="sm" class="justify-start text-wrap rounded-none w-full"
:variant="$route.path === `${item?.href}` ? 'secondary' : 'ghost'">
<component :is="item?.icon"/>
<div class="ml-2 max-w-52 text-wrap">{{ $t(item?.title as string) }}</div>
<div v-if="item?.label" class="ml-2 rounded-lg bg-primary px-2 mt-0.5 text-[0.625rem] text-primary-foreground">{{ item?.label }}</div>
</Button>
</NavigationRouterLink>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<NavigationRouterLink v-else :external="navigator?.external" :link="navigator?.href as string"
:class="`${navigator?.position === NavigationPosition.LEFT_BOTTOM ? 'absolute bottom-0 left-0 right-0' : ''}`">
<TooltipProvider>
<Tooltip :delay-duration="0">
Expand All @@ -26,6 +50,20 @@ import { Button } from '@/components/ui/button'
import { NavigationModel, NavigationPosition } from '@/model/Navigation'
import { ChevronsLeft } from 'lucide-vue-next'
import NavigationRouterLink from '@/views/layouts/base/components/components/NavigationRouterLink.vue'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuPortal,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger
} from '@/components/ui/dropdown-menu'
export default defineComponent({
name: 'NavigationOpened',
Expand All @@ -39,7 +77,19 @@ export default defineComponent({
NavigationRouterLink,
ChevronsLeft,
Button,
Tooltip, TooltipContent, TooltipProvider, TooltipTrigger
Tooltip, TooltipContent, TooltipProvider, TooltipTrigger,
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuPortal,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger
},
props: {
navigator: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<a v-if="external" :href="link" target="_blank">
<a v-if="external" :href="link as string" target="_blank">
<slot></slot>
</a>
<RouterLink v-else :to="link">
<RouterLink v-else :to="link as string">
<slot></slot>
</RouterLink>
</template>
Expand Down

0 comments on commit 124778d

Please sign in to comment.