@coffic/cosy-ui 0.9.23 → 0.9.25
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/dist/app.css +1 -1
- package/dist/index-astro.ts +0 -2
- package/dist/src/assets/iconData.ts +5 -0
- package/dist/src/utils/link.ts +1 -1
- package/dist/src/utils/theme.ts +99 -96
- package/dist/src-astro/article/Article.astro +1 -0
- package/dist/src-astro/container/Container.astro +9 -0
- package/dist/src-astro/footer/Footer.astro +16 -20
- package/dist/src-astro/footer/FooterCopyright.astro +8 -17
- package/dist/src-astro/footer/FooterICP.astro +18 -0
- package/dist/src-astro/footer/index.ts +1 -0
- package/dist/src-astro/footer/types.ts +27 -0
- package/dist/src-astro/header/Header.astro +53 -54
- package/dist/src-astro/header/HeaderCenter.astro +59 -0
- package/dist/src-astro/header/HeaderEnd.astro +90 -0
- package/dist/src-astro/header/HeaderStart.astro +78 -0
- package/dist/src-astro/header/MobileNav.astro +44 -0
- package/dist/src-astro/header/NavItems.astro +82 -0
- package/dist/src-astro/header/index.ts +6 -0
- package/dist/src-astro/icons/GlobeIcon.astro +28 -0
- package/dist/src-astro/icons/index.ts +1 -0
- package/dist/src-astro/language-switcher/LanguageSwitcher.astro +5 -2
- package/dist/src-astro/layout-app/AppHeader.astro +95 -0
- package/dist/src-astro/layout-app/AppLayout.astro +18 -26
- package/dist/src-astro/layout-basic/index.ts +1 -0
- package/dist/src-astro/{types → layout-basic}/layout.ts +5 -5
- package/dist/src-astro/modal/Modal.astro +39 -4
- package/dist/src-astro/sidebar/DesktopSidebar.astro +123 -0
- package/dist/src-astro/sidebar/MobileSidebar.astro +91 -0
- package/dist/src-astro/sidebar/Sidebar.astro +45 -86
- package/dist/src-astro/sidebar/SidebarNav.astro +12 -3
- package/dist/src-astro/sidebar/index.ts +1 -2
- package/dist/src-astro/theme-switcher/ThemeItem.astro +43 -3
- package/dist/src-astro/theme-switcher/ThemeSwitcher.astro +6 -67
- package/dist/src-astro/theme-switcher/index.ts +1 -9
- package/dist/src-astro/types/footer.ts +5 -0
- package/dist/src-astro/types/header.ts +6 -0
- package/package.json +1 -1
- package/dist/src-astro/nav-item/NavItems.astro +0 -44
- package/dist/src-astro/nav-item/index.ts +0 -3
- package/dist/src-astro/sidebar/MobileNav.astro +0 -55
- package/dist/src-astro/theme-switcher/ThemeSwitcherBasic.astro +0 -7
@@ -0,0 +1,90 @@
|
|
1
|
+
---
|
2
|
+
/**
|
3
|
+
* @component HeaderEnd
|
4
|
+
*
|
5
|
+
* @description
|
6
|
+
* HeaderEnd 组件负责渲染 Header 的右侧区域,包括主题切换器、语言切换器和右侧导航项。
|
7
|
+
* 这是一个内部组件,通常由 Header 组件使用。
|
8
|
+
*
|
9
|
+
* @usage
|
10
|
+
* ```astro
|
11
|
+
* <HeaderEnd
|
12
|
+
* navPosition={navPosition}
|
13
|
+
* navItems={navItems}
|
14
|
+
* activeLink={activeLink}
|
15
|
+
* linkHeightClass={linkHeightClass}
|
16
|
+
* showThemeSwitcher={showThemeSwitcher}
|
17
|
+
* isI18nEnabled={isI18nEnabled}
|
18
|
+
* astroI18n={astroI18n}
|
19
|
+
* />
|
20
|
+
* ```
|
21
|
+
*
|
22
|
+
* @props
|
23
|
+
* - navPosition - 导航位置
|
24
|
+
* - navItems - 导航项数组
|
25
|
+
* - activeLink - 当前激活的链接
|
26
|
+
* - linkHeightClass - 链接高度类名
|
27
|
+
* - showThemeSwitcher - 是否显示主题切换器
|
28
|
+
* - isI18nEnabled - 是否启用国际化
|
29
|
+
* - astroI18n - astro:i18n 模块
|
30
|
+
*/
|
31
|
+
import {
|
32
|
+
ThemeSwitcher,
|
33
|
+
LanguageSwitcher,
|
34
|
+
MenuIcon,
|
35
|
+
type INavItem,
|
36
|
+
} from '../../index-astro';
|
37
|
+
import NavItems from './NavItems.astro';
|
38
|
+
|
39
|
+
export interface Props {
|
40
|
+
navPosition: string;
|
41
|
+
navItems: INavItem[];
|
42
|
+
activeLink: string;
|
43
|
+
linkHeightClass: string;
|
44
|
+
showThemeSwitcher: boolean;
|
45
|
+
isI18nEnabled: boolean;
|
46
|
+
astroI18n?: any;
|
47
|
+
}
|
48
|
+
|
49
|
+
const {
|
50
|
+
navPosition,
|
51
|
+
navItems,
|
52
|
+
activeLink,
|
53
|
+
linkHeightClass,
|
54
|
+
showThemeSwitcher,
|
55
|
+
isI18nEnabled,
|
56
|
+
astroI18n,
|
57
|
+
} = Astro.props;
|
58
|
+
---
|
59
|
+
|
60
|
+
<div class="cosy:navbar-end cosy:pr-1">
|
61
|
+
{
|
62
|
+
navPosition === 'end' && (
|
63
|
+
<div class="cosy:hidden cosy:lg:flex">
|
64
|
+
<NavItems
|
65
|
+
navItems={navItems}
|
66
|
+
activeLink={activeLink}
|
67
|
+
linkHeightClass={linkHeightClass}
|
68
|
+
gap={4}
|
69
|
+
/>
|
70
|
+
</div>
|
71
|
+
)
|
72
|
+
}
|
73
|
+
|
74
|
+
{showThemeSwitcher && <ThemeSwitcher />}
|
75
|
+
{isI18nEnabled && <LanguageSwitcher astroI18n={astroI18n} />}
|
76
|
+
|
77
|
+
<!-- 移动端汉堡菜单按钮 -->
|
78
|
+
{
|
79
|
+
navItems.length > 0 && (
|
80
|
+
<button
|
81
|
+
type="button"
|
82
|
+
class="cosy:btn cosy:btn-ghost cosy:btn-sm cosy:lg:hidden"
|
83
|
+
data-modal-target="mobile-nav">
|
84
|
+
<MenuIcon class="cosy:w-5 cosy:h-5" />
|
85
|
+
</button>
|
86
|
+
)
|
87
|
+
}
|
88
|
+
|
89
|
+
<slot name="navbar-end" />
|
90
|
+
</div>
|
@@ -0,0 +1,78 @@
|
|
1
|
+
---
|
2
|
+
/**
|
3
|
+
* @component HeaderStart
|
4
|
+
*
|
5
|
+
* @description
|
6
|
+
* HeaderStart 组件负责渲染 Header 的左侧区域,包括 logo 和左侧导航项。
|
7
|
+
* 这是一个内部组件,通常由 Header 组件使用。
|
8
|
+
*
|
9
|
+
* @usage
|
10
|
+
* ```astro
|
11
|
+
* <HeaderStart
|
12
|
+
* logo={logo}
|
13
|
+
* logoHref={logoHref}
|
14
|
+
* height={height}
|
15
|
+
* navPosition={navPosition}
|
16
|
+
* navItems={navItems}
|
17
|
+
* activeLink={activeLink}
|
18
|
+
* linkHeightClass={linkHeightClass}
|
19
|
+
* debug={debug}
|
20
|
+
* />
|
21
|
+
* ```
|
22
|
+
*
|
23
|
+
* @props
|
24
|
+
* - logo - logo 图片
|
25
|
+
* - logoHref - logo 链接地址
|
26
|
+
* - height - header 高度
|
27
|
+
* - navPosition - 导航位置
|
28
|
+
* - navItems - 导航项数组
|
29
|
+
* - activeLink - 当前激活的链接
|
30
|
+
* - linkHeightClass - 链接高度类名
|
31
|
+
* - debug - 是否启用调试模式
|
32
|
+
*/
|
33
|
+
import { type INavItem } from '../../index-astro';
|
34
|
+
import NavItems from './NavItems.astro';
|
35
|
+
import LogoLink from './LogoLink.astro';
|
36
|
+
|
37
|
+
export interface Props {
|
38
|
+
logo: string | ImageMetadata;
|
39
|
+
logoHref: string;
|
40
|
+
height: '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
41
|
+
navPosition: string;
|
42
|
+
navItems: INavItem[];
|
43
|
+
activeLink: string;
|
44
|
+
linkHeightClass: string;
|
45
|
+
debug: boolean;
|
46
|
+
}
|
47
|
+
|
48
|
+
const {
|
49
|
+
logo,
|
50
|
+
logoHref,
|
51
|
+
height,
|
52
|
+
navPosition,
|
53
|
+
navItems,
|
54
|
+
activeLink,
|
55
|
+
linkHeightClass,
|
56
|
+
debug,
|
57
|
+
} = Astro.props;
|
58
|
+
---
|
59
|
+
|
60
|
+
<div class="cosy:navbar-start cosy:pl-1" data-role="header-start">
|
61
|
+
{
|
62
|
+
navPosition === 'start' ? (
|
63
|
+
<div class="cosy:flex cosy:items-center cosy:gap-4">
|
64
|
+
<LogoLink src={logo} href={logoHref} size={height} debug={debug} />
|
65
|
+
<div class="cosy:lg:flex">
|
66
|
+
<NavItems
|
67
|
+
navItems={navItems}
|
68
|
+
activeLink={activeLink}
|
69
|
+
linkHeightClass={linkHeightClass}
|
70
|
+
/>
|
71
|
+
</div>
|
72
|
+
</div>
|
73
|
+
) : (
|
74
|
+
<LogoLink src={logo} href={logoHref} size={height} debug={debug} />
|
75
|
+
)
|
76
|
+
}
|
77
|
+
<slot name="navbar-start" />
|
78
|
+
</div>
|
@@ -0,0 +1,44 @@
|
|
1
|
+
---
|
2
|
+
/**
|
3
|
+
* @component MobileNav
|
4
|
+
*
|
5
|
+
* @description
|
6
|
+
* MobileNav 组件是一个移动端导航菜单,用于在小屏幕设备上显示导航项。
|
7
|
+
* 这个组件通常与 Modal 组件配合使用,提供移动端的导航体验。
|
8
|
+
*
|
9
|
+
* @usage
|
10
|
+
* ```astro
|
11
|
+
* <MobileNav
|
12
|
+
* navItems={navItems}
|
13
|
+
* activeLink={activeLink}
|
14
|
+
* linkHeightClass={linkHeightClass}
|
15
|
+
* />
|
16
|
+
* ```
|
17
|
+
*
|
18
|
+
* @props
|
19
|
+
* - navItems - 导航项数组
|
20
|
+
* - activeLink - 当前激活的链接
|
21
|
+
* - linkHeightClass - 链接高度类名
|
22
|
+
*/
|
23
|
+
import { type INavItem } from '../../index-astro';
|
24
|
+
import NavItems from './NavItems.astro';
|
25
|
+
|
26
|
+
export interface Props {
|
27
|
+
navItems: INavItem[];
|
28
|
+
activeLink: string;
|
29
|
+
linkHeightClass: string;
|
30
|
+
}
|
31
|
+
|
32
|
+
const { navItems, activeLink, linkHeightClass } = Astro.props;
|
33
|
+
---
|
34
|
+
|
35
|
+
<div class="cosy:flex cosy:flex-col cosy:gap-2">
|
36
|
+
<nav class="cosy:flex cosy:flex-col cosy:gap-1">
|
37
|
+
<NavItems
|
38
|
+
navItems={navItems}
|
39
|
+
activeLink={activeLink}
|
40
|
+
linkHeightClass={linkHeightClass}
|
41
|
+
vertical={true}
|
42
|
+
/>
|
43
|
+
</nav>
|
44
|
+
</div>
|
@@ -0,0 +1,82 @@
|
|
1
|
+
---
|
2
|
+
/**
|
3
|
+
* @component NavItems
|
4
|
+
*
|
5
|
+
* @description
|
6
|
+
* NavItems 组件用于渲染导航栏中的导航项目列表。
|
7
|
+
* 支持配置导航项之间的间距,提供预设的 gap 值。
|
8
|
+
*
|
9
|
+
* @usage
|
10
|
+
* ```astro
|
11
|
+
* <NavItems
|
12
|
+
* navItems={navItems}
|
13
|
+
* activeLink={activeLink}
|
14
|
+
* linkHeightClass={linkHeightClass}
|
15
|
+
* gap={2}
|
16
|
+
* />
|
17
|
+
* ```
|
18
|
+
*
|
19
|
+
* @props
|
20
|
+
* - navItems: INavItem[] - 导航项数组
|
21
|
+
* - activeLink: string - 当前激活的链接
|
22
|
+
* - linkHeightClass: string - 链接高度类名
|
23
|
+
* - vertical?: boolean - 是否垂直布局,默认 false
|
24
|
+
* - gap?: number - 导航项之间的间距,可选值:0, 1, 2, 3, 4, 6, 8, 10, 12,默认 2
|
25
|
+
*/
|
26
|
+
import '../../style.ts';
|
27
|
+
import { type INavItem, Link, ListItem } from '../../index-astro';
|
28
|
+
|
29
|
+
interface Props {
|
30
|
+
navItems: INavItem[];
|
31
|
+
activeLink: string;
|
32
|
+
linkHeightClass: string;
|
33
|
+
vertical?: boolean;
|
34
|
+
gap?: number;
|
35
|
+
}
|
36
|
+
|
37
|
+
const {
|
38
|
+
navItems,
|
39
|
+
activeLink,
|
40
|
+
linkHeightClass,
|
41
|
+
vertical = false,
|
42
|
+
gap = 2,
|
43
|
+
} = Astro.props;
|
44
|
+
|
45
|
+
// 预设的 gap 值映射
|
46
|
+
const gapClasses = {
|
47
|
+
0: '',
|
48
|
+
1: 'cosy:gap-1',
|
49
|
+
2: 'cosy:gap-2',
|
50
|
+
3: 'cosy:gap-3',
|
51
|
+
4: 'cosy:gap-4',
|
52
|
+
6: 'cosy:gap-6',
|
53
|
+
8: 'cosy:gap-8',
|
54
|
+
10: 'cosy:gap-10',
|
55
|
+
12: 'cosy:gap-12',
|
56
|
+
} as const;
|
57
|
+
|
58
|
+
// 获取对应的 gap 类名
|
59
|
+
const gapClass = gapClasses[gap as keyof typeof gapClasses] || gapClasses[2];
|
60
|
+
---
|
61
|
+
|
62
|
+
<ul
|
63
|
+
data-active-link={activeLink}
|
64
|
+
class:list={[
|
65
|
+
'cosy:px-1 cosy:menu cosy:w-full',
|
66
|
+
vertical ? 'cosy:menu-vertical' : 'cosy:menu-horizontal',
|
67
|
+
linkHeightClass,
|
68
|
+
gapClass,
|
69
|
+
]}>
|
70
|
+
{
|
71
|
+
navItems.map((item) => (
|
72
|
+
<ListItem>
|
73
|
+
<Link
|
74
|
+
variant={activeLink === item.href ? 'primary' : 'default'}
|
75
|
+
href={item.href}
|
76
|
+
class:list={[linkHeightClass]}>
|
77
|
+
{item.title}
|
78
|
+
</Link>
|
79
|
+
</ListItem>
|
80
|
+
))
|
81
|
+
}
|
82
|
+
</ul>
|
@@ -1 +1,7 @@
|
|
1
1
|
export { default as Header } from './Header.astro';
|
2
|
+
export { default as HeaderStart } from './HeaderStart.astro';
|
3
|
+
export { default as HeaderCenter } from './HeaderCenter.astro';
|
4
|
+
export { default as HeaderEnd } from './HeaderEnd.astro';
|
5
|
+
export { default as LogoLink } from './LogoLink.astro';
|
6
|
+
export { default as MobileNav } from './MobileNav.astro';
|
7
|
+
export { default as NavItems } from './NavItems.astro';
|
@@ -0,0 +1,28 @@
|
|
1
|
+
---
|
2
|
+
import AstroIcon from './AstroIcon.astro';
|
3
|
+
|
4
|
+
interface Props {
|
5
|
+
/**
|
6
|
+
* 图标的大小
|
7
|
+
* @default "24px"
|
8
|
+
*/
|
9
|
+
size?: string;
|
10
|
+
/**
|
11
|
+
* 图标的颜色
|
12
|
+
* @default "currentColor"
|
13
|
+
*/
|
14
|
+
color?: string;
|
15
|
+
/**
|
16
|
+
* 自定义类名
|
17
|
+
*/
|
18
|
+
class?: string;
|
19
|
+
}
|
20
|
+
|
21
|
+
const {
|
22
|
+
size = '24px',
|
23
|
+
color = 'currentColor',
|
24
|
+
class: className = '',
|
25
|
+
} = Astro.props;
|
26
|
+
---
|
27
|
+
|
28
|
+
<AstroIcon name="globe" size={size} stroke={color} class={className} />
|
@@ -21,6 +21,7 @@ export { default as CodeIcon } from './CodeIcon.astro';
|
|
21
21
|
export { default as DeleteIcon } from './DeleteIcon.astro';
|
22
22
|
export { default as ErrorIcon } from './ErrorIcon.astro';
|
23
23
|
export { default as GithubIcon } from './GithubIcon.astro';
|
24
|
+
export { default as GlobeIcon } from './GlobeIcon.astro';
|
24
25
|
export { default as InfoCircle } from './InfoCircle.astro';
|
25
26
|
export { default as InboxArchive } from './InboxArchive.astro';
|
26
27
|
export { default as SettingsIcon } from './SettingsIcon.astro';
|
@@ -27,7 +27,7 @@
|
|
27
27
|
* - class - 自定义CSS类名
|
28
28
|
*/
|
29
29
|
|
30
|
-
import { ChevronDownIcon, Link, ListItem } from '../../index-astro';
|
30
|
+
import { ChevronDownIcon, GlobeIcon, Link, ListItem } from '../../index-astro';
|
31
31
|
import {
|
32
32
|
checkSwitcherRenderState,
|
33
33
|
generateSwitcherLinks,
|
@@ -78,7 +78,10 @@ if (renderState.shouldRender && Astro.currentLocale) {
|
|
78
78
|
renderState.shouldRender && (
|
79
79
|
<div class={`cosy:dropdown cosy:dropdown-end ${className}`}>
|
80
80
|
<div tabindex="0" role="button" class:list={['cosy:btn cosy:btn-ghost']}>
|
81
|
-
<
|
81
|
+
<GlobeIcon size="16px" class="cosy:w-4 cosy:h-4 cosy:mr-1" />
|
82
|
+
<span class="cosy:mr-1 cosy:hidden cosy:sm:inline">
|
83
|
+
{renderState.currentLanguageName}
|
84
|
+
</span>
|
82
85
|
<ChevronDownIcon size="16px" class="cosy:w-4 cosy:h-4" />
|
83
86
|
</div>
|
84
87
|
<ul
|
@@ -0,0 +1,95 @@
|
|
1
|
+
---
|
2
|
+
/**
|
3
|
+
* AppHeader组件
|
4
|
+
*
|
5
|
+
* 专门处理应用布局中的头部导航栏
|
6
|
+
*
|
7
|
+
* @param {Object} headerConfig - 头部配置
|
8
|
+
* @param {boolean} [debug=false] - 是否启用调试模式
|
9
|
+
* @param {boolean} [showSidebar=true] - 是否显示侧边栏切换按钮
|
10
|
+
* @param {boolean} [showSearch=true] - 是否显示搜索按钮
|
11
|
+
* @param {Object} rest - 其他属性
|
12
|
+
*
|
13
|
+
* @slot navbar-start - 导航栏开始位置的内容
|
14
|
+
* @slot navbar-center - 导航栏中间位置的内容
|
15
|
+
* @slot navbar-end - 导航栏结束位置的内容
|
16
|
+
* @slot modal-search - 搜索模态框内容,当提供此slot时会显示搜索按钮
|
17
|
+
*
|
18
|
+
* @example
|
19
|
+
* ```astro
|
20
|
+
* ---
|
21
|
+
* import AppHeader from './AppHeader.astro';
|
22
|
+
* import { Button } from '@coffic/cosy-ui';
|
23
|
+
* ---
|
24
|
+
*
|
25
|
+
* <AppHeader>
|
26
|
+
* <div slot="navbar-start">
|
27
|
+
* <h1 class="cosy:text-xl cosy:font-bold">我的应用</h1>
|
28
|
+
* </div>
|
29
|
+
*
|
30
|
+
* <div slot="navbar-center">
|
31
|
+
* <nav class="cosy:flex cosy:gap-4">
|
32
|
+
* <a href="/docs" class="cosy:link cosy:link-hover">文档</a>
|
33
|
+
* <a href="/components" class="cosy:link cosy:link-hover">组件</a>
|
34
|
+
* </nav>
|
35
|
+
* </div>
|
36
|
+
*
|
37
|
+
* <div slot="navbar-end">
|
38
|
+
* <Button variant="primary">登录</Button>
|
39
|
+
* </div>
|
40
|
+
* </AppHeader>
|
41
|
+
* ```
|
42
|
+
*/
|
43
|
+
|
44
|
+
import '../../style.ts';
|
45
|
+
import { Header, Button, MenuIcon, SearchIcon } from '../../index-astro';
|
46
|
+
|
47
|
+
interface Props {
|
48
|
+
headerConfig?: any;
|
49
|
+
debug?: boolean;
|
50
|
+
showSidebar?: boolean;
|
51
|
+
showSearch?: boolean;
|
52
|
+
[key: string]: any;
|
53
|
+
}
|
54
|
+
|
55
|
+
const {
|
56
|
+
headerConfig = {},
|
57
|
+
debug = false,
|
58
|
+
showSidebar = true,
|
59
|
+
showSearch = true,
|
60
|
+
...rest
|
61
|
+
}: Props = Astro.props;
|
62
|
+
---
|
63
|
+
|
64
|
+
<Header {...headerConfig} debug={debug}>
|
65
|
+
<div slot="navbar-start">
|
66
|
+
{/* 小屏幕显示侧边栏切换按钮 */}
|
67
|
+
{
|
68
|
+
showSidebar && (
|
69
|
+
<Button
|
70
|
+
class="cosy:lg:hidden"
|
71
|
+
data-modal-target="mobile-sidebar"
|
72
|
+
variant="ghost"
|
73
|
+
size="sm">
|
74
|
+
<MenuIcon size="20px" />
|
75
|
+
</Button>
|
76
|
+
)
|
77
|
+
}
|
78
|
+
<slot name="navbar-start" />
|
79
|
+
</div>
|
80
|
+
|
81
|
+
<div slot="navbar-center">
|
82
|
+
<slot name="navbar-center" />
|
83
|
+
</div>
|
84
|
+
|
85
|
+
<div slot="navbar-end">
|
86
|
+
{
|
87
|
+
showSearch && Astro.slots.has('modal-search') && (
|
88
|
+
<Button data-modal-target="modalSearch" variant="ghost" size="sm">
|
89
|
+
<SearchIcon size="24px" />
|
90
|
+
</Button>
|
91
|
+
)
|
92
|
+
}
|
93
|
+
<slot name="navbar-end" />
|
94
|
+
</div>
|
95
|
+
</Header>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
/**
|
3
3
|
* AppLayout组件
|
4
4
|
*
|
5
|
-
*
|
5
|
+
* 适用于页面布局,包含头部导航、侧边栏导航和目录
|
6
6
|
*
|
7
7
|
* 布局效果:
|
8
8
|
*
|
@@ -45,15 +45,15 @@
|
|
45
45
|
* @param {boolean} [debug=true] - 是否启用调试模式
|
46
46
|
* @param {Object} mainContentConfig - 主内容区域配置
|
47
47
|
* @param {Object} footerConfig - 页脚配置
|
48
|
-
* @param {Object} headerConfig -
|
48
|
+
* @param {Object} headerConfig - 头部配置(传递给AppHeader组件)
|
49
49
|
* @param {Object} metaConfig - 元数据配置
|
50
50
|
* @param {Object} rest - 其他属性
|
51
51
|
*
|
52
52
|
* @slot default - 主内容区域
|
53
|
-
* @slot navbar-start -
|
54
|
-
* @slot navbar-center -
|
55
|
-
* @slot navbar-end -
|
56
|
-
* @slot modal-search - 搜索模态框内容,当提供此slot
|
53
|
+
* @slot navbar-start - 导航栏开始位置的内容(传递给AppHeader)
|
54
|
+
* @slot navbar-center - 导航栏中间位置的内容(传递给AppHeader)
|
55
|
+
* @slot navbar-end - 导航栏结束位置的内容(传递给AppHeader)
|
56
|
+
* @slot modal-search - 搜索模态框内容,当提供此slot时会显示搜索按钮(传递给AppHeader)
|
57
57
|
*
|
58
58
|
* @example
|
59
59
|
* ```astro
|
@@ -242,14 +242,12 @@ import {
|
|
242
242
|
BaseLayout,
|
243
243
|
type IAppLayoutProps,
|
244
244
|
Footer,
|
245
|
-
Header,
|
246
245
|
Container,
|
247
246
|
Main,
|
248
247
|
Sidebar,
|
249
248
|
Modal,
|
250
|
-
SearchIcon,
|
251
|
-
Button,
|
252
249
|
} from '../../index-astro';
|
250
|
+
import AppHeader from './AppHeader.astro';
|
253
251
|
import SkeletonLoader from './SkeletonLoader.astro';
|
254
252
|
|
255
253
|
interface Props extends IAppLayoutProps {}
|
@@ -328,22 +326,16 @@ const sidebarHeightClass = getSidebarHeightClass(headerConfig?.height);
|
|
328
326
|
<BaseLayout {...metaConfig} debug={debug}>
|
329
327
|
{
|
330
328
|
showHeader && (
|
331
|
-
<
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
<
|
339
|
-
|
340
|
-
|
341
|
-
<SearchIcon size="24px" />
|
342
|
-
</Button>
|
343
|
-
)}
|
344
|
-
<slot name="navbar-end" />
|
345
|
-
</div>
|
346
|
-
</Header>
|
329
|
+
<AppHeader
|
330
|
+
headerConfig={headerConfig}
|
331
|
+
debug={debug}
|
332
|
+
showSidebar={showSidebar}
|
333
|
+
showSearch={true}>
|
334
|
+
<slot name="navbar-start" slot="navbar-start" />
|
335
|
+
<slot name="navbar-center" slot="navbar-center" />
|
336
|
+
<slot name="navbar-end" slot="navbar-end" />
|
337
|
+
<slot name="modal-search" slot="modal-search" />
|
338
|
+
</AppHeader>
|
347
339
|
)
|
348
340
|
}
|
349
341
|
|
@@ -365,7 +357,7 @@ const sidebarHeightClass = getSidebarHeightClass(headerConfig?.height);
|
|
365
357
|
}
|
366
358
|
|
367
359
|
<!-- 主内容区域 -->
|
368
|
-
<Main {...mainContentConfig} class="cosy:flex-1 cosy:min-w-
|
360
|
+
<Main {...mainContentConfig} class="cosy:flex-1 cosy:min-w-xs">
|
369
361
|
<SkeletonLoader
|
370
362
|
showLoading={true}
|
371
363
|
loadingSize="xl"
|
@@ -1,8 +1,8 @@
|
|
1
|
-
import type { IFooterProps } from '
|
2
|
-
import type { IHeaderProps } from '
|
3
|
-
import type { IMainContentProps } from '
|
4
|
-
import type { IMetaProps } from '
|
5
|
-
import type { ISidebarProps } from '
|
1
|
+
import type { IFooterProps } from '../types/footer';
|
2
|
+
import type { IHeaderProps } from '../types/header';
|
3
|
+
import type { IMainContentProps } from '../types/main';
|
4
|
+
import type { IMetaProps } from './meta';
|
5
|
+
import type { ISidebarProps } from '../types/sidebar';
|
6
6
|
|
7
7
|
export interface IAppLayoutProps {
|
8
8
|
/**
|
@@ -42,6 +42,13 @@
|
|
42
42
|
* <img src="/images/large-image.jpg" alt="大图预览" />
|
43
43
|
* </Modal>
|
44
44
|
* ```
|
45
|
+
*
|
46
|
+
* 带链接标题的模态框:
|
47
|
+
* ```astro
|
48
|
+
* <Modal id="help-modal" title="帮助文档" titleHref="/help" titleExternal>
|
49
|
+
* <p>点击标题可以跳转到帮助文档。</p>
|
50
|
+
* </Modal>
|
51
|
+
* ```
|
45
52
|
*/
|
46
53
|
|
47
54
|
import '../../style.ts';
|
@@ -57,20 +64,38 @@ interface Props {
|
|
57
64
|
* 模态框的标题
|
58
65
|
*/
|
59
66
|
title?: string;
|
67
|
+
/**
|
68
|
+
* 标题的链接地址,传入后标题会变成可点击的链接
|
69
|
+
*/
|
70
|
+
titleHref?: string;
|
71
|
+
/**
|
72
|
+
* 标题链接是否为外部链接
|
73
|
+
*/
|
74
|
+
titleExternal?: boolean;
|
60
75
|
/**
|
61
76
|
* 自定义类名
|
62
77
|
*/
|
63
78
|
class?: string;
|
64
79
|
}
|
65
80
|
|
66
|
-
const {
|
81
|
+
const {
|
82
|
+
id,
|
83
|
+
title = '',
|
84
|
+
titleHref,
|
85
|
+
titleExternal = false,
|
86
|
+
class: className = '',
|
87
|
+
} = Astro.props;
|
67
88
|
---
|
68
89
|
|
69
90
|
<dialog id={id} class="cosy:modal">
|
70
|
-
<div class:list={['cosy:modal-box
|
91
|
+
<div class:list={['cosy:modal-box', className]}>
|
71
92
|
<div
|
72
|
-
class="cosy:flex cosy:justify-between cosy:items-center cosy:border-b-1 cosy:border-base-300
|
73
|
-
<Heading
|
93
|
+
class="cosy:flex cosy:justify-between cosy:items-center cosy:p-2 cosy:border-b-1 cosy:border-base-300 not-prose">
|
94
|
+
<Heading
|
95
|
+
level={4}
|
96
|
+
class="cosy:modal-title cosy:m-0"
|
97
|
+
href={titleHref}
|
98
|
+
external={titleExternal}>
|
74
99
|
{title}
|
75
100
|
</Heading>
|
76
101
|
<CloseButton class="cosy:absolute" />
|
@@ -108,6 +133,16 @@ const { id, title = '', class: className = '' } = Astro.props;
|
|
108
133
|
if (trigger) {
|
109
134
|
console.log('Modal: 触发模态框', id);
|
110
135
|
modal.showModal();
|
136
|
+
|
137
|
+
// 在modal显示后自动focus到第一个input元素
|
138
|
+
setTimeout(() => {
|
139
|
+
const firstInput = modal.querySelector(
|
140
|
+
'input, textarea, select, [contenteditable="true"]'
|
141
|
+
);
|
142
|
+
if (firstInput) {
|
143
|
+
firstInput.focus();
|
144
|
+
}
|
145
|
+
}, 100); // 延迟100ms确保modal完全显示
|
111
146
|
}
|
112
147
|
};
|
113
148
|
|