Skip to content

Commit

Permalink
feat(components): add tabs component
Browse files Browse the repository at this point in the history
  • Loading branch information
chizukicn committed Nov 10, 2023
1 parent 8c1f0be commit 580ef36
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 10 deletions.
2 changes: 2 additions & 0 deletions packages/components/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export * from "../core/src/item/component";
export * from "../core/src/icon/component";
export * from "../core/src/switch/component";
export * from "../core/src/config-provider/component";
export * from "../core/src/tabs/component";
export * from "../core/src/tab-pane/component";
4 changes: 2 additions & 2 deletions packages/core/src/config-provider/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { provideSharedConfig } from "@hoci/core";
export const HiConfigProvider = defineComponent({
props: {
icon: {
type: Object as PropType<SharedConfig["icon"]>
type: Object as PropType<Partial<SharedConfig["icon"]>>
},
activateEvent: {
type: String as PropType<SharedConfig["activateEvent"]>
type: String as PropType<Partial<SharedConfig["activateEvent"]>>
}
},
setup(props, context) {
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/item/component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { capitalize, defineComponent, h } from "vue";
import { defineComponent, h } from "vue";
import { itemProps, useSelectionItem } from "@hoci/core";
import { capitalize } from "tslx";

export const HiItem = defineComponent({
name: "HiItem",
Expand Down
17 changes: 11 additions & 6 deletions packages/core/src/item/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,20 @@ export const useSelectionItem = defineHookComponent({
context.changeActive(props.value);
};

const label = computed(() => {
let label = props.label ?? context.label;
if (label && typeof label == "function") {
label = label(props.value)!;
}
return Array.isArray(label) ? label : [label];
});

function render() {
return renderSlot(slots, "default", {
active: context.isActive(props.value),
activate
}, () => {
let label = props.label ?? context.label;
if (label && typeof label == "function") {
label = label(props.value)!;
}
return Array.isArray(label) ? label : [label];
return label.value;
});
}

Expand Down Expand Up @@ -104,7 +108,8 @@ export const useSelectionItem = defineHookComponent({
isActive,
isDisabled,
className,
activateEvent
activateEvent,
label
};
}
});
Expand Down
21 changes: 21 additions & 0 deletions packages/core/src/tab-pane/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { defineComponent, h } from "vue";
import { capitalize } from "tslx";
import { itemProps, useSelectionItem } from "../item";

export const HiTabPane = defineComponent({
props: {
...itemProps
},
setup(props, context) {
const { className, activateEvent, activate, isDisabled, label } = useSelectionItem(props, context);
return () => {
return h("div",
{
class: className.value,
[`on${capitalize(activateEvent.value)}`]: activate,
disabled: isDisabled.value
}
, label.value);
};
}
});
42 changes: 42 additions & 0 deletions packages/core/src/tabs/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { defineComponent, h, renderSlot } from "vue";
import { classPropType } from "@hoci/shared";
import { selectionProps, useSelectionList } from "../selection";

export const HiTabs = defineComponent({
props: {
...selectionProps,
headerClass: {
type: classPropType
},
contentClass: {
type: classPropType
},
as: {
type: String,
default: "div"
},
headerAs: {
type: String,
default: "div"
},
contentAs: {
type: String,
default: "div"
}
},
setup(props, context) {
const selection = useSelectionList(props, context);

return () => {
const content = selection.renderItem();
return h(props.as, [
h(props.headerAs, {
class: props.headerClass
}, renderSlot(context.slots, "default")),
h(props.contentAs, {
class: props.contentClass
}, content)
]);
};
}
});
20 changes: 19 additions & 1 deletion playground/src/app.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
<script lang="tsx">
import { defineComponent, reactive, ref } from "vue";
import { HiAffix, HiConfigProvider, HiIcon, HiItem, HiSelection, HiSwitch } from "hoci";
import { HiAffix, HiConfigProvider, HiIcon, HiItem, HiSelection, HiSwitch, HiTabPane, HiTabs } from "hoci";
import hociSvg from "./assets/hoci.svg";
const Tab1 = defineComponent(() => {
return () => <div class="p-4">
<HiSwitch as="span" class="cursor-pointer duration-200 select-none" activeClass="text-hex-f00">Tab 1</HiSwitch>
</div>;
});
export default defineComponent(() => {
const selectedIndex = ref<number[] | number>(2);
const logs = ref<string[]>([]);
Expand Down Expand Up @@ -39,6 +45,18 @@ export default defineComponent(() => {
<HiConfigProvider icon={{ size: 96 }}>
<hi-icon class="text-green rounded w-12 h-12" src={hociSvg}/>
<HiIcon size={0} class="text-green rounded w-12 h-12" src={hociSvg}/>
<HiTabs
headerClass="flex space-x-3"
itemClass="b-1 b-solid px-2 b-gray-3 rounded cursor-pointer"
activeClass="b-transparent bg-blue-3 text-white"
v-model={selectedIndex.value} class="mt-12">
<HiTabPane value={1} label="tab1">
<Tab1/>
</HiTabPane>
<HiTabPane value={2} label="tab2">
这是Tab 2
</HiTabPane>
</HiTabs>
<HiAffix class="my-1" as="div" offset={30}>
<div class="inline-block p-4 bg-blue-200" >
Offset Top 30px
Expand Down

0 comments on commit 580ef36

Please sign in to comment.