mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-10-17 07:03:42 +08:00
feat(packages): materials support slider-tab. closed #823
This commit is contained in:
@@ -95,3 +95,27 @@
|
|||||||
.chrome-tab_dark .chrome-tab-divider {
|
.chrome-tab_dark .chrome-tab-divider {
|
||||||
background-color: rgba(255, 255, 255, 0.9);
|
background-color: rgba(255, 255, 255, 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.slider-tab {
|
||||||
|
background-color: transparent;
|
||||||
|
height: 100%;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-tab_dark {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-tab:hover {
|
||||||
|
color: var(--soy-primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-tab_active {
|
||||||
|
color: var(--soy-primary-color);
|
||||||
|
background-color: var(--soy-primary-color-opacity1);
|
||||||
|
border-bottom-color: var(--soy-primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-tab_active_dark {
|
||||||
|
background-color: var(--soy-primary-color-opacity2);
|
||||||
|
}
|
||||||
|
@@ -10,6 +10,10 @@ declare const styles: {
|
|||||||
readonly 'chrome-tab_dark': string;
|
readonly 'chrome-tab_dark': string;
|
||||||
readonly 'chrome-tab-divider': string;
|
readonly 'chrome-tab-divider': string;
|
||||||
readonly 'svg-close': string;
|
readonly 'svg-close': string;
|
||||||
|
readonly 'slider-tab': string;
|
||||||
|
readonly 'slider-tab_active': string;
|
||||||
|
readonly 'slider-tab_active_dark': string;
|
||||||
|
readonly 'slider-tab_dark': string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default styles;
|
export default styles;
|
||||||
|
@@ -5,6 +5,7 @@ import type { PageTabMode, PageTabProps } from '../../types';
|
|||||||
import { ACTIVE_COLOR, createTabCssVars } from './shared';
|
import { ACTIVE_COLOR, createTabCssVars } from './shared';
|
||||||
import ChromeTab from './chrome-tab.vue';
|
import ChromeTab from './chrome-tab.vue';
|
||||||
import ButtonTab from './button-tab.vue';
|
import ButtonTab from './button-tab.vue';
|
||||||
|
import SliderTab from './slider-tab.vue';
|
||||||
import SvgClose from './svg-close.vue';
|
import SvgClose from './svg-close.vue';
|
||||||
import style from './index.module.css';
|
import style from './index.module.css';
|
||||||
|
|
||||||
@@ -26,7 +27,7 @@ interface Emits {
|
|||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
const activeTabComponent = computed(() => {
|
const activeTabComponent = computed(() => {
|
||||||
const { mode, chromeClass, buttonClass } = props;
|
const { mode, chromeClass, buttonClass, sliderClass } = props;
|
||||||
|
|
||||||
const tabComponentMap = {
|
const tabComponentMap = {
|
||||||
chrome: {
|
chrome: {
|
||||||
@@ -36,6 +37,10 @@ const activeTabComponent = computed(() => {
|
|||||||
button: {
|
button: {
|
||||||
component: ButtonTab,
|
component: ButtonTab,
|
||||||
class: buttonClass
|
class: buttonClass
|
||||||
|
},
|
||||||
|
slider: {
|
||||||
|
component: SliderTab,
|
||||||
|
class: sliderClass
|
||||||
}
|
}
|
||||||
} satisfies Record<PageTabMode, { component: Component; class?: string }>;
|
} satisfies Record<PageTabMode, { component: Component; class?: string }>;
|
||||||
|
|
||||||
@@ -45,7 +50,7 @@ const activeTabComponent = computed(() => {
|
|||||||
const cssVars = computed(() => createTabCssVars(props.activeColor));
|
const cssVars = computed(() => createTabCssVars(props.activeColor));
|
||||||
|
|
||||||
const bindProps = computed(() => {
|
const bindProps = computed(() => {
|
||||||
const { chromeClass: _chromeCls, buttonClass: _btnCls, ...rest } = props;
|
const { chromeClass: _chromeCls, buttonClass: _btnCls, sliderClass: _sliderCls, ...rest } = props;
|
||||||
|
|
||||||
return rest;
|
return rest;
|
||||||
});
|
});
|
||||||
|
53
packages/materials/src/libs/page-tab/slider-tab.vue
Normal file
53
packages/materials/src/libs/page-tab/slider-tab.vue
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { PageTabProps } from '../../types';
|
||||||
|
import style from './index.module.css';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'SliderTab'
|
||||||
|
});
|
||||||
|
|
||||||
|
defineProps<PageTabProps>();
|
||||||
|
|
||||||
|
type SlotFn = (props?: Record<string, unknown>) => any;
|
||||||
|
|
||||||
|
type Slots = {
|
||||||
|
/**
|
||||||
|
* Slot
|
||||||
|
*
|
||||||
|
* The center content of the tab
|
||||||
|
*/
|
||||||
|
default?: SlotFn;
|
||||||
|
/**
|
||||||
|
* Slot
|
||||||
|
*
|
||||||
|
* The left content of the tab
|
||||||
|
*/
|
||||||
|
prefix?: SlotFn;
|
||||||
|
/**
|
||||||
|
* Slot
|
||||||
|
*
|
||||||
|
* The right content of the tab
|
||||||
|
*/
|
||||||
|
suffix?: SlotFn;
|
||||||
|
};
|
||||||
|
|
||||||
|
defineSlots<Slots>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class=":soy: relative inline-flex cursor-pointer items-center justify-center gap-6px whitespace-nowrap px-12px py-4px"
|
||||||
|
:class="[
|
||||||
|
style['slider-tab'],
|
||||||
|
{ [style['slider-tab_dark']]: darkMode },
|
||||||
|
{ [style['slider-tab_active']]: active },
|
||||||
|
{ [style['slider-tab_active_dark']]: active && darkMode }
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<slot name="prefix"></slot>
|
||||||
|
<slot></slot>
|
||||||
|
<slot name="suffix"></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
@@ -239,7 +239,7 @@ export type LayoutCssVars = {
|
|||||||
*
|
*
|
||||||
* @default chrome
|
* @default chrome
|
||||||
*/
|
*/
|
||||||
export type PageTabMode = 'button' | 'chrome';
|
export type PageTabMode = 'button' | 'chrome' | 'slider';
|
||||||
|
|
||||||
export interface PageTabProps {
|
export interface PageTabProps {
|
||||||
/** Whether is dark mode */
|
/** Whether is dark mode */
|
||||||
@@ -262,6 +262,8 @@ export interface PageTabProps {
|
|||||||
buttonClass?: string;
|
buttonClass?: string;
|
||||||
/** The class of the chrome tab */
|
/** The class of the chrome tab */
|
||||||
chromeClass?: string;
|
chromeClass?: string;
|
||||||
|
/** The class of the title tab */
|
||||||
|
sliderClass?: string;
|
||||||
/** Whether the tab is active */
|
/** Whether the tab is active */
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
/** The color of the active tab */
|
/** The color of the active tab */
|
||||||
|
@@ -40,7 +40,8 @@ export const themeScrollModeOptions = transformRecordToOption(themeScrollModeRec
|
|||||||
|
|
||||||
export const themeTabModeRecord: Record<UnionKey.ThemeTabMode, App.I18n.I18nKey> = {
|
export const themeTabModeRecord: Record<UnionKey.ThemeTabMode, App.I18n.I18nKey> = {
|
||||||
chrome: 'theme.layout.tab.mode.chrome',
|
chrome: 'theme.layout.tab.mode.chrome',
|
||||||
button: 'theme.layout.tab.mode.button'
|
button: 'theme.layout.tab.mode.button',
|
||||||
|
slider: 'theme.layout.tab.mode.slider'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const themeTabModeOptions = transformRecordToOption(themeTabModeRecord);
|
export const themeTabModeOptions = transformRecordToOption(themeTabModeRecord);
|
||||||
|
@@ -169,7 +169,9 @@ init();
|
|||||||
<div
|
<div
|
||||||
ref="tabRef"
|
ref="tabRef"
|
||||||
class="h-full flex pr-18px"
|
class="h-full flex pr-18px"
|
||||||
:class="[themeStore.tab.mode === 'chrome' ? 'items-end' : 'items-center gap-12px']"
|
:class="[
|
||||||
|
themeStore.tab.mode === 'chrome' || themeStore.tab.mode === 'slider' ? 'items-end' : 'items-center gap-12px'
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<PageTab
|
<PageTab
|
||||||
v-for="tab in tabStore.tabs"
|
v-for="tab in tabStore.tabs"
|
||||||
|
@@ -135,6 +135,7 @@ const local: App.I18n.Schema = {
|
|||||||
height: 'Tab Height',
|
height: 'Tab Height',
|
||||||
mode: {
|
mode: {
|
||||||
title: 'Tab Mode',
|
title: 'Tab Mode',
|
||||||
|
slider: 'Slider',
|
||||||
chrome: 'Chrome',
|
chrome: 'Chrome',
|
||||||
button: 'Button'
|
button: 'Button'
|
||||||
}
|
}
|
||||||
|
@@ -132,6 +132,7 @@ const local: App.I18n.Schema = {
|
|||||||
height: '标签栏高度',
|
height: '标签栏高度',
|
||||||
mode: {
|
mode: {
|
||||||
title: '标签栏风格',
|
title: '标签栏风格',
|
||||||
|
slider: '滑块风格',
|
||||||
chrome: '谷歌风格',
|
chrome: '谷歌风格',
|
||||||
button: '按钮风格'
|
button: '按钮风格'
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user