Skip to content

Commit

Permalink
Add tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
xinjie-zhang committed Dec 10, 2022
1 parent 9d52d4e commit bbbf3b0
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 1 deletion.
69 changes: 69 additions & 0 deletions components/tabs.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<template x-component:hui="tab-group" x-modelable="value" x-data="{value : null}">
<slot></slot>
<script>
return {
isSelected(val) {
return val === this.value
},
select(val) {
this.value = val
}
}
</script>
</template>
<template x-component:hui="tab-list">
<slot></slot>
<script>
return {
onMounted() {
let container = this.$closest('tab-group')
if (!container) throw Error('tab-list should be contained in tab-group')
}
}
</script>
</template>
<template x-component:hui="tab" x-data="{
get selected(){return $api && $api.context.isSelected($api.value)}
}" @click="$api.onSelect()">
<slot></slot>
<script>
return {
get context() { return this.$of('tab-group') },
get value() { return this.$prop('value') },
get disabled() { return this.$prop('disabled') },
onMounted() {
let container = this.$closest('tab-list')
if (!container) throw Error('tab should be contained in tab-list')
},
onSelect() {
if (this.disabled) return
this.context.select(this.value)
}
}
</script>
</template>
<template x-component:hui="tab-panels">
<slot></slot>
<script>
return {
onMounted() {
let container = this.$closest('tab-group')
if (!container) throw Error('tab-panels should be contained in tab-group')
}
}
</script>
</template>
<template x-component:hui="tab-panel" x-data="{
get selected(){return $api && $api.context.isSelected($prop('value'))}
}" x-show="selected">
<slot></slot>
<script>
return {
get context() { return this.$of('tab-group') },
onMounted() {
let container = this.$closest('tab-panels')
if (!container) throw Error('tab-panel should be contained in tab-panels')
}
}
</script>
</template>
81 changes: 81 additions & 0 deletions examples/tabs/tabs.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<head>
<!--
<script src="https://unpkg.com/@vimesh/style" defer></script>
<script src="https://unpkg.com/@vimesh/ui"></script>
<script src="https://unpkg.com/alpinejs" defer></script>
-->

<script src="/node_modules/@vimesh/style/dist/vs.dev.js" defer></script>
<script src="/node_modules/@vimesh/ui/dist/vui.dev.js"></script>
<script src="/node_modules/alpinejs/dist/cdn.js" defer></script>

<script>
$vui.config.importMap = {
"*": '/components/${component}.html'
}
</script>
<style>
[x-cloak] {
display: none !important;
}
</style>

<script>

let data = {
manual: false,
tabs: [
{ name: 'My Account', content: 'Tab content for my account' },
{ name: 'Company', content: 'Tab content for company', disabled: true },
{ name: 'Team Members', content: 'Tab content for team members' },
{ name: 'Billing', content: 'Tab content for billing' },
]
}
data.selectedTab = data.tabs[0].name
</script>
</head>

<body x-cloak x-import="hui/tabs,switch" class="p-2" x-data="data">
<div class="flex h-full w-screen flex-col items-start space-y-12 bg-gray-50 p-12">
<hui-switch-group as="div" class="flex items-center space-x-4">
<hui-switch-label>Manual keyboard activation</hui-switch-label>

<hui-switch as="button" x-model="manual" :class="['relative inline-flex flex-shrink-0 h-6 transition-colors duration-200 ease-in-out border-2 border-transparent rounded-full cursor-pointer w-11 focus:outline-none focus:shadow-outline',
checked ? 'bg-indigo-600' : 'bg-gray-200']">
<span class="inline-block h-5 w-5 transform rounded-full bg-white transition duration-200 ease-in-out"
:class="{ 'translate-x-5': checked, 'translate-x-0': !checked }"></span>
</hui-switch>
</hui-switch-group>

<hui-tab-group class="flex w-full max-w-3xl flex-col" :manual="manual" x-model="selectedTab">
<hui-tab-list class="relative z-0 flex divide-x divide-gray-200 rounded-lg shadow">

<template x-for="(tab, tabIdx) in tabs" :key="tab.name">
<hui-tab :value="tab.name" :disabled="tab.disabled"
class="group relative min-w-0 flex-1 overflow-hidden bg-white py-4 px-4 text-center text-sm font-medium hover:bg-gray-50 focus:z-10"
:class="{
'text-gray-900': selected,
'text-gray-500 hover:text-gray-700': !selected,
'rounded-l-lg': tabIdx === 0,
'rounded-r-lg': tabIdx === tabs.length - 1,
'opacity-50': tab.disabled,
}">
<span x-text="tab.name"></span>
<template x-if="tab.disabled">
<small class="inline-block px-4 text-xs">(disabled)</small>
</template>
<span aria-hidden="true" class="absolute inset-x-0 bottom-0 h-0.5"
:class="{ 'bg-indigo-500': selected, 'bg-transparent': !selected }"></span>
</hui-tab>
</template>
</hui-tab-list>

<hui-tab-panels class="mt-4">
<template x-for="tab in tabs" :key="tab.name">
<hui-tab-panel :value="tab.name" class="rounded-lg bg-white p-4 shadow" x-html="tab.content">
</hui-tab-panel>
</template>
</hui-tab-panels>
</hui-tab-group>
</div>
</body>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vimesh/headless",
"version": "0.2.0",
"version": "0.3.0",
"repository": "https://github.com/vimeshjs/vimesh-headless.git",
"author": "Jacky ZHANG <[email protected]>",
"license": "MIT",
Expand Down

0 comments on commit bbbf3b0

Please sign in to comment.