Skip to content
This repository has been archived by the owner on Aug 25, 2024. It is now read-only.

Commit

Permalink
Merge pull request #7 from livraison-dev/feat/command-palette
Browse files Browse the repository at this point in the history
 feat(heade): add header component
  • Loading branch information
elonehoo authored Dec 27, 2023
2 parents 0df83a8 + 5bda24f commit abdc965
Show file tree
Hide file tree
Showing 16 changed files with 1,016 additions and 6 deletions.
49 changes: 49 additions & 0 deletions components/header/Header.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script setup lang="ts">
const tagList = ref<{
requestType: string
url: string
}[]>([
{
requestType: 'GET',
url: 'https://livraison-app.vercel.app',
},
{
requestType: 'POST',
url: 'https://livraison-app.vercel.app',
},
])
const sidebar = useSidebarStore()
const { show } = storeToRefs(sidebar)
const linkQuery = useRouteQuery('link')
function remakeRouteQuery() {
if (linkQuery.value === undefined)
linkQuery.value = tagList.value[0].url
}
watch(linkQuery, () => {
if (linkQuery.value === undefined)
linkQuery.value = tagList.value[0].url
})
onMounted(() => {
remakeRouteQuery()
})
</script>

<template>
<div class="flex h-14 items-center">
<SidebarIconAction v-if="!show" />
<Dnd
v-model="tagList"
class=""
:animation="100"
>
<HeaderTag v-for="tag in tagList" :key="tag.url" :label="tag.requestType" :url="tag.url" />
</Dnd>
<HeaderIconAdd />
</div>
</template>
11 changes: 11 additions & 0 deletions components/header/icon/Add.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script setup lang="ts">
defineOptions({
name: 'HeaderIconAdd',
})
</script>

<template>
<div class="flex justify-center items-center ">
<Icon name="carbon:add" class="text-5 mt-0 cursor-pointer icon-hover" />
</div>
</template>
18 changes: 18 additions & 0 deletions components/header/tag/Tag.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script setup lang="ts">
const props = defineProps<{
label: string
url: string
}>()
</script>

<template>
<div class="float-left cursor-pointer leading-5 flex flex-[0_0_auto] p-x-2 items-center">
<Label :class="props.label">{{ props.label }}</Label>
<Label class="truncate pl-0.5 w-30 inline-block">{{ props.url }}</Label>
<Icon name="carbon:close" class="text-5 mt-0 icon-hover" />
</div>
</template>

<style>
</style>
13 changes: 11 additions & 2 deletions components/layout/Root.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,23 @@
defineOptions({
name: 'LayoutRoot',
})
const sidebar = useSidebarStore()
const { panSize } = storeToRefs(sidebar)
</script>

