This commit is contained in:
dap
2024-08-15 09:27:39 +08:00
84 changed files with 577 additions and 262 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/design",
"version": "5.0.1",
"version": "5.1.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -52,12 +52,12 @@
--secondary-foreground: 0 0% 98%;
/* Used for accents such as hover effects on <DropdownMenuItem>, <SelectItem>...etc */
--accent: 240 3.7% 15.9%;
--accent-hover: 240 3.7% 20.9%;
--accent: 216 5% 19%;
--accent-hover: 216 5% 24%;
--accent-foreground: 0 0% 98%;
/* Darker color */
--heavy: 240 3.7% 20.9%;
--heavy: 216 5% 24%;
--heavy-foreground: var(--accent-foreground);
/* Default border color */
@@ -82,15 +82,15 @@
/* 基本文字大小 */
--font-size-base: 16px;
/* 主体内容背景色 */
--content: 240 11% 96%;
/* =============component & UI============= */
--sidebar: 222.34deg 10.43% 12.27%;
--sidebar-deep: 220deg 13.06% 9%;
--menu: var(--sidebar);
/* header */
--header: 222.34deg 10.43% 12.27%;
color-scheme: dark;
}
@@ -117,6 +117,7 @@
--ring: 263.4 70% 50.4%;
--sidebar: 224 71.4% 4.1%;
--sidebar-deep: 224 71.4% 4.1%;
--header: 224 71.4% 4.1%;
}
.dark[data-theme='pink'],
@@ -142,6 +143,7 @@
--ring: 346.8 77.2% 49.8%;
--sidebar: 20 14.3% 4.1%;
--sidebar-deep: 20 14.3% 4.1%;
--header: 20 14.3% 4.1%;
}
.dark[data-theme='rose'],
@@ -167,6 +169,7 @@
--ring: 0 72.2% 50.6%;
--sidebar: 0 0% 3.9%;
--sidebar-deep: 0 0% 3.9%;
--header: 0 0% 3.9%;
}
.dark[data-theme='sky-blue'],
@@ -192,6 +195,7 @@
--ring: 224.3 76.3% 48%;
--sidebar: 222.2 84% 4.9%;
--sidebar-deep: 222.2 84% 4.9%;
--header: 222.2 84% 4.9%;
}
.dark[data-theme='deep-blue'],
@@ -217,6 +221,7 @@
--ring: 224.3 76.3% 48%;
--sidebar: 222.2 84% 4.9%;
--sidebar-deep: 222.2 84% 4.9%;
--header: 222.2 84% 4.9%;
}
.dark[data-theme='green'],
@@ -242,6 +247,7 @@
--ring: 142.4 71.8% 29.2%;
--sidebar: 20 14.3% 4.1%;
--sidebar-deep: 20 14.3% 4.1%;
--header: 20 14.3% 4.1%;
}
.dark[data-theme='deep-green'],
@@ -267,6 +273,7 @@
--ring: 142.4 71.8% 29.2%;
--sidebar: 20 14.3% 4.1%;
--sidebar-deep: 20 14.3% 4.1%;
--header: 20 14.3% 4.1%;
}
.dark[data-theme='orange'],
@@ -292,6 +299,7 @@
--ring: 20.5 90.2% 48.2%;
--sidebar: 20 14.3% 4.1%;
--sidebar-deep: 20 14.3% 4.1%;
--header: 20 14.3% 4.1%;
}
.dark[data-theme='yellow'],
@@ -317,6 +325,7 @@
--ring: 35.5 91.7% 32.9%;
--sidebar: 20 14.3% 4.1%;
--sidebar-deep: 20 14.3% 4.1%;
--header: 20 14.3% 4.1%;
}
.dark[data-theme='zinc'],
@@ -342,6 +351,7 @@
--ring: 240 4.9% 83.9%;
--sidebar: 240 10% 3.9%;
--sidebar-deep: 240 10% 3.9%;
--header: 240 4.9% 83.9%;
}
.dark[data-theme='neutral'],
@@ -367,6 +377,7 @@
--ring: 0 0% 83.1%;
--sidebar: 0 0% 3.9%;
--sidebar-deep: 0 0% 3.9%;
--header: 0 0% 3.9%;
}
.dark[data-theme='slate'],
@@ -392,6 +403,7 @@
--ring: 212.7 26.8% 83.9;
--sidebar: 222.2 84% 4.9%;
--sidebar-deep: 222.2 84% 4.9%;
--header: 222.2 84% 4.9%;
}
.dark[data-theme='gray'],
@@ -417,4 +429,5 @@
--ring: 216 12.2% 83.9%;
--sidebar: 224 71.4% 4.1%;
--sidebar-deep: 224 71.4% 4.1%;
--header: 224 71.4% 4.1%;
}

