Skip to content

Commit

Permalink
feat(Tabs): add new Headless UI's version tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
gravitano committed May 29, 2023
1 parent e00b1e4 commit f24de34
Show file tree
Hide file tree
Showing 14 changed files with 271 additions and 103 deletions.
48 changes: 24 additions & 24 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
module.exports = {
stories: [
'../packages/*/src/**/*.stories.@(js|jsx|ts|tsx|mdx)',
'../stories/**/*.stories.@(js|jsx|ts|tsx|mdx)',
],
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
framework: '@storybook/vue3',
core: {
builder: '@storybook/builder-vite',
},
features: {
storyStoreV7: true,
},
viteFinal: (config) => {
return {
...config,
build: {
...config.build,
sourcemap: false,
// target: ['es2020'],
},
};
},
};
module.exports = {
stories: [
'../packages/*/src/**/*.stories.@(js|jsx|ts|tsx|mdx)',
'../stories/**/*.stories.@(js|jsx|ts|tsx|mdx)',
],
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
framework: '@storybook/vue3',
core: {
builder: '@storybook/builder-vite',
},
features: {
storyStoreV7: true,
},
// viteFinal: (config) => {
// return {
// ...config,
// build: {
// ...config.build,
// sourcemap: false,
// // target: ['es2020'],
// },
// };
// },
};
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"@tailwindcss/typography": "^0.5.2",
"@typescript-eslint/eslint-plugin": "^5.30.6",
"@typescript-eslint/parser": "^5.30.6",
"@vitejs/plugin-vue": "^1.10.2",
"@vitejs/plugin-vue": "^4.2.3",
"@vitest/coverage-c8": "^0.31.1",
"@vitest/ui": "^0.31.1",
"@vue/compiler-sfc": "^3.3.4",
Expand All @@ -57,7 +57,7 @@
"conventional-changelog-cli": "^2.2.2",
"eslint": ">=5.16.0",
"eslint-plugin-storybook": "^0.6.10",
"eslint-plugin-vue": "^9.13.0",
"eslint-plugin-vue": "^9.14.1",
"happy-dom": "^9.19.2",
"husky": "^8.0.1",
"jsdom": "^21.1.1",
Expand Down
58 changes: 58 additions & 0 deletions packages/tabs/src/VTabGroup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<script setup lang="ts">
import {TabGroup} from '@headlessui/vue';
import type {TabVariants} from './variants';
import type {DefaultColors} from '@morpheme/theme/defaultTheme';
import {computed} from 'vue';
const props = withDefaults(
defineProps<{
modelValue?: number;
variant?: TabVariants;
vertical?: boolean;
centerActive?: boolean;
color?: DefaultColors;
}>(),
{
variant: 'underline',
color: 'primary',
},
);
const emit =
defineEmits<{
(e: 'update:modelValue', value: number): void;
}>();
const modelValue = computed({
get() {
return props.modelValue;
},
set(value: number) {
emit('update:modelValue', value);
},
});
function onTabChange(value: number) {
modelValue.value = value;
}
</script>

<template>
<TabGroup
class="v-tabs v-tabs--group"
:class="[
`v-tabs-${color}`,
`v-tabs--${variant}`,
{
'v-tabs--vertical': vertical,
'v-tabs--center-active': centerActive,
},
]"
as="div"
:selectedIndex="modelValue"
:vertical="vertical"
@change="onTabChange"
>
<slot />
</TabGroup>
</template>
18 changes: 18 additions & 0 deletions packages/tabs/src/VTabItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script setup lang="ts">
import {Tab} from '@headlessui/vue';
</script>

<template>
<Tab as="template" v-slot="{selected}">
<button
class="v-tabs-item"
:class="[
{
'v-tabs-item--active': selected,
},
]"
>
<slot />
</button>
</Tab>
</template>
9 changes: 9 additions & 0 deletions packages/tabs/src/VTabList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script setup lang="ts">
import {TabList} from '@headlessui/vue';
</script>

<template>
<TabList class="v-tabs-items">
<slot />
</TabList>
</template>
9 changes: 9 additions & 0 deletions packages/tabs/src/VTabPanel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script setup lang="ts">
import {TabPanel} from '@headlessui/vue';
</script>