<template>
<LayoutBasic :border-positions="[]">
<Splitpanes>
<Splitpanes @resize="panSize.size = $event[0].size">
<Sidebar />
<SplitpanesPane :size="80" :min-size="70" :max-size="85">
<slot />
<!-- header -->
<Header />
<!-- bodyer -->
<div class="mx-4">
<slot />
</div>
</SplitpanesPane>
</Splitpanes>
</LayoutBasic>
Expand Down
61 changes: 61 additions & 0 deletions composables/useRouteHash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { customRef, nextTick, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { toValue, tryOnScopeDispose } from '@vueuse/shared'
import type { MaybeRefOrGetter } from '@vueuse/shared'
import type { ReactiveRouteOptions, RouteHashValueRaw } from '~/types/router'

let _hash: RouteHashValueRaw

export function useRouteHash(
defaultValue?: MaybeRefOrGetter<RouteHashValueRaw>,
{
mode = 'replace',
route = useRoute(),
router = useRouter(),
}: ReactiveRouteOptions = {},
) {
_hash = route.hash

tryOnScopeDispose(() => {
_hash = undefined
})

let _trigger: () => void

const proxy = customRef<RouteHashValueRaw>((track, trigger) => {
_trigger = trigger

return {
get() {
track()

return _hash || toValue(defaultValue)
},
set(v) {
if (v === _hash)
return

_hash = v === null ? undefined : v

trigger()

nextTick(() => {
const { params, query } = route

router[toValue(mode)]({ params, query, hash: _hash as string })
})
},
}
})

watch(
() => route.hash,
() => {
_hash = route.hash
_trigger()
},
{ flush: 'sync' },
)

return proxy
}
103 changes: 103 additions & 0 deletions composables/useRouteParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { customRef, nextTick, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { toValue, tryOnScopeDispose } from '@vueuse/shared'
import type { Ref } from 'vue'
import type { MaybeRefOrGetter } from '@vueuse/shared'
import type { LocationAsRelativeRaw, RouteParamValueRaw, Router } from 'vue-router'
import type { ReactiveRouteOptionsWithTransform } from '~/types/router'

const _queue = new WeakMap<Router, Map<string, any>>()

export function useRouteParams(
name: string
): Ref<null | string | string[]>

export function useRouteParams<
T extends RouteParamValueRaw = RouteParamValueRaw,
K = T,
>(
name: string,
defaultValue?: MaybeRefOrGetter<T>,
options?: ReactiveRouteOptionsWithTransform<T, K>
): Ref<K>

export function useRouteParams<
T extends RouteParamValueRaw = RouteParamValueRaw,
K = T,
>(
name: string,
defaultValue?: MaybeRefOrGetter<T>,
options: ReactiveRouteOptionsWithTransform<T, K> = {},
): Ref<K> {
const {
mode = 'replace',
route = useRoute(),
router = useRouter(),
transform = value => value as any as K,
} = options

if (!_queue.has(router))
_queue.set(router, new Map())

const _paramsQueue = _queue.get(router)!

let param = route.params[name] as any

tryOnScopeDispose(() => {
param = undefined
})

let _trigger: () => void

const proxy = customRef<any>((track, trigger) => {
_trigger = trigger

return {
get() {
track()

return transform(param !== undefined ? param : toValue(defaultValue))
},
set(v) {
if (param === v)
return

param = v
_paramsQueue.set(name, v)

trigger()

nextTick(() => {
if (_paramsQueue.size === 0)
return

const newParams = Object.fromEntries(_paramsQueue.entries())
_paramsQueue.clear()

const { params, query, hash } = route

router[toValue(mode)]({
params: {
...params,
...newParams,
},
query,
hash,
} as LocationAsRelativeRaw)
})
},
}
})

watch(
() => route.params[name],
(v) => {
param = v

_trigger()
},
{ flush: 'sync' },
)

return proxy as Ref<K>
}
100 changes: 100 additions & 0 deletions composables/useRouteQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { customRef, nextTick, watch } from 'vue'
import { toValue, tryOnScopeDispose } from '@vueuse/shared'
import { useRoute, useRouter } from 'vue-router'
import type { Router } from 'vue-router'
import type { Ref } from 'vue'
import type { MaybeRefOrGetter } from '@vueuse/shared'
import type { ReactiveRouteOptionsWithTransform, RouteQueryValueRaw } from '~/types/router'

const _queue = new WeakMap<Router, Map<string, any>>()

export function useRouteQuery(
name: string
): Ref<null | string | string[]>

export function useRouteQuery<
T extends RouteQueryValueRaw = RouteQueryValueRaw,
K = T,
>(
name: string,
defaultValue?: MaybeRefOrGetter<T>,
options?: ReactiveRouteOptionsWithTransform<T, K>
): Ref<K>

export function useRouteQuery<
T extends RouteQueryValueRaw = RouteQueryValueRaw,
K = T,
>(
name: string,
defaultValue?: MaybeRefOrGetter<T>,
options: ReactiveRouteOptionsWithTransform<T, K> = {},
): Ref<K> {
const {
mode = 'replace',
route = useRoute(),
router = useRouter(),
transform = value => value as any as K,
} = options

if (!_queue.has(router))
_queue.set(router, new Map())

const _queriesQueue = _queue.get(router)!

let query = route.query[name] as any

tryOnScopeDispose(() => {
query = undefined
})

let _trigger: () => void

const proxy = customRef<any>((track, trigger) => {
_trigger = trigger

return {
get() {
track()

return transform(query !== undefined ? query : toValue(defaultValue))
},
set(v) {
if (query === v)
return

query = v
_queriesQueue.set(name, v)

trigger()

nextTick(() => {
if (_queriesQueue.size === 0)
return

const newQueries = Object.fromEntries(_queriesQueue.entries())
_queriesQueue.clear()

const { params, query, hash } = route

router[toValue(mode)]({
params,
query: { ...query, ...newQueries },
hash,
})
})
},
}
})

watch(
() => route.query[name],
(v) => {
query = v

_trigger()
},
{ flush: 'sync' },
)

return proxy as any as Ref<K>
}
4 changes: 2 additions & 2 deletions pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script setup lang="ts">
const showSidebar = useSidebarStore()
const linkQuery = useRouteQuery('link')
</script>

<template>
<div>
<SidebarIconAction v-if="!showSidebar.show" />
{{ linkQuery }}
</div>
</template>
2 changes: 1 addition & 1 deletion store/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const useSidebarStore = defineStore('sidebar', () => {
maxSize: number
}>({
minSize: 15,
size: 0,
size: 20,
maxSize: 30,
})

Expand Down
Loading

0 comments on commit abdc965

Please sign in to comment.