Skip to content

Commit

Permalink
feat: setup tabs example
Browse files Browse the repository at this point in the history
  • Loading branch information
tmg0 committed May 27, 2024
1 parent 6235852 commit 4cfaf03
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 48 deletions.
48 changes: 16 additions & 32 deletions playground/vite/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,42 +1,26 @@
<script setup>
<script setup lang="ts">
import { ref } from 'vue'
import { HeroProvider } from 'hero-motion'
import Cursor from './components/Cursor.vue'
import { Tab, Tabs } from './components/Tabs'
const activeKey = ref(5)
const isActive = i => i === activeKey.value
const activeTab = ref('A')
function mapRange(from, to) {
return (value) => {
const [fromMin, fromMax] = from
const [toMin, toMax] = to
return (value - fromMin) * (toMax - toMin) / (fromMax - fromMin) + toMin
}
function onSelect(value) {
activeTab.value = value
}
const fontSizeRange = mapRange([1, 9], [12, 12 * 9])
const BG_COLORS = [
'#ef4444',
'#f97316',
'#f59e0b',
'#eab308',
'#84cc16',
'#22c55e',
'#10b981',
'#14b8a6',
'#06b6d4',
]
</script>

<template>
<div class="flex">
<div class="p-5 grid grid-cols-3 gap-5 shadow-xl m-5 rounded-xl bg-slate-500">
<HeroProvider :transition="{ bounce: 0 }">
<div v-for="i in 9" :key="i" class="w-32 h-32 cursor-pointer rounded-xl bg-slate-700" @click="activeKey = i">
<Cursor v-if="isActive(i)" :style="{ background: BG_COLORS[i - 1], fontSize: `${fontSizeRange(i)}px` }" />
</div>
</HeroProvider>
<HeroProvider>
<div class="p-6">
<Tabs>
<Tab :is-active="activeTab === 'A'" @click="onSelect('A')">
TabA
</Tab>
<Tab :is-active="activeTab === 'B'" @click="onSelect('B')">
TabB
</Tab>
</Tabs>
</div>
</div>
</HeroProvider>
</template>
15 changes: 0 additions & 15 deletions playground/vite/src/components/Cursor.vue

This file was deleted.

19 changes: 19 additions & 0 deletions playground/vite/src/components/Tabs/Tab.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script setup lang="ts">
import TabCursor from './TabCursor.vue'
defineProps<{
isActive: boolean
}>()
const emit = defineEmits(['click'])
</script>

<template>
<button class="z-0 w-full px-3 py-1 flex group relative justify-center items-center cursor-pointer transition-opacity tap-highlight-transparent data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-30 data-[hover-unselected=true]:opacity-disabled outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 h-8 text-small rounded-small" @click="emit('click')">
<div class="relative z-10 whitespace-nowrap transition-colors text-black/75 text-sm group-data-[selected=true]:text-default-foreground">
<slot />
</div>

<TabCursor v-if="isActive" />
</button>
</template>
9 changes: 9 additions & 0 deletions playground/vite/src/components/Tabs/TabCursor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script setup lang="ts">
import { Hero } from 'hero-motion'
</script>

<template>
<Hero layout-id="tab-cursor" as="span" class="absolute z-0 inset-0 rounded-lg bg-white dark:bg-default shadow-small">
<slot />
</Hero>
</template>
7 changes: 7 additions & 0 deletions playground/vite/src/components/Tabs/Tabs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<template>
<div class="inline-flex">
<div class="flex p-1 h-fit gap-2 items-center flex-nowrap overflow-x-scroll scrollbar-hide bg-gray-100 rounded-xl">
<slot />
</div>
</div>
</template>
4 changes: 4 additions & 0 deletions playground/vite/src/components/Tabs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Tabs from './Tabs.vue'
import Tab from './Tab.vue'

export { Tabs, Tab }
112 changes: 111 additions & 1 deletion src/components/hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,118 @@ interface Transition {
ease: string
}

type HTMLTag =
| 'a'
| 'abbr'
| 'address'
| 'area'
| 'article'
| 'aside'
| 'audio'
| 'b'
| 'base'
| 'bdi'
| 'bdo'
| 'blockquote'
| 'body'
| 'br'
| 'button'
| 'canvas'
| 'caption'
| 'cite'
| 'code'
| 'col'
| 'colgroup'
| 'data'
| 'datalist'
| 'dd'
| 'del'
| 'details'
| 'dfn'
| 'dialog'
| 'div'
| 'dl'
| 'dt'
| 'em'
| 'embed'
| 'fieldset'
| 'figcaption'
| 'figure'
| 'footer'
| 'form'
| 'h1'
| 'h2'
| 'h3'
| 'h4'
| 'h5'
| 'h6'
| 'head'
| 'header'
| 'hr'
| 'html'
| 'i'
| 'iframe'
| 'img'
| 'input'
| 'ins'
| 'kbd'
| 'label'
| 'legend'
| 'li'
| 'link'
| 'main'
| 'map'
| 'mark'
| 'meta'
| 'meter'
| 'nav'
| 'noscript'
| 'object'
| 'ol'
| 'optgroup'
| 'option'
| 'output'
| 'p'
| 'picture'
| 'pre'
| 'progress'
| 'q'
| 'rp'
| 'rt'
| 'ruby'
| 's'
| 'samp'
| 'script'
| 'section'
| 'select'
| 'small'
| 'source'
| 'span'
| 'strong'
| 'style'
| 'sub'
| 'summary'
| 'sup'
| 'table'
| 'tbody'
| 'td'
| 'template'
| 'textarea'
| 'tfoot'
| 'th'
| 'thead'
| 'time'
| 'title'
| 'tr'
| 'track'
| 'u'
| 'ul'
| 'var'
| 'video'
| 'wbr'

const props = {
as: { type: String as PropType<'div'>, default: 'div' },
as: { type: String as PropType<HTMLTag>, default: 'div' },
layoutId: { type: [String, Number], default: undefined },
transition: { type: Object as PropType<Partial<Transition>>, default: undefined },
ignore: { type: Array as PropType<string[]>, default: () => [] },
Expand Down

0 comments on commit 4cfaf03

Please sign in to comment.