View File

@@ -8,7 +8,7 @@
/* 主体区域背景色 */
--background-deep: 210 11.11% 96.47%;
--foreground: 222 84% 5%;
--foreground: 210 6% 21%;
/* Background color for <Card /> */
--card: 0 0% 100%;
@@ -82,16 +82,16 @@
/* 基本文字大小 */
--font-size-base: 16px;
/* 主体内容背景色 */
--content: 240 11% 96%;
/* =============component & UI============= */
/* menu */
--sidebar: 0 0% 100%;
--sidebar-deep: 210 11.11% 96.47%;
--sidebar-deep: 0 0% 100%;
--menu: var(--sidebar);
/* header */
--header: 0 0% 100%;
accent-color: var(--primary);
color-scheme: light;
}

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/icons",
"version": "5.0.1",
"version": "5.1.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -38,7 +38,7 @@ export {
RotateCw,
Search,
SearchX,
Settings2,
Settings,
Sun,
SunMoon,
SwatchBook,

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/shared",
"version": "5.0.1",
"version": "5.1.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/typings",
"version": "5.0.1",
"version": "5.1.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -7,6 +7,13 @@ type LayoutType =
type ThemeModeType = 'auto' | 'dark' | 'light';
/**
* 偏好设置按钮位置
* fixed 固定在右侧
* header 顶栏
*/
type PreferencesButtonPositionType = 'fixed' | 'header';
type BuiltinThemeType =
| 'custom'
| 'deep-blue'
@@ -92,6 +99,7 @@ export type {
LoginExpiredModeType,
NavigationStyleType,
PageTransitionType,
PreferencesButtonPositionType,
TabsStyleType,
ThemeModeType,
};

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/composables",
"version": "5.0.1",
"version": "5.1.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/preferences",
"version": "5.0.1",
"version": "5.1.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -19,6 +19,7 @@ const defaultPreferences: Preferences = {
locale: 'zh-CN',
loginExpiredMode: 'modal',
name: 'Vben Admin',
preferencesButtonPosition: 'fixed',
watermark: false,
},
breadcrumb: {
@@ -90,7 +91,8 @@ const defaultPreferences: Preferences = {
colorWarning: 'hsl(42 84% 61%)',
mode: 'auto',
radius: '0.5',
semiDarkMenu: true,
semiDarkHeader: false,
semiDarkSidebar: true,
},
transition: {
enable: true,

View File

@@ -10,6 +10,7 @@ import type {
LoginExpiredModeType,
NavigationStyleType,
PageTransitionType,
PreferencesButtonPositionType,
TabsStyleType,
ThemeModeType,
} from '@vben-core/typings';
@@ -49,6 +50,8 @@ interface AppPreferences {
loginExpiredMode: LoginExpiredModeType;
/** 应用名 */
name: string;
/** 偏好设置按钮位置 */
preferencesButtonPosition: PreferencesButtonPositionType;
/**
* @zh_CN 是否开启水印
*/
@@ -183,8 +186,10 @@ interface ThemePreferences {
mode: ThemeModeType;
/** 圆角 */
radius: string;
/** 是否开启半深色header只在theme='light'时生效) */
semiDarkHeader: boolean;
/** 是否开启半深色菜单只在theme='light'时生效) */
semiDarkMenu: boolean;
semiDarkSidebar: boolean;
}
interface TransitionPreferences {

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/layout-ui",
"version": "5.0.1",
"version": "5.1.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -36,6 +36,10 @@ interface Props {
* 侧边菜单宽度
*/
sidebarWidth: number;
/**
* 主题
*/
theme: string | undefined;
/**
* 宽度
*/
@@ -76,15 +80,16 @@ function handleToggleMenu() {
<template>
<header
:class="theme"
:style="style"
class="border-border bg-background top-0 flex w-full flex-[0_0_auto] items-center border-b transition-[margin-top] duration-200"
class="border-border bg-header top-0 flex w-full flex-[0_0_auto] items-center border-b transition-[margin-top] duration-200"
>
<div v-if="slots.logo" :style="logoStyle">
<slot name="logo"></slot>
</div>
<VbenIconButton
v-if="showToggleBtn || isMobile"
class="my-0 ml-2 mr-1 rounded"
class="my-0 ml-2 mr-1 rounded-md"
@click="handleToggleMenu"
>
<Menu class="size-4" />

View File

@@ -24,9 +24,8 @@ interface Props {
domVisible?: boolean;
/**
* 扩展区域宽度
* @default 180
*/
extraWidth?: number;
extraWidth: number;
/**
* 固定扩展区域
* @default false
@@ -69,13 +68,12 @@ interface Props {
/**
* 主题
*/
theme?: string;
theme: string;
/**
* 宽度
* @default 180
*/
width?: number;
width: number;
/**
* zIndex
* @default 0
@@ -87,7 +85,6 @@ const props = withDefaults(defineProps<Props>(), {
collapseHeight: 42,
collapseWidth: 48,
domVisible: true,
extraWidth: 180,
fixedExtra: false,
isSidebarMixed: false,
marginTop: 0,
@@ -95,8 +92,6 @@ const props = withDefaults(defineProps<Props>(), {
paddingTop: 0,
show: true,
showCollapseButton: true,
theme: 'dark',
width: 180,
zIndex: 0,
});
@@ -181,10 +176,8 @@ const extraContentStyle = computed((): CSSProperties => {
});
const collapseStyle = computed((): CSSProperties => {
const { collapseHeight } = props;
return {
height: `${collapseHeight}px`,
height: `${props.collapseHeight}px`,
};
});

View File

@@ -0,0 +1,41 @@
import type { LayoutType } from '@vben-core/typings';
import type { VbenLayoutProps } from '../vben-layout';
import { computed } from 'vue';
export function useLayout(props: VbenLayoutProps) {
const currentLayout = computed(() =>
props.isMobile ? 'sidebar-nav' : (props.layout as LayoutType),
);
/**
* 是否全屏显示content不需要侧边、底部、顶部、tab区域
*/
const isFullContent = computed(() => currentLayout.value === 'full-content');
/**
* 是否侧边混合模式
*/
const isSidebarMixedNav = computed(
() => currentLayout.value === 'sidebar-mixed-nav',
);
/**
* 是否为头部导航模式
*/
const isHeaderNav = computed(() => currentLayout.value === 'header-nav');
/**
* 是否为混合导航模式
*/
const isMixedNav = computed(() => currentLayout.value === 'mixed-nav');
return {
currentLayout,
isFullContent,
isHeaderNav,
isMixedNav,
isSidebarMixedNav,
};
}

View File

@@ -62,12 +62,6 @@ interface VbenLayoutProps {
* @default 48
*/
headerHeight?: number;
/**
* header高度增加高度
* 在顶部存在导航时额外加高header高度
* @default 10
*/
headerHeightOffset?: number;
/**
* 顶栏是否隐藏
* @default false
@@ -78,6 +72,10 @@ interface VbenLayoutProps {
* @default 'fixed'
*/
headerMode?: LayoutHeaderModeType;
/**
* header 顶栏主题
*/
headerTheme?: ThemeModeType;
/**
* 是否显示header切换侧边栏按钮
* @default
@@ -133,11 +131,6 @@ interface VbenLayoutProps {
* @default 80
*/
sidebarMixedWidth?: number;
/**
* 侧边栏是否半深色
* @default false
*/
sidebarSemiDark?: boolean;
/**
* 侧边栏
* @default dark

View File

@@ -13,6 +13,7 @@ import {
LayoutSidebar,
LayoutTabbar,
} from './components';
import { useLayout } from './hooks/use-layout';
interface Props extends VbenLayoutProps {}
@@ -32,7 +33,6 @@ const props = withDefaults(defineProps<Props>(), {
footerFixed: true,
footerHeight: 32,
headerHeight: 50,
headerHeightOffset: 10,
headerHidden: false,
headerMode: 'fixed',
headerToggleSidebarButton: true,
@@ -43,7 +43,6 @@ const props = withDefaults(defineProps<Props>(), {
sidebarExtraCollapsedWidth: 60,
sidebarHidden: false,
sidebarMixedWidth: 80,
sidebarSemiDark: true,
sidebarTheme: 'dark',
sidebarWidth: 180,
sideCollapseWidth: 60,
@@ -73,57 +72,23 @@ const {
const { y: mouseY } = useMouse({ target: contentRef, type: 'client' });
const realLayout = computed(() =>
props.isMobile ? 'sidebar-nav' : props.layout,
);
/**
* 是否全屏显示content不需要侧边、底部、顶部、tab区域
*/
const fullContent = computed(() => realLayout.value === 'full-content');
/**
* 是否侧边混合模式
*/
const isSidebarMixedNav = computed(
() => realLayout.value === 'sidebar-mixed-nav',
);
/**
* 是否为头部导航模式
*/
const isHeaderNav = computed(() => realLayout.value === 'header-nav');
/**
* 是否为混合导航模式
*/
const isMixedNav = computed(() => realLayout.value === 'mixed-nav');
const {
currentLayout,
isFullContent,
isHeaderNav,
isMixedNav,
isSidebarMixedNav,
} = useLayout(props);
/**
* 顶栏是否自动隐藏
*/
const isHeaderAutoMode = computed(() => props.headerMode === 'auto');
/**
* header区域高度
*/
const getHeaderHeight = computed(() => {
const { headerHeight, headerHeightOffset } = props;
// if (!headerVisible) {
// return 0;
// }
// 顶部存在导航时增加10
const offset = isMixedNav.value || isHeaderNav.value ? headerHeightOffset : 0;
return headerHeight + offset;
});
const headerWrapperHeight = computed(() => {
let height = 0;
if (props.headerVisible && !props.headerHidden) {
height += getHeaderHeight.value;
height += props.headerHeight;
}
if (props.tabbarEnable) {
height += props.tabbarHeight;
@@ -151,8 +116,8 @@ const sidebarEnableState = computed(() => {
* 侧边区域离顶部高度
*/
const sidebarMarginTop = computed(() => {
const { isMobile } = props;
return isMixedNav.value && !isMobile ? getHeaderHeight.value : 0;
const { headerHeight, isMobile } = props;
return isMixedNav.value && !isMobile ? headerHeight : 0;
});
/**
@@ -195,30 +160,13 @@ const sidebarExtraWidth = computed(() => {
/**
* 是否侧边栏模式,包含混合侧边
*/
const isSideMode = computed(() =>
['mixed-nav', 'sidebar-mixed-nav', 'sidebar-nav'].includes(realLayout.value),
const isSideMode = computed(
() =>
currentLayout.value === 'mixed-nav' ||
currentLayout.value === 'sidebar-mixed-nav' ||
currentLayout.value === 'sidebar-nav',
);
const showSidebar = computed(() => {
// if (isMixedNav.value && !props.sideHidden) {
// return false;
// }
return isSideMode.value && sidebarEnable.value;
});
const sidebarFace = computed(() => {
const { sidebarSemiDark, sidebarTheme } = props;
const isDark = sidebarTheme === 'dark' || sidebarSemiDark;
return {
theme: isDark ? 'dark' : 'light',
};
});
/**
* 遮罩可见性
*/
const maskVisible = computed(() => !sidebarCollapse.value && props.isMobile);
/**
* header fixed值
*/
@@ -232,13 +180,25 @@ const headerFixed = computed(() => {
);
});
const showSidebar = computed(() => {
// if (isMixedNav.value && !props.sideHidden) {
// return false;
// }
return isSideMode.value && sidebarEnable.value;
});
/**
* 遮罩可见性
*/
const maskVisible = computed(() => !sidebarCollapse.value && props.isMobile);
const mainStyle = computed(() => {
let width = '100%';
let sidebarAndExtraWidth = 'unset';
if (
headerFixed.value &&
realLayout.value !== 'header-nav' &&
realLayout.value !== 'mixed-nav' &&
currentLayout.value !== 'header-nav' &&
currentLayout.value !== 'mixed-nav' &&
showSidebar.value &&
!props.isMobile
) {
@@ -253,7 +213,7 @@ const mainStyle = computed(() => {
? getSideCollapseWidth.value
: props.sidebarMixedWidth;
const sideWidth = sidebarExtraCollapse.value
? getSideCollapseWidth.value
? props.sidebarExtraCollapsedWidth
: props.sidebarWidth;
// 100% - 侧边菜单混合宽度 - 菜单宽度
@@ -312,7 +272,7 @@ const contentStyle = computed((): CSSProperties => {
return {
marginTop:
fixed &&
!fullContent.value &&
!isFullContent.value &&
!headerIsHidden.value &&
(!isHeaderAutoMode.value || scrollY.value < headerWrapperHeight.value)
? `${headerWrapperHeight.value}px`
@@ -330,11 +290,11 @@ const headerZIndex = computed(() => {
const headerWrapperStyle = computed((): CSSProperties => {
const fixed = headerFixed.value;
return {
height: fullContent.value ? '0' : `${headerWrapperHeight.value}px`,
height: isFullContent.value ? '0' : `${headerWrapperHeight.value}px`,
left: isMixedNav.value ? 0 : mainStyle.value.sidebarAndExtraWidth,
position: fixed ? 'fixed' : 'static',
top:
headerIsHidden.value || fullContent.value
headerIsHidden.value || isFullContent.value
? `-${headerWrapperHeight.value}px`
: 0,
width: mainStyle.value.width,
@@ -403,7 +363,10 @@ watch(
watch(
[() => props.headerMode, () => mouseY.value],
() => {
if (!isHeaderAutoMode.value || isMixedNav.value || fullContent.value) {
if (!isHeaderAutoMode.value || isMixedNav.value || isFullContent.value) {
if (props.headerMode !== 'auto-scroll') {
headerIsHidden.value = false;
}
return;
}
headerIsHidden.value = true;
@@ -439,7 +402,7 @@ watch(
if (
props.headerMode !== 'auto-scroll' ||
isMixedNav.value ||
fullContent.value
isFullContent.value
) {
return;
}
@@ -465,8 +428,6 @@ function handleOpenMenu() {
<template>
<div class="relative flex min-h-full w-full">
<slot name="preferences"></slot>
<slot name="floating-groups"></slot>
<LayoutSidebar
v-if="sidebarEnableState"
v-model:collapse="sidebarCollapse"
@@ -478,12 +439,12 @@ function handleOpenMenu() {
:dom-visible="!isMobile"
:extra-width="sidebarExtraWidth"
:fixed-extra="sidebarExpandOnHover"
:header-height="isMixedNav ? 0 : getHeaderHeight"
:header-height="isMixedNav ? 0 : headerHeight"
:is-sidebar-mixed="isSidebarMixedNav"
:margin-top="sidebarMarginTop"
:mixed-width="sidebarMixedWidth"
:show="showSidebar"
:theme="sidebarFace.theme"
:theme="sidebarTheme"
:width="getSidebarWidth"
:z-index="sidebarZIndex"
@leave="() => emit('sideMouseLeave')"
@@ -518,12 +479,13 @@ function handleOpenMenu() {
<LayoutHeader
v-if="headerVisible"
:full-width="!isSideMode"
:height="getHeaderHeight"
:height="headerHeight"
:is-mixed-nav="isMixedNav"
:is-mobile="isMobile"
:show="!fullContent && !headerHidden"
:show="!isFullContent && !headerHidden"
:show-toggle-btn="showHeaderToggleButton"
:sidebar-width="sidebarWidth"
:theme="headerTheme"
:width="mainStyle.width"
:z-index="headerZIndex"
@open-menu="handleOpenMenu"
@@ -563,7 +525,7 @@ function handleOpenMenu() {
v-if="footerEnable"
:fixed="footerFixed"
:height="footerHeight"
:show="!fullContent"
:show="!isFullContent"
:width="footerWidth"
:z-index="zIndex"
>

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/menu-ui",
"version": "5.0.1",
"version": "5.1.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -479,8 +479,8 @@ $namespace: vben;
}
&.is-horizontal:not(.is-rounded) {
--menu-item-height: 60px;
--menu-item-radius: 0px;
--menu-item-height: 40px;
--menu-item-radius: 6px;
}
&.is-horizontal.is-rounded {
@@ -498,13 +498,13 @@ $namespace: vben;
--menu-background-color: transparent;
&.is-dark {
--menu-item-hover-color: var(--foreground);
--menu-item-hover-color: hsl(var(--accent-foreground));
--menu-item-hover-background-color: hsl(var(--accent));
--menu-item-active-color: hsl(var(--foreground));
--menu-item-active-color: hsl(var(--accent-foreground));
--menu-item-active-background-color: hsl(var(--accent));
--menu-submenu-active-color: hsl(var(--foreground));
--menu-submenu-active-background-color: hsl(var(--accent));
--menu-submenu-hover-color: hsl(var(--foreground));
--menu-submenu-hover-color: hsl(var(--accent-foreground));
--menu-submenu-hover-background-color: hsl(var(--accent));
}
@@ -514,7 +514,7 @@ $namespace: vben;
--menu-item-hover-background-color: hsl(var(--accent));
--menu-item-hover-color: hsl(var(--primary));
--menu-submenu-active-color: hsl(var(--primary));
--menu-submenu-active-background-color: hsl(var(--primary) / 30%);
--menu-submenu-active-background-color: hsl(var(--primary) / 15%);
--menu-submenu-hover-color: hsl(var(--primary));
--menu-submenu-hover-background-color: hsl(var(--accent));
}
@@ -776,7 +776,7 @@ $namespace: vben;
&.is-active {
div[data-state='open'] > .#{$namespace}-sub-menu-content,
> .#{$namespace}-sub-menu-content {
font-weight: 500;
// font-weight: 500;
color: var(--menu-submenu-active-color);
text-decoration: none;
cursor: pointer;

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/shadcn-ui",
"version": "5.0.1",
"version": "5.1.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -22,6 +22,7 @@ export * from './scrollbar';
export * from './segmented';
export * from './sheet';
export * from './spinner';
export * from './swap';
export * from './tooltip';
export * from './ui/alert-dialog';
export * from './ui/avatar';

View File

@@ -1 +1 @@
export { default as Spinner } from './spinner.vue';
export { default as VbenSpinner } from './spinner.vue';

View File

@@ -0,0 +1 @@
export { default as VbenSwap } from './swap.vue';

View File

@@ -0,0 +1,126 @@
<script lang="ts" setup>
interface Props {
/**
* @zh_CN 交换模式
*/
mode?: 'flip' | 'rotate';
/**
* @zh_CN 开启时的样式
*/
offClass?: string;
/**
* @zh_CN 关闭时的样式
*/
onClass?: string;
}
defineOptions({
name: 'Swap',
});
withDefaults(defineProps<Props>(), {
mode: 'rotate',
onClass: '',
});
</script>
<template>
<label
:class="{
'swap-flip': mode === 'flip',
'swap-rotate': mode === 'rotate',
}"
class="swap"
>
<input class="hidden" type="checkbox" />
<div :class="onClass" class="swap-on">
<slot name="swap-on"></slot>
</div>
<div :class="offClass" class="swap-off">
<slot name="swap-off"></slot>
</div>
</label>
</template>
<style scoped>
.swap {
@apply relative inline-grid cursor-pointer select-none place-content-center;
}
.swap > * {
@apply col-start-1 row-start-1 duration-300 ease-out;
transition-property: transform, opacity;
}
.swap-rotate .swap-on,
.swap-rotate .swap-indeterminate,
.swap-rotate input:indeterminate ~ .swap-on {
@apply rotate-45;
}
.swap-rotate input:checked ~ .swap-off,
.swap-active:where(.swap-rotate) .swap-off,
.swap-rotate input:indeterminate ~ .swap-off {
@apply -rotate-45;
}
.swap-rotate input:checked ~ .swap-on,
.swap-active:where(.swap-rotate) .swap-on,
.swap-rotate input:indeterminate ~ .swap-indeterminate {
@apply rotate-0;
}
.swap-flip {
transform-style: preserve-3d;
perspective: 16em;
}
.swap-flip .swap-on,
.swap-flip .swap-indeterminate,
.swap-flip input:indeterminate ~ .swap-on {
@apply opacity-100;
transform: rotateY(180deg);
backface-visibility: hidden;
}
.swap-flip input:checked ~ .swap-off,
.swap-active:where(.swap-flip) .swap-off,
.swap-flip input:indeterminate ~ .swap-off {
@apply opacity-100;
transform: rotateY(-180deg);
backface-visibility: hidden;
}
.swap-flip input:checked ~ .swap-on,
.swap-active:where(.swap-flip) .swap-on,
.swap-flip input:indeterminate ~ .swap-indeterminate {
transform: rotateY(0deg);
}
.swap input {
@apply appearance-none;
}
.swap .swap-on,
.swap .swap-indeterminate,
.swap input:indeterminate ~ .swap-on {
@apply opacity-0;
}
.swap input:checked ~ .swap-off,
.swap-active .swap-off,
.swap input:indeterminate ~ .swap-off {
@apply opacity-0;
}
.swap input:checked ~ .swap-on,
.swap-active .swap-on,
.swap input:indeterminate ~ .swap-indeterminate {
@apply opacity-100;
}
</style>

View File

@@ -30,7 +30,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
<template>
<DialogPortal>
<DialogOverlay
class="data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 border-border fixed inset-0 z-[1000] grid place-items-center overflow-y-auto bg-black/80"
class="data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 border-border fixed inset-0 z-[1000] grid place-items-center overflow-y-auto border bg-black/80"
>
<DialogContent
:class="

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
@@ -11,7 +11,7 @@ import {
} from 'radix-vue';
const props = withDefaults(
defineProps<{ class?: HTMLAttributes['class'] } & HoverCardContentProps>(),
defineProps<{ class?: any } & HoverCardContentProps>(),
{
sideOffset: 4,
},

View File

@@ -9,10 +9,10 @@ export const sheetVariants = cva(
variants: {
side: {
bottom:
'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',
'inset-x-0 bottom-0 border-t border-border data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',
left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm',
right:
'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm',
'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm',
top: 'inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',
},
},

View File

@@ -5,7 +5,7 @@ import type { HTMLAttributes } from 'vue';
import { cva, type VariantProps } from 'class-variance-authority';
export const toastVariants = cva(
'group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',
'group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border border-border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',
{
defaultVariants: {
variant: 'default',

View File

@@ -41,7 +41,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
v-bind="{ ...forwarded, ...$attrs }"
:class="
cn(
'bg-accent text-accent-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border-border z-[1000] overflow-hidden rounded-sm px-4 py-2 text-xs shadow-md',
'bg-accent text-accent-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border-border shadow-float z-[1000] overflow-hidden rounded-sm border px-4 py-2 text-xs',
props.class,
)
"

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/tabs-ui",
"version": "5.0.1",
"version": "5.1.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -109,7 +109,7 @@ function scrollIntoView() {
<!-- divider -->
<div
v-if="i !== 0 && tab.key !== active"
class="tabs-chrome__divider bg-foreground/80 absolute left-[var(--gap)] top-1/2 z-0 h-4 w-[1px] translate-y-[-50%] transition-all"
class="tabs-chrome__divider bg-foreground/60 absolute left-[var(--gap)] top-1/2 z-0 h-4 w-[1px] translate-y-[-50%] transition-all"
></div>
<!-- background -->
<div