@fiscozen/tab 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/src/FzTabs.vue +12 -14
- package/src/__test__/__snapshots__/FzTabs.test.ts.snap +1 -1
- package/src/common.ts +11 -0
- package/src/components/{FzTabName.vue → FzTabButton.vue} +26 -10
- package/src/components/FzTabPicker.vue +16 -13
- package/src/types.ts +0 -5
- package/src/components/FzTabPickerValue.vue +0 -40
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fiscozen/tab",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Design System Tab component",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"keywords": [],
|
|
8
8
|
"author": "Cristian Barraco",
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@fiscozen/
|
|
11
|
-
"@fiscozen/
|
|
10
|
+
"@fiscozen/composables": "^0.1.34",
|
|
11
|
+
"@fiscozen/badge": "^0.1.2"
|
|
12
12
|
},
|
|
13
13
|
"peerDependencies": {
|
|
14
14
|
"tailwindcss": "^3.4.1",
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"@awesome.me/kit-8137893ad3": "^1.0.65",
|
|
34
34
|
"@fortawesome/fontawesome-svg-core": "^6.5.1",
|
|
35
35
|
"@fortawesome/vue-fontawesome": "^3.0.6",
|
|
36
|
+
"@fiscozen/tsconfig": "^0.1.0",
|
|
36
37
|
"@fiscozen/prettier-config": "^0.1.0",
|
|
37
38
|
"@fiscozen/eslint-config": "^0.1.0",
|
|
38
|
-
"@fiscozen/
|
|
39
|
-
"@fiscozen/icons": "^0.1.10"
|
|
39
|
+
"@fiscozen/icons": "^0.1.15"
|
|
40
40
|
},
|
|
41
41
|
"license": "MIT",
|
|
42
42
|
"scripts": {
|
package/src/FzTabs.vue
CHANGED
|
@@ -6,18 +6,17 @@
|
|
|
6
6
|
ref="tabContainer"
|
|
7
7
|
@wheel="onWheel"
|
|
8
8
|
>
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
/>
|
|
9
|
+
<template v-if="!horizontalOverflow && isOverflowing">
|
|
10
|
+
<FzTabPicker :tabs="tabs" :size="size" />
|
|
11
|
+
</template>
|
|
12
|
+
<template v-else>
|
|
13
|
+
<FzTabButton
|
|
14
|
+
v-for="tab in tabs"
|
|
15
|
+
:tab="tab"
|
|
16
|
+
:key="tab.title"
|
|
17
|
+
:size="size"
|
|
18
|
+
/>
|
|
19
|
+
</template>
|
|
21
20
|
<slot name="tabs-container-end" />
|
|
22
21
|
</div>
|
|
23
22
|
<slot name="tabs-end" />
|
|
@@ -35,12 +34,11 @@ import {
|
|
|
35
34
|
useSlots,
|
|
36
35
|
watch,
|
|
37
36
|
VNode,
|
|
38
|
-
onUnmounted,
|
|
39
37
|
onBeforeUnmount,
|
|
40
38
|
} from "vue";
|
|
41
39
|
import { FzTabsProps, FzTabProps } from "./types";
|
|
42
40
|
import FzTabPicker from "./components/FzTabPicker.vue";
|
|
43
|
-
import
|
|
41
|
+
import FzTabButton from "./components/FzTabButton.vue";
|
|
44
42
|
import FzTab from "./FzTab.vue";
|
|
45
43
|
|
|
46
44
|
const props = withDefaults(defineProps<FzTabsProps>(), {
|
|
@@ -20,7 +20,7 @@ exports[`FzTabs > renders with badgeContent on tab1 1`] = `
|
|
|
20
20
|
<div data-v-97c498eb="" class="flex flex-row">
|
|
21
21
|
<div data-v-97c498eb="" class="tab-container flex rounded-lg gap-8 p-2 bg-grey-100 w-fit max-w-full overflow-x-auto flex-row"><button data-v-97c498eb="" class="w-auto flex font-medium items-center max-w-[136px] rounded-md text-sm h-40 gap-6 py-8 px-12 bg-white text-blue-500 cursor-pointer" title="tab1" badgecontent="1">
|
|
22
22
|
<!--v-if--><span class="text-ellipsis whitespace-nowrap overflow-hidden">tab1</span>
|
|
23
|
-
<div class="flex items-center justify-center font-medium text-xs px-8
|
|
23
|
+
<div class="flex items-center justify-center font-medium text-xs px-8 size-20 bg-blue-500 text-core-white rounded-full !px-0">1</div>
|
|
24
24
|
</button><button data-v-97c498eb="" class="w-auto flex font-medium items-center max-w-[136px] rounded-md text-sm h-40 gap-6 py-8 px-12 text-grey-500 bg-grey-100 hover:bg-background-alice-blue active:bg-white active:text-blue-500 cursor-pointer" title="tab2">
|
|
25
25
|
<!--v-if--><span class="text-ellipsis whitespace-nowrap overflow-hidden">tab2</span>
|
|
26
26
|
<!--v-if-->
|
package/src/common.ts
CHANGED
|
@@ -2,3 +2,14 @@ export const mapSizeToClasses = {
|
|
|
2
2
|
sm: "text-sm h-40 gap-6 py-8 px-12",
|
|
3
3
|
md: "text-md h-40 gap-8 py-12 px-14",
|
|
4
4
|
};
|
|
5
|
+
|
|
6
|
+
export const mapSelectedTabToClasses = {
|
|
7
|
+
picker: "bg-background-alice-blue text-blue-500",
|
|
8
|
+
tab: "bg-white text-blue-500",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const mapUnselectedTabToClasses = {
|
|
12
|
+
picker:
|
|
13
|
+
"bg-white hover:bg-background-alice-blue text-black hover:text-blue-500",
|
|
14
|
+
tab: "text-grey-500 bg-grey-100 hover:bg-background-alice-blue active:bg-white active:text-blue-500",
|
|
15
|
+
};
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button :class="classes" @click="onClickTab" v-bind="tab">
|
|
3
3
|
<FzIcon v-if="tab.icon" :name="tab.icon" :size="size" />
|
|
4
|
-
<span class="text-ellipsis whitespace-nowrap overflow-hidden">{{
|
|
4
|
+
<span class="text-ellipsis flex-1 whitespace-nowrap overflow-hidden">{{
|
|
5
5
|
tab.title
|
|
6
6
|
}}</span>
|
|
7
7
|
<FzBadge
|
|
8
|
-
v-if="tab.badgeContent"
|
|
8
|
+
v-if="tab.badgeContent != null"
|
|
9
9
|
:color="selectedTab === tab.title ? 'blue' : 'black'"
|
|
10
10
|
:size="size"
|
|
11
11
|
>
|
|
12
12
|
{{ tab.badgeContent }}
|
|
13
13
|
</FzBadge>
|
|
14
|
+
<slot />
|
|
14
15
|
</button>
|
|
15
16
|
</template>
|
|
16
17
|
<script setup lang="ts">
|
|
@@ -18,27 +19,42 @@ import { inject, computed, Ref } from "vue";
|
|
|
18
19
|
import { FzBadge } from "@fiscozen/badge";
|
|
19
20
|
import { FzIcon } from "@fiscozen/icons";
|
|
20
21
|
import { FzTabProps } from "../types";
|
|
21
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
mapSelectedTabToClasses,
|
|
24
|
+
mapSizeToClasses,
|
|
25
|
+
mapUnselectedTabToClasses,
|
|
26
|
+
} from "../common";
|
|
22
27
|
|
|
23
|
-
const props =
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
const props = withDefaults(
|
|
29
|
+
defineProps<{
|
|
30
|
+
tab: FzTabProps;
|
|
31
|
+
size: "sm" | "md";
|
|
32
|
+
type: "picker" | "tab";
|
|
33
|
+
readonly: boolean;
|
|
34
|
+
}>(),
|
|
35
|
+
{
|
|
36
|
+
type: "tab",
|
|
37
|
+
readonly: false,
|
|
38
|
+
},
|
|
39
|
+
);
|
|
27
40
|
|
|
28
41
|
const selectedTab = inject<Ref<string>>("selectedTab");
|
|
42
|
+
const emit = defineEmits(["click"]);
|
|
29
43
|
|
|
30
44
|
const classes = computed(() => [
|
|
31
45
|
"w-auto flex font-medium items-center max-w-[136px] rounded-md",
|
|
32
46
|
mapSizeToClasses[props.size],
|
|
47
|
+
props.type === "picker" ? "text-left" : "",
|
|
33
48
|
selectedTab?.value === props.tab.title
|
|
34
|
-
?
|
|
35
|
-
:
|
|
49
|
+
? mapSelectedTabToClasses[props.type]
|
|
50
|
+
: mapUnselectedTabToClasses[props.type],
|
|
36
51
|
props.tab.disabled ? "cursor-not-allowed" : "cursor-pointer",
|
|
37
52
|
]);
|
|
38
53
|
|
|
39
54
|
const onClickTab = () => {
|
|
40
55
|
if (!props.tab.disabled) {
|
|
41
|
-
selectedTab!.value = props.tab.title;
|
|
56
|
+
if (!props.readonly) selectedTab!.value = props.tab.title;
|
|
57
|
+
emit("click");
|
|
42
58
|
}
|
|
43
59
|
};
|
|
44
60
|
</script>
|
|
@@ -3,29 +3,28 @@
|
|
|
3
3
|
position="bottom"
|
|
4
4
|
:isOpen
|
|
5
5
|
class="w-full overflow-hidden"
|
|
6
|
-
contentClass="bg-transparent"
|
|
6
|
+
contentClass="bg-transparent z-70"
|
|
7
7
|
>
|
|
8
8
|
<template #opener>
|
|
9
|
-
<
|
|
10
|
-
|
|
9
|
+
<FzTabButton
|
|
10
|
+
:tab="selectedTabProps!"
|
|
11
11
|
:size="size"
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
type="tab"
|
|
13
|
+
readonly
|
|
14
|
+
@click="isOpen = !isOpen"
|
|
14
15
|
>
|
|
15
|
-
<span class="overflow-hidden text-ellipsis whitespace-nowrap">
|
|
16
|
-
{{ selectedTab }}
|
|
17
|
-
</span>
|
|
18
16
|
<FzIcon :name="isOpen ? 'chevron-up' : 'chevron-down'" :size="size" />
|
|
19
|
-
</
|
|
17
|
+
</FzTabButton>
|
|
20
18
|
</template>
|
|
21
19
|
<div
|
|
22
20
|
class="flex flex-col p-4 rounded shadow overflow-hidden bg-core-white z-10"
|
|
23
21
|
:style="{ width: containerWidth }"
|
|
24
22
|
>
|
|
25
|
-
<
|
|
23
|
+
<FzTabButton
|
|
26
24
|
v-for="tab in tabs"
|
|
27
25
|
:tab="tab"
|
|
28
26
|
:size="size"
|
|
27
|
+
type="picker"
|
|
29
28
|
@click="closePicker"
|
|
30
29
|
/>
|
|
31
30
|
</div>
|
|
@@ -33,12 +32,13 @@
|
|
|
33
32
|
</template>
|
|
34
33
|
|
|
35
34
|
<script setup lang="ts">
|
|
36
|
-
import { ref, inject, computed } from "vue";
|
|
35
|
+
import { ref, inject, computed, Ref } from "vue";
|
|
37
36
|
import { FzFloating } from "@fiscozen/composables";
|
|
38
37
|
import { FzIcon } from "@fiscozen/icons";
|
|
38
|
+
import { FzBadge } from "@fiscozen/badge";
|
|
39
39
|
import { FzTabProps } from "../types";
|
|
40
40
|
import { mapSizeToClasses } from "../common";
|
|
41
|
-
import
|
|
41
|
+
import FzTabButton from "./FzTabButton.vue";
|
|
42
42
|
|
|
43
43
|
const isOpen = ref(false);
|
|
44
44
|
const props = defineProps<{
|
|
@@ -47,7 +47,10 @@ const props = defineProps<{
|
|
|
47
47
|
}>();
|
|
48
48
|
const opener = ref<HTMLElement>();
|
|
49
49
|
|
|
50
|
-
const selectedTab = inject("selectedTab");
|
|
50
|
+
const selectedTab = inject<Ref<string>>("selectedTab");
|
|
51
|
+
const selectedTabProps = computed(() => {
|
|
52
|
+
return props.tabs.find((tab) => tab.title === selectedTab?.value);
|
|
53
|
+
});
|
|
51
54
|
|
|
52
55
|
const computedClasses = computed(() => [
|
|
53
56
|
"flex items-center text-left max-w-[136px] rounded-md h-auto bg-white text-blue-500 font-medium cursor-pointer capitalize ",
|
package/src/types.ts
CHANGED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<button
|
|
3
|
-
:key="tab.title"
|
|
4
|
-
@click="onPickerValueClick"
|
|
5
|
-
:class="computedClasses"
|
|
6
|
-
:disabled="tab.disabled"
|
|
7
|
-
>
|
|
8
|
-
{{ tab.title }}
|
|
9
|
-
</button>
|
|
10
|
-
</template>
|
|
11
|
-
|
|
12
|
-
<script setup lang="ts">
|
|
13
|
-
import { Ref, inject, computed } from "vue";
|
|
14
|
-
import { FzTabProps } from "../types";
|
|
15
|
-
import { mapSizeToClasses } from "../common";
|
|
16
|
-
|
|
17
|
-
const props = defineProps<{
|
|
18
|
-
tab: FzTabProps;
|
|
19
|
-
size: "sm" | "md";
|
|
20
|
-
}>();
|
|
21
|
-
|
|
22
|
-
const emit = defineEmits(["click"]);
|
|
23
|
-
|
|
24
|
-
const selectedTab = inject<Ref<string>>("selectedTab");
|
|
25
|
-
const computedClasses = computed(() => [
|
|
26
|
-
mapSizeToClasses[props.size],
|
|
27
|
-
"flex items-center text-left max-w-[136px] h-auto bg-white text-blue-500 font-medium cursor-pointer capitalize rounded",
|
|
28
|
-
selectedTab?.value === props.tab.title
|
|
29
|
-
? "!bg-background-alice-blue"
|
|
30
|
-
: "hover:!bg-background-alice-blue !text-black hover:!text-blue-500",
|
|
31
|
-
props.tab.disabled ? "cursor-not-allowed" : "cursor-pointer",
|
|
32
|
-
]);
|
|
33
|
-
|
|
34
|
-
const onPickerValueClick = () => {
|
|
35
|
-
if (!props.tab.disabled) {
|
|
36
|
-
selectedTab!.value = props.tab.title;
|
|
37
|
-
emit("click");
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
</script>
|