<template>
<TabPanel class="v-tabs-panel">
<slot />
</TabPanel>
</template>
9 changes: 9 additions & 0 deletions packages/tabs/src/VTabPanels.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script setup lang="ts">
import {TabPanels} from '@headlessui/vue';
</script>

<template>
<TabPanels class="v-tabs-panels">
<slot />
</TabPanels>
</template>
38 changes: 37 additions & 1 deletion packages/tabs/src/VTabs.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import VCard from '@morpheme/card';
import {ref} from 'vue';
import {Story} from '@storybook/vue3';
import VTabsSlider from './VTabsSlider.vue';
import VTabList from './VTabList.vue';
import VTabPanels from './VTabPanels.vue';
import VTabPanel from './VTabPanel.vue';
import VTabGroup from './VTabGroup.vue';
import VTabItem from './VTabItem.vue';

function createItems(len = 20, additionalItem = {}) {
return [...Array(20)].map((v, k) => ({
Expand Down Expand Up @@ -46,7 +51,6 @@ export default {
},
},
args: {
modelValue: 0,
items: createItems(),
},
};
Expand Down Expand Up @@ -574,3 +578,35 @@ export const DarkMode: Story = (args) => ({
</div>
`,
});

export const HeadlessUI: Story = (args) => ({
components: {
VTabGroup,
VTabsSlider,
VTabList,
VTabItem,
VTabPanels,
VTabPanel,
},
setup() {
const tab = ref(1);
delete args.items;
return {args, tab};
},
template: `
<VTabGroup v-model="tab" v-bind="args">
<VTabList>
<VTabItem>Tab 1</VTabItem>
<VTabItem>Tab 2</VTabItem>
<VTabItem>Tab 3</VTabItem>
</VTabList>
<VTabPanels>
<VTabPanel>Tab 1 content</VTabPanel>
<VTabPanel>Tab 2 content</VTabPanel>
<VTabPanel>Tab 3 content</VTabPanel>
</VTabPanels>
</VTabGroup>
<p class="font-mono text-sm">Selected: {{ tab }}</p>
`,
});
10 changes: 10 additions & 0 deletions packages/tabs/src/VTabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Icon from '@morpheme/icon';
import VTab from './VTab.vue';
import VTabsSlider from './VTabsSlider.vue';
import {TabVariants} from './variants';
import {VTabsApiSymbol} from './api';
const props = defineProps({
modelValue: {
Expand Down Expand Up @@ -260,6 +261,15 @@ const onTabRemoved = (index: number) => {
};
provide('activeTab', readonly(selected));
provide(VTabsApiSymbol, {
selected,
onTabClicked,
onTabRemoved,
setTabRef,
next,
previous,
});
</script>

<template>
Expand Down
1 change: 1 addition & 0 deletions packages/tabs/src/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const VTabsApiSymbol = Symbol('VTabs');
11 changes: 8 additions & 3 deletions packages/tabs/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import './VTabs.dark.scss';
export * from './types';
export * from './variants';
export * from './api';
export {default} from './VTabs.vue';
export {default as VTabs} from './VTabs.vue';
export {default as VTab} from './VTab.vue';
export {default as VTabsSlider} from './VTabsSlider.vue';
export * from './types';
export * from './variants';
export {default as VTabGroup} from './VTabGroup.vue';
export {default as VTabItem} from './VTabItem.vue';
export {default as VTabList} from './VTabList.vue';
export {default as VTabPanel} from './VTabPanel.vue';
export {default as VTabPanels} from './VTabPanels.vue';
15 changes: 14 additions & 1 deletion packages/themes/src/morpheme/_tabs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@
display: flex;
align-items: center;

&--group:not(&--vertical) {
flex-direction: column;
align-items: flex-start;
}

&-panels {
padding: var(--v-tabs-padding-y) var(--v-tabs-padding-x);
flex: 1 1 0%;
}

&-slider {
height: var(--v-tabs-slider-height);
width: var(--v-tabs-slider-width);
Expand Down Expand Up @@ -90,9 +100,12 @@
}

/* vertical */
&--vertical {
align-items: flex-start;
}

&--vertical &-items {
flex-direction: column;
width: 100%;
}

&--vertical &-slider {
Expand Down
Loading

0 comments on commit f24de34

Please sign in to comment.